| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 |
- import crypto from "node:crypto";
- import { PASSWORD_POLICY, validateNewPassword } from "@/lib/auth/passwordPolicy";
- const LETTERS = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
- const DIGITS = "23456789";
- const SPECIALS = "!@#$%&*_-";
- const CHARSET = `${LETTERS}${DIGITS}${SPECIALS}`;
- const DEFAULT_TEMP_PASSWORD_LENGTH = Math.max(PASSWORD_POLICY.minLength, 12);
- const MAX_GENERATION_ATTEMPTS = 20;
- function randomChar(chars) {
- const i = crypto.randomInt(0, chars.length);
- return chars[i];
- }
- function shuffle(input) {
- const chars = String(input).split("");
- for (let i = chars.length - 1; i > 0; i -= 1) {
- const j = crypto.randomInt(0, i + 1);
- [chars[i], chars[j]] = [chars[j], chars[i]];
- }
- return chars.join("");
- }
- function normalizeLength(length) {
- if (!Number.isInteger(length)) return DEFAULT_TEMP_PASSWORD_LENGTH;
- return Math.max(PASSWORD_POLICY.minLength, length);
- }
- export function generateAdminTemporaryPassword({ length } = {}) {
- const targetLength = normalizeLength(length);
- for (let attempt = 0; attempt < MAX_GENERATION_ATTEMPTS; attempt += 1) {
- const base = [randomChar(LETTERS), randomChar(DIGITS)];
- while (base.length < targetLength) {
- base.push(randomChar(CHARSET));
- }
- const candidate = shuffle(base.join(""));
- if (validateNewPassword({ newPassword: candidate }).ok) {
- return candidate;
- }
- }
- throw new Error("Unable to generate temporary password");
- }
|