From 3e3776b4779a4594bbc7036a5f2a6fff2fb7b690 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Sat, 27 Jun 2026 14:33:51 +0200 Subject: [PATCH] feat(db): add pure isBanActive predicate matching Laravel ban filtering --- packages/db/src/bans/is-ban-active.test.ts | 22 ++++++++++++++++++++++ packages/db/src/bans/is-ban-active.ts | 5 +++++ 2 files changed, 27 insertions(+) create mode 100644 packages/db/src/bans/is-ban-active.test.ts create mode 100644 packages/db/src/bans/is-ban-active.ts diff --git a/packages/db/src/bans/is-ban-active.test.ts b/packages/db/src/bans/is-ban-active.test.ts new file mode 100644 index 00000000..9b63bfb2 --- /dev/null +++ b/packages/db/src/bans/is-ban-active.test.ts @@ -0,0 +1,22 @@ +import { describe, it, expect } from "vitest"; +import { isBanActive } from "./is-ban-active.js"; + +describe("isBanActive", () => { + const now = 1_700_000_000; // fixed unix seconds + + it("is active when ban_expire is in the future", () => { + expect(isBanActive({ banExpire: now + 100 }, now)).toBe(true); + }); + + it("is inactive when ban_expire is in the past", () => { + expect(isBanActive({ banExpire: now - 100 }, now)).toBe(false); + }); + + it("is inactive when ban_expire equals now (Laravel uses strict >)", () => { + expect(isBanActive({ banExpire: now }, now)).toBe(false); + }); + + it("is inactive for the default 0 expiry", () => { + expect(isBanActive({ banExpire: 0 }, now)).toBe(false); + }); +}); diff --git a/packages/db/src/bans/is-ban-active.ts b/packages/db/src/bans/is-ban-active.ts new file mode 100644 index 00000000..53c7a5b9 --- /dev/null +++ b/packages/db/src/bans/is-ban-active.ts @@ -0,0 +1,5 @@ +// Mirrors Laravel's active-ban query: where('ban_expire', '>', time()). +// ban_expire and now are both unix timestamps in seconds. +export function isBanActive(ban: { banExpire: number }, nowUnixSeconds: number): boolean { + return ban.banExpire > nowUnixSeconds; +}