Enforce admin CSRF, harden catalog translate, use CMS hotel name for PayPal.
Local Build and Deploy / deploy (push) Successful in 1m38s
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:
1 parent
6b884ad25a
commit
2de3696993
18 files changed
+218
-62
No files matched your search
@@ -5,9 +5,11 @@ import { Prisma } from "@/generated/prisma/client";
|
||||
import { requirePermission } from "@/lib/admin/guard";
|
||||
import { PERMS } from "@/lib/permissions";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { logAudit } from "@/lib/services/audit";
|
||||
import { allocateCatalogItemId } from "@/lib/services/furni-import";
|
||||
import { rcon } from "@/lib/services/rcon";
|
||||
import { logStaffActivity } from "@/lib/services/staff-activity";
|
||||
import { translateItemsSchema } from "@/lib/validators/catalog";
|
||||
|
||||
const CATALOG_ITEM_FIELDS = [
|
||||
"pageId",
|
||||
@@ -323,13 +325,19 @@ export async function updateCatalogItem({
|
||||
return { ok: true as const, data: {} };
|
||||
}
|
||||
|
||||
export async function translateCatalogItems({
|
||||
items,
|
||||
}: {
|
||||
export async function translateCatalogItems(input: {
|
||||
/** `id` is items_base.id (not catalog_items.id) */
|
||||
items: Array<{ id: number; publicName: string; description: string }>;
|
||||
items: Array<{ id: number; publicName: string; description?: string }>;
|
||||
}) {
|
||||
await requirePermission(PERMS.CATALOG_EDIT);
|
||||
const staff = await requirePermission(PERMS.CATALOG_EDIT);
|
||||
const parsed = translateItemsSchema.safeParse(input);
|
||||
if (!parsed.success) {
|
||||
return {
|
||||
ok: false as const,
|
||||
error: parsed.error.issues[0]?.message ?? "Invalid translate payload",
|
||||
};
|
||||
}
|
||||
const { items } = parsed.data;
|
||||
const { invalidateFurniDataCache } = await import(
|
||||
"@/lib/services/catalog-items-loader"
|
||||
);
|
||||
@@ -413,6 +421,17 @@ export async function translateCatalogItems({
|
||||
}
|
||||
|
||||
await rcon.updateCatalog();
|
||||
await logAudit({
|
||||
userId: staff.id,
|
||||
action: "items_base_translate",
|
||||
target: "ItemsBase",
|
||||
after: {
|
||||
namesUpdated,
|
||||
descriptionsUpdated,
|
||||
furniDataUpdated: furniResult.updated > 0,
|
||||
furniDataInserted: furniResult.inserted,
|
||||
},
|
||||
});
|
||||
revalidatePath("/admin/catalog");
|
||||
return {
|
||||
ok: true as const,
|
||||
|
||||
Reference in new issue
Block a user