gate locale behind functional consent

This commit is contained in:
2026-08-12 18:03:11 +02:00
parent 195d4169f5
commit 4bf50514bf
212 changed files with 173 additions and 840 deletions
-10
View File
@@ -1,10 +0,0 @@
/**
* Configures @payloadcms/plugin-form-builder from IPAL's FormsOption.
*
* Provides the form/form-submissions collections and field types. Email
* delivery is intentionally NOT handled here — the plugin's own SMTP-from-panel
* sender (submitForm) does that, so the form-builder's built-in email (which
* needs a Payload email adapter) is left unused.
*/ export { };
//# sourceMappingURL=formsPluginConfig.d.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["formsPluginConfig.d.ts"],"sourcesContent":["import type { Plugin } from 'payload';\nimport type { FormsOption } from './types.js';\n/**\n * Configures @payloadcms/plugin-form-builder from IPAL's FormsOption.\n *\n * Provides the form/form-submissions collections and field types. Email\n * delivery is intentionally NOT handled here — the plugin's own SMTP-from-panel\n * sender (submitForm) does that, so the form-builder's built-in email (which\n * needs a Payload email adapter) is left unused.\n */\nexport declare function buildFormsPlugin(forms: FormsOption): Plugin;\n"],"names":[],"mappings":"AAEA;;;;;;;CAOC,GACD,WAAqE"}
-6
View File
@@ -1,6 +0,0 @@
export { buildFormsPlugin } from './formsPluginConfig.js';
export { checkRateLimit } from './rateLimit.js';
export { submitForm } from './submitForm.js';
export { validateSubmission } from './validateSubmission.js';
//# sourceMappingURL=index.d.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["index.d.ts"],"sourcesContent":["export { buildFormsPlugin } from './formsPluginConfig.js';\nexport { checkRateLimit } from './rateLimit.js';\nexport type { RateLimitArgs } from './rateLimit.js';\nexport { submitForm } from './submitForm.js';\nexport type { SubmitFormArgs, SubmitFormResult } from './submitForm.js';\nexport type { FormsCollectionOverrides, FormsFieldsOverride, FormsOption } from './types.js';\nexport { validateSubmission } from './validateSubmission.js';\nexport type { FormValidationResult } from './validateSubmission.js';\n"],"names":["buildFormsPlugin","checkRateLimit","submitForm","validateSubmission"],"mappings":"AAAA,SAASA,gBAAgB,QAAQ,yBAAyB;AAC1D,SAASC,cAAc,QAAQ,iBAAiB;AAEhD,SAASC,UAAU,QAAQ,kBAAkB;AAG7C,SAASC,kBAAkB,QAAQ,0BAA0B"}
-7
View File
@@ -1,7 +0,0 @@
/**
* Returns true when the request is within the limit, false when it should be
* rejected. A missing key (no IP) is allowed through — better to accept a
* submission than to block everyone behind a proxy that strips the header.
*/ export { };
//# sourceMappingURL=rateLimit.d.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["rateLimit.d.ts"],"sourcesContent":["export type RateLimitArgs = {\n /** Identifier to limit on — typically the client IP. */\n key: string;\n /** Max submissions allowed per window. Defaults to 5. */\n max?: number;\n /** Window length in ms. Defaults to 60_000 (one minute). */\n windowMs?: number;\n};\n/**\n * Returns true when the request is within the limit, false when it should be\n * rejected. A missing key (no IP) is allowed through — better to accept a\n * submission than to block everyone behind a proxy that strips the header.\n */\nexport declare function checkRateLimit({ key, max, windowMs }: RateLimitArgs): boolean;\n"],"names":[],"mappings":"AAQA;;;;CAIC,GACD,WAAuF"}
-3
View File
@@ -1,3 +0,0 @@
import 'server-only';
//# sourceMappingURL=submitForm.d.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["submitForm.d.ts"],"sourcesContent":["import 'server-only';\nimport type { BasePayload } from 'payload';\nexport type SubmitFormArgs = {\n /** Submitted field data — shape matches the form's fields. */\n data: Record<string, unknown>;\n /** Form-builder form ID this submission belongs to. */\n formId: string;\n /** Client IP — used for Turnstile and rate limiting. */\n ip?: string;\n /**\n * Rate limit: max submissions per IP per minute. Defaults to 5.\n * Set to 0 to disable (e.g. when a real limiter sits in front).\n */\n maxPerMinute?: number;\n payload: BasePayload;\n /** Turnstile token; when present it is verified, when absent it is skipped. */\n turnstileToken?: string;\n};\n/**\n * Why a submission failed — a code, never a user-facing string.\n *\n * The plugin knows what went wrong; it deliberately doesn't decide how to say\n * it. The frontend maps these to its own copy, in its own language, and renders\n * whatever component fits — a field error, a toast, a full message. The plugin\n * has no business choosing the wording or the locale.\n *\n * - `rate_limited` — too many submissions from this IP\n * - `turnstile` — bot check failed\n * - `validation` — a field is missing/too long, or unknown keys were sent;\n * `field` and `kind` narrow it down when a specific field is\n * at fault (absent for whole-payload problems like unknown keys)\n * - `not_found` — no form with this id\n * - `error` — persistence failed unexpectedly\n */\nexport type SubmitFailure = {\n /** The offending field's name, when one field is at fault. */\n field?: string;\n /** What was wrong with it. */\n kind?: 'required' | 'too_long' | 'unknown_fields';\n reason: 'validation';\n success: false;\n} | {\n reason: 'error';\n success: false;\n} | {\n reason: 'not_found';\n success: false;\n} | {\n reason: 'rate_limited';\n success: false;\n} | {\n reason: 'turnstile';\n success: false;\n};\nexport type SubmitFormResult = {\n submissionId: number | string;\n success: true;\n} | SubmitFailure;\n/**\n * Handles a form submission end to end: rate limit, verify Turnstile, validate\n * against the form's own schema, then store.\n *\n * The order is cost-ascending on purpose — the cheapest checks reject first, so\n * a flood never reaches Turnstile's network call or the database.\n *\n * Emails aren't sent here. The form-builder sends whatever an editor configured\n * under the form's \"Emails\" tab (form-submissions hook → payload.sendEmail),\n * which goes out over panelSmtpAdapter. Storing the submission is enough.\n *\n * server-only: touches the Turnstile secret.\n */\nexport declare function submitForm({ data, formId, ip, maxPerMinute, payload, turnstileToken, }: SubmitFormArgs): Promise<SubmitFormResult>;\n"],"names":[],"mappings":"AAAA,OAAO,cAAc"}
-6
View File
@@ -1,6 +0,0 @@
/**
* Forms configuration — mirrors the fields a client enables in the
* form-builder plugin. Kept minimal; the plugin passes these through.
*/ export { };
//# sourceMappingURL=types.d.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["types.d.ts"],"sourcesContent":["import type { CollectionConfig, Field } from 'payload';\n/**\n * Receives the collection's default fields and returns the final list — add,\n * remove, or reorder. Same shape the form-builder uses.\n */\nexport type FormsFieldsOverride = (args: {\n defaultFields: Field[];\n}) => Field[];\n/**\n * Overrides for a forms-related collection: replace the fields and/or any\n * other collection setting (admin, access, hooks…).\n */\nexport type FormsCollectionOverrides = {\n fields?: FormsFieldsOverride;\n} & Partial<Omit<CollectionConfig, 'fields'>>;\n/**\n * Forms configuration — mirrors the fields a client enables in the\n * form-builder plugin. Kept minimal; the plugin passes these through.\n */\nexport type FormsOption = {\n /** Field types available in the form builder. Sensible defaults applied. */\n fields?: {\n checkbox?: boolean;\n email?: boolean;\n message?: boolean;\n number?: boolean;\n payment?: boolean;\n select?: boolean;\n text?: boolean;\n textarea?: boolean;\n };\n /**\n * Override the forms collection. The plugin stays opinion-free about what a\n * form needs beyond its fields — a client that wants, say, a per-form\n * notification address adds it here:\n *\n * formOverrides: {\n * fields: ({ defaultFields }) => [\n * ...defaultFields,\n * { name: 'notificationEmail', type: 'email' },\n * ],\n * }\n */\n formOverrides?: FormsCollectionOverrides;\n /** Override the form-submissions collection (same shape). */\n formSubmissionOverrides?: FormsCollectionOverrides;\n /** Collections a form can redirect to (e.g. ['pages']). */\n redirectRelationships?: string[];\n};\n"],"names":[],"mappings":"AAeA;;;CAGC,GACD,WA6BE"}
-3
View File
@@ -1,3 +0,0 @@
export { };
//# sourceMappingURL=validateSubmission.d.js.map
-1
View File
@@ -1 +0,0 @@
{"version":3,"sources":["validateSubmission.d.ts"],"sourcesContent":["import type { BasePayload } from 'payload';\n/** A form-builder field, trimmed to what validation needs. */\ntype FormField = {\n blockType?: string;\n label?: string;\n name?: string;\n required?: boolean | null;\n};\ntype FormDoc = {\n fields?: FormField[];\n id: number | string;\n /** Per-form notification address, when the client added the field. */\n notificationEmail?: string;\n title?: string;\n};\n/**\n * Validation outcome — codes, not user-facing strings. The frontend turns these\n * into its own copy (see SubmitFailure in submitForm).\n */\nexport type FormValidationResult = {\n /** Offending field, when a single field is at fault. */\n field?: string;\n kind: 'required' | 'too_long' | 'unknown_fields';\n ok: false;\n reason: 'invalid';\n} | {\n cleaned: Record<string, unknown>;\n form: FormDoc;\n ok: true;\n} | {\n ok: false;\n reason: 'not_found';\n};\n/**\n * Checks submitted data against the form's own definition, rather than trusting\n * whatever arrived.\n *\n * The server action is a public endpoint: a caller can skip the rendered form\n * and post arbitrary keys. Without this, unknown fields would be stored,\n * required fields could be missing, and an oversized value could sail through.\n * So we load the form, keep only keys that are real fields, reject when a\n * required one is blank, and cap length.\n *\n * Returns the loaded form on success so the caller doesn't fetch it twice, and\n * a code + offending field on failure so the frontend can point at it.\n */\nexport declare function validateSubmission(payload: BasePayload, formId: string, data: Record<string, unknown>): Promise<FormValidationResult>;\nexport {};\n"],"names":[],"mappings":"AA+CA,WAAU"}