fix(auth): SSO confirmation works in the desktop app; allow switching to SSO #474

Merged
jared merged 1 commits from fix/sso-uia-desktop into lotus 2026-10-26 12:12:02 -04:00
Owner

Reported by a user (Jeff): signing out other sessions with SSO doesn't work.

What the server logs show (Synapse, @bigmanjeff, Oct 25–26):

  • Each attempt follows the same cycle: POST /delete_devices → 401 → SSO fallback page → OIDC callback → mark_ui_auth_stage_complete. So the SSO step succeeded every time.
  • The next delete_devices was a fresh 401 challenge (119 B, the size of a new session with password and SSO flows). It was never a retry carrying the completed session. 4 attempts, none succeeded.
  • The device requests came from Edg/155 (the Windows desktop app's WebView2). The SSO pages came from Chrome/156, his system browser.

Cause

  1. SSOStage only showed "Continue" once window.open returned a window. The desktop app opens the SSO page in the system browser and gets no window back. A popup can also lose its opener. Either way authDone never arrives, the dialog stays on "Continue with SSO", and the only way on is starting over: a new request without the session, in a loop.
  2. ActionUIA forced the first supported flow. With password and SSO both offered, that's often password, which an SSO-only account may not know, and there was no way to pick SSO.

Fix

  • SSOStage: once the sign-in page has been opened, show Continue (and Open the sign-in page again), with the copy "Finish signing in on the page that opened, then come back here and select Continue." When authDone does arrive, it still continues automatically.
  • ActionUIA: when another supported flow exists, offer Use SSO instead / Use your password instead. This covers device sign-out and the cross-signing setup.

Tested

  • In the browser against a build, with delete_devices mocked so it succeeds only if the retry carries the session:
    • desktop (window.open returns null): Continue appears; the retry sends {"session":"S1"} and the device is signed out;
    • password offered first: "Use SSO instead" leads to the SSO stage, and then to sign-out;
    • popup losing its opener: Continue works.
  • The current lotus build loops in the desktop case: the SSO dialog never offers Continue.
  • New e2e/sso-uia.spec.ts covers the desktop and password-first cases (2/2).
  • 1,446 unit tests pass; lint is at 28 warnings.

Server-side note (not changed here): Synapse logs "SSO mapping for IdP https://auth.lotusguild.org, but this is no longer configured", and "has previously logged in with multiple SSO IdPs" for this user. That's a leftover mapping from an older Authelia provider ID. It's harmless (Synapse picks oidc-authelia) but could be cleaned up in user_external_ids.

🤖 Generated with Claude Code

https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5

**Reported by a user (Jeff):** signing out other sessions with SSO doesn't work. **What the server logs show** (Synapse, @bigmanjeff, Oct 25–26): - Each attempt follows the same cycle: `POST /delete_devices` → 401 → SSO fallback page → OIDC callback → `mark_ui_auth_stage_complete`. **So the SSO step succeeded every time.** - The next `delete_devices` was a **fresh** 401 challenge (119 B, the size of a new session with password and SSO flows). It was never a retry carrying the completed session. 4 attempts, none succeeded. - The device requests came from `Edg/155` (the **Windows desktop app**'s WebView2). The SSO pages came from `Chrome/156`, his system browser. **Cause** 1. `SSOStage` only showed "Continue" once `window.open` returned a window. The desktop app opens the SSO page in the system browser and gets no window back. A popup can also lose its opener. Either way `authDone` never arrives, the dialog stays on "Continue with SSO", and the only way on is starting over: a new request without the session, in a loop. 2. `ActionUIA` forced the first supported flow. With password and SSO both offered, that's often password, which an SSO-only account may not know, and there was no way to pick SSO. **Fix** - **SSOStage:** once the sign-in page has been opened, show **Continue** (and **Open the sign-in page again**), with the copy "Finish signing in on the page that opened, then come back here and select Continue." When `authDone` does arrive, it still continues automatically. - **ActionUIA:** when another supported flow exists, offer **Use SSO instead** / **Use your password instead**. This covers device sign-out and the cross-signing setup. **Tested** - In the browser against a build, with `delete_devices` mocked so it succeeds only if the retry carries the session: - **desktop** (`window.open` returns null): Continue appears; the retry sends `{"session":"S1"}` and the device is signed out; - **password offered first:** "Use SSO instead" leads to the SSO stage, and then to sign-out; - **popup losing its opener:** Continue works. - The current `lotus` build loops in the desktop case: the SSO dialog never offers Continue. - New `e2e/sso-uia.spec.ts` covers the desktop and password-first cases (2/2). - 1,446 unit tests pass; lint is at 28 warnings. **Server-side note (not changed here):** Synapse logs "SSO mapping for IdP `https://auth.lotusguild.org`, but this is no longer configured", and "has previously logged in with multiple SSO IdPs" for this user. That's a leftover mapping from an older Authelia provider ID. It's harmless (Synapse picks `oidc-authelia`) but could be cleaned up in `user_external_ids`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared added 1 commit 2026-10-26 11:50:08 -04:00
fix(auth): SSO confirmation works in the desktop app; allow switching to SSO
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 1m50s
CI / Build & Quality Checks (pull_request) Successful in 3m15s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Playwright smoke (e2e) (pull_request) Successful in 18m29s
f7f6059b33
Reported by a desktop user: signing out other sessions with SSO looped.
Server logs: the SSO step completed every time, but each delete_devices
retry came without the session (a fresh 401 challenge), 4 attempts, none
succeeded. The app is the Windows desktop build (WebView2) and the SSO
pages opened in the system browser.

- SSOStage only offered "Continue" once window.open returned a window. The
  desktop app opens the page in the system browser (no window back), and a
  popup can lose its opener, so "authDone" never arrives and the only way
  on was starting over. Now "Continue" (plus "Open the sign-in page again")
  appears as soon as the page was opened; authDone still auto-continues.
- ActionUIA: when the server offers password and SSO, the first flow was
  forced (often password, which an SSO-only account may not know). Offer
  "Use SSO instead" / "Use your password instead".

e2e: desktop (window.open returns null) completes with the session; with
password offered first, SSO is one click away.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared scheduled this pull request to auto merge when all checks succeed 2026-10-26 11:50:15 -04:00
jared merged commit 29ece6a0c8 into lotus 2026-10-26 12:12:02 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#474