feat(sso): add tests for linkable existing user and enhance linking l… - #102
Merged
Conversation
…ogic for invited accounts
…g SSO for password logins
…t for connection IDs
…s multiple languages
juicycleff
approved these changes
Sep 1, 2026
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.
What
Four SSO sign-in changes:
(1) link SSO to invited-but-unactivated accounts,
(2) fire AfterSignIn for SSO logins,
(3) SSO enforcement ("Require SSO"),
(4) identifier-first SSO discovery in the shared SignInForm.
Why
(1) The link guard refused any unverified pre-existing account, breaking "admin invites → user signs in via SSO" — every invited user hit auth_failed.
(2) SSO logins go through IssueSession, which never emitted AfterSignIn, so audit/plugin hooks missed them.
(3) Enterprises mandating SSO had no way to block password fallback for their domain.
(4) The form was already email→password two-step; only home-realm discovery was missing to match Okta/MS/Google.
How
(1) In linkableExistingUser, unverified + no password → link & mark verified (IdP proves email control); has password → keep refusing (takeover vector).
(2) Emit EmitAfterSignIn in authenticateUser after the session is issued.
(3) New enforced column (migration add_enforced) + OnBeforeSignIn veto of password login for an enforced domain, with owner/admin bypass.
(4) New resolveSSO?(email) prop + SSOResolution on SignInForm: enforced → straight to IdP, optional → SSO + password, no-SSO/error → password (fails open).
Tests
link_test.go, matching_test.go, enforce_test.go, sign-in-form.sso.test.tsx (+ existing sign-in tests). Go + ui-components build/lint/suite green.