The PingStorage SDK provides a flexible storage interface and a set of common storage solutions for the Ping SDKs, serving React Native applications.
Note: 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-storage module
yarn add @ping-identity/rn-storage
# If you are developing your app using iOS, run this command
cd ios && pod install
Optional integration packages:
yarn add @ping-identity/rn-logger
If you install the logger package, you can pass StorageLoggerOptions to storage APIs for
JavaScript-side logging. Native storage logger application is not enabled yet; loggerId remains
bridge-only for now.
The storage SDK exposes two helpers for common use cases.
Use configure* to register and resolve the config for inline module usage:
import {
CacheStrategy,
configureSessionStorage,
configureOidcStorage,
} from '@ping-identity/rn-storage';
import type {
SessionStorage,
OidcStorage,
StorageConfig,
} from '@ping-identity/rn-storage';
// Configure session storage for Journey SSO tokens (Android configuration)
const sessionStorage: SessionStorage = configureSessionStorage({
android: {
keyAlias: 'ping.session',
fileName: 'ping_session_store',
cacheStrategy: CacheStrategy.CACHE,
},
});
// Configure OIDC storage for OAuth/OIDC tokens (Android configuration)
const oidcStorage: OidcStorage = configureOidcStorage({
android: {
keyAlias: 'ping.oidc',
fileName: 'ping_oidc_tokens',
},
ios: {
account: 'com.example.app.oidc',
encryptor: true,
},
});
Notes:
configureSessionStorage / configureOidcStorage return opaque storage handles.
Handle objects include id and kind and can be passed into native-backed modules.android.keyAlias and other
android options (including fileName, strongBoxPreferred) are optional.ios.account (Keychain account)
and ios.encryptor (true uses an Encryptor, false uses NoEncryptor).android.cacheStrategy controls how the SDK caches data when native storage
is unavailable.StorageLoggerOptions is optional. The logger field provides JS-side logging only — storage registration is a synchronous in-memory operation with no native log output.You can import StorageConfig to type the input passed to
configureSessionStorage / configureOidcStorage. The configured outputs are
branded as SessionStorage or OidcStorage for type safety.
import type { OidcStorage, StorageConfig } from '@ping-identity/rn-storage';
const oidcCfg: StorageConfig = {
android: {
keyAlias: 'ping.oidc',
fileName: 'ping_oidc_tokens',
},
};
const oidcStorage: OidcStorage = configureOidcStorage(oidcCfg);
// Pass the storage handle to modules that accept storage ids.
// createOidcClient({ storage: oidcStorage, ... });
Pass to createBindingClient({ userKeyStorage }) to override the default key store:
import { configureBindingUserKeyStorage } from '@ping-identity/rn-storage';
import { createBindingClient } from '@ping-identity/rn-binding';
const userKeyStorage = configureBindingUserKeyStorage({
android: {
keyAlias: 'binding.user.key',
fileName: 'binding_user_keys',
},
ios: {
account: 'com.example.app.binding',
encryptor: true,
},
});
const bindingClient = createBindingClient({ userKeyStorage });
Pass to createPushClient({ storage }) to override the default push credential store:
import { configurePushStorage } from '@ping-identity/rn-storage';
import { createPushClient } from '@ping-identity/rn-push';
const pushStorage = configurePushStorage({
android: {
keyAlias: 'push_key',
fileName: 'push_credentials',
},
});
const pushClient = createPushClient({ storage: pushStorage });
Pass to createOathClient({ storage }) to override the default OATH credential store.
iOS supports additional OATH-specific keychain options via iosOath:
import { configureOathStorage } from '@ping-identity/rn-storage';
import { createOathClient } from '@ping-identity/rn-oath';
const oathStorage = configureOathStorage({
android: {
fileName: 'oath_credentials.db',
},
iosOath: {
service: 'com.example.app.oath',
requireBiometrics: true,
requireDevicePasscode: false,
biometricPrompt: 'Authenticate to access OATH credentials',
accessGroup: 'com.example.shared',
},
});
const client = await createOathClient({ storage: oathStorage });
iosOath options:
| Option | Type | Description |
|---|---|---|
service |
string |
Keychain service identifier |
requireBiometrics |
boolean |
Require biometric authentication to access stored credentials |
requireDevicePasscode |
boolean |
Require device passcode as a fallback |
biometricPrompt |
string |
Prompt string shown during biometric authentication |
accessGroup |
string |
Keychain access group for sharing across app extensions |
Pass the storage handle returned by configureSessionStorage or
configureOidcStorage directly into Journey config:
import {
configureOidcStorage,
configureSessionStorage,
type OidcStorage,
} from '@ping-identity/rn-storage';
import { createJourneyClient } from '@ping-identity/rn-journey';
const sessionStorage = configureSessionStorage({
android: {
keyAlias: 'ping.session',
fileName: 'ping_session_store',
},
});
const oidcStorage: OidcStorage = configureOidcStorage({
// Android-only fields
android: {
keyAlias: 'ping.oidc',
fileName: 'ping_oidc_tokens',
},
// iOS-only fields
ios: {
account: 'com.example.app.oidc',
encryptor: true,
},
});
const journeyClient = createJourneyClient({
serverUrl: 'https://example.com/am',
modules: {
session: {
storage: sessionStorage,
},
oidc: {
storage: oidcStorage,
},
},
});
Storage operations reject or throw a StorageError instance, which extends PingError extends Error.
Use instanceof to narrow the error type:
import { StorageError } from '@ping-identity/rn-storage';
try {
const sessionStorage = configureSessionStorage({
android: {
keyAlias: 'ping.session',
fileName: 'ping_session_store',
},
});
} catch (err) {
if (err instanceof StorageError) {
console.log(err.code, err.type, err.message);
}
}
This project is licensed under the MIT License - see the LICENSE file for details