fix(admin): Kategorie und Slug beim Produkt-Anlegen serverseitig pruefen
Die Kategorie kam bisher nur per Typ-Cast aus dem Formular; ein manipulierter Wert endete als unbehandelte Prisma-Ausnahme. Ein eigener Slug wurde ungeprueft zur oeffentlichen Adresse, inklusive Schraegstrichen und Sonderzeichen. Neues adminProductIdentitySchema: Kategorie per Enum, Slug auf a-z, 0-9 und Bindestrich (Umlaute umschrieben, max. 80 Zeichen), leere Adresse wird mit Meldung abgelehnt. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
1 parent
c125e91941
commit
95b4b5953d
3 files changed
+68
-4
No files matched your search
@@ -4,7 +4,7 @@ import { revalidatePath } from "next/cache";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { logAdminAction } from "@/lib/audit-log";
|
||||
import { notifyStockAvailable } from "@/lib/stock-notifications";
|
||||
import { adminProductNumbersSchema } from "@/lib/validation";
|
||||
import { adminProductIdentitySchema, adminProductNumbersSchema } from "@/lib/validation";
|
||||
import { isValidUploadPath } from "@/lib/uploads";
|
||||
import { requireAdmin, fail, str, strOrNull, strArray } from "./_shared";
|
||||
import { succeed } from "@/lib/flash";
|
||||
@@ -29,7 +29,15 @@ async function assertPricedIfActive(redirectPath: string, isActive: boolean, pri
|
||||
|
||||
export async function createProductAction(formData: FormData): Promise<void> {
|
||||
const admin = await requireAdmin();
|
||||
const slug = str(formData, "slug") || str(formData, "name").toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
||||
const parsedIdentity = adminProductIdentitySchema.safeParse({
|
||||
name: str(formData, "name"),
|
||||
slug: str(formData, "slug"),
|
||||
category: str(formData, "category") || "HONIG",
|
||||
});
|
||||
if (!parsedIdentity.success) {
|
||||
return fail("/admin/produkte/neu", parsedIdentity.error.issues[0]?.message ?? "Ungültige Eingabe.");
|
||||
}
|
||||
const { slug, category } = parsedIdentity.data;
|
||||
|
||||
const parsedNumbers = adminProductNumbersSchema.safeParse({
|
||||
intensityMild: str(formData, "intensityMild"),
|
||||
@@ -49,7 +57,6 @@ export async function createProductAction(formData: FormData): Promise<void> {
|
||||
const isActive = formData.get("isActive") === "on";
|
||||
await assertPricedIfActive("/admin/produkte/neu", isActive, numbers.priceCents);
|
||||
|
||||
const category = (str(formData, "category") || "HONIG") as "HONIG" | "KERZEN" | "PROPOLIS";
|
||||
// Nur Honig ist einer Ernte/Charge zugeordnet — Kerzen, Propolis & Co. sind
|
||||
// davon unabhaengig. Eingaben aus dem Formular werden fuer diese Kategorien
|
||||
// ignoriert statt sich auf eine korrekt ausgefuellte Auswahl zu verlassen.
|
||||
|
||||
Reference in new issue
Block a user