From e2cbe11a5f30455a3e86f119b112895227dcbbc4 Mon Sep 17 00:00:00 2001 From: Owen Date: Fri, 16 Jan 2026 14:19:36 -0800 Subject: [PATCH] Send error codes down to olm --- server/routers/olm/error.ts | 28 +++++++++++ server/routers/olm/getUserOlm.ts | 4 +- .../routers/olm/handleOlmRegisterMessage.ts | 49 +++++++++++++++++-- 3 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 server/routers/olm/error.ts diff --git a/server/routers/olm/error.ts b/server/routers/olm/error.ts new file mode 100644 index 00000000..978c1a1a --- /dev/null +++ b/server/routers/olm/error.ts @@ -0,0 +1,28 @@ +import { sendToClient } from "#dynamic/routers/ws"; +// Error codes for registration failures +export const OlmErrorCodes = { + OLM_NOT_FOUND: "OLM_NOT_FOUND", + CLIENT_ID_NOT_FOUND: "CLIENT_ID_NOT_FOUND", + CLIENT_NOT_FOUND: "CLIENT_NOT_FOUND", + CLIENT_BLOCKED: "CLIENT_BLOCKED", + ORG_NOT_FOUND: "ORG_NOT_FOUND", + USER_ID_NOT_FOUND: "USER_ID_NOT_FOUND", + INVALID_USER_SESSION: "INVALID_USER_SESSION", + USER_ID_MISMATCH: "USER_ID_MISMATCH", + ACCESS_POLICY_DENIED: "ACCESS_POLICY_DENIED" +} as const; + +// Helper function to send registration error +export async function sendOlmError( + code: string, + errorMessage: string, + olmId: string +) { + sendToClient(olmId, { + type: "olm/error", + data: { + code, + message: errorMessage + } + }); +} diff --git a/server/routers/olm/getUserOlm.ts b/server/routers/olm/getUserOlm.ts index dc0bfde3..578438f8 100644 --- a/server/routers/olm/getUserOlm.ts +++ b/server/routers/olm/getUserOlm.ts @@ -8,8 +8,8 @@ import response from "@server/lib/response"; import { z } from "zod"; import { fromError } from "zod-validation-error"; import logger from "@server/logger"; -import { OpenAPITags, registry } from "@server/openApi"; import { getUserDeviceName } from "@server/db/names"; +// import { OpenAPITags, registry } from "@server/openApi"; const paramsSchema = z .object({ @@ -101,7 +101,7 @@ export async function getUserOlm( const model = result.fingerprints?.deviceModel || null; const newName = getUserDeviceName(model, olm.name); - const responseData = blocked !== undefined + const responseData = blocked !== undefined ? { ...olm, name: newName, blocked } : { ...olm, name: newName }; diff --git a/server/routers/olm/handleOlmRegisterMessage.ts b/server/routers/olm/handleOlmRegisterMessage.ts index 46241603..0c69ce8d 100644 --- a/server/routers/olm/handleOlmRegisterMessage.ts +++ b/server/routers/olm/handleOlmRegisterMessage.ts @@ -27,6 +27,7 @@ import config from "@server/lib/config"; import { encodeHexLowerCase } from "@oslojs/encoding"; import { sha256 } from "@oslojs/crypto/sha2"; import { buildSiteConfigurationForOlmClient } from "./buildConfiguration"; +import { OlmErrorCodes, sendOlmError } from "./error"; export const handleOlmRegisterMessage: MessageHandler = async (context) => { logger.info("Handling register olm message!"); @@ -53,6 +54,11 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { if (!olm.clientId) { logger.warn("Olm client ID not found"); + sendOlmError( + OlmErrorCodes.CLIENT_ID_NOT_FOUND, + "Olm client ID not found", + olm.olmId + ); return; } @@ -64,11 +70,23 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { if (!client) { logger.warn("Client ID not found"); + sendOlmError( + OlmErrorCodes.CLIENT_NOT_FOUND, + "Client not found in organization", + olm.olmId + ); return; } if (client.blocked) { - logger.debug(`Client ${client.clientId} is blocked. Ignoring register.`); + logger.debug( + `Client ${client.clientId} is blocked. Ignoring register.` + ); + sendOlmError( + OlmErrorCodes.CLIENT_BLOCKED, + "Client is blocked", + olm.olmId + ); return; } @@ -80,12 +98,22 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { if (!org) { logger.warn("Org not found"); + sendOlmError( + OlmErrorCodes.ORG_NOT_FOUND, + "Organization not found", + olm.olmId + ); return; } if (orgId) { if (!olm.userId) { logger.warn("Olm has no user ID"); + sendOlmError( + OlmErrorCodes.USER_ID_NOT_FOUND, + "User ID not found for this client", + olm.olmId + ); return; } @@ -93,10 +121,20 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { await validateSessionToken(userToken); if (!userSession || !user) { logger.warn("Invalid user session for olm register"); - return; // by returning here we just ignore the ping and the setInterval will force it to disconnect + sendOlmError( + OlmErrorCodes.INVALID_USER_SESSION, + "Invalid or expired user session token", + olm.olmId + ); + return; } if (user.userId !== olm.userId) { logger.warn("User ID mismatch for olm register"); + sendOlmError( + OlmErrorCodes.USER_ID_MISMATCH, + "User ID does not match the authenticated session", + olm.olmId + ); return; } @@ -114,6 +152,11 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { logger.warn( `Olm user ${olm.userId} does not pass access policies for org ${orgId}: ${policyCheck.error}` ); + sendOlmError( + OlmErrorCodes.ACCESS_POLICY_DENIED, + `Access policy denied: ${policyCheck.error}`, + olm.olmId + ); return; } } @@ -151,7 +194,7 @@ export const handleOlmRegisterMessage: MessageHandler = async (context) => { .update(clients) .set({ pubKey: publicKey, - archived: false, + archived: false }) .where(eq(clients.clientId, client.clientId));