diff --git a/lib/new-admin/graphql/modules/authentication.js b/lib/new-admin/graphql/modules/authentication.js index e0237b7c..55c7252f 100644 --- a/lib/new-admin/graphql/modules/authentication.js +++ b/lib/new-admin/graphql/modules/authentication.js @@ -272,8 +272,12 @@ const reset2FA = (token, userID, code, secret, context) => { return users.getUserById(userID) .then(user => { destroySessionIfSameUser(context, user) - return users.reset2FASecret(token, user.id, secret).then(() => true) + if (user.temp_twofa_code !== secret) { + throw new authErrors.InvalidTwoFactorError() + } + return users.reset2FASecret(token, user.id, secret) }) + .then(() => true) .catch(err => console.error(err)) } diff --git a/lib/users.js b/lib/users.js index 8f58ea00..9b7e3522 100644 --- a/lib/users.js +++ b/lib/users.js @@ -89,7 +89,7 @@ function reset2FASecret (token, id, secret) { return validateAuthToken(token, 'reset_twofa').then(res => { if (!res.success) throw new Error('Failed to verify 2FA reset token') return db.tx(t => { - const q1 = t.none('UPDATE users SET twofa_code=$1 WHERE id=$2', [secret, id]) + const q1 = t.none('UPDATE users SET twofa_code=$1, temp_twofa_code=NULL WHERE id=$2', [secret, id]) const q2 = t.none(`DELETE FROM user_sessions WHERE sess -> 'user' ->> 'id'=$1`, [id]) const q3 = t.none(`DELETE FROM auth_tokens WHERE token=$1 and type='reset_twofa'`, [token]) return t.batch([q1, q2, q3])