UNPKG

@turnkey/sdk-react-native

Version:
301 lines (295 loc) 10.5 kB
'use strict'; var Keychain = require('react-native-keychain'); var errors = require('./errors.js'); var constants = require('./constants.js'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var Keychain__namespace = /*#__PURE__*/_interopNamespaceDefault(Keychain); // This package leverages `react-native-keychain` to securely store session data. // We use `Keychain.getGenericPassword()` to retrieve stored values, where: // - `service` is used as a key to reference the stored data. // - `credentials.password` is used to hold sensitive data, such as session keys or encrypted session objects. // // Note: `credentials.password` does not need to contain a literal password; // it is simply a secure storage location for sensitive string data. /** * Retrieves the embedded key from secure storage. * * - Attempts to retrieve the stored embedded private key using Keychain. * - Optionally deletes the key from storage after retrieval if `deleteKey` is true. * * @param deleteKey - Whether to remove the embedded key after retrieval (defaults to false). * @param storageKey - The service key for the embedded key. * @returns The embedded private key if found, otherwise null. * @throws {TurnkeyReactNativeError} If retrieving or deleting the key fails. */ const getEmbeddedKey = async (deleteKey = false, storageKey) => { try { const credentials = await Keychain__namespace.getGenericPassword({ service: storageKey, }); if (credentials) { if (deleteKey) { await Keychain__namespace.resetGenericPassword({ service: storageKey, }); } return credentials.password; } return null; } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to get embedded key", error); } }; /** * Saves the provided embedded key (private key) securely in storage. * * - Uses Keychain to store the private key for the given service key. * * @param key - The private key to store securely. * @param storageKey - The service key under which to store the embedded key. * @throws {TurnkeyReactNativeError} If saving the key fails. */ const saveEmbeddedKey = async (key, storageKey) => { try { await Keychain__namespace.setGenericPassword(storageKey, key, { accessible: Keychain__namespace.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY, service: storageKey, }); } catch (error) { throw new errors.TurnkeyReactNativeError("Could not save the embedded key.", error); } }; /** * Retrieves a stored session from secure storage. * * @param sessionKey The unique key identifying the session. * @returns The session object if found, otherwise `null`. * @throws If retrieving the session fails. */ const getSession = async (sessionKey) => { try { const credentials = await Keychain__namespace.getGenericPassword({ service: sessionKey, }); return credentials ? JSON.parse(credentials.password) : null; } catch (error) { throw new errors.TurnkeyReactNativeError(`Failed to get session for sessionKey "${sessionKey}"`, error); } }; /** * Saves a session securely in storage. * * @param session The session object to store securely. * @param sessionKey The unique key under which the session is stored. * @throws If saving the session fails. */ const saveSession = async (session, sessionKey) => { try { await Keychain__namespace.setGenericPassword(sessionKey, JSON.stringify(session), { accessible: Keychain__namespace.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY, service: sessionKey, }); } catch (error) { throw new errors.TurnkeyReactNativeError("Could not save the session", error); } }; /** * Deletes a session from secure storage. * * @param sessionKey The unique key identifying the session to reset. * @throws If deleting the session fails. */ const deleteSession = async (sessionKey) => { try { await Keychain__namespace.resetGenericPassword({ service: sessionKey }); } catch (error) { throw new errors.TurnkeyReactNativeError("Could not delete the session.", error); } }; /** * Retrieves the selected session key from secure storage. * * @returns The selected session key as a string, or `null` if not found. * @throws If retrieving the session key fails. */ const getSelectedSessionKey = async () => { try { const credentials = await Keychain__namespace.getGenericPassword({ service: constants.StorageKeys.SelectedSession, }); return credentials ? credentials.password : null; } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to get selected session key", error); } }; /** * Saves the selected session key to secure storage. * * @param sessionKey The session key to mark as selected. * @throws If saving the session key fails. */ const saveSelectedSessionKey = async (sessionKey) => { try { await Keychain__namespace.setGenericPassword(constants.StorageKeys.SelectedSession, sessionKey, { accessible: Keychain__namespace.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY, service: constants.StorageKeys.SelectedSession, }); } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to save selected session key", error); } }; /** * Clears the selected session key from secure storage. * * @throws If deleting the session key fails. */ const clearSelectedSessionKey = async () => { try { await Keychain__namespace.resetGenericPassword({ service: constants.StorageKeys.SelectedSession, }); } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to clear selected session key", error); } }; /** * Adds a session key to the session list in secure storage. * * - Retrieves the existing session list. * - Appends the new session key if it does not already exist. * - Stores the updated session list. * * @param sessionKey The session key to add. * @throws If the session key already exists or saving fails. */ const addSessionKey = async (sessionKey) => { try { const credentials = await Keychain__namespace.getGenericPassword({ service: constants.StorageKeys.SessionKeys, }); let keys = []; if (credentials) { try { keys = JSON.parse(credentials.password); if (!Array.isArray(keys)) { throw new Error("Session list is corrupted."); } } catch { throw new errors.TurnkeyReactNativeError("Failed to parse session list."); } } if (keys.includes(sessionKey)) { return; } keys.push(sessionKey); await Keychain__namespace.setGenericPassword(constants.StorageKeys.SessionKeys, JSON.stringify(keys), { accessible: Keychain__namespace.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY, service: constants.StorageKeys.SessionKeys, }); } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to add session key.", error); } }; /** * Retrieves all session keys stored in secure storage. * * @returns An array of session keys. * @throws If retrieving the session list fails. */ const getSessionKeys = async () => { try { const credentials = await Keychain__namespace.getGenericPassword({ service: constants.StorageKeys.SessionKeys, }); if (!credentials) { return []; } try { const keys = JSON.parse(credentials.password); if (!Array.isArray(keys)) { throw new Error("Session list is corrupted."); } return keys; } catch { throw new errors.TurnkeyReactNativeError("Failed to parse session list."); } } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to retrieve session list.", error); } }; /** * Removes a session key from the session list in secure storage. * * - Fetches the existing session list. * - Removes the specified session key. * - Saves the updated session list back to secure storage. * * @param sessionKey The session key to remove. * @throws If removing the session key fails. */ const removeSessionKey = async (sessionKey) => { try { const credentials = await Keychain__namespace.getGenericPassword({ service: constants.StorageKeys.SessionKeys, }); let keys = []; if (credentials) { try { keys = JSON.parse(credentials.password); if (!Array.isArray(keys)) { throw new Error("Session list is corrupted."); } } catch { throw new errors.TurnkeyReactNativeError("Failed to parse session list."); } } const updatedKeys = keys.filter((key) => key !== sessionKey); await Keychain__namespace.setGenericPassword(constants.StorageKeys.SessionKeys, JSON.stringify(updatedKeys), { accessible: Keychain__namespace.ACCESSIBLE.WHEN_UNLOCKED_THIS_DEVICE_ONLY, service: constants.StorageKeys.SessionKeys, }); } catch (error) { throw new errors.TurnkeyReactNativeError("Failed to remove session key.", error); } }; exports.addSessionKey = addSessionKey; exports.clearSelectedSessionKey = clearSelectedSessionKey; exports.deleteSession = deleteSession; exports.getEmbeddedKey = getEmbeddedKey; exports.getSelectedSessionKey = getSelectedSessionKey; exports.getSession = getSession; exports.getSessionKeys = getSessionKeys; exports.removeSessionKey = removeSessionKey; exports.saveEmbeddedKey = saveEmbeddedKey; exports.saveSelectedSessionKey = saveSelectedSessionKey; exports.saveSession = saveSession; //# sourceMappingURL=storage.js.map