Skip to content

feat(wallet): expire idle sessions and warn before disconnecting - #1214

Open
bilhokista wants to merge 3 commits into
Fracverse:masterfrom
bilhokista:feat/1084-wallet-session-timeout
Open

feat(wallet): expire idle sessions and warn before disconnecting#1214
bilhokista wants to merge 3 commits into
Fracverse:masterfrom
bilhokista:feat/1084-wallet-session-timeout

Conversation

@bilhokista

Copy link
Copy Markdown

Closes #1084.

The hole that matters most is not the timer

A 30-minute in-memory timer does nothing once the tab is closed. WalletProvider restored the address from localStorage unconditionally:

const savedAddress = localStorage.getItem("inheritx_wallet_address");
if (savedAddress && savedWalletId) { setAddress(savedAddress); ... }

So on a shared machine, closing the browser and reopening the page tomorrow silently reconnects the previous person's wallet. That is the public-terminal risk the issue describes, and a timer alone would not have touched it.

The restore path now checks a persisted inheritx_wallet_last_activity timestamp and clears all three keys if the session is stale.

A missing or unparseable timestamp counts as expired. That is deliberate: a session written before this change has no recorded activity, and treating "unknown" as "still valid" would leave in place exactly the sessions this is meant to clear. The cost is that everyone is asked to reconnect once after deploy, which seems like the right trade for a security fix.

The one exception is a timestamp in the future — a clock change or a tampered value — which restarts the window rather than locking the user out.

The timer

sessionPhase splits idle time into active / warning / expired, with the warning covering the final 60 seconds. A 1-second interval reads it and either exposes sessionSecondsLeft for a countdown modal or disconnects.

Two implementation details worth review:

  • Activity is tracked in a ref, not state. These events fire constantly; re-rendering the whole wallet tree on every scroll would be its own bug.
  • disconnect is reached through a ref. Listing it as an effect dependency would tear down and rebuild the interval every time kit changes, resetting the countdown.

secondsUntilExpiry rounds up, so the countdown never displays "0 seconds" while time remains.

What this PR does not include

Requirement 2 asks for a modal. I exposed sessionSecondsLeft and extendSession on the context but did not add the modal component, because the app has no shared modal primitive and dropping a new one into WalletProvider would put UI inside a context provider that currently renders none. A consumer can render it in three lines from the values now available.

Say the word and I will add the modal here — I would just rather you choose where it lives than have me pick for you.

Tests

frontend/tests/lib/walletSession.test.ts — 18 cases: the phase boundaries asserted to the millisecond (including that expiry happens at the timeout, and that one millisecond earlier is still warning), the countdown never going negative or showing 0 while time remains, and every rejection path for a stored timestamp — missing, empty, unparseable, zero, negative, stale — plus the future-timestamp tolerance.

Honest note on verification: I could not run Vitest locally (no full workspace install), but this frontend has Vitest configured so the file runs in CI normally. I transpiled walletSession.ts and executed it standalone against 25 assertions covering the same ground — all pass.

The WalletContext wiring — the listeners, the interval, the ref indirection — has no test here and needs CI or a manual check. The behaviour I would most like verified is that the interval is genuinely torn down on unmount and on disconnect, since a leaked 1-second timer would be an unpleasant thing to ship.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CrfEY1tvXrbeMDAUzxfuk7

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.

Frontend: Build Wallet Connection Session Timeout & Auto-Disconnect Warning

1 participant