Skip to content

feat: implement reCAPTCHA Enterprise#9066

Draft
mikehardy wants to merge 22 commits into
mainfrom
recaptcha-enterprise
Draft

feat: implement reCAPTCHA Enterprise#9066
mikehardy wants to merge 22 commits into
mainfrom
recaptcha-enterprise

Conversation

@mikehardy

Copy link
Copy Markdown
Collaborator

Description

More documentation to come - this is in progress at this moment, pushing for visibility only

Related issues

Can link upstream and FlutterFire sister repo PR

Release Summary

Will be conventional commits for an automated semantic release

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
    • Yes
  • My change supports the following platforms;
    • Android
    • iOS
    • Other (macOS, web)
  • My change includes tests;
    • e2e tests added or updated in packages/\*\*/e2e
    • jest tests added or updated in packages/\*\*/__tests__
  • I have updated TypeScript types that are affected by my change.
  • This is a breaking change;
    • Yes
    • No

Test Plan

A great deal of unit and type and e2e and documentation tests


Think react-native-firebase is great? Please consider supporting the project with any of the below:

@gemini-code-assist

Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces support for reCAPTCHA Enterprise in react-native-firebase, enabling enhanced bot protection for App Check and Auth. The changes include the addition of new provider classes, native dependency updates for Android, and comprehensive configuration plumbing to propagate site keys across platforms. The implementation follows a modular approach, ensuring type parity with the Firebase JS SDK while providing platform-specific runtime behavior.

Highlights

  • reCAPTCHA Enterprise Support: Implemented reCAPTCHA Enterprise for App Check and Auth, including new provider classes and native integration.
  • Configuration Plumbing: Added recaptchaSiteKey support to FirebaseAppOptions to enable cross-platform configuration.
  • Platform-Specific Routing: Introduced robust routing logic to handle reCAPTCHA providers across iOS, Android, and Web contexts.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements Phase 0 and Phase 1 of the reCAPTCHA Enterprise design plan, adding recaptchaSiteKey plumbing to the core app options and introducing ReCaptchaV3Provider and ReCaptchaEnterpriseProvider to the App Check package. It updates the Web bridge to support real JS SDK providers and provider-less initialization, extends native provider configurations, and adds comprehensive unit and type tests. The review feedback focuses on simplifying the platform routing logic by removing dead code for macOS (which is already handled under the isOther path) and improving runtime robustness by using optional chaining when accessing app options.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +82 to +88
if (
context.platformOS === 'android' ||
context.platformOS === 'ios' ||
context.platformOS === 'macos'
) {
return { providerName: 'recaptcha' };
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Since RNFBCommon.isOther is true when Platform.OS is 'macos', the initializeAppCheck method in namespaced.ts will always return early on macOS and never call resolveNativeInitializeAppCheckRoute. Therefore, checking for 'macos' inside resolveNativeInitializeAppCheckRoute is dead code and can be safely removed to simplify the platform routing logic.

    if (
      context.platformOS === 'android' ||
      context.platformOS === 'ios'
    ) {
      return { providerName: 'recaptcha' };
    }

};
}

if (context.platformOS === 'ios' || context.platformOS === 'macos') {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

As macOS is handled under the isOther path, context.platformOS will never be 'macos' when executing resolveNativeInitializeAppCheckRoute. You can safely simplify this check to only check for 'ios'.

Suggested change
if (context.platformOS === 'ios' || context.platformOS === 'macos') {
if (context.platformOS === 'ios') {

Comment on lines +31 to +35
export function assertNativeRecaptchaSiteKeyConsistency(
appOptions: Pick<ReactNativeFirebase.FirebaseAppOptions, 'recaptchaSiteKey'>,
constructorSiteKey: string,
): void {
const configSiteKey = appOptions.recaptchaSiteKey;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

low

To prevent potential runtime TypeErrors if appOptions is null or undefined (for example, in testing or custom environments), use optional chaining when accessing recaptchaSiteKey.

Suggested change
export function assertNativeRecaptchaSiteKeyConsistency(
appOptions: Pick<ReactNativeFirebase.FirebaseAppOptions, 'recaptchaSiteKey'>,
constructorSiteKey: string,
): void {
const configSiteKey = appOptions.recaptchaSiteKey;
export function assertNativeRecaptchaSiteKeyConsistency(
appOptions: Pick<ReactNativeFirebase.FirebaseAppOptions, 'recaptchaSiteKey'>,
constructorSiteKey: string,
): void {
const configSiteKey = appOptions?.recaptchaSiteKey;

Comment on lines +85 to +91
app: { options: { recaptchaSiteKey?: string } },
options: WebInitializeAppCheckOptions,
): JsAppCheckOptions {
const { provider, isTokenAutoRefreshEnabled } = options;

if (!provider) {
const recaptchaSiteKey = app.options.recaptchaSiteKey;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

low

To prevent potential runtime errors if app or app.options is undefined or null (e.g., in custom environments or unit tests), use optional chaining when retrieving recaptchaSiteKey.

Suggested change
app: { options: { recaptchaSiteKey?: string } },
options: WebInitializeAppCheckOptions,
): JsAppCheckOptions {
const { provider, isTokenAutoRefreshEnabled } = options;
if (!provider) {
const recaptchaSiteKey = app.options.recaptchaSiteKey;
app: { options: { recaptchaSiteKey?: string } },
options: WebInitializeAppCheckOptions,
): JsAppCheckOptions {
const { provider, isTokenAutoRefreshEnabled } = options;
if (!provider) {
const recaptchaSiteKey = app?.options?.recaptchaSiteKey;

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Hello 👋, this PR has been opened for more than 14 days with no activity on it.

If you think this is a mistake please comment and ping a maintainer to get this merged ASAP! Thanks for contributing!

You have 7 days until this gets closed automatically

@github-actions github-actions Bot added the Stale label Jul 7, 2026
mikehardy added 17 commits July 23, 2026 20:04
Add first-class recaptchaSiteKey on FirebaseAppOptions with native
FirebaseOptions/FIROptions wiring on Android and iOS, Other/Web passthrough,
tests.
Runtime helpers for distinguishing Other/Web from Other/Hermes targets,
with unit tests.
Export js-sdk-matching ReCaptchaV3Provider and ReCaptchaEnterpriseProvider
stubs, extend native provider unions with recaptcha, and add tests.
Refactor the Other/Web bridge to use real js-sdk providers, support
provider-less init when recaptchaSiteKey is set, and add routing tests.
Add native/web routing helpers for recaptcha providers, Hermes rejection,
provider-less web init, and Enterprise site-key consistency checks with tests.
Document exported ReCaptcha provider classes and narrowed AppCheckOptions
compare-types drift reasons for the new public surface.
Cover js-sdk provider classes, native recaptcha configure options, and
provider-less initializeAppCheck when recaptchaSiteKey is set.
Link firebase-appcheck-recaptcha and route the recaptcha provider to
RecaptchaAppCheckProviderFactory using native FirebaseOptions site key.
…errors

Implement FIRRecaptchaProvider on iOS, link RecaptchaEnterprise pod,
reject configure failures, block macOS recaptcha routing in JS, and add tests.
Wire native Android/iOS bridges, Other/Web js-sdk delegation, Hermes
no-op with warning, reCAPTCHA SDK deps, compare-types, and tests.
Document provider routing tables, initializeRecaptchaConfig, recaptchaSiteKey
config, and platform behaviour across app-check, auth, and migration guides.
Link reCAPTCHA design from the okf-bundle index, add an app-check provider
matrix, update auth compare-types triage for initializeRecaptchaConfig, and
document native coverage paths for App Check and Auth reCAPTCHA branches.
Add App Check recaptcha and Auth initializeRecaptchaConfig e2e smokes,
including Other/Web and Other/Hermes path coverage where applicable.
Document that config plugins copy native Firebase files verbatim and
users must redownload google-services files after enabling App Check reCAPTCHA.
Document tiered e2e verification (App Check + Auth), secondaryFromNative
cloud Auth path, Identity Platform AUDIT setup, and dual-setup runbook.

Add a doctor script to automate GCP / IAM Firebase console setup for
reCAPTCHA Enterprise where possible.
Avoid isObject narrowing that erased AppCheckOptions, type the web App
Check instance correctly, and update provider-validation / TurboModule
mocks after adding the native recaptcha provider.
@mikehardy
mikehardy force-pushed the recaptcha-enterprise branch from 2d9964b to ac5000b Compare July 24, 2026 01:15
…ride

Use @OverRide for the Spec method instead of @ReactMethod so the auth
Android module compiles under New Architecture.
The Auth Emulator does not implement getRecaptchaConfig; cloud Enterprise
coverage remains on secondaryFromNative once the project is provisioned.
@github-actions github-actions Bot removed the Stale label Jul 24, 2026
@codecov

codecov Bot commented Jul 24, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 70.04405% with 68 lines in your changes missing coverage. Please review.
✅ Project coverage is 66.25%. Comparing base (5dfef91) to head (b16aec5).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #9066      +/-   ##
============================================
+ Coverage     66.03%   66.25%   +0.22%     
- Complexity     1903     1907       +4     
============================================
  Files           497      499       +2     
  Lines         39065    39344     +279     
  Branches       5845     5879      +34     
============================================
+ Hits          25794    26064     +270     
- Misses        11806    11855      +49     
+ Partials       1465     1425      -40     
Flag Coverage Δ
android-native 63.58% <75.00%> (+0.03%) ⬆️
e2e-ts-android 59.98% <30.00%> (-0.12%) ⬇️
e2e-ts-ios 62.54% <27.28%> (-0.19%) ⬇️
e2e-ts-macos 49.78% <20.00%> (-0.22%) ⬇️
ios-native 62.54% <27.28%> (-0.19%) ⬇️
jest 49.47% <85.50%> (-0.47%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

RNFBErrorDomain is file-private in RNFBSharedUtils; use a local constant
with the same domain string so the recaptcha provider compiles.
Record RecaptchaEnterprise / RecaptchaEnterpriseSDK deps pulled in for
App Check and Auth reCAPTCHA provider support.
Avoid Auth Emulator getRecaptchaConfig gaps on the default app; use the
natively initialized cloud secondary app for the no-throw smoke on iOS/Android.
@mikehardy
mikehardy force-pushed the recaptcha-enterprise branch from 405de90 to b16aec5 Compare July 24, 2026 22:37
@mikehardy
mikehardy marked this pull request as draft July 24, 2026 22:41
@mikehardy mikehardy added the blocked: firebase-sdk Pending a confirmed fix landing on the official native sdk's (iOS/Android). label Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

blocked: firebase-sdk Pending a confirmed fix landing on the official native sdk's (iOS/Android).

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant