added validation for forms, sensitive text fields have been masked

This commit is contained in:
2026-08-21 17:15:02 +02:00
parent 5aa66ff37a
commit 2215766940
19 changed files with 325 additions and 4 deletions
+12 -1
View File
@@ -1,6 +1,11 @@
import 'server-only';
import type { BasePayload } from 'payload';
export type SubmitFormArgs = {
/**
* Name of the GDPR consent checkbox. A field with this name must be checked
* for the submission to succeed (enforced server-side). Defaults to 'consent'.
*/
consentFieldName?: string;
/** Submitted field data — shape matches the form's fields. */
data: Record<string, unknown>;
/** Form-builder form ID this submission belongs to. */
@@ -30,6 +35,7 @@ export type SubmitFormArgs = {
* `field` and `kind` narrow it down when a specific field is
* at fault (absent for whole-payload problems like unknown keys)
* - `not_found` — no form with this id
* - `consent` — a required GDPR consent checkbox was left unchecked
* - `error` — persistence failed unexpectedly
*/
export type SubmitFailure = {
@@ -39,6 +45,11 @@ export type SubmitFailure = {
kind?: 'required' | 'too_long' | 'unknown_fields';
reason: 'validation';
success: false;
} | {
field?: string;
/** A GDPR consent field existed on the form but wasn't checked. */
reason: 'consent';
success: false;
} | {
reason: 'error';
success: false;
@@ -69,4 +80,4 @@ export type SubmitFormResult = {
*
* server-only: touches the Turnstile secret.
*/
export declare function submitForm({ data, formId, ip, maxPerMinute, payload, turnstileToken, }: SubmitFormArgs): Promise<SubmitFormResult>;
export declare function submitForm({ consentFieldName, data, formId, ip, maxPerMinute, payload, turnstileToken, }: SubmitFormArgs): Promise<SubmitFormResult>;
+6
View File
@@ -18,6 +18,12 @@ export type FormsCollectionOverrides = {
* form-builder plugin. Kept minimal; the plugin passes these through.
*/
export type FormsOption = {
/**
* Name of the checkbox field treated as a GDPR consent gate. A form field
* with this name must be checked for submission to succeed — enforced
* server-side in submitForm. Defaults to 'consent'.
*/
consentFieldName?: string;
/** Field types available in the form builder. Sensible defaults applied. */
fields?: {
checkbox?: boolean;
+5 -1
View File
@@ -27,6 +27,10 @@ export type FormValidationResult = {
cleaned: Record<string, unknown>;
form: FormDoc;
ok: true;
} | {
field: string;
ok: false;
reason: 'consent';
} | {
ok: false;
reason: 'not_found';
@@ -44,5 +48,5 @@ export type FormValidationResult = {
* Returns the loaded form on success so the caller doesn't fetch it twice, and
* a code + offending field on failure so the frontend can point at it.
*/
export declare function validateSubmission(payload: BasePayload, formId: string, data: Record<string, unknown>): Promise<FormValidationResult>;
export declare function validateSubmission(payload: BasePayload, formId: string, data: Record<string, unknown>, consentFieldName?: string): Promise<FormValidationResult>;
export {};