import { getUsers, getUserByEmail } from 'officerdb'; // Who this platform knows about, loaded once at launch. // // This is a CLASSIFIER, never a gate. Nothing here decides whether a request is allowed — the signin // handler still does its own database lookup and is the only thing that authenticates. The snapshot // exists so the audit middleware can answer one question cheaply, on the hot path of an unauthenticated // endpoint: "is the name in this request even one of ours?" A wrong answer costs a spurious log line or // a missing one, never access. // // It holds emails AND usernames because both are identities a caller can present, and both are unique // columns on `users`. Matching is case-insensitive: an attempt on OWNER@example.com is the owner's own // address typed differently, not a stranger, and logging it as an intrusion would train the owner to // ignore the file. // // Single-user is a hard invariant here, so this set has two entries in practice. It is a Set rather // than a string because that invariant is the platform's, not this file's, and a Set costs nothing. let snapshot: Set | null = null; const key = (identity: string) => identity.trim().toLowerCase(); const identitiesOf = (user: { email: string; username: string | null }): string[] => [user.email, user.username].filter((value): value is string => typeof value === 'string' && !!value.trim()); /** Read every account into memory. Called once at launch; safe to call again to refresh. */ export async function loadKnownUsers(): Promise { const users = await getUsers(); snapshot = new Set(users.flatMap(identitiesOf).map(key)); return snapshot.size; } /** * Fold a newly created account in. Bootstrap is the only path that mints one, and without this the * owner's very first sign-in after creating the account would be logged as a stranger — the snapshot * having been taken while the user table was still empty. */ export function rememberUser(user: { email: string; username: string | null }): void { if (!snapshot) return; for (const identity of identitiesOf(user)) snapshot.add(key(identity)); } /** How many identities are loaded, or null if the launch-time load has not succeeded. */ export const knownIdentityCount = (): number | null => snapshot?.size ?? null; /** * Whether an identity belongs to an account. Falls back to the database when the launch-time load * never ran or failed — a Postgres blip at boot must not turn every later login into an alert. */ export async function isKnownIdentity(identity: string): Promise { const wanted = key(identity); if (!wanted) return false; if (snapshot) return snapshot.has(wanted); const user = await getUserByEmail(identity).catch(() => undefined); return !!user; }