// Tiny helpers shared between the Node-side global setup and any in-spec // helpers that need to reproduce the worker's token-hashing scheme. // Mirrors src/worker/services/crypto.ts (which uses Web Crypto, identical // behaviour in Node 20+). export const encodeBase64Url = (bytes: Uint8Array): string => Buffer.from(bytes).toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, ""); // Mirrors src/worker/services/crypto.ts — base64url-encoded digest, NOT // hex. The worker hashes invite tokens with this scheme; we have to match // it byte-for-byte so the hash we INSERT in setup matches the hash the // worker computes when the spec POSTs the token to /api/invite/. export const sha256 = async (input: string): Promise => { const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(input)); return encodeBase64Url(new Uint8Array(digest)); };