From 310a3f815bfa72959e021057119b8dc2a9f92c1a Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Wed, 2 Oct 2024 08:45:55 +0200 Subject: [PATCH 1/3] chore: updated volto-form-block to 3.9.3 --- package.json | 2 +- src/customizations/volto-form-block/components/View.jsx | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9d3db24d3..7ca07e424 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ "volto-dropdownmenu": "4.1.3", "volto-editablefooter": "5.1.7", "volto-feedback": "0.3.2", - "volto-form-block": "3.9.2", + "volto-form-block": "3.9.3", "volto-gdpr-privacy": "2.2.7", "volto-google-analytics": "2.0.0", "volto-multilingual-widget": "3.2.1", diff --git a/src/customizations/volto-form-block/components/View.jsx b/src/customizations/volto-form-block/components/View.jsx index 5f2e31354..7c3f4004f 100644 --- a/src/customizations/volto-form-block/components/View.jsx +++ b/src/customizations/volto-form-block/components/View.jsx @@ -5,7 +5,7 @@ import React, { useState, useEffect, useReducer, useRef } from 'react'; import { useSelector, useDispatch } from 'react-redux'; import PropTypes from 'prop-types'; import { useIntl, defineMessages } from 'react-intl'; -import { submitForm } from 'volto-form-block/actions'; +import { submitForm, resetOTP } from 'volto-form-block/actions'; import { getFieldName } from 'volto-form-block/components/utils'; import FormView from 'volto-form-block/components/FormView'; import { formatDate } from '@plone/volto/helpers/Utils/Date'; @@ -127,6 +127,7 @@ const View = ({ data, id, path }) => { const [formData, setFormData] = useReducer((state, action) => { if (action.reset) { + dispatch(resetOTP(id)); return getInitialData(data); } From 46c1662c5903bea28092c4ee80a9dbceca7e4db7 Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Wed, 2 Oct 2024 09:25:01 +0200 Subject: [PATCH 2/3] feat: switchable email otp validation per form --- .../volto-form-block/components/FormView.jsx | 84 ++++++++++--------- .../volto-form-block/components/View.jsx | 10 ++- .../volto-form-block/formSchema.js | 18 ++++ 3 files changed, 70 insertions(+), 42 deletions(-) diff --git a/src/customizations/volto-form-block/components/FormView.jsx b/src/customizations/volto-form-block/components/FormView.jsx index 0b2653092..ebaa641c3 100644 --- a/src/customizations/volto-form-block/components/FormView.jsx +++ b/src/customizations/volto-form-block/components/FormView.jsx @@ -209,47 +209,51 @@ const FormView = ({ })} {/*OTP*/} - {data.subblocks - .filter((subblock) => subblock.use_as_bcc) - .map((subblock, index) => { - const fieldName = getFieldName( - subblock.label, - subblock.id, - ); - const name = fieldName + OTP_FIELDNAME_EXTENDER; - const fieldValue = formData[fieldName]?.value; - const value = formData[fieldName]?.otp; - const fields_to_send_with_value = - getFieldsToSendWithValue(subblock); + {data.email_otp_verification ? ( + data.subblocks + .filter((subblock) => subblock.use_as_bcc) + .map((subblock, index) => { + const fieldName = getFieldName( + subblock.label, + subblock.id, + ); + const name = fieldName + OTP_FIELDNAME_EXTENDER; + const fieldValue = formData[fieldName]?.value; + const value = formData[fieldName]?.otp; + const fields_to_send_with_value = + getFieldsToSendWithValue(subblock); - return ( - - - { - onChangeFormData( - subblock.id, - fieldName, - fieldValue, - { - ...fields_to_send_with_value, - otp: value, - }, - ); - }} - value={value} - valid={isValidField(name)} - errorMessage={getErrorMessage(name)} - formHasErrors={formErrors?.length > 0} - path={path} - block_id={block_id} - /> - - - ); - })} + return ( + + + { + onChangeFormData( + subblock.id, + fieldName, + fieldValue, + { + ...fields_to_send_with_value, + otp: value, + }, + ); + }} + value={value} + valid={isValidField(name)} + errorMessage={getErrorMessage(name)} + formHasErrors={formErrors?.length > 0} + path={path} + block_id={block_id} + /> + + + ); + }) + ) : ( + <> + )} {enableCaptcha && <>{captcha.render()}} diff --git a/src/customizations/volto-form-block/components/View.jsx b/src/customizations/volto-form-block/components/View.jsx index 7c3f4004f..e48b80141 100644 --- a/src/customizations/volto-form-block/components/View.jsx +++ b/src/customizations/volto-form-block/components/View.jsx @@ -127,7 +127,9 @@ const View = ({ data, id, path }) => { const [formData, setFormData] = useReducer((state, action) => { if (action.reset) { - dispatch(resetOTP(id)); + if (data.email_otp_verification) { + dispatch(resetOTP(id)); + } return getInitialData(data); } @@ -210,7 +212,11 @@ const View = ({ data, id, path }) => { field: name, message: intl.formatMessage(messages.invalidEmailMessage), }); - } else if (isBCC && !formData[name].otp) { + } else if ( + data.email_otp_verification && + isBCC && + !formData[name].otp + ) { v.push({ field: name + OTP_FIELDNAME_EXTENDER, message: intl.formatMessage(messages.insertOtp), diff --git a/src/customizations/volto-form-block/formSchema.js b/src/customizations/volto-form-block/formSchema.js index a8c0363a5..be1ce9c20 100644 --- a/src/customizations/volto-form-block/formSchema.js +++ b/src/customizations/volto-form-block/formSchema.js @@ -102,6 +102,15 @@ const messages = defineMessages({ id: 'mail_footer_label', defaultMessage: 'Text at the end of the email', }, + email_otp_verification: { + id: 'form_email_otp_verification', + defaultMessage: 'Validate BCC emails with OTP verification', + }, + email_otp_verification_description: { + id: 'form_email_otp_verification_description', + defaultMessage: + "Prevent spam from your website. By enabling this option, you do not allow malicious users to send emails to other email addresses through your website. The OTP will be requested for all email-type fields for which the 'Send a copy of the email to this address' option is checked.", + }, }); const Schema = (data) => { @@ -130,6 +139,7 @@ const Schema = (data) => { ...(data?.show_cancel ? ['cancel_label'] : []), 'set_limit', ...(data?.set_limit ? ['limit'] : []), + 'email_otp_verification', 'mail_header', 'mail_footer', 'captcha', @@ -202,6 +212,14 @@ const Schema = (data) => { '@id': 'collective.volto.formsupport.captcha.providers', }, }, + email_otp_verification: { + type: 'boolean', + title: intl.formatMessage(messages.email_otp_verification), + description: intl.formatMessage( + messages.email_otp_verification_description, + ), + default: false, + }, store: { type: 'boolean', title: intl.formatMessage(messages.store), From 4f461351ccdeeab8ca2234950f068c17fa5eb0fd Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Wed, 2 Oct 2024 15:01:49 +0200 Subject: [PATCH 3/3] chore: updated volto-form-block --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 7ca07e424..106cecc3b 100644 --- a/package.json +++ b/package.json @@ -152,7 +152,7 @@ "volto-dropdownmenu": "4.1.3", "volto-editablefooter": "5.1.7", "volto-feedback": "0.3.2", - "volto-form-block": "3.9.3", + "volto-form-block": "3.10.0", "volto-gdpr-privacy": "2.2.7", "volto-google-analytics": "2.0.0", "volto-multilingual-widget": "3.2.1", diff --git a/yarn.lock b/yarn.lock index 4aa2bb72b..c57e32036 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8251,7 +8251,7 @@ __metadata: volto-dropdownmenu: 4.1.3 volto-editablefooter: 5.1.7 volto-feedback: 0.3.2 - volto-form-block: 3.9.2 + volto-form-block: 3.10.0 volto-gdpr-privacy: 2.2.7 volto-google-analytics: 2.0.0 volto-multilingual-widget: 3.2.1 @@ -16171,9 +16171,9 @@ __metadata: languageName: node linkType: hard -"volto-form-block@npm:3.9.2": - version: 3.9.2 - resolution: "volto-form-block@npm:3.9.2" +"volto-form-block@npm:3.10.0": + version: 3.10.0 + resolution: "volto-form-block@npm:3.10.0" dependencies: "@hcaptcha/react-hcaptcha": ^0.3.6 file-saver: ^2.0.5 @@ -16182,7 +16182,7 @@ __metadata: peerDependencies: "@plone/volto": ">=16.0.0-alpha.38" volto-subblocks: ^2.1.0 - checksum: a47c5241bed9e5959241ccadd3992753718b0b1fae5f3104089600c5f0d2b71193d9c0a41235e7e9f3fadce9691a5c0bc14722d667cbcf8a1a5793a381c4a746 + checksum: 8ddce2c624cf329f446a63772ce8dd643aed957b8d967463e76f3f83383704ca9b3d1fe0669390c5a965d9a2568123fdbb3408cf831cadb9e5cebfd164ca0aa9 languageName: node linkType: hard