Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WSJ-503: Upgrade foia request form to google recaptcha v3. #2066

Merged
merged 2 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions js/components/foia_request_form.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, { useRef, useState, useEffect } from 'react';
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
import { Map } from 'immutable';
import CustomFieldTemplate from 'components/request_custom_field_template';
import USWDSRadioWidget from 'components/uswds_radio_widget';
import USWDSCheckboxWidget from 'components/uswds_checkbox_widget';
import ReCAPTCHA from 'react-google-recaptcha';
import { GoogleReCaptchaProvider, GoogleReCaptcha } from 'react-google-recaptcha-v3'; // Import v3 hook
import { requestActions } from '../actions';
import { SubmissionResult } from '../models';
import CustomObjectFieldTemplate from './object_field_template';
Expand All @@ -20,17 +20,21 @@ import dispatcher from '../util/dispatcher';
function FoiaRequestForm({
formData, upload, onSubmit, requestForm, submissionResult,
}) {
const recaptchaRef = useRef();

const [settingsdata, setData] = useState(null);
const [settingsdata, setSettingsdata] = useState(null);
const [token, setToken] = useState('');
const [refreshReCaptcha, setRefreshReCaptcha] = useState(false);

useEffect(() => {
fetch('/files/settings.json')
.then((response) => response.json())
.then((result) => setData(result))
.then((result) => setSettingsdata(result))
.catch((error) => console.error('Error fetching recaptcha site key:', error));
}, []);

const setTokenFunc = (getToken) => {
setToken(getToken);
};

// Helper function to jump to the first form error.
function focusOnFirstError() {
const fieldErrors = document.getElementsByClassName('usa-input-error');
Expand All @@ -57,6 +61,7 @@ function FoiaRequestForm({

// Listen for jsonSchema validation errors and jump to them.
function onError() {
setRefreshReCaptcha(!refreshReCaptcha);
focusOnFirstError();
}

Expand All @@ -74,12 +79,8 @@ function FoiaRequestForm({
}

function onFormSubmit({ formData: data }) {
const recaptchaValue = recaptchaRef.current.getValue();
// Now you can use the recaptchaValue for your form submission

// TODO - probably not needed -- remove ?
// The captcha field is added to the Expedited Processing section.
data.expedited_processing.captcha = recaptchaValue;
// Now you can use the recaptcha token for your form submission
data.expedited_processing.captcha = token;

// Merge the sections into a single payload
const payload = rf.mergeSectionFormData(data);
Expand Down Expand Up @@ -160,25 +161,28 @@ function FoiaRequestForm({
using the contact information provided to you on this site.
</p>
</div>
{ /* eslint-disable-next-line no-nested-ternary */ }
{upload.get('inProgress')
? (
<UploadProgress
progressTotal={upload.get('progressTotal')}
progressLoaded={upload.get('progressLoaded')}
/>
)
: (
<div style={{ marginTop: '2em' }}>
{settingsdata && settingsdata.RECAPTCHA_SITE_KEY
? <ReCAPTCHA ref={recaptchaRef} sitekey={settingsdata.RECAPTCHA_SITE_KEY} /> : <p>Inavlid Site Key</p>}
<button
className="usa-button usa-button-big usa-button-primary-alt"
type="submit"
>
Submit request
</button>
</div>
)}
: settingsdata && settingsdata.RECAPTCHA_SITE_KEY
? (
<GoogleReCaptchaProvider reCaptchaKey={settingsdata.RECAPTCHA_SITE_KEY}>
<GoogleReCaptcha
className="google-recaptcha-custom-class"
onVerify={setTokenFunc}
refreshReCaptcha={refreshReCaptcha}
/>
<div style={{ marginTop: '2em' }} />
<button className="usa-button usa-button-big usa-button-primary-alt" type="submit">
Submit request
</button>
</GoogleReCaptchaProvider>
) : (<p>Invalid key</p>)}
{submissionResult.errorMessage
&& (
<p>
Expand Down
49 changes: 13 additions & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"prop-types": "15.x",
"react": "17.x",
"react-dom": "17.x",
"react-google-recaptcha": "^3.1.0",
"react-google-recaptcha-v3": "^1.10.1",
"react-modal": "3.x",
"react-router-dom": "5.x",
"swagger-ui": "^3.52.5",
Expand Down