This package provides a native-backed FIDO bridge for React Native.
useJourneyForm integrationNote: This module requires that the
@ping-identity/rn-coremodule is already set up and installed.
# Install & setup the core module
yarn add @ping-identity/rn-core
# Install the rn-fido module
yarn add @ping-identity/rn-fido
# If you are developing your app using iOS, run this command
cd ios && pod install
Optional integration packages:
yarn add @ping-identity/rn-logger
https://<rp-domain>/.well-known/assetlinks.json.assetlinks.json contains your Android package name and signing cert fingerprint(s).androidx.credentials:credentials-play-services-auth.com.google.android.gms:play-services-fido.webcredentials:<rp-domain>).https://<rp-domain>/.well-known/apple-app-site-association.Use createFidoClient(config?) and call operations on the returned client.
import { createFidoClient } from '@ping-identity/rn-fido';
import { logger } from '@ping-identity/rn-logger';
const log = logger({ level: 'debug' });
const fido = createFidoClient({
logger: log,
android: {
useFido2Client: true,
},
});
const registrationResult = await fido.register({
challenge: 'base64url-challenge',
rp: { id: 'example.com', name: 'Example Inc.' },
user: {
id: 'base64url-user-id',
name: 'user@example.com',
displayName: 'Example User',
},
pubKeyCredParams: [{ type: 'public-key', alg: -7 }],
});
const authenticationResult = await fido.authenticate({
challenge: 'base64url-challenge',
rpId: 'example.com',
allowCredentials: [],
});
If you install the logger package, pass a JS logger instance created via
@ping-identity/rn-logger.
If the logger package is not installed/configured, do not pass logger values in FIDO config.
JavaScript-side FIDO logs use this logger on both platforms.
Native logger forwarding currently applies on Android; iOS native forwarding is a no-op.
import { createFidoClient } from '@ping-identity/rn-fido';
import { logger } from '@ping-identity/rn-logger';
const jsLogger = logger({ level: 'debug' });
const fido = createFidoClient({
logger: jsLogger,
});
import { createFidoClient } from '@ping-identity/rn-fido';
const fidoA = createFidoClient({
android: { useFido2Client: true },
});
const fidoB = createFidoClient({
android: { useFido2Client: false },
});
await fidoA.register({ challenge: '...' });
await fidoB.authenticate({ challenge: '...' });
Run Journey FIDO callbacks explicitly before journey.next(...).
import { createFidoClient } from '@ping-identity/rn-fido';
const fido = createFidoClient();
if (node.type === 'ContinueNode') {
for (const callback of node.callbacks ?? []) {
if (callback.type === 'FidoRegistrationCallback') {
await fido.registerForJourney(journey, {
index: 0,
deviceName: 'My Device',
});
}
if (callback.type === 'FidoAuthenticationCallback') {
await fido.authenticateForJourney(journey, { index: 0 });
}
}
await journey.next({});
}
useJourneyForm integrationWhen using useJourneyForm, FIDO fields are marked with executionMode: 'integration_required'.
This indicates app code must run FIDO integration explicitly.
import { useJourneyForm } from '@ping-identity/rn-journey';
import { createFidoClient } from '@ping-identity/rn-fido';
const form = useJourneyForm(node);
const fido = createFidoClient();
for (const field of form.fields) {
if (field.ref.type === 'FidoRegistrationCallback') {
await fido.registerForJourney(journey, {
index: field.ref.typeIndex,
deviceName: 'My Device',
});
}
if (field.ref.type === 'FidoAuthenticationCallback') {
await fido.authenticateForJourney(journey, {
index: field.ref.typeIndex,
});
}
}
await journey.next({});
import { createFidoClient } from '@ping-identity/rn-fido';
import type {
FidoClient,
FidoConfig,
FidoRegistrationOptions,
FidoRegistrationResult,
FidoAuthenticationOptions,
FidoAuthenticationResult,
FidoJourneyRegistrationOptions,
FidoJourneyAuthenticationOptions,
FidoJourneyResult,
JourneyInstance,
} from '@ping-identity/rn-fido';
function createFidoClient(config?: FidoConfig): FidoClient;
interface FidoClient {
register(options: FidoRegistrationOptions): Promise<FidoRegistrationResult>;
authenticate(
options: FidoAuthenticationOptions,
): Promise<FidoAuthenticationResult>;
registerForJourney(
journey: JourneyInstance,
options?: FidoJourneyRegistrationOptions,
): Promise<FidoJourneyResult>;
authenticateForJourney(
journey: JourneyInstance,
options?: FidoJourneyAuthenticationOptions,
): Promise<FidoJourneyResult>;
}
Rejected promises throw a FidoError instance, which extends PingError extends Error. Use instanceof FidoError to narrow in catch blocks.
Stable error codes:
FIDO_ERRORFIDO_REGISTER_ERRORFIDO_AUTHENTICATE_ERRORFIDO_AUTHENTICATE_CANCELLEDFIDO_ACTIVITY_UNAVAILABLE (Android)FIDO_WINDOW_UNAVAILABLE (iOS)FIDO_CALLBACK_NOT_FOUNDandroid.useFido2Client is an Android-only override.
undefined (default): native SDK auto-detection/default behavior.true: force Google Play Services FIDO2 APIs.false: force Android Credential Manager APIs.FidoClient configuration.Activity for FIDO calls.UIWindowScene/ASPresentationAnchor for FIDO calls.Full passkey E2E strategy (including OS-level credential surfaces outside app UI) is still to be determined.
MIT