From 494e2972242a478c0ebe823a828be5f2f0fb5bf4 Mon Sep 17 00:00:00 2001
From: Lorenz Stechauner <lorenz.stechauner@necronda.net>
Date: Mon, 29 Aug 2022 14:31:11 +0200
Subject: [PATCH] Use localStorage

---
 src/locutus.ts | 71 +++++++++++++++++++++++++++++++++++++++++---------
 src/main.ts    |  2 +-
 tsconfig.json  |  6 ++---
 3 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/src/locutus.ts b/src/locutus.ts
index 6634ee9..3294080 100644
--- a/src/locutus.ts
+++ b/src/locutus.ts
@@ -26,15 +26,37 @@ export class App {
             this.handleUrl(event.newURL);
         });
 
-        this.handleUrl(document.URL);
+        const domainName = window.localStorage['domainName'];
+        const sessionToken = window.localStorage['sessionToken'];
+        if (domainName && sessionToken) {
+            USIMP.Domain.fromName(domainName).then((domain) => {
+                const session = new USIMP.Session(domain);
+                session.chooseDomainServer().then(() => {
+                    session.token = sessionToken;
+                    session.ping().then(() => {
+                        this.session = session;
+                        this.defaultLocation = '/';
+                        this.handleUrl(document.URL);
+                    })
+                });
+            }, (error) => {
+                if (error instanceof DOMException) {
+                    throw new Error("Connection timed out");
+                } else {
+                    throw new Error("Invalid USIMP domain");
+                }
+            });
+        } else {
+            this.handleUrl(document.URL);
+        }
     }
 
-    close() {
-        if (this.session) this.session.close();
+    quit() {
+        if (this.session) this.session.close().then();
     }
 
     sleep() {
-        if (this.session) this.session.sleep();
+        if (this.session) this.session.sleep().then();
     }
 
     async wakeup() {
@@ -52,7 +74,7 @@ export class App {
     }
 
     handleHash(hash: string) {
-        if (hash[0] === '#') hash = hash.substr(1);
+        if (hash[0] === '#') hash = hash.substring(1);
 
         const defaultCase = () => {
             history.replaceState(null, document.title, `#${this.defaultLocation}`);
@@ -110,7 +132,7 @@ export class App {
         if (response.status === "success") {
             this.session = session;
             this.defaultLocation = "/";
-            this.setHash("/");
+            return true;
         } else {
             console.error(response.error);
             throw new Error(response.error.message || response.error.code);
@@ -188,6 +210,8 @@ export class App {
                 <input name="account" placeholder="Account name" type="text" required/>
                 <input name="domain" placeholder="Domain" type="text" pattern="([a-zA-Z0-9_-]+\\.)+[a-zA-Z]{2,}" required/>
                 <input name="password" placeholder="Password" type="password" required/>
+                <label><input name="saveAccountName" type="checkbox"/> Save Account Name</label>
+                <label><input name="keepSession" type="checkbox"/> Keep me signed in</label>
                 <button type="submit">Login</button>
             </form>`;
 
@@ -204,8 +228,21 @@ export class App {
             }
 
             try {
+                const accountName: string = form['account'].value;
+                const domainName: string = form['domain'].value;
+                const keepSession: boolean = form['keepSession'].checked;
+                const saveAccountName: boolean = form['saveAccountName'].checked;
                 try {
-                    await this.login(form['account'].value, form['domain'].value, form['password'].value);
+                    if (await this.login(accountName, domainName, form['password'].value)) {
+                        window.localStorage.clear();
+                        if (keepSession || saveAccountName)
+                            window.localStorage['domainName'] = domainName;
+                        if (keepSession)
+                            window.localStorage['sessionToken'] = this.session?.token;
+                        if (saveAccountName)
+                            window.localStorage['accountName'] = accountName;
+                        this.setHash("/");
+                    }
                 } finally {
                     for (const d of form.getElementsByTagName("div")) form.removeChild(d);
                     for (const e of form.getElementsByTagName("input")) e.disabled = false;
@@ -231,19 +268,29 @@ export class App {
 
         const domain = document.getElementsByName("domain")[0];
         if (!domain) throw new Error("Element name=domain not found");
-
-        domain.addEventListener("input", (event) => {
+        domain.addEventListener("input", () => {
             domain.removeAttribute("invalid");
         });
 
         const account = document.getElementsByName("account")[0];
         if (!account) throw new Error("Element name=account not found");
-
-        account.addEventListener("input", (event) => {
+        account.addEventListener("input", () => {
             account.removeAttribute("invalid");
         });
 
-        account.focus();
+        const password = document.getElementsByName("password")[0];
+        if (!password) throw new Error("Element name=password not found");
+
+        const accountName = window.localStorage['accountName'];
+        const domainName = window.localStorage['domainName'];
+        if (accountName && domainName) {
+            form['account'].value = accountName;
+            form['domain'].value = domainName;
+            form['saveAccountName'].checked = true;
+            password.focus();
+        } else {
+            account.focus();
+        }
     }
 
     setupMain() {
diff --git a/src/main.ts b/src/main.ts
index 9b1cf48..dc80d2d 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -28,7 +28,7 @@ window.addEventListener("DOMContentLoaded", () => {
     }
 
     window.addEventListener("beforeunload", () => {
-        locutus.close();
+        locutus.quit();
     });
 });
 
diff --git a/tsconfig.json b/tsconfig.json
index d44da8e..803b1b1 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,10 +1,10 @@
 {
   "compilerOptions": {
     /* Visit https://aka.ms/tsconfig.json to read more about this file */
-    "target": "ES2020",
-    "module": "ES2020",
+    "target": "ESNext",
+    "module": "ESNext",
     "outDir": "dest/www/res/scripts",
-    "rootDir": "src",
+    "rootDir": "src/",
     "strict": true,
     "noImplicitAny": true,
     "strictNullChecks": true,