Skip to content

Commit ecf0577

Browse files
subhankarmaitiguabuarpit-jnsnyk-bot
authored
feat: architectural refactor for multi-platform extensibility (#1233)
Co-authored-by: guabu <[email protected]> Co-authored-by: Arpit Jain <[email protected]> Co-authored-by: snyk-bot <[email protected]>
1 parent 90da85a commit ecf0577

File tree

155 files changed

+11861
-9782
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

155 files changed

+11861
-9782
lines changed

.husky/pre-push

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npm run prepush

.shiprc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"files": {
3-
"src/networking/telemetry.ts": [],
3+
"src/core/utils/telemetry.ts": [],
44
".version": []
55
},
66
"postbump": "node scripts/jsdocs.js"

EXAMPLES-WEB.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
# React Native Auth0 for Web: Examples
2+
3+
This guide provides usage examples specifically for developers targeting **React Native Web**. The web platform uses the underlying `@auth0/auth0-spa-js` library, and its features are aligned with browser security best practices.
4+
5+
## 1. The Hooks-Based Approach (Recommended)
6+
7+
This is the simplest and recommended way to integrate Auth0. The `Auth0Provider` handles all the complexity of the redirect flow automatically.
8+
9+
### Step 1: Wrap Your App in the `Auth0Provider`
10+
11+
In your main application entry point (e.g., `App.tsx`), wrap your application with the provider.
12+
13+
```jsx
14+
// src/App.tsx
15+
import React from 'react';
16+
import { Auth0Provider } from 'react-native-auth0';
17+
import config from './auth0-configuration';
18+
import MainComponent from './MainComponent'; // Your main app UI
19+
20+
const App = () => (
21+
<Auth0Provider domain={config.domain} clientId={config.clientId}>
22+
<MainComponent />
23+
</Auth0Provider>
24+
);
25+
26+
export default App;
27+
```
28+
29+
### Step 2: Use the `useAuth0` Hook in Your Components
30+
31+
The `Auth0Provider` will automatically handle the redirect callback when your app loads. The `useAuth0` hook will then provide the authentication state.
32+
33+
```jsx
34+
// src/MainComponent.tsx
35+
import React from 'react';
36+
import { useAuth0 } from 'react-native-auth0';
37+
import { View, Button, Text, ActivityIndicator } from 'react-native';
38+
39+
const MainComponent = () => {
40+
const { authorize, clearSession, user, isLoading, error } = useAuth0();
41+
42+
const onLogin = async () => {
43+
try {
44+
// This triggers a redirect to the Auth0 Universal Login page.
45+
await authorize({ scope: 'openid profile email' });
46+
} catch (e) {
47+
console.error('Login error:', e);
48+
}
49+
};
50+
51+
const onLogout = async () => {
52+
try {
53+
await clearSession();
54+
} catch (e) {
55+
console.error('Logout error:', e);
56+
}
57+
};
58+
59+
if (isLoading) {
60+
return (
61+
<View>
62+
<ActivityIndicator size="large" />
63+
</View>
64+
);
65+
}
66+
67+
return (
68+
<View>
69+
{error && <Text>Error: {error.message}</Text>}
70+
{user ? (
71+
<>
72+
<Text>Welcome, {user.name}!</Text>
73+
<Button title="Log Out" onPress={onLogout} />
74+
</>
75+
) : (
76+
<Button title="Log In" onPress={onLogin} />
77+
)}
78+
</View>
79+
);
80+
};
81+
```
82+
83+
## 2. The Class-Based / Manual Approach
84+
85+
If you are not using React Hooks or need more fine-grained control, you can instantiate the `Auth0` class and handle the redirect callback manually.
86+
87+
### Step 1: Instantiate the `Auth0` Client
88+
89+
Create a singleton instance of the client.
90+
91+
```javascript
92+
// src/api/auth0.ts
93+
import Auth0 from 'react-native-auth0';
94+
import config from '../auth0-configuration';
95+
96+
const auth0 = new Auth0({
97+
domain: config.domain,
98+
clientId: config.clientId,
99+
});
100+
101+
export default auth0;
102+
```
103+
104+
### Step 2: Handle the Redirect Callback
105+
106+
In your application's root component or entry point, you need to add logic to process the result from Auth0 after the user is redirected back.
107+
108+
```jsx
109+
// src/App.tsx
110+
import React, { useEffect, useState } from 'react';
111+
import { View, Button, Text } from 'react-native';
112+
import auth0 from './api/auth0'; // Import your singleton
113+
import type { User } from 'react-native-auth0';
114+
115+
const App = () => {
116+
const [user, setUser] = useState<User | null>(null);
117+
const [isLoading, setIsLoading] = useState(true);
118+
119+
useEffect(() => {
120+
const checkSession = async () => {
121+
// Check if the URL contains redirect parameters
122+
if (window.location.search.includes('code=') && window.location.search.includes('state=')) {
123+
try {
124+
// Process the redirect
125+
await auth0.webAuth.handleRedirectCallback();
126+
} catch (e) {
127+
console.error(e);
128+
}
129+
// Clean the URL
130+
window.history.replaceState({}, document.title, '/');
131+
}
132+
133+
// After handling a potential redirect, check for an existing session
134+
try {
135+
const credentials = await auth0.credentialsManager.getCredentials();
136+
// Assuming you have a way to decode the idToken to get the user
137+
// const decodedUser = jwt_decode(credentials.idToken);
138+
// setUser(decodedUser);
139+
} catch (e) {
140+
// No credentials, user is not logged in
141+
setUser(null);
142+
}
143+
setIsLoading(false);
144+
};
145+
146+
checkSession();
147+
}, []);
148+
149+
const onLogin = async () => {
150+
await auth0.webAuth.authorize({ scope: 'openid profile email' });
151+
};
152+
153+
const onLogout = async () => {
154+
await auth0.webAuth.clearSession();
155+
};
156+
157+
// ... Render UI based on isLoading and user state ...
158+
};
159+
```
160+
161+
## Unsupported Web Features
162+
163+
For security reasons, the web platform **does not support** direct authentication grants. The following methods from the `auth` provider will throw a `NotImplemented` error:
164+
165+
- `auth.passwordRealm()`
166+
- `auth.loginWithOTP()`
167+
- `auth.loginWithSMS()`
168+
- `auth.loginWithEmail()`
169+
- `auth.refreshToken()`
170+
171+
All these flows should be configured in your [Auth0 Universal Login](https://auth0.com/docs/universal-login) page and initiated via the `authorize()` method.

MIGRATION_GUIDE.md

Lines changed: 133 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2,69 +2,159 @@
22

33
## Upgrading from v4 -> v5
44

5-
### Compatibility Requirements
5+
Version 5.0 of `react-native-auth0` is a significant update featuring a complete architectural overhaul. This new foundation improves performance, maintainability, and provides a more consistent API across all platforms.
66

7-
- **React**: v5 requires React 19 or higher
8-
- **React Native**: v5 requires React Native 0.78.0 or higher
9-
- **Expo**: v5 requires Expo 53 or higher
7+
Upgrading from v4.x requires addressing several breaking changes. Please follow this guide carefully.
108

11-
### Breaking Changes
9+
## 1. Compatibility & Installation
1210

13-
- **Platform Compatibility**: The minimum iOS deployment target is now 14.0. Update your iOS/Podfile with:
11+
Before updating the library, ensure your project meets the new minimum requirements.
1412

15-
```
16-
platform :ios, '14.0'
17-
```
13+
### Environment Requirements
1814

19-
- **Android Requirements**: Android SDK API level 35 or higher is now required
15+
- **React:** `19.0.0` or higher
16+
- **React Native:** `0.78.0` or higher
17+
- **Expo:** SDK `53` or higher
18+
- **iOS:** Deployment Target `14.0`
19+
- **Android:** Target SDK `35` or higher
2020

21-
### Migration Steps
21+
### Updating Your Project
2222

23-
#### For Regular React Native Projects
23+
#### For Standard React Native Projects:
2424

25-
1. First, ensure your project uses React 19 and React Native 0.78.0 or higher:
25+
1. **Upgrade React Native:**
26+
```bash
27+
npm install react@^19.0.0 react-native@^0.78.0
28+
```
29+
2. **Update this Library:**
30+
```bash
31+
npm install react-native-auth0@beta
32+
```
33+
3. **Update iOS Target:** In your `ios/Podfile`, set the platform version:
34+
```ruby
35+
platform :ios, '14.0'
36+
```
37+
4. **Install Pods:**
38+
```bash
39+
cd ios && pod install && cd ..
40+
```
2641

27-
```bash
28-
npm install react@^19.0.0
29-
npm install react-native@^0.78.0
30-
```
42+
#### For Expo Projects:
3143

32-
2. Update the react-native-auth0 package:
44+
1. **Upgrade Expo SDK:**
45+
```bash
46+
npx expo upgrade
47+
```
48+
2. **Update this Library:**
49+
```bash
50+
npm install react-native-auth0@beta
51+
```
52+
3. **Rebuild Native Code:**
53+
```bash
54+
npx expo prebuild --clean
55+
```
56+
> **Warning:** This will overwrite any manual changes in your `ios` and `android` directories.
3357

34-
```bash
35-
npm install react-native-auth0@beta
36-
```
58+
## 2. Breaking API Changes
3759

38-
3. Update your iOS minimum deployment target in your Podfile:
60+
The following API changes require code modifications in your application.
3961

40-
```ruby
41-
platform :ios, '14.0'
42-
```
62+
### Change #1: User Profile Properties are now `camelCase`
4363

44-
4. Install the updated pods:
45-
```bash
46-
cd ios && pod install && cd ..
47-
```
64+
To align with modern JavaScript standards, all properties on the `user` object are now `camelCase`.
4865

49-
#### For Expo Projects
66+
**✅ Action Required:** Update all references to `user` properties.
5067

51-
1. Update to Expo 53 or higher:
68+
| Before (snake_case) | After (camelCase) |
69+
| :-------------------- | :------------------- |
70+
| `user.given_name` | `user.givenName` |
71+
| `user.family_name` | `user.familyName` |
72+
| `user.email_verified` | `user.emailVerified` |
73+
| `user.phone_number` | `user.phoneNumber` |
74+
| ...and so on. | |
5275

53-
```bash
54-
npx expo upgrade
55-
```
76+
### Change #2: Credentials Object uses `expiresAt`
5677

57-
2. Update the react-native-auth0 package:
78+
The `Credentials` object no longer includes `expiresIn` (a duration). It now provides `expiresAt`, an absolute **UNIX timestamp** (in seconds), making expiration checks simpler and less error-prone.
5879

59-
```bash
60-
npm install react-native-auth0@beta
61-
```
80+
**✅ Action Required:** Replace all logic using `expiresIn` with `expiresAt`.
6281

63-
3. Rebuild your app:
64-
```bash
65-
npx expo prebuild --clean
66-
```
67-
Note: This will reset any manual changes to your native code.
82+
**Before:**
83+
84+
```javascript
85+
const expiresAt = Date.now() / 1000 + credentials.expiresIn;
86+
if (isExpired(expiresAt)) {
87+
// ...
88+
}
89+
```
90+
91+
**After:**
92+
93+
```javascript
94+
// Direct comparison is now possible
95+
if (credentials.expiresAt < Date.now() / 1000) {
96+
// ...
97+
}
98+
99+
// Or, use the new helper method (if you have an instance of the Credentials model):
100+
if (credentials.isExpired()) {
101+
// ...
102+
}
103+
```
104+
105+
### Change #3: Standardized `AuthError` Object
106+
107+
All errors thrown by the library are now instances of a single, consistent `AuthError` class. This replaces multiple error types like `CredentialsManagerError`.
108+
109+
**✅ Action Required:** Update your `try...catch` blocks to handle the new unified error object.
110+
111+
**Before:**
112+
113+
```javascript
114+
catch (e) {
115+
// Inconsistent properties like e.error, e.error_description
116+
console.error(e.message);
117+
}
118+
```
119+
120+
**After:**
121+
122+
```javascript
123+
import { AuthError } from 'react-native-auth0';
124+
125+
catch (e) {
126+
if (e instanceof AuthError) {
127+
// Consistent properties are now available
128+
console.error(e.name, e.message); // e.g., 'invalid_grant', 'The refresh token is invalid.'
129+
}
130+
}
131+
```
132+
133+
### Change #4: Updated `authorize` and `clearSession` Signatures
134+
135+
For improved clarity, SDK-specific options (like `ephemeralSession`) have been moved into a separate, second `options` object.
136+
137+
**✅ Action Required:** Restructure calls to `authorize` and `clearSession`.
138+
139+
**Before:**
140+
141+
```javascript
142+
// Mixed parameters and options
143+
await authorize({
144+
scope: 'openid profile',
145+
ephemeralSession: true,
146+
});
147+
```
148+
149+
**After:**
150+
151+
```javascript
152+
// Parameters and options are now separate arguments
153+
await authorize(
154+
{ scope: 'openid profile' }, // 1. OIDC / Auth0 Parameters
155+
{ ephemeralSession: true } // 2. SDK-Specific Options
156+
);
157+
```
68158
69159
## Upgrading from v3 -> v4
70160

0 commit comments

Comments
 (0)