Skip to content

Commit 0e8c06d

Browse files
Merge branch 'master' of https://github.com/auth0/react-native-auth0 into feat/native-to-web-sso
2 parents 40aec34 + f63fd8c commit 0e8c06d

36 files changed

+1656
-417
lines changed

.github/workflows/publish-docs.yml

Lines changed: 55 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,70 @@
11
name: PUBLISH DOCS
22
on:
3-
workflow_dispatch:
4-
workflow_call:
5-
# or set up your own custom triggers
3+
workflow_dispatch:
4+
workflow_call:
5+
# or set up your own custom triggers
66
permissions:
7-
contents: write # allows the 'Commit' step without tokens
7+
contents: write # allows the 'Commit' step without tokens
88

99
jobs:
10-
get_history: # create an artifact from the existing documentation builds
11-
runs-on: ubuntu-latest
12-
steps:
13-
- name: get the gh-pages repo
14-
uses: actions/checkout@v6
15-
with:
16-
ref: gh-pages
10+
get_history: # create an artifact from the existing documentation builds
11+
runs-on: ubuntu-latest
12+
steps:
13+
- name: get the gh-pages repo
14+
uses: actions/checkout@v6
15+
with:
16+
ref: gh-pages
1717

18-
- name: remove all symbolic links from root if present
19-
run: |
20-
find . -maxdepth 1 -type l -delete
18+
- name: remove all symbolic links from root if present
19+
run: |
20+
find . -maxdepth 1 -type l -delete
2121
22-
- name: tar the existing docs from root
23-
run: |
24-
tar -cvf documentation.tar ./
22+
- name: tar the existing docs from root
23+
run: |
24+
tar -cvf documentation.tar ./
2525
26-
- name: create a document artifact
27-
uses: actions/upload-artifact@v5
28-
with:
29-
name: documentation
30-
path: documentation.tar
31-
retention-days: 1
26+
- name: create a document artifact
27+
uses: actions/upload-artifact@v5
28+
with:
29+
name: documentation
30+
path: documentation.tar
31+
retention-days: 1
3232

33-
build_and_deploy: # builds the distribution and then the documentation
34-
needs: get_history
35-
runs-on: ubuntu-latest
36-
permissions:
37-
contents: write
38-
steps:
39-
- name: Checkout src
40-
uses: actions/checkout@v6
41-
with:
42-
token: ${{ github.token }}
33+
build_and_deploy: # builds the distribution and then the documentation
34+
needs: get_history
35+
runs-on: ubuntu-latest
36+
permissions:
37+
contents: write
38+
steps:
39+
- name: Checkout src
40+
uses: actions/checkout@v6
41+
with:
42+
token: ${{ github.token }}
4343

44-
- name: Download the existing documents artifact
45-
uses: actions/download-artifact@v6
46-
with:
47-
name: documentation
48-
- run: rm -rf ./docs # delete previous docs folder present
49-
- run: mkdir ./docs # create an empty docs folder
50-
- run: tar -xf documentation.tar -C ./docs
51-
- run: rm -f documentation.tar
44+
- name: Download the existing documents artifact
45+
uses: actions/download-artifact@v6
46+
with:
47+
name: documentation
48+
- run: rm -rf ./docs # delete previous docs folder present
49+
- run: mkdir ./docs # create an empty docs folder
50+
- run: tar -xf documentation.tar -C ./docs
51+
- run: rm -f documentation.tar
5252

53-
- name: Setup
54-
uses: ./.github/actions/setup
53+
- name: Setup
54+
uses: ./.github/actions/setup
5555

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

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

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

65-
- name: Deploy to GitHub Pages
66-
uses: peaceiris/actions-gh-pages@v4
67-
with:
68-
github_token: ${{ github.token }}
69-
publish_dir: ./docs
70-
keep_files: false
65+
- name: Deploy to GitHub Pages
66+
uses: peaceiris/actions-gh-pages@v4
67+
with:
68+
github_token: ${{ github.token }}
69+
publish_dir: ./docs
70+
keep_files: false

EXAMPLES.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
- [Handling DPoP token migration](#handling-dpop-token-migration)
2626
- [Checking token type](#checking-token-type)
2727
- [Handling nonce errors](#handling-nonce-errors)
28+
- [Multi-Resource Refresh Tokens (MRRT)](#multi-resource-refresh-tokens-mrrt)
29+
- [Overview](#mrrt-overview)
30+
- [Prerequisites](#mrrt-prerequisites)
31+
- [Using MRRT with Hooks](#using-mrrt-with-hooks)
32+
- [Using MRRT with Auth0 Class](#using-mrrt-with-auth0-class)
33+
- [Web Platform Configuration](#web-platform-configuration)
2834
- [Bot Protection](#bot-protection)
2935
- [Domain Switching](#domain-switching)
3036
- [Android](#android)
@@ -304,6 +310,128 @@ auth0.webAuth
304310

305311
If the URL doesn't contain the expected values, an error will be raised through the provided callback.
306312

313+
## Multi-Resource Refresh Tokens (MRRT)
314+
315+
### MRRT Overview
316+
317+
Multi-Resource Refresh Tokens (MRRT) allow your application to obtain access tokens for multiple APIs using a single refresh token. This is useful when your application needs to access multiple backend services, each identified by a different audience.
318+
319+
### MRRT Prerequisites
320+
321+
Before using MRRT, ensure:
322+
323+
1. **MRRT is enabled on your Auth0 tenant** - Contact Auth0 support or enable it through the Auth0 Dashboard
324+
2. **Request `offline_access` scope during login** - This ensures a refresh token is issued
325+
3. **Configure your APIs in Auth0 Dashboard** - Each API you want to access should be registered with its own audience identifier
326+
327+
### Using MRRT with Hooks
328+
329+
```tsx
330+
import { useAuth0 } from 'react-native-auth0';
331+
332+
function MyComponent() {
333+
const { authorize, getApiCredentials, clearApiCredentials } = useAuth0();
334+
335+
const login = async () => {
336+
// Login with offline_access to get a refresh token
337+
await authorize({
338+
scope: 'openid profile email offline_access',
339+
audience: 'https://primary-api.example.com',
340+
});
341+
};
342+
343+
const getFirstApiToken = async () => {
344+
try {
345+
// Get credentials for the first API
346+
const credentials = await getApiCredentials(
347+
'https://first-api.example.com',
348+
'read:data write:data'
349+
);
350+
console.log('First API Access Token:', credentials.accessToken);
351+
console.log('Expires At:', new Date(credentials.expiresAt * 1000));
352+
} catch (error) {
353+
console.error('Error:', error);
354+
}
355+
};
356+
357+
const getSecondApiToken = async () => {
358+
try {
359+
// Get credentials for a different API using the same refresh token
360+
const credentials = await getApiCredentials(
361+
'https://second-api.example.com',
362+
'read:reports'
363+
);
364+
console.log('Second API Access Token:', credentials.accessToken);
365+
} catch (error) {
366+
console.error('Error:', error);
367+
}
368+
};
369+
370+
const clearFirstApiCache = async () => {
371+
// Clear cached credentials for a specific API
372+
await clearApiCredentials('https://first-api.example.com');
373+
};
374+
375+
return (
376+
// Your UI components
377+
);
378+
}
379+
```
380+
381+
### Using MRRT with Auth0 Class
382+
383+
```js
384+
import Auth0 from 'react-native-auth0';
385+
386+
const auth0 = new Auth0({
387+
domain: 'YOUR_AUTH0_DOMAIN',
388+
clientId: 'YOUR_AUTH0_CLIENT_ID',
389+
});
390+
391+
// Login with offline_access scope
392+
await auth0.webAuth.authorize({
393+
scope: 'openid profile email offline_access',
394+
audience: 'https://primary-api.example.com',
395+
});
396+
397+
// Get credentials for a specific API
398+
const apiCredentials = await auth0.credentialsManager.getApiCredentials(
399+
'https://first-api.example.com',
400+
'read:data write:data'
401+
);
402+
403+
console.log('Access Token:', apiCredentials.accessToken);
404+
console.log('Token Type:', apiCredentials.tokenType);
405+
console.log('Expires At:', apiCredentials.expiresAt);
406+
console.log('Scope:', apiCredentials.scope);
407+
408+
// Clear cached credentials for a specific API
409+
await auth0.credentialsManager.clearApiCredentials(
410+
'https://first-api.example.com'
411+
);
412+
```
413+
414+
### Web Platform Configuration
415+
416+
On the **web platform**, you must explicitly enable MRRT support in the `Auth0Provider`:
417+
418+
```tsx
419+
import { Auth0Provider } from 'react-native-auth0';
420+
421+
function App() {
422+
return (
423+
<Auth0Provider
424+
domain="your-domain.auth0.com"
425+
clientId="your-client-id"
426+
useMrrt={true}
427+
cacheLocation="localstorage"
428+
>
429+
<YourApp />
430+
</Auth0Provider>
431+
);
432+
}
433+
```
434+
307435
## Bot Protection
308436

309437
If you are using the [Bot Protection](https://auth0.com/docs/anomaly-detection/bot-protection) feature and performing database login/signup via the Authentication API, you need to handle the `requires_verification` error. It indicates that the request was flagged as suspicious and an additional verification step is necessary to log the user in. That verification step is web-based, so you need to use Universal Login to complete it.

FAQ.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ function App() {
391391
const onLogin = async () => {
392392
await authorize({
393393
audience: AUDIENCE,
394-
scope: 'openid profile email offline_access'
394+
scope: 'openid profile email offline_access',
395395
});
396396
};
397397

@@ -400,7 +400,7 @@ function App() {
400400
const credentials = await getCredentials(
401401
'openid profile email offline_access',
402402
0,
403-
{ audience: AUDIENCE } // ← Must include audience here!
403+
{ audience: AUDIENCE } // ← Must include audience here!
404404
);
405405
console.log('JWT Access Token:', credentials.accessToken);
406406
};
@@ -427,15 +427,15 @@ Define your auth configuration once and reuse it:
427427
```javascript
428428
const AUTH_CONFIG = {
429429
audience: 'https://your-api.example.com',
430-
scope: 'openid profile email offline_access'
430+
scope: 'openid profile email offline_access',
431431
};
432432

433433
// Login
434434
await authorize(AUTH_CONFIG);
435435

436436
// Get credentials later (include audience in parameters)
437437
await getCredentials(AUTH_CONFIG.scope, 0, {
438-
audience: AUTH_CONFIG.audience
438+
audience: AUTH_CONFIG.audience,
439439
});
440440
```
441441

@@ -444,13 +444,13 @@ await getCredentials(AUTH_CONFIG.scope, 0, {
444444
```javascript
445445
const auth0 = new Auth0({
446446
domain: 'YOUR_DOMAIN',
447-
clientId: 'YOUR_CLIENT_ID'
447+
clientId: 'YOUR_CLIENT_ID',
448448
});
449449

450450
// Login
451451
await auth0.webAuth.authorize({
452452
audience: 'https://your-api.example.com',
453-
scope: 'openid profile email offline_access'
453+
scope: 'openid profile email offline_access',
454454
});
455455

456456
// Get credentials (must include audience)

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,9 +212,9 @@ To use the SDK with Expo, configure the app at build time by providing the `doma
212212

213213
> :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)
214214
215-
| API | Description |
216-
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
217-
| domain | Mandatory: Provide the Auth0 domain that can be found at the [Application Settings](https://manage.auth0.com/#/applications) |
215+
| API | Description |
216+
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
217+
| domain | Mandatory: Provide the Auth0 domain that can be found at the [Application Settings](https://manage.auth0.com/#/applications) |
218218
| 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"`. |
219219

220220
**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.

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ dependencies {
9696
implementation "com.facebook.react:react-android"
9797
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
9898
implementation "androidx.browser:browser:1.2.0"
99-
implementation 'com.auth0.android:auth0:3.10.0'
99+
implementation 'com.auth0.android:auth0:3.11.0'
100100
}
101101

102102
if (isNewArchitectureEnabled()) {

0 commit comments

Comments
 (0)