fix post window close auth bug
This commit is contained in:
parent
46a127c217
commit
6a19a96855
7 changed files with 91 additions and 82 deletions
|
|
@ -13,7 +13,12 @@ module.exports = {
|
||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off"
|
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||||
|
"no-unused-vars": "off",
|
||||||
|
"@typescript-eslint/no-unused-vars": [
|
||||||
|
"error",
|
||||||
|
{ "argsIgnorePattern": "^_" }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
|
|
@ -23,7 +28,7 @@ module.exports = {
|
||||||
"*.js"
|
"*.js"
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
"@typescript-eslint/no-var-requires": "off"
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
},
|
},
|
||||||
env: {
|
env: {
|
||||||
jest: true
|
jest: true
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
import { BrowserWindow } from "electron";
|
import { BrowserWindow, ipcMain } from "electron";
|
||||||
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
|
import { createProtocol } from "vue-cli-plugin-electron-builder/lib";
|
||||||
|
import { windowEmitter } from './windowEmitter';
|
||||||
|
import { sendMessage } from './session';
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
|
|
||||||
interface WindowSettings {
|
interface WindowSettings {
|
||||||
|
|
@ -10,8 +12,17 @@ interface WindowSettings {
|
||||||
resizable: boolean;
|
resizable: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleMessage = (event: any, arg: any) => {
|
||||||
|
sendMessage(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
const windowMount = (): void => {
|
||||||
|
windowEmitter.emit('window-active', true);
|
||||||
|
ipcMain.on('send-message', handleMessage);
|
||||||
|
}
|
||||||
|
|
||||||
export const createWindow = async (options: WindowSettings): Promise<BrowserWindow> => {
|
export const createWindow = async (options: WindowSettings): Promise<BrowserWindow> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, _reject) => {
|
||||||
const win: BrowserWindow = new BrowserWindow({
|
const win: BrowserWindow = new BrowserWindow({
|
||||||
width: options.width,
|
width: options.width,
|
||||||
height: options.height,
|
height: options.height,
|
||||||
|
|
@ -35,8 +46,10 @@ export const createWindow = async (options: WindowSettings): Promise<BrowserWind
|
||||||
}
|
}
|
||||||
|
|
||||||
win.webContents.on('did-finish-load', () => {
|
win.webContents.on('did-finish-load', () => {
|
||||||
|
windowMount();
|
||||||
resolve(win);
|
resolve(win);
|
||||||
});
|
});
|
||||||
})
|
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,58 +1,50 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
import { createWindow } from './createWindow';
|
import { createWindow } from './createWindow';
|
||||||
import { ipcMain, BrowserWindow } from "electron";
|
import { ipcMain, BrowserWindow } from "electron";
|
||||||
import { initSession, sendMessage } from './session';
|
import { initSession } from './session';
|
||||||
import { windowEmitter } from './windowEmitter';
|
import { windowEmitter } from './windowEmitter';
|
||||||
const portAudio = require('naudiodon');
|
// const portAudio = require('naudiodon');
|
||||||
|
|
||||||
interface ipcRendererPayload {
|
interface IpcRendererPayload {
|
||||||
endpoint: string;
|
endpoint: string;
|
||||||
message: any;
|
message: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
let activeSession = false;
|
|
||||||
let win: BrowserWindow | null;
|
let win: BrowserWindow | null;
|
||||||
|
let activeSession = false;
|
||||||
|
|
||||||
windowEmitter.on('ipc-renderer', (payload: ipcRendererPayload) => {
|
windowEmitter.on('ipc-renderer', (payload: IpcRendererPayload) => {
|
||||||
if (win)
|
if (win)
|
||||||
win.webContents.send(payload.endpoint, {
|
win.webContents.send(payload.endpoint, {
|
||||||
message: payload.message
|
message: payload.message
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
* The main function will be run after electron app is ready.
|
|
||||||
*/
|
|
||||||
export async function main() {
|
|
||||||
|
|
||||||
// create main window.
|
|
||||||
if (!win) {
|
|
||||||
win = await createWindow({ width: 350, height: 525, resizable: false });
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Instantiate socket session with crimata-platorm.
|
|
||||||
if (!activeSession) {
|
|
||||||
initSession();
|
|
||||||
}
|
|
||||||
activeSession = true;
|
|
||||||
|
|
||||||
const handleMessage = (event: any, arg: any) => {
|
|
||||||
sendMessage(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
const windowMount = (): void => {
|
|
||||||
windowEmitter.emit('window-active', true);
|
|
||||||
ipcMain.on('send-message', handleMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
const windowDismount = (): void => {
|
const windowDismount = (): void => {
|
||||||
win = null;
|
win = null;
|
||||||
windowEmitter.emit('window-active', false);
|
windowEmitter.emit('window-active', false);
|
||||||
ipcMain.removeAllListeners('send-message');
|
ipcMain.removeAllListeners('send-message');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle window mount and dismount.
|
/*
|
||||||
win.webContents.on('did-finish-load', windowMount);
|
* The main function will be run after electron app is ready.
|
||||||
|
*/
|
||||||
|
export async function main() {
|
||||||
|
|
||||||
|
// create main window.
|
||||||
|
if (!win) win = await createWindow({
|
||||||
|
width: 350,
|
||||||
|
height: 525,
|
||||||
|
resizable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Instantiate socket session with crimata-platorm.
|
||||||
|
if (!activeSession) initSession();
|
||||||
|
|
||||||
|
activeSession = true;
|
||||||
|
|
||||||
|
// Handle window close.
|
||||||
win.on("closed", windowDismount);
|
win.on("closed", windowDismount);
|
||||||
|
|
||||||
// TODO: FIX recorder restart bug
|
// TODO: FIX recorder restart bug
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,10 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
import WebSocket from 'ws';
|
import WebSocket from 'ws';
|
||||||
import { windowEmitter } from './windowEmitter';
|
import { windowEmitter } from './windowEmitter';
|
||||||
import { ipcMain } from "electron";
|
import { ipcMain } from "electron";
|
||||||
|
|
||||||
const EventEmitter = require('events');
|
|
||||||
|
|
||||||
class SocketEmitter extends EventEmitter {}
|
|
||||||
|
|
||||||
export const socketEmitter = new SocketEmitter();
|
|
||||||
|
|
||||||
interface RenderMessage {
|
interface RenderMessage {
|
||||||
type: 'render';
|
|
||||||
content: string;
|
content: string;
|
||||||
context: string;
|
context: string;
|
||||||
subContext: string;
|
subContext: string;
|
||||||
|
|
@ -33,24 +28,21 @@ let auth = false;
|
||||||
const receiveMessage = (message: string): void => {
|
const receiveMessage = (message: string): void => {
|
||||||
|
|
||||||
while(!auth) {
|
while(!auth) {
|
||||||
console.log('window emitter @ session.ts recieve')
|
|
||||||
windowEmitter.emit('auth-res', message);
|
windowEmitter.emit('auth-res', message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsed: RenderMessage = JSON.parse(message);
|
const parsed: RenderMessage = JSON.parse(message);
|
||||||
if (parsed.type === "render") {
|
|
||||||
windowEmitter.emit('ipc-renderer', {
|
windowEmitter.emit('ipc-renderer', {
|
||||||
endpoint: 'render-message',
|
endpoint: 'render-message',
|
||||||
message: parsed
|
message: parsed
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
}
|
|
||||||
|
|
||||||
const authUser = async (event: any, payload: string | UserCreds | null): Promise<string> => {
|
const authSession = async (_event, payload: string | UserCreds | null): Promise<string> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
console.log('authenticating...');
|
console.log('authenticating...');
|
||||||
console.log('window emitter @ session.ts auth')
|
|
||||||
windowEmitter.on('auth-res', (res: string) => {
|
windowEmitter.on('auth-res', (res: string) => {
|
||||||
if (res === 'locked') {
|
if (res === 'locked') {
|
||||||
reject(res);
|
reject(res);
|
||||||
|
|
@ -69,6 +61,14 @@ const authUser = async (event: any, payload: string | UserCreds | null): Promise
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const sendMessage = (content: string | Buffer) => {
|
||||||
|
if (content instanceof Buffer) {
|
||||||
|
socket.send(content);
|
||||||
|
} else if (content){
|
||||||
|
socket.send(JSON.stringify(content));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const initSession = () => {
|
export const initSession = () => {
|
||||||
if (socket) {
|
if (socket) {
|
||||||
socket.removeAllListeners();
|
socket.removeAllListeners();
|
||||||
|
|
@ -84,7 +84,7 @@ export const initSession = () => {
|
||||||
|
|
||||||
// handle renderer auth-token event
|
// handle renderer auth-token event
|
||||||
ipcMain.removeHandler('auth-user'); // avoid setting duplicate handlers
|
ipcMain.removeHandler('auth-user'); // avoid setting duplicate handlers
|
||||||
ipcMain.handle('auth-user', authUser);
|
ipcMain.handle('auth-user', authSession);
|
||||||
|
|
||||||
socket.on('open', () => {
|
socket.on('open', () => {
|
||||||
console.log('Success! Connected to Crimata.');
|
console.log('Success! Connected to Crimata.');
|
||||||
|
|
@ -98,7 +98,7 @@ export const initSession = () => {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on('error', (e) => {
|
socket.on('error', (_e) => {
|
||||||
console.log('ERROR: Failed to connect.');
|
console.log('ERROR: Failed to connect.');
|
||||||
socket.removeAllListeners();
|
socket.removeAllListeners();
|
||||||
socket.close();
|
socket.close();
|
||||||
|
|
@ -109,20 +109,13 @@ export const initSession = () => {
|
||||||
}
|
}
|
||||||
}, reconnectTimeout);
|
}, reconnectTimeout);
|
||||||
|
|
||||||
})
|
});
|
||||||
|
|
||||||
socket.on('close', () => {
|
socket.on('close', () => {
|
||||||
console.log('Connection droped. Restarting.')
|
console.log('Connection droped. Restarting.')
|
||||||
initSession();
|
initSession();
|
||||||
})
|
});
|
||||||
|
|
||||||
socket.on("message", receiveMessage);
|
socket.on("message", receiveMessage);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const sendMessage = (content: string | Buffer) => {
|
|
||||||
if (content instanceof Buffer) {
|
|
||||||
socket.send(content);
|
|
||||||
} else if (content){
|
|
||||||
socket.send(JSON.stringify(content));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
import { reactive, watch, toRefs } from 'vue';
|
import { reactive, toRefs } from 'vue';
|
||||||
import { useIpc } from './ipc';
|
import { useIpc } from './ipc';
|
||||||
|
|
||||||
interface AuthState {
|
interface AuthState {
|
||||||
access_token?: string | null;
|
accessToken?: string | null;
|
||||||
error?: Error;
|
error?: Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = reactive<AuthState>({
|
const state = reactive<AuthState>({
|
||||||
access_token: undefined,
|
accessToken: undefined,
|
||||||
error: undefined,
|
error: undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -15,20 +15,28 @@ const AUTH_KEY = 'crimata_token';
|
||||||
|
|
||||||
const token = window.localStorage.getItem(AUTH_KEY);
|
const token = window.localStorage.getItem(AUTH_KEY);
|
||||||
|
|
||||||
// authenticate on socket connect
|
const authToken = async () => {
|
||||||
window.ipcRenderer.on("fetch-token", async (event, payload: null) => {
|
|
||||||
const { data, invoke } = useIpc('auth-user');
|
const { data, invoke } = useIpc('auth-user');
|
||||||
try {
|
try {
|
||||||
await invoke(token);
|
await invoke(token);
|
||||||
state.access_token = data.value;
|
state.accessToken = data.value;
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
state.error = e;
|
state.error = e;
|
||||||
console.log('ERROR: failed authentication');
|
console.log('ERROR: failed authentication');
|
||||||
window.localStorage.removeItem(AUTH_KEY);
|
window.localStorage.removeItem(AUTH_KEY);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// authenticate on socket connect
|
||||||
|
window.ipcRenderer.on("fetch-token", async (_event, _arg) => {
|
||||||
|
authToken();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (token) {
|
||||||
|
authToken();
|
||||||
|
}
|
||||||
|
|
||||||
export const useAuth = () => {
|
export const useAuth = () => {
|
||||||
const setToken = (token: string, remember: boolean) => {
|
const setToken = (token: string, remember: boolean) => {
|
||||||
if (remember) {
|
if (remember) {
|
||||||
|
|
@ -36,18 +44,18 @@ export const useAuth = () => {
|
||||||
window.localStorage.setItem(AUTH_KEY, token);
|
window.localStorage.setItem(AUTH_KEY, token);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.access_token = token;
|
state.accessToken = token;
|
||||||
state.error = undefined;
|
state.error = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
const logout = (): Promise<void> => {
|
const logout = (): Promise<void> => {
|
||||||
window.localStorage.removeItem(AUTH_KEY);
|
window.localStorage.removeItem(AUTH_KEY);
|
||||||
return Promise.resolve(state.access_token = undefined);
|
return Promise.resolve(state.accessToken = undefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setToken,
|
setToken,
|
||||||
logout,
|
logout,
|
||||||
...toRefs(state), // access_token, error
|
...toRefs(state), // accessToken, error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,13 +35,13 @@ const router = createRouter({
|
||||||
});
|
});
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
const { access_token } = useAuth();
|
const { accessToken } = useAuth();
|
||||||
|
|
||||||
// Not logged into a guarded route?
|
// Not logged into a guarded route?
|
||||||
if (to.meta.requiresAuth && !access_token?.value) next({ name: 'login' });
|
if (to.meta.requiresAuth && !accessToken?.value) next({ name: 'login' });
|
||||||
|
|
||||||
// Logged in for an auth route
|
// Logged in for an auth route
|
||||||
else if ((to.name == 'login' || to.name == 'register') && access_token!.value) next({ name: 'home' });
|
else if ((to.name == 'login' || to.name == 'register') && accessToken!.value) next({ name: 'home' });
|
||||||
|
|
||||||
// Carry On...
|
// Carry On...
|
||||||
else next();
|
else next();
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, toRefs, reactive, watch, ref } from "vue";
|
import { defineComponent, ref } from "vue";
|
||||||
import { useAuth } from "@/modules/auth";
|
import { useAuth } from "@/modules/auth";
|
||||||
import { useIpc } from "@/modules/ipc";
|
import { useIpc } from "@/modules/ipc";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
|
@ -35,14 +35,14 @@ interface LoginPayload {
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: "Login",
|
name: "Login",
|
||||||
setup() {
|
setup() {
|
||||||
const { setToken, access_token } = useAuth();
|
const { setToken } = useAuth();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const email = ref("");
|
const email = ref("");
|
||||||
const password = ref("");
|
const password = ref("");
|
||||||
const rememberMe = ref(false);
|
const rememberMe = ref(false);
|
||||||
|
|
||||||
const { loading, error, data, invoke, errorMessage } = useIpc('auth-user');
|
const { data, invoke } = useIpc('auth-user');
|
||||||
|
|
||||||
const submit = async () => {
|
const submit = async () => {
|
||||||
const payload = {
|
const payload = {
|
||||||
|
|
@ -60,9 +60,7 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
loading,
|
|
||||||
submit,
|
submit,
|
||||||
errorMessage,
|
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
rememberMe
|
rememberMe
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue