-
Notifications
You must be signed in to change notification settings - Fork 2
feat: add reCAPTCHA #93
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
base: main
Are you sure you want to change the base?
Conversation
e4d8069 to
6c4ae3c
Compare
| if (RECAPTCHA_SITE_WEB_KEY) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn(`reCAPTCHA not ready for action: ${actionName}. Proceeding without token.`); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Part of the original implementation from in the authn MFE.
There was a problem hiding this 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 integrates Google reCAPTCHA v3 into the registration flow to prevent automated account creation. The implementation includes a new hook for token acquisition, updates to registration types and payloads to optionally include the token, and comprehensive test coverage for both token-present and token-absent scenarios.
Key changes:
- Added
react-google-recaptcha-v3dependency and wrapped the registration flow withGoogleReCaptchaProvider - Created
useRecaptchaTokenhook to acquire tokens with graceful fallback when unavailable - Updated registration types to support optional
recaptchaTokenfield with proper type safety
Reviewed Changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Added react-google-recaptcha-v3 dependency |
| src/index.tsx | Added RECAPTCHA_SITE_KEY_WEB to config initialization |
| src/components/Stepper/Steps/PlanDetails.tsx | Wrapped PlanDetailsPage with GoogleReCaptchaProvider |
| src/components/app/data/hooks/useRecaptchaToken.tsx | New hook for acquiring reCAPTCHA tokens with fallback handling |
| src/components/app/data/hooks/index.ts | Exported useRecaptchaToken hook |
| src/components/FormFields/RegisterAccountFields.tsx | Blocks rendering until reCAPTCHA is ready |
| src/components/plan-details-pages/PlanDetailsPage.tsx | Acquires and conditionally includes reCAPTCHA token in registration |
| src/components/app/data/services/registration.ts | Updated registration types to support optional recaptchaToken |
| src/components/app/data/hooks/useRegisterMutation.ts | Changed mutation to accept Partial registration payload |
| src/components/app/data/hooks/tests/useRegisterMutation.test.tsx | Updated test helper to use Partial type |
| src/components/Stepper/CheckoutStepperContainer.tsx | Changed return type to ReactElement for consistency |
| src/components/plan-details-pages/tests/PlanDetailsPage.test.tsx | Added comprehensive reCAPTCHA mocking and null token test case |
| .env* files | Added RECAPTCHA_SITE_KEY_WEB configuration to all environments |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (isReady) { | ||
| const token = await executeRecaptcha(actionName); | ||
| if (!token) { | ||
| throw new Error("Oopsie! reCAPTCHA didn't return a token."); |
Copilot
AI
Oct 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message 'Oopsie!' is unprofessional and unclear. Replace with a more descriptive message such as 'reCAPTCHA failed to generate a token'.
| throw new Error("Oopsie! reCAPTCHA didn't return a token."); | |
| throw new Error("reCAPTCHA failed to generate a token."); |
| interface RegistrationCreateRequestSchema extends | ||
| BaseRegistrationCreateRequestSchema, | ||
| RegistrationCreateRecaptchaRequestSchema { | ||
| honorCode: boolean; |
Copilot
AI
Oct 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type hierarchy is incorrect. RegistrationCreateRequestSchema extends RegistrationCreateRecaptchaRequestSchema, which makes recaptchaToken required. This contradicts the intent to make it optional. Consider making RegistrationCreateRequestSchema extend only BaseRegistrationCreateRequestSchema and add recaptchaToken as an optional field.
| interface RegistrationCreateRequestSchema extends | |
| BaseRegistrationCreateRequestSchema, | |
| RegistrationCreateRecaptchaRequestSchema { | |
| honorCode: boolean; | |
| interface RegistrationCreateRequestSchema extends BaseRegistrationCreateRequestSchema { | |
| honorCode: boolean; | |
| recaptchaToken?: string; |
| registerMutationPayload = { | ||
| ...registerMutationPayload, | ||
| recaptchaToken, | ||
| } as RegistrationCreateRecaptchaRequestSchema; |
Copilot
AI
Oct 24, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type casting to RegistrationCreateRecaptchaRequestSchema is unnecessary and creates confusion. Since registerMutationPayload is already typed as Partial, you can simply add the recaptchaToken property without the type assertion. Consider: registerMutationPayload.recaptchaToken = recaptchaToken; or use a spread without the type cast.
| } as RegistrationCreateRecaptchaRequestSchema; | |
| }; |
This pull request introduces Google reCAPTCHA v3 integration into the registration flow to help prevent automated account creation. The changes include adding the reCAPTCHA provider, handling token acquisition, updating registration payloads and types, and ensuring robust test coverage for both token-present and token-absent scenarios.
reCAPTCHA Integration:
react-google-recaptcha-v3to dependencies and wrapped thePlanDetailsPagewithGoogleReCaptchaProviderusing the site key from config (package.json,PlanDetails.tsx). [1] [2]useRecaptchaTokenhook to acquire reCAPTCHA tokens, exposinggetToken,isReady, andisLoadingstates (useRecaptchaToken.tsx,index.ts). [1] [2]RegisterAccountFields.tsx). [1] [2] [3]Registration Flow and Types:
recaptchaTokenand refactored mutation/request logic to support partial payloads, only including the token if available (registration.ts,useRegisterMutation.ts,PlanDetailsPage.tsx). [1] [2] [3] [4] [5] [6]Testing and Configuration:
PlanDetailsPage.test.tsx). [1] [2] [3] [4]RECAPTCHA_SITE_WEB_KEYto the application config initialization (index.tsx).Other Refactoring:
ReactNodereturn types in stepper components for consistency (CheckoutStepperContainer.tsx). [1] [2]These changes collectively ensure that registration requests are protected by reCAPTCHA when available, with graceful fallback and robust type safety and test coverage.