summaryrefslogtreecommitdiff
path: root/addons/website_form/static/src
diff options
context:
space:
mode:
authorfja-odoo <fja@odoo.com>2020-04-24 10:50:28 +0000
committerfja-odoo <fja@odoo.com>2020-06-05 10:58:50 +0000
commit541148613451f4c14a299672d91c4397d8a9f6de (patch)
treec798cd359c3960d4ae86ebc9847666a3a30bf4a6 /addons/website_form/static/src
parentfea1706f275e88a0d28dd2776c6aa0dd62c1bf3d (diff)
[IMP] google_recaptcha, *: integrate recaptchaV3
* = base_setup, website_form, website_sale, website_crm, crm_iap_lead_website, website_hr_recruitment, website_mass_mailing Integrate reCaptchaV3 on website_form submit and website_mass_mailing subscription. You can now use ReCaptchaV3 to add reCaptcha verification in any module using google_recaptcha. Also added a better error management on the form with custom messages. task-2217980 closes odoo/odoo#48466 Related: odoo/enterprise#9649 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
Diffstat (limited to 'addons/website_form/static/src')
-rw-r--r--addons/website_form/static/src/snippets/s_website_form/000.js34
-rw-r--r--addons/website_form/static/src/snippets/s_website_form/001.scss10
-rw-r--r--addons/website_form/static/src/snippets/s_website_form/options.js31
-rw-r--r--addons/website_form/static/src/xml/website_form.xml10
-rw-r--r--addons/website_form/static/src/xml/website_form_editor.xml9
5 files changed, 70 insertions, 24 deletions
diff --git a/addons/website_form/static/src/snippets/s_website_form/000.js b/addons/website_form/static/src/snippets/s_website_form/000.js
index 4d08906c6b5..b06a9b62a74 100644
--- a/addons/website_form/static/src/snippets/s_website_form/000.js
+++ b/addons/website_form/static/src/snippets/s_website_form/000.js
@@ -3,6 +3,7 @@ odoo.define('website_form.s_website_form', function (require) {
var core = require('web.core');
var time = require('web.time');
+ const {ReCaptcha} = require('google_recaptcha.ReCaptchaV3');
var ajax = require('web.ajax');
var publicWidget = require('web.public.widget');
@@ -21,11 +22,19 @@ odoo.define('website_form.s_website_form', function (require) {
*/
init: function () {
this._super(...arguments);
+ this._recaptcha = new ReCaptcha();
this.__started = new Promise(resolve => this.__startResolve = resolve);
},
-
+ willStart: function () {
+ const res = this._super(...arguments);
+ if (!this.$target[0].classList.contains('s_website_form_no_recaptcha')) {
+ this._recaptcha.loadLibs();
+ }
+ return res;
+ },
start: function () {
var self = this;
+
// Initialize datetimepickers
var datepickers_options = {
minDate: moment({y: 1900}),
@@ -86,7 +95,7 @@ odoo.define('website_form.s_website_form', function (require) {
this.$target.parent().find('.s_website_form_end_message').addClass('d-none');
},
- send: function (e) {
+ send: async function (e) {
e.preventDefault(); // Prevent the default submit behavior
// Prevent users from crazy clicking
this.$target.find('.s_website_form_send, .o_website_form_send').addClass('disabled'); // !compatibility
@@ -95,7 +104,7 @@ odoo.define('website_form.s_website_form', function (require) {
self.$target.find('#s_website_form_result, #o_website_form_result').empty(); // !compatibility
if (!self.check_error_fields({})) {
- self.update_status('invalid');
+ self.update_status('error', _t("Please fill in the form correctly."));
return false;
}
@@ -132,6 +141,13 @@ odoo.define('website_form.s_website_form', function (require) {
}
});
+ const tokenObj = await this._recaptcha.getToken('website_form');
+ if (tokenObj.token) {
+ form_values['recaptcha_token_response'] = tokenObj.token;
+ } else if (tokenObj.error) {
+ self.update_status('error', tokenObj.error);
+ return false;
+ }
// Post form and handle result
ajax.post(this.$target.attr('action') + (this.$target.data('force_action') || this.$target.data('model_name')), form_values)
.then(function (result_data) {
@@ -140,7 +156,7 @@ odoo.define('website_form.s_website_form', function (require) {
result_data = JSON.parse(result_data);
if (!result_data.id) {
// Failure, the server didn't return the created record ID
- self.update_status('error');
+ self.update_status('error', result_data.error ? result_data.error : false);
if (result_data.error_fields) {
// If the server return a list of bad fields, show these fields for users
self.check_error_fields(result_data.error_fields);
@@ -265,17 +281,23 @@ odoo.define('website_form.s_website_form', function (require) {
return value;
},
- update_status: function (status) {
+ update_status: function (status, message) {
if (status !== 'success') { // Restore send button behavior if result is an error
this.$target.find('.s_website_form_send, .o_website_form_send').removeClass('disabled'); // !compatibility
}
var $result = this.$('#s_website_form_result, #o_website_form_result'); // !compatibility
+ if (status === 'error' && !message) {
+ message = _t("An error has occured, the form has not been sent.");
+ }
+
// Note: we still need to wait that the widget is properly started
// before any qweb rendering which depends on xmlDependencies
// because the event handlers are binded before the call to
// willStart for public widgets...
- this.__started.then(() => $result.replaceWith(qweb.render(`website_form.status_${status}`)));
+ this.__started.then(() => $result.replaceWith(qweb.render(`website_form.status_${status}`, {
+ message: message,
+ })));
},
});
});
diff --git a/addons/website_form/static/src/snippets/s_website_form/001.scss b/addons/website_form/static/src/snippets/s_website_form/001.scss
index acfaae6f5a1..375a4bb5fe0 100644
--- a/addons/website_form/static/src/snippets/s_website_form/001.scss
+++ b/addons/website_form/static/src/snippets/s_website_form/001.scss
@@ -43,15 +43,15 @@
padding-bottom: 0.5rem;
}
- .s_website_form_submit {
+ .s_website_form_submit, .s_website_form_recaptcha {
.s_website_form_label {
float: left;
height: 1px;
}
- &.s_website_form_no_submit_label {
- .s_website_form_label {
- display: none;
- }
+ }
+ .s_website_form_no_submit_label {
+ .s_website_form_label {
+ display: none;
}
}
}
diff --git a/addons/website_form/static/src/snippets/s_website_form/options.js b/addons/website_form/static/src/snippets/s_website_form/options.js
index f21f3e11ef2..582791f381f 100644
--- a/addons/website_form/static/src/snippets/s_website_form/options.js
+++ b/addons/website_form/static/src/snippets/s_website_form/options.js
@@ -9,7 +9,10 @@ const qweb = core.qweb;
const _t = core._t;
const FormEditor = options.Class.extend({
- xmlDependencies: ['/website_form/static/src/xml/website_form_editor.xml'],
+ xmlDependencies: [
+ '/website_form/static/src/xml/website_form_editor.xml',
+ '/google_recaptcha/static/src/xml/recaptcha.xml',
+ ],
//----------------------------------------------------------------------
// Private
@@ -340,8 +343,8 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
const proms = [this._super(...arguments)];
// Disable text edition
this.$target.attr('contentEditable', false);
- // Make button editable
- this.$target.find('.s_website_form_send').attr('contentEditable', true);
+ // Make button and recaptcha editable
+ this.$target.find('.s_website_form_send, .s_website_form_recaptcha').attr('contentEditable', true);
// Get potential message
this.$message = this.$target.parent().find('.s_website_form_end_message');
this.showEndMessage = false;
@@ -479,6 +482,22 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
this.$target[0].dataset.mark = value.trim();
this._setLabelsMark();
},
+ /**
+ * Toggle the recaptcha legal terms
+ */
+ toggleRecaptchaLegal: function (previewMode, value, params) {
+ const recaptchaLegalEl = this.$target[0].querySelector('.s_website_form_recaptcha');
+ if (recaptchaLegalEl) {
+ recaptchaLegalEl.remove();
+ } else {
+ const template = document.createElement('template');
+ const labelWidth = this.$target[0].querySelector('.s_website_form_label').style.width;
+ template.innerHTML = qweb.render("webite_form.s_website_form_recaptcha_legal", {labelWidth: labelWidth});
+ const legal = template.content.firstElementChild;
+ legal.setAttribute('contentEditable', true);
+ this.$target.find('.s_website_form_submit').before(legal);
+ }
+ },
//--------------------------------------------------------------------------
// Private
@@ -503,6 +522,8 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
return this.$target[0].dataset.successMode;
case 'setMark':
return this._getMark();
+ case 'toggleRecaptchaLegal':
+ return !this.$target[0].querySelector('.s_website_form_recaptcha') || '';
}
return this._super(...arguments);
},
@@ -643,7 +664,7 @@ options.registry.WebsiteFormEditor = FormEditor.extend({
await formInfo.formFields.forEach(async field => {
field.formatInfo = formatInfo;
await this._fetchFieldRecords(field);
- this.$target.find('.s_website_form_submit').before(this._renderField(field));
+ this.$target.find('.s_website_form_submit, .s_website_form_recaptcha').first().before(this._renderField(field));
});
}
},
@@ -1219,7 +1240,7 @@ options.registry.AddFieldForm = FormEditor.extend({
const field = this._getCustomField('char', 'Custom Text');
field.formatInfo = this._getDefaultFormat();
const htmlField = this._renderField(field);
- this.$target.find('.s_website_form_submit').before(htmlField);
+ this.$target.find('.s_website_form_submit, .s_website_form_recaptcha').first().before(htmlField);
this.trigger_up('activate_snippet', {
$snippet: $(htmlField),
});
diff --git a/addons/website_form/static/src/xml/website_form.xml b/addons/website_form/static/src/xml/website_form.xml
index 5403f763e24..9c1390c74df 100644
--- a/addons/website_form/static/src/xml/website_form.xml
+++ b/addons/website_form/static/src/xml/website_form.xml
@@ -8,17 +8,11 @@
</span>
</t>
- <!-- Missing field status -->
- <t t-name="website_form.status_invalid">
- <span id="s_website_form_result" class="text-danger ml8">
- <i class="fa fa-close mr4" role="img" aria-label="Error" title="Error"/>Please fill in the form correctly.
- </span>
- </t>
-
<!-- Error status -->
<t t-name="website_form.status_error">
<span id="s_website_form_result" class="text-danger ml8">
- <i class="fa fa-close mr4" role="img" aria-label="Error" title="Error"/>An error has occured, the form has not been sent.
+ <i class="fa fa-close mr4" role="img" aria-label="Error" title="Error"/>
+ <t t-esc="message"/>
</span>
</t>
</templates>
diff --git a/addons/website_form/static/src/xml/website_form_editor.xml b/addons/website_form/static/src/xml/website_form_editor.xml
index 6db59f01a22..13d4ae1aeb5 100644
--- a/addons/website_form/static/src/xml/website_form_editor.xml
+++ b/addons/website_form/static/src/xml/website_form_editor.xml
@@ -21,6 +21,15 @@
</div>
</t>
+ <t t-name="webite_form.s_website_form_recaptcha_legal">
+ <div class="col-12 s_website_form_recaptcha" data-name="Recaptcha Legal">
+ <div t-attf-style="width: #{labelWidth or '200px'}" class="s_website_form_label"/>
+ <div class="col-sm">
+ <t t-call="google_recaptcha.recaptcha_legal_terms"/>
+ </div>
+ </div>
+ </t>
+
<!-- Generic Field Layout -->
<!-- Changes made here needs to be reflected in the different Form view (Contact Us, Jobs, ...) -->
<t t-name="website_form.field">