marmar-context / web / context / server / demo-auth.ts
demo-auth.ts
Raw
// ACC-2 and ACC-11 on the hosted site: Try a fictional patient needs no account and no shared
// password. Each browser gets a random demo id (it only keeps one browser's drafts apart), and
// the demo reads only the fictional patients' own records, with the local reader.
import { randomUUID } from "node:crypto";
import { CASES } from "./cases";
import { ModelError } from "./model-runtime";

const COOKIE = "__Host-marmar-context-demo";
const TTL = 2 * 60 * 60;
const FICTIONAL = new Set(CASES.flatMap((c) => c.sources.map((s) => s.text)));

/** The browser's demo id, and the cookie to set when it is new. */
export function demoOwner(request: Request): { owner: string; setCookie: string | null } {
  const token = request.headers
    .get("Cookie")
    ?.split(";")
    .map((x) => x.trim())
    .find((x) => x.startsWith(COOKIE + "="))
    ?.slice(COOKIE.length + 1);
  if (token && /^[a-f0-9-]{36}$/.test(token)) return { owner: `demo-${token}`, setCookie: null };
  const id = randomUUID();
  return { owner: `demo-${id}`, setCookie: `${COOKIE}=${id}; Secure; HttpOnly; SameSite=Strict; Path=/; Max-Age=${TTL}` };
}

/** Only the fictional patients' records, never pasted or real text, and never the model. */
export function demoOnly(sources: { text: string; clarification?: unknown }[], useModel = false) {
  if (useModel) throw new ModelError("Try a fictional patient uses the local reader only. No model is called.", 403);
  if (!sources.every((s) => !s.clarification && FICTIONAL.has(s.text)))
    throw new ModelError("Try a fictional patient reads the fictional patients' records only.", 403);
}