misc: addressed PR comments

This commit is contained in:
Sheen Capadngan
2024-05-24 23:45:16 +08:00
parent 9b2b6d61be
commit c0daa11aeb
7 changed files with 79 additions and 69 deletions
+15 -1
View File
@@ -143,6 +143,19 @@ export const userDALFactory = (db: TDbClient) => {
}
};
const incrementFailedMfaAttempt = async (userId: string, tx?: Knex) => {
try {
const [user] = await (tx || db)(TableName.Users)
.where("id", userId)
.increment("consecutiveFailedMfaAttempts", 1)
.returning("*");
return user;
} catch (error) {
throw new DatabaseError({ error, name: "Increment Failed MFA Attempt" });
}
};
return {
...userOrm,
findUserByUsername,
@@ -155,6 +168,7 @@ export const userDALFactory = (db: TDbClient) => {
upsertUserEncryptionKey,
createUserEncryption,
findOneUserAction,
createUserAction
createUserAction,
incrementFailedMfaAttempt
};
};
-53
View File
@@ -1,7 +1,5 @@
import slugify from "@sindresorhus/slugify";
import { TableName } from "@app/db/schemas";
import { DatabaseError } from "@app/lib/errors";
import { alphaNumericNanoId } from "@app/lib/nanoid";
import { TUserDALFactory } from "@app/services/user/user-dal";
@@ -21,54 +19,3 @@ export const normalizeUsername = async (username: string, userDAL: Pick<TUserDAL
}
}
};
export const processFailedMfaAttempt = async (userId: string, userDAL: Pick<TUserDALFactory, "transaction">) => {
try {
const updatedUser = await userDAL.transaction(async (tx) => {
const PROGRESSIVE_DELAY_INTERVAL = 3;
const [user] = await tx(TableName.Users)
.where("id", userId)
.increment("consecutiveFailedMfaAttempts", 1)
.returning("*");
if (!user) {
throw new Error("User not found");
}
const progressiveDelaysInMins = [5, 30, 60];
// lock user when failed attempt exceeds threshold
if (user.consecutiveFailedMfaAttempts >= PROGRESSIVE_DELAY_INTERVAL * (progressiveDelaysInMins.length + 1)) {
return (
await tx(TableName.Users)
.where("id", userId)
.update({
isLocked: true,
temporaryLockDateEnd: null
})
.returning("*")
)[0];
}
// delay user only when failed MFA attempts is a multiple of configured delay interval
if (user.consecutiveFailedMfaAttempts % PROGRESSIVE_DELAY_INTERVAL === 0) {
const delayIndex = user.consecutiveFailedMfaAttempts / PROGRESSIVE_DELAY_INTERVAL - 1;
return (
await tx(TableName.Users)
.where("id", userId)
.update({
temporaryLockDateEnd: new Date(new Date().getTime() + progressiveDelaysInMins[delayIndex] * 60 * 1000)
})
.returning("*")
)[0];
}
return user;
});
return updatedUser;
} catch (error) {
throw new DatabaseError({ error, name: "Process failed MFA Attempt" });
}
};