Link a Google login to a signed-in member, explicit link only; Bifrost stores no Heimdall token #81
Loading…
Reference in a new issue
No description provided.
Delete branch "heimdall/google-link"
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?
Steps 1-5 of mind follow-up
bifrost-google-link-plan, under the steward's rulingsbifrost-google-link-bearer-fresh-signinandbifrost-google-invitation-link-only.Flow (a state machine over the existing protected attempt cookie, which carries a purpose, the expected Heimdall account id and a pending link id, never a token):
Link Googleon/Membership/Status(antiforgery) -> ordinary Heimdall sign-in, attemptLinkStart.POST /v1/oauth/google/start mode=link; browser goes to Google via Heimdall (LinkAwaitGoogle).heimdall_pending_link_id(the complete page now forwards it) -> a second fresh Heimdall sign-in (LinkConfirm).POST /links/confirm; membership refreshed from the verified identity; session untouched; fixed outcome wording for linked / identity_linked_elsewhere (409) / expired (410) / error.Google stays out of sign-in and member access. Old attempt cookies without a purpose still read as sign-in. The
Authorizationheader is now redacted from HttpClient logs (a bearer would have logged at Trace).Notes: no
/accountpage exists, so the button is on/Membership/Status. Replaying step C starts another fresh sign-in but grants nothing (pending id is single-use at Heimdall); strict single-use would need server-side consumed-nonce state, not added. The pending link id sits in the LinkConfirm cookie by design.Tests first (red 16/30 before code); Heimdall-filtered 185 pass; mutations on no-token-in-cookie, account match, session match, antiforgery, header redaction all caught. Not deployed. Needs a Google client configured in Heimdall before it can work live; Eureka decides the ship.
🤖 Generated with Claude Code