This commit is contained in:
Milo Schwartz
2024-12-25 15:55:50 -05:00
22 changed files with 520 additions and 438 deletions

View File

@@ -92,10 +92,6 @@ export async function disable2fa(
.set({ twoFactorEnabled: false })
.where(eq(users.userId, user.userId));
await db
.delete(twoFactorBackupCodes)
.where(eq(twoFactorBackupCodes.userId, user.userId));
sendEmail(
TwoFactorAuthNotification({
email: user.email,

View File

@@ -63,18 +63,23 @@ export async function requestPasswordReset(
);
}
await db
.delete(passwordResetTokens)
.where(eq(passwordResetTokens.userId, existingUser[0].userId));
const token = generateRandomString(
8,
alphabet("0-9", "A-Z", "a-z")
);
await db.transaction(async (trx) => {
await trx
.delete(passwordResetTokens)
.where(eq(passwordResetTokens.userId, existingUser[0].userId));
const token = generateRandomString(8, alphabet("0-9", "A-Z", "a-z"));
const tokenHash = await hashPassword(token);
const tokenHash = await hashPassword(token);
await db.insert(passwordResetTokens).values({
userId: existingUser[0].userId,
email: existingUser[0].email,
tokenHash,
expiresAt: createDate(new TimeSpan(2, "h")).getTime()
await trx.insert(passwordResetTokens).values({
userId: existingUser[0].userId,
email: existingUser[0].email,
tokenHash,
expiresAt: createDate(new TimeSpan(2, "h")).getTime()
});
});
const url = `${config.app.base_url}/auth/reset-password?email=${email}&token=${token}`;

View File

@@ -135,20 +135,22 @@ export async function resetPassword(
await invalidateAllSessions(resetRequest[0].userId);
await db
.update(users)
.set({ passwordHash })
.where(eq(users.userId, resetRequest[0].userId));
await db.transaction(async (trx) => {
await trx
.update(users)
.set({ passwordHash })
.where(eq(users.userId, resetRequest[0].userId));
await db
.delete(passwordResetTokens)
.where(eq(passwordResetTokens.email, email));
await trx
.delete(passwordResetTokens)
.where(eq(passwordResetTokens.email, email));
});
await sendEmail(ConfirmPasswordReset({ email }), {
from: config.email?.no_reply,
to: email,
subject: "Password Reset Confirmation"
})
});
return response<ResetPasswordResponse>(res, {
data: null,

View File

@@ -62,16 +62,18 @@ export async function verifyEmail(
const valid = await isValidCode(user, code);
if (valid) {
await db
.delete(emailVerificationCodes)
.where(eq(emailVerificationCodes.userId, user.userId));
await db.transaction(async (trx) => {
await trx
.delete(emailVerificationCodes)
.where(eq(emailVerificationCodes.userId, user.userId));
await db
.update(users)
.set({
emailVerified: true
})
.where(eq(users.userId, user.userId));
await trx
.update(users)
.set({
emailVerified: true
})
.where(eq(users.userId, user.userId));
});
} else {
return next(
createHttpError(

View File

@@ -76,21 +76,23 @@ export async function verifyTotp(
let codes;
if (valid) {
// if valid, enable two-factor authentication; the totp secret is no longer temporary
await db
.update(users)
.set({ twoFactorEnabled: true })
.where(eq(users.userId, user.userId));
await db.transaction(async (trx) => {
await trx
.update(users)
.set({ twoFactorEnabled: true })
.where(eq(users.userId, user.userId));
const backupCodes = await generateBackupCodes();
codes = backupCodes;
for (const code of backupCodes) {
const hash = await hashPassword(code);
const backupCodes = await generateBackupCodes();
codes = backupCodes;
for (const code of backupCodes) {
const hash = await hashPassword(code);
await db.insert(twoFactorBackupCodes).values({
userId: user.userId,
codeHash: hash
});
}
await trx.insert(twoFactorBackupCodes).values({
userId: user.userId,
codeHash: hash
});
}
});
}
if (!valid) {