Frontend verify / commits (push) Skipped
Frontend verify / commits (pull_request) Failing after 40s
Frontend verify / security (pull_request) Skipped
Frontend verify / verify (pull_request) Skipped
Frontend verify / security (push) Successful in 11s
Frontend verify / verify (push) Failing after 7m35s
56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
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);
|
|
});
|
|
});
|