/** * Azure (Entra ID) authentication helpers. * * Canonical, unit-tested home for the small pieces of auth logic shared by the * frontend. The PocketBase hook `pb_hooks/team_members.pb.js` re-implements * `resolveRole` / `parseAdminEmails` in the JSVM runtime (it cannot import this * module) — keep the two in sync. * * Login itself goes through PocketBase's built-in OAuth2 flow: * pb.collection('team_members').authWithOAuth2({ provider: OIDC_PROVIDER }) * The OIDC provider ("oidc") is configured against Entra in migration * 1781000000_team_members_to_auth.js. */ /** Provider name registered on the `team_members` auth collection. */ export const OIDC_PROVIDER = 'oidc'; /** * Parse the ENTRA_ADMIN_EMAILS-style comma-separated allow-list into a * normalised (lower-cased, trimmed, de-duplicated, empty-free) array. * @param {string} [csv] * @returns {string[]} */ export function parseAdminEmails(csv) { if (!csv) return []; const seen = new Set(); for (const part of String(csv).toLowerCase().split(',')) { const email = part.trim(); if (email) seen.add(email); } return [...seen]; } /** * Resolve a user's role from their e-mail and the admin allow-list. * @param {string} email * @param {string} [adminEmailsCsv] * @returns {'admin'|'user'} */ export function resolveRole(email, adminEmailsCsv) { const allow = parseAdminEmails(adminEmailsCsv); return allow.includes(String(email || '').trim().toLowerCase()) ? 'admin' : 'user'; } /** * Derive a display name from OIDC claims, falling back to the e-mail prefix. * @param {{ name?: string }} [claims] * @param {string} [email] * @returns {string} */ export function deriveName(claims, email) { const fromClaim = claims && typeof claims.name === 'string' ? claims.name.trim() : ''; if (fromClaim) return fromClaim; if (email && email.includes('@')) return email.split('@')[0]; return 'Onbekend'; }