]> Repos - mime-chat/commitdiff
add login, register, and auth
authorriqo <hernandeze2@xavier.edu>
Mon, 8 Feb 2021 15:43:29 +0000 (09:43 -0600)
committerriqo <hernandeze2@xavier.edu>
Mon, 8 Feb 2021 15:43:29 +0000 (09:43 -0600)
17 files changed:
src/background/audio.ts [new file with mode: 0644]
src/background/run.ts
src/background/user.ts [new file with mode: 0644]
src/components/home/messageBubble/index.vue
src/components/home/messageVisualizer/index.vue
src/components/taInput/inputController.ts
src/modules/auth.ts [new file with mode: 0644]
src/modules/ipc.ts [new file with mode: 0644]
src/modules/keyDownHandler/keyBoardMaps/keyboardCharMap.ts [moved from src/composables/keyDownHandler/keyBoardMaps/keyboardCharMap.ts with 100% similarity]
src/modules/keyDownHandler/keyBoardMaps/keyboardNameMap.ts [moved from src/composables/keyDownHandler/keyBoardMaps/keyboardNameMap.ts with 100% similarity]
src/modules/keyDownHandler/useKeyDownHandler.ts [moved from src/composables/keyDownHandler/useKeyDownHandler.ts with 100% similarity]
src/modules/mediaStream.ts [moved from src/composables/mediaStream.ts with 100% similarity]
src/modules/scrollView.ts [moved from src/composables/scrollView.ts with 100% similarity]
src/modules/textWrap.ts [moved from src/composables/textWrap.ts with 100% similarity]
src/router.ts
src/views/login.vue
src/views/register.vue

diff --git a/src/background/audio.ts b/src/background/audio.ts
new file mode 100644 (file)
index 0000000..3ce3d89
--- /dev/null
@@ -0,0 +1,49 @@
+const portAudio = require('naudiodon');
+
+let audioInput: string[] = [];
+
+function processAudio(audioInput: Array<string>): Buffer {
+    let audio = '';
+    audioInput.forEach(chunk => audio += chunk);
+    return  Buffer.from(audio, "base64");
+}
+
+
+const updateRecorder = async (Event: any, record: boolean): void => {
+  if (record) {
+      ia.resume();
+  } else {
+      ia.pause();
+      const audio = processAudio(audioInput);
+      // emmit ws event with audio
+      // sendAudio(audio);
+      audioInput = [];
+  }
+}
+
+
+let ia = new portAudio.AudioIO({
+  inOptions: {
+    channelCount: 1,
+    sampleFormat: 16,
+    sampleRate: 16000,
+    deviceId: -1,
+    closeOnError: false,
+  }
+});
+ia.setEncoding('base64');
+ia.start();
+ia.pause();
+ia.on('error', (e: Error) => {
+    console.log('Error recording audio', + e);
+});
+ia.on('data', (chunk: string) => {
+  audioInput.push(chunk);
+});
+
+export function useIA() {
+    return {
+        ia,
+        processAudio
+    }
+}
index 767db2a0c14bdce41dee1c95d5938ce71f005abd..49ccacaba1e3588a8ed112767d2d9b5a3fb44bf7 100644 (file)
@@ -1,6 +1,5 @@
 import { createWindow } from './createWindow';
-import { Recorder } from './recorder';
-import { ipcMain, BrowserWindow } from "electron";
+import { ipcMain  } from "electron";
 import WebSocket from 'ws';
 import { windowEmitter } from './windowEmitter';
 const portAudio = require('naudiodon');
@@ -12,6 +11,27 @@ export function main(): void {
 
     let audioInput: string[] = [];
 
+    const authUser = (event: any, arg: any) => {
+        let reply;
+        reply = {
+            id: "2",
+            email: "hernandeze@xavier.edu",
+            firstName: "Enrique",
+            lastName: "Hernandez",
+            access_token: "test-token"
+        }
+        if (arg === ['undefined']) {
+            reply = new Error('AUTH-FAILED');
+        }
+        event.reply('auth-user-reply', reply)
+    }
+    ipcMain.on('auth-user', authUser);
+
+    const authLogin = (event: any, arg: any) => {
+        console.log(arg)
+        event.reply('auth-login-reply', true)
+    }
+
     // create main window.
     const win = createWindow({ width: 350, height: 525, resizable: false });
 
@@ -44,19 +64,16 @@ export function main(): void {
           ia.resume();
       } else {
           ia.pause();
-          const audio = processAudio();
+          const audio = processAudio(audioInput);
           sendAudio(audio);
           audioInput = [];
       }
     }
 
-    function processAudio(): Buffer {
+    function processAudio(audioInput: Array<string>): Buffer {
         let audio = '';
-        audioInput.forEach(s => {
-            audio += s;
-        });
-        const buffer = Buffer.from(audio, "base64");
-        return buffer;
+        audioInput.forEach(chunk => audio += chunk);
+        return  Buffer.from(audio, "base64");
     }
 
     const windowMount = (): void => {
@@ -64,13 +81,16 @@ export function main(): void {
         // ipc event handlers
         ipcMain.on('update-recorder', updateRecorder);
         ipcMain.on('send-message', sendMessage);
+        ipcMain.on('auth-login', authLogin);
     }
 
     const windowDismount = (): void => {
          windowEmitter.emit('window-active', false);
         // TODO: Gracefully close socket connection
-         ipcMain.removeListener('update-recorder', updateRecorder);
-         ipcMain.removeListener('send-message', sendMessage);
+         ipcMain.removeAllListeners('update-recorder');
+         ipcMain.removeAllListeners('send-message');
+         ipcMain.removeAllListeners('auth-login');
+         ipcMain.removeAllListeners('auth-user');
     }
 
     // socket handlers
@@ -92,12 +112,11 @@ export function main(): void {
     });
     ia.setEncoding('base64');
     ia.start();
+    ia.pause();
     ia.on('error', (e: Error) => {
-        console.log('error recording audio', + e);
+        console.log('Error recording audio', + e);
     });
-    ia.pause();
     ia.on('data', (chunk: string) => {
       audioInput.push(chunk);
-      console.log('Got %d characters of string data:', chunk.length);
     });
 }
diff --git a/src/background/user.ts b/src/background/user.ts
new file mode 100644 (file)
index 0000000..1258257
--- /dev/null
@@ -0,0 +1,22 @@
+
+const authUser = (event: any, arg: any) => {
+    let reply;
+    reply = {
+        id: "2",
+        email: "hernandeze@xavier.edu",
+        firstName: "Enrique",
+        lastName: "Hernandez",
+        access_token: "test-token"
+    }
+    if (arg === ['undefined']) {
+        reply = new Error('AUTH-FAILED');
+    }
+    event.reply('auth-user-reply', reply)
+}
+
+ipcMain.on('auth-user', authUser);
+
+const authLogin = (event: any, arg: any) => {
+    console.log(arg)
+    event.reply('auth-login-reply', true)
+}
index cd9ecd19aa1218d551ba4ecbca77a9e440b3a2ca..03041b11bac8ebf37ef159bf9cf8be43138874b3 100644 (file)
@@ -31,7 +31,7 @@ import useComputedBubble from "./bubbleDetails/computed";
 import useBubbleDrawer from "./bubbleDetails/drawer";
 
 // text wrap composition
-import useTextWrap from "@/composables/textWrap";
+import useTextWrap from "@/modules/textWrap";
 
 import { defineComponent, onMounted, ref, reactive } from "vue";
 export default defineComponent({
index 36db2cc321f9d000f9cf79a837fe2442ddaa71d0..897285d9d1d959aa5293e23785b7ffc049517dcb 100644 (file)
 
 <script lang="ts">
 import useMessageVisualizer from "./viewDetails/visualizer";
-
-import useScrollView from "@/composables/scrollView";
-
+import useScrollView from "@/modules/scrollView";
 import MessageItem from "../messageBubble/index.vue";
-
 import { Message } from "@/types/message/index";
-
 import { Mitt } from "@/types/mitt/index";
 import { defineComponent, reactive, inject } from "vue";
+
 export default defineComponent({
   name: "MessageVisualizer",
   components: { MessageItem },
index 9a83a0cfa8b81d0f29f805aa519163bb004f27bd..fd89d2eb5d4e300223eee84f542e44800d914b4f 100644 (file)
@@ -1,11 +1,7 @@
 import { ref, watch, onUnmounted, onMounted } from "vue";
-
-import useKeyDownHandler from "@/composables/keyDownHandler/useKeyDownHandler";
-
-import useMediaStream from "@/composables/mediaStream";
-
+import useKeyDownHandler from "@/modules/keyDownHandler/useKeyDownHandler";
+import useMediaStream from "@/modules/mediaStream";
 import useAudioVisualizer from './audioDetails/audioVisualizer';
-
 import useTextVisualizer from './textDetails/textVisualizer';
 
 /*
diff --git a/src/modules/auth.ts b/src/modules/auth.ts
new file mode 100644 (file)
index 0000000..92f84fc
--- /dev/null
@@ -0,0 +1,70 @@
+import { reactive, watch, toRefs } from 'vue';
+import { useIpc } from './ipc';
+
+interface User {
+    id: string;
+    email: string;
+    firstName: string;
+    lastName: string;
+    access_token: string;
+}
+
+interface AuthState {
+    authenticating: boolean;
+    user?: User;
+    error?: Error;
+}
+
+const state = reactive<AuthState>({
+    authenticating: false,
+    user: undefined,
+    error: undefined,
+});
+
+const AUTH_KEY = 'crimata_token';
+
+const token = window.localStorage.getItem(AUTH_KEY);
+
+if (token) {
+    const { loading, error, data, send } = useIpc('auth-user');
+
+    state.authenticating = true;
+
+    // authenticate token against crimata-platform
+    send([token]);
+
+    watch([loading], () => {
+        if (error.value) {
+            console.log('ERROR: failed authentication')
+            window.localStorage.removeItem(AUTH_KEY);
+        }
+        else if (data.value) {
+            state.user = data.value;
+        }
+
+        state.authenticating = false;
+    })
+}
+
+export const useAuth = () => {
+    const setUser = (payload: User, remember: boolean) => {
+        if (remember) {
+            // Save
+            window.localStorage.setItem(AUTH_KEY, payload.access_token);
+        }
+
+        state.user = payload;
+        state.error = undefined;
+    }
+
+    const logout = (): Promise<void> => {
+        window.localStorage.removeItem(AUTH_KEY);
+        return Promise.resolve(state.user = undefined);
+    }
+
+    return {
+        setUser,
+        logout,
+        ...toRefs(state), // authenticating, user, error
+    }
+}
diff --git a/src/modules/ipc.ts b/src/modules/ipc.ts
new file mode 100644 (file)
index 0000000..7f7d0a9
--- /dev/null
@@ -0,0 +1,54 @@
+import { ref, computed } from 'vue'
+
+export const useIpc = (endpoint: string) => {
+    const data = ref();
+    const loading = ref(false);
+    const error = ref();
+    const listener = ref(false);
+
+    const errorMessage = computed(() => {
+        console.log('ERROR', error.value);
+        if (error.value) {
+            return error.value.message
+        }
+    })
+
+    const send = (payload?: Record<string, any>, callback?: (arg: any) => void) => {
+        loading.value = true;
+        error.value = undefined;
+
+        window.ipcRenderer.on(endpoint + '-reply', (event: any, arg: any | Error) => {
+            if (arg instanceof Error) {
+                error.value = arg;
+                throw arg;
+            } else {
+                if (callback) {
+                    callback(arg);
+                }
+                data.value = arg;
+                loading.value = false;
+            }
+        });
+        window.ipcRenderer.send(endpoint, payload);
+    };
+
+    const onEvent = (callback: (event: any, arg: any) => void) => {
+        listener.value = true;
+        window.ipcRenderer.on(endpoint, callback);
+    };
+
+    const post = (payload?: Record<string, any>) => {
+        window.postMessage({
+            myTypeField: endpoint,
+            message: payload
+        }, '*')
+    };
+
+    return {
+        loading,
+        data,
+        error,
+        errorMessage,
+        send
+    }
+}
index 9e4c6d39cb37b388aae20b321a152ecae7f1d76d..30c92b2f5206827ba4733381c97045841eac8a33 100644 (file)
@@ -1,35 +1,32 @@
-import { 
-    createRouter, 
-    createWebHistory, 
-    createWebHashHistory, 
-    RouteRecordRaw 
+import {
+  createRouter,
+  createWebHistory,
+  createWebHashHistory,
+  RouteRecordRaw
 } from "vue-router";
-
-import Home from "./views/home.vue";
-import Login from "./views/login.vue";
-import Splash from "./views/splash.vue";
+import Home from "@/views/home.vue";
+import { useAuth } from '@/modules/auth';
 
 // Define the routes (/*) for the app here.
 const routes: Array<RouteRecordRaw> = [
-
   {
-    path: "/sdf",
-    name: "Splash",
-    component: Splash
+    path: "/",
+    name: "home",
+    component: Home,
+    meta: { requiresAuth: true },
   },
-
   {
-    path: "/sdf",
-    name: "Home",
-    component: Home
+    path: "/login",
+    name: "login",
+    component: () => import("@/views/login.vue"),
+    meta: { requiresAuth: false },
   },
-
   {
-    path: "/",
-    name: "Login",
-    component: Login
+    path: "/register",
+    name: "register",
+    component: () => import("@/views/register.vue"),
+    meta: { requiresAuth: false },
   },
-
 ];
 
 const router = createRouter({
@@ -37,4 +34,17 @@ const router = createRouter({
   routes
 });
 
-export default router;
\ No newline at end of file
+router.beforeEach((to, from, next) => {
+  const { user } = useAuth();
+
+  // Not logged into a guarded route?
+  if (to.meta.requiresAuth && !user?.value) next({ name: 'login' });
+
+  // Logged in for an auth route
+  else if ((to.name == 'login' || to.name == 'register') && user!.value) next({ name: 'home' });
+
+  // Carry On...
+  else next();
+})
+
+export default router;
index 5d6954ef9769f91a902cca27b4792a7adc95d798..83d1a89771883138f526c6c0185b7b559ad3e3fb 100644 (file)
 <template>
-    <LoginComponent />
+  <form id="login" @submit.prevent="submit">
+    <!-- login title -->
+    <div id="loginTitle">Crimata Messenger</div>
+
+    <!-- username and password forms -->
+    <div id="loginBox">
+      <!-- username -->
+      <input class="input" type="text" v-model="email" placeholder="username" />
+
+      <!-- password -->
+      <input class="input" type="password" v-model="password" placeholder="Password" />
+    </div>
+
+    <!-- submit button -->
+    <button class="button" type="submit">Login</button>
+  </form>
 </template>
 
 <script lang="ts">
+import { defineComponent, toRefs, reactive, watch } from "vue";
+import { useAuth } from "@/modules/auth";
+import { useIpc } from "@/modules/ipc";
+import { useRouter } from "vue-router";
 
-import { defineComponent } from "vue";
-import LoginComponent from "@/components/login/index.vue";
+interface LoginPayload {
+  email: string;
+  password: string;
+  rememberMe: boolean;
+}
 
 export default defineComponent({
-
   name: "Login",
-  components: { LoginComponent },
+  setup() {
+    const { setUser, user } = useAuth();
+    const router = useRouter();
+
+    const payload = reactive<LoginPayload>({
+      email: "",
+      password: "",
+      rememberMe: true,
+    });
+
+    const { loading, data, send, errorMessage } = useIpc("auth-login");
 
+    const submit = async () => {
+      // console.log(toRefs(payload));
+      send({
+        email: payload.email,
+        password: payload.password,
+      });
+      console.log(data.value, "login");
+      // setUser(data.value, payload.rememberMe);
+      // router.push({ name: "home" });
+    };
+
+    watch(loading, () => {
+      console.log("loading changed");
+      console.log(data.value, "post laoding");
+    });
+
+    return {
+      loading,
+      submit,
+      errorMessage,
+      ...toRefs(payload),
+    };
+  },
 });
+</script>
+
+<style lang="scss" scoped>
+#login {
+  width: 350px;
+  height: 500px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  background-color: #e6e6e6;
+}
+
+#loginBox {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+}
+
+.input {
+  background-color: #B9B9B9;
+  border: none;
+  color: white;
+  padding: 16px;
+  text-decoration: none;
+  margin: 4px 2px;
+  cursor: pointer;
+  border-radius: 10px;
+}
 
-</script>
\ No newline at end of file
+.button {
+  background-color: #58C4FD;
+  border: none;
+  color: white;
+  padding: 10px 20px;
+  text-decoration: none;
+  border-radius: 20px;
+  font-weight: bold;
+}
+</style>
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..7fed6b699ecd3f949f2716e54b53251ccdf70c7d 100644 (file)
@@ -0,0 +1,71 @@
+<template>
+  <div id="login">
+    <!-- login title -->
+    <div id="loginTitle">Login</div>
+
+    <!-- username and password forms -->
+    <div id="loginBox">
+      <!-- username -->
+      <input class="input" type="text" v-model="login.username" placeholder="username" />
+
+      <!-- password -->
+      <input class="input" type="password" v-model="login.password" placeholder="Password" />
+    </div>
+
+    <!-- submit button -->
+    <button class="button" @click="submitCreds">Submit</button>
+  </div>
+</template>
+
+<script lang="ts">
+import {
+  computed,
+  defineComponent,
+  onErrorCaptured,
+  reactive,
+  ref,
+  toRefs,
+} from "vue";
+import { useRouter } from "vue-router";
+import { useIpc } from "@/modules/ipc";
+import { useAuth } from "@/modules/auth";
+
+interface RegisterPayload {
+  email?: string;
+  password?: string;
+  firstName?: string;
+  lastName?: string;
+}
+
+export default defineComponent({
+  name: "Register",
+  setup() {
+    const payload = reactive<RegisterPayload>({
+      email: undefined,
+      password: undefined,
+      firstName: undefined,
+      lastName: undefined,
+    });
+
+    const { error, loading, send, data, errorMessage } = useIpc(
+      "auth-register"
+    );
+
+    const { setUser } = useAuth();
+    const router = useRouter();
+
+    const submit = async () => {
+      send(payload);
+      setUser(data.value, true);
+      router.push({ name: "home" });
+    };
+
+    return {
+      ...toRefs(payload),
+      submit,
+      loading,
+      errorMessage,
+    };
+  },
+});
+</script>