Repository navigation
feat: Google sign-in and invite-only signup - #120
Merged
Merged
Conversation
Google OIDC adapter (PKCE, state, nonce, browser-bound flow cookie). Accounts link by Google subject, so email changes keep the account. Admins create, list and revoke 48h single-use invites; signup needs a verified Google email matching the invite. Without Google config the server runs admin-only.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack 2/3: Google sign-in and invite-only signup (API).
internal/googlewire adapter (authorization URL with PKCE S256, state, nonce; code exchange; ID token claim checks: issuer, audience, expiry, nonce).identityserviceowns invite and Google sign-in rules;reviewstore/invites.gopersists them. Admin creates, lists and revokes invites (/api/v2/admin/invites*): link<public URL>/invite#t=…, shown once, stored hashed, 48h, single use; re-inviting replaces the email's pending invite; an email already linked to an account is 409. Signup requires Google to report a verified email equal to the invite's; accepting uses the invite and creates the account in one transaction. Accounts are keyed by Googlesub, so an email change keeps the account and updates the recorded email. Usernames derive from the email. Google accounts without an account or invite cannot sign up.POST /api/v2/auth/google,GET /api/v2/auth/google/callback(always 303 to the app, failures as?signin=),POST /api/v2/invites/lookup,POST /api/v2/invites/google, admin invite routes andInvite. The callback is a cross-site navigation authenticated by state plus an HttpOnly flow cookie scoped to the callback path, so it runs before the same-origin check. New envDIFFX_SERVER_GOOGLE_CLIENT_ID/DIFFX_SERVER_GOOGLE_CLIENT_SECRET(secret env only); Google needsDIFFX_SERVER_PUBLIC_URL. Without Google config the server runs admin-only: Google routes 404, invite creation 409.mise run checkand pre-push pass. In-process tests against a fake Google token endpoint: invite signup, unverified or mismatched email refused, missing flow cookie and reused state refused, sign-in bysubafter an email change, uninvited account refused, disabled account refused, replaced and revoked invites unusable, member and CSRF refused on admin routes, unconfigured server. Store tests include concurrent acceptance yielding one account. Real-binary script (35 checks): config validation, authorize URL parameters, cookie attributes, hashed secrets, callback failures, replace/revoke. Not tested against real Google with real credentials yet.internal/google. Docs andcompose.yamldescribe the Google settings and redirect URI.