security headers, notifications, GDPR consent, masked fields
This commit is contained in:
+22
-2
@@ -12,6 +12,14 @@
|
||||
'g-recaptcha-response'
|
||||
]);
|
||||
/** Hard ceiling on a single field's length, independent of the form config. */ const MAX_FIELD_LENGTH = 5000;
|
||||
/**
|
||||
* Default name for a GDPR consent field. A checkbox with this name is treated
|
||||
* as a consent gate: it MUST be checked for the submission to go through,
|
||||
* enforced here server-side regardless of how the field was configured in the
|
||||
* panel (so an editor can't weaken it by forgetting `required` or, worse,
|
||||
* pre-ticking it with defaultValue: true — which GDPR forbids). Configurable
|
||||
* via FormsOption.consentFieldName.
|
||||
*/ const DEFAULT_CONSENT_FIELD = 'consent';
|
||||
/**
|
||||
* Checks submitted data against the form's own definition, rather than trusting
|
||||
* whatever arrived.
|
||||
@@ -24,7 +32,7 @@
|
||||
*
|
||||
* 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 async function validateSubmission(payload, formId, data) {
|
||||
*/ export async function validateSubmission(payload, formId, data, consentFieldName = DEFAULT_CONSENT_FIELD) {
|
||||
let form;
|
||||
try {
|
||||
form = await payload.findByID({
|
||||
@@ -47,7 +55,19 @@
|
||||
for (const field of fields){
|
||||
const value = data[field.name];
|
||||
const isBlank = value == null || typeof value === 'string' && value.trim() === '' || value === false;
|
||||
if (field.required && isBlank) {
|
||||
// GDPR consent gate: a field matching the consent name must be truthy
|
||||
// (checked). Enforced independently of `required`, so it can't be weakened
|
||||
// in the panel. This is the one field where server-side enforcement is the
|
||||
// legal guarantee — the frontend can't bypass it, the editor can't misset it.
|
||||
if (field.name === consentFieldName) {
|
||||
if (value !== true) {
|
||||
return {
|
||||
field: field.name,
|
||||
ok: false,
|
||||
reason: 'consent'
|
||||
};
|
||||
}
|
||||
} else if (field.required && isBlank) {
|
||||
return {
|
||||
field: field.name,
|
||||
kind: 'required',
|
||||
|
||||
Reference in New Issue
Block a user