Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
33905d4
feat(appcheck): implement RecaptchaEnterpriseProvider and tests (#16150)
ncooke3 May 4, 2026
250212e
package.swift newline
ncooke3 May 4, 2026
5f894cb
fix(AppCheck): log error when siteKey is empty in provider init
ncooke3 May 4, 2026
0cee53b
tests: add manual e2e tests
ncooke3 May 7, 2026
8eecc10
feedback
ncooke3 May 7, 2026
b0e2039
review
ncooke3 May 7, 2026
0cbf732
update versions
ncooke3 May 7, 2026
bb35028
fixes and review
ncooke3 May 7, 2026
3c84e4a
Merge branch 'main' into nc/recaptcha-1
ncooke3 May 7, 2026
10ff653
fixes
ncooke3 May 7, 2026
c5d6cd4
app dele
ncooke3 May 7, 2026
4d84847
e2e
ncooke3 May 7, 2026
180b29f
podfile
ncooke3 May 7, 2026
cee38df
review:
ncooke3 May 7, 2026
098066d
Review
ncooke3 May 7, 2026
db54acf
fix podfile
ncooke3 May 7, 2026
4a67322
add fixes to e2e file
ncooke3 May 7, 2026
678bf77
e2e updates
ncooke3 May 8, 2026
197949c
delegate fixes
ncooke3 May 8, 2026
2c564e7
rewrite in swift
ncooke3 May 13, 2026
0abebb5
doc comments:
ncooke3 May 13, 2026
a977ee3
Refactor and modernize Recaptcha Enterprise provider testing
ncooke3 May 13, 2026
984b525
rename
ncooke3 May 28, 2026
39b2adb
public getter and setter for site key
ncooke3 May 28, 2026
94a1f8d
recaptcha factory rename and options handling
ncooke3 May 28, 2026
ce8264f
Merge remote-tracking branch 'origin/main' into nc/recaptcha-1
ncooke3 May 28, 2026
10c3814
recaptchanenterprise -> recaptcha renames
ncooke3 May 28, 2026
2fb8aed
renames cont
ncooke3 May 28, 2026
74817fd
logging improvements
ncooke3 May 28, 2026
fae69fa
Apply suggestion from @paulb777
ncooke3 May 28, 2026
7fd95eb
Update FirebaseAppCheck/Apps/FIRAppCheckTestApp/E2E_TESTING.md
ncooke3 May 28, 2026
e092cf9
Update FirebaseAppCheck/Apps/FIRAppCheckTestApp/E2E_TESTING.md
ncooke3 May 28, 2026
4750edb
fixes
ncooke3 Jun 2, 2026
7b077e3
Merge branch 'main' into nc/recaptcha-1
ncooke3 Jun 5, 2026
4f4f117
integrate recaptcha provider into default provider
ncooke3 Jun 5, 2026
08ae2ac
better exception messaging
ncooke3 Jun 8, 2026
27f172d
final checks
ncooke3 Jun 8, 2026
98cd99f
Update FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRRecaptchaP…
ncooke3 Jun 9, 2026
eb6377f
Update FirebaseAppCheck/Sources/Public/FirebaseAppCheck/FIRRecaptchaP…
ncooke3 Jun 9, 2026
7419e79
Update FirebaseAppCheck/Sources/RecaptchaProvider/FIRRecaptchaProvide…
ncooke3 Jun 9, 2026
435f4b4
Update FirebaseAppCheck/Tests/Unit/DefaultProviderFactory/FIRDefaultP…
ncooke3 Jun 9, 2026
11e7a08
Merge branch 'main' into nc/recaptcha-1
ncooke3 Jun 9, 2026
8d8a9db
changelog
ncooke3 Jun 9, 2026
ee8b08e
remove API from header
ncooke3 Jun 9, 2026
a786cda
fixes
ncooke3 Jun 9, 2026
1ee4e53
Update sdk.core.yml
ncooke3 Jun 9, 2026
d0e4e86
Apply suggestion from @ncooke3
ncooke3 Jun 9, 2026
33dfc9b
Apply suggestion from @ncooke3
ncooke3 Jun 9, 2026
b040e1f
Avail fixes
ncooke3 Jun 10, 2026
8f2478c
log
ncooke3 Jun 10, 2026
7c1eff5
Update infra.spm_global.yml
ncooke3 Jun 10, 2026
d2ec668
Update infra.spm_global.yml
ncooke3 Jun 10, 2026
5f91bb6
Test fixes
ncooke3 Jun 10, 2026
d818736
Update infra.spm_global.yml
ncooke3 Jun 10, 2026
6d86c07
Update infra.samples.client_app.yml
ncooke3 Jun 10, 2026
f7bf2fb
Exempt SharedTestUtilities from check_imports.swift strict else rule
ncooke3 Jun 10, 2026
e883fa6
fix spec linting warning
ncooke3 Jun 10, 2026
1a12aed
Merge remote-tracking branch 'origin/nc/recaptcha-1' into nc/recaptcha-1
ncooke3 Jun 10, 2026
053ac90
fixes
ncooke3 Jun 10, 2026
4af5aab
Merge branch 'main' into nc/recaptcha-1
ncooke3 Jun 10, 2026
5824a89
workflow work
ncooke3 Jun 10, 2026
791e164
fst fixes
ncooke3 Jun 10, 2026
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
4 changes: 4 additions & 0 deletions .github/workflows/infra.samples.client_app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ on:

env:
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
FIREBASE_APP_CHECK_BRANCH: main
Comment thread
ncooke3 marked this conversation as resolved.

concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
Expand All @@ -44,6 +45,7 @@ jobs:
method: xcodebuild
os: ${{ matrix.os }}
xcode: ${{ matrix.xcode }}
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'

client-app-spm-source-firestore:
strategy:
Expand All @@ -63,6 +65,7 @@ jobs:
os: ${{ matrix.os }}
xcode: ${{ matrix.xcode }}
setup_command: echo "FIREBASE_SOURCE_FIRESTORE=1" >> $GITHUB_ENV
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'

client-app-cocoapods:
strategy:
Expand All @@ -80,3 +83,4 @@ jobs:
os: ${{ matrix.os }}
xcode: ${{ matrix.xcode }}
setup_command: scripts/install_prereqs.sh ClientApp iOS xcodebuild
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'
8 changes: 8 additions & 0 deletions .github/workflows/infra.spm_global.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
spm-package-resolved:
env:
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
FIREBASE_APP_CHECK_BRANCH: main
runs-on: macos-26
outputs:
cache_key: ${{ steps.generate_cache_key.outputs.cache_key }}
Expand All @@ -55,6 +56,9 @@ jobs:
# Don't run on private repo unless it is a PR.
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
needs: [spm-package-resolved]
env:
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
FIREBASE_APP_CHECK_BRANCH: main
strategy:
matrix:
include:
Expand Down Expand Up @@ -105,6 +109,8 @@ jobs:
# Don't run on private repo unless it is a PR.
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
needs: [spm-package-resolved]
env:
FIREBASE_APP_CHECK_BRANCH: main
strategy:
matrix:
include:
Expand Down Expand Up @@ -144,6 +150,8 @@ jobs:
# Don't run on private repo unless it is a PR.
if: (github.repository == 'Firebase/firebase-ios-sdk' && github.event_name == 'schedule') || github.event_name == 'pull_request'
needs: [spm-package-resolved]
env:
FIREBASE_APP_CHECK_BRANCH: main
strategy:
matrix:
# Full set of Firebase-Package tests only run on iOS. Run subset on other platforms.
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/sdk.appcheck.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ jobs:
uses: ./.github/workflows/_spm.yml
with:
target: ${{ matrix.target }}
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'

catalyst:
uses: ./.github/workflows/_catalyst.yml
Expand Down Expand Up @@ -57,6 +58,7 @@ jobs:
method: spm
sanitizers: ${{ matrix.diagnostic }}
setup_command: scripts/setup_spm_tests.sh
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'

app_check-cron-only:
needs: pod_lib_lint
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/sdk.core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ jobs:
uses: ./.github/workflows/_spm.yml
with:
target: CoreUnit
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'

catalyst:
uses: ./.github/workflows/_catalyst.yml
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/sdk.firestore.yml
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ jobs:
env:
FIREBASECI_USE_LATEST_GOOGLEAPPMEASUREMENT: 1
FIREBASE_SOURCE_FIRESTORE: 1
FIREBASE_APP_CHECK_BRANCH: main
outputs:
cache_key: ${{ steps.generate_cache_key.outputs.cache_key }}
steps:
Expand Down Expand Up @@ -591,6 +592,7 @@ jobs:
runs-on: ${{ matrix.os }}
env:
FIREBASE_SOURCE_FIRESTORE: 1
FIREBASE_APP_CHECK_BRANCH: main
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Xcode
Expand All @@ -614,6 +616,7 @@ jobs:
with:
target: FirebaseFirestoreTests
platforms: iOS
env_vars: '{"FIREBASE_APP_CHECK_BRANCH": "main"}'

spm-source-cron:
# Don't run on private repo.
Expand All @@ -624,6 +627,7 @@ jobs:
target: [tvOS, macOS, catalyst]
env:
FIREBASE_SOURCE_FIRESTORE: 1
FIREBASE_APP_CHECK_BRANCH: main
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Xcode
Expand All @@ -648,6 +652,8 @@ jobs:
strategy:
matrix:
target: [tvOS, macOS, catalyst]
env:
FIREBASE_APP_CHECK_BRANCH: main
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
- name: Xcode
Expand Down
6 changes: 5 additions & 1 deletion FirebaseAppCheck.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Pod::Spec.new do |s|
s.osx.weak_framework = 'DeviceCheck'
s.tvos.weak_framework = 'DeviceCheck'

s.dependency 'AppCheckCore', '~> 11.0'
s.dependency 'AppCheckCore', '~> 11.3'
Comment thread
ncooke3 marked this conversation as resolved.
Comment thread
ncooke3 marked this conversation as resolved.
s.dependency 'FirebaseAppCheckInterop', '~> 12.15.0'
s.dependency 'FirebaseCore', '~> 12.15.0'
s.dependency 'GoogleUtilities/Environment', '~> 8.1'
Expand Down Expand Up @@ -93,7 +93,11 @@ Pod::Spec.new do |s|
}
swift_unit_tests.source_files = [
base_dir + 'Tests/Unit/Swift/**/*.swift',
'SharedTestUtilities/ExceptionCatcher.[mh]'
]
swift_unit_tests.pod_target_xcconfig = {
'SWIFT_OBJC_BRIDGING_HEADER' => '$(PODS_TARGET_SRCROOT)/FirebaseAppCheck/Tests/Unit/Swift/FirebaseAppCheck-unit-Bridging-Header.h'
}

swift_unit_tests.dependency 'FirebaseCoreExtension', '~> 12.15.0'
end
Expand Down
182 changes: 182 additions & 0 deletions FirebaseAppCheck/Apps/FIRAppCheckTestApp/E2E_TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# E2E Testing with FIRAppCheckTestApp

This document provides information on how to configure and run End-to-End (E2E)
tests for App Check providers using this sample app.

## Configurability

The app's behavior can be configured using environment variables passed during
test execution.

### Environment Variables

Starting with Xcode 13, you can pass environment variables directly to the
test runner by prefixing them with `TEST_RUNNER_`. The prefix is stripped when
it reaches the test process.

- **`TEST_RUNNER_RECAPTCHA_SITE_KEY`**: The reCAPTCHA site key used
by the `AppCheckRecaptchaProvider`.
- **Access in Code**: Read via
`ProcessInfo.processInfo.environment["RECAPTCHA_SITE_KEY"]`.
- **`TEST_RUNNER_APP_CHECK_PROVIDER`**: Specifies which App Check provider
factory to use.
- **Supported Values**: `recaptcha` (default), `debug`.
- **Access in Code**: Read via
`ProcessInfo.processInfo.environment["APP_CHECK_PROVIDER"]`.

### Manual Override

For local debugging and manual testing, you can override the environment
variables by setting `manualProviderOverride` in `AppDelegate.swift`:

```swift
let manualProviderOverride: String? = "debug"
```

## Running Tests

The commands below should be run from the **repository root**.

### Prerequisites
- Ensure you have a local checkout of the `app-check` repository if you are
developing it locally. Set `FIREBASE_APP_CHECK_LOCAL_PATH` to point to it.

### Sample Commands

#### Run tests with reCAPTCHA provider

```bash
export TEST_RUNNER_RECAPTCHA_SITE_KEY="your_site_key_here"
export TEST_RUNNER_APP_CHECK_PROVIDER="recaptcha"
export FIREBASE_APP_CHECK_LOCAL_PATH="/path/to/your/local/app-check"
SIM_ID=$(xcrun simctl list devices available | grep "iPhone" | grep -E -o '[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}' | head -n 1)

xcodebuild test \
-workspace FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcworkspace \
-scheme FIRAppCheckTestApp \
-destination "platform=iOS Simulator,id=$SIM_ID"
```

#### Run tests with Debug provider

```bash
export TEST_RUNNER_APP_CHECK_PROVIDER="debug"
export FIREBASE_APP_CHECK_LOCAL_PATH="/path/to/your/local/app-check"
SIM_ID=$(xcrun simctl list devices available | grep "iPhone" | grep -E -o '[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}' | head -n 1)

xcodebuild test \
-workspace FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcworkspace \
-scheme FIRAppCheckTestApp \
-destination "platform=iOS Simulator,id=$SIM_ID"
```
*Note: The Debug provider might require you to register the generated debug token in the Firebase Console for the tests to pass if they interact with live services.*

### Running and Testing in Xcode

If you prefer to use the Xcode UI instead of `xcodebuild`, follow these steps
to configure the environment:

#### 1. Resolve Local Dependency
If you are using a local checkout of the `app-check` repository, Xcode must be
launched from the terminal with the `FIREBASE_APP_CHECK_LOCAL_PATH` environment
variable set so that Swift Package Manager can resolve it correctly.

Run the following command from the repository root:
```bash
open --env FIREBASE_APP_CHECK_LOCAL_PATH=/path/to/your/local/app-check FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcworkspace
```

#### 2. Configure Provider and Site Key
You have two options to configure the provider when running or testing in Xcode:

**Option A: Via Manual Override in Code (Easiest for Running the App)**
If you just want to quickly run the app with a specific provider without
changing scheme settings:
1. Open `AppDelegate.swift`.
2. Locate `manualProviderOverride` in `application(_:didFinishLaunchingWithOptions:)`.
3. Set it to your desired provider:
```swift
let manualProviderOverride: String? = "recaptcha"
```
*Note: Remember to revert this change before committing.*

**Option B: Via Xcode Scheme (Recommended for Tests)**
This avoids modifying code and works for both running and testing.
1. In Xcode, go to **Product > Scheme > Edit Scheme...** (or press `⌘<`).
2. Select the **Run** or **Test** action in the left sidebar, depending on
what you are doing.
3. Go to the **Arguments** tab.
4. In the **Environment Variables** section, add:
* `APP_CHECK_PROVIDER`: Set to `recaptcha` or `debug`.
* `RECAPTCHA_SITE_KEY`: Set to your reCAPTCHA site key (required for
`recaptcha`).

### Running and Testing with CocoaPods

If you prefer to use the CocoaPods workflow instead of SPM:

#### 0. Clean Up State (Optional but Recommended)
If you are switching from the SPM workflow or encounter issues, it is
recommended to clean up the CocoaPods state first:
```bash
pod deintegrate FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcodeproj
rm -rf FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcworkspace
rm -f FirebaseAppCheck/Apps/FIRAppCheckTestApp/Podfile.lock
```

#### 1. Install Dependencies
To ensure a clean update and avoid conflicts with local development paths or
stale state, it is recommended to remove the existing `Pods` directory and
`Podfile.lock` before updating.

Run the following command from the repository root:
```bash
rm -rf FirebaseAppCheck/Apps/FIRAppCheckTestApp/Pods
rm -f FirebaseAppCheck/Apps/FIRAppCheckTestApp/Podfile.lock
FIREBASE_APP_CHECK_LOCAL_PATH="/path/to/your/local/app-check" pod update --repo-update --project-directory=FirebaseAppCheck/Apps/FIRAppCheckTestApp/
```

#### 2. Open Workspace
Open the generated CocoaPods workspace instead of the project file:
```bash
open FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcworkspace
```

#### 3. Remove SPM Dependencies (If needed)
By default, the project file is configured for SPM. To avoid duplicate symbol
issues or conflicting resolutions when using CocoaPods:
1. In Xcode, select the project in the file navigator.
2. Select the project file at the top (not a target).
3. Go to the **Package Dependencies** tab.
4. Remove the `firebase-ios-sdk` or `app-check` package references if they
appear there.
5. Also, select the `FIRAppCheckTestApp` target, go to the **General** tab,
and scroll down to **Frameworks, Libraries, and Embedded Content**.
6. Remove any SPM-resolved frameworks from this list.

#### 4. Configure and Run
You can configure the provider and site key either via the Xcode Scheme or by
passing environment variables to `xcodebuild`.

**Via Xcode Scheme:**
Follow the instructions in **[Running and Testing in Xcode](#running-and-testing-in-xcode)**.

**Via `xcodebuild` (Command Line):**
Run the following command from the repository root, replacing the site key with
your own:
```bash
export TEST_RUNNER_RECAPTCHA_SITE_KEY="your_site_key_here"
export TEST_RUNNER_APP_CHECK_PROVIDER="recaptcha"
SIM_ID=$(xcrun simctl list devices available | grep "iPhone" | grep -E -o '[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}' | head -n 1)

xcodebuild test \
-workspace FirebaseAppCheck/Apps/FIRAppCheckTestApp/FIRAppCheckTestApp.xcworkspace \
-scheme FIRAppCheckTestApp \
-destination "platform=iOS Simulator,id=$SIM_ID"
```
*(Note: See [Running Tests](#running-tests) for how to dynamically find a valid
simulator destination).*

## Project Structure

- **`FIRAppCheckTestAppTests`**: A hosted unit test target containing the test cases. It runs inside the app process to have access to the full app context.
Loading
Loading