convex-auth v2.4.1
Highlights
- Argon2id password hashing —
argon2id-wasm(Rust → WASM), ~10x faster in the Convex isolate. New hashes in standard PHC format ($argon2id$v=19$m=19456,t=2,p=1$); legacy packed, Better Auth scrypt, and PBKDF2 hashes still verify — no migration needed. - Passkeys, web + React Native/Expo — registration, sign-in, revocation, and rename, bound to the caller’s identity. Conditional-UI autofill on web;
react-native-passkeys-backed ceremonies on iOS/Android verified by the same server actions. Validated end-to-end on both platforms. - Session hardening — every session-validating path now rejects revoked sessions; session lists never expose raw tokens (
isCurrentcomputed server-side,revokeSessiontakessessionIdwith an ownership check); 2FA pending challenges are opaque hashed tokens, not JWTs. - Passkey revocation cascade — sessions and refresh tokens minted by a passkey record
credentialId; revoking the passkey (or detecting a cloned authenticator via signature-counter regression) revokes them all, across arbitrarily large histories including pre-credentialIdlegacy rows. - Admin dashboard — impersonation with audited sessions, user search + detail panel, organization member/role management, audit-log filters.
- Query exhaustion fixes — all revocation and code-consume paths paginate to exhaustion; sessions, refresh tokens, and live codes beyond the first index page can no longer survive revocation.
What’s Changed
Password hashing
- Switch password hashing to
argon2id-wasm; WASM init failures now surface as errors instead of reading as “wrong password”.
Passkeys
- Passkey management (register, list, revoke, rename) bound to
ctx.auth.getUserIdentity(). - Non-increasing signature counter revokes the passkey and writes a
passkey_counter_regressionaudit event (cloned-authenticator detection). renamePasskeymutation viaauth.renamePasskey,usePasskeys().rename,onRenameprop onPasskeyManager.passkey.maxPasskeysPerUserconfig (default 10), re-checked at verification time.passkey.originacceptsstring | string[];attestationType,userVerification,residentKey,authenticatorAttachmentconfigurable.usePasskeys({ autofill: true })enables WebAuthn conditional-UI sign-in.- Challenges record
rpID, accepted origins, effective identifier, and UV policy at generation; verification uses stored values. - Relaxed-UV passkey sign-in on a 2FA account returns
twoFactorRedirect; the pending challenge carriescredentialIdso the minted session stays revocable with the passkey. BothusePasskeyshooks store the challenge token soConvexVerifyTwoFactorFormcompletes the flow. - Passkey revocation paginates all lookups to exhaustion, attributes legacy sessions via stored-JWT
identityId, and consumes in-flight pending challenges. usePasskeysfetches ceremony options at invocation time, not mount — no stale challenges.- Audit events:
passkey_registered,passkey_authenticated,passkey_renamed,passkey_revoked. - React Native / Expo:
usePasskeysunder@vortex-api/convex-auth/react-native/passkeys(optionalreact-native-passkeyspeer). Configurepasskey.originper platform includingandroid:apk-key-hash:<hash>.
Sessions & 2FA
listSessionsno longer returnstoken; items carry server-computedisCurrent.revokeSessiontakes{ sessionId }with caller-ownership verification.ConvexSessionListdropscurrentSessionToken(web + React Native). Migration:revokeSession({ token })→revokeSession({ sessionId }); remove thecurrentSessionTokenprop.revokedAtenforced on session resolution, token-verify action, bearer/convex/tokenand/session, MCP OAuth authorize, OAuth account linking, andverifySession(no more arbitrary-active-session fallback).- Session-family revocation,
revokeSessionsForUser, refresh-token revocation, password-reset revoke, and verification-code consume/revoke paths all paginate to exhaustion. authAccountsgainsby_user_provider_issuer;organization_membersgainsby_user_status.
Admin
- Safe impersonation: short-lived audited sessions,
IMPERSONATION_SESSION_DURATION_MSconfig, banner + stop in the React example. createUser,setRole,setUserPassword,listUserswith search/filter/sort/pagination.listAdminAuditsfilters (action,targetType,targetId,adminId,from,to);auditsFiltersdashboard controls.- Member list/search/pagination,
updateMemberRole,removeMemberdashboard wiring. - User search + detail side panel via
usersSearch,onViewUser,selectedUser.
React Native demo
- Single
react-nativeversion across the workspace; Metro native extensions; Expo SDK 57 alignment; Uniwind theme init +accent-colorpatch; session JWT no longer rendered in the header.
Full Changelog: https://github.com/VortexNYC/convex-auth/compare/v2.3.0...v2.4.1