diff --git a/docs/src/03-services.md b/docs/src/03-services.md index 711209aa8..c665052ee 100644 --- a/docs/src/03-services.md +++ b/docs/src/03-services.md @@ -170,6 +170,17 @@ const socket = io(BACKEND_URL, { }); ``` +### Socket event contract (Tauri) + +In Tauri mode, the Rust socket forwards server events to the frontend via the `server:event` Tauri event. The frontend listens and can emit back via `emitViaRustSocket` (see `utils/tauriSocket.ts`). + +| Direction | Event name | Payload | Description | +|------------|----------------------------|----------------------------------|-------------| +| Backend → | `request:encryption_key` | (any) | Backend requests the client’s encryption key. | +| Frontend → | `encryption_key` | `{ encryptionKey: string \| null }` | Frontend sends `encryptionKeyByUser` for the current user from authSlice. | + +Constants: `REQUEST_ENCRYPTION_KEY`, `ENCRYPTION_KEY_EVENT` (exported from `utils/tauriSocket.ts`). + ## MTProto Service (`services/mtprotoService.ts`) Telegram MTProto client singleton. diff --git a/src/utils/tauriSocket.ts b/src/utils/tauriSocket.ts index b78e22795..aa478fb9b 100644 --- a/src/utils/tauriSocket.ts +++ b/src/utils/tauriSocket.ts @@ -12,6 +12,10 @@ * Legacy bridge (for backwards compatibility during migration): * - socket:should_connect / socket:should_disconnect * - report_socket_connected / disconnected / error + * + * Socket event contract (backend <-> frontend): + * - Backend emits: REQUEST_ENCRYPTION_KEY — frontend should reply with encryption key. + * - Frontend emits: ENCRYPTION_KEY_EVENT — payload { encryptionKey: string | null } from authSlice. */ import { isTauri as coreIsTauri, invoke } from '@tauri-apps/api/core'; import { listen, UnlistenFn } from '@tauri-apps/api/event'; @@ -20,6 +24,12 @@ import { store } from '../store'; import { setSocketIdForUser, setStatusForUser } from '../store/socketSlice'; import { BACKEND_URL } from './config'; +/** Event name the backend emits to request the client’s encryption key. */ +export const REQUEST_ENCRYPTION_KEY = 'request:encryption_key'; + +/** Event name the frontend emits with encryptionKeyByUser (authSlice) for the current user. */ +export const ENCRYPTION_KEY_EVENT = 'encryption_key'; + // Check if we're running in Tauri export const isTauri = (): boolean => { return coreIsTauri(); @@ -154,8 +164,16 @@ export async function setupTauriSocketListeners(): Promise { // Listen for forwarded server events unlistenServerEvent = await listen<{ event: string; data: unknown }>('server:event', event => { - console.log('[TauriSocket] Server event:', event.payload.event, event.payload.data); - // Future: dispatch to specific handlers based on event type + const { event: eventName, data } = event.payload; + console.log('[TauriSocket] Server event:', eventName, data); + + if (eventName === REQUEST_ENCRYPTION_KEY) { + const state = store.getState(); + const userId = + state.user.user?._id ?? getSocketUserId(); + const encryptionKey = state.auth.encryptionKeyByUser[userId] ?? null; + void emitViaRustSocket(ENCRYPTION_KEY_EVENT, { encryptionKey }); + } }); // Legacy: Listen for connect requests from Rust (backwards compat)