"@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",
"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",
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: {
},
setup() {
- const { post } = useIpc();
+
+ const { post, invoke } = useIpc();
+
+ const { user } = useAuth();
// Whether browser has received user info yet.
const ready = ref(false);
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.
}
- 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');
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 {
"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;
})
-
-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();
}
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";
}
// 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) {
};
-// 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.
"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) => {
}
- 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();
}
}
- const onClose = (event: WebSocket.CloseEvent) => {
+ const onClose = (_event: WebSocket.CloseEvent) => {
console.log("WS:Socket closed normally.")
}
return {
createSocket,
- sendMessage
+ sendMessage,
+ send
}
-}
\ No newline at end of file
+}
// 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);
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);
}
// 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({
--- /dev/null
+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
+ }
+
+}
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"
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"
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"