Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ jobs:
- name: Run RL Scanner
uses: auth0/devsecops-tooling/.github/actions/rl-scan@main
with:
artifact-name: "react-native-auth0"
artifact-path: "${{ github.workspace }}/react-native-auth0.tgz"
artifact-name: 'react-native-auth0'
artifact-path: '${{ github.workspace }}/react-native-auth0.tgz'
version: ${{ steps.get_version.outputs.version }}
RLSECURE_LICENSE: ${{ secrets.RLSECURE_LICENSE }}
RLSECURE_SITE_KEY: ${{ secrets.RLSECURE_SITE_KEY }}
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
[Full Changelog](https://github.com/auth0/react-native-auth0/compare/v5.5.1...v5.6.0)

**Added**

- feat: surface DPoP credential state errors from native SDKs [\#1529](https://github.com/auth0/react-native-auth0/pull/1529) ([@subhankarmaiti](https://github.com/subhankarmaiti))
- feat(android): expose allowedBrowserPackages option for web authentication [\#1513](https://github.com/auth0/react-native-auth0/pull/1513) ([@mrbrentkelly](https://github.com/mrbrentkelly))

**Fixed**

- fix: apply deepCamelCase to MFA challenge response [\#1510](https://github.com/auth0/react-native-auth0/pull/1510) ([@AkhtarZaman7](https://github.com/AkhtarZaman7))
- docs: add Expo callback URL format to README [\#1522](https://github.com/auth0/react-native-auth0/pull/1522) ([@subhankarmaiti](https://github.com/subhankarmaiti))


## [v5.5.1](https://github.com/auth0/react-native-auth0/tree/v5.5.1) (2026-04-23)

[Full Changelog](https://github.com/auth0/react-native-auth0/compare/v5.5.0...v5.5.1)
Expand Down
122 changes: 114 additions & 8 deletions EXAMPLES-WEB.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,120 @@ const App = () => {
};
```

## Unsupported Web Features
## 3. MFA Flexible Factors Grant (Web)

For security reasons, the web platform **does not support** direct authentication grants. The following methods from the `auth` provider will throw a `NotImplemented` error:
The MFA Flexible Factors Grant is fully supported on the web platform. It uses the `@auth0/auth0-spa-js` MFA API under the hood.

- `auth.passwordRealm()`
- `auth.loginWithOTP()`
- `auth.loginWithSMS()`
- `auth.loginWithEmail()`
- `auth.refreshToken()`
### Using MFA with Hooks

All these flows should be configured in your [Auth0 Universal Login](https://auth0.com/docs/universal-login) page and initiated via the `authorize()` method.
```tsx
import React, { useState } from 'react';
import { View, Button, TextInput, Text } from 'react-native';
import { useAuth0, MfaError, MfaErrorCodes } from 'react-native-auth0';

function MfaScreen({ mfaToken }: { mfaToken: string }) {
const { mfa } = useAuth0();
const [otp, setOtp] = useState('');

const listAuthenticators = async () => {
try {
const authenticators = await mfa.getAuthenticators({ mfaToken });
console.log('Authenticators:', authenticators);
} catch (error) {
if (error instanceof MfaError) {
console.error('MFA error:', error.type, error.message);
}
}
};

const enrollTotp = async () => {
try {
const challenge = await mfa.enroll({ mfaToken, type: 'otp' });
if (challenge.type === 'totp') {
console.log('Scan QR:', challenge.barcodeUri);
console.log('Secret:', challenge.secret);
}
} catch (error) {
if (error instanceof MfaError) {
console.error('Enrollment error:', error.type);
}
}
};

const verifyOtp = async () => {
try {
const credentials = await mfa.verify({ mfaToken, otp });
console.log('Authenticated!', credentials.accessToken);
} catch (error) {
if (error instanceof MfaError) {
switch (error.type) {
case MfaErrorCodes.INVALID_OTP:
console.log('Incorrect code');
break;
case MfaErrorCodes.TOO_MANY_ATTEMPTS:
console.log('Too many attempts');
break;
case MfaErrorCodes.EXPIRED_MFA_TOKEN:
console.log('Session expired');
break;
}
}
}
};

return (
<View>
<Button title="List Authenticators" onPress={listAuthenticators} />
<Button title="Enroll TOTP" onPress={enrollTotp} />
<TextInput placeholder="Enter OTP" value={otp} onChangeText={setOtp} />
<Button title="Verify" onPress={verifyOtp} />
</View>
);
}
```

### Using MFA with Auth0 Class

```typescript
import Auth0, { MfaError, MfaErrorCodes } from 'react-native-auth0';

const auth0 = new Auth0({
domain: 'YOUR_AUTH0_DOMAIN',
clientId: 'YOUR_AUTH0_CLIENT_ID',
});

// List authenticators
const authenticators = await auth0.mfa.getAuthenticators({
mfaToken: 'mfa_token',
});

// Enroll TOTP
const challenge = await auth0.mfa.enroll({
mfaToken: 'mfa_token',
type: 'otp',
});

// Enroll SMS
const smsChallenge = await auth0.mfa.enroll({
mfaToken: 'mfa_token',
phoneNumber: '+12025550135',
});

// Challenge an authenticator
const challengeResult = await auth0.mfa.challenge({
mfaToken: 'mfa_token',
authenticatorId: 'sms|dev_123',
});

// Verify OTP
const credentials = await auth0.mfa.verify({
mfaToken: 'mfa_token',
otp: '123456',
});
```

## Web Platform Notes

The web platform supports direct authentication grants including `auth.passwordRealm()`, `auth.createUser()`, `auth.resetPassword()`, and the MFA Flexible Factors Grant. These methods make direct HTTP calls to the Auth0 API.

Token refresh is handled automatically by `credentialsManager.getCredentials()` on the web. The `auth.refreshToken()` method is not available.
Loading
Loading