feat: server-side JS field validators for extended inputs (#158) - #163
feat: server-side JS field validators for extended inputs (#158)#163romain-pm wants to merge 2 commits into
Conversation
Re-enforces field constraints on form submission, in JavaScript, so a client bypassing browser validation cannot store out-of-range values. formidable-engine: - depends on the javascript-modules SDK (JSServerExtensionInvoker), imported from the javascript-modules-engine bundle (feature/js-server-extensions-sdk) - new validateFieldsWithJs pipeline step (after validateRequired): loads each submitted field's node (system session) and runs JS validators registered for its type; a violation rejects the submission with FMDB-010. Fails closed on validator error; skipped entirely when the SDK service is absent - FormFieldMetadataCollector now carries field node identifiers - JsFieldValidator bridges the pipeline to the SDK invoker formidable-extended-inputs: - registerFormFieldValidator(props, fn) JS API (server.registry.add) - validators for rating (1..max int), scale (min..max by step), switch (true/false), consent (true, required-aware) Verified end-to-end on Jahia 8.2.x: valid values (incl. edges) accepted; forged rating/scale/switch/consent values rejected with FMDB-010; 149 engine tests green.
📝 Documentation GuidelinesThank you for contributing to our documentation! To ensure your contributions meet our standards, please review these resources:
This comment is posted automatically when changes are detected in the |
…t values New security spec (42-extended-inputs-server-validation.cy.ts) POSTs directly to the submit servlet, bypassing the browser, and asserts: - valid submissions (incl. boundary values) are accepted - forged rating/scale/switch/consent values are rejected with FMDB-010, including an in-bounds but off-step scale value Adds fmdbext node factories (extendedInputs fixtures) and installs formidable-extended-inputs in the CI provisioning manifest. 19/19 passing against a local Jahia 8.2.x.
|
Heads-up: the base branch of this PR ( A few things to know for that rebase — #172 also addressed the server-side validation gap, but at a different level:
Also note #172 shipped a few fixes on the fields your validators target (switch buttons mode no longer prechecks "No", rating DOM order) — none of them change the submitted value contract, so your validator logic should rebase cleanly. |
|
Branch housekeeping: this draft is more than a hundred commits behind main since July. Do you plan to pick it up (a rebase would be the first step), or can we close it and keep the work reachable from the closed PR? No action from me until you say. |
What
Completes the server-side validation gap left open in #158: the extended field types now re-enforce their constraints on submission, in JavaScript, so a client that bypasses the browser cannot store out-of-range values.
Stacked on #162 (base branch
feat/extended-inputs-module) — review/merge that first. The diff here is only the validation layer.Cross-repo dependency⚠️
Depends on a new javascript-modules SDK: Jahia/javascript-modules#686 (branch
feature/js-server-extensions-sdk, stacked onfeature/js-server-extensions). That branch exports a small, polyglot-free SDK (JSServerExtensionInvoker) so a third-party bundle can consume JS-declared server extensions and invoke their callbacks. That must be released before this can build/run against a stock engine.How it works
JSServerExtensionInvoker.forEach(type, handler)runs within one pooled GraalVM context;Invoker.call(callable, args…)executes a JS function and converts the result to plain Java. No GraalVM/engine-internal types leak, soformidable-engineneeds no polyglot dependency.validateFieldsWithJspipeline step (aftervalidateRequired) loads each submitted field's node with a system session and runs the JS validators registered for its node type; a violation rejects the submission with FMDB-010. Fails closed on validator error; skipped entirely (graceful) if the SDK service is absent.FormFieldMetadataCollectornow carries field node identifiers;JsFieldValidatoris the bridge.registerFormFieldValidator({ nodeType }, (node, value, locale) => …)(thin wrapper overserver.registry.add), plus validators for rating (1..max integer), scale (min..max by step), switch (true/false), consent (true, required-aware).Verification
Built, deployed (SDK engine + formidable) and driven end-to-end on a local Jahia 8.2.x by POSTing directly to
/modules/formidable-engine/form-submit, bypassing the browser:999,abc,0,3.599,abcmaybeyes11,-1149
formidable-engineunit tests pass, and 19 new Cypress e2e specs (see below) pass against a local instance.Notes / follow-ups
formidable-extended-inputspure-JS/CND with no per-field Java.npsview but configured with custom bounds would validate against those bounds (documented edge case).security/42-extended-inputs-server-validation.cy.ts, 19 tests: valid + boundary accepted, forged rating/scale/switch/consent — incl. an off-step scale value — rejected with FMDB-010);formidable-extended-inputsadded to the CI provisioning manifest. Messages are literal English (surfaced only as the opaque FMDB-010 code to visitors);{bundle.key}i18n could be wired if we want localized validator messages in logs.