react-native-biometric-verifier 0.0.48 → 0.0.49

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-biometric-verifier",
3
- "version": "0.0.48",
3
+ "version": "0.0.49",
4
4
  "description": "A React Native module for biometric verification with face recognition and QR code scanning",
5
5
  "main": "src/index.js",
6
6
  "private": false,
@@ -3,7 +3,7 @@ import { Platform, PermissionsAndroid } from 'react-native';
3
3
  import Geolocation from 'react-native-geolocation-service';
4
4
 
5
5
  /**
6
- * Geolocation Hook for GPS functionality
6
+ * FAST + ACCURATE Geolocation Hook (Optimized for Verification)
7
7
  */
8
8
  export const useGeolocation = (notifyMessage) => {
9
9
  const locationWatchId = useRef(null);
@@ -36,7 +36,7 @@ export const useGeolocation = (notifyMessage) => {
36
36
 
37
37
  return granted;
38
38
  } catch (err) {
39
- console.error('[Geolocation Permissions] Error:', err);
39
+ console.error('[Geo Permissions]', err);
40
40
  return false;
41
41
  }
42
42
  }, [notifyMessage]);
@@ -52,90 +52,127 @@ export const useGeolocation = (notifyMessage) => {
52
52
  }, []);
53
53
 
54
54
  /* -------------------------------------------------------------------------- */
55
- /* HIGH ACCURACY GPS */
55
+ /* FAST + ACCURATE LOCATION FETCH */
56
56
  /* -------------------------------------------------------------------------- */
57
57
  const getCurrentLocation = useCallback((options = {}) => {
58
- return new Promise(async (resolve, reject) => {
59
- let bestCoords = null;
60
- let bestAccuracy = Infinity;
58
+ return new Promise((resolve, reject) => {
59
+ let samples = [];
60
+ let resolved = false;
61
61
 
62
62
  const defaultOptions = {
63
63
  enableHighAccuracy: true,
64
- timeout: 20000,
65
- maximumAge: 0,
64
+ timeout: 8000, // ⏱ fast
65
+ maximumAge: 2000, // allow cached fix
66
66
  forceRequestLocation: true,
67
67
  showLocationDialog: true,
68
+ interval: 800,
69
+ fastestInterval: 500,
70
+ distanceFilter: 0,
68
71
  ...options,
69
72
  };
70
73
 
71
74
  try {
72
- const pos = await new Promise((res, rej) => {
73
- Geolocation.getCurrentPosition(res, rej, defaultOptions);
74
- });
75
-
76
- if (!pos.coords || typeof pos.coords.latitude !== 'number' || typeof pos.coords.longitude !== 'number') {
77
- reject(new Error('Invalid GPS coordinates received'));
78
- return;
79
- }
80
-
81
- bestCoords = {
82
- latitude: pos.coords.latitude,
83
- longitude: pos.coords.longitude,
84
- altitude: pos.coords.altitude || 0,
85
- accuracy: pos.coords.accuracy,
86
- speed: pos.coords.speed || 0,
87
- heading: pos.coords.heading || 0,
88
- timestamp: pos.timestamp,
89
- };
90
-
91
- bestAccuracy = pos.coords.accuracy;
92
-
93
- if (bestAccuracy > 15) {
94
- locationWatchId.current = Geolocation.watchPosition(
95
- (p) => {
96
- if (
97
- p.coords &&
98
- typeof p.coords.latitude === 'number' &&
99
- typeof p.coords.longitude === 'number' &&
100
- p.coords.accuracy < bestAccuracy
101
- ) {
102
- bestAccuracy = p.coords.accuracy;
103
- bestCoords = {
104
- latitude: p.coords.latitude,
105
- longitude: p.coords.longitude,
106
- altitude: p.coords.altitude || 0,
107
- accuracy: p.coords.accuracy,
108
- speed: p.coords.speed || 0,
109
- heading: p.coords.heading || 0,
110
- timestamp: p.timestamp,
111
- };
112
- }
113
-
114
- if (bestAccuracy <= 5) {
115
- stopLocationWatching();
116
- }
117
- },
118
- (err) => {
119
- console.error('[Geolocation Watch Error]:', err);
75
+ /* ---------------- FAST FIRST FIX ---------------- */
76
+ Geolocation.getCurrentPosition(
77
+ (pos) => {
78
+ if (!pos?.coords || resolved) return;
79
+
80
+ const {
81
+ latitude,
82
+ longitude,
83
+ accuracy,
84
+ altitude = 0,
85
+ speed = 0,
86
+ heading = 0,
87
+ } = pos.coords;
88
+
89
+ // Accept immediately if good enough for verification
90
+ if (accuracy <= 15) {
91
+ resolved = true;
92
+ resolve({
93
+ latitude,
94
+ longitude,
95
+ altitude,
96
+ accuracy,
97
+ speed,
98
+ heading,
99
+ timestamp: pos.timestamp,
100
+ });
101
+ }
102
+
103
+ samples.push({
104
+ latitude,
105
+ longitude,
106
+ altitude,
107
+ accuracy,
108
+ speed,
109
+ heading,
110
+ timestamp: pos.timestamp,
111
+ });
112
+ },
113
+ (err) => {
114
+ console.warn('[Geo Fast Fix Failed]', err);
115
+ },
116
+ defaultOptions
117
+ );
118
+
119
+ /* ---------------- BACKGROUND IMPROVEMENT ---------------- */
120
+ locationWatchId.current = Geolocation.watchPosition(
121
+ (p) => {
122
+ if (!p?.coords) return;
123
+
124
+ const {
125
+ latitude,
126
+ longitude,
127
+ accuracy,
128
+ altitude = 0,
129
+ speed = 0,
130
+ heading = 0,
131
+ } = p.coords;
132
+
133
+ /* -------- LIGHT NOISE FILTERS -------- */
134
+ if (accuracy > 40) return;
135
+ if (speed > 50) return;
136
+
137
+ samples.push({
138
+ latitude,
139
+ longitude,
140
+ altitude,
141
+ accuracy,
142
+ speed,
143
+ heading,
144
+ timestamp: p.timestamp,
145
+ });
146
+
147
+ if (samples.length > 8) samples.shift();
148
+
149
+ samples.sort((a, b) => a.accuracy - b.accuracy);
150
+ const best = samples[0];
151
+
152
+ // Upgrade accuracy silently
153
+ if (best.accuracy <= 6 && !resolved) {
154
+ resolved = true;
120
155
  stopLocationWatching();
121
- },
122
- defaultOptions
123
- );
124
-
125
- setTimeout(() => stopLocationWatching(), 12000);
126
- }
127
-
128
- resolve({
129
- latitude: bestCoords.latitude,
130
- longitude: bestCoords.longitude,
131
- altitude: bestCoords.altitude,
132
- accuracy: bestAccuracy,
133
- speed: bestCoords.speed,
134
- heading: bestCoords.heading,
135
- timestamp: bestCoords.timestamp,
136
- });
156
+ resolve(best);
157
+ }
158
+ },
159
+ (err) => {
160
+ console.error('[Geo Watch Error]', err);
161
+ stopLocationWatching();
162
+ },
163
+ defaultOptions
164
+ );
165
+
166
+ /* ---------------- HARD STOP ---------------- */
167
+ setTimeout(() => {
168
+ if (!resolved && samples.length) {
169
+ resolved = true;
170
+ stopLocationWatching();
171
+ samples.sort((a, b) => a.accuracy - b.accuracy);
172
+ resolve(samples[0]);
173
+ }
174
+ }, 5000);
137
175
  } catch (err) {
138
- console.error('[Geolocation] Failed to get location:', err);
139
176
  stopLocationWatching();
140
177
  notifyMessage?.('Failed to get location', 'error');
141
178
  reject(err);
@@ -150,28 +187,31 @@ export const useGeolocation = (notifyMessage) => {
150
187
  (lat1, lon1, lat2, lon2, alt1 = 0, alt2 = 0) => {
151
188
  try {
152
189
  if (
153
- typeof lat1 !== 'number' || typeof lon1 !== 'number' ||
154
- typeof lat2 !== 'number' || typeof lon2 !== 'number' ||
155
- isNaN(lat1) || isNaN(lon1) || isNaN(lat2) || isNaN(lon2)
190
+ typeof lat1 !== 'number' ||
191
+ typeof lon1 !== 'number' ||
192
+ typeof lat2 !== 'number' ||
193
+ typeof lon2 !== 'number'
156
194
  ) return Infinity;
157
195
 
158
- const toRad = (deg) => deg * Math.PI / 180;
159
- const R = 6371e3; // meters
196
+ const toRad = deg => deg * Math.PI / 180;
197
+ const R = 6371e3;
198
+
160
199
  const φ1 = toRad(lat1);
161
200
  const φ2 = toRad(lat2);
162
201
  const Δφ = toRad(lat2 - lat1);
163
202
  const Δλ = toRad(lon2 - lon1);
164
203
 
165
- const a = Math.sin(Δφ / 2) ** 2 +
166
- Math.cos(φ1) * Math.cos(φ2) *
167
- Math.sin(Δλ / 2) ** 2;
204
+ const a =
205
+ Math.sin(Δφ / 2) ** 2 +
206
+ Math.cos(φ1) * Math.cos(φ2) *
207
+ Math.sin(Δλ / 2) ** 2;
208
+
168
209
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
169
210
  const surfaceDistance = R * c;
170
211
 
171
- const heightDifference = Math.abs(alt1 - alt2);
172
- return Math.sqrt(surfaceDistance ** 2 + heightDifference ** 2);
173
- } catch (err) {
174
- console.error('[Geolocation Distance] Error:', err);
212
+ const heightDiff = Math.abs(alt1 - alt2);
213
+ return Math.sqrt(surfaceDistance ** 2 + heightDiff ** 2);
214
+ } catch {
175
215
  return Infinity;
176
216
  }
177
217
  },
@@ -179,25 +219,20 @@ export const useGeolocation = (notifyMessage) => {
179
219
  );
180
220
 
181
221
  const calculateSafeDistance = useCallback(
182
- (point1, point2) => {
222
+ (p1, p2) => {
183
223
  try {
184
- const lat1 = typeof point1.latitude === 'number' ? point1.latitude :
185
- typeof point1.lat === 'number' ? point1.lat : 0;
186
- const lon1 = typeof point1.longitude === 'number' ? point1.longitude :
187
- typeof point1.lng === 'number' ? point1.lng :
188
- typeof point1.lon === 'number' ? point1.lon : 0;
189
- const alt1 = point1.altitude || point1.alt || 0;
190
-
191
- const lat2 = typeof point2.latitude === 'number' ? point2.latitude :
192
- typeof point2.lat === 'number' ? point2.lat : 0;
193
- const lon2 = typeof point2.longitude === 'number' ? point2.longitude :
194
- typeof point2.lng === 'number' ? point2.lng :
195
- typeof point2.lon === 'number' ? point2.lon : 0;
196
- const alt2 = point2.altitude || point2.alt || 0;
197
-
198
- return calculateEnhancedDistance(lat1, lon1, lat2, lon2, alt1, alt2);
199
- } catch (err) {
200
- console.error('[Geolocation SafeDistance] Error:', err);
224
+ const lat1 = p1.latitude ?? p1.lat;
225
+ const lon1 = p1.longitude ?? p1.lng ?? p1.lon;
226
+ const alt1 = p1.altitude ?? p1.alt ?? 0;
227
+
228
+ const lat2 = p2.latitude ?? p2.lat;
229
+ const lon2 = p2.longitude ?? p2.lng ?? p2.lon;
230
+ const alt2 = p2.altitude ?? p2.alt ?? 0;
231
+
232
+ return calculateEnhancedDistance(
233
+ lat1, lon1, lat2, lon2, alt1, alt2
234
+ );
235
+ } catch {
201
236
  return Infinity;
202
237
  }
203
238
  },
@@ -205,15 +240,13 @@ export const useGeolocation = (notifyMessage) => {
205
240
  );
206
241
 
207
242
  /* -------------------------------------------------------------------------- */
208
- /* GETTERS */
243
+ /* API */
209
244
  /* -------------------------------------------------------------------------- */
210
- const getCurrentWatchId = useCallback(() => locationWatchId.current, []);
211
-
212
245
  return {
213
246
  requestLocationPermission,
214
247
  getCurrentLocation,
215
248
  stopLocationWatching,
216
- getCurrentWatchId,
249
+ getCurrentWatchId: () => locationWatchId.current,
217
250
  calculateEnhancedDistance,
218
251
  calculateSafeDistance,
219
252
  };
package/src/index.js CHANGED
@@ -18,11 +18,9 @@ import {
18
18
  } from "react-native";
19
19
  import Icon from "react-native-vector-icons/MaterialIcons";
20
20
 
21
- // Custom hooks
21
+ // Custom hooks - Removed unnecessary ones
22
22
  import { useCountdown } from "./hooks/useCountdown";
23
23
  import { useGeolocation } from "./hooks/useGeolocation";
24
- import { useWifiService } from "./hooks/useWifiService";
25
- import { useBluetoothService } from "./hooks/useBluetoothService";
26
24
  import { useImageProcessing } from "./hooks/useImageProcessing";
27
25
  import { useNotifyMessage } from "./hooks/useNotifyMessage";
28
26
  import { useSafeCallback } from "./hooks/useSafeCallback";
@@ -54,13 +52,12 @@ const BiometricModal = forwardRef(({
54
52
  navigation,
55
53
  MaxDistanceMeters = 30,
56
54
  duration = 100,
57
- useWiFiFingerprinting = true,
58
55
  }, ref) => {
59
56
  // Custom hooks - Initialize notification hook first
60
57
  const { notification, fadeAnim, slideAnim, notifyMessage, clearNotification } = useNotifyMessage();
61
58
  const { countdown, startCountdown, resetCountdown, pauseCountdown, resumeCountdown } = useCountdown(duration);
62
59
 
63
- // Split hooks for geolocation and WiFi
60
+ // Only keep geolocation hook
64
61
  const {
65
62
  requestLocationPermission,
66
63
  getCurrentLocation,
@@ -68,25 +65,10 @@ const BiometricModal = forwardRef(({
68
65
  calculateSafeDistance,
69
66
  } = useGeolocation(notifyMessage);
70
67
 
71
- const {
72
- requestWifiPermissions,
73
- scanWifiFingerprint,
74
- matchWifiFingerprint,
75
- getLocationWithWifi,
76
- } = useWifiService(notifyMessage);
77
-
78
- const {
79
- requestBluetoothPermission,
80
- startBluetoothScan,
81
- stopBluetoothScan,
82
- nearbyDevices,
83
- clearDevices,
84
- } = useBluetoothService(notifyMessage);
85
-
86
68
  const { convertImageToBase64 } = useImageProcessing();
87
69
  const safeCallback = useSafeCallback(callback, notifyMessage);
88
70
 
89
- // State
71
+ // State - Simplified
90
72
  const [modalVisible, setModalVisible] = useState(false);
91
73
  const [cameraType, setCameraType] = useState("back");
92
74
  const [state, setState] = useState({
@@ -96,7 +78,7 @@ const BiometricModal = forwardRef(({
96
78
  employeeData: null,
97
79
  animationState: Global.AnimationStates.qrScan,
98
80
  qrData: null,
99
- wifiReferenceScan: null,
81
+ // Removed: wifiReferenceScan
100
82
  });
101
83
 
102
84
  // Refs
@@ -105,8 +87,7 @@ const BiometricModal = forwardRef(({
105
87
  const responseRef = useRef(null);
106
88
  const processedRef = useRef(false);
107
89
  const resetTimeoutRef = useRef(null);
108
- const bleScanTimeoutRef = useRef(null);
109
- const wifiScanTimeoutRef = useRef(null);
90
+ // Removed: bleScanTimeoutRef, wifiScanTimeoutRef
110
91
 
111
92
  // Animation values
112
93
  const iconScaleAnim = useRef(new Animated.Value(1)).current;
@@ -120,7 +101,7 @@ const BiometricModal = forwardRef(({
120
101
  getStatus: () => state,
121
102
  }));
122
103
 
123
- // Cleanup on unmount
104
+ // Cleanup on unmount - Simplified
124
105
  useEffect(() => {
125
106
  return () => {
126
107
  mountedRef.current = false;
@@ -129,20 +110,10 @@ const BiometricModal = forwardRef(({
129
110
  clearTimeout(resetTimeoutRef.current);
130
111
  }
131
112
 
132
- if (bleScanTimeoutRef.current) {
133
- clearTimeout(bleScanTimeoutRef.current);
134
- }
135
-
136
- if (wifiScanTimeoutRef.current) {
137
- clearTimeout(wifiScanTimeoutRef.current);
138
- }
139
-
140
- stopBluetoothScan();
141
113
  stopLocationWatching();
142
- clearDevices();
143
114
  clearNotification();
144
115
  };
145
- }, [stopBluetoothScan, stopLocationWatching, clearDevices, clearNotification]);
116
+ }, [stopLocationWatching, clearNotification]);
146
117
 
147
118
  // Update dataRef when data changes
148
119
  useEffect(() => {
@@ -202,7 +173,7 @@ const BiometricModal = forwardRef(({
202
173
  }
203
174
  }, [animateIcon, pauseCountdown, resumeCountdown]);
204
175
 
205
- // Reset state helper
176
+ // Reset state helper - Simplified
206
177
  const resetState = useCallback(() => {
207
178
  if (onclose) {
208
179
  onclose(false);
@@ -215,22 +186,19 @@ const BiometricModal = forwardRef(({
215
186
  employeeData: null,
216
187
  animationState: Global.AnimationStates.qrScan,
217
188
  qrData: null,
218
- wifiReferenceScan: null,
219
189
  });
220
190
 
221
191
  setModalVisible(false);
222
192
  processedRef.current = false;
223
193
  resetCountdown();
224
- stopBluetoothScan();
225
194
  stopLocationWatching();
226
- clearDevices();
227
195
  clearNotification();
228
196
 
229
197
  if (resetTimeoutRef.current) {
230
198
  clearTimeout(resetTimeoutRef.current);
231
199
  resetTimeoutRef.current = null;
232
200
  }
233
- }, [resetCountdown, stopBluetoothScan, stopLocationWatching, clearDevices, clearNotification, onclose]);
201
+ }, [resetCountdown, stopLocationWatching, clearNotification, onclose]);
234
202
 
235
203
  // Error handler
236
204
  const handleProcessError = useCallback(
@@ -276,108 +244,7 @@ const BiometricModal = forwardRef(({
276
244
  return true;
277
245
  }, [apiurl, handleProcessError]);
278
246
 
279
- /**
280
- * WiFi fingerprint scanning with validation
281
- */
282
- const performWiFiScan = useCallback(async () => {
283
- if (!useWiFiFingerprinting || Platform.OS !== 'android') {
284
- return { scan: [], score: 0, isMatch: false };
285
- }
286
-
287
- try {
288
- updateState({ loadingType: Global.LoadingTypes.wifiScan });
289
-
290
- // Request WiFi permissions if needed
291
- const hasWifiPermission = await requestWifiPermissions();
292
- if (!hasWifiPermission) {
293
- return { scan: [], score: 0, isMatch: false };
294
- }
295
-
296
- // Perform WiFi scan using the WiFi service hook
297
- const wifiScan = await scanWifiFingerprint();
298
-
299
- if (wifiScan.length === 0) {
300
- notifyMessage("No WiFi networks detected", "warning");
301
- return { scan: [], score: 0, isMatch: false };
302
- }
303
-
304
- // If we have a reference scan, match against it
305
- if (state.wifiReferenceScan && state.wifiReferenceScan.length > 0) {
306
- const matchResult = matchWifiFingerprint(wifiScan, state.wifiReferenceScan);
307
- const isMatch = matchResult.score >= 3; // Threshold of 3 matching APs
308
-
309
- if (isMatch) {
310
- notifyMessage(`WiFi fingerprint match: ${matchResult.score.toFixed(1)}`, "success");
311
- } else {
312
- notifyMessage(`Weak WiFi match: ${matchResult.score.toFixed(1)}`, "warning");
313
- }
314
-
315
- return {
316
- scan: wifiScan,
317
- score: matchResult.score,
318
- isMatch,
319
- matchDetails: matchResult
320
- };
321
- }
322
-
323
- // Return scan without matching
324
- return { scan: wifiScan, score: 0, isMatch: false };
325
- } catch (error) {
326
- console.warn("WiFi scan failed:", error);
327
- notifyMessage("WiFi scan unavailable", "warning");
328
- return { scan: [], score: 0, isMatch: false };
329
- }
330
- }, [
331
- useWiFiFingerprinting,
332
- requestWifiPermissions,
333
- scanWifiFingerprint,
334
- matchWifiFingerprint,
335
- state.wifiReferenceScan,
336
- notifyMessage,
337
- updateState
338
- ]);
339
-
340
- /**
341
- * Find consistent BLE devices across multiple samples
342
- */
343
- const findConsistentBLEDevices = useCallback((samples) => {
344
- const deviceMap = new Map();
345
-
346
- samples.forEach((sample, sampleIndex) => {
347
- sample.forEach(device => {
348
- if (!deviceMap.has(device.id)) {
349
- deviceMap.set(device.id, {
350
- ...device,
351
- distances: [],
352
- samples: 0
353
- });
354
- }
355
- const entry = deviceMap.get(device.id);
356
- entry.distances.push(parseFloat(device.distance));
357
- entry.samples++;
358
- });
359
- });
360
-
361
- // Filter for devices seen in at least 2 samples
362
- return Array.from(deviceMap.values())
363
- .filter(device => device.samples >= 2)
364
- .map(device => ({
365
- ...device,
366
- avgDistance: device.distances.reduce((a, b) => a + b, 0) / device.distances.length,
367
- stdDev: calculateStdDev(device.distances)
368
- }))
369
- .filter(device => device.stdDev < 2);
370
- }, []);
371
-
372
- /**
373
- * Calculate standard deviation
374
- */
375
- const calculateStdDev = (array) => {
376
- const n = array.length;
377
- const mean = array.reduce((a, b) => a + b) / n;
378
- return Math.sqrt(array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n);
379
- };
380
-
247
+ // Simplified QR scanning handler - GPS + Key verification only
381
248
  const handleQRScanned = useCallback(
382
249
  async (qrCodeData) => {
383
250
  if (!validateApiUrl()) return;
@@ -389,7 +256,7 @@ const BiometricModal = forwardRef(({
389
256
  });
390
257
 
391
258
  try {
392
- // 1. Request permissions
259
+ // 1. Request location permission
393
260
  updateState({ loadingType: Global.LoadingTypes.locationPermission });
394
261
  const hasLocationPermission = await requestLocationPermission();
395
262
  if (!hasLocationPermission) {
@@ -397,11 +264,6 @@ const BiometricModal = forwardRef(({
397
264
  return;
398
265
  }
399
266
 
400
- const hasBluetoothPermission = await requestBluetoothPermission();
401
- if (!hasBluetoothPermission) {
402
- notifyMessage("Bluetooth scanning may not work", "warning");
403
- }
404
-
405
267
  // 2. Parse QR data with validation
406
268
  const qrString = typeof qrCodeData === "object" ? qrCodeData?.data : qrCodeData;
407
269
  if (!qrString || typeof qrString !== "string") {
@@ -430,38 +292,12 @@ const BiometricModal = forwardRef(({
430
292
  return;
431
293
  }
432
294
 
433
- // 4. Perform initial WiFi scan FIRST to establish reference
434
- let wifiFingerprint = [];
435
- let wifiMatchScore = 0;
436
- let isWiFiMatch = false;
437
- let wifiMatchDetails = null;
438
-
439
- if (useWiFiFingerprinting && Platform.OS === 'android') {
440
- try {
441
- const wifiResult = await performWiFiScan();
442
- wifiFingerprint = wifiResult.scan;
443
-
444
- // Store as reference for later matching
445
- if (wifiFingerprint.length > 0) {
446
- updateState({ wifiReferenceScan: wifiFingerprint });
447
- }
448
- } catch (wifiError) {
449
- console.warn('WiFi scan failed:', wifiError);
450
- notifyMessage("WiFi scan failed, continuing without WiFi verification", "warning");
451
- }
452
- }
453
-
454
- // 5. Get high-accuracy location
295
+ // 4. Get high-accuracy location
455
296
  updateState({ loadingType: Global.LoadingTypes.gettingLocation });
456
297
 
457
298
  let location;
458
299
  try {
459
- // Use combined location with WiFi if available, otherwise just GPS
460
- if (useWiFiFingerprinting && wifiFingerprint.length > 0) {
461
- location = await getLocationWithWifi({ getCurrentLocation });
462
- } else {
463
- location = await getCurrentLocation();
464
- }
300
+ location = await getCurrentLocation();
465
301
  } catch (locationError) {
466
302
  console.error('Location error:', locationError);
467
303
  handleProcessError("Failed to get location. Please try again.");
@@ -486,45 +322,7 @@ const BiometricModal = forwardRef(({
486
322
  notifyMessage(`Location accuracy is ${location.accuracy.toFixed(1)}m. For best results, move to an open area.`, 'warning');
487
323
  }
488
324
 
489
- // 6. Perform SECOND WiFi scan to compare with reference
490
- if (useWiFiFingerprinting && Platform.OS === 'android' && state.wifiReferenceScan) {
491
- try {
492
- const wifiResult = await performWiFiScan();
493
- wifiFingerprint = wifiResult.scan;
494
- wifiMatchScore = wifiResult.score;
495
- isWiFiMatch = wifiResult.isMatch;
496
- wifiMatchDetails = wifiResult.matchDetails;
497
- } catch (wifiError) {
498
- console.warn('Second WiFi scan failed:', wifiError);
499
- // Continue without WiFi match
500
- }
501
- }
502
-
503
- // 7. Enhanced BLE scanning (optional)
504
- updateState({ loadingType: Global.LoadingTypes.bleScan });
505
-
506
- let consistentDevices = [];
507
- let isBLENearby = false;
508
-
509
- try {
510
- startBluetoothScan();
511
-
512
- // Collect BLE data with multiple samples
513
- const bleSamples = [];
514
- for (let i = 0; i < 3; i++) {
515
- await new Promise(resolve => setTimeout(resolve, 2000));
516
- bleSamples.push([...nearbyDevices]);
517
- }
518
-
519
- consistentDevices = findConsistentBLEDevices(bleSamples);
520
- isBLENearby = consistentDevices.length > 0 && consistentDevices.some(d => d.avgDistance <= 5);
521
- } catch (bleError) {
522
- console.warn("BLE scanning failed:", bleError);
523
- } finally {
524
- stopBluetoothScan();
525
- }
526
-
527
- // 8. Calculate distance using safe calculation
325
+ // 5. Calculate distance using safe calculation
528
326
  updateState({ loadingType: Global.LoadingTypes.calculateDistance });
529
327
 
530
328
  const distance = calculateSafeDistance(
@@ -540,20 +338,8 @@ const BiometricModal = forwardRef(({
540
338
 
541
339
  const distanceWithinThreshold = distance <= MaxDistanceMeters;
542
340
 
543
- // Enhanced verification criteria
544
- let verificationPassed = distanceWithinThreshold && qrDepKey === depkey;
545
- let verificationMethod = "GPS+Key";
546
-
547
- // Add WiFi fingerprint verification if enabled and we have a reference
548
- if (useWiFiFingerprinting && state.wifiReferenceScan && state.wifiReferenceScan.length > 0) {
549
- verificationMethod = isWiFiMatch ? "GPS+WiFi+Key" : "GPS+Key";
550
-
551
- if (isWiFiMatch) {
552
- // Strong WiFi verification achieved
553
- } else if (wifiFingerprint.length > 0) {
554
- notifyMessage(`WiFi environment changed (score: ${wifiMatchScore.toFixed(1)}). Using GPS verification.`, "warning");
555
- }
556
- }
341
+ // Simple verification criteria - GPS + Key only
342
+ const verificationPassed = distanceWithinThreshold && qrDepKey === depkey;
557
343
 
558
344
  if (verificationPassed) {
559
345
  const locationDetails = {
@@ -571,20 +357,11 @@ const BiometricModal = forwardRef(({
571
357
  heading: location.heading || 0,
572
358
  timestamp: location.timestamp || Date.now()
573
359
  },
574
- wifiFingerprint: {
575
- accessPoints: wifiFingerprint,
576
- matchScore: wifiMatchScore,
577
- isMatch: isWiFiMatch,
578
- enabled: useWiFiFingerprinting,
579
- matchDetails: wifiMatchDetails,
580
- referenceScanTimestamp: state.wifiReferenceScan?.[0]?.timestamp || Date.now()
581
- },
582
360
  distanceMeters: distance,
583
361
  accuracyBuffer: MaxDistanceMeters,
584
362
  verified: true,
585
- verificationMethod: verificationMethod,
363
+ verificationMethod: "GPS+Key",
586
364
  verifiedAt: new Date().toISOString(),
587
- bleDevicesDetected: consistentDevices,
588
365
  locationMethod: location.provider || 'unknown',
589
366
  qrData: qrString,
590
367
  qrKey: qrDepKey
@@ -599,52 +376,34 @@ const BiometricModal = forwardRef(({
599
376
  loadingType: Global.LoadingTypes.none,
600
377
  });
601
378
 
602
- let successMessage = `Location verified! Distance: ${distance.toFixed(1)}m (±${Math.max(location.accuracy || 0, qrAccuracy).toFixed(1)}m)`;
603
- if (useWiFiFingerprinting && isWiFiMatch) {
604
- successMessage += `, Strong WiFi match: ${wifiMatchScore.toFixed(1)}`;
605
- } else if (useWiFiFingerprinting && wifiFingerprint.length > 0) {
606
- successMessage += `, WiFi environment: ${wifiFingerprint.length} APs detected`;
607
- }
608
-
379
+ const successMessage = `Location verified! Distance: ${distance.toFixed(1)}m (±${Math.max(location.accuracy || 0, qrAccuracy).toFixed(1)}m)`;
609
380
  notifyMessage(successMessage, "success");
610
381
  setTimeout(() => startFaceRecognition(), 1200);
611
382
  } else {
612
383
  let errorMsg = `Verification failed: ${distance.toFixed(1)}m away`;
613
384
  if (qrDepKey !== depkey) errorMsg += " (Key mismatch)";
614
- if (useWiFiFingerprinting && wifiFingerprint.length > 0) {
615
- errorMsg += ` (WiFi environment: ${wifiFingerprint.length} APs)`;
616
- }
617
385
  handleProcessError(errorMsg);
618
386
  }
619
387
  } catch (error) {
620
- console.error("Enhanced verification failed:", error);
621
- handleProcessError("Unable to verify location or proximity.", error);
388
+ console.error("Location verification failed:", error);
389
+ handleProcessError("Unable to verify location. Please try again.", error);
622
390
  }
623
391
  },
624
392
  [
625
393
  validateApiUrl,
626
394
  updateState,
627
395
  requestLocationPermission,
628
- requestBluetoothPermission,
629
396
  getCurrentLocation,
630
- getLocationWithWifi,
631
- startBluetoothScan,
632
- stopBluetoothScan,
633
- nearbyDevices,
634
- findConsistentBLEDevices,
635
397
  notifyMessage,
636
398
  handleProcessError,
637
399
  startFaceRecognition,
638
400
  depkey,
639
401
  MaxDistanceMeters,
640
402
  calculateSafeDistance,
641
- useWiFiFingerprinting,
642
- performWiFiScan,
643
- state.wifiReferenceScan,
644
403
  ]
645
404
  );
646
405
 
647
- // Face scan upload - SECOND STEP with WiFi re-validation
406
+ // Face scan upload - SECOND STEP (simplified, no WiFi revalidation)
648
407
  const uploadFaceScan = useCallback(
649
408
  async (selfie) => {
650
409
  if (!validateApiUrl()) return;
@@ -655,25 +414,6 @@ const BiometricModal = forwardRef(({
655
414
  return;
656
415
  }
657
416
 
658
- // Optional: Re-validate WiFi fingerprint during face scan
659
- let wifiRevalidation = null;
660
- if (useWiFiFingerprinting && Platform.OS === 'android' && state.wifiReferenceScan) {
661
- const wifiResult = await performWiFiScan();
662
- if (wifiResult.scan.length > 0) {
663
- wifiRevalidation = {
664
- scan: wifiResult.scan,
665
- score: wifiResult.score,
666
- isMatch: wifiResult.isMatch,
667
- referenceScanLength: state.wifiReferenceScan.length,
668
- timestamp: new Date().toISOString()
669
- };
670
-
671
- if (!wifiResult.isMatch) {
672
- notifyMessage("Warning: WiFi environment changed since QR scan", "warning");
673
- }
674
- }
675
- }
676
-
677
417
  const currentData = dataRef.current;
678
418
 
679
419
  if (!currentData) {
@@ -729,7 +469,6 @@ const BiometricModal = forwardRef(({
729
469
  ...responseRef.current,
730
470
  ...response.data?.data || {},
731
471
  faceRecognition: response.data?.data || null,
732
- wifiRevalidation: wifiRevalidation,
733
472
  };
734
473
 
735
474
  updateState({
@@ -775,10 +514,7 @@ const BiometricModal = forwardRef(({
775
514
  safeCallback,
776
515
  handleProcessError,
777
516
  state.qrData,
778
- state.wifiReferenceScan,
779
517
  apiurl,
780
- useWiFiFingerprinting,
781
- performWiFiScan,
782
518
  ]
783
519
  );
784
520
 
@@ -877,9 +613,6 @@ const BiometricModal = forwardRef(({
877
613
  <View style={styles.titleContainer}>
878
614
  <Text style={styles.title}>Biometric Verification</Text>
879
615
  <Text style={styles.subtitle}>{state.currentStep}</Text>
880
- {useWiFiFingerprinting && Platform.OS === 'android' && (
881
- <Text style={styles.wifiIndicator}>WiFi Fingerprinting: Active</Text>
882
- )}
883
616
  </View>
884
617
  </View>
885
618
  )}