/**
* Auth RPC handlers — whoami.
*
* Phase 2a cleanup: auth-challenge, auth-verify, auth-verify-ssh, and
* auth-logout handlers are gone. Identity is established via the
* /api/rpc signed-envelope path (see `spec/flows/auth-envelope.md`).
* Session cookies are minted server-side from verified envelopes as a
* short-lived cache for SSR form POSTs.
*
* whoami stays — it's the handler /api/rpc dispatches when the browser
* calls `signRpc('whoami')` on page load. It also backs the legacy
* `/api/auth/me` GET route.
*/
export function authHandlers (svc) {
const registry = () => svc.identityRegistry
return [
{
name: 'whoami',
fn: async (ctx) => {
if (ctx && ctx.transport === 'uds') {
return {
transport: 'uds',
publicKey: null,
trust: 'local',
note: 'UDS callers are automatically trusted (local user)'
}
}
if (!ctx || !ctx.identity || !ctx.identity.publicKey) {
return { transport: ctx && ctx.transport, publicKey: null, trust: null }
}
const pkHex = ctx.identity.publicKey
const user = await registry().getUserByIdentity(pkHex).catch(() => null)
const perms = user && Array.isArray(user.globalPermissions) ? user.globalPermissions : []
// Map registry permissions back to the wire-compatible terms the
// rest of v3 uses: 'admin' → 'owner', 'write' → 'writer'.
const trustLevel = perms.includes('admin')
? 'owner'
: perms.includes('write') ? 'writer' : 'unknown'
return {
transport: ctx.transport,
publicKey: pkHex,
trust: trustLevel,
userId: user ? user.userId : null
}
}
}
]
}