From 272e3c3093c0dbc253f2a2406125cc497354cd01 Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Fri, 9 Sep 2022 10:00:01 +0200 Subject: [PATCH 1/7] feat: added honeypot field type --- src/components/Field.jsx | 13 ++++- src/components/Widget/HoneypotWidget.css | 3 + src/components/Widget/HoneypotWidget.jsx | 70 ++++++++++++++++++++++++ 3 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 src/components/Widget/HoneypotWidget.css create mode 100644 src/components/Widget/HoneypotWidget.jsx diff --git a/src/components/Field.jsx b/src/components/Field.jsx index 9eb8916..cda4b11 100644 --- a/src/components/Field.jsx +++ b/src/components/Field.jsx @@ -3,7 +3,6 @@ import PropTypes from 'prop-types'; import { useIntl, defineMessages } from 'react-intl'; import WysiwygWidget from '@plone/volto/components/manage/Widgets/WysiwygWidget'; - import EmailWidget from './Widget/EmailWidget'; import FileWidget from './Widget/FileWidget'; import DatetimeWidget from './Widget/DatetimeWidget'; @@ -13,6 +12,7 @@ import TextWidget from './Widget/TextWidget'; import TextareaWidget from './Widget/TextareaWidget'; import CheckboxListWidget from './Widget/CheckboxListWidget'; import RadioWidget from './Widget/RadioWidget'; +import HoneypotWidget from './Widget/HoneypotWidget'; import './Field.css'; @@ -214,6 +214,17 @@ const Field = ({ ) : (
))} + + {field_type === 'honeypot' && ( + + )} {config.blocks.blocksConfig.form.additionalFields?.reduce((acc, val) => { if (val.id === field_type) return [ diff --git a/src/components/Widget/HoneypotWidget.css b/src/components/Widget/HoneypotWidget.css new file mode 100644 index 0000000..38b56a1 --- /dev/null +++ b/src/components/Widget/HoneypotWidget.css @@ -0,0 +1,3 @@ +.honey-wrapper { + display: none; +} diff --git a/src/components/Widget/HoneypotWidget.jsx b/src/components/Widget/HoneypotWidget.jsx new file mode 100644 index 0000000..0f8dff5 --- /dev/null +++ b/src/components/Widget/HoneypotWidget.jsx @@ -0,0 +1,70 @@ +/** + * HoneypotWidget component. + * @module components/manage/Widgets/HoneypotWidget + */ + +import React from 'react'; +import PropTypes from 'prop-types'; + +import TextWidget from '@plone/volto/components/manage/Widgets/TextWidget'; +import './HoneypotWidget.css'; + +/** + * HoneypotWidget component class. + * @function HoneypotWidget + * @returns {string} Markup of the component. + */ +const HoneypotWidget = ({ + id, + title, + required, + description, + error, + value = [], + valueList, + onChange, +}) => { + return ( +
+ +
+ ); +}; + +/** + * Property types. + * @property {Object} propTypes Property types. + * @static + */ +HoneypotWidget.propTypes = { + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + description: PropTypes.string, + required: PropTypes.bool, + error: PropTypes.arrayOf(PropTypes.string), + wrapped: PropTypes.bool, +}; + +/** + * Default properties. + * @property {Object} defaultProps Default properties. + * @static + */ +HoneypotWidget.defaultProps = { + description: null, + required: false, + error: [], + value: [], + onChange: null, + onEdit: null, + onDelete: null, +}; + +export default HoneypotWidget; From cd294c45b54920c6f0d0f15c70a9b33469bfa6a0 Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Fri, 9 Sep 2022 10:02:14 +0200 Subject: [PATCH 2/7] fix: fix HoneypotWidget props --- src/components/Widget/HoneypotWidget.jsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/components/Widget/HoneypotWidget.jsx b/src/components/Widget/HoneypotWidget.jsx index 0f8dff5..cfc8755 100644 --- a/src/components/Widget/HoneypotWidget.jsx +++ b/src/components/Widget/HoneypotWidget.jsx @@ -47,8 +47,6 @@ HoneypotWidget.propTypes = { id: PropTypes.string.isRequired, title: PropTypes.string.isRequired, description: PropTypes.string, - required: PropTypes.bool, - error: PropTypes.arrayOf(PropTypes.string), wrapped: PropTypes.bool, }; @@ -59,8 +57,6 @@ HoneypotWidget.propTypes = { */ HoneypotWidget.defaultProps = { description: null, - required: false, - error: [], value: [], onChange: null, onEdit: null, From 2723f5281fb918f2baf30940a746a956b85cc49c Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Fri, 9 Sep 2022 11:31:36 +0200 Subject: [PATCH 3/7] feat: added honeypot widget captcha --- src/components/Field.jsx | 12 ---- src/components/Widget/Captcha.jsx | 11 ++++ ...otWidget.css => HoneypotCaptchaWidget.css} | 0 .../Widget/HoneypotCaptchaWidget.jsx | 43 ++++++++++++ src/components/Widget/HoneypotWidget.jsx | 66 ------------------- 5 files changed, 54 insertions(+), 78 deletions(-) rename src/components/Widget/{HoneypotWidget.css => HoneypotCaptchaWidget.css} (100%) create mode 100644 src/components/Widget/HoneypotCaptchaWidget.jsx delete mode 100644 src/components/Widget/HoneypotWidget.jsx diff --git a/src/components/Field.jsx b/src/components/Field.jsx index cda4b11..3c18033 100644 --- a/src/components/Field.jsx +++ b/src/components/Field.jsx @@ -12,7 +12,6 @@ import TextWidget from './Widget/TextWidget'; import TextareaWidget from './Widget/TextareaWidget'; import CheckboxListWidget from './Widget/CheckboxListWidget'; import RadioWidget from './Widget/RadioWidget'; -import HoneypotWidget from './Widget/HoneypotWidget'; import './Field.css'; @@ -214,17 +213,6 @@ const Field = ({ ) : (
))} - - {field_type === 'honeypot' && ( - - )} {config.blocks.blocksConfig.form.additionalFields?.reduce((acc, val) => { if (val.id === field_type) return [ diff --git a/src/components/Widget/Captcha.jsx b/src/components/Widget/Captcha.jsx index c5421ac..0b9d441 100644 --- a/src/components/Widget/Captcha.jsx +++ b/src/components/Widget/Captcha.jsx @@ -2,6 +2,7 @@ import React, { createRef } from 'react'; import GoogleReCaptchaWidget from './GoogleReCaptchaWidget'; import HCaptchaWidget from './HCaptchaWidget'; import NoRobotsCaptchaWidget from './NoRobotsCaptchaWidget'; +import HoneypotCaptchaWidget from './HoneypotCaptchaWidget'; class Captcha extends React.Component { constructor(props) { @@ -77,6 +78,16 @@ class Captcha extends React.Component { captchaToken={captchaToken} > ); + } else if (captcha === 'honeypot') { + return ( + + ); } else { return null; } diff --git a/src/components/Widget/HoneypotWidget.css b/src/components/Widget/HoneypotCaptchaWidget.css similarity index 100% rename from src/components/Widget/HoneypotWidget.css rename to src/components/Widget/HoneypotCaptchaWidget.css diff --git a/src/components/Widget/HoneypotCaptchaWidget.jsx b/src/components/Widget/HoneypotCaptchaWidget.jsx new file mode 100644 index 0000000..989a0ba --- /dev/null +++ b/src/components/Widget/HoneypotCaptchaWidget.jsx @@ -0,0 +1,43 @@ +/** + * HoneypotCaptchaWidget component. + * @module components/manage/Widgets/HoneypotCaptchaWidget + */ + +import React, { useState } from 'react'; + +import TextWidget from '@plone/volto/components/manage/Widgets/TextWidget'; +import './HoneypotCaptchaWidget.css'; + +/** + * HoneypotCaptchaWidget component class. + * @function HoneypotCaptchaWidget + * @returns {string} Markup of the component. + */ +const HoneypotCaptchaWidget = ({ id, id_check, title, captchaToken }) => { + const createToken = (id, id_check, value) => { + const token = { + id: id, + id_check: id_check, + value: value, + }; + return JSON.stringify(token); + }; + const [value, setValue] = useState(); + return ( +
+ { + captchaToken.current = createToken(id, id_check, value); + setValue(value); + }} + value={value} + /> +
+ ); +}; + +export default HoneypotCaptchaWidget; diff --git a/src/components/Widget/HoneypotWidget.jsx b/src/components/Widget/HoneypotWidget.jsx deleted file mode 100644 index cfc8755..0000000 --- a/src/components/Widget/HoneypotWidget.jsx +++ /dev/null @@ -1,66 +0,0 @@ -/** - * HoneypotWidget component. - * @module components/manage/Widgets/HoneypotWidget - */ - -import React from 'react'; -import PropTypes from 'prop-types'; - -import TextWidget from '@plone/volto/components/manage/Widgets/TextWidget'; -import './HoneypotWidget.css'; - -/** - * HoneypotWidget component class. - * @function HoneypotWidget - * @returns {string} Markup of the component. - */ -const HoneypotWidget = ({ - id, - title, - required, - description, - error, - value = [], - valueList, - onChange, -}) => { - return ( -
- -
- ); -}; - -/** - * Property types. - * @property {Object} propTypes Property types. - * @static - */ -HoneypotWidget.propTypes = { - id: PropTypes.string.isRequired, - title: PropTypes.string.isRequired, - description: PropTypes.string, - wrapped: PropTypes.bool, -}; - -/** - * Default properties. - * @property {Object} defaultProps Default properties. - * @static - */ -HoneypotWidget.defaultProps = { - description: null, - value: [], - onChange: null, - onEdit: null, - onDelete: null, -}; - -export default HoneypotWidget; From b4d990ca822d0c42e263194e3e91221fc7715dd2 Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Fri, 9 Sep 2022 11:49:37 +0200 Subject: [PATCH 4/7] fix: fix captcha widget --- src/components/Widget/Captcha.jsx | 3 +-- src/components/Widget/HoneypotCaptchaWidget.jsx | 7 +++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/Widget/Captcha.jsx b/src/components/Widget/Captcha.jsx index 0b9d441..c64ff2a 100644 --- a/src/components/Widget/Captcha.jsx +++ b/src/components/Widget/Captcha.jsx @@ -82,8 +82,7 @@ class Captcha extends React.Component { return ( diff --git a/src/components/Widget/HoneypotCaptchaWidget.jsx b/src/components/Widget/HoneypotCaptchaWidget.jsx index 989a0ba..d7a68ed 100644 --- a/src/components/Widget/HoneypotCaptchaWidget.jsx +++ b/src/components/Widget/HoneypotCaptchaWidget.jsx @@ -13,11 +13,10 @@ import './HoneypotCaptchaWidget.css'; * @function HoneypotCaptchaWidget * @returns {string} Markup of the component. */ -const HoneypotCaptchaWidget = ({ id, id_check, title, captchaToken }) => { - const createToken = (id, id_check, value) => { +const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { + const createToken = (id, value) => { const token = { id: id, - id_check: id_check, value: value, }; return JSON.stringify(token); @@ -31,7 +30,7 @@ const HoneypotCaptchaWidget = ({ id, id_check, title, captchaToken }) => { label={title} title={title} onChange={(field, value) => { - captchaToken.current = createToken(id, id_check, value); + captchaToken.current = createToken(id, value); setValue(value); }} value={value} From 1a3c19bfa644147024347bc543f3cb8cc73e7f6d Mon Sep 17 00:00:00 2001 From: Giulia Ghisini Date: Fri, 9 Sep 2022 11:55:16 +0200 Subject: [PATCH 5/7] fix: fix captcha widget manage token --- src/components/Widget/HoneypotCaptchaWidget.jsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/components/Widget/HoneypotCaptchaWidget.jsx b/src/components/Widget/HoneypotCaptchaWidget.jsx index d7a68ed..b7ce966 100644 --- a/src/components/Widget/HoneypotCaptchaWidget.jsx +++ b/src/components/Widget/HoneypotCaptchaWidget.jsx @@ -3,7 +3,7 @@ * @module components/manage/Widgets/HoneypotCaptchaWidget */ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import TextWidget from '@plone/volto/components/manage/Widgets/TextWidget'; import './HoneypotCaptchaWidget.css'; @@ -13,6 +13,9 @@ import './HoneypotCaptchaWidget.css'; * @function HoneypotCaptchaWidget * @returns {string} Markup of the component. */ + +/*By default, captcha token is setted, and becames empty if user/bot fills the field. + */ const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { const createToken = (id, value) => { const token = { @@ -21,6 +24,11 @@ const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { }; return JSON.stringify(token); }; + + useEffect(() => { + captchaToken.current = createToken(id, new Date().toString()); + }, [captchaToken, id]); + const [value, setValue] = useState(); return (
@@ -30,7 +38,8 @@ const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { label={title} title={title} onChange={(field, value) => { - captchaToken.current = createToken(id, value); + //captchaToken.current = createToken(id, value); + captchaToken.current = undefined; setValue(value); }} value={value} From 1946a0839cda2e19693c21cc64c48c79395b32e7 Mon Sep 17 00:00:00 2001 From: Sara Bianchi Date: Fri, 16 Sep 2022 12:34:48 +0200 Subject: [PATCH 6/7] chore: added captcha value of submit request --- src/components/View.jsx | 6 +++++- src/components/Widget/Captcha.jsx | 9 ++++++++- src/components/Widget/HoneypotCaptchaWidget.jsx | 12 +++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/components/View.jsx b/src/components/View.jsx index de33449..dbd45f8 100644 --- a/src/components/View.jsx +++ b/src/components/View.jsx @@ -137,10 +137,13 @@ const View = ({ data, id, path }) => { .then(() => { if (isValidForm()) { let attachments = {}; - const captcha = { + let captcha = { provider: data.captcha, token: captchaToken.current, }; + if (data.captcha === 'honeypot') { + captcha.value = formData[data.captcha_props.id]?.value ?? ''; + } let formattedFormData = { ...formData }; data.subblocks.forEach((subblock) => { @@ -194,6 +197,7 @@ const View = ({ data, id, path }) => { captchaToken, captcha: data.captcha, captcha_props: data.captcha_props, + onChangeFormData, }); useEffect(() => { diff --git a/src/components/Widget/Captcha.jsx b/src/components/Widget/Captcha.jsx index c64ff2a..b9119cd 100644 --- a/src/components/Widget/Captcha.jsx +++ b/src/components/Widget/Captcha.jsx @@ -40,7 +40,13 @@ class Captcha extends React.Component { } render() { - const { captchaToken, captcha, captcha_props } = this.props; + const { + captchaToken, + captcha, + captcha_props, + onChangeFormData, + } = this.props; + const captchaRef = this.captchaRef; if (captcha === 'recaptcha') { return ( @@ -85,6 +91,7 @@ class Captcha extends React.Component { title={captcha_props.id} captchaRef={captchaRef} captchaToken={captchaToken} + onChangeFormData={onChangeFormData} /> ); } else { diff --git a/src/components/Widget/HoneypotCaptchaWidget.jsx b/src/components/Widget/HoneypotCaptchaWidget.jsx index b7ce966..0d49bd3 100644 --- a/src/components/Widget/HoneypotCaptchaWidget.jsx +++ b/src/components/Widget/HoneypotCaptchaWidget.jsx @@ -16,7 +16,12 @@ import './HoneypotCaptchaWidget.css'; /*By default, captcha token is setted, and becames empty if user/bot fills the field. */ -const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { +const HoneypotCaptchaWidget = ({ + id, + title, + captchaToken, + onChangeFormData, +}) => { const createToken = (id, value) => { const token = { id: id, @@ -29,6 +34,10 @@ const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { captchaToken.current = createToken(id, new Date().toString()); }, [captchaToken, id]); + useEffect(() => { + onChangeFormData(id, id, '', { label: id }); + }, []); + const [value, setValue] = useState(); return (
@@ -41,6 +50,7 @@ const HoneypotCaptchaWidget = ({ id, title, captchaToken }) => { //captchaToken.current = createToken(id, value); captchaToken.current = undefined; setValue(value); + onChangeFormData(id, field, value, {}); }} value={value} /> From 300d6c9c560163e2fec455c9e23bc8af4552fddc Mon Sep 17 00:00:00 2001 From: Sara Bianchi Date: Fri, 16 Sep 2022 15:20:38 +0200 Subject: [PATCH 7/7] fix: fixed const variables and added row class --- src/components/Widget/HoneypotCaptchaWidget.css | 2 +- src/components/Widget/HoneypotCaptchaWidget.jsx | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/Widget/HoneypotCaptchaWidget.css b/src/components/Widget/HoneypotCaptchaWidget.css index 38b56a1..bf44dcb 100644 --- a/src/components/Widget/HoneypotCaptchaWidget.css +++ b/src/components/Widget/HoneypotCaptchaWidget.css @@ -1,3 +1,3 @@ -.honey-wrapper { +.public-ui .ui.grid > .row.honey-wrapper { display: none; } diff --git a/src/components/Widget/HoneypotCaptchaWidget.jsx b/src/components/Widget/HoneypotCaptchaWidget.jsx index 0d49bd3..92d31b6 100644 --- a/src/components/Widget/HoneypotCaptchaWidget.jsx +++ b/src/components/Widget/HoneypotCaptchaWidget.jsx @@ -6,6 +6,7 @@ import React, { useState, useEffect } from 'react'; import TextWidget from '@plone/volto/components/manage/Widgets/TextWidget'; +import { Grid } from 'semantic-ui-react'; import './HoneypotCaptchaWidget.css'; /** @@ -40,7 +41,7 @@ const HoneypotCaptchaWidget = ({ const [value, setValue] = useState(); return ( -
+ -
+ ); };