All files / validators password.js

0% Statements 0/65
0% Branches 0/1
0% Functions 0/1
0% Lines 0/65

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66                                                                                                                                   
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { z } from "zod";
// Password validation schema with strong requirements
export const passwordSchema = z
    .string()
    .min(12, "Password must be at least 12 characters")
    .regex(/[A-Z]/, "Password must contain uppercase letter")
    .regex(/[a-z]/, "Password must contain lowercase letter")
    .regex(/[0-9]/, "Password must contain number")
    .regex(/[^A-Za-z0-9]/, "Password must contain special character");
// Async function to check against pwned passwords API
export function isPasswordCompromised(password) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            // Simple hash function for demonstration (in production, use proper crypto)
            const encoder = new TextEncoder();
            const data = encoder.encode(password);
            const hashBuffer = yield crypto.subtle.digest("SHA-1", data);
            const hashArray = Array.from(new Uint8Array(hashBuffer));
            const hashHex = hashArray
                .map((b) => b.toString(16).padStart(2, "0"))
                .join("")
                .toUpperCase();
            const _prefix = hashHex.substring(0, 5);
            const _suffix = hashHex.substring(5);
            // In a real implementation, you would call the pwned passwords API
            // const response = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`);
            // const hashes = await response.text();
            // return hashes.includes(suffix);
            // For now, we'll return false to indicate the password is not compromised
            return false;
        }
        catch (_error) {
            // If there's an error checking, we'll be conservative and assume it's not compromised
            return false;
        }
    });
}
// Combined password validation function
export function validatePassword(password) {
    return __awaiter(this, void 0, void 0, function* () {
        const result = passwordSchema.safeParse(password);
        if (!result.success) {
            const errors = result.error.issues.map((issue) => issue.message);
            return { valid: false, errors };
        }
        // Check if password is compromised
        const isCompromised = yield isPasswordCompromised(password);
        if (isCompromised) {
            return {
                valid: false,
                errors: ["Password has been compromised in a data breach"],
            };
        }
        return { valid: true, errors: [] };
    });
}