@credocentral/e-identity-react-native
v1.0.2
Published
React Native SDK for e-identity OAuth2/OIDC authentication with MFA and passkey support
Readme
@credocentral/e-identity-react-native
React Native SDK for e-identity — OAuth2/OIDC authentication with MFA and passkey support.
Features
- OAuth2 Authorization Code + PKCE login via
react-native-app-auth(in-app browser) - Secure token storage via
react-native-keychain(iOS Keychain / Android Keystore) - Automatic token refresh
- MFA: TOTP, Email OTP, SMS OTP, passkey challenge & enrollment
- Recovery code fallback
- Forced password-change flow
- Pre-built screen components (navigation-agnostic, callback-based)
- Passkey native modules: iOS 16+ (
ASAuthorizationController) · Android API 28+ (CredentialManager)
Installation
npm install @credocentral/e-identity-react-native react-native-app-auth react-native-keychain react-native-get-random-valuesiOS
cd ios && pod installAdd the redirect scheme to Info.plist (for react-native-app-auth):
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>com.yourapp.auth</string>
</array>
</dict>
</array>Register the native module in your AppDelegate by adding EIdentityRNPackage to the packages list (auto-linking handles this in React Native 0.60+).
Android
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET"/>Add the redirect activity for react-native-app-auth:
<activity android:name="net.openid.appauth.RedirectUriReceiverActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="com.yourapp.auth"/>
</intent-filter>
</activity>Quick Start
import { EIdentityProvider, useEIdentity } from '@credocentral/e-identity-react-native';
const config = {
issuerUrl: 'https://id.example.com',
appId: 'your-app-uuid',
redirectScheme: 'com.yourapp.auth',
};
export function App() {
return (
<EIdentityProvider config={config}>
<Navigator />
</EIdentityProvider>
);
}
function HomeScreen() {
const { user, isAuthenticated, login, logout } = useEIdentity();
if (!isAuthenticated) return <Button title="Sign in" onPress={login} />;
return (
<View>
<Text>Welcome, {user?.firstName}</Text>
<Button title="Sign out" onPress={logout} />
</View>
);
}Guards
import { EIdentityGuard, MfaChallengeGate, ForcedPasswordChangeGate } from '@credocentral/e-identity-react-native';
// Redirect to login if not authenticated
<EIdentityGuard onUnauthenticated={() => navigation.replace('Login')}>
<HomeScreen />
</EIdentityGuard>
// Block access until MFA is complete
<MfaChallengeGate onMfaRequired={() => navigation.navigate('MfaChallenge', { challengeToken })}>
<SecureScreen />
</MfaChallengeGate>
// Block access until password is changed
<ForcedPasswordChangeGate onChangeRequired={() => navigation.replace('ChangePassword')}>
<HomeScreen />
</ForcedPasswordChangeGate>Pre-built Screens
All screens are navigation-agnostic and accept callback props.
import {
TotpChallengeScreen,
OtpChallengeScreen,
RecoveryCodeScreen,
PasskeyChallengeScreen,
TotpEnrollScreen,
PasskeyEnrollScreen,
ForcePasswordChangeScreen,
} from '@credocentral/e-identity-react-native';
// Use EIdentityRNClient from context or create one directly
const { client } = useEIdentityClient(); // or: new EIdentityRNClient({ config })
<TotpChallengeScreen
client={client}
challengeToken={route.params.challengeToken}
onSuccess={(tokens) => navigation.replace('Home')}
onUseRecovery={() => navigation.navigate('RecoveryCode', { challengeToken })}
/>
<ForcePasswordChangeScreen
client={client}
onSuccess={() => navigation.replace('Home')}
/>Hooks
import { useMfaChallenge, useForcePasswordChange } from '@credocentral/e-identity-react-native';
// Build a custom MFA challenge UI
const { status, error, verifyTotp, verifyOtp, resendOtp, verifyRecovery, authenticateWithPasskey } =
useMfaChallenge(client, challengeToken);
// Build a custom password change UI
const { isChanging, error, changePassword } = useForcePasswordChange(client);Client API
| Method | Description |
|---|---|
| initialize() | Load persisted session; auto-refresh if expired |
| login() | PKCE login via in-app browser |
| logout() | Revoke + clear session |
| getValidToken() | Return a non-expired access token (refreshes if needed) |
| verifyTotpChallenge(token, code) | Verify TOTP code |
| verifyOtpChallenge(token, code) | Verify email/SMS OTP |
| resendOtpChallenge(token) | Resend OTP; returns masked destination |
| verifyRecoveryCode(token, code) | Verify recovery code |
| authenticateWithPasskey(token) | Combined passkey assertion flow |
| enrollTotpOptions() | Fetch TOTP enrollment options (requires auth) |
| confirmTotpEnrollment(setupToken, code) | Confirm TOTP; returns recovery codes |
| enrollPasskey() | Combined passkey registration flow |
| listMfaMethods() | List enrolled MFA methods |
| regenerateRecoveryCodes() | Generate new recovery codes |
| changePassword(current, new) | Change password (clears forcePasswordChange) |
Requirements
- React Native 0.73+
- iOS 13+ (passkeys require iOS 16+)
- Android API 21+ (passkeys require API 28+)
License
MIT
