Skip to content

Ask for one name, because that is all it ever was - #85

Merged
NiKrause merged 2 commits into
mainfrom
fix/one-name-not-two
Aug 21, 2026
Merged

Ask for one name, because that is all it ever was#85
NiKrause merged 2 commits into
mainfrom
fix/one-name-not-two

Conversation

@NiKrause

@NiKrause NiKrause commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Ready. The release this waited for exists: the handle is 64 random bytes from 0.5.1, which reached main separately as #87. The pin here is 0.5.1 and this branch is rebased onto current main.

Worth recording, because it cost a wrong conclusion once: 0.5.1 was published to npm without a GitHub release, so the release list still ends at v0.5.0 — dated a day before #46 was merged. Checking releases says the blocker is still there.

The onboarding screen asked twice for a label and warned that sharing the first one would destroy somebody's passkey. Both follow from the same defect: the identity provider built the WebAuthn user handle out of that field, and an authenticator replaces a credential whose (origin, handle) already exists. The field was an identifier wearing a label's clothes, and warning about it was the honest thing to do.

The handle is 64 random bytes now, which makes the field a name and nothing else. The code comment above the form has been waiting for exactly this:

…it stays until the handle is random rather than typed — #45, after which this field is genuinely just a name and the two can become one.

What changes

  • One input. Its value goes to WebAuthn as both the account name and the display name — two slots in the same credential picker, not two facts about a person.
  • The warning goes, in both catalogues: "If somebody on this device has already used the same name, pick another: theirs would be replaced." Two people at one front desk may now enter the same name and get two identities.
  • The rest of the hint stays — no e-mail needed — and gains the reason the name is harmless.
  • onboarding_display_name and its hint are deleted from en.json and de.json rather than left dangling; nothing else referenced them.
  • m0-shell keeps its assertion that the hint is tied to the input via aria-describedby. A hint a screen reader never reaches is not a hint, whatever it says — only the reason it exists has changed.

Related

fix/accounts-per-passkey builds account switching on this device — the follow-on consequence of the same change, since re-registering now adds a passkey instead of replacing one. It does not touch StudioGate.svelte, so there is no overlap in the diff, but the two belong together: this PR removes the warning that the absence of account switching would otherwise justify.

Verification

Build succeeds, 180 unit tests pass, prettier and eslint clean. The E2E onboarding helpers now fill one field; they were not run here.

Added after the rebase

Sitting next to the account separation (#82), two texts on one screen contradicted each other. The onboarding warning ended "whatever sits under the old passkey is out of reach", while the footer three lines below offers "switch account — sign in with a different passkey on this device".

Since accounts are separated per DID rather than overwriting one another, it is the warning that was wrong: a second passkey leaves the first account's studio exactly where it was, and switching leads back to it.

What survived is the part still worth saying — the studio sees a new device and has to approve it again. That is a real cost and a real reason to press the other button; losing the data is not one any more. Both catalogues and the comment above the paragraph moved together.

Verification after the rebase

Build, prettier, eslint, svelte-check (0 errors) and 188 unit tests green locally, plus m0-shell and m2-accounts — both sides of the contradiction. CI green on 410d179.

NiKrause added a commit that referenced this pull request Aug 21, 2026
A patch release: credentials registered under 0.5.0 keep working and the
derived did:key is unchanged, so no device has to move in step with another.

What it brings here is the random WebAuthn user handle
(Le-Space/orbitdb-identity-provider-webauthn-did#45). The handle used to be
the UTF-8 of the name typed on the onboarding screen, and an authenticator
keeps one credential per (origin, handle) — so two people at one front desk
who picked the same name destroyed each other's passkey and the identity
behind it. That is the hazard the form currently warns about; the warning can
go once this is in (#85).

Also in 0.5.1: largeBlob keystores actually persist their secret key, and the
credential carries the authenticator's own answer on extension support rather
than the browser's guess.

Bumped in both places — the dependency range and the pnpm override — and the
lockfile regenerated with the pinned pnpm 10.33.0.

Verified: build succeeds, 188 unit tests pass, the installed provider resolves
to 0.5.1.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
NiKrause added a commit that referenced this pull request Aug 21, 2026
This branch removed the second field and the warning about it on the
argument that the WebAuthn user handle is no longer derived from what
somebody types. That is only true from
Le-Space/orbitdb-identity-provider-webauthn-did#46, which is merged
upstream but was in no release when this was opened — so the PR said it
must not merge until one existed.

One does: 0.5.1 on npm. Its `createCredential` builds the handle as

    const userHandle = crypto.getRandomValues(new Uint8Array(64))

and passes it as `user.id`, which is exactly the change this depends on.

It is easy to miss, and that is worth recording: 0.5.1 was published to
npm without a GitHub release, so the release list still ends at v0.5.0
from a day before the merge. Looking there says the blocker is still
there.

Both the override and the dependency range move together; leaving the
range at ^0.5.0 while the override said 0.5.1 would be two sources of
truth for one decision.

Refs #85
NiKrause and others added 2 commits August 21, 2026 20:27
The onboarding screen asked twice for a label and warned that sharing the
first one would destroy somebody's passkey. Both follow from the same defect:
the identity provider built the WebAuthn user handle out of that field, and an
authenticator replaces a credential whose (origin, handle) already exists. So
the field was an identifier wearing a label's clothes, and the honest thing to
do was warn about it.

The handle is 64 random bytes now
(Le-Space/orbitdb-identity-provider-webauthn-did#45), which makes the field a
name and nothing else. One input, given to WebAuthn as both the account name
and the display name — they are two slots in the same credential picker, not
two facts about a person.

The warning goes, because it is no longer true: two people at one front desk
may now enter the same name and get two identities. The rest of the hint
stays — no e-mail needed — and gains the reason the name is harmless.

`onboarding_display_name` and its hint are deleted from both catalogues rather
than left dangling; nothing else referenced them.

The m0-shell test keeps its assertion that the hint is tied to the input via
aria-describedby. A hint a screen reader never reaches is not a hint, whatever
it says — only the reason it exists has changed.

Verified: build succeeds, 180 unit tests pass, prettier and eslint clean. The
E2E onboarding helpers now fill one field; they were not run here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rebasing onto main put this branch beside the account separation, and the
two texts then contradicted each other on the same screen.

The onboarding warning ended: "whatever sits under the old passkey is out
of reach." The footer, three lines further down, offers "switch account —
sign in with a different passkey on this device." Both cannot be true, and
since #82 it is the warning that is wrong: accounts are separated per DID
rather than overwriting one another, so a second passkey leaves the first
account's studio exactly where it was and switching leads back to it.

What is still worth saying is the part that survived: the studio sees a
new device and has to approve it again. That is a real cost and a reason
to press the other button. Losing the data is not, any more.

The comment above the paragraph carried the same claim and moved with it —
it is the one that explains why the paragraph exists at all.

Refs #85, #82
@NiKrause
NiKrause force-pushed the fix/one-name-not-two branch from 9a1d70e to 410d179 Compare August 21, 2026 18:31
@NiKrause
NiKrause marked this pull request as ready for review August 21, 2026 19:33
@NiKrause
NiKrause merged commit 7ba5bde into main Aug 21, 2026
1 check 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.

1 participant