feature: add secured message
- encrypt/decrypt every message (require ^0.0.2) Signed-off-by: pakintada@gmail.com <Pakin>
This commit is contained in:
parent
4ca8b3b270
commit
2a0841a798
14 changed files with 314 additions and 147 deletions
|
|
@ -7,16 +7,20 @@ import { auth } from '../client/firebase';
|
|||
import { auth as authStore } from '$lib/core/stores/auth';
|
||||
import { addNotification } from './noti';
|
||||
import { permission } from './permissions';
|
||||
import { WebCryptoHelper } from '../utils/crypto';
|
||||
|
||||
let socket: WebSocket | null = null;
|
||||
let reconnectTimeout: any;
|
||||
let socketCheck: any;
|
||||
let sendAuthInfoInterval: any;
|
||||
const ENABLE_WS_DEBUG: boolean = false;
|
||||
|
||||
export const socketConnectionOfflineCount = writable<number>(0);
|
||||
export const socketAlreadySendHeartbeat = writable<number>(0);
|
||||
export const socketStore = writable<WebSocket | null>(null);
|
||||
|
||||
export const sharedKey = writable<CryptoKey | null>(null);
|
||||
|
||||
export function waitForOpenSocket(timeoutMs = 8000): Promise<WebSocket | null> {
|
||||
const currentSocket = get(socketStore);
|
||||
if (currentSocket?.readyState === WebSocket.OPEN) {
|
||||
|
|
@ -49,7 +53,7 @@ export function waitForOpenSocket(timeoutMs = 8000): Promise<WebSocket | null> {
|
|||
});
|
||||
}
|
||||
|
||||
export function connectToWebsocket(id_token?: string) {
|
||||
export async function connectToWebsocket(id_token?: string) {
|
||||
if (browser) {
|
||||
// console.log('connecting to ', env.PUBLIC_WSS);
|
||||
try {
|
||||
|
|
@ -57,12 +61,12 @@ export function connectToWebsocket(id_token?: string) {
|
|||
return;
|
||||
}
|
||||
|
||||
let productionMode = env.PUBLIC_WSS.startsWith('wss');
|
||||
|
||||
let ws_url = productionMode ? `${env.PUBLIC_WSS}?token=${id_token}` : `${env.PUBLIC_WSS}`;
|
||||
let ws_url = env.PUBLIC_WSS;
|
||||
socket = new WebSocket(ws_url);
|
||||
sharedKey.set(null);
|
||||
const { privateKey, publicKeyBase64 } = await WebCryptoHelper.generateKeyPair();
|
||||
|
||||
socket.addEventListener('open', () => {
|
||||
socket.addEventListener('open', async () => {
|
||||
socketStore.set(socket);
|
||||
addNotification('INFO:Connected!');
|
||||
|
||||
|
|
@ -74,29 +78,40 @@ export function connectToWebsocket(id_token?: string) {
|
|||
let auth_data = get(authStore);
|
||||
let perms = get(permission);
|
||||
|
||||
// Debug: check if auth_data has uid
|
||||
console.log('[WS Auth] Sending auth with:', {
|
||||
uid: auth_data?.uid,
|
||||
name: auth_data?.displayName,
|
||||
email: auth_data?.email
|
||||
});
|
||||
socket.send(
|
||||
JSON.stringify({
|
||||
token: id_token ?? '',
|
||||
client_public_key: publicKeyBase64
|
||||
})
|
||||
);
|
||||
|
||||
sendMessage({
|
||||
type: 'auth',
|
||||
payload: {
|
||||
user: {
|
||||
uid: auth_data?.uid ?? '',
|
||||
name: auth_data?.displayName ?? '',
|
||||
email: auth_data?.email ?? '',
|
||||
permissions: perms.join(',')
|
||||
}
|
||||
sendAuthInfoInterval = setInterval(async () => {
|
||||
if (get(sharedKey)) {
|
||||
// Debug: check if auth_data has uid
|
||||
console.log('[WS Auth] Sending auth info with:', {
|
||||
uid: auth_data?.uid,
|
||||
name: auth_data?.displayName,
|
||||
email: auth_data?.email
|
||||
});
|
||||
await sendMessage({
|
||||
type: 'auth',
|
||||
payload: {
|
||||
user: {
|
||||
uid: auth_data?.uid ?? '',
|
||||
name: auth_data?.displayName ?? '',
|
||||
email: auth_data?.email ?? '',
|
||||
permissions: perms.join(',')
|
||||
}
|
||||
}
|
||||
});
|
||||
clearInterval(sendAuthInfoInterval);
|
||||
}
|
||||
});
|
||||
}, 3000);
|
||||
}
|
||||
console.log(socket);
|
||||
|
||||
// heartbeat 10s
|
||||
socketCheck = setInterval(() => {
|
||||
socketCheck = setInterval(async () => {
|
||||
if (get(socketAlreadySendHeartbeat) > 0) {
|
||||
let heartbeat_may_offline_count = get(socketConnectionOfflineCount);
|
||||
|
||||
|
|
@ -108,13 +123,13 @@ export function connectToWebsocket(id_token?: string) {
|
|||
socketConnectionOfflineCount.set(0);
|
||||
socketAlreadySendHeartbeat.set(0);
|
||||
|
||||
connectToWebsocket(id_token);
|
||||
await connectToWebsocket(id_token);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (socket != null) {
|
||||
sendMessage({
|
||||
await sendMessage({
|
||||
type: 'heartbeat',
|
||||
payload: {}
|
||||
});
|
||||
|
|
@ -130,18 +145,19 @@ export function connectToWebsocket(id_token?: string) {
|
|||
if (auth.currentUser && socket == null) {
|
||||
console.log('try reconnect websocket ...');
|
||||
// retry again
|
||||
reconnectTimeout = setTimeout(() => {
|
||||
connectToWebsocket(id_token);
|
||||
reconnectTimeout = setTimeout(async () => {
|
||||
await connectToWebsocket(id_token);
|
||||
}, 5000);
|
||||
}
|
||||
});
|
||||
|
||||
socket.addEventListener('message', (event) => {
|
||||
handleIncomingMessages(event.data);
|
||||
socket.addEventListener('message', async (event) => {
|
||||
await handleIncomingMessages(event.data, privateKey);
|
||||
});
|
||||
|
||||
socket.addEventListener('close', () => {
|
||||
socketStore.set(null);
|
||||
sharedKey.set(null);
|
||||
socket = null;
|
||||
|
||||
clearInterval(socketCheck);
|
||||
|
|
@ -149,13 +165,14 @@ export function connectToWebsocket(id_token?: string) {
|
|||
if (auth.currentUser && !socket) {
|
||||
console.log('try reconnect websocket ...');
|
||||
// retry again
|
||||
reconnectTimeout = setTimeout(() => connectToWebsocket(id_token), 5000);
|
||||
reconnectTimeout = setTimeout(async () => await connectToWebsocket(id_token), 5000);
|
||||
}
|
||||
});
|
||||
|
||||
socket.addEventListener('error', (e) => {
|
||||
// console.log('WebSocket error: ', e);
|
||||
socketStore.set(null);
|
||||
sharedKey.set(null);
|
||||
});
|
||||
} catch (socket_error: any) {
|
||||
if (ENABLE_WS_DEBUG) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue