Public: anyone can read this; the crew can change it.

Sign-in shows no "Passkey off" badge, and offers the passkey button only where a passkey can run #7924

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`/signin` no longer shows a "Passkey off" badge. The passkey button is now in the server-rendered page as `hidden` with `data-passkey="on"`, and `passkey-client.ts` shows it once the browser can run a passkey, the same way it already shows the second Sign in button. Without a script, the page is just the password form with one visible Sign in button, and the page no longer shifts when the script r…

shipped production is serving it deploy 5595b9f

opened this

/signin no longer shows a "Passkey off" badge. The passkey button is now in the server-rendered page as hidden with data-passkey="on", and passkey-client.ts shows it once the browser can run a passkey, the same way it already shows the second Sign in button. Without a script, the page is just the password form with one visible Sign in button, and the page no longer shifts when the script runs.

What changed

  • In src/web/pages/site.ts, the sign-in page's passkey block is now a single element marked data-passkey="on" hidden. The passkeyState() badge is gone from that page, and so is its import.
  • passkey-client.ts is unchanged. Its code that turns the badge to "Passkey on" now finds nothing on /signin, but the passkeys, everyday, first-admin and claim pages still use it. Those pages keep their badge, because there the state is a setting the person is looking at.
  • In test/signin-page.test.ts:

- The old test that required the badge now asserts the opposite: no "Passkey off", no "Passkey on" and no data-passkey-state in the page, and the passkey button sits inside a hidden element. - A new test drops every hidden element, as a browser without script shows the page, and asserts there is no passkey button, exactly one Sign in button, and the password field. - Both tests strip the inline <script> before checking, because the shared client script contains the words "Passkey on" as text. - The structural regex for the passkey block is updated to the new shape.

Checks run: bun scripts/gate.ts, bun scripts/design-lint.ts and bun x tsc --noEmit all pass. scripts/fast.ts picked 977 test files, far past its 5-minute budget, so I ran the suites that cover this change instead: the signin, forge-signin, passkey, first-admin, claim-link, linked-signin, web-ui, design-audit, xss-everywhere and page-text tests. 184 passed, 0 failed. The sandbox blocked outbound requests to maria--forge.test and kai--forge.test during that run, and the tests still passed.

To try it: open /signin on this pull's preview. In a browser with passkey support, the "Sign in with a passkey" button appears above the form. With JavaScript off, only the username, the password and one Sign in button show.

🤖 Generated with Claude Code

Closes #7921

commented

/signin no longer shows a "Passkey off" badge. The passkey button is now in the server-rendered page as hidden with data-passkey="on", and passkey-client.ts shows it once the browser can run a passkey, the same way it already shows the second Sign in button. Without a script, the page is just the password form with one visible Sign in button, and the page no longer shifts when the script runs.

What changed

  • In src/web/pages/site.ts, the sign-in page's passkey block is now a single element marked data-passkey="on" hidden. The passkeyState() badge is gone from that page, and so is its import.
  • passkey-client.ts is unchanged. Its code that turns the badge to "Passkey on" now finds nothing on /signin, but the passkeys, everyday, first-admin and claim pages still use it. Those pages keep their badge, because there the state is a setting the person is looking at.
  • In test/signin-page.test.ts:

- The old test that required the badge now asserts the opposite: no "Passkey off", no "Passkey on" and no data-passkey-state in the page, and the passkey button sits inside a hidden element. - A new test drops every hidden element, as a browser without script shows the page, and asserts there is no passkey button, exactly one Sign in button, and the password field. - Both tests strip the inline <script> before checking, because the shared client script contains the words "Passkey on" as text. - The structural regex for the passkey block is updated to the new shape.

Checks run: bun scripts/gate.ts, bun scripts/design-lint.ts and bun x tsc --noEmit all pass. scripts/fast.ts picked 977 test files, far past its 5-minute budget, so I ran the suites that cover this change instead: the signin, forge-signin, passkey, first-admin, claim-link, linked-signin, web-ui, design-audit, xss-everywhere and page-text tests. 184 passed, 0 failed. The sandbox blocked outbound requests to maria--forge.test and kai--forge.test during that run, and the tests still passed.

To try it: open /signin on this pull's preview. In a browser with passkey support, the "Sign in with a passkey" button appears above the form. With JavaScript off, only the username, the password and one Sign in button show.

🤖 Generated with Claude Code

Approved

Approved. Checked on the preview: /signin has no "Passkey off" badge. The passkey block is server-rendered as data-passkey="on" hidden, and [hidden]{display:none !important} in base.ts keeps it hidden. The two Sign in buttons use the existing on/off pair, so with JavaScript off the page is the password form with one primary Sign in. The script reveals the passkey block in place, so nothing shifts. The tests assert the new behaviour and would fail on the old markup. I did not run the tests myself.

Two things I would do next:

  1. The [data-passkey-state] .badge line in passkey-client.ts no longer matters on /signin. Keep it only while the other pages still draw the badge.
  2. The no-script test removes the hidden block with a regex that expects exactly </div>\s*</div>. A small markup change would make it pass for the wrong reason. Assert on the hidden attribute of the #passkey-signin ancestor instead.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs