chore(release): v1.4.45 — analytics 9 s perf fix + audit-marathon closure + v1.4.44 hotfix merged

Audit-marathon close: 14 waves + W10 QA + reconcile. Perf fix (analytics 9 s -> 2-3 s), Zod multi-issue rollout (41 routes), Withings parked-state automation, mobile-UI WCAG 2.5.5 close, QoL i18n + offline banner + account delete, security PII drop + replay-injection scan. Migration 0075 required. Tests 4815 -> 5076.
This commit is contained in:
Marc-André Bombeck authored and GitHub committed 2026-05-21 23:13:21 +02:00
1 parent 324d4bb411
commit 6c7fc7dc84
167 files changed
+11233 -371

No files matched your search

@@ -30,9 +30,27 @@ vi.mock("@/lib/rate-limit", () => ({
remaining: 29,
resetAt: Date.now() + 15 * 60 * 1000,
}),
// v1.4.43 W13 M-4 — the route now routes through the auth-surface
// wrapper. Default to a clean per-IP result.
checkAuthSurfaceRateLimit: vi.fn().mockResolvedValue({
allowed: true,
remaining: 29,
resetAt: Date.now() + 15 * 60 * 1000,
ip: "203.0.113.1",
}),
rateLimitHeaders: vi.fn(() => ({})),
}));
vi.mock("@/lib/auth/hmac", () => ({
hashToken: vi.fn(
(raw: string) =>
`hash-${Buffer.from(raw, "utf-8")
.toString("hex")
.slice(0, 16)
.padStart(16, "0")}`,
),
}));
vi.mock("next/headers", () => ({
headers: vi.fn(async () => ({ get: () => null })),
cookies: vi.fn(async () => ({
@@ -44,7 +62,10 @@ vi.mock("next/headers", () => ({
import { POST } from "@/app/api/auth/check-user/route";
import { prisma } from "@/lib/db";
import { checkRateLimit } from "@/lib/rate-limit";
import {
checkRateLimit,
checkAuthSurfaceRateLimit,
} from "@/lib/rate-limit";
interface CheckUserBody {
data: {
@@ -69,6 +90,12 @@ beforeEach(() => {
remaining: 29,
resetAt: Date.now() + 15 * 60 * 1000,
});
vi.mocked(checkAuthSurfaceRateLimit).mockResolvedValue({
allowed: true,
remaining: 29,
resetAt: Date.now() + 15 * 60 * 1000,
ip: "203.0.113.1",
} as never);
});
afterEach(() => {
@@ -149,11 +176,12 @@ describe("POST /api/auth/check-user", () => {
});
it("returns 429 when the per-IP rate-limit is exhausted", async () => {
vi.mocked(checkRateLimit).mockResolvedValueOnce({
vi.mocked(checkAuthSurfaceRateLimit).mockResolvedValueOnce({
allowed: false,
remaining: 0,
resetAt: Date.now() + 15 * 60 * 1000,
});
ip: "203.0.113.1",
} as never);
const res = await POST(makeRequest({ identifier: "anyone@example.com" }));
expect(res.status).toBe(429);
expect(prisma.user.findFirst).not.toHaveBeenCalled();