feat: password-gated recovery phrase display for HD wallets (closes #161)
All checks were successful
check / check (push) Successful in 32s
All checks were successful
check / check (push) Successful in 32s
A user who created a wallet in AutistMask and did not write the phrase
down had no way to retrieve it. Adds a "Show recovery phrase" action on
the wallet row in Settings, next to the per-wallet actions that already
live there, mirroring the per-address private key export in structure,
password gate and warning treatment.
The screen displays the secret that owns every address in the wallet, so:
- Only HD wallets are offered it. walletHasRecoveryPhrase() is an
allowlist on type "hd", so the key and xprv types — which have no
phrase at all — are excluded, as is any type added later.
- Nothing is decrypted and nothing enters the page until
decryptWithPassword accepts the password. A wrong password produces a
full-sentence error and leaves the value node empty.
- Leaving the screen wipes it by any route, not just "Back": views that
hold a secret register a cleanup with showView() via onViewLeave(),
which also covers the settings gear.
- The phrase is never assigned to state, so it cannot be persisted, and
the view is not in RESTORABLE_VIEWS — reopening the popup lands on
Home. That set moves to src/popup/restorableViews.js so the exclusion
can be asserted directly; the popup entry point cannot be required
outside a browser.
- The phrase cannot reach the logger: the view does not import
src/shared/log.js, and the failed-decrypt path reports a fixed
sentence rather than the caught error.
Tests: unit coverage for the type gate, the RESTORABLE_VIEWS exclusion
and the absence of any logger path; the DOM behaviour is driven against
the real popup in the e2e suite, which is where this repo tests views.
This commit is contained in:
50
README.md
50
README.md
@@ -107,9 +107,12 @@ unavailable). The suite lives in `tests/e2e/` and is driven by
|
||||
`playwright-core`, whose version must stay matched to the container's Playwright
|
||||
version — the browsers ship inside the image.
|
||||
|
||||
It covers popup load, wallet creation through the UI, the Add Token screen and
|
||||
the transaction detail screen for an ERC-20 transfer. All outbound network is
|
||||
intercepted at the browser level and served from fixtures in
|
||||
It covers popup load, wallet creation through the UI, the Add Token screen, the
|
||||
transaction detail screen for an ERC-20 transfer, and the recovery phrase screen
|
||||
— which wallet types are offered it, that it holds nothing before the password
|
||||
is accepted, that a wrong password reveals nothing, that leaving it by either
|
||||
route wipes it, and that reopening the popup does not land on it. All outbound
|
||||
network is intercepted at the browser level and served from fixtures in
|
||||
`tests/e2e/network.js`, so the run is deterministic and fully offline;
|
||||
unrecognised outbound requests are reported as failures rather than silently
|
||||
allowed.
|
||||
@@ -375,8 +378,11 @@ runtime debug mode is on, or when the active network is a testnet. They are not
|
||||
repeated in the element lists below.
|
||||
|
||||
Closing and reopening the popup returns to the screen the user was last on only
|
||||
for the views listed in `RESTORABLE_VIEWS` (`src/popup/index.js`). Every other
|
||||
screen, including ExportPrivKey, falls back to Home.
|
||||
for the views listed in `RESTORABLE_VIEWS` (`src/popup/restorableViews.js`).
|
||||
Every other screen falls back to Home. The screens that display a secret —
|
||||
ExportPrivKey and ShowRecoveryPhrase — are deliberately absent from that list,
|
||||
so the popup can never reopen onto one of them with no password prompt in front
|
||||
of it.
|
||||
|
||||
#### Welcome (`welcome`)
|
||||
|
||||
@@ -676,8 +682,9 @@ screen, including ExportPrivKey, falls back to Home.
|
||||
- **When**: User tapped the Settings gear.
|
||||
- **Elements**:
|
||||
- "Back" button, "Settings" heading
|
||||
- Wallets: one row per wallet with its name (tap to rename inline) and an
|
||||
`[x]` delete button, plus a "+ Add wallet" button
|
||||
- Wallets: one row per wallet with its name (tap to rename inline), a
|
||||
`[recovery phrase]` button on HD wallets only, and an `[x]` delete button,
|
||||
plus a "+ Add wallet" button
|
||||
- Tracked Tokens: one row per tracked token with an `[x]` remove button,
|
||||
plus a "+ Add token" button
|
||||
- Display: "Show tracked tokens with zero balance" checkbox and a Theme
|
||||
@@ -702,6 +709,7 @@ screen, including ExportPrivKey, falls back to Home.
|
||||
- **Transitions**:
|
||||
- "+ Add wallet" → **AddWallet**
|
||||
- "+ Add token" → **SettingsAddToken**
|
||||
- `[recovery phrase]` on an HD wallet → **ShowRecoveryPhrase**
|
||||
- `[x]` on a wallet → **DeleteWallet**
|
||||
- Tap wallet name → inline rename field (no screen change)
|
||||
- `[x]` on a tracked token or a site → removes it in place (no screen
|
||||
@@ -709,6 +717,32 @@ screen, including ExportPrivKey, falls back to Home.
|
||||
- Ten clicks on the version → reveals the Debug well (no screen change)
|
||||
- "Back" (or Settings gear again) → previous screen (Home)
|
||||
|
||||
#### ShowRecoveryPhrase (`show-phrase`)
|
||||
|
||||
- **When**: User tapped `[recovery phrase]` on a wallet row in Settings. HD
|
||||
wallets only: key and xprv wallets have no recovery phrase, so their rows do
|
||||
not offer the action at all.
|
||||
- **Elements**:
|
||||
- "Back" button, "Recovery Phrase" heading
|
||||
- Wallet name
|
||||
- Warning box stating that anyone holding these words can take everything in
|
||||
the wallet, from any device, without the password
|
||||
- Error line
|
||||
- Password input + "Reveal" button, shown until the password is accepted
|
||||
- The recovery phrase itself, in full and click-to-copy, shown only after a
|
||||
correct password and in place of the password prompt
|
||||
- **Transitions**:
|
||||
- "Reveal" (correct password) → the phrase replaces the password prompt (no
|
||||
screen change)
|
||||
- "Reveal" (wrong password) → full-sentence error, nothing revealed (no
|
||||
screen change)
|
||||
- "Back" → previous screen (Settings)
|
||||
- **Secret handling**: nothing is decrypted or written into the page until the
|
||||
password is accepted; the phrase is never stored in state, and it is wiped
|
||||
from the page whenever the screen is left by any route, including the Settings
|
||||
gear. The screen is not restorable, so reopening the popup lands on Home
|
||||
rather than back on the phrase.
|
||||
|
||||
#### DeleteWallet (`delete-wallet-confirm`)
|
||||
|
||||
- **When**: User tapped the `[x]` next to a wallet in Settings.
|
||||
@@ -1148,7 +1182,7 @@ Currently supported:
|
||||
|
||||
- [x] Delete wallet (with confirmation)
|
||||
- [ ] Delete address from HD wallet (with confirmation)
|
||||
- [ ] Show wallet's recovery phrase (requires password)
|
||||
- [x] Show wallet's recovery phrase (requires password)
|
||||
|
||||
### Transactions
|
||||
|
||||
|
||||
Reference in New Issue
Block a user