diff --git a/index.ts b/index.ts index 32528b4..5dcb152 100644 --- a/index.ts +++ b/index.ts @@ -1,75 +1,79 @@ -import { NativeModules } from 'react-native' +import { NativeModules } from "react-native"; -const { ReactNativeBiometrics: bridge } = NativeModules +const { ReactNativeBiometrics: bridge } = NativeModules; /** * Type alias for possible biometry types */ -export type BiometryType = 'TouchID' | 'FaceID' | 'Biometrics' +export type BiometryType = "TouchID" | "FaceID" | "Biometrics"; interface RNBiometricsOptions { - allowDeviceCredentials?: boolean + allowDeviceCredentials?: boolean; } interface IsSensorAvailableResult { - available: boolean - biometryType?: BiometryType - error?: string + available: boolean; + biometryType?: BiometryType; + error?: string; } interface CreateKeysResult { - publicKey: string + publicKey: string; } interface BiometricKeysExistResult { - keysExist: boolean + keysExist: boolean; } interface DeleteKeysResult { - keysDeleted: boolean + keysDeleted: boolean; } interface CreateSignatureOptions { - promptMessage: string - payload: string - cancelButtonText?: string + promptMessage: string; + payload: string; + cancelButtonText?: string; } interface CreateSignatureResult { - success: boolean - signature?: string - error?: string + success: boolean; + signature?: string; + error?: string; } interface SimplePromptOptions { - promptMessage: string - fallbackPromptMessage?: string - cancelButtonText?: string + promptMessage: string; + fallbackPromptMessage?: string; + cancelButtonText?: string; } interface SimplePromptResult { - success: boolean - error?: string + success: boolean; + error?: string; +} + +interface Options { + accessGroup?: string; } /** * Enum for touch id sensor type */ -export const TouchID = 'TouchID' +export const TouchID = "TouchID"; /** * Enum for face id sensor type */ -export const FaceID = 'FaceID' +export const FaceID = "FaceID"; /** * Enum for generic biometrics (this is the only value available on android) */ -export const Biometrics = 'Biometrics' +export const Biometrics = "Biometrics"; export const BiometryTypes = { TouchID, FaceID, - Biometrics -} + Biometrics, +}; export module ReactNativeBiometricsLegacy { /** @@ -77,7 +81,7 @@ export module ReactNativeBiometricsLegacy { * @returns {Promise} Promise that resolves to an object with details about biometrics available */ export function isSensorAvailable(): Promise { - return new ReactNativeBiometrics().isSensorAvailable() + return new ReactNativeBiometrics().isSensorAvailable(); } /** @@ -85,8 +89,11 @@ export module ReactNativeBiometricsLegacy { * an object with object.publicKey, which is the public key of the newly generated key pair * @returns {Promise} Promise that resolves to object with details about the newly generated public key */ - export function createKeys(): Promise { - return new ReactNativeBiometrics().createKeys() + export function createKeys( + createKeyOptions?: Options + ): Promise { + const keyOptions = createKeyOptions || {}; + return new ReactNativeBiometrics().createKeys(keyOptions); } /** @@ -95,7 +102,7 @@ export module ReactNativeBiometricsLegacy { * @returns {Promise} Promise that resolves to object with details about the existence of keys */ export function biometricKeysExist(): Promise { - return new ReactNativeBiometrics().biometricKeysExist() + return new ReactNativeBiometrics().biometricKeysExist(); } /** @@ -104,7 +111,7 @@ export module ReactNativeBiometricsLegacy { * @returns {Promise} Promise that resolves to an object with details about the deletion */ export function deleteKeys(): Promise { - return new ReactNativeBiometrics().deleteKeys() + return new ReactNativeBiometrics().deleteKeys(); } /** @@ -116,8 +123,10 @@ export module ReactNativeBiometricsLegacy { * @param {string} createSignatureOptions.payload * @returns {Promise} Promise that resolves to an object cryptographic signature details */ - export function createSignature(createSignatureOptions: CreateSignatureOptions): Promise { - return new ReactNativeBiometrics().createSignature(createSignatureOptions) + export function createSignature( + createSignatureOptions: CreateSignatureOptions + ): Promise { + return new ReactNativeBiometrics().createSignature(createSignatureOptions); } /** @@ -129,96 +138,108 @@ export module ReactNativeBiometricsLegacy { * @param {string} simplePromptOptions.fallbackPromptMessage * @returns {Promise} Promise that resolves an object with details about the biometrics result */ - export function simplePrompt(simplePromptOptions: SimplePromptOptions): Promise { - return new ReactNativeBiometrics().simplePrompt(simplePromptOptions) + export function simplePrompt( + simplePromptOptions: SimplePromptOptions + ): Promise { + return new ReactNativeBiometrics().simplePrompt(simplePromptOptions); } } export default class ReactNativeBiometrics { - allowDeviceCredentials = false - - /** - * @param {Object} rnBiometricsOptions - * @param {boolean} rnBiometricsOptions.allowDeviceCredentials - */ - constructor(rnBiometricsOptions?: RNBiometricsOptions) { - const allowDeviceCredentials = rnBiometricsOptions?.allowDeviceCredentials ?? false - this.allowDeviceCredentials = allowDeviceCredentials - } - - /** - * Returns promise that resolves to an object with object.biometryType = Biometrics | TouchID | FaceID - * @returns {Promise} Promise that resolves to an object with details about biometrics available - */ - isSensorAvailable(): Promise { - return bridge.isSensorAvailable({ - allowDeviceCredentials: this.allowDeviceCredentials - }) - } - - /** - * Creates a public private key pair,returns promise that resolves to - * an object with object.publicKey, which is the public key of the newly generated key pair - * @returns {Promise} Promise that resolves to object with details about the newly generated public key - */ - createKeys(): Promise { - return bridge.createKeys({ - allowDeviceCredentials: this.allowDeviceCredentials - }) - } - - /** - * Returns promise that resolves to an object with object.keysExists = true | false - * indicating if the keys were found to exist or not - * @returns {Promise} Promise that resolves to object with details aobut the existence of keys - */ - biometricKeysExist(): Promise { - return bridge.biometricKeysExist() - } - - /** - * Returns promise that resolves to an object with true | false - * indicating if the keys were properly deleted - * @returns {Promise} Promise that resolves to an object with details about the deletion - */ - deleteKeys(): Promise { - return bridge.deleteKeys() - } - - /** - * Prompts user with biometrics dialog using the passed in prompt message and - * returns promise that resolves to an object with object.signature, - * which is cryptographic signature of the payload - * @param {Object} createSignatureOptions - * @param {string} createSignatureOptions.promptMessage - * @param {string} createSignatureOptions.payload - * @returns {Promise} Promise that resolves to an object cryptographic signature details - */ - createSignature(createSignatureOptions: CreateSignatureOptions): Promise { - createSignatureOptions.cancelButtonText = createSignatureOptions.cancelButtonText ?? 'Cancel' - - return bridge.createSignature({ - allowDeviceCredentials: this.allowDeviceCredentials, - ...createSignatureOptions - }) - } - - /** - * Prompts user with biometrics dialog using the passed in prompt message and - * returns promise that resolves to an object with object.success = true if the user passes, - * object.success = false if the user cancels, and rejects if anything fails - * @param {Object} simplePromptOptions - * @param {string} simplePromptOptions.promptMessage - * @param {string} simplePromptOptions.fallbackPromptMessage - * @returns {Promise} Promise that resolves an object with details about the biometrics result - */ - simplePrompt(simplePromptOptions: SimplePromptOptions): Promise { - simplePromptOptions.cancelButtonText = simplePromptOptions.cancelButtonText ?? 'Cancel' - simplePromptOptions.fallbackPromptMessage = simplePromptOptions.fallbackPromptMessage ?? 'Use Passcode' - - return bridge.simplePrompt({ - allowDeviceCredentials: this.allowDeviceCredentials, - ...simplePromptOptions - }) - } + allowDeviceCredentials = false; + + /** + * @param {Object} rnBiometricsOptions + * @param {boolean} rnBiometricsOptions.allowDeviceCredentials + */ + constructor(rnBiometricsOptions?: RNBiometricsOptions) { + const allowDeviceCredentials = + rnBiometricsOptions?.allowDeviceCredentials ?? false; + this.allowDeviceCredentials = allowDeviceCredentials; + } + + /** + * Returns promise that resolves to an object with object.biometryType = Biometrics | TouchID | FaceID + * @returns {Promise} Promise that resolves to an object with details about biometrics available + */ + isSensorAvailable(): Promise { + return bridge.isSensorAvailable({ + allowDeviceCredentials: this.allowDeviceCredentials, + }); + } + + /** + * Creates a public private key pair,returns promise that resolves to + * an object with object.publicKey, which is the public key of the newly generated key pair + * @returns {Promise} Promise that resolves to object with details about the newly generated public key + */ + createKeys(createKeyOptions?: Options): Promise { + const keyOptions = createKeyOptions || {}; + return bridge.createKeys({ + allowDeviceCredentials: this.allowDeviceCredentials, + ...keyOptions, + }); + } + + /** + * Returns promise that resolves to an object with object.keysExists = true | false + * indicating if the keys were found to exist or not + * @returns {Promise} Promise that resolves to object with details aobut the existence of keys + */ + biometricKeysExist(): Promise { + return bridge.biometricKeysExist(); } + + /** + * Returns promise that resolves to an object with true | false + * indicating if the keys were properly deleted + * @returns {Promise} Promise that resolves to an object with details about the deletion + */ + deleteKeys(): Promise { + return bridge.deleteKeys(); + } + + /** + * Prompts user with biometrics dialog using the passed in prompt message and + * returns promise that resolves to an object with object.signature, + * which is cryptographic signature of the payload + * @param {Object} createSignatureOptions + * @param {string} createSignatureOptions.promptMessage + * @param {string} createSignatureOptions.payload + * @returns {Promise} Promise that resolves to an object cryptographic signature details + */ + createSignature( + createSignatureOptions: CreateSignatureOptions + ): Promise { + createSignatureOptions.cancelButtonText = + createSignatureOptions.cancelButtonText ?? "Cancel"; + + return bridge.createSignature({ + allowDeviceCredentials: this.allowDeviceCredentials, + ...createSignatureOptions, + }); + } + + /** + * Prompts user with biometrics dialog using the passed in prompt message and + * returns promise that resolves to an object with object.success = true if the user passes, + * object.success = false if the user cancels, and rejects if anything fails + * @param {Object} simplePromptOptions + * @param {string} simplePromptOptions.promptMessage + * @param {string} simplePromptOptions.fallbackPromptMessage + * @returns {Promise} Promise that resolves an object with details about the biometrics result + */ + simplePrompt( + simplePromptOptions: SimplePromptOptions + ): Promise { + simplePromptOptions.cancelButtonText = + simplePromptOptions.cancelButtonText ?? "Cancel"; + simplePromptOptions.fallbackPromptMessage = + simplePromptOptions.fallbackPromptMessage ?? "Use Passcode"; + + return bridge.simplePrompt({ + allowDeviceCredentials: this.allowDeviceCredentials, + ...simplePromptOptions, + }); + } +} diff --git a/ios/ReactNativeBiometrics.m b/ios/ReactNativeBiometrics.m index 03ec388..d100190 100644 --- a/ios/ReactNativeBiometrics.m +++ b/ios/ReactNativeBiometrics.m @@ -77,9 +77,17 @@ @implementation ReactNativeBiometrics } }; + NSMutableDictionary *keyAttributesWithOptions = keyAttributes.mutableCopy; + + NSString *accessGroup = [RCTConvert NSString:params[@"accessGroup"]]; + + if (accessGroup != nil) { + keyAttributesWithOptions[(id)kSecAttrAccessGroup] = accessGroup; + } + [self deleteBiometricKey]; NSError *gen_error = nil; - id privateKey = CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyAttributes, (void *)&gen_error)); + id privateKey = CFBridgingRelease(SecKeyCreateRandomKey((__bridge CFDictionaryRef)keyAttributesWithOptions, (void *)&gen_error)); if(privateKey != nil) { id publicKey = CFBridgingRelease(SecKeyCopyPublicKey((SecKeyRef)privateKey));