The sign-in page builds each enterprise SSO button from the provider's
loginPath. BrowserAuth set loginPath only for oauth and site logins, so
the console and Pod login pages received null, and the browser opened
/null?purpose=console&... and hit Phoenix.Router.NoRouteError.
Console providers now link to /sessions/oidc/:provider_id/authorization
on the current site host, because console login never leaves that host.
Pod providers link to the same endpoint on the target Pod origin, as
oauth and site providers already do. PodURL.oidc_authorization_path/1
owns the path, and BrowserSessions.md states which host each ceremony
uses.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
On the Site Admin Console sign-in page (
/sessions/new?purpose=console), clicking an enterprise SSO button such as Feishu opens/null?purpose=console&return_to=...and fails withPhoenix.Router.NoRouteError. The Pod sign-in page has the same fault.Cause. Since d20cc01 the sign-in page builds each SSO button with
new URL(provider.loginPath, window.location.origin)instead of a fixed/sessions/oidc/:provider_id/authorizationpath.AnkoleWeb.BrowserAuthaddslogin_pathto OIDC providers only foroauthand tenant-targetedsitelogins. Forconsoleandpodlogins it returnsLoginPolicy.login_providers()directly, and those entries have nologin_path.loginProviderstherefore returnedloginPath: null(although the response declares it non-null), andnew URL(null, origin)resolves to/null.Fix.
consolelogin gives each OIDC provider the path/sessions/oidc/:provider_id/authorizationon the current host. Console login always runs on the site host andTargets.resolve/2rejects it on Pod hosts. A Pod origin would point to the privileged tenant's subdomain.podlogin gives each OIDC provider that endpoint on the target Pod origin (PodURL.origin/2), asoauthandsitelogins already do. A Pod target can come from an explicittenant_idon a non-Pod host, and the SSO button does not forwardtenant_id, so a relative path would lose the tenant.provider_login_path/2takes the origin.PodURL.oidc_authorization_path/1owns the path, andoidc_authorization_url/3returns the same URLs as before.BrowserSessions.mdstates which hostloginPathuses for each ceremony. Changelog:2.1.0-alpha.6.Verification
auth_controller_test.exs: the console OIDC test now readsloginPathfromGET /api/v2/browser/identity-providers?purpose=consoleand follows it to the upstream redirect, instead of using a hard-coded path. Without the fix, it fails withloginPathnil.pod_membership_authentication_test.exs: the Pod SSO provider assertion now checks the host and path ofloginPath. Without the fix, the FOSS branch fails becauseloginPathis missing.bun run control-plane:test: 5222 tests, 0 failures.ANKOLE_EDITION=saas, the two changed test files and the private browser flow tests pass (37 tests). Theoauthassertion onloginPathin the private tests is unchanged.mix format --check-formatted,mix compile --warnings-as-errors, andmix credo --stricton the changed files: no new findings.🤖 Generated with Claude Code
Summary by CodeRabbit
/nullpage.