From 75467ca55a01cc9214cecff3fef0b636d20a04e9 Mon Sep 17 00:00:00 2001 From: rdbsolutions Date: Wed, 16 Apr 2025 14:44:04 +0100 Subject: [PATCH 1/3] remove eval funciton in form for CSP fix --- components/elements/index.js | 144 ++++++++++++++++++++++--- components/elements/validationUtils.js | 71 ++++++++++++ 2 files changed, 201 insertions(+), 14 deletions(-) create mode 100644 components/elements/validationUtils.js diff --git a/components/elements/index.js b/components/elements/index.js index 8a4d84bf..a11ea73b 100644 --- a/components/elements/index.js +++ b/components/elements/index.js @@ -37,6 +37,7 @@ const ReactQuill = dynamic(() => import("react-quill-new"), { ssr: false }); import { useStore as store, useSelector } from "react-redux"; import { useDispatch } from "react-redux"; +import { validateField } from "./validationUtils"; // Import the validation function const RenderTextfield = ({ id, @@ -223,7 +224,9 @@ export function Textfield(props) { // console.log(parentField, formProps, form); //console.log("validation props:", validation); - + const requiredMessage = t("account:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return (
{parentField != false ? ( @@ -234,7 +237,15 @@ export function Textfield(props) { component={RenderTextfield} type="text" className="govuk-input govuk-input--width-20" - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function label={props.label} maxFieldLength={props.maxFieldLength} /> @@ -246,7 +257,15 @@ export function Textfield(props) { component={RenderTextfield} type="text" className="govuk-input govuk-input--width-20" - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function label={props.label} errorMsg={t("newappeal:is-required-label")} maxFieldLength={props.maxFieldLength} @@ -356,6 +375,9 @@ export function MultiLinefield(props) { //console.log(showIfHasParentShowValue, formProps[form].values[parentField]); let { t } = useTranslation(); + const requiredMessage = t("newappeal:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return ( <> {parentField != false ? ( @@ -383,7 +405,15 @@ export function MultiLinefield(props) { rows="5" className="govuk-textarea govuk-input--width-30" aria-describedby={props.name + "-hint"} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function maxFieldLength={props.maxFieldLength} />
@@ -412,7 +442,15 @@ export function MultiLinefield(props) { rows="5" className="govuk-textarea govuk-input--width-30" aria-describedby={props.name + "-hint"} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function maxFieldLength={props.maxFieldLength} /> @@ -517,6 +555,9 @@ export function RichMultiLinefield(props) { //console.log(showIfHasParentShowValue, formProps[form].values[parentField]); let { t } = useTranslation(); + const requiredMessage = t("newappeal:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return ( <> {parentField != false ? ( @@ -543,7 +584,15 @@ export function RichMultiLinefield(props) { rows="5" className="govuk-textarea govuk-input--width-30" aria-describedby={props.name + "-hint"} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function maxFieldLength={props.maxFieldLength} /> @@ -572,7 +621,15 @@ export function RichMultiLinefield(props) { rows="5" className="govuk-textarea govuk-input--width-30" aria-describedby={props.name + "-hint"} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function maxFieldLength={props.maxFieldLength} /> @@ -738,6 +795,9 @@ export function DateFieldPicker(props) { _.has(formProps[form].values, parentField) && formProps[form].values[parentField]) == parentFieldShowOnValue; + const requiredMessage = t("newappeal:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return (
{parentField != false ? ( @@ -747,7 +807,15 @@ export function DateFieldPicker(props) { id={name} label={label} component={RenderDatePicker} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function errorMsg={t("newappeal:select-a-date-label")} dateStart={dateStart} dateEnd={dateEnd} @@ -760,7 +828,15 @@ export function DateFieldPicker(props) { id={name} label={label} component={RenderDatePicker} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function errorMsg={t("newappeal:select-a-date-label")} dateStart={dateStart} dateEnd={dateEnd} @@ -1187,6 +1263,9 @@ export function Radiofield(props) { (showIfHasParentShowValue == parentField) != false && showIfHasParentShowValue; + const requiredMessage = t("newappeal:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return ( <> {parentField != false ? ( @@ -1202,7 +1281,15 @@ export function Radiofield(props) { component={RenderRadio} inline={props.inline} hint={props.hint} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function requiredDocumentLabel={props.requiredDocumentLabel} requiredDocumentValue={props.requiredDocumentValue} setDocumentsList={props.setDocumentsList} @@ -1221,7 +1308,15 @@ export function Radiofield(props) { component={RenderRadio} inline={props.inline} hint={props.hint} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function requiredDocumentLabel={props.requiredDocumentLabel} requiredDocumentValue={props.requiredDocumentValue} setDocumentsList={props.setDocumentsList} @@ -1458,7 +1553,9 @@ export function NumericField(props) { showIfHasParentShowValue; //console.log("parentField:", parentField, showIfHasParentShowValue); - + const requiredMessage = t("newappeal:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return ( <> {parentField != false ? ( @@ -1474,7 +1571,15 @@ export function NumericField(props) { pattern="[0-9]*" inputMode="numeric" parse={Number} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function component={RenderTextfield} label={label} maxFieldLength={props.maxFieldLength} @@ -1586,6 +1691,9 @@ export function DecimalField(props) { return undefined; }; + const requiredMessage = t("newappeal:is-required-label"); + const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); + const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return ( <> {parentField != false ? ( @@ -1602,7 +1710,15 @@ export function DecimalField(props) { pattern="[0-9]*" inputMode="numeric" parse={Number} - validate={eval(validation)} + validate={(value) => + validateField( + value, + validation, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ) + } // Use the external validate function component={RenderTextfield} label={props.label} maxFieldLength={props.maxFieldLength} diff --git a/components/elements/validationUtils.js b/components/elements/validationUtils.js new file mode 100644 index 00000000..ea0d60b9 --- /dev/null +++ b/components/elements/validationUtils.js @@ -0,0 +1,71 @@ +// validationUtils.js + +// Validation functions +const required = (value, requiredMessage, emojiNotAllowedMessage) => { + let errors; + if (!value) { + errors = requiredMessage; + } else { + const emojiRegex = + /[\u{1F600}-\u{1F64F}\u{1F300}-\u{1F5FF}\u{1F680}-\u{1F6FF}\u{1F700}-\u{1F77F}\u{1F780}-\u{1F7FF}\u{1F800}-\u{1F8FF}\u{1F900}-\u{1F9FF}\u{1FA00}-\u{1FA6F}\u{1FA70}-\u{1FAFF}\u{2600}-\u{26FF}\u{2700}-\u{27BF}\u{2300}-\u{23FF}\u{2B50}\u{1F004}-\u{1F0CF}\u{1F0A0}-\u{1F0A5}\u{1F170}-\u{1F251}]/gu; + + if (emojiRegex.test(value)) { + errors = emojiNotAllowedMessage; + } + } + return errors; +}; + +const postcode = (value, invalidPostcodeMessage) => + value && + !/^([A-Z][A-HJ-Y]?[0-9][A-Z0-9]? ?[0-9][A-Z]{2}|GIR ?0A{2})$/i.test(value) + ? "Invalid postcode" + : undefined; + +// Function to parse the validation string +export const parseValidationString = (validationString) => { + if (typeof validationString !== "string") { + return []; // Return an empty array if it's not a string + } + + // Remove square brackets and split by commas + return validationString + .replace(/[\[\]']+/g, "") // Remove square brackets + .split(",") // Split by commas + .map((rule) => rule.trim()); // Trim each validation rule +}; + +// Function to handle multiple validation rules +export const validateField = ( + value, + validationString, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage +) => { + const validations = parseValidationString(validationString); // Parse the validation string + let errors; + + console.log(typeof validations, validations); + for (let validationRule of validations) { + const validationFunc = validationFunctions[validationRule]; + if (validationFunc) { + errors = validationFunc( + value, + requiredMessage, + emojiNotAllowedMessage, + invalidPostcodeMessage + ); + } + if (errors) break; // Exit if any validation fails + } + + return errors; +}; + +// Map validation strings to actual validation functions +export const validationFunctions = { + required, + postcode, + // Add other validation functions as needed +}; From 35f19bd975efc0d2a40e12c6904fac1e0878c88b Mon Sep 17 00:00:00 2001 From: rdbsolutions Date: Wed, 16 Apr 2025 14:48:15 +0100 Subject: [PATCH 2/3] removed comments --- components/elements/validationUtils.js | 2 -- components/myportal/uploadFile.js | 2 +- components/newappeal/buildsection.js | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/components/elements/validationUtils.js b/components/elements/validationUtils.js index ea0d60b9..43f9dbef 100644 --- a/components/elements/validationUtils.js +++ b/components/elements/validationUtils.js @@ -45,8 +45,6 @@ export const validateField = ( ) => { const validations = parseValidationString(validationString); // Parse the validation string let errors; - - console.log(typeof validations, validations); for (let validationRule of validations) { const validationFunc = validationFunctions[validationRule]; if (validationFunc) { diff --git a/components/myportal/uploadFile.js b/components/myportal/uploadFile.js index 015a303d..492c8b84 100644 --- a/components/myportal/uploadFile.js +++ b/components/myportal/uploadFile.js @@ -290,7 +290,7 @@ let UploadFile = (props) => { const uploadAction = await uploadFiles(dataObj, fileObj).then( (data) => { - console.log("hello", data); + console.log("$1", data); } ); // router.push({ diff --git a/components/newappeal/buildsection.js b/components/newappeal/buildsection.js index 2cf10ef7..7d57af76 100644 --- a/components/newappeal/buildsection.js +++ b/components/newappeal/buildsection.js @@ -125,7 +125,7 @@ let BuildSection = (props) => { props.props.accountDetails.containerID, props.props.appealType.caseReference.ticketnumber ).then((data) => { - console.log("hello", data); + console.log("$1", data); setCompletedUploadFiles(true); return data; }); From cf0c05ff6ac414faaf363874858c468a02cb15bc Mon Sep 17 00:00:00 2001 From: rdbsolutions Date: Wed, 16 Apr 2025 14:55:06 +0100 Subject: [PATCH 3/3] removed comments --- .../representation/representationAgent.js | 4 ++-- .../representation/representationAppellant.js | 4 ++-- .../representationInterestedPartyPerson.js | 4 ++-- .../case/representation/representationLPA.js | 24 +++++++++---------- components/elements/index.js | 2 +- components/newappeal/buildsection.js | 10 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/components/case/representation/representationAgent.js b/components/case/representation/representationAgent.js index c5c39db2..6e13b87e 100644 --- a/components/case/representation/representationAgent.js +++ b/components/case/representation/representationAgent.js @@ -287,13 +287,13 @@ const RepAgent = (props) => { props.props.props.form[props.form] .values || {}; - console.log("valuesobj:", valuesObj); + //console.log("valuesobj:", valuesObj); delete valuesObj[ "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateRepresentation( valuesObj, false, diff --git a/components/case/representation/representationAppellant.js b/components/case/representation/representationAppellant.js index 64ccd627..5dc66794 100644 --- a/components/case/representation/representationAppellant.js +++ b/components/case/representation/representationAppellant.js @@ -275,13 +275,13 @@ const RepAppellant = (props) => { props.props.props.form[props.form] .values || {}; - console.log("valuesobj:", valuesObj); + //console.log("valuesobj:", valuesObj); delete valuesObj[ "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateRepresentation( valuesObj, false, diff --git a/components/case/representation/representationInterestedPartyPerson.js b/components/case/representation/representationInterestedPartyPerson.js index 6967c61d..11c3cca6 100644 --- a/components/case/representation/representationInterestedPartyPerson.js +++ b/components/case/representation/representationInterestedPartyPerson.js @@ -283,13 +283,13 @@ const RepInterestedPartyPerson = (props) => { props.props.props.form[props.form] .values || {}; - console.log("valuesobj:", valuesObj); + //console.log("valuesobj:", valuesObj); delete valuesObj[ "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateRepresentation( valuesObj, false, diff --git a/components/case/representation/representationLPA.js b/components/case/representation/representationLPA.js index 19eb3b5b..9818fe09 100644 --- a/components/case/representation/representationLPA.js +++ b/components/case/representation/representationLPA.js @@ -480,16 +480,16 @@ let RepLPA = (props) => { props.form ].values || {}; - console.log( - "valuesobj:", - valuesObj - ); + // console.log( + // "valuesobj:", + // valuesObj + // ); delete valuesObj[ "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateRepresentation( valuesObj, false, @@ -515,13 +515,13 @@ let RepLPA = (props) => { props.props.props.form[props.form] .values || {}; - console.log("valuesobj:", valuesObj); + //console.log("valuesobj:", valuesObj); delete valuesObj[ "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateRepresentation( valuesObj, false, @@ -571,16 +571,16 @@ let RepLPA = (props) => { props.form ].values || {}; - console.log( - "valuesobj:", - valuesObj - ); + // console.log( + // "valuesobj:", + // valuesObj + // ); delete valuesObj[ "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateRepresentation( valuesObj, false, diff --git a/components/elements/index.js b/components/elements/index.js index a11ea73b..931edf43 100644 --- a/components/elements/index.js +++ b/components/elements/index.js @@ -224,7 +224,7 @@ export function Textfield(props) { // console.log(parentField, formProps, form); //console.log("validation props:", validation); - const requiredMessage = t("account:is-required-label"); + const requiredMessage = t("newappeal:is-required-label"); const emojiNotAllowedMessage = t("newappeal:emojis-not-allowed-label"); const invalidPostcodeMessage = t("newappeal:invalid-postcode-label"); return ( diff --git a/components/newappeal/buildsection.js b/components/newappeal/buildsection.js index 7d57af76..712bff39 100644 --- a/components/newappeal/buildsection.js +++ b/components/newappeal/buildsection.js @@ -488,7 +488,7 @@ let BuildSection = (props) => { "_pinswg_appellant_value" ]; - console.log("on save:", valuesObj); + //console.log("on save:", valuesObj); updateCaseProgress( valuesObj, false, @@ -593,10 +593,10 @@ let BuildSection = (props) => { props.props.form[props.form] .values || {}; - console.log( - "valuesobj:", - valuesObj - ); + // console.log( + // "valuesobj:", + // valuesObj + // ); delete valuesObj[ "_pinswg_appellant_value"