Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
8966a87
feat: added support for MRRT on Android/iOS
subhankarmaiti Jul 29, 2025
e02ca6b
feat: add support for Multi-Resource Refresh Tokens (MRRT) in WebAuth…
subhankarmaiti Aug 6, 2025
ce2a7c6
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Sep 9, 2025
20ea213
fix: add environment specification for test job
subhankarmaiti Sep 9, 2025
6aa0180
Revert "fix: add environment specification for test job"
subhankarmaiti Sep 10, 2025
a1458c3
Merge branch 'master' into SDK-6263_mrrt_support
arpit-jn Oct 4, 2025
a5fb232
chore: updated auth0.swift, auth0.android and spa-js to support the DPoP
subhankarmaiti Oct 7, 2025
dc10e43
android native layer changes
subhankarmaiti Oct 7, 2025
d1bcb71
feat: add DPoP support in Auth0 initialization and new methods for DP…
subhankarmaiti Oct 7, 2025
10a4e3b
feat: implement DPoP support with error handling and header generatio…
subhankarmaiti Oct 16, 2025
e8182e5
feat: update auth0-spa-js to version 2.7.0 and adjust DPoP proof gene…
subhankarmaiti Oct 21, 2025
920bf99
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Oct 21, 2025
7909449
feat: enhance Jest environment and tests with DPoP key handling methods
subhankarmaiti Oct 22, 2025
f0546d0
feat: add test suites for getDPoPHeaders in NativeAuth0Client and Web…
subhankarmaiti Oct 22, 2025
7f0cce0
feat: add optional nonce parameter to getDPoPHeaders methods and upda…
subhankarmaiti Oct 23, 2025
e5a574d
feat: add optional nonce parameter to getDPoPHeaders method and valid…
subhankarmaiti Oct 23, 2025
ac59591
feat: update documentation to include DPoP features and migration gui…
subhankarmaiti Oct 29, 2025
58ce08c
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Oct 29, 2025
1edb925
feat: allow dynamic token type in Credentials and update documentation
subhankarmaiti Oct 29, 2025
b44cec8
Merge branch 'feat/dpop-support' of https://github.com/auth0/react-na…
subhankarmaiti Oct 29, 2025
6cb2524
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Oct 30, 2025
68cd580
feat: enhance API credentials management with detailed error handling…
subhankarmaiti Nov 14, 2025
1f994d2
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Nov 14, 2025
d4b153b
fix: bind Auth0NativeModule context in getApiCredentials and clearApi…
subhankarmaiti Nov 14, 2025
8bc36ac
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Nov 18, 2025
4afe3ab
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Nov 25, 2025
860205b
Merge branch 'master' of https://github.com/auth0/react-native-auth0 …
subhankarmaiti Nov 25, 2025
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
110 changes: 55 additions & 55 deletions .github/workflows/publish-docs.yml
Original file line number Diff line number Diff line change
@@ -1,70 +1,70 @@
name: PUBLISH DOCS
on:
workflow_dispatch:
workflow_call:
# or set up your own custom triggers
workflow_dispatch:
workflow_call:
# or set up your own custom triggers
permissions:
contents: write # allows the 'Commit' step without tokens
contents: write # allows the 'Commit' step without tokens

jobs:
get_history: # create an artifact from the existing documentation builds
runs-on: ubuntu-latest
steps:
- name: get the gh-pages repo
uses: actions/checkout@v6
with:
ref: gh-pages
get_history: # create an artifact from the existing documentation builds
runs-on: ubuntu-latest
steps:
- name: get the gh-pages repo
uses: actions/checkout@v6
with:
ref: gh-pages

- name: remove all symbolic links from root if present
run: |
find . -maxdepth 1 -type l -delete
- name: remove all symbolic links from root if present
run: |
find . -maxdepth 1 -type l -delete

- name: tar the existing docs from root
run: |
tar -cvf documentation.tar ./
- name: tar the existing docs from root
run: |
tar -cvf documentation.tar ./

- name: create a document artifact
uses: actions/upload-artifact@v5
with:
name: documentation
path: documentation.tar
retention-days: 1
- name: create a document artifact
uses: actions/upload-artifact@v5
with:
name: documentation
path: documentation.tar
retention-days: 1

build_and_deploy: # builds the distribution and then the documentation
needs: get_history
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout src
uses: actions/checkout@v6
with:
token: ${{ github.token }}
build_and_deploy: # builds the distribution and then the documentation
needs: get_history
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout src
uses: actions/checkout@v6
with:
token: ${{ github.token }}

- name: Download the existing documents artifact
uses: actions/download-artifact@v6
with:
name: documentation
- run: rm -rf ./docs # delete previous docs folder present
- run: mkdir ./docs # create an empty docs folder
- run: tar -xf documentation.tar -C ./docs
- run: rm -f documentation.tar
- name: Download the existing documents artifact
uses: actions/download-artifact@v6
with:
name: documentation
- run: rm -rf ./docs # delete previous docs folder present
- run: mkdir ./docs # create an empty docs folder
- run: tar -xf documentation.tar -C ./docs
- run: rm -f documentation.tar

- name: Setup
uses: ./.github/actions/setup
- name: Setup
uses: ./.github/actions/setup

- name: Build documents
run: yarn docs #set up 'docs' build script in your package.json
- name: Build documents
run: yarn docs #set up 'docs' build script in your package.json

- name: Remove all the symbolic links from docs folder
run: find ./docs -type l -delete
- name: Remove all the symbolic links from docs folder
run: find ./docs -type l -delete

- name: Run cleanup and manage document versions
run: node scripts/manage-doc-versions.js
- name: Run cleanup and manage document versions
run: node scripts/manage-doc-versions.js

- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ github.token }}
publish_dir: ./docs
keep_files: false
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ github.token }}
publish_dir: ./docs
keep_files: false
12 changes: 6 additions & 6 deletions FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ function App() {
const onLogin = async () => {
await authorize({
audience: AUDIENCE,
scope: 'openid profile email offline_access'
scope: 'openid profile email offline_access',
});
};

Expand All @@ -400,7 +400,7 @@ function App() {
const credentials = await getCredentials(
'openid profile email offline_access',
0,
{ audience: AUDIENCE } // ← Must include audience here!
{ audience: AUDIENCE } // ← Must include audience here!
);
console.log('JWT Access Token:', credentials.accessToken);
};
Expand All @@ -427,15 +427,15 @@ Define your auth configuration once and reuse it:
```javascript
const AUTH_CONFIG = {
audience: 'https://your-api.example.com',
scope: 'openid profile email offline_access'
scope: 'openid profile email offline_access',
};

// Login
await authorize(AUTH_CONFIG);

// Get credentials later (include audience in parameters)
await getCredentials(AUTH_CONFIG.scope, 0, {
audience: AUTH_CONFIG.audience
audience: AUTH_CONFIG.audience,
});
```

Expand All @@ -444,13 +444,13 @@ await getCredentials(AUTH_CONFIG.scope, 0, {
```javascript
const auth0 = new Auth0({
domain: 'YOUR_DOMAIN',
clientId: 'YOUR_CLIENT_ID'
clientId: 'YOUR_CLIENT_ID',
});

// Login
await auth0.webAuth.authorize({
audience: 'https://your-api.example.com',
scope: 'openid profile email offline_access'
scope: 'openid profile email offline_access',
});

// Get credentials (must include audience)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ To use the SDK with Expo, configure the app at build time by providing the `doma

> :info: If you want to switch between multiple domains in your app, refer [here](https://github.com/auth0/react-native-auth0/blob/master/EXAMPLES.md#domain-switching)

| API | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domain | Mandatory: Provide the Auth0 domain that can be found at the [Application Settings](https://manage.auth0.com/#/applications) |
| API | Description |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| domain | Mandatory: Provide the Auth0 domain that can be found at the [Application Settings](https://manage.auth0.com/#/applications) |
| customScheme | Optional: Custom scheme to build the callback URL with. The value provided here should be passed to the `customScheme` option parameter of the `authorize` and `clearSession` methods. The custom scheme should be a unique, all lowercase value with no special characters. To use Android App Links, set this value to `"https"`. |

**Note:** When using `customScheme: "https"` for Android App Links, the plugin will automatically add `android:autoVerify="true"` to the intent-filter in your Android manifest to enable automatic verification of App Links.
Expand Down
41 changes: 41 additions & 0 deletions android/src/main/java/com/auth0/react/A0Auth0Module.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.app.Activity
import android.content.Intent
import androidx.fragment.app.FragmentActivity
import com.auth0.android.Auth0
import com.auth0.android.result.APICredentials
import com.auth0.android.authentication.AuthenticationAPIClient
import com.auth0.android.authentication.AuthenticationException
import com.auth0.android.authentication.storage.CredentialsManagerException
Expand Down Expand Up @@ -290,6 +291,46 @@ class A0Auth0Module(private val reactContext: ReactApplicationContext) : A0Auth0
promise.resolve(secureCredentialsManager.hasValidCredentials(minTtl.toLong()))
}

@ReactMethod
override fun getApiCredentials(
audience: String,
scope: String?,
minTtl: Double,
parameters: ReadableMap,
promise: Promise
) {
val cleanedParameters = mutableMapOf<String, String>()
parameters.toHashMap().forEach { (key, value) ->
value?.let { cleanedParameters[key] = it.toString() }
}

UiThreadUtil.runOnUiThread {
secureCredentialsManager.getApiCredentials(
audience,
scope,
minTtl.toInt(),
cleanedParameters,
emptyMap(), // headers not supported from JS yet

Choose a reason for hiding this comment

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

Empty headers map comment is misleading

The comment says "headers not supported from JS yet", but headers are not being passed because the React Native bridge doesn't expose this parameter. Consider either:

  1. Adding header support if it's a planned feature
  2. Or updating the comment to clarify this is by design for security reasons (headers from JS could pose security risks)

object : com.auth0.android.callback.Callback<APICredentials, CredentialsManagerException> {
override fun onSuccess(credentials: APICredentials) {
val map = ApiCredentialsParser.toMap(credentials)
promise.resolve(map)
}

override fun onFailure(e: CredentialsManagerException) {
val errorCode = deduceErrorCode(e)
promise.reject(errorCode, e.message, e)
}
}
)
}
}

@ReactMethod
override fun clearApiCredentials(audience: String, promise: Promise) {
secureCredentialsManager.clearApiCredentials(audience)
promise.resolve(true)
}

Choose a reason for hiding this comment

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

Missing blank line before closing brace

For consistency with the rest of the class structure, there should be a blank line before the closing method brace and the next method/property.

Suggested change
}
secureCredentialsManager.clearApiCredentials(audience)
promise.resolve(true)
}

override fun getConstants(): Map<String, String> {
return mapOf("bundleIdentifier" to reactContext.applicationInfo.packageName)
}
Expand Down
22 changes: 22 additions & 0 deletions android/src/main/java/com/auth0/react/ApiCredentialsParser.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.auth0.react

import com.auth0.android.result.APICredentials
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReadableMap

object ApiCredentialsParser {

private const val ACCESS_TOKEN_KEY = "accessToken"
private const val EXPIRES_AT_KEY = "expiresAt"
private const val SCOPE_KEY = "scope"
private const val TOKEN_TYPE_KEY = "tokenType"

fun toMap(credentials: APICredentials): ReadableMap {
val map = Arguments.createMap()
map.putString(ACCESS_TOKEN_KEY, credentials.accessToken)
map.putDouble(EXPIRES_AT_KEY, credentials.expiresAt.time / 1000.0)
map.putString(SCOPE_KEY, credentials.scope)
map.putString(TOKEN_TYPE_KEY, credentials.type)
return map
}
}

Choose a reason for hiding this comment

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

Missing newline at end of file

The file should end with a newline character for POSIX compliance and consistency with the rest of the codebase.

Suggested change
}
}
}

14 changes: 14 additions & 0 deletions android/src/main/oldarch/com/auth0/react/A0Auth0Spec.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,20 @@ abstract class A0Auth0Spec(context: ReactApplicationContext) : ReactContextBaseJ
@DoNotStrip
abstract fun clearCredentials(promise: Promise)

@ReactMethod
@DoNotStrip
abstract fun getApiCredentials(
audience: String,
scope: String?,
minTTL: Double,
parameters: ReadableMap,
promise: Promise
)

@ReactMethod
@DoNotStrip
abstract fun clearApiCredentials(audience: String, promise: Promise)

@ReactMethod
@DoNotStrip
abstract fun webAuth(
Expand Down
9 changes: 8 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ export default defineConfig([
// TypeScript-specific configuration for type-checked rules
{
files: ['**/*.ts', '**/*.tsx'],
ignores: ['**/__tests__/**', '**/__mocks__/**', '**/*.spec.ts', '**/*.spec.tsx', '**/*.test.ts', '**/*.test.tsx'],
ignores: [
'**/__tests__/**',
'**/__mocks__/**',
'**/*.spec.ts',
'**/*.spec.tsx',
'**/*.test.ts',
'**/*.test.tsx',
],
languageOptions: {
parserOptions: {
project: true,
Expand Down
3 changes: 3 additions & 0 deletions example/src/navigation/MainTabNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import ProfileScreen from '../screens/hooks/Profile';
import ApiScreen from '../screens/hooks/Api';
import MoreScreen from '../screens/hooks/More';
import CredentialsScreen from '../screens/hooks/CredentialsScreen';

export type MainTabParamList = {
Profile: undefined;
Api: undefined;
More: undefined;
Credentials: undefined;
};

const Tab = createBottomTabNavigator<MainTabParamList>();
Expand All @@ -31,6 +33,7 @@ const MainTabNavigator = () => {
component={ProfileScreen}
// You can add icons here if desired
/>
<Tab.Screen name="Credentials" component={CredentialsScreen} />
<Tab.Screen name="Api" component={ApiScreen} />
<Tab.Screen name="More" component={MoreScreen} />
</Tab.Navigator>
Expand Down
Loading