Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/android-plugin-placeholder-scope.md
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 5 additions & 0 deletions .changeset/android-recovery-review-fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-native-app-auth": patch
---

Preserve existing Kotlin imports when configuring Android authorization recovery, including imports with inline comments.
5 changes: 5 additions & 0 deletions .changeset/configured-headers-and-gradle-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-native-app-auth": patch
---

Respect configured Swift bridging headers, including inherited and configuration-specific paths, and use a fallback header when inheritance is empty. Preserve Gradle comments and ignore commented-out declarations and keys when adding Android redirect placeholders. Keep repeated plugin application idempotent.
5 changes: 5 additions & 0 deletions .changeset/current-react-native-baseline.md
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 5 additions & 0 deletions .changeset/gradle-placeholder-expressions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-native-app-auth": patch
---

Set the Android Expo redirect placeholder without rewriting existing Gradle maps. Preserve empty maps, additive assignments, expression values, and unrelated placeholders, and keep repeated plugin application idempotent.
5 changes: 5 additions & 0 deletions .changeset/ios-url-scheme-mod-result.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'react-native-app-auth': patch
---

Register the iOS OAuth callback scheme in the generated Info.plist mod result, including when another Expo mod supplies a separate plist object.
5 changes: 5 additions & 0 deletions .changeset/kotlin-result-handler-detection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'react-native-app-auth': patch
---

Detect existing Kotlin activity-result callbacks regardless of whitespace or comments, ignore commented-out integration, and preserve formatted AppAuth forwarding calls.
5 changes: 5 additions & 0 deletions .changeset/revocation-form-encoding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"react-native-app-auth": patch
---

Form-encode tokens and optional client IDs in revocation requests so special characters are sent unchanged to the provider.
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ examples/expo-cng/ios
examples/expo-cng/android
examples/expo-cng/*.tsbuildinfo


# The demo uses the repository root Yarn workspace lockfile.
/examples/demo/package-lock.json
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

</p>

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.

For Expo apps using iOS scenes, list `react-native-app-auth` before `expo-build-properties` and enable `ios.enableSceneSupport`. See the [Expo setup guide](./docs/docs/usage/expo-setup.md) for the complete configuration.

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
Expand Down Expand Up @@ -74,13 +76,17 @@ To learn more, read [this short introduction to OAuth and PKCE](https://formidab

Please see our [contributing guide](./.github/CONTRIBUTING.md).

The demo is a Yarn workspace. Install dependencies from the repository root with
Yarn 1.22.22; the root `yarn.lock` also resolves the local library for the demo.

### Running the iOS app

After cloning the repository, run the following:

```sh
cd react-native-app-auth/Example
yarn
cd react-native-app-auth
yarn install --frozen-lockfile
cd examples/demo
(cd ios && pod install)
npx react-native run-ios
```
Expand All @@ -90,8 +96,9 @@ npx react-native run-ios
After cloning the repository, run the following:

```sh
cd react-native-app-auth/Example
yarn
cd react-native-app-auth
yarn install --frozen-lockfile
cd examples/demo
npx react-native run-android
```

Expand Down
21 changes: 17 additions & 4 deletions docs/docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:

Expand All @@ -52,12 +54,24 @@ If you're using **Expo with Continuous Native Generation (CNG)**, you can use ou
{
"redirectUrls": ["com.yourapp.scheme://oauth"]
}
],
[
"expo-build-properties",
{
"ios": {
"enableSceneSupport": true
}
}
]
]
}
}
```

For iOS scenes, install `expo-build-properties` with `npx expo install expo-build-properties`
and keep it after `react-native-app-auth` in the plugins array. The reverse order
can cause the scene transformation to fail during prebuild.

Then run `expo prebuild` to generate your iOS and Android projects with the correct OAuth URL scheme configuration.

**📖 [Complete Expo Setup Guide →](./usage/expo-setup)**
Expand Down Expand Up @@ -115,8 +129,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
<key>CFBundleURLTypes</key>
Expand Down Expand Up @@ -272,7 +285,7 @@ If you want to support universal links, add the following to `AppDelegate.mm` un
+ @property(nonatomic, weak)id<RNAppAuthAuthorizationFlowManagerDelegate>authorizationFlowManagerDelegate;
```

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<NSString *, id> *) options {
Expand Down
41 changes: 32 additions & 9 deletions docs/docs/usage/expo-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -22,9 +22,17 @@ npm install react-native-app-auth
yarn add react-native-app-auth
```

For iOS scene support, also install `expo-build-properties`:

```bash
npx expo install expo-build-properties
```

### 2. Configure the Plugin

Add the plugin to your `app.json` or `app.config.js`:
Add the plugins to your `app.json` or `app.config.js`. For iOS scenes, keep
`react-native-app-auth` **before** `expo-build-properties`, as shown below.
The reverse order can cause the scene transformation to fail during prebuild.

```json
{
Expand All @@ -35,6 +43,14 @@ Add the plugin to your `app.json` or `app.config.js`:
{
"redirectUrls": ["com.yourapp.scheme://oauth"]
}
],
[
"expo-build-properties",
{
"ios": {
"enableSceneSupport": true
}
}
]
]
}
Expand All @@ -59,6 +75,12 @@ 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.

The SDK 57 scene delegate forwards URL callbacks to the patched AppDelegate.

### 4. Use the Library

```typescript
Expand Down Expand Up @@ -109,13 +131,14 @@ Check that the manifest placeholder was added to `android/app/build.gradle`:
```gradle
android {
defaultConfig {
manifestPlaceholders = [
appAuthRedirectScheme: 'com.yourapp.scheme',
]
manifestPlaceholders.appAuthRedirectScheme = 'com.yourapp.scheme'
}
}
```

The plugin sets this key after existing placeholder configuration, preserving
unrelated entries, map expressions, and additive assignments.

## TypeScript Support

The plugin is built with TypeScript and provides full type safety. Import types as needed:
Expand Down Expand Up @@ -170,14 +193,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).
For advanced use cases or non-Expo projects, see the [Manual Setup Guide](../#manual-setup).
5 changes: 2 additions & 3 deletions docs/docs/usage/manual-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
<key>CFBundleURLTypes</key>
Expand Down Expand Up @@ -214,7 +213,7 @@ If you want to support universal links, add the following to `AppDelegate.mm` un
+ @property(nonatomic, weak)id<RNAppAuthAuthorizationFlowManagerDelegate>authorizationFlowManagerDelegate;
```

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<NSString *, id> *) options {
Expand Down
82 changes: 42 additions & 40 deletions examples/demo/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -196,49 +196,51 @@ function App(): React.JSX.Element {
}, [authState]);

return (
<SafeAreaView>
<ScrollView>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
<SafeAreaProvider>
<SafeAreaView>
<ScrollView>
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />

<Header title="React Native App Auth Demo" />
<Header title="React Native App Auth Demo" />

<KeyValueLabel
label="Access Token"
value={authState.accessToken || 'N/A'}
/>
<KeyValueLabel
label="Access Token Expiration Date"
value={authState.accessTokenExpirationDate || 'N/A'}
/>
<KeyValueLabel
label="Refresh Token"
value={authState.refreshToken || 'N/A'}
/>
<KeyValueLabel label="Provider" value={authState.provider || 'N/A'} />
<KeyValueLabel
label="Scopes"
value={authState.scopes?.join(', ') || 'N/A'}
/>
<Row>
<Button
title="Login with Auth0"
onPress={() => handleAuthorize('auth0')}
<KeyValueLabel
label="Access Token"
value={authState.accessToken || 'N/A'}
/>
<Button
title="Login with IdentityServer"
onPress={() => handleAuthorize('identityserver')}
<KeyValueLabel
label="Access Token Expiration Date"
value={authState.accessTokenExpirationDate || 'N/A'}
/>
</Row>
<Row>
{authState.refreshToken ? (
<Button onPress={handleRefresh} title="Refresh" />
) : null}
{showRevoke ? (
<Button onPress={handleRevoke} title="Revoke" color="#EF525B" />
) : null}
</Row>
</ScrollView>
</SafeAreaView>
<KeyValueLabel
label="Refresh Token"
value={authState.refreshToken || 'N/A'}
/>
<KeyValueLabel label="Provider" value={authState.provider || 'N/A'} />
<KeyValueLabel
label="Scopes"
value={authState.scopes?.join(', ') || 'N/A'}
/>
<Row>
<Button
title="Login with Auth0"
onPress={() => handleAuthorize('auth0')}
/>
<Button
title="Login with IdentityServer"
onPress={() => handleAuthorize('identityserver')}
/>
</Row>
<Row>
{authState.refreshToken ? (
<Button onPress={handleRefresh} title="Refresh" />
) : null}
{showRevoke ? (
<Button onPress={handleRevoke} title="Revoke" color="#EF525B" />
) : null}
</Row>
</ScrollView>
</SafeAreaView>
</SafeAreaProvider>
);
}

Expand Down
Loading
Loading