add user-auth and init-session events

This commit is contained in:
riqo 2021-05-25 09:01:28 -05:00
commit ea3fc85371
8 changed files with 174 additions and 77 deletions

View file

@ -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",

View file

@ -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 {

View file

@ -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();
}

View file

@ -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.

View file

@ -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
}
}
}

View file

@ -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
View 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
}
}

View file

@ -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"