Skip to content

feat(ui): refuse alias collision on Create/Restore (#117)#125

Merged
iduartgomez merged 2 commits intomainfrom
feat/warn-alias-collision-117
May 6, 2026
Merged

feat(ui): refuse alias collision on Create/Restore (#117)#125
iduartgomez merged 2 commits intomainfrom
feat/warn-alias-collision-117

Conversation

@iduartgomez
Copy link
Copy Markdown
Contributor

Summary

  • Pre-check Identity::get_alias(name) before submitting CreateIdentity from both Create new identity (CreateAliasForm) and Restore from backup (ImportForm). If the name is already in use, refuse with an inline error banner — no keygen, no delegate write, no inbox orphaning.
  • Mirrors the existing collision guard on inline rename (Identity::rename_in_place) for behavioural consistency: every alias-mutating UI path now refuses silent overwrite.
  • Adds an offline Playwright test in email-app.spec.ts that submits the seeded address1 alias and asserts the error banner shows + the six-word fingerprint reveal does not.

Closes #117.

Why refuse, not confirm

Identity replacement is destructive — the prior inbox stays on the network but the keys to decrypt it are gone. A confirm dialog risks accidental clicks; the rename flow already uses refuse, so this matches.

Test plan

  • cargo check -p freenet-email-ui (default + example-data,no-sync)
  • cargo clippy -p freenet-email-ui -- -D warnings (default + example-data,no-sync)
  • cargo fmt --all -- --check
  • Offline Playwright (email-app.spec.ts, chromium): 39 passed including new collision test
  • CI build-and-test + ui-playwright

…on (#81)

#114 + #115 + #120 fixes plus a spec correction (use page.reload()
instead of page.goBack(), since the SPA doesn't push history entries
on click — goBack landed on about:blank rather than the inbox)
make tests 2 + 3 deterministically green on the iso harness. Drop
the FREENET_LIVE_E2E_SEND gate so they run by default.

Two assertions stay gated as separate concerns:

- Test 3 round 3 (alice → bob retry) gated on
  FREENET_LIVE_E2E_AFT_CAP_RAISED — AFT day-1 cap is 1 slot, alice
  burned hers in round 1; needs #85 to make tier configurable.
- Test 3 round 2 (bob → alice reply) gated on FREENET_LIVE_E2E_REPLY
  — flaky ~33%, separate flake tracked in #122. Click-to-read +
  reload assertion (the original #113 target) still runs and passes
  deterministically.

Verified locally via 3 consecutive `cargo make test-e2e-real-node`
runs, all passing in ~12s each.
Before submitting a NodeAction::CreateIdentity for a new alias name,
check Identity::get_alias(name). If it returns Some, refuse with an
inline error banner instead of advancing through keygen → reveal →
delegate write.

Two paths are guarded:

  - CreateAliasForm::submit — Create new identity. Rejects before
    keygen (no burned keys for a refused name).
  - ImportForm::onclick (Restore) — refuses to overwrite an existing
    identity record from a backup file, since the backup's keys would
    silently replace the on-device delegate entry and orphan the
    previous inbox.

Mirrors the existing rename collision guard at
\`Identity::rename_in_place\`. The two flows are now consistent:
explicit two-step (delete then create/restore) is required to swap an
alias, and there is no UI path that silently destroys access to a
prior inbox.

Adds an offline-mode Playwright test that submits "address1" — already
seeded — and asserts the banner appears and the fingerprint reveal
does not.
@iduartgomez iduartgomez merged commit 71c1ffa into main May 6, 2026
5 of 7 checks passed
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.

UI: warn before overwriting existing alias on Create Identity (production data loss)

1 participant