add authenticate on socket connect
This commit is contained in:
parent
4a9e19bb43
commit
e0da50eb27
7 changed files with 112 additions and 70 deletions
|
|
@ -14,12 +14,6 @@ interface ipcRendererPayload {
|
|||
*/
|
||||
export function main(): void {
|
||||
|
||||
// Instantiate socket session with crimata-platorm.
|
||||
initSession();
|
||||
|
||||
// mount auth-user listener
|
||||
ipcMain.on('auth-user', authUser);
|
||||
|
||||
// create main window.
|
||||
const win = createWindow({ width: 350, height: 525, resizable: false });
|
||||
|
||||
|
|
@ -34,18 +28,17 @@ export function main(): void {
|
|||
}
|
||||
|
||||
const windowMount = (): void => {
|
||||
// Instantiate socket session with crimata-platorm.
|
||||
initSession();
|
||||
windowEmitter.emit('window-active', true);
|
||||
// ipc event handlers
|
||||
ipcMain.on('send-message', handleMessage);
|
||||
ipcMain.on('auth-login', authLogin);
|
||||
}
|
||||
|
||||
const windowDismount = (): void => {
|
||||
windowEmitter.emit('window-active', false);
|
||||
// TODO: Gracefully close socket connection
|
||||
ipcMain.removeAllListeners('send-message');
|
||||
ipcMain.removeAllListeners('auth-login');
|
||||
ipcMain.removeAllListeners('auth-user');
|
||||
}
|
||||
|
||||
// Handle window mount and dismount.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import WebSocket from 'ws';
|
||||
import { windowEmitter } from './windowEmitter';
|
||||
import { ipcMain } from "electron";
|
||||
|
||||
type Message = {
|
||||
type: string;
|
||||
|
|
@ -14,85 +15,87 @@ interface RenderMessage extends Message {
|
|||
time: string;
|
||||
}
|
||||
|
||||
interface AuthMessage extends Message {
|
||||
interface AuthUser extends Message {
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
access_token: string;
|
||||
}
|
||||
|
||||
interface AuthRequest {
|
||||
token: string;
|
||||
}
|
||||
|
||||
interface PostLogin {
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface PostMessage {
|
||||
content: string;
|
||||
}
|
||||
|
||||
const ip = 'ws://localhost';
|
||||
const port = 8080;
|
||||
const username = 'hernandeze2@xavier.edu';
|
||||
const reconnectTimeout = 3000; //ms
|
||||
let socket: WebSocket;
|
||||
let success = false;
|
||||
|
||||
const receiveMessage = (message: string): void => {
|
||||
// NOTE assuming message is JSON string
|
||||
const parsed: RenderMessage | AuthMessage = JSON.parse(message);
|
||||
if (message === 'locked') {
|
||||
windowEmitter.emit('auth-resp', message);
|
||||
return;
|
||||
}
|
||||
const parsed: RenderMessage | AuthUser = JSON.parse(message);
|
||||
if (parsed.type === "render") {
|
||||
windowEmitter.emit('ipc-renderer', {
|
||||
endpoint: 'render-message',
|
||||
message: parsed
|
||||
});
|
||||
} else if (parsed.type === "auth") {
|
||||
windowEmitter.emit('auth-resp', parsed);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect and send username
|
||||
const authToken = async (event: any, token: string): Promise<string | AuthUser > => {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log('authenticating...');
|
||||
windowEmitter.on('auth-resp', (arg: string | AuthUser) => {
|
||||
if (arg === 'locked') {
|
||||
reject(arg);
|
||||
}
|
||||
resolve(arg);
|
||||
});
|
||||
if (token) {
|
||||
socket.send(token);
|
||||
} else {
|
||||
socket.send('no-token');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Connect and authenticate
|
||||
export function initSession() {
|
||||
|
||||
let success = false;
|
||||
socket = new WebSocket(`${ip}:${port}`);
|
||||
socket.binaryType = 'arraybuffer';
|
||||
|
||||
socket.on('open', () => {
|
||||
console.log('Connected to crimata-platform');
|
||||
socket.send(username);
|
||||
success = true;
|
||||
|
||||
// handle renderer auth-token event
|
||||
ipcMain.removeHandler('auth-token'); // avoid setting duplicate handlers
|
||||
ipcMain.handle('auth-token', authToken);
|
||||
|
||||
// fetch token from renderer
|
||||
windowEmitter.emit('ipc-renderer', {
|
||||
endpoint: 'fetch-token',
|
||||
message: null
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
socket.on("message", receiveMessage);
|
||||
|
||||
setTimeout(()=> {
|
||||
if (!success) {
|
||||
throw new Error('Unable to connect to crimata-platform')
|
||||
// initSession();
|
||||
throw new Error('Unable to connect to crimata-platform');
|
||||
}
|
||||
}, 3000)
|
||||
}, reconnectTimeout);
|
||||
}
|
||||
|
||||
export const authUser = (event: any, arg: AuthRequest) => {
|
||||
console.log('sending token to socket', arg)
|
||||
try {
|
||||
sendMessage({
|
||||
content: arg.token
|
||||
});
|
||||
windowEmitter.on('auth-resp', (payload: AuthMessage) => {
|
||||
event.reply('auth-user-reply', payload);
|
||||
})
|
||||
} catch(e){
|
||||
console.log('Error authenticating user! ' + e);
|
||||
event.reply('auth-user-reply', e);
|
||||
}
|
||||
}
|
||||
|
||||
export const authLogin = (event: any, arg: PostLogin) => {
|
||||
export const authLogin = (event: any, arg: any) => {
|
||||
try {
|
||||
sendMessage(arg)
|
||||
windowEmitter.on('auth-resp', (payload: AuthMessage) => {
|
||||
windowEmitter.on('auth-resp', (payload: AuthUser) => {
|
||||
event.reply('auth-login-reply', payload);
|
||||
})
|
||||
} catch(e) {
|
||||
|
|
@ -101,10 +104,10 @@ export const authLogin = (event: any, arg: PostLogin) => {
|
|||
}
|
||||
}
|
||||
|
||||
export const sendMessage = (content: PostMessage | Buffer | PostLogin) => {
|
||||
export const sendMessage = (content: string | Buffer) => {
|
||||
if (content instanceof Buffer) {
|
||||
socket.send(content);
|
||||
} else {
|
||||
} else if (content){
|
||||
socket.send(JSON.stringify(content));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,10 +24,23 @@ const state = reactive<AuthState>({
|
|||
const AUTH_KEY = 'crimata_token';
|
||||
|
||||
const token = window.localStorage.getItem(AUTH_KEY);
|
||||
console.log('token: ',token)
|
||||
|
||||
// authenticate on socket connect
|
||||
window.ipcRenderer.on("fetch-token", async (event, payload) => {
|
||||
const { data, invoke } = useIpc('auth-token');
|
||||
try {
|
||||
await invoke(token);
|
||||
state.user = data.value;
|
||||
}
|
||||
catch(e) {
|
||||
state.error = e;
|
||||
console.log('ERROR: failed authentication');
|
||||
window.localStorage.removeItem(AUTH_KEY);
|
||||
}
|
||||
});
|
||||
|
||||
if (token) {
|
||||
const { loading, error, data, send } = useIpc('auth-user');
|
||||
const { loading, error, data, send, invoke } = useIpc('auth-user');
|
||||
|
||||
state.authenticating = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,20 @@ export const useIpc = (endpoint: string) => {
|
|||
}
|
||||
})
|
||||
|
||||
const invoke = (payload: any) => {
|
||||
loading.value = true;
|
||||
error.value = undefined;
|
||||
|
||||
return window.ipcRenderer.invoke(endpoint, payload).then(res => {
|
||||
data.value = res;
|
||||
}).catch(e => {
|
||||
error.value = e;
|
||||
throw e;
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
})
|
||||
}
|
||||
|
||||
const send = (payload?: Record<string, any>, callback?: (arg: any) => void) => {
|
||||
loading.value = true;
|
||||
error.value = undefined;
|
||||
|
|
@ -46,6 +60,7 @@ export const useIpc = (endpoint: string) => {
|
|||
data,
|
||||
error,
|
||||
errorMessage,
|
||||
send
|
||||
send,
|
||||
invoke
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
src/modules/socket.ts
Normal file
17
src/modules/socket.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
interface SocketState {
|
||||
connection: WebSocket | null;
|
||||
auth: boolean;
|
||||
}
|
||||
|
||||
// Create WebSocket connection.
|
||||
const socket = new WebSocket('ws://localhost:8080');
|
||||
|
||||
// Connection opened
|
||||
socket.onopen = function (event) {
|
||||
socket.send('Hello Server!');
|
||||
}
|
||||
|
||||
socket.onmessage = function(event) {
|
||||
console.debug("WebSocket message received:", event);
|
||||
}
|
||||
|
||||
|
|
@ -41,24 +41,21 @@ export default defineComponent({
|
|||
rememberMe: true,
|
||||
});
|
||||
|
||||
const { loading, data, send, errorMessage } = useIpc("auth-login");
|
||||
//const { loading, data, send, errorMessage } = useIpc("auth-login");
|
||||
|
||||
const { loading, error, data, invoke, errorMessage } = useIpc('test');
|
||||
const submit = async () => {
|
||||
// console.log(toRefs(payload));
|
||||
send({
|
||||
request: "register",
|
||||
email: payload.email,
|
||||
password: payload.password,
|
||||
});
|
||||
console.log(data.value, "login");
|
||||
await invoke({
|
||||
request: "register",
|
||||
email: payload.email,
|
||||
password: payload.password,
|
||||
})
|
||||
console.log('testing incoke', data.value.test)
|
||||
// setUser(data.value, payload.rememberMe);
|
||||
router.push({ name: "home" });
|
||||
};
|
||||
|
||||
watch(loading, () => {
|
||||
console.log(data.value)
|
||||
setUser(data.value, payload.rememberMe);
|
||||
router.push({ name: "home" });
|
||||
});
|
||||
|
||||
return {
|
||||
loading,
|
||||
submit,
|
||||
|
|
|
|||
|
|
@ -14,12 +14,16 @@ const wss = new WebSocket.Server({
|
|||
|
||||
wss.on("connection", function connection(ws, req) {
|
||||
ws.on("message", function incoming(message) {
|
||||
|
||||
console.log(message)
|
||||
// const parsed = JSON.parse(message)
|
||||
// console.log(parsed)
|
||||
if (message === 'no-token') {
|
||||
console.log('no token to authenticate');
|
||||
ws.send('locked');
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const ip = req.socket.remoteAddress;
|
||||
console.log("received connection from", ip);
|
||||
ws.send(JSON.stringify(testMessage));
|
||||
// ws.send(JSON.stringify(testMessage));
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue