]> Repos - mime-chat/commitdiff
update sockets, account, auth
authorriqo <hernandeze2@xavier.edu>
Mon, 14 Jun 2021 13:52:01 +0000 (08:52 -0500)
committerriqo <hernandeze2@xavier.edu>
Mon, 14 Jun 2021 13:52:40 +0000 (08:52 -0500)
20 files changed:
build/config.gypi [deleted file]
package.json
public/index.html
src/account.ts [new file with mode: 0644]
src/api/account.ts
src/auth.ts [new file with mode: 0644]
src/composables/http.ts
src/composables/ipcHandler.ts [new file with mode: 0644]
src/composables/json.ts
src/composables/store.ts [new file with mode: 0644]
src/composables/websockets.ts
src/config.ts [new file with mode: 0644]
src/init.ts
src/ipc/account.ts
src/ipc/index.ts
src/ipc/session.ts
src/main.ts
src/session.ts
src/types.ts
src/window.ts

diff --git a/build/config.gypi b/build/config.gypi
deleted file mode 100644 (file)
index 6f84ed7..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-# Do not edit. File was generated by node-gyp's "configure" step
-{
-  "target_defaults": {
-    "cflags": [],
-    "default_configuration": "Release",
-    "defines": [],
-    "include_dirs": [],
-    "libraries": []
-  },
-  "variables": {
-    "asan": 0,
-    "build_v8_with_gn": "false",
-    "coverage": "false",
-    "dcheck_always_on": 0,
-    "debug_nghttp2": "false",
-    "debug_node": "false",
-    "enable_lto": "false",
-    "enable_pgo_generate": "false",
-    "enable_pgo_use": "false",
-    "error_on_warn": "false",
-    "force_dynamic_crt": 0,
-    "host_arch": "x64",
-    "icu_data_in": "../../deps/icu-tmp/icudt67l.dat",
-    "icu_endianness": "l",
-    "icu_gyp_path": "tools/icu/icu-generic.gyp",
-    "icu_path": "deps/icu-small",
-    "icu_small": "false",
-    "icu_ver_major": "67",
-    "is_debug": 0,
-    "llvm_version": "0.0",
-    "napi_build_version": "6",
-    "node_byteorder": "little",
-    "node_debug_lib": "false",
-    "node_enable_d8": "false",
-    "node_install_npm": "true",
-    "node_module_version": 83,
-    "node_no_browser_globals": "false",
-    "node_prefix": "/",
-    "node_release_urlbase": "https://nodejs.org/download/release/",
-    "node_shared": "false",
-    "node_shared_brotli": "false",
-    "node_shared_cares": "false",
-    "node_shared_http_parser": "false",
-    "node_shared_libuv": "false",
-    "node_shared_nghttp2": "false",
-    "node_shared_openssl": "false",
-    "node_shared_zlib": "false",
-    "node_tag": "",
-    "node_target_type": "executable",
-    "node_use_bundled_v8": "true",
-    "node_use_dtrace": "true",
-    "node_use_etw": "false",
-    "node_use_node_code_cache": "true",
-    "node_use_node_snapshot": "true",
-    "node_use_openssl": "true",
-    "node_use_v8_platform": "true",
-    "node_with_ltcg": "false",
-    "node_without_node_options": "false",
-    "openssl_fips": "",
-    "openssl_is_fips": "false",
-    "shlib_suffix": "83.dylib",
-    "target_arch": "x64",
-    "v8_enable_31bit_smis_on_64bit_arch": 0,
-    "v8_enable_gdbjit": 0,
-    "v8_enable_i18n_support": 1,
-    "v8_enable_inspector": 1,
-    "v8_enable_pointer_compression": 0,
-    "v8_no_strict_aliasing": 1,
-    "v8_optimized_debug": 1,
-    "v8_promise_internal_field_count": 1,
-    "v8_random_seed": 0,
-    "v8_trace_maps": 0,
-    "v8_use_siphash": 1,
-    "want_separate_host_toolset": 0,
-    "xcode_version": "11.0",
-    "nodedir": "/Users/Enrique/Library/Caches/node-gyp/14.4.0",
-    "standalone_static_library": 1
-  }
-}
index 38c1348361c9b89f6208c0a29820d9a7ec3f231e..2b4b7fdcac8b51aa1a952b8023037a3b8ae2a2a4 100644 (file)
@@ -12,7 +12,7 @@
     "postinstall": "electron-builder install-app-deps",
     "postuninstall": "electron-builder install-app-deps"
   },
-  "main": "background.js",
+  "main": "init.js",
   "dependencies": {
     "@google-cloud/speech": "^4.2.0",
     "@types/animejs": "^3.1.2",
@@ -73,7 +73,7 @@
     "lintOnSave": false,
     "pluginOptions": {
       "electronBuilder": {
-        "preload": "src/preload.ts",
+        "preload": "src/renderer/preload.ts",
         "builderOptions": {
           "appId": "com.crimata.ElectronUpdaterApp",
           "artifactName": "${productName}-${version}.${ext}",
index 48809d83c73c2c5cedd8d2a094085e14e5d354ff..8f79d276385d13e9f92064f77a5792480b884231 100644 (file)
     <noscript>
       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
     </noscript>
-    <!-- <h1>Hello World!</h1>
-         We are using Node.js <span id="node-version"></span>, Chromium
-         <span id="chrome-version"></span>, and Electron
-         <span id="electron-version"></span>. -->
-    <div id="app"></div>
+        <div id="app"></div>
     <!-- built files will be auto injected -->
   </body>
 </html>
diff --git a/src/account.ts b/src/account.ts
new file mode 100644 (file)
index 0000000..4884135
--- /dev/null
@@ -0,0 +1,105 @@
+
+import { postAuth, postLogin, postLogout } from "@/api/account";
+import { endSession, launchSession } from "@/session";
+import { getToken, clearToken, setToken } from "@/composables/store";
+import { parseAuthRes } from "./auth";
+
+export const accountAuth = async (): Promise<Error | AuthState> => {
+
+    /* attempt to get a login token from the store */
+    const token = getToken();
+
+    /* try to login with it, returns platform secret and new token on success */
+    if (token) {
+        try {
+
+            const res = await postAuth(token);
+
+            const parsed = parseAuthRes(res);
+
+            setToken(parsed.token)
+
+            return {
+                profile: parsed.profile,
+                token: parsed.token
+            };
+
+        } catch(e) {
+            console.log('[ACCOUNT]', e);
+            clearToken();
+            throw(new Error('Failed to authenticate.'));
+
+        }
+    } else {
+        throw(new Error('Unable to authenticate.'));
+    }
+};
+
+export const accountLogin: IpcHandlerCallback<AccountCredentials, Profile> = async (payload) => {
+     const account = payload as AccountCredentials;
+     try {
+
+         // attempt login with email password
+         const res = await postLogin(account.email, account.password);
+         const parsed = parseAuthRes(res);
+
+         // save jwt token and profile
+         setToken(parsed.token)
+
+         // launch session
+         launchSession(parsed.token)
+
+         // return profile to renderer
+         return parsed.profile;
+
+     } catch(e) {
+         throw e;
+     }
+}
+
+// export const accountLogin = async (account: Account): Promise<Error | Profile> => {
+//
+//     try {
+//
+//         // attempt login with email password
+//         const res = await postLogin(account.email, account.password);
+//         const parsed = parseAuthRes(res);
+//
+//         // save jwt token and profile
+//         setToken(parsed.token)
+//
+//         // launch session
+//         launchSession(parsed.token)
+//
+//         // return profile to renderer
+//         return parsed.profile;
+//
+//     } catch(e) {
+//         console.log('[ACCOUNT]', e);
+//         throw (new Error('Failed to authenticate'));
+//     }
+//
+// }
+
+export const accountLogout = async (): Promise<Error | void> => {
+
+    try {
+        // post logout to backend
+        await postLogout();
+
+        // remove key and crimataId
+        clearToken();
+
+        // kill crimata platform session
+        endSession();
+
+        return;
+
+    } catch(e) {
+        console.log('[ACCOUNT]', e);
+        return (new Error('Failed to logout. Please try again.'));
+    }
+
+}
+
+
index 98d3c69da3533bde6368a0c303c8f470843a0175..a907dfbc9f28b9ba7a5fee89f694958b756b238d 100644 (file)
@@ -1,36 +1,31 @@
 
 import { useHttp } from "@/composables/http";
 import axios from "axios";
+import {config} from "@/config";
 
 const { post } = useHttp();
 
-export const usrPwdAuth = async (email: string, password: string) => {
+export const postAuth = async (token: string) => (
+    await axios({
+        url: config.BUSINESS_URL + config.BUSINESS_PREFIX + '/account/authenticate',
+        headers: {
+            Cookie: `jwt=${token}`
+        },
+        method: 'POST',
+    })
+).data;
 
-  try {
-    return await post('/account/login', { email, password })
 
-  } catch (e) {
-    return null;
-  }
+export const postLogin = async (email: string, password: string) => (
+    await post('/account/login', { email, password })
+).data;
+
+
+export const postLogout =
+    async (): Promise<null | Error> => (await post('/account/logout'));
+
 
-}
 
-export const tokenAuth = async (cid: string, token: string) => {
 
-  try {
-    return await axios({
-      url: "http://127.0.0.1:3000/api/account/profile",
-      headers: {
-          Cookie: `jwt=${token}`
-      },
-      method: 'GET',
-      data: {
-        cid,
-      }
-    })
 
-  } catch (e) {
-    return null;
-  }
 
-}
\ No newline at end of file
diff --git a/src/auth.ts b/src/auth.ts
new file mode 100644 (file)
index 0000000..14ed36a
--- /dev/null
@@ -0,0 +1,13 @@
+
+export const parseAuthRes = (authRes: any) => {
+    const token = authRes.headers['set-cookie'][0].split(";")[0].split("=")[1] as string;
+    const profile = authRes.data as Profile;
+    return {
+        token,
+        profile
+    }
+};
+
+
+
+
index a9519a81bfd8fd3270ea24934c9959b4f222dbeb..e789afa94f58fa36980988e41ae3627b05fc4044 100644 (file)
@@ -1,10 +1,8 @@
 
 import axios, { AxiosRequestConfig } from 'axios';
+import {config} from "@/config";
 
-const preFix = '/api';
-
-const baseURL = "http://127.0.0.1:3000" + preFix;
-
+const baseURL = config.BUSINESS_URL + config.BUSINESS_PREFIX;
 
 interface Request {
     endpoint: string;
@@ -12,7 +10,6 @@ interface Request {
     config?: Record<string, any>;
 }
 
-
 const makeQuery = (reqQuery: Record<string, any>) => {
 
     let result = '';
diff --git a/src/composables/ipcHandler.ts b/src/composables/ipcHandler.ts
new file mode 100644 (file)
index 0000000..b588102
--- /dev/null
@@ -0,0 +1,50 @@
+
+import { ipcMain, IpcMainInvokeEvent } from "electron";
+
+export class IpcHandler<InputType, ReturnType> implements IIpcHandler<InputType, ReturnType> {
+
+  readonly channel: string;
+
+  readonly _handlerCallback: IpcHandlerCallback<InputType, ReturnType>;
+
+  constructor(options: {
+      channel: string;
+      handlerCallback: IpcHandlerCallback<InputType, ReturnType>;
+  }) {
+    this.channel = options.channel;
+    this._handlerCallback = options.handlerCallback;
+  }
+
+  handle() {
+      ipcMain.handle(this.channel, this._onInvoke);
+  }
+
+  remove() {
+      ipcMain.removeHandler(this.channel);
+  }
+
+  private async _onInvoke(_e: IpcMainInvokeEvent, payload?: string | null): Promise<Error | ReturnType> {
+
+      return new Promise(async (resolve, reject) => {
+
+          console.log(`[IPC]:${this.channel}`);
+
+          try {
+
+              const params = payload ? JSON.parse(payload) : null;
+
+              const res = await this._handlerCallback(params);
+
+              resolve(res as unknown as ReturnType);
+
+          } catch(e) {
+              console.log(`[IPC]:${this.channel}`, e);
+              reject(e);
+          }
+      });
+  }
+
+}
+
+
+
index 43b3804f93b91095c1bf983b0fe2587c53f535ff..06ab4b9938502114ea39494365c54a2bb33bb1b9 100644 (file)
@@ -1,9 +1,13 @@
+
+import {config} from "@/config";
+import fs from 'fs';
+
 export const saveToJson = (fileName: string, data: any) => {
 
-    fs.writeFile(configPath + fileName, JSON.stringify(data), (err) => {
+    fs.writeFile(config.configPath + fileName, JSON.stringify(data), (err) => {
         if (err) {
             console.log("Error when saving to json.")
-        }      
+        }
     })
 
-}
\ No newline at end of file
+}
diff --git a/src/composables/store.ts b/src/composables/store.ts
new file mode 100644 (file)
index 0000000..88b9c17
--- /dev/null
@@ -0,0 +1,19 @@
+const Store = require('electron-store');
+
+const schema = {
+       key: {
+               type: 'string',
+       },
+};
+
+const store = new Store({
+    schema,
+    encryptionKey: "super user test"
+});
+
+export const getToken = (): string | undefined => (store.get("token"));
+
+export const clearToken = (): void => (store.delete("token"));
+
+export const setToken = (token: string): void => (store.set('token', token));
+
index d034027a1092ab34b3c0a8a561433cabde94b7e4..820810914ea2ff017d18e1214ce400f2d47fd584 100644 (file)
@@ -3,9 +3,18 @@
 
 import WebSocket from 'ws';
 
-export default function useWebSockets(onMessageCallback: (s: string) => void) {
 
-    let socket: WebSocket | null = null;
+const _connectionCheckTimeout = 4000;
+const _reconnectTimeout = 1000;
+let _connectionCheckInterval: ReturnType<typeof setTimeout>;
+
+
+export default function useWebSockets(
+    messageCallback: (message: string) => void,
+    connectionStatusCallback: (alive: boolean) => void,
+) {
+
+    let socket: WebSocket;
 
     const send = async (data: Record<string, any>): Promise<boolean> => {
         return new Promise((resolve, reject) => {
@@ -21,30 +30,52 @@ export default function useWebSockets(onMessageCallback: (s: string) => void) {
 
     const connect = (socketUrl: string, secret: string) => {
 
+        // avoid setting multiple interval;
+        if (_connectionCheckInterval) clearInterval(_connectionCheckInterval);
+
         /* create a new socket */
-        socket = new WebSocket(socketUrl)
+        socket = new WebSocket(socketUrl);
 
         /* add event listeners */
-
         socket.on("open", () => {
-            if (socket)
+
             socket.send(secret);
+
+            // ping server
+            _connectionCheckInterval = setInterval(() => {
+
+                socket.ping(null, true, (e: Error) => {
+                    if (e) {
+                        socket.close();
+                        connectionStatusCallback(false);
+                        setTimeout(() => connect(socketUrl, secret), _reconnectTimeout);
+                    }
+                });
+
+            }, _connectionCheckTimeout);
+
         });
 
         socket.on("message", (event: WebSocket.MessageEvent) => {
-            onMessageCallback(event.data.toString())
+            messageCallback(event.data.toString())
         });
 
-        socket.on("close", () => {
-            return
+        socket.on("close", (event: WebSocket.CloseEvent) => {
+            connectionStatusCallback(false);
+            clearInterval(_connectionCheckInterval);
+            if (!event.wasClean) {
+                setTimeout(() => connect(socketUrl, secret), _reconnectTimeout);
+            }
+
         });
 
+        socket.on("pong", () => connectionStatusCallback(true));
+
     }
 
     const close = () => {
         if (socket) {
             socket.close();
-            socket = null;
         }
     }
 
diff --git a/src/config.ts b/src/config.ts
new file mode 100644 (file)
index 0000000..b0eb27e
--- /dev/null
@@ -0,0 +1,17 @@
+
+import { app } from "electron";
+
+const env = process.env;
+
+const PLATFORM_PORT = env.PLATFORM_PORT || 8760;
+const PLATFORM_IP = env.PLATFORM_IP || 'http://127.0.0.1';
+
+const BUSINESS_PORT = env.BUSINESS_PORT || 3010;
+const BUSINESS_IP = env.BUSINESS_IP || 'http://127.0.0.1';
+
+export const config = {
+    PLATFORM_URL: `${PLATFORM_IP}:${PLATFORM_PORT}`,
+    BUSINESS_URL: `${BUSINESS_IP}:${BUSINESS_PORT}`,
+    BUSINESS_PREFIX: '/api',
+    configPath: app.getPath('userData')
+}
index 3d0b72124390cae53199bc7b7ae80ef7cb7dbfdb..e68e76601dc5ac7c6957186826cb29ae751c51be 100644 (file)
@@ -9,8 +9,6 @@ import { app, protocol } from "electron";
 import createWindow from "./window";
 import main from "./main";
 
-require('dotenv').config();
-
 console.log('Starting Crimata electron app.');
 
 // Scheme must be registered before the app is ready
@@ -43,4 +41,4 @@ if (isDev) {
     process.on("SIGTERM", () => {
         app.quit();
     });
-}
\ No newline at end of file
+}
index 38600195488b15402097d10b291eabfc95e61b5b..531d1a758407959105cfb0c98385a26d550f9a04 100644 (file)
 
 "use strict";
 
-import { submit, fetchProfile, logout } from "../api/account";
-import { ipcMain, IpcMainInvokeEvent } from "electron";
-import { store } from "@/composables/store";
-
-
-const parseAuthRes = (authRes: any) => {
-    const token = authRes.headers['set-cookie'][0].split(";")[0].split("=")[1] as string;
-    const profile = authRes.data as Profile;
-    return {
-        token,
-        profile
-    }
-};
-
-
-
-
-
-/**
- * Get user profile from store and try to login with it.
- */
-const onTokenLogin = async (
-    _event: IpcMainInvokeEvent,
-    _payload: null
-): Promise<Profile | Error> => (
-
-    new Promise(async (resolve, reject) => {
-        console.log('[IPC]: user-profile');
-
-        // get jwt token and crimataId from store
-        const token = store.get('key');
-        const crimataId = store.get('crimataId');
-
-        // authenticate and fetch profile
-        try {
-
-            // attempt login with email token
-            const res = await fetchProfile(crimataId, token);
-            const parsed = parseAuthRes(res);
-
-            // return profile to renderer
-            resolve(parsed.profile);
-
-        } catch(e) {
-            reject(new Error('Failed to fetch profile.'));
-        }
-    })
-)
-
-
-const onLogin = async (
-    _event: IpcMainInvokeEvent,
-    payload: string
-): Promise<Profile | Error> => (
-
-    new Promise(async (resolve, reject) => {
-        console.log('[IPC]: user-login');
-
-        const account = JSON.parse(payload);
-
-        if ( account.password && account.email ) {
-            try {
-
-                // attempt login with email password
-                const res = await submit(account.email, account.password);
-                const parsed = parseAuthRes(res);
-
-                // save jwt token and profile
-                store.set('key', parsed.token);
-                store.set('crimataId', parsed.profile.crimataId);
-
-                // init session
-
-                // return profile to renderer
-                resolve(parsed.profile);
-
-            } catch(e) {
-                console.log('[API]', e);
-                reject(new Error('Failed to authenticate'));
-            }
-        }
-    })
-)
-
-const onLogout = async (
-    _event: IpcMainInvokeEvent,
-    _payload: null
-): Promise<void> => (
-
-    new Promise(async (resolve, reject) => {
-        console.log('[IPC]: user-logout');
-
-        try {
-            // post logout to backend
-            await logout();
-
-            // remove key and crimataId
-            store.delete('key');
-            store.delete('crimataId');
-
-            // TODO: kill crimata platform session
-            // endSession();
-
-            resolve();
-        } catch(e) {
-            reject(new Error('Failed to logout. Please try again.'));
-        }
-    })
-)
-
-
-export default function useAccountListeners(): void {
-
-    ipcMain.removeHandler("user-profile");
-    ipcMain.handle("user-profile", onProfile);
-
-    ipcMain.removeHandler("user-login");
-    ipcMain.handle("user-login", onLogin);
-
-    ipcMain.removeHandler("user-logout");
-    ipcMain.handle("user-logout", onLogout);
-
-}
+import { accountLogin, accountLogout } from "@/account";
+import {IpcHandler} from "@/composables/ipcHandler";
+
+const LOGIN_CHANNEL = "account-login";
+const LOGOUT_CHANNEL = "account-logout";
+
+const loginHandler =  new IpcHandler({
+    channel: LOGIN_CHANNEL,
+    handlerCallback: accountLogin
+});
+
+const logoutHandler =  new IpcHandler({
+    channel: LOGOUT_CHANNEL,
+    handlerCallback: accountLogout
+});
+
+const handlers = [loginHandler, logoutHandler];
+
+export default handlers;
+
+// export default function useAccountListeners(): void {
+//
+//     ipcMain.removeHandler(LOGIN_HANDLER);
+//     ipcMain.handle(LOGIN_HANDLER, onLogin);
+//
+//     ipcMain.removeHandler(LOGOUT_HANDLER);
+//     ipcMain.handle(LOGOUT_HANDLER, onLogout);
+//
+// }
index 9152ef2cb1611204a222db632c39e77e5ea760db..73a5901c8236b0c3186bc229283ce8cc2cfdd7d6 100644 (file)
@@ -1,17 +1,36 @@
 
 "use strict";
 
-import useAccountListeners from "./account";
+import { IpcHandler } from "@/composables/ipcHandler";
+import handlers from "./account";
 import useSessionListeners from "./session";
 // import useAudioListeners from "./audio";
 
+interface IPCHandlers {
+    [channel: string]: IpcHandler<any, any>;
+}
+
+const ipcHandlers: IPCHandlers = {};
+
+const _initHandlers = () => {
+    handlers.forEach((h) => {
+        if (!(h.channel in ipcHandlers)) {
+            ipcHandlers[h.channel] = h;
+            h.handle();
+        }
+    });
+}
 
 export default function useIpc(): void {
 
-    useAccountListeners();
+    _initHandlers();
+
+    // useAccountListeners();
 
     useSessionListeners();
 
     // useAudioListeners();
 
 }
+
+
index fa50aa1ddd6b26ec92c34de93376ae4b52adc1ee..bbaf0e992f81cba090f2304691dfcc1f872301a6 100644 (file)
@@ -10,11 +10,11 @@ function onSendMessage(_event: IpcMainEvent, payload: Message): void {
 }
 
 // Login attempt, returns success or not.
-function onLogin(_event: IpcMainEvent, payload: LoginPayload) => {
-    authenticate(payload.email, payload.password);
+function onLogin(_event: IpcMainEvent, payload: LoginPayload): void {
+    console.log('hello')
 }
 
 export default function useSessionListeners(): void {
     ipcMain.removeAllListeners("client-message");
     ipcMain.on("client-message", onSendMessage);
-}
\ No newline at end of file
+}
index 9d6414c0073cd152e247013fd85b85e315773e55..b015cd990af52cc4d880b768425f642e16f93a08 100644 (file)
@@ -1,41 +1,21 @@
 /**
  * Where the background logic really begins, gets called by app.onReady().
- * 
+ *
  * Handles authentication. If profile is set, we launch a session, which consis
  * of opening a connection with the platform, initializing the audio streams.
- * 
+ *
  * The session is primarily an interface between the frontend and the platform,
  * relaying messages from one to the other.
- * 
+ *
  */
 
-import { tokenAuth, usrPwdAuth } from "@/api/account";
-import { launchSession, endSession } from "@/session";
 import useIpc from "@/ipc/index";
-import store from "@/composables/store";
+import  { accountAuth } from "./account";
+import { launchSession } from "./session";
+import ipcEmit from "./composables/emitter";
+import createWindow from "./window";
 
-/* authenticate the user */
-export async function authenticate(email: string, password: string) {
-
-    /* attempt normal login */
-    const platformKey, token, crimataId = await usrPwdAuth(email, password);
-
-    /* launch if successful */
-    if (platformKey)
-    launchSession(platformKey, crimataId);
-
-    /* save the token */
-    store.set("token", token);
-
-}
-
-/* logout the user, end the session */
-export function deauthenticate() {
-
-    /* terminate the session */
-    endSession();
-
-}
+let authState: AuthState | null;
 
 export default async function main() {
 
@@ -45,18 +25,14 @@ export default async function main() {
     /* launch browser window */
     await createWindow();
 
-    /* attempt to get a login token from the store */
-    const token = store.get("token");
-
-    /* try to login with it, returns platform secret and new token on success */
-    if (token)
-    const newToken, profile = await tokenAuth(token);
+    try {
+        authState = await accountAuth() as AuthState;
+    } catch(e) {
+        console.log('AUTH:', e);
+        authState = null;
+    } finally {
+        if (authState) launchSession(authState.token as string);
+        ipcEmit("set-profile", authState?.profile);
+    }
 
-    /* if secret, we launch a session */
-    if (newToken)
-    launchSession(newToken, profile);
-
-    /* finally, save the most recent token */
-    store.set("token", newToken);
-
-}
\ No newline at end of file
+}
index afebe5b2af6d5cb6aabf559144dbe3cdc29787fa..158c41ec704128bb233523f6e1dc2c362d6d5949 100644 (file)
@@ -2,24 +2,34 @@
 
 
 
-import useAudio from "@/audio";
-import Canvas from "@/composables/convas";
+// import useAudio from "@/audio";
 import ipcEmit from "@/composables/emitter";
+import useWebsockets from "./composables/websockets";
+import {config} from "@/config";
 
 /* data structure of messages that's tied to the UI */
-let msgrState: UIState | null = null;
+const uiState: any | null = null;
 
 /* start and stop audio functionality */
-const { initAudio, closeAudio } = useAudio();
+// const { initAudio, closeAudio } = useAudio();
+
+let isInitMessage: any;
+
+let deauthenticate: any;
+let isAddMessage: any
 
 /**
  * Controls for interfacing with the platform.
  * Takes an onMessage callback which we define below.
  */
-const { connect, send, close } = useWebsockets((content: any) => {
+
+
+const onMessageCallback = (message: string) => {
+
+    const content  = JSON.parse(message);
 
     /* if the platform fails to authenticate, we must back down */
-    if (content === "auth_error") {
+    if (content === "CLOSE_AUTH_FAIL") {
         deauthenticate();
         return;
     }
@@ -28,8 +38,8 @@ const { connect, send, close } = useWebsockets((content: any) => {
     if (isInitMessage(content)) {
         uiState.set(content);
     }
-    
-    
+
+
     else if (isAddMessage(content)) {
         uiState.add(content);
     }
@@ -37,10 +47,15 @@ const { connect, send, close } = useWebsockets((content: any) => {
     else {
         uiState.update(content);
     }
+}
+
+const onConnectionStatusCallback = (alive: boolean) => {
+    ipcEmit('connection-state', alive);
+}
 
-});
+const { connect, send, close } = useWebsockets(onMessageCallback, onConnectionStatusCallback);
 
-/* send a message to the platform */ 
+/* send a message to the platform */
 export function sendMessage(message: Message) {
 
     /* socket send */
@@ -48,24 +63,22 @@ export function sendMessage(message: Message) {
 
 }
 
+
 /* launch a new session (the main process for authenticated users) */
-export function launchSession(platformKey: string, crimata_id: string) {
+export function launchSession(platformKey: string) {
 
     /* connect to the platform */
-    connect(PLATFORM_URL, platformKey);
+    connect(config.PLATFORM_URL, platformKey);
 
     /* initialize the audio streams */
-    initAudio();
-
-    /* push profile to window */
-    if (win)
-    ipcEmit("update-auth", crimata_id);
+    // initAudio();
 
 }
 
+
 export function endSession() {
 
-    closeAudio();
+    // closeAudio();
 
     close();
 
index e8682b89f3a8fa207199a2b0d8755947f0258cfb..583371e598dd1890a8e231c0eba5999bcd559596 100644 (file)
@@ -1,3 +1,4 @@
+
 interface Message {
     text: boolean | string;
     context: boolean | string;
@@ -28,3 +29,25 @@ interface LoginPayload {
     email: string;
     password: string;
 }
+
+interface AuthState {
+    profile: Profile | null;
+    token: string  | null;
+}
+
+interface AccountCredentials {
+    email: string;
+    password: string;
+}
+
+interface IpcHandlerCallback<I, O> {
+    (payload: I | null): Promise<Error | O>;
+}
+
+interface IIpcHandler<I, O> {
+    handle(): void;
+    remove(): void;
+    readonly _handlerCallback: IpcHandlerCallback<I, O>;
+}
+
+
index 4c69387e6a195fb67bfc76883a7a43ba9936fae7..807064a38d82259961205ea308a577461ff56fb2 100644 (file)
@@ -1,10 +1,12 @@
 "use strict";
 
-import { BrowserWindow, ipcMain } from "electron";
+import { BrowserWindow, ipcMain, app } from "electron";
 import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
-import { backgroundMitt } from './coposables/emitter';
-import { saveToJson } from "./coposables/json";
+import { backgroundMitt } from './composables/emitter';
+import { saveToJson } from "./composables/json";
 import * as path from "path";
+import fs from 'fs';
+import { config } from "@/config";
 const { autoUpdater } = require('electron-updater');
 
 interface IpcRendererPayload {
@@ -19,8 +21,8 @@ const loadWinState = (fileName: string): WindowState => {
     let state: WindowState;
 
     try {
-        state = JSON.parse(fs.readFileSync(configPath + fileName).toString());
-    } 
+        state = JSON.parse(fs.readFileSync(config.configPath + fileName).toString());
+    }
 
     catch (error) {
         state = {
@@ -32,8 +34,8 @@ const loadWinState = (fileName: string): WindowState => {
     }
 
     return state
-    
-} 
+
+}
 
 // Called when a NavBar button is pressed.
 const onNavBar = (_event: any, action: string): void => {
@@ -110,8 +112,8 @@ export default async function createWindow(): Promise<void> {
     win = new BrowserWindow({
       width: winState.width,
       height: winState.height,
-      x: winState.x,
-      y: winState.y,
+      x: winState.x as number,
+      y: winState.y as number,
       resizable: true,
       backgroundColor: '#EBEBEB',
       frame: false,