feat: device-security nudge — verify this device / key backup (#110, #123)
CI / Build & Quality Checks (pull_request) Successful in 1m48s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 12s
CI / Playwright smoke (e2e) (pull_request) Successful in 11m38s
CI / Build & Quality Checks (pull_request) Successful in 1m48s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 12s
CI / Playwright smoke (e2e) (pull_request) Successful in 11m38s
One "security" strip, in the same top slot and style as the status banner (#124), for this device, in priority order: - "Verify this device" — cross-signing exists but this device isn't verified (can't unlock backed-up history, untrusted to others). First, because verifying with the recovery key also connects the backup. - "Connect this device to your key backup" — a backup exists, this device isn't using it. - "Set up key backup" — no backup at all (includes accounts without cross-signing; the setup flow does both). The button opens Settings → Devices (existing flows); "Not now" snoozes. Rules: nothing in a device's first 24 h; "Not now" snoozes that nudge 7 days; 3 dismissals stop it; never on a healthy device; waits until sync has settled (never under "Connecting…"); outage/maintenance/connection strips win. Per-device record in localStorage, wiped on logout. Mounted inside the Matrix client context and an error boundary (an early version outside the context crashed the app on load — caught before pushing). Also: the status strip wraps its text on phones instead of truncating it when there's no Details button (benefits #124's strips too). Design approved on #123 (real-client screenshots there). Tests: 4 unit (the #123 state table, loading, timing, stored record); e2e: nothing during the grace period, "Set up key backup" → Settings → Devices, "Not now" holds across a reload. Unit 1319, Playwright 29 passed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
8e30c73e2f
commit
6a7627fa26
@@ -8,6 +8,7 @@ import { clearNavToActivePathStore } from './navToActivePath';
|
||||
import { DRAFT_MSG_KEY_PREFIX } from '../utils/draft';
|
||||
import { clearCallSession } from '../utils/callRejoin';
|
||||
import { clearOutbox } from '../utils/outbox';
|
||||
import { NUDGE_KEY_PREFIX } from '../utils/securityNudge';
|
||||
|
||||
/**
|
||||
* [Gitea #41] Wipe every persisted composer draft (`draft-msg-<roomId>`). Drafts
|
||||
@@ -77,7 +78,11 @@ const clearStatusMessage = (): void => {
|
||||
return;
|
||||
}
|
||||
keys.forEach((key) => {
|
||||
if (key.startsWith('lotus-status-msg-') || key.startsWith('lotus-status-expiry-')) {
|
||||
if (
|
||||
key.startsWith('lotus-status-msg-') ||
|
||||
key.startsWith('lotus-status-expiry-') ||
|
||||
key.startsWith(NUDGE_KEY_PREFIX)
|
||||
) {
|
||||
try {
|
||||
localStorage.removeItem(key);
|
||||
} catch {
|
||||
|
||||
Reference in New Issue
Block a user