import { createHmac, randomUUID, timingSafeEqual } from "node:crypto"; import type { AgentBffPrincipalResolution } from "@agents24/node/bff"; import { getServerEnvironment } from "./env"; const COOKIE = "agents24_app_session"; const MAX_AGE = 60 * 60 * 24 * 30; function signature(value: string): string { return createHmac("sha256", getServerEnvironment().SESSION_COOKIE_SECRET).update(value).digest("base64url"); } function parseCookies(request: Request): Record { return Object.fromEntries(String(request.headers.get("cookie") || "").split(";").flatMap((part) => { const pivot = part.indexOf("="); if (pivot < 1) return []; return [[part.slice(0, pivot).trim(), decodeURIComponent(part.slice(pivot + 1).trim())]]; })); } function verifiedId(value: string | undefined): string | null { const pivot = String(value || "").lastIndexOf("."); if (pivot < 1) return null; const id = String(value).slice(0, pivot); const supplied = Buffer.from(String(value).slice(pivot + 1)); const expected = Buffer.from(signature(id)); return supplied.length === expected.length && timingSafeEqual(supplied, expected) ? id : null; } function secure(request: Request): boolean { return request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim() === "https" || new URL(request.url).protocol === "https:"; } function cookie(value: string, request: Request, maxAge = MAX_AGE): string { return `${COOKIE}=${encodeURIComponent(value)}; Path=/; HttpOnly; SameSite=Lax; Max-Age=${maxAge}${secure(request) ? "; Secure" : ""}`; } // Replace this function with your application session lookup. Never accept a // user ID supplied by browser request data. Authenticated hosts may also return // a stable `issuer` to share customer governance across Agents and applications. export function resolveAgents24Principal(request: Request): AgentBffPrincipalResolution { const existing = verifiedId(parseCookies(request)[COOKIE]); const subject = existing || randomUUID(); return { principal: { subject, externalSessionId: subject }, ...(existing ? {} : { responseHeaders: { "Set-Cookie": cookie(`${subject}.${signature(subject)}`, request) } }), }; } export function revokeAgents24Principal(request: Request): HeadersInit { return { "Set-Cookie": cookie("", request, 0) }; }