Skip to content

Core 1435 add recaptcha to forms#2827

Draft
RoyEJohnson wants to merge 4 commits into
mainfrom
core-1435-add-recaptcha-to-forms
Draft

Core 1435 add recaptcha to forms#2827
RoyEJohnson wants to merge 4 commits into
mainfrom
core-1435-add-recaptcha-to-forms

Conversation

@RoyEJohnson
Copy link
Copy Markdown
Contributor

@RoyEJohnson RoyEJohnson commented Feb 18, 2026

CORE-1435
Uses the custom grecaptcha routines to put the Submit button behind an "I am human" button, which, when clicked, creates the token, which is populated into a hidden field and included in the form data.

@RoyEJohnson RoyEJohnson force-pushed the core-1435-add-recaptcha-to-forms branch from 64594f0 to 26fa22e Compare February 18, 2026 14:18
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Google reCAPTCHA v3 protection to user-facing forms in the OpenStax application to prevent spam and abuse. The implementation introduces a custom React hook (useRecaptchaToken) that manages token generation and provides a gating mechanism where users must click an "I am a human" button before accessing the form's submit button.

Changes:

  • Added reCAPTCHA v3 integration with a custom React hook for token management
  • Protected contact form and multi-page forms (adoption/interest) with reCAPTCHA gating
  • Added comprehensive test coverage including unit tests and mock helper for testing

Reviewed changes

Copilot reviewed 11 out of 12 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/app/components/recaptcha.tsx Core implementation of the useRecaptchaToken hook that manages token lifecycle and UI gating
src/app/pages/contact/form.tsx Integrates reCAPTCHA into the contact form with hidden token field
src/app/components/multi-page-form/buttons.tsx Wraps submit button in Recaptcha component for multi-page forms
src/index.html Loads Google reCAPTCHA v3 script with site key
test/src/components/recaptcha.test.tsx Unit tests for the reCAPTCHA hook functionality
test/src/helpers/mock-recaptcha.tsx Mock implementation for testing components that use reCAPTCHA
test/src/pages/*.test.tsx Updates existing tests to import the reCAPTCHA mock
test/src/components/multi-page-form.test.tsx Updates test assertion to account for reCAPTCHA changes
package.json Adds @types/grecaptcha type definitions
yarn.lock Lockfile update for new dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/components/multi-page-form/buttons.tsx Outdated
Comment thread src/app/components/recaptcha.tsx
Comment thread test/src/components/recaptcha.test.tsx Outdated
Comment thread src/app/components/recaptcha.tsx Outdated
Comment thread src/app/components/recaptcha.tsx
Comment thread src/app/components/recaptcha.tsx
@RoyEJohnson RoyEJohnson force-pushed the core-1435-add-recaptcha-to-forms branch 3 times, most recently from 71b3f0b to 374a2d9 Compare February 18, 2026 18:16
@RoyEJohnson RoyEJohnson requested a review from Copilot February 18, 2026 18:22
@RoyEJohnson RoyEJohnson force-pushed the core-1435-add-recaptcha-to-forms branch from 374a2d9 to 9cac8d3 Compare February 18, 2026 18:32
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 11 out of 12 changed files in this pull request and generated 8 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +9 to +14
// @ts-expect-error not all properties defined
window.grecaptcha = {
ready: mockReady,
execute: mockExecute
};

Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

useRecaptchaToken checks the global identifier grecaptcha (not window.grecaptcha). In Jest/jsdom, assigning window.grecaptcha = ... does not necessarily define a global grecaptcha, so fetchToken may treat it as unavailable and never call execute. To make the test environment match browser semantics, assign the mock to globalThis.grecaptcha (or explicitly define a global grecaptcha) in addition to window.grecaptcha.

Suggested change
// @ts-expect-error not all properties defined
window.grecaptcha = {
ready: mockReady,
execute: mockExecute
};
const grecaptchaMock = {
ready: mockReady,
execute: mockExecute
};
// @ts-expect-error not all properties defined
// Ensure both window.grecaptcha and the global grecaptcha identifier are set
// so that useRecaptchaToken can find the mock in the Jest/jsdom environment.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).grecaptcha = grecaptchaMock;
// @ts-expect-error not all properties defined
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(globalThis as any).grecaptcha = grecaptchaMock;

Copilot uses AI. Check for mistakes.
<p>{error}</p>
</div>;
}
return <button type="button" disabled={fetching} onClick={fetchToken}>
Copy link

Copilot AI Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When error is set, Recaptcha renders only the error message and removes the button, but the only way to clear the error is by calling fetchToken again—which is no longer possible. Consider rendering a retry button (or keeping the existing button) while showing the error so users can re-attempt token generation.

Suggested change
return <button type="button" disabled={fetching} onClick={fetchToken}>
<p>{error}</p>
<button type="button" disabled={fetching} onClick={fetchToken}>
Try again
</button>

Copilot uses AI. Check for mistakes.
Comment thread src/app/components/recaptcha.tsx
Comment thread src/index.html
Comment thread src/app/components/recaptcha.tsx
Comment thread src/app/components/recaptcha.tsx Outdated
Comment thread test/src/helpers/mock-recaptcha.tsx
Comment thread test/src/components/multi-page-form.test.tsx Outdated
RoyEJohnson and others added 3 commits February 18, 2026 13:02
Add hidden fields to submit token
Name token field
Handle grecaptcha failure to load

Co-Authored-By: Copilot <175728472+Copilot@users.noreply.github.com>
Co-Authored-By: Copilot <175728472+Copilot@users.noreply.github.com>
@RoyEJohnson RoyEJohnson force-pushed the core-1435-add-recaptcha-to-forms branch from 9cac8d3 to 5d88860 Compare February 18, 2026 19:02
@RoyEJohnson RoyEJohnson marked this pull request as draft February 25, 2026 00:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants