diff options
| author | Adam Soltys <[email protected]> | 2026-08-27 12:03:59 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-08-27 12:03:59 -0700 |
| commit | 0526da5cb8c5d1790effe6c3871c1f237962509c (patch) | |
| tree | 8109169272e2b0185f8475dd762cbb134269765b /src | |
| parent | 838046f049cad53fd45ef435a6dafcb3efbda638 (diff) | |
| download | coinosv3-0526da5cb8c5d1790effe6c3871c1f237962509c.tar.gz coinosv3-0526da5cb8c5d1790effe6c3871c1f237962509c.zip | |
One tap, one dialog: a passkey sign-in with nothing on the device rolls straight into creating one — the browser's own passkey sheet is the confirmation, and dismissing it is a quiet cancel, not an error
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019eA8JRq9Wr7z2fRQk99HLi
Diffstat (limited to 'src')
| -rw-r--r-- | src/features/nostrlogin.js | 33 | ||||
| -rw-r--r-- | src/i18n.js | 2 |
2 files changed, 11 insertions, 24 deletions
diff --git a/src/features/nostrlogin.js b/src/features/nostrlogin.js index 981491e..9b9d1ef 100644 --- a/src/features/nostrlogin.js +++ b/src/features/nostrlogin.js @@ -239,8 +239,9 @@ export function nostrLoginFeature(ctx) { } // Passkey sign-in: try an existing credential first; when the device has - // none (or the user dismisses the picker), offer to create one instead of - // showing a bare error. + // none (or the picker is dismissed), roll straight into creating one — the + // browser's own passkey dialog IS the confirmation, so an interstitial of + // ours would just be a second question. async function passkeyLogin(run) { ui.nostrLoginError = ''; const pass = await import('../passkey.js'); @@ -249,20 +250,14 @@ export function nostrLoginFeature(ctx) { await run(() => keySigner(sk)); } catch (e) { if (/derive a wallet key/.test(e.message)) { ui.nostrLoginError = e.message; render(); return; } - ui.passkeyOffer = true; // no credential picked — offer creation - render(); - } - } - async function passkeyCreateLogin(run) { - ui.nostrLoginError = ''; - ui.passkeyOffer = null; - try { - const pass = await import('../passkey.js'); - const sk = await pass.passkeyCreate(); - await run(() => keySigner(sk)); - } catch (e) { - ui.nostrLoginError = e.message; - render(); + try { + const sk = await pass.passkeyCreate(); + await run(() => keySigner(sk)); + } catch (e2) { + // dismissing the create dialog is a plain cancel, not an error + if (!/NotAllowed|abort/i.test(String(e2.name || '') + e2.message)) ui.nostrLoginError = e2.message; + render(); + } } } @@ -289,12 +284,6 @@ export function nostrLoginFeature(ctx) { ? h('button', { class: 'btn-block', style: pad, disabled: ui.nostrLoginBusy, onClick: () => passkeyLogin(run) }, markedLabel(PASSKEY_MARK, t('nlPasskey'))) : null, - ui.passkeyOffer - ? h('div', { class: 'row gap6', style: 'align-items:center' }, - h('span', { class: 'small muted grow' }, t('nlPasskeyNone')), - h('button', { class: 'btn-sm', disabled: ui.nostrLoginBusy, onClick: () => passkeyCreateLogin(run) }, t('nlPasskeyCreate')), - h('button', { class: 'btn-sm btn-ghost', onClick: () => { ui.passkeyOffer = null; render(); } }, t('cancel'))) - : null, ]; } diff --git a/src/i18n.js b/src/i18n.js index eec6eba..8ec64ce 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -633,8 +633,6 @@ const STR = { nlExtension: 'Use browser extension', nlGoogle: 'Sign in with Google', nlPasskey: 'Sign in with a passkey', - nlPasskeyNone: 'No passkey was used. Create one for this wallet?', - nlPasskeyCreate: 'Create passkey', nlKeyOrBunker: 'nsec, private key, or bunker://…', nlGo: 'Log in', nlHint: 'Works with Amber, Amethyst and other remote signers (paste their bunker:// address), or a browser extension. A pasted key is used once and never stored.', |
