]> Repos - mime-chat/commitdiff
add authenticate on socket connect
authorEnrique Hernandez <enrique.hernandez@fii-usa.com>
Tue, 9 Feb 2021 23:07:45 +0000 (17:07 -0600)
committerEnrique Hernandez <enrique.hernandez@fii-usa.com>
Tue, 9 Feb 2021 23:09:11 +0000 (17:09 -0600)
src/background/run.ts
src/background/session.ts
src/modules/auth.ts
src/modules/ipc.ts
src/modules/socket.ts [new file with mode: 0644]
src/views/login.vue
testServer.js

index 4c2404a32ffb9797363b19d04d253eec3a52c1f0..b8af00290b1e5d08fa74a22732e233aca734a508 100644 (file)
@@ -14,12 +14,6 @@ interface ipcRendererPayload {
  */
 export function main(): void {
 
-    // Instantiate socket session with crimata-platorm.
-    initSession();
-
-    // mount auth-user listener
-    ipcMain.on('auth-user', authUser);
-
     // create main window.
     const win = createWindow({ width: 350, height: 525, resizable: false });
 
@@ -34,18 +28,17 @@ export function main(): void {
     }
 
     const windowMount = (): void => {
+        // Instantiate socket session with crimata-platorm.
+        initSession();
         windowEmitter.emit('window-active', true);
-        // ipc event handlers
         ipcMain.on('send-message', handleMessage);
         ipcMain.on('auth-login', authLogin);
     }
 
     const windowDismount = (): void => {
          windowEmitter.emit('window-active', false);
-        // TODO: Gracefully close socket connection
          ipcMain.removeAllListeners('send-message');
          ipcMain.removeAllListeners('auth-login');
-         ipcMain.removeAllListeners('auth-user');
     }
 
     // Handle window mount and dismount.
index 55d30b05b1c02c736ea5130982ed2df6521ad36d..4612757592cb82d2f21ebbc23bda0c3c2dc29d90 100644 (file)
@@ -1,5 +1,6 @@
 import WebSocket from 'ws';
 import { windowEmitter } from './windowEmitter';
+import { ipcMain  } from "electron";
 
 type Message = {
     type: string;
@@ -14,85 +15,87 @@ interface RenderMessage  extends Message  {
   time: string;
 }
 
-interface AuthMessage extends Message  {
+interface AuthUser extends Message  {
     email: string;
     firstName: string;
     lastName: string;
     access_token: string;
 }
 
-interface AuthRequest {
-    token: string;
-}
-
-interface PostLogin {
-    email: string;
-    password: string;
-}
-
-interface PostMessage {
-    content: string;
-}
-
 const ip = 'ws://localhost';
 const port = 8080;
-const username = 'hernandeze2@xavier.edu';
+const reconnectTimeout = 3000; //ms
 let socket: WebSocket;
+let success = false;
 
 const receiveMessage = (message: string): void => {
   // NOTE assuming message is JSON string
-  const parsed: RenderMessage | AuthMessage  = JSON.parse(message);
+  if (message === 'locked') {
+      windowEmitter.emit('auth-resp', message);
+      return;
+  }
+  const parsed: RenderMessage | AuthUser  = JSON.parse(message);
   if (parsed.type === "render") {
     windowEmitter.emit('ipc-renderer', {
         endpoint: 'render-message',
         message: parsed
     });
-  } else if (parsed.type === "auth") {
-      windowEmitter.emit('auth-resp', parsed);
   }
 }
 
-// Connect and send username
+const authToken = async (event: any, token: string): Promise<string | AuthUser > => {
+    return new Promise((resolve, reject) => {
+        console.log('authenticating...');
+        windowEmitter.on('auth-resp', (arg: string | AuthUser) => {
+            if (arg === 'locked') {
+                reject(arg);
+            }
+            resolve(arg);
+        });
+        if (token) {
+            socket.send(token);
+        } else {
+            socket.send('no-token');
+        }
+    });
+};
+
+// Connect and authenticate
 export function initSession() {
 
-    let success = false;
     socket = new WebSocket(`${ip}:${port}`);
     socket.binaryType = 'arraybuffer';
 
     socket.on('open', () => {
         console.log('Connected to crimata-platform');
-        socket.send(username);
         success = true;
+
+        // handle renderer auth-token event
+        ipcMain.removeHandler('auth-token'); // avoid setting duplicate handlers
+        ipcMain.handle('auth-token', authToken);
+
+        // fetch token from renderer
+        windowEmitter.emit('ipc-renderer', {
+            endpoint: 'fetch-token',
+            message: null
+        });
+
     })
 
     socket.on("message", receiveMessage);
 
     setTimeout(()=> {
         if (!success) {
-            throw new Error('Unable to connect to crimata-platform')
+            // initSession();
+            throw new Error('Unable to connect to crimata-platform');
         }
-    }, 3000)
-}
-
-export const authUser = (event: any, arg: AuthRequest) => {
-    console.log('sending token to socket', arg)
-    try {
-        sendMessage({
-            content: arg.token
-        });
-        windowEmitter.on('auth-resp', (payload: AuthMessage) => {
-            event.reply('auth-user-reply', payload);
-        })
-    } catch(e){
-        console.log('Error authenticating user! ' + e);
-        event.reply('auth-user-reply', e);
-    }
+    }, reconnectTimeout);
 }
 
-export const authLogin = (event: any, arg: PostLogin) => {
+export const authLogin = (event: any, arg: any) => {
     try {
         sendMessage(arg)
-        windowEmitter.on('auth-resp', (payload: AuthMessage) => {
+        windowEmitter.on('auth-resp', (payload: AuthUser) => {
             event.reply('auth-login-reply', payload);
         })
     } catch(e) {
@@ -101,10 +104,10 @@ export const authLogin = (event: any, arg: PostLogin) => {
     }
 }
 
-export const sendMessage = (content: PostMessage | Buffer | PostLogin) => {
+export const sendMessage = (content: string | Buffer) => {
     if (content instanceof Buffer) {
         socket.send(content);
-    } else {
+    } else if (content){
         socket.send(JSON.stringify(content));
     }
 }
index 16be95c6ab2e13ede2c594355656d5442335b08e..ec8e4447a7bbd1342966ac5a0caed4ec92a5930b 100644 (file)
@@ -24,10 +24,23 @@ const state = reactive<AuthState>({
 const AUTH_KEY = 'crimata_token';
 
 const token = window.localStorage.getItem(AUTH_KEY);
-console.log('token: ',token)
+
+// authenticate on socket connect
+window.ipcRenderer.on("fetch-token", async (event, payload) => {
+    const { data, invoke  } = useIpc('auth-token');
+    try {
+        await invoke(token);
+        state.user = data.value;
+    }
+    catch(e) {
+        state.error = e;
+        console.log('ERROR: failed authentication');
+        window.localStorage.removeItem(AUTH_KEY);
+    }
+});
 
 if (token) {
-    const { loading, error, data, send } = useIpc('auth-user');
+    const { loading, error, data, send, invoke  } = useIpc('auth-user');
 
     state.authenticating = true;
 
index aebe9034fce1abf59b2b184c4e6d76448b2c00b9..dbf191bd27e2f089297074fbaf3522ceb30e91c1 100644 (file)
@@ -13,6 +13,20 @@ export const useIpc = (endpoint: string) => {
         }
     })
 
+    const invoke = (payload: any) => {
+        loading.value = true;
+        error.value = undefined;
+
+        return window.ipcRenderer.invoke(endpoint, payload).then(res => {
+            data.value = res;
+        }).catch(e => {
+            error.value = e;
+            throw e;
+        }).finally(() => {
+            loading.value = false;
+        })
+    }
+
     const send = (payload?: Record<string, any>, callback?: (arg: any) => void) => {
         loading.value = true;
         error.value = undefined;
@@ -46,6 +60,7 @@ export const useIpc = (endpoint: string) => {
         data,
         error,
         errorMessage,
-        send
+        send,
+        invoke
     }
 }
diff --git a/src/modules/socket.ts b/src/modules/socket.ts
new file mode 100644 (file)
index 0000000..07f3dbb
--- /dev/null
@@ -0,0 +1,17 @@
+interface SocketState {
+    connection: WebSocket | null;
+    auth: boolean;
+}
+
+// Create WebSocket connection.
+const socket = new WebSocket('ws://localhost:8080');
+
+// Connection opened
+socket.onopen = function (event) {
+    socket.send('Hello Server!');
+}
+
+socket.onmessage = function(event) {
+  console.debug("WebSocket message received:", event);
+}
+
index a887bf1c64bd732224584458a0636c26e1136d1e..185b2311f38cae781ad94af8b3529237d5d69a27 100644 (file)
@@ -41,24 +41,21 @@ export default defineComponent({
       rememberMe: true,
     });
 
-    const { loading, data, send, errorMessage } = useIpc("auth-login");
+    //const { loading, data, send, errorMessage } = useIpc("auth-login");
 
+    const { loading, error, data,  invoke, errorMessage  } = useIpc('test');
     const submit = async () => {
       // console.log(toRefs(payload));
-      send({
-        request: "register",
-        email: payload.email,
-        password: payload.password,
-      });
-      console.log(data.value, "login");
+        await invoke({
+            request: "register",
+            email: payload.email,
+            password: payload.password,
+            })
+        console.log('testing incoke', data.value.test)
+        // setUser(data.value, payload.rememberMe);
+        router.push({ name: "home" });
     };
 
-    watch(loading, () => {
-      console.log(data.value)
-      setUser(data.value, payload.rememberMe);
-      router.push({ name: "home" });
-    });
-
     return {
       loading,
       submit,
index 6c8fbc852060b80b6613d5d480172dd1e0868a6e..3d9864f4547c33b76a3b3c1802767b337d6214a3 100644 (file)
@@ -14,12 +14,16 @@ const wss = new WebSocket.Server({
 
 wss.on("connection", function connection(ws, req) {
   ws.on("message", function incoming(message) {
+
     console.log(message)
-    // const parsed = JSON.parse(message)
-    //   console.log(parsed)
+      if (message === 'no-token') {
+          console.log('no token to authenticate');
+          ws.send('locked');
+      }
+
   });
 
   const ip = req.socket.remoteAddress;
   console.log("received connection from", ip);
-  ws.send(JSON.stringify(testMessage));
+  // ws.send(JSON.stringify(testMessage));
 });