// What shows of the signed-in user: the name and e-mail authelia // reports, the initials avatar built from them, and the authelia pages the // menu links. Pure, so the swarm UI's tests can run it. export interface WhoAmI { displayName: string | null; email: string | null; } // The seven chromatic theme colours the avatar is picked from, by name. const AVATAR_ACCENTS = [ "var(--red)", "var(--yellow)", "var(--green)", "var(--cyan)", "var(--blue)", "var(--purple)", "var(--pink)", ]; /** A colour for `seed`: the same name always gets the same one. */ export function pickAccent(seed: string): string { let hash = 0; for (let i = 0; i < seed.length; i++) hash = (hash * 31 + seed.charCodeAt(i)) | 0; return AVATAR_ACCENTS[Math.abs(hash) % AVATAR_ACCENTS.length]; } /** * Lenient parse of authelia's `GET /api/user/info`, which wraps its answer in * a `{status, data}` envelope. The menu is cosmetic, so a shape that is not * recognised gives no name rather than an error. */ export function parseWhoAmI(body: unknown): WhoAmI { const record = (body ?? {}) as Record; const data = (record.data ?? record) as Record; const displayName = typeof data.display_name === "string" ? data.display_name : null; const emails = Array.isArray(data.emails) ? data.emails : null; const email = emails && typeof emails[0] === "string" ? (emails[0] as string) : null; return { displayName, email }; } /** The name to show: the display name, else the e-mail, else none. */ export function labelOf(who: WhoAmI | null): string | null { return who?.displayName || who?.email || null; } /** The letter in the avatar, or "?" when there is no name. */ export function initialOf(label: string | null): string { return label ? label.trim().charAt(0).toUpperCase() : "?"; } /** Authelia's settings and sign-out pages under `autheliaUrl`, if it is known. */ export function accountLinks( autheliaUrl: string | null, ): { settings: string; logout: string } | null { if (!autheliaUrl) return null; // The trailing slash comes off so `/settings` appends cleanly. const base = autheliaUrl.replace(/\/+$/, ""); return { settings: `${base}/settings`, logout: `${base}/logout` }; }