97 lines
3.9 KiB
TypeScript
97 lines
3.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { parseAdminSettingsForm, redactSettingsAuditDetails } from "./adminSettingsValidation.server";
|
|
|
|
const sensitiveHeadScript = `<script>window.token="secret-token";fetch("https://tracker.example/pixel?apiKey=raw-key")</script>`;
|
|
|
|
function createForm(values: Record<string, string | boolean | undefined>) {
|
|
const form = new FormData();
|
|
Object.entries(values).forEach(([key, value]) => {
|
|
if (value !== undefined) {
|
|
form.set(key, typeof value === "boolean" ? String(value) : value);
|
|
}
|
|
});
|
|
return form;
|
|
}
|
|
|
|
describe("adminSettingsValidation.server", () => {
|
|
it("normalizes valid general settings and rejects missing required names", () => {
|
|
const valid = parseAdminSettingsForm(
|
|
"general",
|
|
createForm({ action: "update", name: " Acme Portal ", theme: "zinc", headScripts: sensitiveHeadScript, bodyScripts: "" })
|
|
);
|
|
|
|
expect(valid).toMatchObject({ ok: true, section: "general" });
|
|
expect(valid.ok && valid.data).toMatchObject({ name: "Acme Portal", theme: "zinc", headScripts: sensitiveHeadScript, bodyScripts: "" });
|
|
|
|
const invalid = parseAdminSettingsForm("general", createForm({ action: "update", name: " " }));
|
|
|
|
expect(invalid).toEqual({ ok: false, status: 400, errors: { name: ["This field is required."] } });
|
|
});
|
|
|
|
it("normalizes authentication booleans", () => {
|
|
const result = parseAdminSettingsForm(
|
|
"authentication",
|
|
createForm({ action: "update", requireEmailVerification: "on", requireOrganization: "true" })
|
|
);
|
|
|
|
expect(result).toMatchObject({
|
|
ok: true,
|
|
section: "authentication",
|
|
data: {
|
|
authRequireEmailVerification: true,
|
|
authRequireOrganization: true,
|
|
authRequireName: false,
|
|
},
|
|
});
|
|
});
|
|
|
|
it("normalizes analytics settings (EU-sterilisiert, ohne Google Analytics)", () => {
|
|
const valid = parseAdminSettingsForm("analytics", createForm({ action: "update", enabled: "true", simpleAnalytics: "on" }));
|
|
|
|
expect(valid).toMatchObject({
|
|
ok: true,
|
|
section: "analytics",
|
|
data: {
|
|
analyticsEnabled: true,
|
|
analyticsSimpleAnalytics: true,
|
|
analyticsPlausibleAnalytics: false,
|
|
},
|
|
});
|
|
|
|
// EU-Sterilisation (R-P1a): ein mitgesendetes googleAnalyticsTrackingId wird ignoriert, nicht persistiert.
|
|
const ignored = parseAdminSettingsForm("analytics", createForm({ action: "update", googleAnalyticsTrackingId: "G-ABC12345" }));
|
|
expect(ignored.ok).toBe(true);
|
|
expect(JSON.stringify(ignored)).not.toContain("G-ABC12345");
|
|
});
|
|
|
|
it("normalizes cookie settings and rejects malformed actions or booleans", () => {
|
|
const valid = parseAdminSettingsForm("cookies", createForm({ action: "update", enabled: "true" }));
|
|
|
|
expect(valid).toEqual({ ok: true, section: "cookies", data: { cookiesEnabled: true } });
|
|
|
|
const invalid = parseAdminSettingsForm("cookies", createForm({ action: "delete", enabled: "true" }));
|
|
|
|
expect(invalid).toEqual({ ok: false, status: 400, errors: { action: ["Invalid action."] } });
|
|
|
|
const tampered = parseAdminSettingsForm("cookies", createForm({ action: "update", enabled: "definitely" }));
|
|
|
|
expect(tampered).toEqual({ ok: false, status: 400, errors: { enabled: ["Boolean value is invalid."] } });
|
|
});
|
|
|
|
it("redacts scripts, tokens and query strings from audit details", () => {
|
|
const audit = redactSettingsAuditDetails("general", {
|
|
headScripts: sensitiveHeadScript,
|
|
bodyScripts: `<script src="https://cdn.example/app.js?token=raw-token"></script>`,
|
|
brandingLogo: "https://assets.example/logo.png?token=raw-token",
|
|
cookiesEnabled: true,
|
|
});
|
|
|
|
expect(audit).toContain("headScripts");
|
|
expect(audit).toContain("cookiesEnabled");
|
|
expect(audit).toContain("true");
|
|
expect(audit).not.toContain(sensitiveHeadScript);
|
|
expect(audit).not.toContain("raw-token");
|
|
expect(audit).not.toContain("?token=");
|
|
});
|
|
});
|