fix(ui): reuse existing UserId when replacing alias entry (#114 followup)#120
Merged
iduartgomez merged 1 commit intomainfrom May 6, 2026
Merged
Conversation
…wup) #114 fix replaced ALIASES + user.identities entries in place when the alias already existed, but generated a fresh UserId::new() each time. `User::set_logged_id` asserts `id.0 < self.identities.len()` and `logged_id()` indexes by `id.0`, so the UserId must equal the slot index. With a fresh UserId(N) replacing a slot at index 0, the next login asserts `1 < 1` and panics with `id.0 < self.identities.len()`. Reuse the existing slot's UserId on replace; generate a new one only when pushing into a fresh slot. Surfaced by FREENET_LIVE_E2E_SEND=1 iso harness test 2: assertion failed: id.0 < self.identities.len()
This was referenced May 6, 2026
Open
iduartgomez
added a commit
that referenced
this pull request
May 6, 2026
…on (#81) (#123) #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.
iduartgomez
added a commit
that referenced
this pull request
May 6, 2026
* test(e2e): flip FREENET_LIVE_E2E_SEND off + fix click-to-read assertion (#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. * feat(ui): refuse-with-error on alias collision in Create/Restore (#117) 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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The #114 dedup fix replaced ALIASES + user.identities entries in place when the alias already existed, but generated a fresh `UserId::new()` each time.
`User::set_logged_id` asserts `id.0 < self.identities.len()` and `logged_id()` indexes by `id.0`, so the UserId must equal the slot index. Replacing slot 0 with an Identity carrying `UserId(N>=1)` panics on the next `set_logged_id` call:
```
assertion failed: id.0 < self.identities.len()
```
Surfaced by an FREENET_LIVE_E2E_SEND=1 iso harness run during #81 followup verification — test 2 panicked once the dedup path was exercised on a delegate-restored alias.
Fix
Reuse the existing slot's UserId on replace; generate a new one only when pushing into a fresh slot. Both `set_alias` (manual create) and `set_aliases` (delegate restore) updated.
Test plan