Skip to content

Commit 67ab15b

Browse files
authored
Merge pull request #2069 from rgristroph-usdoj/WS-503-recaptchv3
WS-503: Reworking the way Google ReCaptcha is called
2 parents b0123fd + 2b3b18c commit 67ab15b

File tree

1 file changed

+103
-45
lines changed

1 file changed

+103
-45
lines changed

js/components/foia_request_form.jsx

+103-45
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,10 @@ import { scrollOffset } from '../util/dom';
1818
import dispatcher from '../util/dispatcher';
1919

2020
function FoiaRequestForm({
21-
formData, upload, onSubmit, requestForm, submissionResult,
21+
formData, upload, onSubmit, requestForm, submissionResult, refreshReCaptcha, setRefreshReCaptcha, token, setTokenFunc,
2222
}) {
23-
const [settingsdata, setSettingsdata] = useState(null);
24-
const [token, setToken] = useState('');
25-
const [refreshReCaptcha, setRefreshReCaptcha] = useState(false);
2623
const { executeRecaptcha } = useGoogleReCaptcha();
2724

28-
const setTokenFunc = (getToken) => {
29-
setToken(getToken);
30-
};
31-
3225
const handleReCaptchaVerify = useCallback(async () => {
3326
if (!executeRecaptcha) {
3427
console.log('Execute recaptcha not yet available');
@@ -39,15 +32,11 @@ function FoiaRequestForm({
3932
setTokenFunc(newtoken);
4033
console.log('newtoken:');
4134
console.log(newtoken);
42-
}, [executeRecaptcha]);
35+
}, []);
4336

4437
useEffect(() => {
45-
fetch('/files/settings.json')
46-
.then((response) => response.json())
47-
.then((result) => setSettingsdata(result))
48-
.catch((error) => console.error('Error fetching recaptcha site key:', error));
4938
handleReCaptchaVerify();
50-
}, [handleReCaptchaVerify]);
39+
}, []);
5140

5241
// Helper function to jump to the first form error.
5342
function focusOnFirstError() {
@@ -94,7 +83,6 @@ function FoiaRequestForm({
9483

9584
function onFormSubmit({ formData: data }) {
9685
// Now you can use the recaptcha token for your form submission
97-
handleReCaptchaVerify();
9886
data.expedited_processing.captcha = token;
9987

10088
// Merge the sections into a single payload
@@ -138,13 +126,26 @@ function FoiaRequestForm({
138126
};
139127

140128
// Map these to react-jsonschema-form Ids
141-
const steps = (requestForm.sections || []).map((section) => `root_${section.id}`);
129+
const steps = ((requestForm && requestForm.sections) || []).map((section) => `root_${section.id}`);
142130

143-
const errors = (submissionResult.errors instanceof Map)
131+
// eslint-disable-next-line no-nested-ternary
132+
const errors = (submissionResult !== undefined ? ((submissionResult.errors instanceof Map)
144133
? submissionResult.errors.toJS()
145-
: submissionResult.errors;
134+
: submissionResult.errors) : null);
135+
146136
const formContext = { steps, errors };
147-
const { jsonSchema, uiSchema } = requestForm;
137+
138+
let jsonSchema;
139+
let uiSchema;
140+
if (requestForm) {
141+
({ jsonSchema, uiSchema } = requestForm);
142+
} else {
143+
return (
144+
<Form
145+
validator={validator}
146+
/>
147+
);
148+
}
148149

149150
const templates = {
150151
FieldTemplate: CustomFieldTemplate,
@@ -154,14 +155,14 @@ function FoiaRequestForm({
154155
return (
155156
<Form
156157
className="foia-request-form sidebar_content-inner"
157-
disabled={upload.get('inProgress')}
158+
disabled={(upload !== undefined ? upload.get('inProgress') : false)}
158159
templates={templates}
159160
formContext={formContext}
160-
formData={formData.toJS()}
161+
formData={(formData !== undefined ? formData.toJS() : [])}
161162
onChange={onChange}
162163
onSubmit={onFormSubmit}
163-
schema={jsonSchema}
164-
uiSchema={uiSchema}
164+
schema={(jsonSchema !== undefined ? jsonSchema : [])}
165+
uiSchema={(uiSchema !== undefined ? uiSchema : [])}
165166
widgets={widgets}
166167
customValidate={validate}
167168
validator={validator}
@@ -183,28 +184,20 @@ function FoiaRequestForm({
183184
</p>
184185
</div>
185186
{ /* eslint-disable-next-line no-nested-ternary */ }
186-
{upload.get('inProgress')
187+
{((upload !== undefined) && upload.get('inProgress'))
187188
? (
188189
<UploadProgress
189190
progressTotal={upload.get('progressTotal')}
190191
progressLoaded={upload.get('progressLoaded')}
191192
/>
192-
)
193-
: settingsdata && settingsdata.RECAPTCHA_SITE_KEY
194-
? (
195-
<GoogleReCaptchaProvider reCaptchaKey={settingsdata.RECAPTCHA_SITE_KEY}>
196-
<GoogleReCaptcha
197-
className="google-recaptcha-custom-class"
198-
onVerify={setTokenFunc}
199-
refreshReCaptcha={refreshReCaptcha}
200-
/>
201-
<div style={{ marginTop: '2em' }} />
202-
<button className="usa-button usa-button-big usa-button-primary-alt" type="submit">
203-
Submit request
204-
</button>
205-
</GoogleReCaptchaProvider>
206-
) : (<p>Invalid key</p>)}
207-
{submissionResult.errorMessage
193+
) : (
194+
<div style={{ marginTop: '2em' }}>
195+
<button className="usa-button usa-button-big usa-button-primary-alt" type="submit">
196+
Submit request
197+
</button>
198+
</div>
199+
)}
200+
{(submissionResult !== undefined && submissionResult.errorMessage)
208201
&& (
209202
<p>
210203
<span className="usa-input-error-message" role="alert">
@@ -218,15 +211,80 @@ function FoiaRequestForm({
218211
}
219212

220213
FoiaRequestForm.propTypes = {
221-
formData: PropTypes.object.isRequired,
222-
upload: PropTypes.instanceOf(Map).isRequired,
214+
formData: PropTypes.object,
215+
upload: PropTypes.instanceOf(Map),
223216
onSubmit: PropTypes.func,
224-
requestForm: PropTypes.object.isRequired,
225-
submissionResult: PropTypes.instanceOf(SubmissionResult).isRequired,
217+
requestForm: PropTypes.object,
218+
submissionResult: PropTypes.instanceOf(SubmissionResult),
219+
setRefreshReCaptcha: PropTypes.func,
220+
refreshReCaptcha: PropTypes.bool,
221+
token: PropTypes.string,
222+
setTokenFunc: PropTypes.func,
226223
};
227224

228225
FoiaRequestForm.defaultProps = {
229226
onSubmit: () => { },
230227
};
231228

232-
export default FoiaRequestForm;
229+
function SubmitRequestPage({
230+
formData, upload, onSubmit, requestForm, submissionResult,
231+
}) {
232+
const [settingsdata, setSettingsdata] = useState(null);
233+
const [refreshReCaptcha, setRefreshReCaptcha] = useState(false);
234+
const [token, setToken] = useState('');
235+
236+
const setTokenFunc = (getToken) => {
237+
setToken(getToken);
238+
};
239+
240+
useEffect(() => {
241+
fetch('/files/settings.json')
242+
.then((response) => response.json())
243+
.then((result) => {
244+
console.log('result = ', result);
245+
setSettingsdata(result);
246+
})
247+
.catch((error) => {
248+
settingsdata.RECAPTCHA_SITE_KEY = 'DEFAULT';
249+
console.error('Error fetching recaptcha site key:', error);
250+
});
251+
}, []);
252+
253+
return (
254+
settingsdata && settingsdata.RECAPTCHA_SITE_KEY
255+
? (
256+
// eslint-disable-next-line react/jsx-wrap-multilines
257+
<GoogleReCaptchaProvider reCaptchaKey={settingsdata.RECAPTCHA_SITE_KEY}>
258+
<GoogleReCaptcha
259+
className="google-recaptcha-custom-class"
260+
onVerify={setTokenFunc}
261+
refreshReCaptcha={refreshReCaptcha}
262+
scriptProps={{ async: true }}
263+
/>
264+
<FoiaRequestForm
265+
setRefreshReCaptcha={setRefreshReCaptcha}
266+
refreshReCaptcha={refreshReCaptcha}
267+
token={token}
268+
setTokenFunc={setTokenFunc}
269+
formData={formData}
270+
upload={upload}
271+
onSubmit={onSubmit}
272+
requestForm={requestForm}
273+
submissionResult={submissionResult}
274+
/>
275+
</GoogleReCaptchaProvider>)
276+
: (
277+
<p>Invalid key</p>
278+
)
279+
);
280+
}
281+
282+
SubmitRequestPage.propTypes = {
283+
formData: PropTypes.object,
284+
upload: PropTypes.instanceOf(Map),
285+
onSubmit: PropTypes.func,
286+
requestForm: PropTypes.object,
287+
submissionResult: PropTypes.instanceOf(SubmissionResult),
288+
};
289+
290+
export default SubmitRequestPage;

0 commit comments

Comments
 (0)