import { authBearer, cors } from '@pikku/core/middleware' import { addHTTPMiddleware } from '@pikku/core/http' import { betterAuthSession } from '@pikku/better-auth' const mapSession = (result: any) => ({ userId: result.user.id, // A missing/malformed memberRoles field means the auth wiring/schema is // stale — fail loudly instead of silently dropping to [] (no permissions), // which shows the real roles in the UI while every gated RPC 403s. memberRoles: (() => { const raw = result.user.memberRoles if (raw == null) { throw new Error( `Session for user ${result.user.id} has no memberRoles — auth wiring/schema is out of date`, ) } // The SQLite kysely runs SerializePlugin, so the JSON `member_roles` // column may already be deserialized to an array; only parse a string. return (Array.isArray(raw) ? raw : JSON.parse(raw)) as string[] })(), }) addHTTPMiddleware('*', [ cors({ origin: true, credentials: true }), betterAuthSession({ mapSession, impersonation: { loadUser: (userId: string, services: any) => services.kysely .selectFrom('user') .where('id', '=', userId) .select(['id', 'memberRoles']) .executeTakeFirst(), }, }), // External consoles (sandbox/woven-build view) can't carry the session cookie, // so they authenticate with `Authorization: Bearer `. The // CLI normally emits this alongside its session middleware, but our own global // session middleware makes it step aside (pikku#754) — so add the console-token // bridge here or console:* RPCs 403 in the sandbox. authBearer({ token: { secretId: 'PIKKU_CONSOLE_TOKEN', userSession: { userId: 'pikku-console-token' }, }, }), ])