kms electron

This commit is contained in:
HorizonCode 2024-01-10 16:26:45 +01:00
parent 1f1dc65a97
commit 6790fe5ef6
14 changed files with 217 additions and 108 deletions

11
main.js
View File

@ -1,5 +1,5 @@
// Modules to control application life and create native browser window // Modules to control application life and create native browser window
const { app, BrowserWindow, Menu } = require("electron"); const { app, BrowserWindow, Menu, ipcMain } = require("electron");
const path = require("path"); const path = require("path");
const serve = require("electron-serve"); const serve = require("electron-serve");
const loadURL = serve({ directory: "public" }); const loadURL = serve({ directory: "public" });
@ -15,6 +15,13 @@ function isDev() {
return !app.isPackaged; return !app.isPackaged;
} }
function registerIPCPipes() {
ipcMain.handle("ezpplauncher:login", (e, args) => {
console.log(args);
return "yes";
});
}
function createWindow() { function createWindow() {
setupTitlebar(); setupTitlebar();
@ -50,6 +57,8 @@ function createWindow() {
loadURL(mainWindow); loadURL(mainWindow);
} }
registerIPCPipes();
// Uncomment the following line of code when app is ready to be packaged. // Uncomment the following line of code when app is ready to be packaged.
// loadURL(mainWindow); // loadURL(mainWindow);

14
package-lock.json generated
View File

@ -9,6 +9,7 @@
"version": "2.0.0", "version": "2.0.0",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.6.5",
"custom-electron-titlebar": "^4.2.7", "custom-electron-titlebar": "^4.2.7",
"electron-serve": "^1.1.0" "electron-serve": "^1.1.0"
}, },
@ -1875,8 +1876,7 @@
"node_modules/asynckit": { "node_modules/asynckit": {
"version": "0.4.0", "version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
"dev": true
}, },
"node_modules/at-least-node": { "node_modules/at-least-node": {
"version": "1.0.0", "version": "1.0.0",
@ -1928,7 +1928,6 @@
"version": "1.6.5", "version": "1.6.5",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz", "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
"integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==", "integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
"dev": true,
"dependencies": { "dependencies": {
"follow-redirects": "^1.15.4", "follow-redirects": "^1.15.4",
"form-data": "^4.0.0", "form-data": "^4.0.0",
@ -2447,7 +2446,6 @@
"version": "1.0.8", "version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"dev": true,
"dependencies": { "dependencies": {
"delayed-stream": "~1.0.0" "delayed-stream": "~1.0.0"
}, },
@ -2924,7 +2922,6 @@
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"dev": true,
"engines": { "engines": {
"node": ">=0.4.0" "node": ">=0.4.0"
} }
@ -3578,7 +3575,6 @@
"version": "1.15.4", "version": "1.15.4",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
"dev": true,
"funding": [ "funding": [
{ {
"type": "individual", "type": "individual",
@ -3614,7 +3610,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
"dev": true,
"dependencies": { "dependencies": {
"asynckit": "^0.4.0", "asynckit": "^0.4.0",
"combined-stream": "^1.0.8", "combined-stream": "^1.0.8",
@ -4573,7 +4568,6 @@
"version": "1.52.0", "version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"engines": { "engines": {
"node": ">= 0.6" "node": ">= 0.6"
} }
@ -4582,7 +4576,6 @@
"version": "2.1.35", "version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"dependencies": { "dependencies": {
"mime-db": "1.52.0" "mime-db": "1.52.0"
}, },
@ -5664,8 +5657,7 @@
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
"dev": true
}, },
"node_modules/pump": { "node_modules/pump": {
"version": "3.0.0", "version": "3.0.0",

View File

@ -33,6 +33,7 @@
"check": "svelte-check --tsconfig ./tsconfig.json" "check": "svelte-check --tsconfig ./tsconfig.json"
}, },
"dependencies": { "dependencies": {
"axios": "^1.6.5",
"custom-electron-titlebar": "^4.2.7", "custom-electron-titlebar": "^4.2.7",
"electron-serve": "^1.1.0" "electron-serve": "^1.1.0"
}, },

View File

@ -70,11 +70,11 @@ export default {
browser: true, browser: true,
dedupe: ["svelte"], dedupe: ["svelte"],
}), }),
commonjs(),
typescript({ typescript({
sourceMap: !production, sourceMap: !production,
inlineSources: !production, inlineSources: !production,
}), }),
commonjs(),
image(), image(),
// In dev mode, call `npm run start` once // In dev mode, call `npm run start` once

View File

@ -7,7 +7,6 @@
DropdownDivider, DropdownDivider,
Button, Button,
Checkbox, Checkbox,
DarkMode,
} from "flowbite-svelte"; } from "flowbite-svelte";
import Progressbar from "./lib/Progressbar.svelte"; import Progressbar from "./lib/Progressbar.svelte";
import { import {
@ -18,13 +17,12 @@
UserSolid, UserSolid,
} from "flowbite-svelte-icons"; } from "flowbite-svelte-icons";
import ezppLogo from "../public/favicon.png"; import ezppLogo from "../public/favicon.png";
import { currentPage } from "./storage/localStore";
import { Page } from "./consts/pages";
import Login from "./pages/Login.svelte";
import Launch from "./pages/Launch.svelte";
let loggedIn = true; let loggedIn = false;
let patch = true;
let loading = false;
let currentStatus = "Preparing launch...";
let rand = 0;
</script> </script>
<div class="p-2 flex flex-row justify-between items-center"> <div class="p-2 flex flex-row justify-between items-center">
@ -34,98 +32,74 @@
>EZPPLauncher</span >EZPPLauncher</span
> >
</div> </div>
<div class="flex flex-row gap-2 w-fill cursor-pointer md:order-2"> {#if $currentPage != Page.Login}
<Avatar <div class="flex flex-row gap-2 w-fill cursor-pointer md:order-2">
class="rounded-lg border dark:border-gray-700 hover:ring-4 hover:ring-gray-200 dark:hover:ring-gray-800" <Avatar
src={loggedIn ? "https://a.ez-pp.farm/1001" : "https://a.ez-pp.farm/0"} class="rounded-lg border dark:border-gray-700 hover:ring-4 hover:ring-gray-200 dark:hover:ring-gray-800"
id="avatar-menu" src={loggedIn ? "https://a.ez-pp.farm/1001" : "https://a.ez-pp.farm/0"}
/> id="avatar-menu"
</div> />
<Dropdown placement="bottom" triggeredBy="#avatar-menu"> </div>
<DropdownHeader> <Dropdown placement="bottom" triggeredBy="#avatar-menu">
<span class="block text-sm">{loggedIn ? "Quetzalcoatl" : "Guest"}</span> <DropdownHeader>
<span <span class="block text-sm">{loggedIn ? "Quetzalcoatl" : "Guest"}</span>
class="block truncate text-sm font-medium text-gray-500 dark:text-gray-200" <span
> class="block truncate text-sm font-medium text-gray-500 dark:text-gray-200"
{loggedIn ? "me@horizonco.de" : "Please log in!"} >
</span> {loggedIn ? "me@horizonco.de" : "Please log in!"}
</DropdownHeader> </span>
{#if loggedIn} </DropdownHeader>
{#if loggedIn}
<DropdownItem
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
>
<UserSolid class="select-none outline-none border-none" />
Profile
</DropdownItem>
{/if}
<DropdownItem <DropdownItem
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
> >
<UserSolid class="select-none outline-none border-none" /> <UserSettingsSolid class="select-none outline-none border-none" />
Profile Settings
</DropdownItem> </DropdownItem>
{/if} <DropdownDivider />
<DropdownItem {#if loggedIn}
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" <DropdownItem
> class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
<UserSettingsSolid class="select-none outline-none border-none" /> on:click={() => (loggedIn = false)}
Settings >
</DropdownItem> <ArrowRightFromBracketSolid
<DropdownDivider /> class="select-none outline-none border-none"
{#if loggedIn} />
<DropdownItem Sign out
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" </DropdownItem>
on:click={() => (loggedIn = false)} {:else}
> <DropdownItem
<ArrowRightFromBracketSolid class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
class="select-none outline-none border-none" on:click={() => currentPage.set(Page.Login)}
/> >
Sign out <ArrowRightToBracketSolid
</DropdownItem> class="select-none outline-none border-none"
{:else} />
<DropdownItem Login
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" </DropdownItem>
on:click={() => (loggedIn = true)} <DropdownItem
> class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors"
<ArrowRightToBracketSolid >
class="select-none outline-none border-none" <UserPlusSolid class="select-none outline-none border-none" />
/> Register
Login </DropdownItem>
</DropdownItem> {/if}
<DropdownItem </Dropdown>
class="flex flex-row gap-2 border-0 dark:!bg-gray-700 dark:active:!bg-gray-900 dark:hover:!bg-gray-800 transition-colors" {/if}
>
<UserPlusSolid class="select-none outline-none border-none" />
Register
</DropdownItem>
{/if}
</Dropdown>
</div> </div>
<main class="h-[265px] my-auto flex flex-col justify-center items-center p-5"> {#if $currentPage == Page.Login}
<div <Login />
class="container flex flex-col items-center justify-center gap-5 border border-gray-300 dark:border-gray-700 rounded-lg" {:else}
> <Launch />
<Button {/if}
color="light"
size="xl"
class="active:!bg-gray-900"
on:click={() => {
rand = Math.random() * 100;
loading = true;
}}>Launch</Button
>
<Checkbox color="primary" bind:checked={patch}>
Patching {patch ? "enabled" : "disabled"}
</Checkbox>
{#if loading}
<div class="w-full flex flex-col justify-center items-center gap-2">
<p class="m-0 p-0 dark:text-gray-100">{currentStatus}</p>
<Progressbar
animate={true}
progress={rand}
labelInside={true}
size="h-6"
indeterminate
labelInsideClass="bg-primary-600 drop-shadow-xl text-gray-100 text-base font-medium text-center p-1 leading-none rounded-full"
/>
</div>
{/if}
</div>
</main>
<style> <style>
.container { .container {

4
src/consts/pages.ts Normal file
View File

@ -0,0 +1,4 @@
export enum Page {
Login = 0,
Launch = 1,
}

View File

@ -3,7 +3,7 @@
import { tweened } from "svelte/motion"; import { tweened } from "svelte/motion";
import { twMerge, twJoin } from "tailwind-merge"; import { twMerge, twJoin } from "tailwind-merge";
export let progress: string | number | undefined = "45"; export let progress: string | number | undefined | null = "45";
export let precision = 0; export let precision = 0;
export let tweenDuration = 400; export let tweenDuration = 400;
export let animate = false; export let animate = false;
@ -15,7 +15,7 @@
export let labelInsideClass = export let labelInsideClass =
"text-primary-100 text-xs font-medium text-center p-0.5 leading-none rounded-full"; "text-primary-100 text-xs font-medium text-center p-0.5 leading-none rounded-full";
export let divClass = "w-full bg-gray-200 rounded-full dark:bg-gray-700"; export let divClass = "w-full bg-gray-200 rounded-full dark:bg-gray-700";
export let indeterminate = false; export let indeterminate = progress == null;
const barColors: Record<string, string> = { const barColors: Record<string, string> = {
primary: "bg-primary-600", primary: "bg-primary-600",

24
src/pages/Launch.svelte Normal file
View File

@ -0,0 +1,24 @@
<script lang="ts">
import { Button } from "flowbite-svelte";
import Progressbar from "../lib/Progressbar.svelte";
</script>
<main class="h-[265px] my-auto flex flex-col justify-center items-center p-5">
<div
class="container flex flex-col items-center justify-center gap-5 rounded-lg p-3"
>
<Button color="light" size="xl" class="dark:active:!bg-gray-900"
>Launch</Button
>
<div class="w-full flex flex-col justify-center items-center gap-2">
<p class="m-0 p-0 dark:text-gray-100">Waiting</p>
<Progressbar
animate={true}
progress={null}
labelInside={true}
size="h-6"
labelInsideClass="bg-primary-600 drop-shadow-xl text-gray-100 text-base font-medium text-center p-1 leading-none rounded-full"
/>
</div>
</div>
</main>

59
src/pages/Login.svelte Normal file
View File

@ -0,0 +1,59 @@
<script lang="ts">
import { Input, Button, Spinner } from "flowbite-svelte";
import { performLogin } from "../util/loginUtil";
import type { User } from "../types/user";
import { currentUser } from "../storage/localStore";
let loading = false;
let username = "";
let password = "";
const processLogin = async () => {
loading = true;
const loginResult = await performLogin(username, password);
if (loginResult instanceof Error) {
loading = false;
return;
}
};
</script>
<main class="h-[265px] my-auto flex flex-col justify-center items-center p-5">
<div
class="container flex flex-col items-center justify-center gap-5 rounded-lg p-3"
>
<Input
type="text"
placeholder="Username"
size="md"
disabled={loading}
bind:value={username}
/>
<Input
type="password"
placeholder="Password"
size="md"
disabled={loading}
bind:value={password}
/>
<div class="flex flex-col justify-center items-center gap-5 mt-2">
<Button
class="dark:active:!bg-gray-900"
color="light"
disabled={loading}
on:click={processLogin}
>
{#if loading}
<Spinner size={"5"} color="white"></Spinner>
{:else}
Login
{/if}
</Button>
<Button
class="!bg-transparent border-none dark:text-gray-700 hover:!bg-gray-700/15 ring-primary active:ring-2 focus:ring-2"
color="none"
disabled={loading}>Continue without login</Button
>
</div>
</div>
</main>

View File

@ -0,0 +1,6 @@
import { type Writable, writable } from "svelte/store";
import { Page } from "../consts/pages";
import type { User } from "../types/user";
export const currentUser: Writable<undefined | User> = writable(undefined);
export const currentPage = writable(Page.Login);

4
src/types/error.ts Normal file
View File

@ -0,0 +1,4 @@
export type Error = {
code: number;
message: string;
};

View File

@ -2,3 +2,4 @@ declare module "*.jpg";
declare module "*.jpeg"; declare module "*.jpeg";
declare module "*.png"; declare module "*.png";
declare module "*.svg"; declare module "*.svg";
declare module "*.svelte";

5
src/types/user.ts Normal file
View File

@ -0,0 +1,5 @@
export type User = {
id: number;
name: string;
email: string;
};

30
src/util/loginUtil.ts Normal file
View File

@ -0,0 +1,30 @@
import axios from "axios";
import type { Error } from "../types/error";
import type { User } from "../types/user";
import { ipcRenderer } from "electron";
const loginCheckEndpoint = "https://ez-pp.farm/login/check";
let retries = 0;
export const performLogin = async (
username: string,
password: string,
) => {
const result = await ipcRenderer.invoke("ezpplauncher:login", {
username,
password,
});
console.log(result);
return ({ code: 403, message: "Login failed." } as Error);
/* const result = await axios.post(loginCheckEndpoint, { username, password });
const code = result.data.code ?? 404;
if (code === 200 || code === 403) {
retries = 0;
return result.data.user as User;
} else {
if (retries++ >= 5) {
return ({ code: 403, message: "Login failed." } as Error);
}
return await performLogin(username, password);
} */
};