feat(security): nudge to sign out sessions unused for 3 months (#113) #452

Merged
jared merged 1 commits from feat/stale-sessions into lotus 2026-10-25 00:43:15 -04:00
Owner

Fixes #113. Owner decisions 2026-10-25: the existing strip plus the Devices page, stale at 90 days, and pre-selected bulk sign-out.

The issue's other questions are settled by what already exists:

  • the unverified-device nudge stays separate;
  • the strip says "haven't used in 3 months" without an IP (the Devices page still shows the IP, as before);
  • the current session is never included;
  • SSO re-authentication already works for sign-out.

What users see

  • In the security strip (lowest priority, after verify / key backup):

    You have 3 sessions you haven't used in 3 months. Signing them out keeps your account safe if an old device is lost. [Review] [Not now]

    • It follows the same rules as the other nudges: not in a device's first 24 h; "Not now" snoozes 7 days; it's gone after 3 dismissals.
    • Each nudge now snoozes independently, so a snoozed key-backup nudge no longer hides this one.
  • Review opens Settings → Devices with those sessions ticked for sign-out: one "Logout" confirm, with the usual re-auth (password or SSO). You can untick any first.
    • They're listed first and marked "Inactive for 3+ months", under a one-line explanation.
    • OIDC accounts sign out on the provider's dashboard, so nothing is ticked there.

Rules (staleSessions): last seen at least 90 days ago; never the current session; a session with no last-seen time is left alone.

Tested

  • e2e stale-sessions.spec.ts against a local Synapse. Synapse can't backdate last-seen, so the session list is served with one real extra session made 120 days old.
    • The fresh account first shows the key-backup nudge. After "Not now", the stale-sessions nudge appears.
    • Review shows the session marked Inactive and "Logout from selected devices (1 selected)".
    • Logout plus the password re-auth signs it out on the server; the recent session stays.
  • Unit tests: 3 new (the stale rule incl. edges, wording, priority/snooze); 1,436 pass. Lint is at 29.

🤖 Generated with Claude Code

https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5

Fixes #113. Owner decisions 2026-10-25: **the existing strip plus the Devices page**, stale at **90 days**, and **pre-selected bulk sign-out**. The issue's other questions are settled by what already exists: - the unverified-device nudge stays separate; - the strip says "haven't used in 3 months" without an IP (the Devices page still shows the IP, as before); - the current session is never included; - SSO re-authentication already works for sign-out. **What users see** - **In the security strip** (lowest priority, after verify / key backup): > You have 3 sessions you haven't used in 3 months. Signing them out keeps your account safe if an old device is lost. **[Review] [Not now]** - It follows the same rules as the other nudges: not in a device's first 24 h; "Not now" snoozes 7 days; it's gone after 3 dismissals. - Each nudge now snoozes independently, so a snoozed key-backup nudge no longer hides this one. - **Review** opens **Settings → Devices** with those sessions **ticked for sign-out**: one "Logout" confirm, with the usual re-auth (password or SSO). You can untick any first. - They're listed first and marked **"Inactive for 3+ months"**, under a one-line explanation. - OIDC accounts sign out on the provider's dashboard, so nothing is ticked there. **Rules (`staleSessions`):** last seen at least 90 days ago; never the current session; a session with no last-seen time is left alone. **Tested** - **e2e `stale-sessions.spec.ts`** against a local Synapse. Synapse can't backdate last-seen, so the session list is served with one real extra session made 120 days old. - The fresh account first shows the key-backup nudge. After "Not now", the stale-sessions nudge appears. - Review shows the session marked Inactive and "Logout from selected devices (1 selected)". - Logout plus the password re-auth signs it out on the server; the recent session stays. - **Unit tests:** 3 new (the stale rule incl. edges, wording, priority/snooze); 1,436 pass. Lint is at 29. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared added 1 commit 2026-10-24 23:52:44 -04:00
feat(security): nudge to sign out sessions unused for 3 months (#113)
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Build & Quality Checks (pull_request) Successful in 4m4s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 17s
CI / Playwright smoke (e2e) (pull_request) Successful in 24m20s
c907b0ba99
Sessions of this account not seen for 90+ days (never the current one; a
session with no last-seen time is left alone) get a nudge in the existing
security strip, after the device-security ones and with the same rules
("Not now" snoozes 7 days, gone after 3 dismissals; a snoozed security
nudge no longer hides it): "You have 3 sessions you haven't used in 3
months. Signing them out keeps your account safe if an old device is
lost." [Review]

Review opens Settings -> Devices with those sessions ticked for sign-out
(one confirm, the usual re-auth incl. SSO); they are listed first and
marked "Inactive for 3+ months". OIDC accounts sign out on the
provider's dashboard, so nothing is ticked there.

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-24 23:52:52 -04:00
jared merged commit 0d4f2e4a87 into lotus 2026-10-25 00:43:15 -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#452