Skip to main content
‹ /migrate
Function

migrateItem()

Moves one item of react-native-keychain or expo-secure-store, with the prompt when it is protected. For the items migrateFrom… skipped as requiresAuth, at a moment the user expects Face ID.

Section/migrateDraftIn the package, not released yet: the API can still change.
Import
import { migrateItem } from '@apexnative/keychain/migrate';

migrateFromReactNativeKeychain and migrateFromExpoSecureStore never show a prompt, so they leave a protected item where it is and report it as requiresAuth. migrateItem moves one such item: it shows the prompt of the old item, writes the value into this package with the protection you give, and finishes the old item.

Usage​

src/auth/unlock.ts
import { AccessControl, Accessible } from '@apexnative/keychain';
import { migrateItem } from '@apexnative/keychain/migrate';

// On the screen that used to unlock rnk's protected password with Face ID.
const report = await migrateItem(
{ library: 'reactNativeKeychain', service: 'auth' },
{
prompt: { title: 'Unlock your account' },
setOptions: {
accessible: Accessible.WhenUnlockedThisDeviceOnly,
accessControl: AccessControl.BiometryCurrentSet,
},
removeSource: true,
}
);

if (report.migrated.length === 1) {
// The password is now the credentials of createKeychain({ service: 'auth' }).
}

Signature​

function migrateItem(item: MigrationItem, options?: MigrateItemOptions): Promise<MigrationReport>;
ReturnsPromise<MigrationReport>PromptWhen the old item is protected: its own promptThrowsINVALID_ARGUMENT for an item or options that aren't valid. A canceled prompt, and any failure of the move, is in the reportPlatformsiOSAndroid

Parameters​

ParameterTypeDescription
itemRequiredMigrationItemWhich old item. { library: 'reactNativeKeychain', service? } for a generic password (without service: rnk's default), { library: 'reactNativeKeychain', server } for internet credentials, { library: 'expoSecureStore', key, keychainService? } for an item of expo-secure-store. See MigrationItem.
optionsMigrateItemOptionsWhere and how the new item is written. See below.
OptionTypeDescription
promptPromptThe texts of the prompt the old item shows. See Prompt.
setOptionsSetOptionsHow the new item is written: accessible, accessControl, authValidity, synchronizable, android; no label.
intoKeychainThe storage that gets internet credentials and items of expo-secure-store. Default: `keychain`. A generic password goes to the storage of its service.
removeSourcebooleanDelete the old item once the new one is written; else mark it as moved. Default false.
accessGroupstringiOS: look for the item in this access group only.

Returns​

A MigrationReport of the one item: its key in migrated, or in skipped with a reason.

Outcomes​

What happenedThe report
Movedmigrated: [key]
The user canceled the promptskipped: [{ key, kind, reason: 'error', error }], error.code is USER_CANCELED
Another prompt outcome: a lockout, a failed scanskipped with reason: 'error' and the prompt's code
No such itemskipped with reason: 'notFound'
The key is taken in this packageskipped with reason: 'exists', nothing overwritten

A canceled prompt is no exception: the user can try again, and the old item is still there for the next call. An item that isn't protected moves without a prompt, as with migrateFrom….

import { KeychainErrorCode, isKeychainError } from '@apexnative/keychain/migrate';

const [skipped] = report.skipped;
if (skipped && isKeychainError(skipped.error, KeychainErrorCode.UserCanceled)) {
showPasswordForm(); // and offer the move again next time
}

See also​