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 {
|
export function main(): void {
|
||||||
|
|
||||||
// Instantiate socket session with crimata-platorm.
|
|
||||||
initSession();
|
|
||||||
|
|
||||||
// mount auth-user listener
|
|
||||||
ipcMain.on('auth-user', authUser);
|
|
||||||
|
|
||||||
// create main window.
|
// create main window.
|
||||||
const win = createWindow({ width: 350, height: 525, resizable: false });
|
const win = createWindow({ width: 350, height: 525, resizable: false });
|
||||||
|
|
||||||
|
|
@ -34,18 +28,17 @@ export function main(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const windowMount = (): void => {
|
const windowMount = (): void => {
|
||||||
|
// Instantiate socket session with crimata-platorm.
|
||||||
|
initSession();
|
||||||
windowEmitter.emit('window-active', true);
|
windowEmitter.emit('window-active', true);
|
||||||
// ipc event handlers
|
|
||||||
ipcMain.on('send-message', handleMessage);
|
ipcMain.on('send-message', handleMessage);
|
||||||
ipcMain.on('auth-login', authLogin);
|
ipcMain.on('auth-login', authLogin);
|
||||||
}
|
}
|
||||||
|
|
||||||
const windowDismount = (): void => {
|
const windowDismount = (): void => {
|
||||||
windowEmitter.emit('window-active', false);
|
windowEmitter.emit('window-active', false);
|
||||||
// TODO: Gracefully close socket connection
|
|
||||||
ipcMain.removeAllListeners('send-message');
|
ipcMain.removeAllListeners('send-message');
|
||||||
ipcMain.removeAllListeners('auth-login');
|
ipcMain.removeAllListeners('auth-login');
|
||||||
ipcMain.removeAllListeners('auth-user');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle window mount and dismount.
|
// Handle window mount and dismount.
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import WebSocket from 'ws';
|
import WebSocket from 'ws';
|
||||||
import { windowEmitter } from './windowEmitter';
|
import { windowEmitter } from './windowEmitter';
|
||||||
|
import { ipcMain } from "electron";
|
||||||
|
|
||||||
type Message = {
|
type Message = {
|
||||||
type: string;
|
type: string;
|
||||||
|
|
@ -14,85 +15,87 @@ interface RenderMessage extends Message {
|
||||||
time: string;
|
time: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AuthMessage extends Message {
|
interface AuthUser extends Message {
|
||||||
email: string;
|
email: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
access_token: string;
|
access_token: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AuthRequest {
|
|
||||||
token: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PostLogin {
|
|
||||||
email: string;
|
|
||||||
password: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PostMessage {
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const ip = 'ws://localhost';
|
const ip = 'ws://localhost';
|
||||||
const port = 8080;
|
const port = 8080;
|
||||||
const username = 'hernandeze2@xavier.edu';
|
const reconnectTimeout = 3000; //ms
|
||||||
let socket: WebSocket;
|
let socket: WebSocket;
|
||||||
|
let success = false;
|
||||||
|
|
||||||
const receiveMessage = (message: string): void => {
|
const receiveMessage = (message: string): void => {
|
||||||
// NOTE assuming message is JSON string
|
// 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") {
|
if (parsed.type === "render") {
|
||||||
windowEmitter.emit('ipc-renderer', {
|
windowEmitter.emit('ipc-renderer', {
|
||||||
endpoint: 'render-message',
|
endpoint: 'render-message',
|
||||||
message: parsed
|
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() {
|
export function initSession() {
|
||||||
|
|
||||||
let success = false;
|
|
||||||
socket = new WebSocket(`${ip}:${port}`);
|
socket = new WebSocket(`${ip}:${port}`);
|
||||||
socket.binaryType = 'arraybuffer';
|
socket.binaryType = 'arraybuffer';
|
||||||
|
|
||||||
socket.on('open', () => {
|
socket.on('open', () => {
|
||||||
console.log('Connected to crimata-platform');
|
console.log('Connected to crimata-platform');
|
||||||
socket.send(username);
|
|
||||||
success = true;
|
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);
|
socket.on("message", receiveMessage);
|
||||||
|
|
||||||
setTimeout(()=> {
|
setTimeout(()=> {
|
||||||
if (!success) {
|
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) => {
|
export const authLogin = (event: any, arg: any) => {
|
||||||
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) => {
|
|
||||||
try {
|
try {
|
||||||
sendMessage(arg)
|
sendMessage(arg)
|
||||||
windowEmitter.on('auth-resp', (payload: AuthMessage) => {
|
windowEmitter.on('auth-resp', (payload: AuthUser) => {
|
||||||
event.reply('auth-login-reply', payload);
|
event.reply('auth-login-reply', payload);
|
||||||
})
|
})
|
||||||
} catch(e) {
|
} 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) {
|
if (content instanceof Buffer) {
|
||||||
socket.send(content);
|
socket.send(content);
|
||||||
} else {
|
} else if (content){
|
||||||
socket.send(JSON.stringify(content));
|
socket.send(JSON.stringify(content));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,23 @@ const state = reactive<AuthState>({
|
||||||
const AUTH_KEY = 'crimata_token';
|
const AUTH_KEY = 'crimata_token';
|
||||||
|
|
||||||
const token = window.localStorage.getItem(AUTH_KEY);
|
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) {
|
if (token) {
|
||||||
const { loading, error, data, send } = useIpc('auth-user');
|
const { loading, error, data, send, invoke } = useIpc('auth-user');
|
||||||
|
|
||||||
state.authenticating = true;
|
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) => {
|
const send = (payload?: Record<string, any>, callback?: (arg: any) => void) => {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
error.value = undefined;
|
error.value = undefined;
|
||||||
|
|
@ -46,6 +60,7 @@ export const useIpc = (endpoint: string) => {
|
||||||
data,
|
data,
|
||||||
error,
|
error,
|
||||||
errorMessage,
|
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,
|
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 () => {
|
const submit = async () => {
|
||||||
// console.log(toRefs(payload));
|
// console.log(toRefs(payload));
|
||||||
send({
|
await invoke({
|
||||||
request: "register",
|
request: "register",
|
||||||
email: payload.email,
|
email: payload.email,
|
||||||
password: payload.password,
|
password: payload.password,
|
||||||
});
|
})
|
||||||
console.log(data.value, "login");
|
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 {
|
return {
|
||||||
loading,
|
loading,
|
||||||
submit,
|
submit,
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,16 @@ const wss = new WebSocket.Server({
|
||||||
|
|
||||||
wss.on("connection", function connection(ws, req) {
|
wss.on("connection", function connection(ws, req) {
|
||||||
ws.on("message", function incoming(message) {
|
ws.on("message", function incoming(message) {
|
||||||
|
|
||||||
console.log(message)
|
console.log(message)
|
||||||
// const parsed = JSON.parse(message)
|
if (message === 'no-token') {
|
||||||
// console.log(parsed)
|
console.log('no token to authenticate');
|
||||||
|
ws.send('locked');
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ip = req.socket.remoteAddress;
|
const ip = req.socket.remoteAddress;
|
||||||
console.log("received connection from", ip);
|
console.log("received connection from", ip);
|
||||||
ws.send(JSON.stringify(testMessage));
|
// ws.send(JSON.stringify(testMessage));
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue