Skip to content

Make "Keep me signed in" survive browser restarts with 90-day remember-me session lifetimes#63

Open
ruddro-roy wants to merge 2 commits into
thunderbird:mainfrom
ruddro-roy:remember-me-session-lifetimes
Open

Make "Keep me signed in" survive browser restarts with 90-day remember-me session lifetimes#63
ruddro-roy wants to merge 2 commits into
thunderbird:mainfrom
ruddro-roy:remember-me-session-lifetimes

Conversation

@ruddro-roy

@ruddro-roy ruddro-roy commented Jul 12, 2026

Copy link
Copy Markdown

Addresses #62.

Root cause

Two stacked defects, neither in the webmail client:

  1. The tbpro login theme posted the "Keep me signed in" checkbox as a form field Keycloak does not read. Keycloak's authenticator only starts a remember-me session for a field literally named rememberMe, so the checkbox was a no-op. Fixed upstream in “Remember me” checkbox does not persist the session — user is forced to re-authenticate thunderbird-accounts#1091.
  2. The realm's remember-me lifespans (ssoSessionIdleTimeoutRememberMe, ssoSessionMaxLifespanRememberMe) were 0, so even a real remember-me session falls back to the standard 30-minute idle and 10-hour max. Refresh tokens inherit that cap, and oidc-spa restores a session only while the last refresh token is valid, so nothing client-side can outlive it. Fixed upstream in Keycloak fixes for remember me session length(#1091), config cli race(#1099), and forgot password otp flow (#1098) thunderbird-accounts#1100 (90 days).

Measured against production webmail on 2026-07-12: the oidc-spa restoration marker in localStorage expired 30 minutes after the last token refresh, which says the upstream fixes were not yet deployed to auth.tb.pro at that time. Once they are, hosted users need no webmail client change.

What this PR does

  • Bumps the thunderbird-accounts submodule past those two fixes, so the local stack's theme posts rememberMe and a fresh realm import ships the 90-day lifespans.
  • Hardens tests/fixtures/configure-keycloak.mjs. Keycloak imports the realm JSON only into an empty database, so existing dev volumes keep the old zero lifespans forever. The fixture now reconciles rememberMe and both lifespans idempotently, with the same value thunderbird-accounts ships (7776000 s). Standard non remember-me sessions keep whatever policy the realm already has.
  • Adds tests/e2e/remember-me-session.spec.js. It simulates a browser restart by rehydrating a fresh context from a storageState stripped of session cookies, since persistent cookies and localStorage survive a real quit and relaunch while session cookies do not. With the checkbox ticked, the shell must restore silently with no visit to the Keycloak form; without it, the LoginGate must return. On submodule pins whose theme predates the field fix, the positive spec skips with a pointer instead of failing. Both specs bypass the shared auth.setup storageState, so they neither depend on nor disturb the SSO session the rest of the suite reuses.
  • Adds unit coverage for the fixture helper.

Verification (local stack, this branch)

  • remember-me-session.spec.js: 4/4 passed on chromium and firefox against a stack rebuilt from the bumped submodule with a clean realm import and no local patches.
  • Full firefox local-stack lane: 38/38 passed on the previous pin, and 38/38 passed rerun against the bumped pin. One pre-existing delete-message flake passed on its automatic retry in each run and occurs on the unmodified pin as well.
  • Fresh realm import verified through the admin API: rememberMe: true, both remember-me lifespans 7776000, standard sessions untouched (1800 idle, 36000 max).
  • vitest 632 passed, vue-tsc clean, eslint clean.

…oak fixture and cover Keep me signed in across a simulated browser restart with e2e specs. (thunderbird#62)

Keycloak only imports the realm JSON into an empty database, so existing dev volumes keep the old zero remember-me lifespans; the fixture now enforces realm rememberMe and both lifespans idempotently with the values thunderbird-accounts ships. The restart specs strip session cookies from a captured storageState: a remember-me login must silently restore into the shell, a plain login must return to the LoginGate. The positive spec skips with a pointer on submodule pins whose theme predates the rememberMe form-field fix.
@ruddro-roy ruddro-roy force-pushed the remember-me-session-lifetimes branch from 622d178 to 498e17d Compare July 12, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant