From 1ad8f7e1ce57824fe9df077768b2a44eb3d454fc Mon Sep 17 00:00:00 2001 From: Eli Zibin <1131641+zibs@users.noreply.github.com> Date: Wed, 30 Sep 2026 12:44:59 -0700 Subject: [PATCH 01/11] feat!: modernize examples and require React Native 0.86 Upgrade platform floors and Expo integration. Keep native regression checks local or manually dispatched. --- .../android-plugin-placeholder-scope.md | 5 + .changeset/android-recovery-review-fixes.md | 5 + .changeset/current-react-native-baseline.md | 5 + .github/workflows/native-regression.yml | 54 + .github/workflows/pull-request.yml | 2 +- .github/workflows/release.yml | 2 +- README.md | 2 +- docs/docs/introduction.md | 9 +- docs/docs/usage/expo-setup.md | 18 +- docs/docs/usage/manual-setup.md | 5 +- examples/demo/App.tsx | 82 +- examples/demo/README.md | 13 + examples/demo/__tests__/App.test.tsx | 4 + examples/demo/android/app/build.gradle | 4 +- .../RNAppAuthRecoveryInstrumentation.java | 360 + .../android/app/src/debug/AndroidManifest.xml | 9 - .../android/app/src/main/AndroidManifest.xml | 1 + .../src/main/java/com/example/MainActivity.kt | 9 + .../main/java/com/example/MainApplication.kt | 41 +- examples/demo/android/build.gradle | 10 +- examples/demo/android/gradle.properties | 6 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 43705 -> 48966 bytes .../gradle/wrapper/gradle-wrapper.properties | 2 +- examples/demo/android/gradlew | 9 +- examples/demo/android/gradlew.bat | 192 +- .../ios/Example.xcodeproj/project.pbxproj | 18 + examples/demo/ios/Example/AppDelegate.swift | 18 +- examples/demo/ios/Example/Info.plist | 23 + examples/demo/ios/Example/SceneDelegate.swift | 50 + examples/demo/ios/Podfile | 12 +- examples/demo/ios/Podfile.lock | 1936 ++-- examples/demo/jest.config.js | 8 +- examples/demo/metro.config.js | 17 +- examples/demo/package.json | 32 +- examples/demo/tsconfig.json | 10 +- examples/expo-cng/.gitignore | 1 + examples/expo-cng/.yarnrc.yml | 3 + examples/expo-cng/App.tsx | 220 +- examples/expo-cng/README.md | 28 +- examples/expo-cng/app.json | 15 +- examples/expo-cng/package.json | 15 +- examples/expo-cng/yarn.lock | 8903 ++++++++++------- package.json | 8 +- .../android/build.gradle | 4 +- .../native-tests/android-recovery.sh | 16 + packages/react-native-app-auth/package.json | 20 +- .../plugin.fixture-coverage.spec.ts | 360 + .../plugin/src/__tests__/app-delegate.test.ts | 25 +- .../plugin/src/android/app-build-gradle.ts | 83 +- .../plugin/src/android/index.ts | 3 +- .../plugin/src/android/main-activity.ts | 40 + .../plugin/src/expo-version.ts | 22 +- .../react-native-app-auth/plugin/src/index.ts | 5 +- .../plugin/src/ios/app-delegate-header.ts | 4 +- .../plugin/src/ios/app-delegate.ts | 30 +- .../plugin/src/ios/bridging-header.ts | 128 +- .../plugin/src/ios/info-plist.ts | 46 +- .../react-native-app-auth.podspec | 2 +- yarn.lock | 2626 ++--- 59 files changed, 9028 insertions(+), 6552 deletions(-) create mode 100644 .changeset/android-plugin-placeholder-scope.md create mode 100644 .changeset/android-recovery-review-fixes.md create mode 100644 .changeset/current-react-native-baseline.md create mode 100644 .github/workflows/native-regression.yml create mode 100644 examples/demo/android/app/src/androidTest/java/com/example/RNAppAuthRecoveryInstrumentation.java delete mode 100644 examples/demo/android/app/src/debug/AndroidManifest.xml create mode 100644 examples/demo/ios/Example/SceneDelegate.swift create mode 100644 examples/expo-cng/.yarnrc.yml create mode 100644 packages/react-native-app-auth/native-tests/android-recovery.sh create mode 100644 packages/react-native-app-auth/plugin.fixture-coverage.spec.ts create mode 100644 packages/react-native-app-auth/plugin/src/android/main-activity.ts diff --git a/.changeset/android-plugin-placeholder-scope.md b/.changeset/android-plugin-placeholder-scope.md new file mode 100644 index 000000000..733b11856 --- /dev/null +++ b/.changeset/android-plugin-placeholder-scope.md @@ -0,0 +1,5 @@ +--- +"react-native-app-auth": patch +--- + +Configure the Android redirect scheme in defaultConfig while preserving build-type-specific manifest placeholders, and recognize Kotlin imports with inline comments. diff --git a/.changeset/android-recovery-review-fixes.md b/.changeset/android-recovery-review-fixes.md new file mode 100644 index 000000000..01a0d1414 --- /dev/null +++ b/.changeset/android-recovery-review-fixes.md @@ -0,0 +1,5 @@ +--- +"react-native-app-auth": patch +--- + +Preserve existing Kotlin imports when configuring Android authorization recovery, including imports with inline comments. diff --git a/.changeset/current-react-native-baseline.md b/.changeset/current-react-native-baseline.md new file mode 100644 index 000000000..071300415 --- /dev/null +++ b/.changeset/current-react-native-baseline.md @@ -0,0 +1,5 @@ +--- +"react-native-app-auth": major +--- + +Require React Native 0.86+, iOS 15.1+, Android API 24+, and Expo SDK 57+ for the config plugin. Update the CLI example to React Native 0.87 and update the Expo development-build example to SDK 57. Applications on older React Native versions should remain on the 8.x release line. diff --git a/.github/workflows/native-regression.yml b/.github/workflows/native-regression.yml new file mode 100644 index 000000000..cdc8bf8d2 --- /dev/null +++ b/.github/workflows/native-regression.yml @@ -0,0 +1,54 @@ +name: Native Regression + +on: + workflow_dispatch: + +permissions: + contents: read + +jobs: + ios-presenter: + runs-on: macos-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v4 + - name: Boot an iOS simulator + run: | + simulator_id=$(xcrun simctl list devices available --json | python3 -c 'import json, sys; print(next(d["udid"] for runtime, devices in json.load(sys.stdin)["devices"].items() if ".iOS-" in runtime for d in devices if "iPhone" in d["name"]))') + xcrun simctl boot "$simulator_id" + xcrun simctl bootstatus "$simulator_id" -b + echo "SIMULATOR_ID=$simulator_id" >> "$GITHUB_ENV" + - name: Test native iOS presenter selection + run: bash packages/react-native-app-auth/native-tests/ios-presentation.sh "$SIMULATOR_ID" + + android-recovery: + runs-on: ubuntu-latest + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: 17 + - uses: android-actions/setup-android@v3 + - name: Install native build tools + run: sdkmanager 'platforms;android-37.0' 'build-tools;37.0.0' 'ndk;27.1.12297006' 'cmake;3.22.1' + - name: Install JavaScript dependencies + run: yarn install --frozen-lockfile + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Test native Android authorization recovery + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 36 + arch: x86_64 + target: google_apis + disable-animations: true + script: bash packages/react-native-app-auth/native-tests/android-recovery.sh emulator-5554 diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 3f351608e..3caca013b 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -17,7 +17,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'yarn' - name: Install dependencies diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d98da06f0..b5361d202 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,7 @@ jobs: - name: Use Node.js uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 22 cache: 'yarn' - name: Upgrade npm for OIDC diff --git a/README.md b/README.md index 75893ffbe..7503bbb7a 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@

-This versions supports `react-native@0.63+`. The last pre-0.63 compatible version is [`v5.1.3`](https://github.com/FormidableLabs/react-native-app-auth/tree/v5.1.3). +This version supports React Native 0.86+, iOS 15.1+, Android API 24+, and Expo SDK 57+ with development builds. Use the 8.x release line for older React Native applications. React Native bridge for [AppAuth-iOS](https://github.com/openid/AppAuth-iOS) and [AppAuth-Android](https://github.com/openid/AppAuth-Android) SDKS for communicating with diff --git a/docs/docs/introduction.md b/docs/docs/introduction.md index 5e03e1d26..ea5ab2bfe 100644 --- a/docs/docs/introduction.md +++ b/docs/docs/introduction.md @@ -5,6 +5,8 @@ slug: / # Introduction +This version requires React Native 0.86+, iOS 15.1+, and Android API 24+. Expo applications require SDK 57+ and a development build; Expo Go does not include this native module. Use the 8.x release line for older applications. + Get started by installing the dependencies in your application ```sh @@ -39,7 +41,7 @@ try { } ``` -## Expo Setup (SDK 53+) +## Expo Setup (SDK 57+) If you're using **Expo with Continuous Native Generation (CNG)**, you can use our config plugin for automatic setup: @@ -115,8 +117,7 @@ AppAuth supports three options for dependency management. #### Register redirect URL scheme -If you intend to support iOS 10 and older, you need to define the supported redirect URL schemes in -your `Info.plist` as follows: +Define your redirect URL scheme in `Info.plist` so iOS can route OAuth callbacks to your app: ```xml CFBundleURLTypes @@ -272,7 +273,7 @@ If you want to support universal links, add the following to `AppDelegate.mm` un + @property(nonatomic, weak)idauthorizationFlowManagerDelegate; ``` -Add the following code to `AppDelegate.m` (to support iOS 10, React Navigation deep linking and overriding browser behavior in the authorization process) +Add the following code to `AppDelegate.m` (for React Navigation deep linking and custom browsers) ```diff + - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *) options { diff --git a/docs/docs/usage/expo-setup.md b/docs/docs/usage/expo-setup.md index 7f9216524..129e89f30 100644 --- a/docs/docs/usage/expo-setup.md +++ b/docs/docs/usage/expo-setup.md @@ -4,11 +4,11 @@ sidebar_position: 1 # Expo Setup -React Native App Auth provides seamless integration with Expo through our config plugin, supporting **Expo SDK 53+** with Continuous Native Generation (CNG). +React Native App Auth provides seamless integration with Expo through our config plugin, supporting **Expo SDK 57+** with Continuous Native Generation (CNG). ## Prerequisites -- Expo SDK 53 or later +- Expo SDK 57 or later - CNG workflow (not Expo Go) - `expo prebuild` capability @@ -59,6 +59,14 @@ This automatically: - **iOS**: Adds URL scheme to `Info.plist` and configures bridging headers - **Android**: Sets up manifest placeholders in `build.gradle` +The plugin also forwards Android activity results for `resumePendingAuthorize()`. +Call that method at startup with the same token-exchange options as `authorize()` +to recover a browser flow after Android recreates the application process. + +For iOS scene support, put `expo-build-properties` after `react-native-app-auth` +in the plugins array and set its `ios.enableSceneSupport` option to `true`. +The SDK 57 scene delegate forwards URL callbacks to the patched AppDelegate. + ### 4. Use the Library ```typescript @@ -170,14 +178,14 @@ If you have React Navigation deep linking, ensure your OAuth scheme is different If you're migrating from manual iOS/Android setup: 1. Remove manual URL scheme configurations from `Info.plist` and `build.gradle` -2. Remove manual AppDelegate modifications (the plugin handles this automatically for Expo SDK 53+) +2. Remove manual AppDelegate modifications (the plugin handles this automatically for Expo SDK 57+) 3. Add the plugin configuration to `app.json` 4. Run `npx expo prebuild --clean` ## Limitations -- **Expo SDK 53+ only**: Earlier versions require [manual setup](../#manual-setup) +- **Expo SDK 57+ only**: Earlier versions require [manual setup](../#manual-setup) - **CNG workflow only**: Expo Go is not supported (OAuth requires native configuration) - **First-party providers**: Some OAuth providers may require additional native configuration -For advanced use cases or non-Expo projects, see the [Manual Setup Guide](../#manual-setup). \ No newline at end of file +For advanced use cases or non-Expo projects, see the [Manual Setup Guide](../#manual-setup). diff --git a/docs/docs/usage/manual-setup.md b/docs/docs/usage/manual-setup.md index 6574a1f44..98093b163 100644 --- a/docs/docs/usage/manual-setup.md +++ b/docs/docs/usage/manual-setup.md @@ -57,8 +57,7 @@ AppAuth supports three options for dependency management. ### Register redirect URL scheme -If you intend to support iOS 10 and older, you need to define the supported redirect URL schemes in -your `Info.plist` as follows: +Define your redirect URL scheme in `Info.plist` so iOS can route OAuth callbacks to your app: ```xml CFBundleURLTypes @@ -214,7 +213,7 @@ If you want to support universal links, add the following to `AppDelegate.mm` un + @property(nonatomic, weak)idauthorizationFlowManagerDelegate; ``` -Add the following code to `AppDelegate.m` (to support iOS 10, React Navigation deep linking and overriding browser behavior in the authorization process) +Add the following code to `AppDelegate.m` (for React Navigation deep linking and custom browsers) ```diff + - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *) options { diff --git a/examples/demo/App.tsx b/examples/demo/App.tsx index c5593b511..c8a0de6cd 100644 --- a/examples/demo/App.tsx +++ b/examples/demo/App.tsx @@ -11,12 +11,12 @@ import { StatusBar, useColorScheme, Text, - SafeAreaView, StyleSheet, Pressable, View, ScrollView, } from 'react-native'; +import {SafeAreaProvider, SafeAreaView} from 'react-native-safe-area-context'; import { AuthConfiguration, authorize, @@ -196,49 +196,51 @@ function App(): React.JSX.Element { }, [authState]); return ( - - - + + + + -
+
- - - - - - -