From 14ae76540920995652ef711abddc34015025c022 Mon Sep 17 00:00:00 2001 From: Brendan Bond Date: Tue, 5 Mar 2024 13:35:51 -0600 Subject: [PATCH] FIO-7998: refactor recaptcha validation (#5528) * refactor recaptcha * minor --- src/components/recaptcha/ReCaptcha.js | 69 +++++++++++---------------- 1 file changed, 29 insertions(+), 40 deletions(-) diff --git a/src/components/recaptcha/ReCaptcha.js b/src/components/recaptcha/ReCaptcha.js index cc553e46f9..bf862d68bc 100644 --- a/src/components/recaptcha/ReCaptcha.js +++ b/src/components/recaptcha/ReCaptcha.js @@ -63,7 +63,7 @@ export default class ReCaptchaComponent extends Component { return true; } - verify(actionName) { + async verify(actionName) { const siteKey = _get(this.root.form, 'settings.recaptcha.siteKey'); if (!siteKey) { console.warn('There is no Site Key specified in settings in form JSON'); @@ -73,40 +73,34 @@ export default class ReCaptchaComponent extends Component { const recaptchaApiScriptUrl = `https://www.google.com/recaptcha/api.js?render=${_get(this.root.form, 'settings.recaptcha.siteKey')}`; this.recaptchaApiReady = Formio.requireLibrary('googleRecaptcha', 'grecaptcha', recaptchaApiScriptUrl, true); } - if (this.recaptchaApiReady) { + try { + await this.recaptchaApiReady; this.recaptchaVerifiedPromise = new Promise((resolve, reject) => { - this.recaptchaApiReady - .then(() => { - if (!this.isLoading) { - this.isLoading= true; - grecaptcha.ready(_debounce(() => { - grecaptcha - .execute(siteKey, { - action: actionName - }) - .then((token) => { - return this.sendVerificationRequest(token).then(({ verificationResult, token }) => { - this.recaptchaResult = { - ...verificationResult, - token, - }; - this.updateValue(this.recaptchaResult); - return resolve(verificationResult); - }); - }) - .catch(() => { - this.isLoading = false; - }); - }, 1000)); + if (!this.isLoading) { + this.isLoading= true; + grecaptcha.ready(_debounce(async() => { + try { + const token = await grecaptcha.execute(siteKey, { action: actionName }); + const verificationResult = await this.sendVerificationRequest(token); + this.recaptchaResult = { + ...verificationResult, + token, + }; + this.updateValue(this.recaptchaResult); + this.isLoading = false; + return resolve(verificationResult); } - }) - .catch(() => { - return reject(); - }); - }).then(() => { - this.isLoading = false; + catch (err) { + this.isLoading = false; + reject(err); + } + }, 1000)); + } }); } + catch (err) { + this.loading = false; + } } beforeSubmit() { @@ -118,8 +112,7 @@ export default class ReCaptchaComponent extends Component { } sendVerificationRequest(token) { - return Formio.makeStaticRequest(`${Formio.projectUrl}/recaptcha?recaptchaToken=${token}`) - .then((verificationResult) => ({ verificationResult, token })); + return Formio.makeStaticRequest(`${Formio.projectUrl}/recaptcha?recaptchaToken=${token}`); } checkComponentValidity(data, dirty, row, options = {}) { @@ -127,7 +120,7 @@ export default class ReCaptchaComponent extends Component { row = row || this.data; const { async = false } = options; - // Verification could be async only + // Verification could be async only (which for now is only the case for server-side validation) if (!async) { return super.checkComponentValidity(data, dirty, row, options); } @@ -143,12 +136,8 @@ export default class ReCaptchaComponent extends Component { return Promise.resolve(false); } - return this.hook('validateReCaptcha', componentData.token, () => Promise.resolve(true)) - .then((success) => success) - .catch((err) => { - this.setCustomValidity(this.t(err.message || err)); - return false; - }); + // Any further validation will 100% not run on the client + return Promise.resolve(true); } normalizeValue(newValue) {