import { UnauthorizedError, extractBearerToken } from "@continuum/ts-core"; /** * Edge-token checking for the `/ws/edge/v1` upgrade, with no imports beyond * the error types - the same reason `dispatch/job_status.ts` and `stream.ts` * are leaf modules: `../db` opens a connection at import time, and this is * the authentication boundary for the whole gateway protocol, so it is the * last thing that should only be reachable through a running database. */ /** * Whatever verifies an edge JWT. Narrowed to what this needs rather than * taking the `@elysiajs/jwt` decorator's type, so a test can pass a stub and * exercise the real decision logic. */ export type EdgeTokenVerifier = ( token: string, ) => Promise | false | null | undefined>; /** * The farm a verified edge token belongs to, or an `UnauthorizedError`. * * Every failure gets one message. Which part of a forged token to fix next - * signature, scope, expiry - is not something to tell whoever is holding * one; the reason is logged instead. Same reasoning as `requireUser`. * * The farm is returned rather than the claims: it is the only thing the * socket needs, and handing back the whole payload invites a later caller to * start trusting some other claim without deciding to. */ export async function farmFromEdgeUpgrade( authorization: string | null | undefined, verify: EdgeTokenVerifier, ): Promise { let token: string; try { token = extractBearerToken(authorization); } catch { throw new UnauthorizedError("Authorization header must be 'Bearer '"); } const payload = await verify(token); // `scope` is checked, not just the signature: the same secret could be // made to sign something else one day, and a token minted for another // purpose must not open a farm's gateway socket. if (!payload || payload.scope !== "edge") { console.warn("[edge] upgrade rejected: token missing or not scoped to edge"); throw new UnauthorizedError("Invalid or expired edge token"); } // A token whose farm claim is absent or not a string would otherwise // produce a connection whose `farmId` is `undefined`, which reads as // "every farm" to anything doing a lookup. if (typeof payload.farmId !== "string" || payload.farmId.length === 0) { console.warn("[edge] upgrade rejected: edge token carries no farm"); throw new UnauthorizedError("Invalid or expired edge token"); } return payload.farmId; }