diff --git a/README.md b/README.md index cc7a895..fc23c93 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,10 @@ With HCaptcha integration, you also have an additional option in the sidebar in In some test scenarios it's found that the "Passing Threshold" of HCaptcha must be configured as "Auto" to get the best results. In some test cases if one sets the Threshold to "Moderate" HCaptcha starts to fail. +### OTP email validation + +To prevent sending spam emails to users via the email address configured as sender, the 'email' fields type flagged as BCC will require the user to enter an OTP code received at the address entered in the field when user fills out the form. + ## Export With backend support, you can store data submitted from the form. diff --git a/locales/de/LC_MESSAGES/volto.po b/locales/de/LC_MESSAGES/volto.po index 650f70e..0ce947e 100644 --- a/locales/de/LC_MESSAGES/volto.po +++ b/locales/de/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Daten exportieren" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "Textfeld" msgid "form_formDataCount" msgstr "{formDataCount} Element(e) gespeichert" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Löschen" @@ -469,6 +484,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "Beschriftung der Schaltfläche Senden" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Gesendet!" @@ -514,6 +534,11 @@ msgstr "Setzt diese Adresse als Antwortadresse in versendeten Mails" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/en/LC_MESSAGES/volto.po b/locales/en/LC_MESSAGES/volto.po index 3a10917..c8ea6ce 100644 --- a/locales/en/LC_MESSAGES/volto.po +++ b/locales/en/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Export in CSV" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "Textarea" msgid "form_formDataCount" msgstr "{formDataCount} item(s) stored" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Clear" @@ -469,6 +484,11 @@ msgstr "Message of sending confirmed" msgid "form_send_message_helptext" msgstr "You can add the value of a filled field in the form by inserting its ID between curly brackets preceded by $, example: ${field_id}; you can add html elements such as links , new line
, bold and italic formatting." +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "Show cancel button" msgid "form_submit_label" msgstr "Submit button label" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Sent!" @@ -514,6 +534,11 @@ msgstr "If selected, this will be the address the receiver can use to reply." msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/es/LC_MESSAGES/volto.po b/locales/es/LC_MESSAGES/volto.po index 9564076..bc8363f 100644 --- a/locales/es/LC_MESSAGES/volto.po +++ b/locales/es/LC_MESSAGES/volto.po @@ -307,12 +307,12 @@ msgstr "Exportar datos" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -433,11 +433,26 @@ msgstr "Campo de texto" msgid "form_formDataCount" msgstr "{formDataCount} elemento(s) guardados" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -448,7 +463,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Borrar" @@ -478,6 +493,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -488,7 +508,7 @@ msgstr "" msgid "form_submit_label" msgstr "Etiqueta del botón de envío" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Enviado" @@ -523,6 +543,11 @@ msgstr "Si está seleccionado el valor de este campo se utilizará como cabecera msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/eu/LC_MESSAGES/volto.po b/locales/eu/LC_MESSAGES/volto.po index 8297a6a..a81c3bc 100644 --- a/locales/eu/LC_MESSAGES/volto.po +++ b/locales/eu/LC_MESSAGES/volto.po @@ -300,12 +300,12 @@ msgstr "Esportatu datuak" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -426,11 +426,26 @@ msgstr "Testua" msgid "form_formDataCount" msgstr "Gordetako elementu kopurua: {formDataCount}" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -441,7 +456,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Garbitu" @@ -471,6 +486,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -481,7 +501,7 @@ msgstr "" msgid "form_submit_label" msgstr "Bidalketa botoiaren etiketa" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Bidalita!" @@ -516,6 +536,11 @@ msgstr "Aukeratuz gero jasotako posta elektronikoari 'Erantzun' eginez gero erem msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/fr/LC_MESSAGES/volto.po b/locales/fr/LC_MESSAGES/volto.po index 75ac30f..6476b07 100644 --- a/locales/fr/LC_MESSAGES/volto.po +++ b/locales/fr/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Exporter au format CSV" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "Zone de texte" msgid "form_formDataCount" msgstr "{formDataCount} article(s) stocké(s)" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Dégager" @@ -469,6 +484,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "Soumettre l'étiquette du bouton" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Expédié!" @@ -514,6 +534,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/it/LC_MESSAGES/volto.po b/locales/it/LC_MESSAGES/volto.po index 6d24e06..dbbe474 100644 --- a/locales/it/LC_MESSAGES/volto.po +++ b/locales/it/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "Esporta in CSV" msgid "form_edit_fill_required_configuration_fields" msgstr "Inserire i campi obbligatori per la configurazione del form nella sidebar di destra. Il form non verrà mostrato sul sito finché i campi obbligatori non saranno configurati." -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "L'e-mail inserita nel campo 'Mittente di default' deve essere un indirizzo e-mail valido" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "Le e-mail inserite nel campo 'Destinatari' devono essere indirizzi e-mail validi." @@ -424,11 +424,26 @@ msgstr "Area di testo" msgid "form_formDataCount" msgstr "{formDataCount} elementi salvati" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "Inserisci qui il codice OTP ricevuto all'indirizzo {email}" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "Gestione dei dati" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "Puoi inviare un nuovo codice OTP fra" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "Il codice OTP è stato inviato a {email}. Verifica la tua email e inserisci nel campo sopra il codice OTP ricevuto." + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "Giorni validità" msgid "form_remove_data_after_days_helptext" msgstr "Numero di giorni dopo i quali, i dati dovrebbero essere cancellati" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Indietro" @@ -469,6 +484,11 @@ msgstr "Messaggio di conferma invio" msgid "form_send_message_helptext" msgstr "Si può aggiungere il valore di un campo compilato nella form inserendo il suo identificativo tra parentesi graffe preceduto da $, esempio: ${identificativo}; inoltre si possono aggiungere elementi html come link,
, nuova linea
, formattazioni in bold e italic ." +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "Invia il codice OTP a {email}" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "Mostra il bottone annulla" msgid "form_submit_label" msgstr "Testo sul bottone di invio" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Inviato!" @@ -514,6 +534,11 @@ msgstr "Se selezionato, questo sarà l'indirizzo a cui il destinatario potrà ri msgid "formblock_defaultInvalidFieldMessage" msgstr "Il valore inserito non è valido" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "Inserire il codice OTP ricevuto via email." + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/ja/LC_MESSAGES/volto.po b/locales/ja/LC_MESSAGES/volto.po index 5676c5d..d269365 100644 --- a/locales/ja/LC_MESSAGES/volto.po +++ b/locales/ja/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -469,6 +484,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" @@ -514,6 +534,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/nl/LC_MESSAGES/volto.po b/locales/nl/LC_MESSAGES/volto.po index 5676c5d..d269365 100644 --- a/locales/nl/LC_MESSAGES/volto.po +++ b/locales/nl/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -469,6 +484,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" @@ -514,6 +534,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/pt/LC_MESSAGES/volto.po b/locales/pt/LC_MESSAGES/volto.po index 5676c5d..d269365 100644 --- a/locales/pt/LC_MESSAGES/volto.po +++ b/locales/pt/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -469,6 +484,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" @@ -514,6 +534,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/pt_BR/LC_MESSAGES/volto.po b/locales/pt_BR/LC_MESSAGES/volto.po index 632b5d7..525f73c 100644 --- a/locales/pt_BR/LC_MESSAGES/volto.po +++ b/locales/pt_BR/LC_MESSAGES/volto.po @@ -304,12 +304,12 @@ msgstr "Exportar dados" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -430,11 +430,26 @@ msgstr "Área de texto" msgid "form_formDataCount" msgstr "{formDataCount} item(ns) armazenados" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -445,7 +460,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "Limpar" @@ -475,6 +490,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -485,7 +505,7 @@ msgstr "" msgid "form_submit_label" msgstr "Texto do botão de enviar" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "Enviado!" @@ -520,6 +540,11 @@ msgstr "Usar este campo como valor do cabeçalho de 'responder para'" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/ro/LC_MESSAGES/volto.po b/locales/ro/LC_MESSAGES/volto.po index 5676c5d..d269365 100644 --- a/locales/ro/LC_MESSAGES/volto.po +++ b/locales/ro/LC_MESSAGES/volto.po @@ -298,12 +298,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -424,11 +424,26 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -439,7 +454,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -469,6 +484,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -479,7 +499,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" @@ -514,6 +534,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/locales/volto.pot b/locales/volto.pot index 153ecfc..334e100 100644 --- a/locales/volto.pot +++ b/locales/volto.pot @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: Plone\n" -"POT-Creation-Date: 2024-03-18T09:07:32.597Z\n" +"POT-Creation-Date: 2024-04-17T08:56:51.659Z\n" "Last-Translator: Plone i18n \n" "Language-Team: Plone i18n \n" "MIME-Version: 1.0\n" @@ -300,12 +300,12 @@ msgstr "" msgid "form_edit_fill_required_configuration_fields" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'From' field must be a valid e-mail address. msgid "form_edit_invalid_from_email" msgstr "" -#: index +#: helpers/validators # defaultMessage: The e-mail entered in the 'Receipients' field must be a valid e-mail address. msgid "form_edit_invalid_to_email" msgstr "" @@ -426,11 +426,26 @@ msgstr "" msgid "form_formDataCount" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Insert here the OTP code received at {email} +msgid "form_insert_otp" +msgstr "" + #: formSchema # defaultMessage: Manage data msgid "form_manage_data" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: You can send a new OTP code in +msgid "form_otp_countdown" +msgstr "" + +#: components/Widget/OTPWidget +# defaultMessage: OTP code was sent to {email}. Check your email and insert the received OTP code into the field above. +msgid "form_otp_send" +msgstr "" + #: formSchema # defaultMessage: Data wipe msgid "form_remove_data_after_days" @@ -441,7 +456,7 @@ msgstr "" msgid "form_remove_data_after_days_helptext" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Clear msgid "form_reset" msgstr "" @@ -471,6 +486,11 @@ msgstr "" msgid "form_send_message_helptext" msgstr "" +#: components/Widget/OTPWidget +# defaultMessage: Send OTP code to {email} +msgid "form_send_otp_to" +msgstr "" + #: formSchema # defaultMessage: Show cancel button msgid "form_show_cancel" @@ -481,7 +501,7 @@ msgstr "" msgid "form_submit_label" msgstr "" -#: components/FormView +#: components/FormResult # defaultMessage: Sent! msgid "form_submit_success" msgstr "" @@ -516,6 +536,11 @@ msgstr "" msgid "formblock_defaultInvalidFieldMessage" msgstr "" +#: components/View +# defaultMessage: Please, insert the OTP code recived via email. +msgid "formblock_insertOtp_error" +msgstr "" + #: components/View # defaultMessage: The email is incorrect msgid "formblock_invalidEmailMessage" diff --git a/src/actions/index.js b/src/actions/index.js index 2bb5a6c..08d5921 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -85,3 +85,24 @@ export function clearFormData({ path, block_id, expired = false }) { }, }; } + +/** + * sendOTP action + * @module actions/sendOTP + */ +export const SEND_OTP = 'SEND_OTP'; + +export function sendOTP(path, block_id, email) { + return { + type: SEND_OTP, + subrequest: block_id + '_' + email, + request: { + op: 'post', + path: path + '/@validate-email-address', + data: { + email, + uid: block_id, + }, + }, + }; +} diff --git a/src/components/FormView.jsx b/src/components/FormView.jsx index 409192f..b441163 100644 --- a/src/components/FormView.jsx +++ b/src/components/FormView.jsx @@ -1,15 +1,13 @@ import React from 'react'; import { useIntl, defineMessages } from 'react-intl'; -import { - Segment, - Message, - Grid, - Form, - Progress, - Button, -} from 'semantic-ui-react'; +import { Segment, Message, Grid, Form, Progress } from 'semantic-ui-react'; import { getFieldName } from 'volto-form-block/components/utils'; import Field from 'volto-form-block/components/Field'; +import { + OTPWidget, + OTP_FIELDNAME_EXTENDER, + Button, +} from 'volto-form-block/components/Widget'; import config from '@plone/volto/registry'; import { FormResult } from 'volto-form-block/components'; /* Style */ @@ -46,6 +44,8 @@ const FormView = ({ captcha, id, getErrorMessage, + path, + block_id, }) => { const intl = useIntl(); const FieldSchema = config.blocks.blocksConfig.form.fieldSchema; @@ -59,6 +59,25 @@ const FormView = ({ onSubmit(e); }; + const getFieldsToSendWithValue = (subblock) => { + var fields_to_send = []; + var fieldSchemaProperties = FieldSchema(subblock)?.properties; + for (var key in fieldSchemaProperties) { + if (fieldSchemaProperties[key].send_to_backend) { + fields_to_send.push(key); + } + } + + var fields_to_send_with_value = Object.assign( + {}, + ...fields_to_send.map((field) => { + return { + [field]: subblock[field], + }; + }), + ); + return fields_to_send_with_value; + }; return (
@@ -106,22 +125,8 @@ const FormView = ({ {data.subblocks?.map((subblock, index) => { let name = getFieldName(subblock.label, subblock.id); - var fields_to_send = []; - var fieldSchemaProperties = FieldSchema(subblock)?.properties; - for (var key in fieldSchemaProperties) { - if (fieldSchemaProperties[key].send_to_backend) { - fields_to_send.push(key); - } - } - - var fields_to_send_with_value = Object.assign( - {}, - ...fields_to_send.map((field) => { - return { - [field]: subblock[field], - }; - }), - ); + const fields_to_send_with_value = + getFieldsToSendWithValue(subblock); return ( @@ -150,6 +155,47 @@ 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); + + 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} + /> + + + ); + })} + {captcha.render()} {formErrors.length > 0 && ( @@ -159,7 +205,6 @@ const FormView = ({

{intl.formatMessage(messages.form_errors)}

)} - {formState.error && ( diff --git a/src/components/View.jsx b/src/components/View.jsx index 627fddf..5042264 100644 --- a/src/components/View.jsx +++ b/src/components/View.jsx @@ -10,6 +10,7 @@ import config from '@plone/volto/registry'; import { Captcha } from 'volto-form-block/components/Widget'; import { isValidEmail } from 'volto-form-block/helpers/validators'; import ValidateConfigForm from 'volto-form-block/components/ValidateConfigForm'; +import { OTP_FIELDNAME_EXTENDER } from 'volto-form-block/components/Widget'; const messages = defineMessages({ formSubmitted: { @@ -28,6 +29,10 @@ const messages = defineMessages({ id: 'formblock_invalidEmailMessage', defaultMessage: 'The email is incorrect', }, + insertOtp: { + id: 'formblock_insertOtp_error', + defaultMessage: 'Please, insert the OTP code recived via email.', + }, }); const initialState = { @@ -132,6 +137,7 @@ const View = ({ data, id, path }) => { data.subblocks.forEach((subblock, index) => { const name = getFieldName(subblock.label, subblock.id); const fieldType = subblock.field_type; + const isBCC = subblock.use_as_bcc; const additionalField = config.blocks.blocksConfig.form.additionalFields?.filter( (f) => f.id === fieldType && f.isValid !== undefined, @@ -172,14 +178,20 @@ const View = ({ data, id, path }) => { message: intl.formatMessage(messages.requiredFieldMessage), }); } else if ( - fieldType === 'from' && - formData[name]?.value && - !isValidEmail(formData[name].value) + (fieldType === 'from' || fieldType === 'email') && + formData[name]?.value ) { - v.push({ - field: name, - message: intl.formatMessage(messages.invalidEmailMessage), - }); + if (!isValidEmail(formData[name].value)) { + v.push({ + field: name, + message: intl.formatMessage(messages.invalidEmailMessage), + }); + } else if (isBCC && !formData[name].otp) { + v.push({ + field: name + OTP_FIELDNAME_EXTENDER, + message: intl.formatMessage(messages.insertOtp), + }); + } } }); @@ -327,6 +339,8 @@ const View = ({ data, id, path }) => { resetFormState={resetFormState} resetFormOnError={resetFormOnError} getErrorMessage={getErrorMessage} + path={path} + block_id={id} /> ); diff --git a/src/components/Widget/Button.jsx b/src/components/Widget/Button.jsx new file mode 100644 index 0000000..94ceeef --- /dev/null +++ b/src/components/Widget/Button.jsx @@ -0,0 +1,13 @@ +/** + * Button component. + * This is a wrapper for Buttons, to eventually customize Button component if you don't like to use semantic-ui, for example. + * @module components/Widget/OTPWidget + */ + +import { Button as SemanticButton } from 'semantic-ui-react'; + +const Button = (props) => { + return ; +}; + +export default Button; diff --git a/src/components/Widget/FileWidget.jsx b/src/components/Widget/FileWidget.jsx index 6cb80d2..a0d1b8e 100644 --- a/src/components/Widget/FileWidget.jsx +++ b/src/components/Widget/FileWidget.jsx @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { Button, Image, Dimmer } from 'semantic-ui-react'; +import { Image, Dimmer } from 'semantic-ui-react'; import { readAsDataURL } from 'promise-file-reader'; import { injectIntl } from 'react-intl'; import deleteSVG from '@plone/volto/icons/delete.svg'; @@ -14,6 +14,7 @@ import { Icon, FormFieldWrapper } from '@plone/volto/components'; import loadable from '@loadable/component'; import { flattenToAppURL } from '@plone/volto/helpers'; import { defineMessages, useIntl } from 'react-intl'; +import { Button } from 'volto-form-block/components/Widget'; const imageMimetypes = [ 'image/png', @@ -85,8 +86,8 @@ const FileWidget = (props) => { const imgsrc = value?.download ? `${flattenToAppURL(value?.download)}?id=${Date.now()}` : null || value?.data - ? `data:${value['content-type']};${value.encoding},${value.data}` - : null; + ? `data:${value['content-type']};${value.encoding},${value.data}` + : null; /** * Drop handler diff --git a/src/components/Widget/OTPWidget.css b/src/components/Widget/OTPWidget.css new file mode 100644 index 0000000..8c4978f --- /dev/null +++ b/src/components/Widget/OTPWidget.css @@ -0,0 +1,49 @@ +.otp-widget .otp-widget-field-wrapper { + display: flex; + gap: 1rem; + align-items: start; +} +.otp-widget .otp-widget-field-wrapper .field { + flex-grow: 1; +} + +.otp-widget .otp-alert { + position: relative; + padding: 0.5rem 1rem; + margin-bottom: 1rem; + border: 1px solid #5d7083; + border-left: 8px solid #5d7083; + background-color: #fff; + border-radius: 0; + margin-top: -3rem; + margin-bottom: 3rem; +} + +.otp-widget .otp-alert.otp-error { + border-left: 8px solid #cc334d; +} + +.otp-widget .otp-alert.otp-success { + border-left: 8px solid #008055; +} + +.otp-widget .otp-widget-field-wrapper .button-wrapper { + display: flex; + flex-direction: column; +} + +.otp-widget .otp-widget-field-wrapper .button-wrapper .otp-button-message { + font-size: 0.8rem; + color: #555555; + text-align: center; +} +@media (max-width: 1024px) { + .otp-widget .otp-widget-field-wrapper { + flex-direction: column; + } + .otp-widget .otp-widget-field-wrapper .field, + .otp-widget .otp-widget-field-wrapper .button-wrapper, + .otp-widget .otp-widget-field-wrapper .button-wrapper button { + width: 100%; + } +} diff --git a/src/components/Widget/OTPWidget.jsx b/src/components/Widget/OTPWidget.jsx new file mode 100644 index 0000000..defa629 --- /dev/null +++ b/src/components/Widget/OTPWidget.jsx @@ -0,0 +1,200 @@ +/** + * OTPWidget component. + * @module components/Widget/OTPWidget + */ + +import PropTypes from 'prop-types'; +import React, { useState, useEffect } from 'react'; +import { useSelector, useDispatch } from 'react-redux'; +import { useIntl, defineMessages } from 'react-intl'; +import { isValidEmail } from 'volto-form-block/helpers/validators'; +import Field from 'volto-form-block/components/Field'; +import { Button } from 'volto-form-block/components/Widget'; +import { sendOTP } from 'volto-form-block/actions'; + +import 'volto-form-block/components/Widget/OTPWidget.css'; +export const OTP_FIELDNAME_EXTENDER = '_otp'; + +const messages = defineMessages({ + send_otp_to: { + id: 'form_send_otp_to', + defaultMessage: 'Send OTP code to {email}', + }, + insert_otp: { + id: 'form_insert_otp', + defaultMessage: 'Insert here the OTP code received at {email}', + }, + otp_sent: { + id: 'form_otp_send', + defaultMessage: + 'OTP code was sent to {email}. Check your email and insert the received OTP code into the field above.', + }, + otp_countdown: { + id: 'form_otp_countdown', + defaultMessage: 'You can send a new OTP code in', + }, +}); +const getCountDownValues = (countDown) => { + // calculate time left + const days = Math.floor(countDown / (1000 * 60 * 60 * 24)); + const hours = Math.floor( + (countDown % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60), + ); + const minutes = Math.floor((countDown % (1000 * 60 * 60)) / (1000 * 60)); + const seconds = Math.floor((countDown % (1000 * 60)) / 1000); + + return [days, hours, minutes, seconds]; +}; + +const OTPWidget = (props) => { + const OTP_EXIPIRE_MINUTES = 5; + const { + id, + title, + fieldValue, + onChange, + value, + valid, + disabled, + isOnEdit, + formHasErrors, + errorMessage, + path, + block_id, + } = props; + const intl = useIntl(); + const dispatch = useDispatch(); + const _id = id + OTP_FIELDNAME_EXTENDER; + const sendOTPResponse = useSelector( + (state) => state.sendOTP?.subrequests?.[block_id + '_' + fieldValue], + ); + const [countDownEnd, setCountDownEnd] = useState(null); + const [countDown, setCountDown] = useState(null); + + const displayWidget = isValidEmail(fieldValue); + + const sendOTPCode = () => { + dispatch(sendOTP(path, block_id, fieldValue)); + }; + + useEffect(() => { + if (sendOTPResponse?.loaded) { + const end = new Date().getTime() + OTP_EXIPIRE_MINUTES * 60000; + setCountDownEnd(end); + setCountDown(end - new Date().getTime()); + + const interval = setInterval(() => { + setCountDown(countDownEnd - new Date().getTime()); + }, 1000); + + return () => clearInterval(interval); + } else { + setCountDown(null); + setCountDownEnd(null); + } + }, [sendOTPResponse, countDownEnd]); + + return displayWidget ? ( +
+
+
+ + {countDown > 0 && ( +
+ {intl.formatMessage(messages.otp_countdown)}{' '} + {getCountDownValues(countDown) + .filter((v, index) => v > 0 || index === 2 || index === 3) + .map((v) => (v < 10 ? '0' + v : v)) + .join(':')} + . +
+ )} +
+ + +
+ + {sendOTPResponse?.loaded && !sendOTPResponse?.loading && ( +
+ {intl.formatMessage(messages.otp_sent, { email: fieldValue })} +
+ )} + + {sendOTPResponse?.error && ( +
+ {JSON.stringify(sendOTPResponse.error)} +
+ )} +
+ ) : ( + <> + ); +}; + +/** + * Property types + * @property {Object} propTypes Property types. + * @static + */ +OTPWidget.propTypes = { + id: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + description: PropTypes.string, + required: PropTypes.bool, + error: PropTypes.arrayOf(PropTypes.string), + value: PropTypes.string, + onChange: PropTypes.func.isRequired, + onBlur: PropTypes.func, + onClick: PropTypes.func, + minLength: PropTypes.number, + maxLength: PropTypes.number, + placeholder: PropTypes.string, +}; + +/** + * Default properties. + * @property {Object} defaultProps Default properties. + * @static + */ +OTPWidget.defaultProps = { + description: null, + required: false, + error: [], + value: null, + onChange: () => {}, + onBlur: () => {}, + onClick: () => {}, + minLength: null, + maxLength: null, +}; + +export default OTPWidget; diff --git a/src/components/Widget/index.js b/src/components/Widget/index.js index 1b2cb56..a5c031b 100644 --- a/src/components/Widget/index.js +++ b/src/components/Widget/index.js @@ -13,3 +13,6 @@ export { default as RadioWidget } from 'volto-form-block/components/Widget/Radio export { default as SelectWidget } from 'volto-form-block/components/Widget/SelectWidget'; export { default as TextareaWidget } from 'volto-form-block/components/Widget/TextareaWidget'; export { default as TextWidget } from 'volto-form-block/components/Widget/TextWidget'; +export { default as OTPWidget } from 'volto-form-block/components/Widget/OTPWidget'; +export { OTP_FIELDNAME_EXTENDER } from 'volto-form-block/components/Widget/OTPWidget'; +export { default as Button } from 'volto-form-block/components/Widget/Button'; diff --git a/src/index.js b/src/index.js index 07fe390..8b4439d 100644 --- a/src/index.js +++ b/src/index.js @@ -16,6 +16,7 @@ import { getFormData, exportCsvFormData, clearFormData, + sendOTP, } from 'volto-form-block/reducers'; import FormSchema from 'volto-form-block/formSchema'; import FieldSchema from 'volto-form-block/fieldSchema'; @@ -34,6 +35,7 @@ export { submitForm, getFormData, exportCsvFormData, + sendOTP, } from 'volto-form-block/actions'; export { isValidEmail }; @@ -83,13 +85,14 @@ const applyConfig = (config) => { formData: getFormData, exportCsvFormData, clearFormData, + sendOTP, }; - config.settings.loadables['HCaptcha'] = loadable(() => - import('@hcaptcha/react-hcaptcha'), + config.settings.loadables['HCaptcha'] = loadable( + () => import('@hcaptcha/react-hcaptcha'), ); - config.settings.loadables['GoogleReCaptcha'] = loadable.lib(() => - import('react-google-recaptcha-v3'), + config.settings.loadables['GoogleReCaptcha'] = loadable.lib( + () => import('react-google-recaptcha-v3'), ); return config; diff --git a/src/reducers/index.js b/src/reducers/index.js index 4467e1c..1574475 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -7,6 +7,7 @@ import { EXPORT_CSV_FORMDATA, GET_FORM_DATA, CLEAR_FORM_DATA, + SEND_OTP, } from 'volto-form-block/actions'; function download(filename, text) { @@ -95,6 +96,7 @@ export const submitForm = (state = initialState, action = {}) => { ...state.subrequests, [action.subrequest]: { ...(state.subrequests[action.subrequest] || {}), + error: action.error, result: null, loading: false, loaded: false, @@ -226,3 +228,82 @@ export const clearFormData = (state = initialState, action = {}) => { return state; } }; + +/** + * sendOTP reducer. + * @function sendOTP + * @param {Object} state Current state. + * @param {Object} action Action to be handled. + * @returns {Object} New state. + */ +export const sendOTP = (state = initialState, action = {}) => { + switch (action.type) { + case `${SEND_OTP}_PENDING`: + return action.subrequest + ? { + ...state, + subrequests: { + ...state.subrequests, + [action.subrequest]: { + ...(state.subrequests[action.subrequest] || { + items: [], + total: 0, + batching: {}, + }), + error: null, + loaded: false, + loading: true, + }, + }, + } + : { + ...state, + error: null, + loading: true, + loaded: false, + }; + case `${SEND_OTP}_SUCCESS`: + return action.subrequest + ? { + ...state, + subrequests: { + ...state.subrequests, + [action.subrequest]: { + ...(state.subrequests[action.subrequest] || {}), + error: null, + loaded: true, + loading: false, + }, + }, + } + : { + ...state, + error: null, + loaded: true, + loading: false, + }; + case `${SEND_OTP}_FAIL`: + return action.subrequest + ? { + ...state, + subrequests: { + ...state.subrequests, + [action.subrequest]: { + ...(state.subrequests[action.subrequest] || {}), + error: action.error, + loading: false, + loaded: false, + }, + }, + } + : { + ...state, + error: action.error, + loading: false, + loaded: false, + }; + + default: + return state; + } +};