UNPKG

capacitor-biometric-authentication

Version:

Framework-agnostic biometric authentication library. Works with React, Vue, Angular, or vanilla JS. No providers required!

162 lines 5.64 kB
import { BiometricErrorCode, BiometryType } from '../core/types'; export class ReactNativeAdapter { constructor() { this.platform = 'react-native'; // Biometrics module will be loaded dynamically } async getBiometrics() { if (this.biometrics) { return this.biometrics; } try { // Dynamic import for React Native biometrics // eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-explicit-any const ReactNativeBiometrics = require('react-native-biometrics').default; this.biometrics = new ReactNativeBiometrics(); return this.biometrics; } catch (_a) { throw new Error('React Native Biometrics not installed. Please run: npm install react-native-biometrics'); } } async isAvailable() { try { const biometrics = await this.getBiometrics(); const { available } = await biometrics.isSensorAvailable(); return available; } catch (_a) { return false; } } async getSupportedBiometrics() { try { const biometrics = await this.getBiometrics(); const { available, biometryType } = await biometrics.isSensorAvailable(); if (!available) { return []; } // Map React Native biometry types to our types switch (biometryType) { case 'TouchID': return [BiometryType.TOUCH_ID]; case 'FaceID': return [BiometryType.FACE_ID]; case 'Biometrics': case 'Fingerprint': return [BiometryType.FINGERPRINT]; default: return [BiometryType.UNKNOWN]; } } catch (_a) { return []; } } async authenticate(options) { try { const biometrics = await this.getBiometrics(); // Check if biometrics are available const { available, biometryType, error } = await biometrics.isSensorAvailable(); if (!available) { return { success: false, error: { code: BiometricErrorCode.BIOMETRIC_UNAVAILABLE, message: error || 'Biometric authentication is not available' } }; } // Create signature for authentication const { success, signature, error: authError } = await biometrics.createSignature({ promptMessage: (options === null || options === void 0 ? void 0 : options.reason) || 'Authenticate', cancelButtonText: (options === null || options === void 0 ? void 0 : options.cancelTitle) || 'Cancel', payload: 'biometric-auth-payload' }); if (success && signature) { return { success: true, biometryType: this.mapBiometryType(biometryType), sessionId: this.generateSessionId(), platform: 'react-native' }; } else { return { success: false, error: this.mapError(authError) }; } } catch (error) { return { success: false, error: this.mapError(error) }; } } async deleteCredentials() { try { const biometrics = await this.getBiometrics(); await biometrics.deleteKeys(); } catch (_a) { // Ignore errors when deleting credentials } } async hasCredentials() { try { const biometrics = await this.getBiometrics(); const { keysExist } = await biometrics.biometricKeysExist(); return keysExist; } catch (_a) { return false; } } mapBiometryType(type) { if (!type) { return BiometryType.UNKNOWN; } switch (type) { case 'TouchID': return BiometryType.TOUCH_ID; case 'FaceID': return BiometryType.FACE_ID; case 'Biometrics': case 'Fingerprint': return BiometryType.FINGERPRINT; default: return BiometryType.UNKNOWN; } } mapError(error) { let code = BiometricErrorCode.UNKNOWN_ERROR; let message = 'An unknown error occurred'; if (typeof error === 'string') { message = error; // Map common error messages to error codes if (error.includes('cancelled') || error.includes('canceled')) { code = BiometricErrorCode.USER_CANCELLED; } else if (error.includes('failed') || error.includes('not recognized')) { code = BiometricErrorCode.AUTHENTICATION_FAILED; } else if (error.includes('locked')) { code = BiometricErrorCode.LOCKOUT; } } else if (error instanceof Error) { message = error.message; } return { code, message, details: error }; } generateSessionId() { return Date.now().toString(36) + Math.random().toString(36).substr(2); } } //# sourceMappingURL=ReactNativeAdapter.js.map