fix: should always remove 2FA verification token after successful verification (#6604)

This commit is contained in:
Brendan Delfortrie
2025-12-08 19:00:08 -05:00
committed by GitHub
parent 44aa11d3f9
commit 13efb8540b
2 changed files with 29 additions and 5 deletions

View File

@@ -322,10 +322,30 @@ describe("two factor", async () => {
expect(currentBackupCodes.backupCodes).toBeDefined();
expect(currentBackupCodes.backupCodes).not.toContain(backupCode);
// Start a new 2FA session to test invalid backup code
const headers2 = new Headers();
await client.signIn.email({
email: testUser.email,
password: testUser.password,
fetchOptions: {
onSuccess(context) {
const parsed = parseSetCookieHeader(
context.response.headers.get("Set-Cookie") || "",
);
headers2.append(
"cookie",
`better-auth.two_factor=${
parsed.get("better-auth.two_factor")?.value
}`,
);
},
},
});
const res = await client.twoFactor.verifyBackupCode({
code: "invalid-code",
fetchOptions: {
headers,
headers: headers2,
onSuccess(context) {
const parsed = parseSetCookieHeader(
context.response.headers.get("Set-Cookie") || "",

View File

@@ -60,10 +60,18 @@ export async function verifyTwoFactor(ctx: GenericEndpointContext) {
message: "failed to create session",
});
}
// Delete the verification token from the database after successful verification
await ctx.context.internalAdapter.deleteVerificationValue(
verificationToken.id,
);
await setSessionCookie(ctx, {
session,
user,
});
// Always clear the two factor cookie after successful verification
ctx.setCookie(cookieName.name, "", {
maxAge: 0,
});
if (ctx.body.trustDevice) {
const trustDeviceCookie = ctx.context.createAuthCookie(
TRUST_DEVICE_COOKIE_NAME,
@@ -89,10 +97,6 @@ export async function verifyTwoFactor(ctx: GenericEndpointContext) {
ctx.setCookie(ctx.context.authCookies.dontRememberToken.name, "", {
maxAge: 0,
});
// delete the two factor cookie
ctx.setCookie(cookieName.name, "", {
maxAge: 0,
});
}
return ctx.json({
token: session.token,