]> Repos - mime-chat/commitdiff
upgrading auth functionality
authorAndrew Gundersen <gundersena@xavier.edu>
Tue, 23 Mar 2021 15:24:06 +0000 (10:24 -0500)
committerAndrew Gundersen <gundersena@xavier.edu>
Tue, 23 Mar 2021 15:24:06 +0000 (10:24 -0500)
12 files changed:
src/App.vue
src/background/audio.ts
src/background/handlers.ts
src/background/run.ts
src/background/session.ts
src/components/inputItem/controllers/audioCtrl.ts
src/components/settings.vue
src/main.ts
src/modules/auth.ts
src/modules/ws.ts
src/router.ts [deleted file]
src/views/login.vue

index c60eb6c247fed23e304aceeb1df875cae9c4cbc3..44c2a11a86359826fa8eedd8a1bb7d63ebb3f631 100644 (file)
@@ -15,8 +15,9 @@
       />
     </span>
 
-    <!-- Windows -->
-    <router-view/>
+    <!-- Main Pages -->
+    <Messenger v-if="auth"/>
+    <Login v-else />
 
   </div>
 
@@ -26,7 +27,7 @@
 </template>
 
 <script lang="ts">
-import { defineComponent, onMounted, onUnmounted, ref } from 'vue';
+import { defineComponent, onMounted, onUnmounted, ref } from "vue";
 import { useIpc } from "@/modules/ipc";
 import Splash from "@/components/splash.vue"
 
@@ -34,33 +35,48 @@ export default defineComponent({
   components: { Splash },
 
   setup() {
-    
 
-    // Show spash screen til true.
     const ready = ref(false);
 
-    const { invoke } = useIpc();
+    // Whether user is logged in.
+    let auth = ref(false);
+
+    // Attempt token login
+    const key = window.localStorage.getItem(AUTH_KEY);
+    
+    if (key) {
+      post("client-message", key)
+    }
+
+    // onAuthResponse
+    const onAuthResponse = (_event: IpcMainEvent, payload: Auth) => {
+      if (payload.token) {
+        auth.value = true;
+      }
+    }
 
     // Post navbar action to backend.
     const callNavbar = (action: string) => {
-      invoke('nav-bar', action);
+      post('nav-bar', action);
     }
 
-    const onWindowReady = (_event: any, _payload: any) => {
-      ready.value = true;
-    }
 
     onMounted(() => {
-        window.ipcRenderer.on("window-ready", onWindowReady);
+        window.ipcRenderer.on("auth-response", onAuthResponse)
+
+
+        window.ipcRenderer.on("window-ready", () => ready.value = true);
     });
 
     onUnmounted(() => {
         window.ipcRenderer.removeAllListeners("window-ready")
+        window.ipcRenderer.removeAllListeners("auth-response")
     })
 
     return {
         callNavbar,
-        ready
+        ready,
+        auth,
     }
   }
 })
index 5b0ef127d5e008ec221d3f5c2e5de09703dbebf0..02f0e622e1a7d845b2a9c0dcc4ef75a52a493c6e 100644 (file)
@@ -2,19 +2,24 @@
 
 "use strict";
 
-import { sendAudio } from './session'
 import { ipcMain } from "electron";
 import { backgroundMitt } from './emitter';
 
 const portAudio = require('naudiodon');
 
+// Audio in and out stream objects.
 let ai: typeof portAudio.AudioIO | null = null;
 let ao: typeof portAudio.AudioIO | null = null;
+
+// Whether activly recording.
 let record = false;
+
 const audioContainer = {
     input: '',
 }
+
 const encoding = "hex";
+
 const audioOptions = {
     channelCount: 1,
     sampleFormat: 16,
@@ -24,14 +29,15 @@ const audioOptions = {
 }
 
 // callback run on space bar key up and down.
-const updateRecorder = (_event, payload: {
-    isRecording: boolean;
-    uid: string | null;
+const updateRecorder = (_event, payload: { isRecording: boolean; uid: string | null;
+    
 }): void => {
+
     record = payload.isRecording;
     if (!record) {
         if (payload.uid) sendAudio(audioContainer.input, payload.uid);
     }
+
 };
 
 // listen for space key up/down event.
@@ -53,7 +59,7 @@ function bufSplit(buf: Buffer, len: number): Array<Buffer> {
     return chunks;
 }
 
-// main audio function run by run.ts module.
+// Main audio function run by run.ts module.
 export function initAudioIO(): void {
 
     if (!ai) {
@@ -79,7 +85,7 @@ export function initAudioIO(): void {
     }
 }
 
-// play audio buffers.
+// Audio playback.
 export function play(input: Buffer): void {
     let i = 0;
 
@@ -122,6 +128,7 @@ export function play(input: Buffer): void {
     }
 }
 
+// Get's called on window close.
 export function stopStream() {
     if(ai != null) {
         ai.quit();
index 4f3764b78c7b291aced100c9cd767796651094e4..4ba8b7ac404f8edcb12e5152a60abe4db1540972 100644 (file)
@@ -1,48 +1,24 @@
-import { backgroundMitt } from './emitter';
+import { backgroundMitt } from "./emitter";
+import { renderMessage } from "@/modules/message";
+import { Profile, StandardMessage, Annotation } from "@/types/message/index";
+import { play } from "./audio";
 
-// Attempt an authenticaion, either with Token or with Creds.
-const onAuthRequest = async (e: any, payload: string | Creds) => {
-
-    return new Promise((resolve, reject) => {
-
-        console.log('Authenticating...');
-
-        // Handle auth response from server.
-        backgroundMitt.once('auth-res', (res: string) => {
-
-            if (res == "locked") {
-                reject(res);
-            } else {
-                console.log('Success!');
-                auth = true;
-                resolve(res);
-            }
-
-        });
-
-        if (typeof payload !== "string") {
-            payload = JSON.stringify(payload)
-        }
-
-        // Send token to backend
-        socket.send(payload);
 
+export const handleAuthMessage = (message: string) => {
+    backgroundMitt.emit('ipc-renderer', {
+        endpoint: 'auth-response',
+        message: message
     });
-};
-
-
-const handleAuthMessage = (message: string) => {
-    backgroundMitt.emit('auth-res', message);
 }
 
-const handleProfileMessage = (message: Profile) => {
+export const handleProfileMessage = (message: Profile) => {
     backgroundMitt.emit('ipc-renderer', {
         endpoint: 'update-profile',
         message: message
     });
 }
 
-const handleStandardMessage = (m: StandardMessage) => {
+export const handleStandardMessage = (m: StandardMessage) => {
 
     // Create a render message object.
     const message = renderMessage(
@@ -61,7 +37,7 @@ const handleStandardMessage = (m: StandardMessage) => {
     });
 }
 
-const handleAnnotationMessage = (message: Annotation) => {
+export const handleAnnotation = (message: Annotation) => {
     backgroundMitt.emit('ipc-renderer', {
         endpoint: 'render-message',
         message: message 
index 4c312d87b0b7927d160aa8c67abf21fbea0a2ad5..1c60d3b0819c373d825164c659d8cc0c6a132b97 100644 (file)
@@ -1,27 +1,21 @@
 "use strict";
 
 import { createWindow } from './window';
-import useWebSockets from './session';
+import agentInterface from './session';
 import { initAudioIO } from './audio';
 
-let socket = false;
-
 /*
  * The main function will be run after electron app is ready.
  */
 export async function main() {
 
-    const { initSession } = useWebSockets()
+    const { initSession } = agentInterface()
 
     // create main window.
     await createWindow();
 
     // Instantiate socket session with crimata-platorm.
-    if (!socket) {
-        initSocketSession();
-    }
-
-    socket = true;
+    initSession();
 
     // Begin audio stream.
     initAudioIO();
index 28787f41765c7a6e2b3dbb6daddefa8ce13182c7..cb275da00b77ddb77f8216e1c22c04764fbe6aa6 100644 (file)
@@ -1,14 +1,17 @@
 import { backgroundMitt } from './emitter';
+import { ipcMain, IpcMainEvent } from "electron";
+
+import useWebSockets from "@/modules/ws";
 
 import { handleAuthMessage, handleStandardMessage, handleProfileMessage, handleAnnotation } from "./handlers";
 
 
-// Handle messages from server.
+// Calls appropriate endpoint for a server message.
 const onServerMessage = (data: string): void => {
     const message = JSON.parse(data)
 
     if (message.key) {
-        handleAuthMessage(message)
+        backgroundMitt.emit('auth-response', message);
     }
 
     else if (message.content) {
@@ -20,27 +23,26 @@ const onServerMessage = (data: string): void => {
     }
 
     else {
-        handleAnnotationMessage(message)
+        handleAnnotation(message)
     }
 
 };
 
+const { createSocket, sendMessage } = useWebSockets(onServerMessage);
+
 // Handle messages from client.
 const onClientMessage = (_event: IpcMainEvent, payload: any) {
     sendMessage(JSON.stringify(payload))
 }
 
+// Routes messages to and from Crimata Servers.
 export default function agentInterface() {
-
-    const { createSocket, sendMessage } = useWebSockets(onServerMessage)
  
     const initSession = () => {
 
         ipcMain.removeAllListeners()
-        ipcMain.removeHandler('auth-session');
 
-        ipcMain.handle('auth-request', onAuthRequest);
-        ipcMain.on('client-message', onClientMessage);
+        ipcMain.on("client-message", onClientMessage);
 
         createSocket()
     }
@@ -49,117 +51,4 @@ export default function agentInterface() {
         initSession
     }
 
-}
-
-    
-
-
-
-
-
-
-
-
-
-
-
-
-
-// Attempt an authenticaion, either with Token or with Creds.
-const onAuthRequest = async (e: any, payload: string | Creds) => {
-
-    return new Promise((resolve, reject) => {
-
-        console.log('Authenticating...');
-
-        // Handle auth response from server.
-        backgroundMitt.once('auth-res', (res: string) => {
-
-            if (res == "locked") {
-                reject(res);
-            } else {
-                console.log('Success!');
-                auth = true;
-                resolve(res);
-            }
-
-        });
-
-        if (typeof payload !== "string") {
-            payload = JSON.stringify(payload)
-        }
-
-        // Send token to backend
-        socket.send(payload);
-
-    });
-};
-
-
-const handleAuthMessage = (message: string) => {
-    backgroundMitt.emit('auth-res', message);
-}
-
-const handleProfileMessage = (message: Profile) => {
-    backgroundMitt.emit('ipc-renderer', {
-        endpoint: 'update-profile',
-        message: message
-    });
-}
-
-const handleStandardMessage = (m: StandardMessage) => {
-
-    // Create a render message object.
-    const message = renderMessage(
-        m.content.text, m.content.audio, m.context, m.modifier);
-
-    // Play audio if any.
-    if (message.content.audio) {
-        const audioBytes = Buffer.from(m.content.audio as string, 'hex');
-        m.content.audio = true;
-        play(audioBytes);
-    }
-
-    backgroundMitt.emit('ipc-renderer', {
-        endpoint: 'render-message',
-        message: message 
-    });
-}
-
-const handleAnnotationMessage = (message: Annotation) => {
-    backgroundMitt.emit('ipc-renderer', {
-        endpoint: 'render-message',
-        message: message 
-    });
-}
-
-const onMessage = (messageStr: string): void => {
-
-    // Auth messages are strings.
-    if (!auth) {
-        handleAuthMessage(messageStr)
-        return
-    }
-
-    const message = JSON.parse(messageStr)
-    console.log("New message:")
-    console.log(message)
-
-    if (message.content) {
-        handleStandardMessage(message)
-    }
-
-    else if (message.first) {
-        handleProfileMessage(message)
-    }
-
-    else {
-        handleAnnotationMessage(message)
-    }
-
-};
-
-const onClientMessage = (e: any, payload: ClientMessage): void => {
-    console.log('sending message');
-    socket.send(JSON.stringify(payload));
 }
\ No newline at end of file
index 9b2df9fab39103f52d56ed50a8d07e085dfae007..dc090466ea2ade081e6d4cff27833e34b6517230 100644 (file)
@@ -72,7 +72,7 @@ export default function useAudioInputController (typing: Ref) {
             const message = renderMessage("", "", "", "sf")
             emitter.emit("self-message", message);
 
-            post('update-recorder', {
+            const audio = invoke('update-recorder', {
                 isRecording: false,
                 uid: message.uid
             });
index cb1d1a561902cccb85cf4ee26c515c2d6f88cbaa..997c26323f91bc9c57e909db2a8dc59f3b440db1 100644 (file)
         window.addEventListener("keydown", onEscape);
       }
 
-      // When user clicks logout button in settings.
+      // We ask server to log us out.
       const onLogout = () => {
-        logout();
-        router.push({ name: "login" });
-        post("logout", "")
-      } 
+        post("auth-request", "logout")
+      }
 
       return {
         onActive, 
         toggleSettings,
         onLogout
       }
-    }   
+    }
   })
 
 </script>
index fcad020b0aa415a993194d941694817d55c2938e..35774f707853e425c089339c4d0fa8b35bd8a65e 100644 (file)
@@ -1,7 +1,6 @@
 // src/main.ts
 
 import App from "./App.vue";
-import router from "./router";
 
 import mitt from "mitt";
 import { createApp } from "vue";
@@ -12,6 +11,5 @@ const emitter = mitt();
 
 const app = createApp(App)
 
-app.use(router)
 app.provide("mitt", emitter)
 app.mount("#app");
index 3430cf220156b8614b74e794eebad52e02c3c983..b095034bf074b4aeccef2afa9952518f2f98daaa 100644 (file)
@@ -21,7 +21,7 @@ if (token) {
     window.localStorage.setItem(AUTH_KEY, token);
 }
 
-// Load key and invoke onAuthSession to try key-login.
+// Token authentication.
 const authToken = async () => {
     console.log("Calling auth token!!")
     const { invoke  } = useIpc();
index c4875739ba7d743c2d128dab902bfbf89cad586c..6a6594b47512e41492430f4a6a9ba3e1b512ce51 100644 (file)
@@ -7,7 +7,7 @@ let socket: WebSocket;
 
 
 // Run every time we want to connect to backend.
-export default function useWebSockets(receiveCallback: (s: Buffer) => any) {
+export default function useWebSockets(receiveCallback: (s: string) => any) {
 
     const sendMessage = (data: string) => {
 
@@ -27,14 +27,15 @@ export default function useWebSockets(receiveCallback: (s: Buffer) => any) {
 
         console.log('Message received: ', event);
 
-        receiveCallback(event.data)
+        receiveCallback(event.data.toString())
 
     }
 
     const onClose = (event: WebSocket.CloseEvent) => {
-        console.log("socket closed normally.")
+        console.log("Socket closed normally.")
     }
 
+    // Reconnect automatically on error.
     const onError = (event: WebSocket.ErrorEvent) => {
         console.log('WebSocket error: ', event);
 
@@ -55,76 +56,8 @@ export default function useWebSockets(receiveCallback: (s: Buffer) => any) {
     }
 
     return {
-        createSocket
+        createSocket,
+        sendMessage
     }
 
-}
-
-
-
-
-
-
-
-
-    // Close existing sockets.
-    if (socket) {
-        socket.removeAllListeners();
-        socket.terminate();
-        socket.close();
-        success = false;
-    }
-
-    // Init new socket.
-    socket = new WebSocket(`ws://127.0.0.1:8760`);
-    socket.binaryType = 'arraybuffer';
-
-    // Handle requests for authentication (promise).
-    ipcMain.removeHandler('auth-session'); // avoid setting duplicate handlers
-    ipcMain.handle('auth-session', onAuthSession);
-
-    // handle user message event
-    ipcMain.removeAllListeners('client-message');
-    ipcMain.on('client-message', onClientMessage);
-
-    // handle renderer logout event
-    ipcMain.removeAllListeners('logout');
-    ipcMain.on('logout', (_event, _payload: string) => restart());
-
-    // Connect to the backend.
-    socket.on('open', () => {
-        console.log('Connected to Crimata Servers.');
-
-        // Try to authenticate token right away.
-        backgroundMitt.emit('ipc-renderer', {
-            endpoint: 'auth',
-            message: null
-        });
-
-        success = true;
-
-    });
-
-    // Error handling.
-    socket.on('error', (_e) => {
-
-        console.log('ERROR: Failed to connect.');
-        socket.removeAllListeners();
-        socket.close();
-
-        setTimeout(() => {
-            if (!success) {
-                console.log('Reconnecting...');
-                initSession();
-            }
-        }, 3000); // reconnect timeout
-
-    });
-
-    socket.on('close', () => {
-        console.log('Connection droped! Restarting...');
-        restart();
-    });
-
-    socket.on("message", onMessage);
 }
\ No newline at end of file
diff --git a/src/router.ts b/src/router.ts
deleted file mode 100644 (file)
index ee94a61..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-import {
-  createRouter,
-  createWebHistory,
-  createWebHashHistory,
-  RouteRecordRaw
-} from "vue-router";
-import Home from "@/views/messenger.vue";
-import { useAuth } from '@/modules/auth';
-
-// Define the routes (/*) for the app here.
-const routes: Array<RouteRecordRaw> = [
-  {
-    path: "/",
-    name: "home",
-    component: Home,
-    meta: { requiresAuth: true },
-  },
-  {
-    path: "/login",
-    name: "login",
-    component: () => import("@/views/login.vue"),
-    meta: { requiresAuth: false },
-  },
-  {
-    path: "/register",
-    name: "register",
-    component: () => import("@/views/register.vue"),
-    meta: { requiresAuth: false },
-  },
-];
-
-const router = createRouter({
-  history: process.env.IS_ELECTRON ? createWebHashHistory() : createWebHistory(process.env.BASE_URL),
-  routes
-});
-
-// route auth check
-router.beforeEach((to, from, next) => {
-  const { accessToken } = useAuth();
-
-  // Not logged into a guarded route?
-  if (to.meta.requiresAuth && !accessToken.value) {
-      next({ name: 'login' })
-  }
-
-  // Logged in for an auth route
-  else if ((to.name == 'login' || to.name == 'register') && accessToken.value){
-      next({ name: 'home' });
-  }
-
-  // Carry On...
-  else next();
-})
-
-export default router;
index 53e335fc94b30994c03ce880ad150fc0ad484589..5f31fbd05da9c5bdcfe98063b35fc3e334348740 100644 (file)
@@ -24,7 +24,7 @@
     </div>
 
     <!-- submit button; position: fixed -->
-    <button class="submitButton button" type="submit">Submit</button>
+    <button class="submitButton button" type="submitForm">Submit</button>
 
     <div class="invalid" v-if="invalid">
         Incorrect Credentials
@@ -48,57 +48,31 @@ export default defineComponent({
 
   setup() {
 
+    const { post } = useIpc();
     const { setToken } = useAuth();
     const { resetMessages } = useMessages();
-    const router = useRouter();
-
-    const email = ref("");
-    const password = ref("");
-    const invalid = ref(false);
-
-    const { invoke } = useIpc();
-
-    const submit = async () => {
-
-        const payload = {
-          request: "login",
-          email: email.value,
-          password: password.value
-        };
-
-        try {
-            const response = await invoke('auth-session', payload);
 
-            // On login without token, we clear localStorage and messages.
-            window.localStorage.clear();
-            resetMessages();
-
-            setToken(response);
-            invalid.value = false;
-            router.push({ name: "home" });
-        } 
-
-        catch(e) {
-            invalid.value = true;
-            console.log('Error loging in.');
-        }
+    const router = useRouter();
 
-    };
+    const form = ref({
+      email: "",
+      password: "",
+    })
 
-    const switchView = () => {
-      router.push({ name: "register" });
-    };
+    // Submit login credentials to the backend.
+    const submitForm = () => {
+      post("auth-message", form)
+    }
 
     return {
-      submit,
-      email,
-      password,
-      switchView,
-      invalid
+      form,
+      submitForm
     }
 
   },
+
 });
+
 </script>
 
 <style lang="scss" scoped>