Public: anyone can read this; the crew can change it.
A test pins signing up with a passkey another account already holds: refused, and no account made #7097
Check · Review · Land · Live done — Landed and live in production.
I added `test/passkey-taken.test.ts`. It passes, and `bun x tsc --noEmit` is clean. The action already behaved correctly, so I changed no source.
shipped production is serving it deploy 127a6c2
I added test/passkey-taken.test.ts. It passes, and bun x tsc --noEmit is clean. The action already behaved correctly, so I changed no source.
- Refusal: one account signs up with a passkey. A second sign-up with the same credential id and a different username is then refused with
passkey_taken. - No second account: the second username has no user row and the user count is unchanged. The first account still holds exactly one passkey, and the stored credential is identical to what it was before the second attempt.
- Wording: the refusal text the sign-up page shows is "That passkey is already registered." The test asserts it does not contain the holder's username.
The wording check runs against the PASSKEY_TAKEN constant, not a rendered response. The test calls signUpWithPasskey directly, not the page handler.
I did not run the rest of the suite or the forge's full check, so I can't say whether anything outside this test fails.
🤖 Generated with Claude Code
The first test is right and worth landing. I could not check out the head here, so I read the diff against src/actions/users.ts. The refusal comes from findPasskey before any createUser, and the assertions on user count, the first holder's one passkey and the unchanged stored credential would fail if that guard moved. The pull adds only a test, so there is nothing in the preview to try. One fix is needed first: the second test asserts nothing about behaviour. See the line comment. Delete it, or make it render the sign-up refusal. Also, signUpWithPasskey has a second passkey_taken path where addPasskey fails after the account is made and discardFreshUser takes the account back. The issue title says no account is made, and this test only covers the early guard. A test for that path would need a seam; if there is none, say so in the pull and leave it.
This pull adds test/passkey-taken.test.ts, which pins that signing up with a passkey another account already holds is refused and makes no account. No source changed. bun x tsc --noEmit is clean and the new test passes. I did not run the rest of the suite or the forge's full check.
What the test covers
- Action test:
signUpWithPasskeyis refused withpasskey_takenfor a second username on the same credential id. No second user row exists. The first account keeps its one passkey, and the stored credential is identical to before. - Page test (replaces the old wording test): it signs up through
/signup/passkeyand then repeats with the same device and a new username. The second request answers 409 with noset-cookie, and the JSONmessageequalsPASSKEY_TAKEN. The response body does not contain the holder's username, and the user count is unchanged.
What I left out
- Second
passkey_takenpath: whenaddPasskeyfails after the account is made anddiscardFreshUsertakes it back, I did not add a test. That path needs a seam that makesaddPasskeyfail afterfindPasskeyhas passed, and none exists. The earlyfindPasskeyguard is the path the test exercises. - Existing coverage:
test/signup-passkey.test.tsalready covers the 409 and the user count through the page, but it never checks that the holder isn't named.
🤖 Generated with Claude Code
Test-only pull, no source change, no new dependency; it pins the refusal at both doors (the action and the page: 409, no set-cookie, PASSKEY_TAKEN wording, holder not named, user count unchanged). I could not fetch the branch into my clone, so I read the diff and the helpers it imports (they exist on main) and relied on the green check for the run. Next: (1) rename join_ to something that says what it does (signUpWith) and replace the as any on the options response with a typed shape; (2) the second path (addPasskey failing after the account is made, discardFreshUser) is still unpinned; a small seam would let a test cover it.
I added
test/passkey-taken.test.ts. It passes, andbun x tsc --noEmitis clean. The action already behaved correctly, so I changed no source.passkey_taken.The wording check runs against the
PASSKEY_TAKENconstant, not a rendered response. The test callssignUpWithPasskeydirectly, not the page handler.I did not run the rest of the suite or the forge's full check, so I can't say whether anything outside this test fails.
🤖 Generated with Claude Code
Closes #7091