From d188c16e755b7818e0adba59a73678a26b01d6a7 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 23 Feb 2021 16:33:34 +0200 Subject: [PATCH 1/7] Add hCaptcha dependencies --- package.json | 2 ++ yarn.lock | 12 ++++++++++++ 2 files changed, 14 insertions(+) diff --git a/package.json b/package.json index 2ed306f5..d7fe05a1 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@fortawesome/free-brands-svg-icons": "5.15.2", "@fortawesome/free-solid-svg-icons": "5.15.2", "@fortawesome/react-fontawesome": "0.1.14", + "@hcaptcha/react-hcaptcha": "^0.3.2", "@sentry/react": "6.2.0", "@svgr/webpack": "5.5.0", "@swc/core": "1.2.47", @@ -57,6 +58,7 @@ "@testing-library/jest-dom": "5.11.9", "@testing-library/react": "11.2.5", "@testing-library/user-event": "12.7.2", + "@types/hcaptcha__react-hcaptcha": "^0.1.4", "@types/jest": "26.0.20", "@types/node": "14.14.31", "@types/react": "17.0.1", diff --git a/yarn.lock b/yarn.lock index e3f7e1de..81fe8ec5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1296,6 +1296,11 @@ dependencies: "@hapi/hoek" "^8.3.0" +"@hcaptcha/react-hcaptcha@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-0.3.2.tgz#8910ea4c111799336fb64de6aa7b74329a7d7579" + integrity sha512-+90hSDwtnKAk3PXJsyABi+wRHS1B+wgWjDO4nz68KpkLnE73rMz/XMdl+ckrwYkFFilzIDKI3o1IqOpMapEwgg== + "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" @@ -2011,6 +2016,13 @@ dependencies: "@types/node" "*" +"@types/hcaptcha__react-hcaptcha@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@types/hcaptcha__react-hcaptcha/-/hcaptcha__react-hcaptcha-0.1.4.tgz#145cab4f0ac29fe8925dc98ab16cf2dffacad7d5" + integrity sha512-eqEIBR7yn4Y1fRtxPnFlEP8SAHwX762Z27s/ifd5wfJicviz6HynF8gHCgUPPtfYlaQFHa/A0NkwBA5YNmNCmQ== + dependencies: + "@types/react" "*" + "@types/history@*": version "4.7.8" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.8.tgz#49348387983075705fe8f4e02fb67f7daaec4934" From 4042010ea4463518cbb26ab81c993ad7447d6317 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 23 Feb 2021 16:35:16 +0200 Subject: [PATCH 2/7] Add hCaptcha sitekey environment variable to webpack config --- webpack.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index 35c90a74..70c2ae99 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -93,7 +93,8 @@ module.exports = { REACT_APP_SENTRY_DSN: "https://false@notreal.ingest.sentry.io/1234", REACT_APP_OAUTH2_CLIENT_ID: "0", BACKEND_URL: "https://forms-api.pythondiscord.com/", - CONTEXT: "development" + CONTEXT: "development", + HCAPTCHA_SITEKEY: "10000000-ffff-ffff-ffff-000000000001" }), new HtmlWebpackPlugin({ inject: true, template: 'public/index.html' From d7a09635fd800af0f3d67a48063d5ac6729b230a Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 23 Feb 2021 16:38:24 +0200 Subject: [PATCH 3/7] Implement hCaptcha to form page --- src/pages/FormPage.tsx | 50 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 1e331b96..9bd90d30 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -2,7 +2,8 @@ import { jsx, css } from "@emotion/react"; import { Link } from "react-router-dom"; -import React, { SyntheticEvent, useEffect, useState, createRef } from "react"; +import HCaptcha from "@hcaptcha/react-hcaptcha"; +import React, {SyntheticEvent, useEffect, useState, createRef, useRef} from "react"; import { useParams } from "react-router"; import { PropagateLoader } from "react-spinners"; @@ -154,6 +155,14 @@ const closedHeaderStyles = css` } `; +const captchaStyles = css` + text-align: center; + + @media (max-width: 850px) { + padding: 1.2rem; + } +`; + function FormPage(): JSX.Element { const { id } = useParams(); @@ -161,6 +170,9 @@ function FormPage(): JSX.Element { const [sending, setSending] = useState(); const [sent, setSent] = useState(); + let captchaToken: string | null = null; + const captchaRef = useRef(null); + useEffect(() => { getForm(id).then(form => { setForm(form); @@ -208,6 +220,9 @@ function FormPage(): JSX.Element { async function handleSubmit(event: SyntheticEvent) { event.preventDefault(); + // Make copy to avoid losing value on state change. + const submitCaptchaToken = captchaToken; + // Client-side required validation const invalidFieldIDs: number[] = []; questions.forEach((prop, i) => { @@ -242,6 +257,11 @@ function FormPage(): JSX.Element { return; } + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (!(FormFeatures.DisableAntispam in form!.features) && !submitCaptchaToken && captchaRef && captchaRef.current) { + captchaRef.current.execute(); + } + setSending(true); const answers: { [key: string]: unknown } = {}; @@ -276,7 +296,13 @@ function FormPage(): JSX.Element { } }); - await ApiClient.post(`forms/submit/${id}`, {response: answers}); + const data: { [key: string]: unknown } = {response: answers}; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (!(FormFeatures.DisableAntispam in form!.features)) { + data["captcha"] = submitCaptchaToken; + } + + await ApiClient.post(`forms/submit/${id}`, data); setSending(false); setSent(true); } @@ -288,6 +314,25 @@ function FormPage(): JSX.Element { closed_header =
This form is now closed. You will not be able to submit your response.
; } + let captcha = null; + if (!(FormFeatures.DisableAntispam in form.features)) { + captcha = ( +
+ { + captchaToken = token; + }} + onExpire={() => { + captchaToken = null; + }} + ref={captchaRef} + /> +
+ ); + } + return (
@@ -296,6 +341,7 @@ function FormPage(): JSX.Element {
{ closed_header } { questions } + { captcha }
From 06727e0e1a4cbe4d170e96a338ff7462ca0dd8ba Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 23 Feb 2021 16:46:21 +0200 Subject: [PATCH 4/7] Lock yarn hcaptcha dependencies versions --- package.json | 4 ++-- yarn.lock | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d7fe05a1..41bc9039 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "@fortawesome/free-brands-svg-icons": "5.15.2", "@fortawesome/free-solid-svg-icons": "5.15.2", "@fortawesome/react-fontawesome": "0.1.14", - "@hcaptcha/react-hcaptcha": "^0.3.2", + "@hcaptcha/react-hcaptcha": "0.3.2", "@sentry/react": "6.2.0", "@svgr/webpack": "5.5.0", "@swc/core": "1.2.47", @@ -58,7 +58,7 @@ "@testing-library/jest-dom": "5.11.9", "@testing-library/react": "11.2.5", "@testing-library/user-event": "12.7.2", - "@types/hcaptcha__react-hcaptcha": "^0.1.4", + "@types/hcaptcha__react-hcaptcha": "0.1.4", "@types/jest": "26.0.20", "@types/node": "14.14.31", "@types/react": "17.0.1", diff --git a/yarn.lock b/yarn.lock index 81fe8ec5..ee145909 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1296,7 +1296,7 @@ dependencies: "@hapi/hoek" "^8.3.0" -"@hcaptcha/react-hcaptcha@^0.3.2": +"@hcaptcha/react-hcaptcha@0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@hcaptcha/react-hcaptcha/-/react-hcaptcha-0.3.2.tgz#8910ea4c111799336fb64de6aa7b74329a7d7579" integrity sha512-+90hSDwtnKAk3PXJsyABi+wRHS1B+wgWjDO4nz68KpkLnE73rMz/XMdl+ckrwYkFFilzIDKI3o1IqOpMapEwgg== @@ -2016,7 +2016,7 @@ dependencies: "@types/node" "*" -"@types/hcaptcha__react-hcaptcha@^0.1.4": +"@types/hcaptcha__react-hcaptcha@0.1.4": version "0.1.4" resolved "https://registry.yarnpkg.com/@types/hcaptcha__react-hcaptcha/-/hcaptcha__react-hcaptcha-0.1.4.tgz#145cab4f0ac29fe8925dc98ab16cf2dffacad7d5" integrity sha512-eqEIBR7yn4Y1fRtxPnFlEP8SAHwX762Z27s/ifd5wfJicviz6HynF8gHCgUPPtfYlaQFHa/A0NkwBA5YNmNCmQ== From 66650fed4ab97448c0c2341f002cc47544dc26b2 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 23 Feb 2021 16:57:24 +0200 Subject: [PATCH 5/7] Move captcha to outside of form --- src/pages/FormPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 9bd90d30..72049bb7 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -341,8 +341,8 @@ function FormPage(): JSX.Element {
{ closed_header } { questions } - { captcha }
+ { captcha } From 740348f12e4606844aa451a9b6f9b54724ff8192 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Tue, 23 Feb 2021 16:58:29 +0200 Subject: [PATCH 6/7] Don't render captcha in closed forms --- src/pages/FormPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 72049bb7..9abb4353 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -315,7 +315,7 @@ function FormPage(): JSX.Element { } let captcha = null; - if (!(FormFeatures.DisableAntispam in form.features)) { + if (!(FormFeatures.DisableAntispam in form.features) && open) { captcha = (
Date: Tue, 23 Feb 2021 17:00:15 +0200 Subject: [PATCH 7/7] Add margin to bottom of captcha --- src/pages/FormPage.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/pages/FormPage.tsx b/src/pages/FormPage.tsx index 9abb4353..9ac26f11 100644 --- a/src/pages/FormPage.tsx +++ b/src/pages/FormPage.tsx @@ -158,9 +158,7 @@ const closedHeaderStyles = css` const captchaStyles = css` text-align: center; - @media (max-width: 850px) { - padding: 1.2rem; - } + margin-bottom: 1.5rem; `; function FormPage(): JSX.Element {