По фоновой проверке безопасности: mode insensitive превращался в ILIKE, и % / _ в адресе давали «доступ есть» за чужую почту; banned-пользователь считался с доступом; секрет сравнивался обычным ===. Почты в базе — в нижнем регистре (0 из 1426 с заглавными), вход нормализуется. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
34 lines
1.8 KiB
TypeScript
34 lines
1.8 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
import { accessWhere, isAuthorized, parseAccessCheck } from "../access-check";
|
|
|
|
describe("access-check", () => {
|
|
it("нормализует почту и требует оба поля", () => {
|
|
expect(parseAccessCheck({ email: " A@Example.COM ", course_slug: "second-brain-vault" }))
|
|
.toEqual({ email: "a@example.com", courseSlug: "second-brain-vault" });
|
|
expect(parseAccessCheck({ email: "a@example.com" })).toBeNull();
|
|
expect(parseAccessCheck({ course_slug: "x" })).toBeNull();
|
|
expect(parseAccessCheck({ email: "без-собаки", course_slug: "x" })).toBeNull();
|
|
expect(parseAccessCheck(null)).toBeNull();
|
|
expect(parseAccessCheck({ email: "a".repeat(250) + "@b.ru", course_slug: "x" })).toBeNull();
|
|
});
|
|
|
|
it("условие: точная почта (без ILIKE-шаблонов), не заблокирован, курс по slug, доступ не истёк", () => {
|
|
const now = new Date("2026-10-13T00:00:00Z");
|
|
const w = accessWhere({ email: "a@example.com", courseSlug: "second-brain-vault" }, now);
|
|
expect(w.user.email).toBe("a@example.com");
|
|
expect(JSON.stringify(w)).not.toContain("insensitive");
|
|
expect(w.user.NOT).toEqual({ banned: true, OR: [{ banExpires: null }, { banExpires: { gt: now } }] });
|
|
expect(w.course).toEqual({ slug: "second-brain-vault" });
|
|
expect(w.OR).toEqual([{ expiresAt: null }, { expiresAt: { gt: now } }]);
|
|
});
|
|
|
|
it("без секрета или с чужим — отказ", () => {
|
|
expect(isAuthorized("s", "s")).toBe(true);
|
|
expect(isAuthorized("s", undefined)).toBe(false);
|
|
expect(isAuthorized("s", "")).toBe(false);
|
|
expect(isAuthorized(null, "s")).toBe(false);
|
|
expect(isAuthorized("x", "s")).toBe(false);
|
|
expect(isAuthorized("ss", "s")).toBe(false);
|
|
});
|
|
});
|