import { opaque } from "../shared/bridge.ts"; export interface LoginChallenge { state: string; bindingHash: string; verifier: string; challenge: string; expiresAt: number; } // Separate application tables: never Agent broadcast state or Think history. export class BridgeStore { constructor(private readonly storage: DurableObjectStorage) {} initialize() { this.storage.sql.exec( `CREATE TABLE IF NOT EXISTS flarebot_login_challenges (state TEXT PRIMARY KEY, binding_hash TEXT NOT NULL, verifier TEXT NOT NULL, challenge TEXT NOT NULL, expires_at INTEGER NOT NULL)`, ); this.storage.sql.exec( `CREATE TABLE IF NOT EXISTS flarebot_health_replays (jti TEXT PRIMARY KEY, expires_at INTEGER NOT NULL)`, ); this.storage.sql.exec( `CREATE TABLE IF NOT EXISTS flarebot_health_probes (operation_id TEXT NOT NULL, digest TEXT NOT NULL, probe_id TEXT NOT NULL UNIQUE, status TEXT NOT NULL, expires_at INTEGER NOT NULL, PRIMARY KEY(operation_id,digest))`, ); this.prune(); } private prune() { const now = Date.now(); this.storage.sql.exec( "DELETE FROM flarebot_login_challenges WHERE expires_at <= ?", now, ); this.storage.sql.exec( "DELETE FROM flarebot_health_replays WHERE expires_at <= ?", now, ); // Pending probes are retained until actual native teardown acknowledges. this.storage.sql.exec( "DELETE FROM flarebot_health_probes WHERE status = 'complete' AND expires_at <= ?", now, ); } create(value: LoginChallenge) { if ( ![value.state, value.bindingHash, value.verifier, value.challenge].every( opaque, ) || !Number.isSafeInteger(value.expiresAt) || value.expiresAt <= Date.now() || value.expiresAt > Date.now() + 600_000 ) throw new Error("Invalid login challenge"); this.storage.transactionSync(() => { this.prune(); const count = this.storage.sql .exec<{ count: number }>( "SELECT count(*) AS count FROM flarebot_login_challenges", ) .one().count; if (count >= 128) throw new Error("Login unavailable"); this.storage.sql.exec( "INSERT INTO flarebot_login_challenges VALUES (?, ?, ?, ?, ?)", value.state, value.bindingHash, value.verifier, value.challenge, value.expiresAt, ); }); } claim(state: string, bindingHash: string): LoginChallenge | null { if (!opaque(state) || !opaque(bindingHash)) return null; return this.storage.transactionSync(() => { this.prune(); const rows = this.storage.sql .exec<{ state: string; binding_hash: string; verifier: string; challenge: string; expires_at: number; }>( "DELETE FROM flarebot_login_challenges WHERE state = ? AND binding_hash = ? RETURNING *", state, bindingHash, ) .toArray(); const value = rows[0]; return value ? { state: value.state, bindingHash: value.binding_hash, verifier: value.verifier, challenge: value.challenge, expiresAt: value.expires_at, } : null; }); } beginHealth( jti: string, expiresAt: number, operationId: string, digest: string, ): { cached: boolean; probeId: string } { if ( !opaque(jti) || !Number.isSafeInteger(expiresAt) || expiresAt <= Date.now() || expiresAt > Date.now() + 60_000 || !/^[a-f0-9]{32}$/.test(operationId) || !/^[a-f0-9]{64}$/.test(digest) ) throw new Error("Invalid health challenge"); const result = this.storage.transactionSync(() => { this.prune(); if ( this.storage.sql .exec<{ count: number }>( "SELECT count(*) AS count FROM flarebot_health_replays", ) .one().count >= 128 ) throw new Error("Health unavailable"); this.storage.sql.exec( "INSERT INTO flarebot_health_replays VALUES (?, ?)", jti, expiresAt, ); const existing = this.storage.sql .exec<{ status: string; probe_id: string }>( "SELECT status, probe_id FROM flarebot_health_probes WHERE operation_id = ? AND digest = ?", operationId, digest, ) .toArray()[0]; if (existing?.status === "complete") return { cached: true, probeId: existing.probe_id }; if ( existing || this.storage.sql .exec( "SELECT probe_id FROM flarebot_health_probes WHERE status = 'pending'", ) .toArray().length ) return { cached: false, probeId: "" }; if ( this.storage.sql .exec<{ count: number }>( "SELECT count(*) AS count FROM flarebot_health_probes", ) .one().count >= 32 ) return { cached: false, probeId: "" }; const probeId = `health-${crypto.randomUUID()}`; this.storage.sql.exec( "INSERT INTO flarebot_health_probes VALUES (?, ?, ?, 'pending', ?)", operationId, digest, probeId, Date.now() + 86_400_000, ); return { cached: false, probeId }; }); if (!result.probeId) throw new Error("Health pending"); return result; } pending() { return this.storage.sql .exec<{ probe_id: string }>( "SELECT probe_id FROM flarebot_health_probes WHERE status = 'pending'", ) .toArray() .map((row) => row.probe_id); } closed(probeId: string, successful: boolean) { if (successful) this.storage.sql.exec( "UPDATE flarebot_health_probes SET status = 'complete' WHERE probe_id = ?", probeId, ); else this.storage.sql.exec( "DELETE FROM flarebot_health_probes WHERE probe_id = ?", probeId, ); } }