From a69c3ef669c92395a092716dc310e7d30e01b7fd Mon Sep 17 00:00:00 2001 From: martapanc Date: Fri, 16 Feb 2024 21:29:48 +0100 Subject: [PATCH] feat: setup ReCaptcha API endpoint --- .../molecules/ContactForm/ContactForm.tsx | 35 ++++++++-------- src/lib/verifyCaptcha.ts | 41 ------------------- src/pages/api/recaptcha.ts | 36 ++++++++++++++++ 3 files changed, 54 insertions(+), 58 deletions(-) delete mode 100644 src/lib/verifyCaptcha.ts create mode 100644 src/pages/api/recaptcha.ts diff --git a/src/components/molecules/ContactForm/ContactForm.tsx b/src/components/molecules/ContactForm/ContactForm.tsx index 3520b97..3ee4c87 100644 --- a/src/components/molecules/ContactForm/ContactForm.tsx +++ b/src/components/molecules/ContactForm/ContactForm.tsx @@ -6,18 +6,12 @@ import ReCAPTCHA from 'react-google-recaptcha'; import { Trans, useTranslation } from 'react-i18next'; import * as Yup from 'yup'; -import { verifyCaptcha } from '@/lib/verifyCaptcha'; - import Button from '@/components/atoms/buttons/Button'; import { Input } from './Input'; import { Select } from './Select'; import { TextArea } from './TextArea'; -export interface ContactFormProps { - subjects: Subject[]; -} - export interface Subject { key: string; value: string; @@ -33,17 +27,24 @@ const ContactForm = () => { const reCaptchaSiteKey = '6LcSyzAoAAAAAC7JTJ6gtOWW3cjTK_vKRm2WjEtC'; async function handleCaptchaSubmission(token: string | null) { - // Server function to verify captcha - await verifyCaptcha(token) - .then(() => { - setIsVerified(true); - }) - .catch((err) => { - // eslint-disable-next-line no-console - console.log(err); - setIsVerified(false); - setError(true); - }); + const res = await fetch('/api/recaptcha', { + body: JSON.stringify({ token }), + headers: { + 'Content-Type': 'application/json', + }, + method: 'POST', + }); + + const { success, error } = await res.json(); + + if (success) { + setIsVerified(true); + } else { + setIsVerified(false); + setError(true); + // eslint-disable-next-line no-console + console.error(error); + } } useEffect(() => {}, [isVerified]); diff --git a/src/lib/verifyCaptcha.ts b/src/lib/verifyCaptcha.ts deleted file mode 100644 index 79ea8e2..0000000 --- a/src/lib/verifyCaptcha.ts +++ /dev/null @@ -1,41 +0,0 @@ -export interface ReCaptchaResp { - success: boolean; - challenge_ts?: string; - hostname?: string; -} - -export async function verifyCaptcha(token: string | null) { - const key = process.env.NEXT_PUBLIC_RECAPTCHA_KEY as string; - - if (!key) { - throw new Error('Error retrieving reCaptcha secret key.'); - } - - if (token === null) { - throw new Error('reCaptcha Token is null'); - } - - const url = 'https://www.google.com/recaptcha/api/siteverify'; - - const response = await fetch(url, { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: `secret=${key}&response=${token}`, - }); - - if (!response.ok) { - throw new Error('Failed to verify reCAPTCHA: ' + (await response.json())); - } - - const data = await response.json(); - - const reCaptchaResp: ReCaptchaResp = { - success: data.success, - challenge_ts: data['challenge_ts'], - hostname: data['hostname'], - }; - - return reCaptchaResp; -} diff --git a/src/pages/api/recaptcha.ts b/src/pages/api/recaptcha.ts new file mode 100644 index 0000000..8fc9be3 --- /dev/null +++ b/src/pages/api/recaptcha.ts @@ -0,0 +1,36 @@ +import { NextApiRequest, NextApiResponse } from 'next'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + const { token } = req.body; + + if (!token) { + return res.status(400).json({ error: 'Error providing ReCaptcha token' }); + } + + const key = process.env.RECAPTCHA_SECRET_KEY; + + if (!key) { + return res + .status(500) + .json({ error: 'Error retrieving reCaptcha secret key.' }); + } + + const url = 'https://www.google.com/recaptcha/api/siteverify'; + + const response = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: `secret=${key}&response=${token}`, + }); + + if (!response.ok) { + return res.status(500).json({ error: 'Error verifying reCaptcha.' }); + } + + return res.status(200).json({ success: 'Verified' }); +}