r2: bind OAuth completion to the launching browser, one use per state; gate connect starts #3
Loading…
Reference in a new issue
No description provided.
Delete branch "heimdall/r2-state-binding"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Lands the r2 cut (
gamecult-chat:cut_spec:cut-heimdall-binds-completion-to-attempt.r2) on main, plus one extra gate.What changes
gamecult-chat/heimdall-binds-completion(h1:startRequiresAppCallerfor Bifrost; r2: launch hop, signed per-flow__Host-heimdall-oauth-<jti>cookie,claimOAuthStateUsefor phases launch and callback on the in-memory store and an INSERT-onlyoauth_state_usestable, callback expiry check,authorizationUrlis now the launch URL,@fastify/cookie).initiator_account_id, pending links) and #2 (Google OIDC): the OIDC nonce and PKCE secrets are still derived from the state jti and are now put on the provider URL at the launch hop. Both stores keep pending links and gain state-use claims.mode === "connect"withinput.connectionset requires an app caller forappSlug(401 app_auth_required). Previously a creator connect start was unauthenticated while a comment claimed otherwise. Comment fixed. Failing-first test: no secret 201 before the gate, 401 after; own secret 201; foreign or wrong secret 401; direct foreign caller 401.docs/service-contract.md: launch hop, binding cookie, callback refusals, connect gate, Google secrets built at launch.Tests
Typecheck
tsc --noEmit: clean (0 errors).vitest run: 570 passed, 0 failed, 151 skipped (30 files, 28 passed, 2 skipped files). Existing Google link, link-binding and managed-credential tests were migrated to start -> launch -> callback throughtests/oauth-flow.ts; tests that start a creator connect or a Bifrost flow now send the app secret, since those starts are now gated.REQUIRED_COLUMNS101 andREQUIRED_KEYS14 after merging pending_links and oauth_state_uses. No ygg-verify here, so no StrykerJS or mutation run. Vendored CultLib dist was borrowed from the deployed release for local runs, not committed. The 151 skipped are the suite's own skips (not changed here).Deploy
Every client navigates to
authorizationUrlunchanged, so no client change is needed.startRequiresAppCaller(set on Bifrost) needs Bifrost's app secret configured in prod. Existing in-flight states from before deploy have no launch; they are refused at the callback withstate_not_bound. Not merged, not deployed.🤖 Generated with Claude Code