WebAuthn / passkey credential CRUD backed by SQLite (migration 029, SEC-004).
Encapsulates all webauthn_credentials queries so route handlers never
write raw SQL — per AGENT.md: "Do not write raw SQL in route handlers."
Field shapes
id— WebAuthn credential ID (base64url-encoded string, primary key).publicKey— COSE-encoded public key (base64 string).counter— signature counter, monotonically increasing per credential.transports— JSON-encoded array of WebAuthn transport hints, e.g.["internal"],["usb","nfc"]. Stored as TEXT, hydrated to an array by readers below.deviceName— user-supplied label shown in the credentials list.
Methods
(static) countByUser(userId) → {number}
Count credentials for a user. Used by the Settings UI to display "N passkeys registered" without round-tripping the full list.
Parameters:
| Name | Type | Description |
|---|---|---|
userId |
string |
Returns:
- Type
- number
(static) create(cred) → {Object}
Create a new WebAuthn credential row.
Parameters:
| Name | Type | Description | |||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
cred |
Object |
Properties
|
Returns:
The created credential row (with transports hydrated).
- Type
- Object
(static) deleteById(credentialId, userId) → {boolean}
Delete a credential — scoped by userId so one user cannot remove
another user's credential even if they guess the ID.
Parameters:
| Name | Type | Description |
|---|---|---|
credentialId |
string | |
userId |
string |
Returns:
true if a row was deleted.
- Type
- boolean
(static) getById(credentialId) → {Object|undefined}
Look up a credential by its WebAuthn ID.
Parameters:
| Name | Type | Description |
|---|---|---|
credentialId |
string |
Returns:
- Type
- Object | undefined
(static) listByUser(userId) → {Array.<Object>}
List all credentials registered to a user, oldest first so the UI can render them in registration order.
Parameters:
| Name | Type | Description |
|---|---|---|
userId |
string |
Returns:
- Type
- Array.<Object>
(static) updateCounter(credentialId, counter) → {boolean}
Update a credential's signature counter and last-used timestamp after a
successful authentication. The counter is part of the WebAuthn clone-
detection protocol — callers MUST verify newCounter > oldCounter before
calling this; otherwise the credential may have been cloned.
Parameters:
| Name | Type | Description |
|---|---|---|
credentialId |
string | |
counter |
number |
Returns:
true if a row was updated.
- Type
- boolean