@oobit/react-native-sdk 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,11 +2,11 @@
2
2
  * Biometric Authentication Utilities
3
3
  *
4
4
  * Provides cross-platform biometric authentication for card details access.
5
- * Supports Face ID, Touch ID, and Android biometrics.
5
+ * Uses expo-local-authentication which works in Expo Go without native modules.
6
6
  *
7
- * @requires react-native-biometrics - npm install react-native-biometrics
7
+ * @requires expo-local-authentication - included in Expo SDK
8
8
  */
9
- import { BiometryTypes, type BiometryType } from 'react-native-biometrics';
9
+ import * as LocalAuthentication from 'expo-local-authentication';
10
10
  /**
11
11
  * Result of a biometric authentication attempt
12
12
  */
@@ -25,13 +25,13 @@ export interface BiometricResult {
25
25
  export interface BiometricAvailability {
26
26
  /** Whether any biometric authentication is available */
27
27
  available: boolean;
28
- /** The type of biometry available (FaceID, TouchID, Biometrics, or null) */
29
- biometryType: BiometryType | null;
28
+ /** The types of biometry available */
29
+ biometryTypes: LocalAuthentication.AuthenticationType[];
30
30
  }
31
31
  /**
32
32
  * Checks if biometric authentication is available on the device
33
33
  *
34
- * @returns Object containing availability status and biometry type
34
+ * @returns Object containing availability status and biometry types
35
35
  */
36
36
  export declare function isBiometricAvailable(): Promise<BiometricAvailability>;
37
37
  /**
@@ -61,6 +61,6 @@ export declare function authenticateWithBiometrics(promptMessage?: string): Prom
61
61
  * @param biometryType - The biometry type from the device
62
62
  * @returns Human-readable string for the biometry type
63
63
  */
64
- export declare function getBiometryTypeLabel(biometryType: BiometryType | null): string;
65
- export { BiometryTypes };
64
+ export declare function getBiometryTypeLabel(biometryType: LocalAuthentication.AuthenticationType): string;
65
+ export { AuthenticationType } from 'expo-local-authentication';
66
66
  //# sourceMappingURL=biometricUtils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"biometricUtils.d.ts","sourceRoot":"","sources":["../src/biometricUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAA8B,EAAE,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAElG;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,eAAe,GAAG,cAAc,CAAC;QAClE,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB,4EAA4E;IAC5E,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;CACnC;AAOD;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAe3E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,0BAA0B,CAC9C,aAAa,GAAE,MAA4C,GAC1D,OAAO,CAAC,eAAe,CAAC,CAmF1B;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,GAAG,MAAM,CAW9E;AAGD,OAAO,EAAE,aAAa,EAAE,CAAC"}
1
+ {"version":3,"file":"biometricUtils.d.ts","sourceRoot":"","sources":["../src/biometricUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,mBAAmB,MAAM,2BAA2B,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE;QACN,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,eAAe,GAAG,cAAc,CAAC;QAClE,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,aAAa,EAAE,mBAAmB,CAAC,kBAAkB,EAAE,CAAC;CACzD;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,qBAAqB,CAAC,CAiB3E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,0BAA0B,CAC9C,aAAa,GAAE,MAA4C,GAC1D,OAAO,CAAC,eAAe,CAAC,CA8E1B;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,mBAAmB,CAAC,kBAAkB,GACnD,MAAM,CAWR;AAGD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC"}
@@ -3,9 +3,9 @@
3
3
  * Biometric Authentication Utilities
4
4
  *
5
5
  * Provides cross-platform biometric authentication for card details access.
6
- * Supports Face ID, Touch ID, and Android biometrics.
6
+ * Uses expo-local-authentication which works in Expo Go without native modules.
7
7
  *
8
- * @requires react-native-biometrics - npm install react-native-biometrics
8
+ * @requires expo-local-authentication - included in Expo SDK
9
9
  */
10
10
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
11
  if (k2 === undefined) k2 = k;
@@ -41,34 +41,31 @@ var __importStar = (this && this.__importStar) || (function () {
41
41
  };
42
42
  })();
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.BiometryTypes = void 0;
44
+ exports.AuthenticationType = void 0;
45
45
  exports.isBiometricAvailable = isBiometricAvailable;
46
46
  exports.authenticateWithBiometrics = authenticateWithBiometrics;
47
47
  exports.getBiometryTypeLabel = getBiometryTypeLabel;
48
- const react_native_biometrics_1 = __importStar(require("react-native-biometrics"));
49
- Object.defineProperty(exports, "BiometryTypes", { enumerable: true, get: function () { return react_native_biometrics_1.BiometryTypes; } });
50
- // Singleton instance of ReactNativeBiometrics
51
- const rnBiometrics = new react_native_biometrics_1.default({
52
- allowDeviceCredentials: false, // Only allow biometric, not PIN/password fallback
53
- });
48
+ const LocalAuthentication = __importStar(require("expo-local-authentication"));
54
49
  /**
55
50
  * Checks if biometric authentication is available on the device
56
51
  *
57
- * @returns Object containing availability status and biometry type
52
+ * @returns Object containing availability status and biometry types
58
53
  */
59
54
  async function isBiometricAvailable() {
60
55
  try {
61
- const { available, biometryType } = await rnBiometrics.isSensorAvailable();
56
+ const hasHardware = await LocalAuthentication.hasHardwareAsync();
57
+ const isEnrolled = await LocalAuthentication.isEnrolledAsync();
58
+ const supportedTypes = await LocalAuthentication.supportedAuthenticationTypesAsync();
62
59
  return {
63
- available,
64
- biometryType: biometryType || null,
60
+ available: hasHardware && isEnrolled,
61
+ biometryTypes: supportedTypes,
65
62
  };
66
63
  }
67
64
  catch (error) {
68
65
  console.error('[BiometricUtils] Error checking biometric availability:', error);
69
66
  return {
70
67
  available: false,
71
- biometryType: null,
68
+ biometryTypes: [],
72
69
  };
73
70
  }
74
71
  }
@@ -95,8 +92,8 @@ async function isBiometricAvailable() {
95
92
  async function authenticateWithBiometrics(promptMessage = 'Authenticate to view card details') {
96
93
  try {
97
94
  // First check if biometrics are available
98
- const { available, biometryType } = await rnBiometrics.isSensorAvailable();
99
- if (!available) {
95
+ const hasHardware = await LocalAuthentication.hasHardwareAsync();
96
+ if (!hasHardware) {
100
97
  console.log('[BiometricUtils] Biometrics not available on device');
101
98
  return {
102
99
  success: false,
@@ -107,42 +104,46 @@ async function authenticateWithBiometrics(promptMessage = 'Authenticate to view
107
104
  };
108
105
  }
109
106
  // Check if biometrics are enrolled
110
- const { keysExist } = await rnBiometrics.biometricKeysExist();
111
- // Note: Even without keys, simplePrompt should work for basic authentication
112
- // The keysExist check is more for cryptographic operations
113
- console.log(`[BiometricUtils] Attempting biometric auth. Type: ${biometryType}, Keys exist: ${keysExist}`);
107
+ const isEnrolled = await LocalAuthentication.isEnrolledAsync();
108
+ if (!isEnrolled) {
109
+ console.log('[BiometricUtils] No biometrics enrolled');
110
+ return {
111
+ success: false,
112
+ error: {
113
+ reason: 'not_enrolled',
114
+ message: 'No biometric authentication is set up on this device',
115
+ },
116
+ };
117
+ }
118
+ console.log('[BiometricUtils] Attempting biometric authentication...');
114
119
  // Perform the biometric authentication
115
- const { success, error } = await rnBiometrics.simplePrompt({
120
+ const result = await LocalAuthentication.authenticateAsync({
116
121
  promptMessage,
117
- cancelButtonText: 'Cancel',
122
+ cancelLabel: 'Cancel',
123
+ disableDeviceFallback: false, // Allow PIN/password fallback
124
+ fallbackLabel: 'Use Passcode',
118
125
  });
119
- if (success) {
126
+ if (result.success) {
120
127
  console.log('[BiometricUtils] Biometric authentication successful');
121
128
  return { success: true };
122
129
  }
123
130
  // Handle various failure reasons
124
- console.log('[BiometricUtils] Biometric authentication failed:', error);
125
- // Parse the error message to determine the reason
126
- const errorMessage = error || 'Authentication failed';
131
+ console.log('[BiometricUtils] Biometric authentication failed:', result.error);
127
132
  let reason = 'failed';
128
- if (errorMessage.toLowerCase().includes('cancel') ||
129
- errorMessage.toLowerCase().includes('user cancel')) {
133
+ if (result.error === 'user_cancel' || result.error === 'system_cancel') {
130
134
  reason = 'cancelled';
131
135
  }
132
- else if (errorMessage.toLowerCase().includes('not enrolled') ||
133
- errorMessage.toLowerCase().includes('no fingerprint') ||
134
- errorMessage.toLowerCase().includes('no face')) {
136
+ else if (result.error === 'not_enrolled') {
135
137
  reason = 'not_enrolled';
136
138
  }
137
- else if (errorMessage.toLowerCase().includes('not available') ||
138
- errorMessage.toLowerCase().includes('not supported')) {
139
+ else if (result.error === 'not_available') {
139
140
  reason = 'not_available';
140
141
  }
141
142
  return {
142
143
  success: false,
143
144
  error: {
144
145
  reason,
145
- message: errorMessage,
146
+ message: result.warning || 'Authentication failed',
146
147
  },
147
148
  };
148
149
  }
@@ -166,14 +167,17 @@ async function authenticateWithBiometrics(promptMessage = 'Authenticate to view
166
167
  */
167
168
  function getBiometryTypeLabel(biometryType) {
168
169
  switch (biometryType) {
169
- case react_native_biometrics_1.BiometryTypes.FaceID:
170
+ case LocalAuthentication.AuthenticationType.FACIAL_RECOGNITION:
170
171
  return 'Face ID';
171
- case react_native_biometrics_1.BiometryTypes.TouchID:
172
+ case LocalAuthentication.AuthenticationType.FINGERPRINT:
172
173
  return 'Touch ID';
173
- case react_native_biometrics_1.BiometryTypes.Biometrics:
174
- return 'Biometrics';
174
+ case LocalAuthentication.AuthenticationType.IRIS:
175
+ return 'Iris';
175
176
  default:
176
177
  return 'Biometric Authentication';
177
178
  }
178
179
  }
180
+ // Re-export AuthenticationType for convenience
181
+ var expo_local_authentication_1 = require("expo-local-authentication");
182
+ Object.defineProperty(exports, "AuthenticationType", { enumerable: true, get: function () { return expo_local_authentication_1.AuthenticationType; } });
179
183
  //# sourceMappingURL=biometricUtils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"biometricUtils.js","sourceRoot":"","sources":["../src/biometricUtils.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCH,oDAeC;AAsBD,gEAqFC;AAQD,oDAWC;AAhLD,mFAAkG;AAmLzF,8FAnLuB,uCAAa,OAmLvB;AA1JtB,8CAA8C;AAC9C,MAAM,YAAY,GAAG,IAAI,iCAAqB,CAAC;IAC7C,sBAAsB,EAAE,KAAK,EAAE,kDAAkD;CAClF,CAAC,CAAC;AAEH;;;;GAIG;AACI,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC;QACH,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,CAAC;QAE3E,OAAO;YACL,SAAS;YACT,YAAY,EAAE,YAAY,IAAI,IAAI;SACnC,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,yDAAyD,EAAE,KAAK,CAAC,CAAC;QAChF,OAAO;YACL,SAAS,EAAE,KAAK;YAChB,YAAY,EAAE,IAAI;SACnB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACI,KAAK,UAAU,0BAA0B,CAC9C,gBAAwB,mCAAmC;IAE3D,IAAI,CAAC;QACH,0CAA0C;QAC1C,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,YAAY,CAAC,iBAAiB,EAAE,CAAC;QAE3E,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;YACnE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE;oBACL,MAAM,EAAE,eAAe;oBACvB,OAAO,EAAE,0DAA0D;iBACpE;aACF,CAAC;QACJ,CAAC;QAED,mCAAmC;QACnC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,kBAAkB,EAAE,CAAC;QAE9D,6EAA6E;QAC7E,2DAA2D;QAE3D,OAAO,CAAC,GAAG,CACT,qDAAqD,YAAY,iBAAiB,SAAS,EAAE,CAC9F,CAAC;QAEF,uCAAuC;QACvC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC;YACzD,aAAa;YACb,gBAAgB,EAAE,QAAQ;SAC3B,CAAC,CAAC;QAEH,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,sDAAsD,CAAC,CAAC;YACpE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,mDAAmD,EAAE,KAAK,CAAC,CAAC;QAExE,kDAAkD;QAClD,MAAM,YAAY,GAAG,KAAK,IAAI,uBAAuB,CAAC;QACtD,IAAI,MAAM,GAAoD,QAAQ,CAAC;QAEvE,IACE,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAC7C,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,EAClD,CAAC;YACD,MAAM,GAAG,WAAW,CAAC;QACvB,CAAC;aAAM,IACL,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC;YACnD,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC;YACrD,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAC9C,CAAC;YACD,MAAM,GAAG,cAAc,CAAC;QAC1B,CAAC;aAAM,IACL,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC;YACpD,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,EACpD,CAAC;YACD,MAAM,GAAG,eAAe,CAAC;QAC3B,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE;gBACL,MAAM;gBACN,OAAO,EAAE,YAAY;aACtB;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,kDAAkD,EAAE,KAAK,CAAC,CAAC;QAEzE,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;QAEpE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE;gBACL,MAAM,EAAE,QAAQ;gBAChB,OAAO,EAAE,YAAY;aACtB;SACF,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,YAAiC;IACpE,QAAQ,YAAY,EAAE,CAAC;QACrB,KAAK,uCAAa,CAAC,MAAM;YACvB,OAAO,SAAS,CAAC;QACnB,KAAK,uCAAa,CAAC,OAAO;YACxB,OAAO,UAAU,CAAC;QACpB,KAAK,uCAAa,CAAC,UAAU;YAC3B,OAAO,YAAY,CAAC;QACtB;YACE,OAAO,0BAA0B,CAAC;IACtC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"biometricUtils.js","sourceRoot":"","sources":["../src/biometricUtils.ts"],"names":[],"mappings":"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"}
@@ -7,10 +7,8 @@
7
7
  * - Input to RSA: secretKey as Base64 string
8
8
  * - Output: encrypted sessionId as Base64 string
9
9
  *
10
- * Uses react-native-quick-crypto for native RSA-OAEP encryption
11
- * (OpenSSL on Android, CommonCrypto on iOS)
12
- *
13
- * @requires react-native-quick-crypto - npm install react-native-quick-crypto
10
+ * Uses node-forge for pure JavaScript RSA-OAEP encryption.
11
+ * This works in Expo Go without native modules.
14
12
  */
15
13
  /**
16
14
  * Generates a random hex key matching Android's generateRandomHexKey()
@@ -30,10 +28,9 @@ export declare function generateRandomHexKey(): string;
30
28
  */
31
29
  export declare function hexToBase64(hexString: string): string;
32
30
  /**
33
- * Encrypts data using RSA with OAEP-SHA1 padding (native implementation)
31
+ * Encrypts data using RSA with OAEP-SHA1 padding
34
32
  *
35
33
  * MUST match Android's RSA/ECB/OAEPWithSHA-1AndMGF1Padding algorithm
36
- * Uses native crypto (OpenSSL on Android, CommonCrypto on iOS)
37
34
  *
38
35
  * @param data - Plain text data to encrypt (Base64 string of the secret key)
39
36
  * @param publicKeyPem - RSA public key in PEM format
@@ -1 +1 @@
1
- {"version":3,"file":"cryptoUtils.d.ts","sourceRoot":"","sources":["../src/cryptoUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAkCrD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAqBzE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,CAqBnF;AAGD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"cryptoUtils.d.ts","sourceRoot":"","sources":["../src/cryptoUtils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAU7C;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAmBzE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,0BAA0B,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,CAqBnF;AAGD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -8,10 +8,8 @@
8
8
  * - Input to RSA: secretKey as Base64 string
9
9
  * - Output: encrypted sessionId as Base64 string
10
10
  *
11
- * Uses react-native-quick-crypto for native RSA-OAEP encryption
12
- * (OpenSSL on Android, CommonCrypto on iOS)
13
- *
14
- * @requires react-native-quick-crypto - npm install react-native-quick-crypto
11
+ * Uses node-forge for pure JavaScript RSA-OAEP encryption.
12
+ * This works in Expo Go without native modules.
15
13
  */
16
14
  var __importDefault = (this && this.__importDefault) || function (mod) {
17
15
  return (mod && mod.__esModule) ? mod : { "default": mod };
@@ -21,7 +19,7 @@ exports.generateRandomHexKey = generateRandomHexKey;
21
19
  exports.hexToBase64 = hexToBase64;
22
20
  exports.encryptWithRSA = encryptWithRSA;
23
21
  exports.generateSessionCredentials = generateSessionCredentials;
24
- const react_native_quick_crypto_1 = __importDefault(require("react-native-quick-crypto"));
22
+ const node_forge_1 = __importDefault(require("node-forge"));
25
23
  /**
26
24
  * Generates a random hex key matching Android's generateRandomHexKey()
27
25
  *
@@ -55,32 +53,13 @@ function hexToBase64(hexString) {
55
53
  const byte = parseInt(hexString.substring(i, i + 2), 16);
56
54
  binaryString += String.fromCharCode(byte);
57
55
  }
58
- // Use btoa for Base64 encoding (available in React Native with Hermes)
59
- if (typeof btoa === 'function') {
60
- return btoa(binaryString);
61
- }
62
- // Fallback: manual Base64 encoding
63
- const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
64
- let result = '';
65
- let i = 0;
66
- while (i < binaryString.length) {
67
- const a = binaryString.charCodeAt(i++);
68
- const b = binaryString.charCodeAt(i++);
69
- const c = binaryString.charCodeAt(i++);
70
- const triplet = (a << 16) | ((b || 0) << 8) | (c || 0);
71
- result +=
72
- base64Chars[(triplet >> 18) & 0x3f] +
73
- base64Chars[(triplet >> 12) & 0x3f] +
74
- (isNaN(b) ? '=' : base64Chars[(triplet >> 6) & 0x3f]) +
75
- (isNaN(c) ? '=' : base64Chars[triplet & 0x3f]);
76
- }
77
- return result;
56
+ // Use forge's utility for Base64 encoding
57
+ return node_forge_1.default.util.encode64(binaryString);
78
58
  }
79
59
  /**
80
- * Encrypts data using RSA with OAEP-SHA1 padding (native implementation)
60
+ * Encrypts data using RSA with OAEP-SHA1 padding
81
61
  *
82
62
  * MUST match Android's RSA/ECB/OAEPWithSHA-1AndMGF1Padding algorithm
83
- * Uses native crypto (OpenSSL on Android, CommonCrypto on iOS)
84
63
  *
85
64
  * @param data - Plain text data to encrypt (Base64 string of the secret key)
86
65
  * @param publicKeyPem - RSA public key in PEM format
@@ -89,16 +68,17 @@ function hexToBase64(hexString) {
89
68
  */
90
69
  function encryptWithRSA(data, publicKeyPem) {
91
70
  try {
92
- // Convert string to Buffer
93
- const dataBuffer = Buffer.from(data, 'utf8');
71
+ // Parse the PEM-formatted public key
72
+ const publicKey = node_forge_1.default.pki.publicKeyFromPem(publicKeyPem);
94
73
  // Encrypt using RSA-OAEP with SHA-1 (matches Android's OAEPWithSHA-1AndMGF1Padding)
95
- const encrypted = react_native_quick_crypto_1.default.publicEncrypt({
96
- key: publicKeyPem,
97
- padding: react_native_quick_crypto_1.default.constants.RSA_PKCS1_OAEP_PADDING,
98
- oaepHash: 'sha1',
99
- }, dataBuffer);
100
- // Return as Base64 string
101
- return encrypted.toString('base64');
74
+ const encrypted = publicKey.encrypt(data, 'RSA-OAEP', {
75
+ md: node_forge_1.default.md.sha1.create(),
76
+ mgf1: {
77
+ md: node_forge_1.default.md.sha1.create(),
78
+ },
79
+ });
80
+ // Encode to Base64
81
+ return node_forge_1.default.util.encode64(encrypted);
102
82
  }
103
83
  catch (error) {
104
84
  console.error('[CryptoUtils] RSA encryption failed:', error);
@@ -1 +1 @@
1
- {"version":3,"file":"cryptoUtils.js","sourceRoot":"","sources":["../src/cryptoUtils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cryptoUtils.js","sourceRoot":"","sources":["../src/cryptoUtils.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;AAYH,oDAUC;AASD,kCAUC;AAYD,wCAmBC;AAoBD,gEAqBC;AA/GD,4DAA+B;AAE/B;;;;;;;GAOG;AACH,SAAgB,oBAAoB;IAClC,6CAA6C;IAC7C,iFAAiF;IACjF,OAAO,sCAAsC;SAC1C,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACtB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC;QACnC,MAAM,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;QAC1C,OAAO,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC,CAAC;SACD,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,WAAW,CAAC,SAAiB;IAC3C,sCAAsC;IACtC,IAAI,YAAY,GAAG,EAAE,CAAC;IACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,YAAY,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,0CAA0C;IAC1C,OAAO,oBAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,cAAc,CAAC,IAAY,EAAE,YAAoB;IAC/D,IAAI,CAAC;QACH,qCAAqC;QACrC,MAAM,SAAS,GAAG,oBAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,YAAY,CAAC,CAAC;QAE3D,oFAAoF;QACpF,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE;YACpD,EAAE,EAAE,oBAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE;YAC1B,IAAI,EAAE;gBACJ,EAAE,EAAE,oBAAK,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE;aAC3B;SACF,CAAC,CAAC;QAEH,mBAAmB;QACnB,OAAO,oBAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,KAAK,CAAC,CAAC;QAC7D,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,0BAA0B,CAAC,YAAoB;IAC7D,sBAAsB;IACtB,IAAI,CAAC,YAAY,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,8EAA8E;IAC9E,MAAM,YAAY,GAAG,oBAAoB,EAAE,CAAC;IAE5C,4DAA4D;IAC5D,MAAM,eAAe,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;IAElD,+EAA+E;IAC/E,MAAM,SAAS,GAAG,cAAc,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAEhE,OAAO,CAAC,GAAG,CAAC,0DAA0D,CAAC,CAAC;IAExE,OAAO;QACL,YAAY;QACZ,SAAS;KACV,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -8,7 +8,7 @@ export type { WidgetSDKConfig, WidgetEnvironment, DepositToken, WidgetMessageTyp
8
8
  export { WALLET_URLS, MessageTypes } from './types';
9
9
  export { WIDGET_URLS, getWidgetUrl } from './config';
10
10
  export { openNativeWallet, isWalletAvailable } from './walletUtils';
11
- export { authenticateWithBiometrics, isBiometricAvailable, getBiometryTypeLabel, BiometryTypes, } from './biometricUtils';
11
+ export { authenticateWithBiometrics, isBiometricAvailable, getBiometryTypeLabel, AuthenticationType, } from './biometricUtils';
12
12
  export type { BiometricResult, BiometricAvailability } from './biometricUtils';
13
13
  export { generateSessionCredentials, generateRandomHexKey, hexToBase64, } from './cryptoUtils';
14
14
  export type { SessionCredentials } from './cryptoUtils';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAEV,eAAe,EACf,iBAAiB,EACjB,YAAY,EAGZ,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,EAC3B,gCAAgC,EAGhC,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,YAAY,EAEV,eAAe,EACf,iBAAiB,EACjB,YAAY,EAGZ,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,EAC3B,gCAAgC,EAGhC,iBAAiB,EACjB,aAAa,EACb,wBAAwB,EACxB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGrD,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGpE,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAG/E,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,EACpB,WAAW,GACZ,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  * Export all public components, types, and utilities
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.hexToBase64 = exports.generateRandomHexKey = exports.generateSessionCredentials = exports.BiometryTypes = exports.getBiometryTypeLabel = exports.isBiometricAvailable = exports.authenticateWithBiometrics = exports.isWalletAvailable = exports.openNativeWallet = exports.getWidgetUrl = exports.WIDGET_URLS = exports.MessageTypes = exports.WALLET_URLS = exports.WidgetSDK = void 0;
7
+ exports.hexToBase64 = exports.generateRandomHexKey = exports.generateSessionCredentials = exports.AuthenticationType = exports.getBiometryTypeLabel = exports.isBiometricAvailable = exports.authenticateWithBiometrics = exports.isWalletAvailable = exports.openNativeWallet = exports.getWidgetUrl = exports.WIDGET_URLS = exports.MessageTypes = exports.WALLET_URLS = exports.WidgetSDK = void 0;
8
8
  var WidgetSDK_1 = require("./WidgetSDK");
9
9
  Object.defineProperty(exports, "WidgetSDK", { enumerable: true, get: function () { return WidgetSDK_1.WidgetSDK; } });
10
10
  // Export constants
@@ -23,7 +23,7 @@ var biometricUtils_1 = require("./biometricUtils");
23
23
  Object.defineProperty(exports, "authenticateWithBiometrics", { enumerable: true, get: function () { return biometricUtils_1.authenticateWithBiometrics; } });
24
24
  Object.defineProperty(exports, "isBiometricAvailable", { enumerable: true, get: function () { return biometricUtils_1.isBiometricAvailable; } });
25
25
  Object.defineProperty(exports, "getBiometryTypeLabel", { enumerable: true, get: function () { return biometricUtils_1.getBiometryTypeLabel; } });
26
- Object.defineProperty(exports, "BiometryTypes", { enumerable: true, get: function () { return biometricUtils_1.BiometryTypes; } });
26
+ Object.defineProperty(exports, "AuthenticationType", { enumerable: true, get: function () { return biometricUtils_1.AuthenticationType; } });
27
27
  // Export crypto utilities (for advanced usage)
28
28
  var cryptoUtils_1 = require("./cryptoUtils");
29
29
  Object.defineProperty(exports, "generateSessionCredentials", { enumerable: true, get: function () { return cryptoUtils_1.generateSessionCredentials; } });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAiClB,mBAAmB;AACnB,iCAAoD;AAA3C,oGAAA,WAAW,OAAA;AAAE,qGAAA,YAAY,OAAA;AAClC,mCAAqD;AAA5C,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAElC,0BAA0B;AAC1B,6CAAoE;AAA3D,+GAAA,gBAAgB,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAE5C,6BAA6B;AAC7B,mDAK0B;AAJxB,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,sHAAA,oBAAoB,OAAA;AACpB,+GAAA,aAAa,OAAA;AAIf,+CAA+C;AAC/C,6CAIuB;AAHrB,yHAAA,0BAA0B,OAAA;AAC1B,mHAAA,oBAAoB,OAAA;AACpB,0GAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAiClB,mBAAmB;AACnB,iCAAoD;AAA3C,oGAAA,WAAW,OAAA;AAAE,qGAAA,YAAY,OAAA;AAClC,mCAAqD;AAA5C,qGAAA,WAAW,OAAA;AAAE,sGAAA,YAAY,OAAA;AAElC,0BAA0B;AAC1B,6CAAoE;AAA3D,+GAAA,gBAAgB,OAAA;AAAE,gHAAA,iBAAiB,OAAA;AAE5C,6BAA6B;AAC7B,mDAK0B;AAJxB,4HAAA,0BAA0B,OAAA;AAC1B,sHAAA,oBAAoB,OAAA;AACpB,sHAAA,oBAAoB,OAAA;AACpB,oHAAA,kBAAkB,OAAA;AAIpB,+CAA+C;AAC/C,6CAIuB;AAHrB,yHAAA,0BAA0B,OAAA;AAC1B,mHAAA,oBAAoB,OAAA;AACpB,0GAAA,WAAW,OAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oobit/react-native-sdk",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "React Native SDK for integrating Oobit crypto payments into wallet apps",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -41,23 +41,25 @@
41
41
  "peerDependencies": {
42
42
  "expo-intent-launcher": ">=6.0.0",
43
43
  "expo-linking": ">=6.0.0",
44
+ "expo-local-authentication": ">=14.0.0",
44
45
  "react": ">=18.0.0",
45
46
  "react-native": ">=0.70.0",
46
- "react-native-webview": ">=13.0.0",
47
- "react-native-biometrics": ">=3.0.0",
48
- "react-native-quick-crypto": ">=0.7.0"
47
+ "react-native-webview": ">=13.0.0"
48
+ },
49
+ "dependencies": {
50
+ "node-forge": "^1.3.1"
49
51
  },
50
52
  "devDependencies": {
53
+ "@types/node-forge": "^1.3.11",
51
54
  "@types/react": "~19.1.0",
52
55
  "@typescript-eslint/eslint-plugin": "^8.47.0",
53
56
  "@typescript-eslint/parser": "^8.47.0",
54
57
  "eslint": "^9.39.1",
55
58
  "expo-intent-launcher": "~13.0.7",
56
59
  "expo-linking": "~8.0.8",
60
+ "expo-local-authentication": "~15.0.2",
57
61
  "react": "19.1.0",
58
62
  "react-native": "0.81.5",
59
- "react-native-biometrics": "^3.0.1",
60
- "react-native-quick-crypto": "^0.7.9",
61
63
  "react-native-webview": "13.15.0",
62
64
  "typescript": "~5.9.2"
63
65
  },
@@ -2,12 +2,12 @@
2
2
  * Biometric Authentication Utilities
3
3
  *
4
4
  * Provides cross-platform biometric authentication for card details access.
5
- * Supports Face ID, Touch ID, and Android biometrics.
5
+ * Uses expo-local-authentication which works in Expo Go without native modules.
6
6
  *
7
- * @requires react-native-biometrics - npm install react-native-biometrics
7
+ * @requires expo-local-authentication - included in Expo SDK
8
8
  */
9
9
 
10
- import ReactNativeBiometrics, { BiometryTypes, type BiometryType } from 'react-native-biometrics';
10
+ import * as LocalAuthentication from 'expo-local-authentication';
11
11
 
12
12
  /**
13
13
  * Result of a biometric authentication attempt
@@ -28,33 +28,30 @@ export interface BiometricResult {
28
28
  export interface BiometricAvailability {
29
29
  /** Whether any biometric authentication is available */
30
30
  available: boolean;
31
- /** The type of biometry available (FaceID, TouchID, Biometrics, or null) */
32
- biometryType: BiometryType | null;
31
+ /** The types of biometry available */
32
+ biometryTypes: LocalAuthentication.AuthenticationType[];
33
33
  }
34
34
 
35
- // Singleton instance of ReactNativeBiometrics
36
- const rnBiometrics = new ReactNativeBiometrics({
37
- allowDeviceCredentials: false, // Only allow biometric, not PIN/password fallback
38
- });
39
-
40
35
  /**
41
36
  * Checks if biometric authentication is available on the device
42
37
  *
43
- * @returns Object containing availability status and biometry type
38
+ * @returns Object containing availability status and biometry types
44
39
  */
45
40
  export async function isBiometricAvailable(): Promise<BiometricAvailability> {
46
41
  try {
47
- const { available, biometryType } = await rnBiometrics.isSensorAvailable();
42
+ const hasHardware = await LocalAuthentication.hasHardwareAsync();
43
+ const isEnrolled = await LocalAuthentication.isEnrolledAsync();
44
+ const supportedTypes = await LocalAuthentication.supportedAuthenticationTypesAsync();
48
45
 
49
46
  return {
50
- available,
51
- biometryType: biometryType || null,
47
+ available: hasHardware && isEnrolled,
48
+ biometryTypes: supportedTypes,
52
49
  };
53
50
  } catch (error) {
54
51
  console.error('[BiometricUtils] Error checking biometric availability:', error);
55
52
  return {
56
53
  available: false,
57
- biometryType: null,
54
+ biometryTypes: [],
58
55
  };
59
56
  }
60
57
  }
@@ -84,9 +81,9 @@ export async function authenticateWithBiometrics(
84
81
  ): Promise<BiometricResult> {
85
82
  try {
86
83
  // First check if biometrics are available
87
- const { available, biometryType } = await rnBiometrics.isSensorAvailable();
84
+ const hasHardware = await LocalAuthentication.hasHardwareAsync();
88
85
 
89
- if (!available) {
86
+ if (!hasHardware) {
90
87
  console.log('[BiometricUtils] Biometrics not available on device');
91
88
  return {
92
89
  success: false,
@@ -98,48 +95,44 @@ export async function authenticateWithBiometrics(
98
95
  }
99
96
 
100
97
  // Check if biometrics are enrolled
101
- const { keysExist } = await rnBiometrics.biometricKeysExist();
98
+ const isEnrolled = await LocalAuthentication.isEnrolledAsync();
102
99
 
103
- // Note: Even without keys, simplePrompt should work for basic authentication
104
- // The keysExist check is more for cryptographic operations
100
+ if (!isEnrolled) {
101
+ console.log('[BiometricUtils] No biometrics enrolled');
102
+ return {
103
+ success: false,
104
+ error: {
105
+ reason: 'not_enrolled',
106
+ message: 'No biometric authentication is set up on this device',
107
+ },
108
+ };
109
+ }
105
110
 
106
- console.log(
107
- `[BiometricUtils] Attempting biometric auth. Type: ${biometryType}, Keys exist: ${keysExist}`
108
- );
111
+ console.log('[BiometricUtils] Attempting biometric authentication...');
109
112
 
110
113
  // Perform the biometric authentication
111
- const { success, error } = await rnBiometrics.simplePrompt({
114
+ const result = await LocalAuthentication.authenticateAsync({
112
115
  promptMessage,
113
- cancelButtonText: 'Cancel',
116
+ cancelLabel: 'Cancel',
117
+ disableDeviceFallback: false, // Allow PIN/password fallback
118
+ fallbackLabel: 'Use Passcode',
114
119
  });
115
120
 
116
- if (success) {
121
+ if (result.success) {
117
122
  console.log('[BiometricUtils] Biometric authentication successful');
118
123
  return { success: true };
119
124
  }
120
125
 
121
126
  // Handle various failure reasons
122
- console.log('[BiometricUtils] Biometric authentication failed:', error);
127
+ console.log('[BiometricUtils] Biometric authentication failed:', result.error);
123
128
 
124
- // Parse the error message to determine the reason
125
- const errorMessage = error || 'Authentication failed';
126
- let reason: NonNullable<BiometricResult['error']>['reason'] = 'failed';
129
+ let reason: 'cancelled' | 'failed' | 'not_available' | 'not_enrolled' = 'failed';
127
130
 
128
- if (
129
- errorMessage.toLowerCase().includes('cancel') ||
130
- errorMessage.toLowerCase().includes('user cancel')
131
- ) {
131
+ if (result.error === 'user_cancel' || result.error === 'system_cancel') {
132
132
  reason = 'cancelled';
133
- } else if (
134
- errorMessage.toLowerCase().includes('not enrolled') ||
135
- errorMessage.toLowerCase().includes('no fingerprint') ||
136
- errorMessage.toLowerCase().includes('no face')
137
- ) {
133
+ } else if (result.error === 'not_enrolled') {
138
134
  reason = 'not_enrolled';
139
- } else if (
140
- errorMessage.toLowerCase().includes('not available') ||
141
- errorMessage.toLowerCase().includes('not supported')
142
- ) {
135
+ } else if (result.error === 'not_available') {
143
136
  reason = 'not_available';
144
137
  }
145
138
 
@@ -147,14 +140,13 @@ export async function authenticateWithBiometrics(
147
140
  success: false,
148
141
  error: {
149
142
  reason,
150
- message: errorMessage,
143
+ message: result.warning || 'Authentication failed',
151
144
  },
152
145
  };
153
146
  } catch (error) {
154
147
  console.error('[BiometricUtils] Biometric authentication error:', error);
155
148
 
156
- const errorMessage =
157
- error instanceof Error ? error.message : 'Unknown error occurred';
149
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
158
150
 
159
151
  return {
160
152
  success: false,
@@ -172,18 +164,20 @@ export async function authenticateWithBiometrics(
172
164
  * @param biometryType - The biometry type from the device
173
165
  * @returns Human-readable string for the biometry type
174
166
  */
175
- export function getBiometryTypeLabel(biometryType: BiometryType | null): string {
167
+ export function getBiometryTypeLabel(
168
+ biometryType: LocalAuthentication.AuthenticationType
169
+ ): string {
176
170
  switch (biometryType) {
177
- case BiometryTypes.FaceID:
171
+ case LocalAuthentication.AuthenticationType.FACIAL_RECOGNITION:
178
172
  return 'Face ID';
179
- case BiometryTypes.TouchID:
173
+ case LocalAuthentication.AuthenticationType.FINGERPRINT:
180
174
  return 'Touch ID';
181
- case BiometryTypes.Biometrics:
182
- return 'Biometrics';
175
+ case LocalAuthentication.AuthenticationType.IRIS:
176
+ return 'Iris';
183
177
  default:
184
178
  return 'Biometric Authentication';
185
179
  }
186
180
  }
187
181
 
188
- // Re-export BiometryTypes for convenience
189
- export { BiometryTypes };
182
+ // Re-export AuthenticationType for convenience
183
+ export { AuthenticationType } from 'expo-local-authentication';
@@ -7,13 +7,11 @@
7
7
  * - Input to RSA: secretKey as Base64 string
8
8
  * - Output: encrypted sessionId as Base64 string
9
9
  *
10
- * Uses react-native-quick-crypto for native RSA-OAEP encryption
11
- * (OpenSSL on Android, CommonCrypto on iOS)
12
- *
13
- * @requires react-native-quick-crypto - npm install react-native-quick-crypto
10
+ * Uses node-forge for pure JavaScript RSA-OAEP encryption.
11
+ * This works in Expo Go without native modules.
14
12
  */
15
13
 
16
- import QuickCrypto from 'react-native-quick-crypto';
14
+ import forge from 'node-forge';
17
15
 
18
16
  /**
19
17
  * Generates a random hex key matching Android's generateRandomHexKey()
@@ -50,39 +48,14 @@ export function hexToBase64(hexString: string): string {
50
48
  binaryString += String.fromCharCode(byte);
51
49
  }
52
50
 
53
- // Use btoa for Base64 encoding (available in React Native with Hermes)
54
- if (typeof btoa === 'function') {
55
- return btoa(binaryString);
56
- }
57
-
58
- // Fallback: manual Base64 encoding
59
- const base64Chars =
60
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
61
- let result = '';
62
- let i = 0;
63
-
64
- while (i < binaryString.length) {
65
- const a = binaryString.charCodeAt(i++);
66
- const b = binaryString.charCodeAt(i++);
67
- const c = binaryString.charCodeAt(i++);
68
-
69
- const triplet = (a << 16) | ((b || 0) << 8) | (c || 0);
70
-
71
- result +=
72
- base64Chars[(triplet >> 18) & 0x3f] +
73
- base64Chars[(triplet >> 12) & 0x3f] +
74
- (isNaN(b) ? '=' : base64Chars[(triplet >> 6) & 0x3f]) +
75
- (isNaN(c) ? '=' : base64Chars[triplet & 0x3f]);
76
- }
77
-
78
- return result;
51
+ // Use forge's utility for Base64 encoding
52
+ return forge.util.encode64(binaryString);
79
53
  }
80
54
 
81
55
  /**
82
- * Encrypts data using RSA with OAEP-SHA1 padding (native implementation)
56
+ * Encrypts data using RSA with OAEP-SHA1 padding
83
57
  *
84
58
  * MUST match Android's RSA/ECB/OAEPWithSHA-1AndMGF1Padding algorithm
85
- * Uses native crypto (OpenSSL on Android, CommonCrypto on iOS)
86
59
  *
87
60
  * @param data - Plain text data to encrypt (Base64 string of the secret key)
88
61
  * @param publicKeyPem - RSA public key in PEM format
@@ -91,21 +64,19 @@ export function hexToBase64(hexString: string): string {
91
64
  */
92
65
  export function encryptWithRSA(data: string, publicKeyPem: string): string {
93
66
  try {
94
- // Convert string to Buffer
95
- const dataBuffer = Buffer.from(data, 'utf8');
67
+ // Parse the PEM-formatted public key
68
+ const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
96
69
 
97
70
  // Encrypt using RSA-OAEP with SHA-1 (matches Android's OAEPWithSHA-1AndMGF1Padding)
98
- const encrypted = QuickCrypto.publicEncrypt(
99
- {
100
- key: publicKeyPem,
101
- padding: QuickCrypto.constants.RSA_PKCS1_OAEP_PADDING,
102
- oaepHash: 'sha1',
71
+ const encrypted = publicKey.encrypt(data, 'RSA-OAEP', {
72
+ md: forge.md.sha1.create(),
73
+ mgf1: {
74
+ md: forge.md.sha1.create(),
103
75
  },
104
- dataBuffer
105
- );
76
+ });
106
77
 
107
- // Return as Base64 string
108
- return encrypted.toString('base64');
78
+ // Encode to Base64
79
+ return forge.util.encode64(encrypted);
109
80
  } catch (error) {
110
81
  console.error('[CryptoUtils] RSA encryption failed:', error);
111
82
  throw new Error('Failed to encrypt session data');
package/src/index.ts CHANGED
@@ -48,7 +48,7 @@ export {
48
48
  authenticateWithBiometrics,
49
49
  isBiometricAvailable,
50
50
  getBiometryTypeLabel,
51
- BiometryTypes,
51
+ AuthenticationType,
52
52
  } from './biometricUtils';
53
53
  export type { BiometricResult, BiometricAvailability } from './biometricUtils';
54
54