/** * ctx.secrets — what a handler needs when it mints credentials: a random * secret of the requested length from a URL-safe alphabet, from the * platform's CSPRNG. Nothing is stored here; what the handler returns as a * secret attribute is what the platform stores. */ import { randomInt } from "crypto"; const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; export interface Secrets { /** A random string of `length` characters (default 32) from letters and digits. */ generate(length?: number): Promise; } export const secrets: Secrets = { async generate(length = 32) { if (!Number.isInteger(length) || length < 8 || length > 512) throw new Error("secrets.generate: length must be 8..512"); let out = ""; for (let i = 0; i < length; i++) out += ALPHABET[randomInt(ALPHABET.length)]; return out; }, };