diff --git a/Changelog.md b/Changelog.md index 756652c376..08a8ca1701 100644 --- a/Changelog.md +++ b/Changelog.md @@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - FIO 7603: fixed Edit Grid With Empty Rows Not Submitting Form - FIO-7445: fixed an issue where the interpolated data does not show up on PDF - FIO-7421: Adds ReCaptcha error messages to the translations config + - FIO-7804: Added PKCE method for OIDC ## 5.0.0-rc.37 ### Fixed diff --git a/package.json b/package.json index c75ff80f46..577aa00964 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "jwt-decode": "^3.1.2", "lodash": "^4.17.21", "moment": "^2.29.4", - "moment-timezone": "^0.5.43", + "moment-timezone": "^0.5.44", "quill": "^2.0.0-dev.3", "signature_pad": "^4.1.4", "string-hash": "^1.1.3", diff --git a/src/components/button/Button.js b/src/components/button/Button.js index 8c9896d196..8bfa069245 100644 --- a/src/components/button/Button.js +++ b/src/components/button/Button.js @@ -402,9 +402,16 @@ export default class ButtonComponent extends Field { response_type: 'code', client_id: settings.clientId, redirect_uri: (settings.redirectURI && this.interpolate(settings.redirectURI)) || window.location.origin || `${window.location.protocol}//${window.location.host}`, - state: settings.state, scope: settings.scope }; + if (settings.state) { + params.state = settings.state; + } + else if (settings.code_challenge) { + params.code_challenge = settings.code_challenge; + params.code_challenge_method = 'S256'; + } + /*eslint-enable camelcase */ // Needs for the correct redirection URI for the OpenID 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) { diff --git a/yarn.lock b/yarn.lock index 5cf57b0fc2..a44c6135bc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -545,9 +545,9 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/node@*", "@types/node@>=10.0.0": - version "20.11.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.19.tgz#b466de054e9cb5b3831bee38938de64ac7f81195" - integrity sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ== + version "20.11.20" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.20.tgz#f0a2aee575215149a62784210ad88b3a34843659" + integrity sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg== dependencies: undici-types "~5.26.4" @@ -2626,9 +2626,9 @@ ejs-loader@^0.5.0: lodash "^4.17.15" electron-to-chromium@^1.4.668: - version "1.4.679" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.679.tgz#480f497874ce2be162c0ac271eec91918bf96247" - integrity sha512-NhQMsz5k0d6m9z3qAxnsOR/ebal4NAGsrNVRwcDo4Kc/zQ7KdsTKZUxZoygHcVRb0QDW3waEDIcE3isZ79RP6g== + version "1.4.680" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.680.tgz#18a30d3f557993eda2d5b1e21a06c4d51875392f" + integrity sha512-4nToZ5jlPO14W82NkF32wyjhYqQByVaDmLy4J2/tYcAbJfgO2TKJC780Az1V13gzq4l73CJ0yuyalpXvxXXD9A== emoji-regex@^7.0.1: version "7.0.3" @@ -5618,7 +5618,7 @@ mock-local-storage@^1.1.24: core-js "^3.30.2" global "^4.3.2" -moment-timezone@^0.5.43: +moment-timezone@^0.5.44: version "0.5.45" resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.45.tgz#cb685acd56bac10e69d93c536366eb65aa6bcf5c" integrity sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==