react-native-biometric-verifier 0.0.55 → 0.0.57
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 +4 -16
- package/src/components/CaptureImageWithoutEdit.js +3 -4
- package/src/components/Loader.js +84 -96
- package/src/components/Notification.js +38 -14
- package/src/hooks/useFaceDetectionFrameProcessor.js +26 -26
- package/src/hooks/useGeolocation.js +46 -224
- package/src/index.js +430 -560
- package/src/utils/Global.js +0 -1
- package/src/hooks/useBluetoothService.js +0 -195
- package/src/hooks/useWifiService.js +0 -175
package/src/utils/Global.js
CHANGED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
import { useCallback, useState, useRef } from 'react';
|
|
2
|
-
import { Platform, PermissionsAndroid } from 'react-native';
|
|
3
|
-
import { BleManager } from 'react-native-ble-plx';
|
|
4
|
-
|
|
5
|
-
const manager = new BleManager();
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Bluetooth Service Hook for device scanning and distance estimation
|
|
9
|
-
*/
|
|
10
|
-
export const useBluetoothService = (notifyMessage) => {
|
|
11
|
-
const [nearbyDevices, setNearbyDevices] = useState([]);
|
|
12
|
-
const scanTimeoutRef = useRef(null);
|
|
13
|
-
|
|
14
|
-
/* -------------------------------------------------------------------------- */
|
|
15
|
-
/* BLUETOOTH PERMISSIONS */
|
|
16
|
-
/* -------------------------------------------------------------------------- */
|
|
17
|
-
const requestBluetoothPermissions = useCallback(async () => {
|
|
18
|
-
if (Platform.OS !== 'android') return true;
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
let permissions = [];
|
|
22
|
-
if (Platform.Version >= 31) {
|
|
23
|
-
permissions = [
|
|
24
|
-
PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
|
|
25
|
-
PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
|
|
26
|
-
PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
|
|
27
|
-
];
|
|
28
|
-
} else {
|
|
29
|
-
permissions = [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const granted = await PermissionsAndroid.requestMultiple(permissions);
|
|
33
|
-
const allGranted = Object.values(granted).every(
|
|
34
|
-
status => status === PermissionsAndroid.RESULTS.GRANTED
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
if (!allGranted) {
|
|
38
|
-
notifyMessage?.('Bluetooth permissions are required for device scanning', 'warning');
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return allGranted;
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.error('[Permissions] Error:', error);
|
|
44
|
-
notifyMessage?.('Failed to request Bluetooth permissions', 'error');
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}, [notifyMessage]);
|
|
48
|
-
|
|
49
|
-
/* -------------------------------------------------------------------------- */
|
|
50
|
-
/* DISTANCE ESTIMATION */
|
|
51
|
-
/* -------------------------------------------------------------------------- */
|
|
52
|
-
const estimateDistance = useCallback((rssi, txPower = -59) => {
|
|
53
|
-
if (!rssi || rssi >= 0) return -1;
|
|
54
|
-
|
|
55
|
-
const n = 2.0;
|
|
56
|
-
const distance1 = Math.pow(10, (txPower - rssi) / (10 * n));
|
|
57
|
-
const distance2 = 0.89976 * Math.pow(Math.abs(rssi), 0.80976) + 0.111;
|
|
58
|
-
const avgDistance = (distance1 + distance2) / 2;
|
|
59
|
-
|
|
60
|
-
return Math.max(0.1, avgDistance);
|
|
61
|
-
}, []);
|
|
62
|
-
|
|
63
|
-
/* -------------------------------------------------------------------------- */
|
|
64
|
-
/* FILTER STALE DEVICES */
|
|
65
|
-
/* -------------------------------------------------------------------------- */
|
|
66
|
-
const filterStaleDevices = useCallback(() => {
|
|
67
|
-
setNearbyDevices(prev =>
|
|
68
|
-
prev.filter(device => {
|
|
69
|
-
const isRecent = Date.now() - device.lastSeen < 10000; // 10 seconds
|
|
70
|
-
const hasMultipleReadings = device.count >= 3;
|
|
71
|
-
return isRecent && hasMultipleReadings;
|
|
72
|
-
})
|
|
73
|
-
);
|
|
74
|
-
}, []);
|
|
75
|
-
|
|
76
|
-
/* -------------------------------------------------------------------------- */
|
|
77
|
-
/* STOP SCAN */
|
|
78
|
-
/* -------------------------------------------------------------------------- */
|
|
79
|
-
const stopBluetoothScan = useCallback(() => {
|
|
80
|
-
manager.stopDeviceScan();
|
|
81
|
-
if (scanTimeoutRef.current) {
|
|
82
|
-
clearTimeout(scanTimeoutRef.current);
|
|
83
|
-
scanTimeoutRef.current = null;
|
|
84
|
-
}
|
|
85
|
-
}, []);
|
|
86
|
-
|
|
87
|
-
/* -------------------------------------------------------------------------- */
|
|
88
|
-
/* START BLE SCAN */
|
|
89
|
-
/* -------------------------------------------------------------------------- */
|
|
90
|
-
const startBluetoothScan = useCallback(async () => {
|
|
91
|
-
const permission = await requestBluetoothPermissions();
|
|
92
|
-
if (!permission) return;
|
|
93
|
-
|
|
94
|
-
setNearbyDevices([]);
|
|
95
|
-
|
|
96
|
-
const scanOptions = {
|
|
97
|
-
allowDuplicates: true,
|
|
98
|
-
scanMode: 2,
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
manager.startDeviceScan(null, scanOptions, (error, device) => {
|
|
102
|
-
if (error) {
|
|
103
|
-
console.error('[BLE] Scan error:', error);
|
|
104
|
-
stopBluetoothScan();
|
|
105
|
-
|
|
106
|
-
let errorMessage = 'Bluetooth scan failed';
|
|
107
|
-
if (error.errorCode === 102) errorMessage = 'Bluetooth is not enabled';
|
|
108
|
-
else if (error.errorCode === 103) errorMessage = 'Location services required for scanning';
|
|
109
|
-
|
|
110
|
-
notifyMessage?.(errorMessage, 'error');
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (device && device.name && device.rssi) {
|
|
115
|
-
const distance = estimateDistance(device.rssi);
|
|
116
|
-
|
|
117
|
-
if (distance > 0 && distance <= 20) {
|
|
118
|
-
setNearbyDevices(prev => {
|
|
119
|
-
const existingIndex = prev.findIndex(d => d.id === device.id);
|
|
120
|
-
if (existingIndex >= 0) {
|
|
121
|
-
const existing = prev[existingIndex];
|
|
122
|
-
const avgDistance = (parseFloat(existing.distance) + distance) / 2;
|
|
123
|
-
|
|
124
|
-
const updated = [...prev];
|
|
125
|
-
updated[existingIndex] = {
|
|
126
|
-
...existing,
|
|
127
|
-
rssi: device.rssi,
|
|
128
|
-
distance: avgDistance.toFixed(2),
|
|
129
|
-
lastSeen: Date.now(),
|
|
130
|
-
count: existing.count + 1,
|
|
131
|
-
txPowerLevel: device.txPowerLevel || existing.txPowerLevel,
|
|
132
|
-
};
|
|
133
|
-
return updated;
|
|
134
|
-
} else {
|
|
135
|
-
return [
|
|
136
|
-
...prev,
|
|
137
|
-
{
|
|
138
|
-
id: device.id,
|
|
139
|
-
name: device.name || 'Unknown Device',
|
|
140
|
-
rssi: device.rssi,
|
|
141
|
-
distance: distance.toFixed(2),
|
|
142
|
-
lastSeen: Date.now(),
|
|
143
|
-
count: 1,
|
|
144
|
-
manufacturerData: device.manufacturerData,
|
|
145
|
-
serviceUUIDs: device.serviceUUIDs,
|
|
146
|
-
txPowerLevel: device.txPowerLevel,
|
|
147
|
-
isConnectable: device.isConnectable,
|
|
148
|
-
},
|
|
149
|
-
];
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
scanTimeoutRef.current = setTimeout(() => {
|
|
157
|
-
stopBluetoothScan();
|
|
158
|
-
filterStaleDevices();
|
|
159
|
-
}, 10000);
|
|
160
|
-
}, [notifyMessage, requestBluetoothPermissions, stopBluetoothScan, filterStaleDevices, estimateDistance, nearbyDevices]);
|
|
161
|
-
|
|
162
|
-
/* -------------------------------------------------------------------------- */
|
|
163
|
-
/* DEVICE DETAILS */
|
|
164
|
-
/* -------------------------------------------------------------------------- */
|
|
165
|
-
const getDeviceDetails = useCallback(async (deviceId) => {
|
|
166
|
-
try {
|
|
167
|
-
const device = await manager.connectToDevice(deviceId);
|
|
168
|
-
await device.discoverAllServicesAndCharacteristics();
|
|
169
|
-
const services = await device.services();
|
|
170
|
-
|
|
171
|
-
return { ...device, services, isConnected: true };
|
|
172
|
-
} catch (error) {
|
|
173
|
-
console.error('[BLE] Error getting device details:', error);
|
|
174
|
-
return null;
|
|
175
|
-
}
|
|
176
|
-
}, []);
|
|
177
|
-
|
|
178
|
-
/* -------------------------------------------------------------------------- */
|
|
179
|
-
/* CLEAR DEVICES */
|
|
180
|
-
/* -------------------------------------------------------------------------- */
|
|
181
|
-
const clearDevices = useCallback(() => {
|
|
182
|
-
setNearbyDevices([]);
|
|
183
|
-
}, []);
|
|
184
|
-
|
|
185
|
-
return {
|
|
186
|
-
requestBluetoothPermission: requestBluetoothPermissions,
|
|
187
|
-
startBluetoothScan,
|
|
188
|
-
stopBluetoothScan,
|
|
189
|
-
nearbyDevices,
|
|
190
|
-
filterStaleDevices,
|
|
191
|
-
clearDevices,
|
|
192
|
-
getDeviceDetails,
|
|
193
|
-
estimateDistance,
|
|
194
|
-
};
|
|
195
|
-
};
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
import { Platform, PermissionsAndroid } from 'react-native';
|
|
3
|
-
import WifiManager from 'react-native-wifi-reborn';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* WiFi Service Hook for WiFi scanning and fingerprinting
|
|
7
|
-
*/
|
|
8
|
-
export const useWifiService = (notifyMessage) => {
|
|
9
|
-
|
|
10
|
-
/* -------------------------------------------------------------------------- */
|
|
11
|
-
/* WIFI PERMISSIONS */
|
|
12
|
-
/* -------------------------------------------------------------------------- */
|
|
13
|
-
const requestWifiPermissions = useCallback(async () => {
|
|
14
|
-
try {
|
|
15
|
-
if (Platform.OS !== 'android') return false;
|
|
16
|
-
|
|
17
|
-
const permissions = [PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION];
|
|
18
|
-
|
|
19
|
-
if (Platform.Version >= 31) {
|
|
20
|
-
permissions.push(PermissionsAndroid.PERMISSIONS.NEARBY_WIFI_DEVICES);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const result = await PermissionsAndroid.requestMultiple(permissions);
|
|
24
|
-
|
|
25
|
-
const granted = Object.values(result).every(
|
|
26
|
-
status => status === PermissionsAndroid.RESULTS.GRANTED
|
|
27
|
-
);
|
|
28
|
-
|
|
29
|
-
if (!granted) {
|
|
30
|
-
notifyMessage?.('WiFi scanning permissions missing', 'warning');
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return granted;
|
|
34
|
-
} catch (err) {
|
|
35
|
-
console.error('[WiFi Permissions] Error:', err);
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
}, [notifyMessage]);
|
|
39
|
-
|
|
40
|
-
/* -------------------------------------------------------------------------- */
|
|
41
|
-
/* WIFI SCANNING */
|
|
42
|
-
/* -------------------------------------------------------------------------- */
|
|
43
|
-
const scanWifiFingerprint = useCallback(async () => {
|
|
44
|
-
if (Platform.OS !== 'android') return [];
|
|
45
|
-
|
|
46
|
-
try {
|
|
47
|
-
const hasPermission = await requestWifiPermissions();
|
|
48
|
-
if (!hasPermission) return [];
|
|
49
|
-
|
|
50
|
-
const list = await WifiManager.loadWifiList();
|
|
51
|
-
|
|
52
|
-
const fingerprint = list.map(ap => ({
|
|
53
|
-
bssid: ap.BSSID,
|
|
54
|
-
ssid: ap.SSID || 'Unknown',
|
|
55
|
-
rssi: ap.level,
|
|
56
|
-
frequency: ap.frequency || 0,
|
|
57
|
-
capabilities: ap.capabilities || '',
|
|
58
|
-
timestamp: Date.now(),
|
|
59
|
-
}));
|
|
60
|
-
|
|
61
|
-
return fingerprint;
|
|
62
|
-
} catch (err) {
|
|
63
|
-
console.error('[WiFi] Scan failed:', err);
|
|
64
|
-
notifyMessage?.('WiFi scan failed', 'error');
|
|
65
|
-
return [];
|
|
66
|
-
}
|
|
67
|
-
}, [requestWifiPermissions, notifyMessage]);
|
|
68
|
-
|
|
69
|
-
/* -------------------------------------------------------------------------- */
|
|
70
|
-
/* WIFI FINGERPRINT MATCHING */
|
|
71
|
-
/* -------------------------------------------------------------------------- */
|
|
72
|
-
const matchWifiFingerprint = useCallback((scan, reference, options = {}) => {
|
|
73
|
-
const { rssiThreshold = 10, matchWeight = 1, partialMatchWeight = 0.5 } = options;
|
|
74
|
-
|
|
75
|
-
if (!scan || !reference || !Array.isArray(scan) || !Array.isArray(reference)) return 0;
|
|
76
|
-
|
|
77
|
-
let score = 0;
|
|
78
|
-
let matches = 0;
|
|
79
|
-
const totalPossibleMatches = Math.min(scan.length, reference.length);
|
|
80
|
-
|
|
81
|
-
scan.forEach(ap => {
|
|
82
|
-
const match = reference.find(r => r.bssid === ap.bssid);
|
|
83
|
-
if (match) {
|
|
84
|
-
const diff = Math.abs((match.rssi || 0) - ap.rssi);
|
|
85
|
-
score += diff <= rssiThreshold ? matchWeight : partialMatchWeight;
|
|
86
|
-
matches++;
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
const matchPercentage = totalPossibleMatches > 0 ? (matches / totalPossibleMatches) * 100 : 0;
|
|
91
|
-
|
|
92
|
-
return {
|
|
93
|
-
score,
|
|
94
|
-
matches,
|
|
95
|
-
totalPossibleMatches,
|
|
96
|
-
matchPercentage,
|
|
97
|
-
};
|
|
98
|
-
}, []);
|
|
99
|
-
|
|
100
|
-
/* -------------------------------------------------------------------------- */
|
|
101
|
-
/* WIFI UTILITIES */
|
|
102
|
-
/* -------------------------------------------------------------------------- */
|
|
103
|
-
const getWifiNetworksByStrength = useCallback((networks, limit = 5) => {
|
|
104
|
-
if (!Array.isArray(networks)) return [];
|
|
105
|
-
return networks
|
|
106
|
-
.filter(network => network && typeof network.rssi === 'number')
|
|
107
|
-
.sort((a, b) => b.rssi - a.rssi)
|
|
108
|
-
.slice(0, limit);
|
|
109
|
-
}, []);
|
|
110
|
-
|
|
111
|
-
const filterWifiNetworks = useCallback((networks, options = {}) => {
|
|
112
|
-
const { minRssi = -90, maxRssi = -30, excludeHidden = true } = options;
|
|
113
|
-
if (!Array.isArray(networks)) return [];
|
|
114
|
-
|
|
115
|
-
return networks.filter(network => {
|
|
116
|
-
if (!network || !network.bssid) return false;
|
|
117
|
-
if (network.rssi < minRssi || network.rssi > maxRssi) return false;
|
|
118
|
-
if (excludeHidden && (!network.ssid || network.ssid === '' || network.ssid === '<unknown ssid>')) return false;
|
|
119
|
-
return true;
|
|
120
|
-
});
|
|
121
|
-
}, []);
|
|
122
|
-
|
|
123
|
-
const getCurrentWifiInfo = useCallback(async () => {
|
|
124
|
-
if (Platform.OS !== 'android') return null;
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
const hasPermission = await requestWifiPermissions();
|
|
128
|
-
if (!hasPermission) return null;
|
|
129
|
-
|
|
130
|
-
const currentWifi = await WifiManager.getCurrentWifiSSID();
|
|
131
|
-
return { ssid: currentWifi, timestamp: Date.now() };
|
|
132
|
-
} catch (err) {
|
|
133
|
-
console.error('[WiFi] Failed to get current WiFi:', err);
|
|
134
|
-
return null;
|
|
135
|
-
}
|
|
136
|
-
}, [requestWifiPermissions]);
|
|
137
|
-
|
|
138
|
-
/* -------------------------------------------------------------------------- */
|
|
139
|
-
/* COMBINED LOCATION SCAN */
|
|
140
|
-
/* -------------------------------------------------------------------------- */
|
|
141
|
-
const getLocationWithWifi = useCallback(async (geolocationHook) => {
|
|
142
|
-
try {
|
|
143
|
-
const wifiPromise = scanWifiFingerprint();
|
|
144
|
-
|
|
145
|
-
let locationResult;
|
|
146
|
-
try {
|
|
147
|
-
locationResult = await geolocationHook.getCurrentLocation();
|
|
148
|
-
} catch {
|
|
149
|
-
locationResult = null; // continue with WiFi only
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const wifiFingerprint = await wifiPromise;
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
...(locationResult || {}),
|
|
156
|
-
wifi: wifiFingerprint,
|
|
157
|
-
timestamp: Date.now(),
|
|
158
|
-
source: locationResult ? 'gps+wifi' : 'wifi-only',
|
|
159
|
-
};
|
|
160
|
-
} catch (err) {
|
|
161
|
-
console.error('[WiFi+Location] Combined scan failed:', err);
|
|
162
|
-
throw err;
|
|
163
|
-
}
|
|
164
|
-
}, [scanWifiFingerprint]);
|
|
165
|
-
|
|
166
|
-
return {
|
|
167
|
-
requestWifiPermissions,
|
|
168
|
-
scanWifiFingerprint,
|
|
169
|
-
getCurrentWifiInfo,
|
|
170
|
-
matchWifiFingerprint,
|
|
171
|
-
getWifiNetworksByStrength,
|
|
172
|
-
filterWifiNetworks,
|
|
173
|
-
getLocationWithWifi,
|
|
174
|
-
};
|
|
175
|
-
};
|