import { randomBytes, scryptSync, timingSafeEqual } from "node:crypto"; const SCRYPT_KEY_LENGTH = 64; export function normalizePhone(raw: string) { const trimmed = (raw ?? "").trim(); if (!trimmed) return ""; const hasPlus = trimmed.startsWith("+"); const digits = trimmed.replace(/\D/g, ""); if (!digits) return ""; return `${hasPlus ? "+" : ""}${digits}`; } export function hashPassword(password: string) { const salt = randomBytes(16).toString("base64url"); const digest = scryptSync(password, salt, SCRYPT_KEY_LENGTH).toString("base64url"); return `scrypt$${salt}$${digest}`; } export function verifyPassword(password: string, encodedHash: string) { const [algo, salt, digest] = (encodedHash ?? "").split("$"); if (algo !== "scrypt" || !salt || !digest) return false; const actual = scryptSync(password, salt, SCRYPT_KEY_LENGTH); const expected = Buffer.from(digest, "base64url"); if (actual.byteLength !== expected.byteLength) return false; return timingSafeEqual(actual, expected); }