Enforce admin CSRF, harden catalog translate, use CMS hotel name for PayPal.
Local Build and Deploy / deploy (push) Successful in 1m38s

Mutating withAdmin routes now require a double-submit CSRF token; translate is capped at 500 items with audit logging; PayPal descriptions prefer siteSettings hotel_name.

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
SimoandCursor committed 2026-07-18 19:38:42 +02:00
1 parent 6b884ad25a
commit 2de3696993
18 files changed
+218 -62

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
import { describe, expect, it } from "vitest";
import { translateItemsSchema } from "@/lib/validators/catalog";
describe("translateItemsSchema", () => {
it("accepts a valid payload", () => {
const parsed = translateItemsSchema.safeParse({
items: [{ id: 1, publicName: "Chair", description: "A chair" }],
});
expect(parsed.success).toBe(true);
});
it("rejects more than 500 items", () => {
const items = Array.from({ length: 501 }, (_, i) => ({
id: i + 1,
publicName: `Item ${i + 1}`,
}));
const parsed = translateItemsSchema.safeParse({ items });
expect(parsed.success).toBe(false);
});
it("rejects oversized public names", () => {
const parsed = translateItemsSchema.safeParse({
items: [{ id: 1, publicName: "x".repeat(256) }],
});
expect(parsed.success).toBe(false);
});
});
+16
View File
@@ -0,0 +1,16 @@
import { z } from "zod";
export const translateItemsSchema = z.object({
items: z
.array(
z.object({
id: z.coerce.number().int().positive(),
publicName: z.string().min(1, "Name is required").max(255),
description: z.string().max(1000).optional().default(""),
}),
)
.min(1, "At least one item required")
.max(500),
});
export type TranslateItemsInput = z.infer<typeof translateItemsSchema>;