import { BodyBoundCapabilityVerifier, decodeBodyBoundCapability, signBodyBoundRequest, type BodyBoundRequestSignature, type BodyBoundRequestSignatureInput, } from "../web/body-capability.js"; export const COURSE_CHAT_TIMESTAMP_HEADER = "x-thoughtstream-course-timestamp"; export const COURSE_CHAT_NONCE_HEADER = "x-thoughtstream-course-nonce"; export const COURSE_CHAT_SIGNATURE_HEADER = "x-thoughtstream-course-signature"; export const COURSE_CHAT_CSRF_HEADER = "x-thoughtstream-csrf"; export type CourseChatRequestSignatureInput = BodyBoundRequestSignatureInput; export type CourseChatRequestSignature = BodyBoundRequestSignature; export function signCourseChatRequest( key: Buffer, input: CourseChatRequestSignatureInput, ): CourseChatRequestSignature { return signBodyBoundRequest(key, input, "Course chat"); } export class CourseChatCapabilityVerifier { private readonly verifier: BodyBoundCapabilityVerifier; constructor( key: Buffer, options: { now?: (() => number) | undefined; maxSkewMs?: number | undefined; maxNonces?: number | undefined; } = {}, ) { this.verifier = new BodyBoundCapabilityVerifier(key, "Course chat", options); } verify( headers: Record, method: string, path: string, body: Buffer, ): boolean { return this.verifier.verify(headers, { timestamp: COURSE_CHAT_TIMESTAMP_HEADER, nonce: COURSE_CHAT_NONCE_HEADER, signature: COURSE_CHAT_SIGNATURE_HEADER, }, method, path, body); } } export function decodeCourseChatCapability(value: string | undefined): Buffer | undefined { return decodeBodyBoundCapability(value, "Course chat"); }