access-check: точное сравнение почты (без ILIKE-шаблонов), заблокированным — нет, секрет за постоянное время
По фоновой проверке безопасности: mode insensitive превращался в ILIKE, и % / _ в адресе давали «доступ есть» за чужую почту; banned-пользователь считался с доступом; секрет сравнивался обычным ===. Почты в базе — в нижнем регистре (0 из 1426 с заглавными), вход нормализуется. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,10 +12,12 @@ describe("access-check", () => {
|
||||
expect(parseAccessCheck({ email: "a".repeat(250) + "@b.ru", course_slug: "x" })).toBeNull();
|
||||
});
|
||||
|
||||
it("условие: почта без учёта регистра, курс по slug, доступ не истёк", () => {
|
||||
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).toEqual({ equals: "a@example.com", mode: "insensitive" });
|
||||
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 } }]);
|
||||
});
|
||||
@@ -26,5 +28,6 @@ describe("access-check", () => {
|
||||
expect(isAuthorized("s", "")).toBe(false);
|
||||
expect(isAuthorized(null, "s")).toBe(false);
|
||||
expect(isAuthorized("x", "s")).toBe(false);
|
||||
expect(isAuthorized("ss", "s")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user