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: [] }; }); } |