/** * The authorisation rule, on its own and free of any framework import. * * Splitting it out is what lets it be tested directly: pulling in the Auth.js * instance would drag half of Next into a unit test for six lines of policy. */ import { canWrite, type Role } from './roles'; export type Decision = { ok: true } | { ok: false; status: 401 | 403; error: string }; const READ_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']); /** * Whether a caller may perform `method`. * * Anyone the identity provider vouches for may read; only an administrator may * change anything. An unknown method counts as a write: new verbs should * arrive locked, not open. */ export function authorize(role: Role | undefined, method: string): Decision { if (!role) { return { ok: false, status: 401, error: 'Non authentifié' }; } if (READ_METHODS.has(method.toUpperCase())) { return { ok: true }; } if (!canWrite(role)) { return { ok: false, status: 403, error: 'Compte en lecture seule' }; } return { ok: true }; }