[web-v2026.7.1] 2FA userVerificationToken for Authenticator, Email and Duo (#7563)

* 2FA using userVerificationToken

* Fix 2FA Yubikeys

* TwoFactor.find_by_user_and_type take enum parameter not i32

* log_user_event take enum parameter not i32

* Fix 2fa webauthn

* Prevent 2FA claims reuse

* 2fa webauthn return keys when deleting

* 2fa reset twofactor_remember

* Reject 2FA verification tokens issued for another provider

The Email and Duo claims only have optional fields, so a userVerificationToken minted for another
provider deserialized into them and was accepted. Each provider's claims now reject unknown fields,
with a test that every token only parses as its own provider.

Also fix the email 2FA login in the Playwright user setup, which used an undefined `mailBuffer`.

---------

Co-authored-by: Timshel <timshel@users.noreply.github.com>
Co-authored-by: Daniel García <dani-garcia@users.noreply.github.com>
This commit is contained in:
authored and GitHub committed 2026-10-06 23:45:55 +02:00
1 parent b8089e31c2
commit acbf49018f
18 files changed
+667 -366

No files matched your search

+2 -2
View File
@@ -137,11 +137,11 @@ impl TwoFactor {
.await
}
pub async fn find_by_user_and_type(user_uuid: &UserId, atype: i32, conn: &DbConn) -> Option<Self> {
pub async fn find_by_user_and_type(user_uuid: &UserId, atype: TwoFactorType, conn: &DbConn) -> Option<Self> {
conn.run(move |conn| {
twofactor::table
.filter(twofactor::user_uuid.eq(user_uuid))
.filter(twofactor::atype.eq(atype))
.filter(twofactor::atype.eq(atype as i32))
.first::<Self>(conn)
.ok()
})