Skip to content

Commit

Permalink
add safe password generator + test (#2264)
Browse files Browse the repository at this point in the history
  • Loading branch information
jancimertel authored Aug 11, 2024
1 parent ed1c0b2 commit 77ca562
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 3 deletions.
41 changes: 40 additions & 1 deletion packages/server/src/common/functions.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import "ts-jest";
import { sanitizeText } from "./functions";
import { generatePassword, sanitizeText } from "./functions";

describe("Test sanitizeText", function () {
it("should replace nbsp char normal whitespace", () => {
Expand All @@ -8,3 +8,42 @@ describe("Test sanitizeText", function () {
expect(sanitizeText(input)).toEqual(wanted);
});
});

function isSafePassword(password: string) {
// Check if the password is at least 12 characters long
if (password.length < 12) {
return false;
}
// Check if the password contains at least one uppercase letter
if (!/[A-Z]/.test(password)) {
return false;
}
// Check if the password contains at least one lowercase letter
if (!/[a-z]/.test(password)) {
return false;
}
// Check if the password contains at least one digit
if (!/\d/.test(password)) {
return false;
}
// Check if the password contains at least one symbol
if (!/[!@#$%^&*()_+{}\[\]:;<>,.?/~\\-]/.test(password)) {
return false;
}
// If all conditions are met, the password is considered safe
return true;
}

describe("Test generatePassword", function () {
it("should generate valid safe password", () => {
expect(isSafePassword(generatePassword(12))).toBeTruthy();
expect(isSafePassword(generatePassword(13))).toBeTruthy();
expect(isSafePassword(generatePassword(14))).toBeTruthy();
expect(isSafePassword(generatePassword(15))).toBeTruthy();
});

it("should generate invalid password with length < 12", () => {
expect(isSafePassword(generatePassword(11))).toBeFalsy();
expect(isSafePassword(generatePassword(10))).toBeFalsy();
});
});
27 changes: 27 additions & 0 deletions packages/server/src/common/functions.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as crypto from "crypto"

export const getRandomInt = () => {
return Math.floor(Math.random() * 1_000_000_000_000);
};
Expand Down Expand Up @@ -74,3 +76,28 @@ export function sanitizeText(inStr: string): string {
inStr = inStr.replace(/\xa0/gi, " ");
return inStr;
}

export function generatePassword(length = 12): string {
const upperCase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
const lowerCase = 'abcdefghijklmnopqrstuvwxyz';
const digits = '0123456789';
const symbols = '!@#$%^&*()-_=+[]{}|;:,.<>?';

const allChars = upperCase + lowerCase + digits + symbols;

let password = '';
password += upperCase[Math.floor(Math.random() * upperCase.length)];
password += lowerCase[Math.floor(Math.random() * lowerCase.length)];
password += digits[Math.floor(Math.random() * digits.length)];
password += symbols[Math.floor(Math.random() * symbols.length)];

for (let i = 4; i < length; i++) {
const randomByte = crypto.randomBytes(1)[0];
password += allChars[randomByte % allChars.length];
}

// Shuffle the password to make sure the characters are not in the same order
password = password.split('').sort(() => 0.5 - Math.random()).join('');

return password;
}
4 changes: 2 additions & 2 deletions packages/server/src/models/user/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IDbModel, fillArray, fillFlatObject } from "@models/common";
import { EntityEnums, UserEnums } from "@shared/enums";
import { ModelNotValidError } from "@shared/types/errors";
import { generateRandomString, generateUuid, hashPassword } from "@common/auth";
import { regExpEscape } from "@common/functions";
import { generatePassword, regExpEscape } from "@common/functions";
import { nonenumerable } from "@common/decorators";
import { Db } from "@service/rethink";

Expand Down Expand Up @@ -205,7 +205,7 @@ export default class User implements IUser, IDbModel {
}

generatePassword(): string {
const raw = generateRandomString(10);
const raw = generatePassword(12);
return this.setPassword(raw);
}

Expand Down

0 comments on commit 77ca562

Please sign in to comment.