add user-auth and init-session events
This commit is contained in:
parent
fe954f2960
commit
ea3fc85371
8 changed files with 174 additions and 77 deletions
|
|
@ -22,6 +22,7 @@
|
|||
"@types/uuid": "^8.3.0",
|
||||
"@types/ws": "^7.2.7",
|
||||
"animejs": "^3.2.0",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "^3.6.5",
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"electron-updater": "^4.3.8",
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
"ws": "^7.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/electron-devtools-installer": "^2.2.0",
|
||||
"@types/jest": "^24.0.19",
|
||||
"@typescript-eslint/eslint-plugin": "^2.33.0",
|
||||
|
|
|
|||
45
src/App.vue
45
src/App.vue
|
|
@ -35,11 +35,13 @@
|
|||
import { defineComponent, onMounted, onUnmounted, ref } from "vue";
|
||||
import { IpcRendererEvent } from "electron";
|
||||
import { useIpc } from "@/modules/ipc";
|
||||
import { useAuth } from "@/modules/auth"
|
||||
|
||||
import Splash from "@/components/splash.vue";
|
||||
import Messenger from "@/components/messenger.vue";
|
||||
import Login from "@/components/login.vue";
|
||||
|
||||
|
||||
export default defineComponent({
|
||||
|
||||
components: {
|
||||
|
|
@ -49,7 +51,10 @@ export default defineComponent({
|
|||
},
|
||||
|
||||
setup() {
|
||||
const { post } = useIpc();
|
||||
|
||||
const { post, invoke } = useIpc();
|
||||
|
||||
const { user } = useAuth();
|
||||
|
||||
// Whether browser has received user info yet.
|
||||
const ready = ref(false);
|
||||
|
|
@ -58,18 +63,19 @@ export default defineComponent({
|
|||
const profile = ref(false);
|
||||
|
||||
// New messages that browser missed while closed.
|
||||
const newMessages = ref([])
|
||||
const newMessages = ref([]);
|
||||
|
||||
// Receive updated information about the session.
|
||||
const updateState = (_event: IpcRendererEvent, payload: any) => {
|
||||
console.log('YAYAYAYAYA');
|
||||
console.log("APP:Received updated profile and new messages: \n" +
|
||||
` profile: ${payload.message.profile}\n` +
|
||||
` new: ${payload.message.newMessages}`)
|
||||
` new: ${payload.message.newMessages}`);
|
||||
|
||||
if (payload.message.profile) {
|
||||
console.log(`APP:Logged-in, showing Messenger View.`)
|
||||
console.log(`APP:Logged-in, showing Messenger View.`);
|
||||
} else {
|
||||
console.log(`APP:Logged-out, showing Login View.`)
|
||||
console.log(`APP:Logged-out, showing Login View.`);
|
||||
}
|
||||
|
||||
// Set profile and newMessages.
|
||||
|
|
@ -81,8 +87,8 @@ export default defineComponent({
|
|||
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log("APP:mounted.")
|
||||
onMounted(async () => {
|
||||
console.log("APP:mounted.");
|
||||
window.ipcRenderer.on("update-state", updateState)
|
||||
window.ipcRenderer.on("update_available", () => {
|
||||
console.log('testing auto update');
|
||||
|
|
@ -91,11 +97,32 @@ export default defineComponent({
|
|||
window.ipcRenderer.on("update_downloaded", () => {
|
||||
console.log('testing update download');
|
||||
})
|
||||
post("app-mounted", "")
|
||||
|
||||
post("app-mounted", "");
|
||||
|
||||
if(user.value.key) {
|
||||
try {
|
||||
const res = await invoke('user-auth', JSON.stringify(user.value));
|
||||
profile.value = res;
|
||||
} catch(e) {
|
||||
profile.value = false;
|
||||
console.log('[AUTH]', e);
|
||||
} finally {
|
||||
ready.value = true;
|
||||
if (profile.value) {
|
||||
// start session
|
||||
post("init-session", user.value.email);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
profile.value = false;
|
||||
ready.value = true;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.ipcRenderer.removeAllListeners("update-state")
|
||||
window.ipcRenderer.removeAllListeners("update-state");
|
||||
})
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
|
||||
"use strict";
|
||||
|
||||
import { app, dialog } from "electron";
|
||||
import { app, dialog, ipcMain, IpcMainInvokeEvent } from "electron";
|
||||
import { createWindow } from './window';
|
||||
import { initSession, updateState } from './session';
|
||||
import { initSession, onAppMounted } from './session';
|
||||
import { initAudioIO, stopStream } from './audio';
|
||||
import { backgroundMitt } from '@/modules/emitter';
|
||||
import { Profile } from "@/types";
|
||||
|
||||
let win: boolean;
|
||||
|
||||
|
|
@ -38,36 +39,53 @@ autoUpdater.on('update-downloaded', (info: any) => {
|
|||
|
||||
})
|
||||
|
||||
|
||||
interface Profile {
|
||||
crimataId: string;
|
||||
alias: string;
|
||||
initials: string;
|
||||
interface AccountAuth {
|
||||
email: string;
|
||||
password?: string;
|
||||
key: string | null;
|
||||
}
|
||||
|
||||
// Run when electron app is initialized.
|
||||
async function main() {
|
||||
console.log("MAIN:Initializing Electron App.")
|
||||
const onUserAuth = async (_event: any, payload: AccountAuth)
|
||||
:Promise<Error | Profile> => (
|
||||
new Promise((resolve, reject) => {
|
||||
|
||||
// Must wait til window is created.
|
||||
await createWindow();
|
||||
// check for login
|
||||
if (payload.password) {
|
||||
// await user login
|
||||
|
||||
// authenticate against business backend
|
||||
const auth = async (crimataId: string): Promise<Profile | null> => {
|
||||
updateState({key: "", profile: {
|
||||
crimataId: "",
|
||||
alias: "",
|
||||
initials: ""
|
||||
}});
|
||||
return null
|
||||
};
|
||||
auth('');
|
||||
} else {
|
||||
// authenticate token
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
const onSessionInit = (_event: IpcMainInvokeEvent, payload: string) => {
|
||||
// Instantiate socket session with crimata-platorm.
|
||||
initSession();
|
||||
|
||||
// Begin audio stream.
|
||||
initAudioIO();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Run when electron app is initialized.
|
||||
async function main() {
|
||||
|
||||
console.log("MAIN:Initializing Electron App.");
|
||||
|
||||
// Attack browser window init listener.
|
||||
ipcMain.removeAllListeners("app-mounted");
|
||||
ipcMain.on("app-mounted", onAppMounted);
|
||||
|
||||
ipcMain.removeHandler("user-auth");
|
||||
ipcMain.handle("user-auth", onUserAuth);
|
||||
|
||||
ipcMain.removeAllListeners("init-session");
|
||||
ipcMain.on("init-session", onSessionInit);
|
||||
|
||||
// Must wait til window is created.
|
||||
await createWindow();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import { backgroundMitt } from "@/modules/emitter";
|
|||
import { ipcEmit, loadState, saveToJson } from './helpers';
|
||||
import { ipcMain, IpcMainEvent, IpcMainInvokeEvent } from "electron";
|
||||
|
||||
import useWebSockets from "@/modules/websockets";
|
||||
import useWebSockets from "./websockets";
|
||||
|
||||
import { play } from "./audio";
|
||||
import { renderMessage } from "@/modules/message";
|
||||
|
|
@ -56,22 +56,23 @@ export const updateState = (res: AuthProtocol) => {
|
|||
}
|
||||
|
||||
// Send state on new window.
|
||||
const onNewBrowserWindow = (_event: IpcMainInvokeEvent, _payload: any) => {
|
||||
export const onAppMounted = (_event: IpcMainInvokeEvent, _payload: any) => {
|
||||
|
||||
profile = true;
|
||||
console.log('testing!!!', profile)
|
||||
if (typeof profile !== 'undefined') {
|
||||
console.log("SESS:Sending user profile to browser.")
|
||||
console.log("SESS:Sending user profile to browser.");
|
||||
ipcEmit("update-state", {
|
||||
profile: profile,
|
||||
newMessages: state.newMessages
|
||||
})
|
||||
newMessages: [],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Calls appropriate endpoint for a server message.
|
||||
const onMessage = (data: string) => {
|
||||
let message = JSON.parse(data)
|
||||
|
||||
// AuthProtocol message.
|
||||
updateState(message)
|
||||
let message = JSON.parse(data);
|
||||
console.log('received new message', message);
|
||||
|
||||
// Standard message.
|
||||
if (message.content) {
|
||||
|
|
@ -106,57 +107,42 @@ const onMessage = (data: string) => {
|
|||
|
||||
};
|
||||
|
||||
// When socket connects, we update state.
|
||||
const onOpen = () => {
|
||||
// console.log(`SESS:Sending key: ${state.key}`)
|
||||
|
||||
if (state) {
|
||||
// sendMessage({
|
||||
// "key": state.key,
|
||||
// "usr": false,
|
||||
// "pwd": false
|
||||
// })
|
||||
}
|
||||
}
|
||||
|
||||
// Websockets module.
|
||||
const { createSocket, sendMessage } = useWebSockets(onMessage, onOpen);
|
||||
const { createSocket, send } = useWebSockets(onMessage);
|
||||
|
||||
// Handle messages from window/client.
|
||||
const onClientMessage = (_event: IpcMainEvent, payload: any) => {
|
||||
const onClientMessage = async (_event: IpcMainEvent, payload: any):Promise<void> => {
|
||||
console.log("New client message")
|
||||
|
||||
if (payload.hasOwnProperty("key")) {
|
||||
return
|
||||
}
|
||||
const success = sendMessage(payload);
|
||||
|
||||
if (!success) {
|
||||
try {
|
||||
send(payload)
|
||||
} catch(e) {
|
||||
console.log("Unable to send message: ", payload);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Call this to initialize session with Crimata servers.
|
||||
export const initSession = () => {
|
||||
console.log("SESS:Creating new session.")
|
||||
|
||||
// Load Json or createState.
|
||||
state = loadState("session.json")
|
||||
|
||||
console.log("SESS:State loaded: \n" +
|
||||
` key: ${state.key}\n` +
|
||||
` new: ${state.newMessages}`)
|
||||
state = loadState("session.json");
|
||||
|
||||
// Open socket connection.
|
||||
createSocket()
|
||||
createSocket();
|
||||
|
||||
// Attack browser window init listener.
|
||||
ipcMain.removeAllListeners("app-mounted")
|
||||
ipcMain.on("app-mounted", onNewBrowserWindow);
|
||||
// ipcMain.removeAllListeners("app-mounted");
|
||||
// ipcMain.on("app-mounted", onAppMounted);
|
||||
|
||||
// Attach listeners for frontend.
|
||||
ipcMain.removeAllListeners("client-message")
|
||||
ipcMain.removeAllListeners("client-message");
|
||||
ipcMain.on("client-message", onClientMessage);
|
||||
|
||||
// Keep win up-to-date.
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
"use strict";
|
||||
|
||||
import WebSocket from 'ws';
|
||||
import { ipcMain } from "electron";
|
||||
|
||||
let socket: WebSocket;
|
||||
|
||||
|
||||
|
||||
// Run every time we want to connect to backend.
|
||||
export default function useWebSockets(receiveCallback: (s: string) => any, openCallback: () => any) {
|
||||
export default function useWebSockets(
|
||||
receiveCallback: (s: string) => void,
|
||||
openCallback?: () => void
|
||||
) {
|
||||
|
||||
// Returns bool (sucess or fail).
|
||||
const sendMessage = (data: any) => {
|
||||
|
|
@ -24,11 +27,22 @@ export default function useWebSockets(receiveCallback: (s: string) => any, openC
|
|||
|
||||
}
|
||||
|
||||
const onOpen = (event: WebSocket.OpenEvent) => {
|
||||
const send = async (data: Record<string, any>):Promise<boolean> => (
|
||||
new Promise((resolve, reject) => {
|
||||
if (socket.readyState !== 1) {
|
||||
reject(false);
|
||||
}
|
||||
socket.send(JSON.stringify(data))
|
||||
resolve(true);
|
||||
|
||||
}))
|
||||
|
||||
|
||||
const onOpen = (_event: WebSocket.OpenEvent) => {
|
||||
|
||||
console.log("WS:Connected to WS Server!");
|
||||
|
||||
openCallback()
|
||||
if (openCallback) openCallback();
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -40,7 +54,7 @@ export default function useWebSockets(receiveCallback: (s: string) => any, openC
|
|||
|
||||
}
|
||||
|
||||
const onClose = (event: WebSocket.CloseEvent) => {
|
||||
const onClose = (_event: WebSocket.CloseEvent) => {
|
||||
console.log("WS:Socket closed normally.")
|
||||
}
|
||||
|
||||
|
|
@ -66,7 +80,8 @@ export default function useWebSockets(receiveCallback: (s: string) => any, openC
|
|||
|
||||
return {
|
||||
createSocket,
|
||||
sendMessage
|
||||
sendMessage,
|
||||
send
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -57,7 +57,6 @@ const saveWindowState = () => {
|
|||
|
||||
// Do this on window mount.
|
||||
const onWindowMount = (): void => {
|
||||
console.log("BW:Adding window listeners. ")
|
||||
|
||||
// Must tell initApp that window exists.
|
||||
backgroundMitt.emit('window-active', true);
|
||||
|
|
@ -70,12 +69,10 @@ const onWindowMount = (): void => {
|
|||
backgroundMitt.removeAllListeners("ipc-renderer")
|
||||
backgroundMitt.on("ipc-renderer", renderMessage);
|
||||
|
||||
console.log("BW:Listeners created.")
|
||||
}
|
||||
|
||||
// Do this on window dismount (close).
|
||||
const onWindowDismount = (): void => {
|
||||
console.log("BW:Window closed.")
|
||||
win = null;
|
||||
backgroundMitt.emit('window-active', false);
|
||||
}
|
||||
|
|
@ -89,7 +86,6 @@ export async function createWindow(): Promise<void> {
|
|||
|
||||
// Load the saved window state.
|
||||
winState = loadWinState("window.json")
|
||||
console.log(`BW:Creating window [${winState.width}, ${winState.height}].`)
|
||||
|
||||
// Define the browser window.
|
||||
win = new BrowserWindow({
|
||||
|
|
|
|||
34
src/modules/auth.ts
Normal file
34
src/modules/auth.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { ref, Ref} from "vue";
|
||||
|
||||
interface UserState {
|
||||
email: string | null;
|
||||
password?: string;
|
||||
key: string | null;
|
||||
}
|
||||
|
||||
const user:Ref<UserState> = ref({
|
||||
email: null,
|
||||
key: "testing"
|
||||
});
|
||||
|
||||
const CRIMATA_KEY = "CRIMATA_KEY";
|
||||
|
||||
const raw = window.localStorage.getItem(CRIMATA_KEY);
|
||||
|
||||
if (raw) {
|
||||
user.value = JSON.parse(raw);
|
||||
}
|
||||
|
||||
export const useAuth = () => {
|
||||
|
||||
const setUser = (token: UserState) => {
|
||||
window.localStorage.setItem(CRIMATA_KEY, JSON.stringify(token));
|
||||
user.value = token;
|
||||
}
|
||||
|
||||
return {
|
||||
setUser,
|
||||
user
|
||||
}
|
||||
|
||||
}
|
||||
19
yarn.lock
19
yarn.lock
|
|
@ -1279,6 +1279,13 @@
|
|||
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
|
||||
integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
|
||||
|
||||
"@types/axios@^0.14.0":
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/axios/-/axios-0.14.0.tgz#ec2300fbe7d7dddd7eb9d3abf87999964cafce46"
|
||||
integrity sha1-7CMA++fX3d1+udOr+HmZlkyvzkY=
|
||||
dependencies:
|
||||
axios "*"
|
||||
|
||||
"@types/babel__core@^7.1.0":
|
||||
version "7.1.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.12.tgz#4d8e9e51eb265552a7e4f1ff2219ab6133bdfb2d"
|
||||
|
|
@ -2733,6 +2740,13 @@ aws4@^1.8.0:
|
|||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59"
|
||||
integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==
|
||||
|
||||
axios@*, axios@^0.21.1:
|
||||
version "0.21.1"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
|
||||
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
|
||||
dependencies:
|
||||
follow-redirects "^1.10.0"
|
||||
|
||||
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
|
||||
version "6.26.0"
|
||||
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
|
||||
|
|
@ -5871,6 +5885,11 @@ follow-redirects@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
|
||||
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
|
||||
|
||||
follow-redirects@^1.10.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
|
||||
integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
|
|
|||
Loading…
Reference in a new issue