import { describe, expect, it } from "vitest"; import { loginSchema, registerSchema } from "./auth.schema"; const email = "user@example.com"; function canLogIn(password: string) { return loginSchema.safeParse({ email, password }).success; } function canRegister(password: string, confirmation = password) { return registerSchema.safeParse({ email, password, passwordConfirmation: confirmation, }).success; } // Register policy: 8..72 printable ASCII (bcrypt reads 72 bytes, so non-ASCII could be // truncated). Login stays lenient so accounts created under the old policy still sign in. describe("auth password policy", () => { it.each([ ["7 chars", "a".repeat(7), false], ["8 chars", "a".repeat(8), true], ["72 chars", "a".repeat(72), true], ["73 chars", "a".repeat(73), false], ["printable symbols and space", "Aa1 !~\"#$%&'()*+,-./:;<=>?@", true], ["Cyrillic, 8+ chars", "пароль-пароль", false], ["emoji", "passw😀rd", false], ["tab", "pass\tword1", false], ["newline", "password1\n", false], ["DEL", "password\u{7F}1", false], ])("register: %s", (_, password, accepted) => { expect(canRegister(password)).toBe(accepted); }); it("register compares the raw password with its confirmation", () => { const padded = " spaced pass "; expect(canRegister(padded)).toBe(true); expect(canRegister(padded, padded.trim())).toBe(false); }); it.each([ ["legacy Cyrillic password", "пароль-пароль", true], ["short legacy password", "short", true], ["72 bytes", "a".repeat(72), true], ["73 bytes", "a".repeat(73), false], ["36 Cyrillic letters = 72 bytes", "я".repeat(36), true], ["37 Cyrillic letters = 74 bytes", "я".repeat(37), false], ["empty", "", false], ])("login: %s", (_, password, accepted) => { expect(canLogIn(password)).toBe(accepted); }); });