react-native-otp-auto-verify 0.1.5 → 0.1.7
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/LICENSE +1 -0
- package/README.md +56 -8
- package/lib/module/index.js +16 -7
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +3 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +26 -6
- package/src/index.tsx +17 -8
package/LICENSE
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
3
|
Copyright (c) 2026 Kailas Rathod
|
|
4
|
+
|
|
4
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
6
7
|
in the Software without restriction, including without limitation the rights
|
package/README.md
CHANGED
|
@@ -12,6 +12,8 @@ Supports both RN Old Architecture and React Native **New Architecture** (TurboMo
|
|
|
12
12
|
**Android**: automatic OTP detection.
|
|
13
13
|
**iOS**: auto-OTP is not supported—use manual OTP entry as fallback.
|
|
14
14
|
|
|
15
|
+
**Connect:** [GitHub](https://github.com/kailas-rathod/react-native-otp-auto-verify) · [npm](https://www.npmjs.com/package/react-native-otp-auto-verify) · [Issues](https://github.com/kailas-rathod/react-native-otp-auto-verify/issues) · [License](https://github.com/kailas-rathod/react-native-otp-auto-verify/blob/main/LICENSE)
|
|
16
|
+
|
|
15
17
|
---
|
|
16
18
|
<img width="1536" height="1024" alt="otp" src="https://github.com/user-attachments/assets/e4908e99-e7d1-4a96-a6d2-b92c50090db0" />
|
|
17
19
|
|
|
@@ -26,11 +28,12 @@ Supports both RN Old Architecture and React Native **New Architecture** (TurboMo
|
|
|
26
28
|
- ✅ **New Architecture ready**: TurboModule implementation; works with Old Architecture too
|
|
27
29
|
---
|
|
28
30
|
|
|
29
|
-
## Platform
|
|
31
|
+
## Platform Support
|
|
30
32
|
|
|
31
|
-
| Platform | Support | Notes
|
|
32
|
-
|
|
33
|
-
| Android | ✅
|
|
33
|
+
| Platform | Support | Notes |
|
|
34
|
+
|----------|----------|-------|
|
|
35
|
+
| Android | ✅ | Requires Google Play Services on device |
|
|
36
|
+
| iOS | ✅ Native Only | Uses iOS Security Code AutoFill (manual tap required) |
|
|
34
37
|
|
|
35
38
|
## Requirements
|
|
36
39
|
|
|
@@ -77,7 +80,7 @@ Recommended format:
|
|
|
77
80
|
Dear Kailas Rathod, 321500 is your OTP for mobile authentication. This OTP is valid for the next 15 minutes. Please DO NOT share it with anyone.
|
|
78
81
|
uW87Uq6teXc
|
|
79
82
|
```
|
|
80
|
-
|
|
83
|
+
Note: You do not need `<#>` at the start of the message.
|
|
81
84
|
|
|
82
85
|
### 3) Hook usage (recommended)
|
|
83
86
|
|
|
@@ -89,7 +92,7 @@ import { Text, View } from 'react-native';
|
|
|
89
92
|
import { useOtpVerification } from 'react-native-otp-auto-verify';
|
|
90
93
|
|
|
91
94
|
export function OtpScreen() {
|
|
92
|
-
const { hashCode, otp, timeoutError, startListening, stopListening } =
|
|
95
|
+
const { hashCode, otp, timeoutError, error, startListening, stopListening } =
|
|
93
96
|
useOtpVerification({ numberOfDigits: 6 });
|
|
94
97
|
|
|
95
98
|
React.useEffect(() => {
|
|
@@ -102,6 +105,7 @@ export function OtpScreen() {
|
|
|
102
105
|
{!!hashCode && <Text>Hash: {hashCode}</Text>}
|
|
103
106
|
{!!otp && <Text>OTP: {otp}</Text>}
|
|
104
107
|
{timeoutError && <Text>Timeout. Tap resend and try again.</Text>}
|
|
108
|
+
{!!error && <Text>Error: {error.message}</Text>}
|
|
105
109
|
</View>
|
|
106
110
|
);
|
|
107
111
|
}
|
|
@@ -130,6 +134,46 @@ sub.remove();
|
|
|
130
134
|
removeListener();
|
|
131
135
|
```
|
|
132
136
|
|
|
137
|
+
# iOS OTP AutoFill (Native)
|
|
138
|
+
|
|
139
|
+
iOS does **not** allow third-party libraries to read SMS messages.
|
|
140
|
+
|
|
141
|
+
Automatic SMS reading is restricted by Apple for privacy and security reasons.
|
|
142
|
+
Instead, iOS provides a native feature called **Security Code AutoFill**, which suggests the OTP above the keyboard when properly configured.
|
|
143
|
+
|
|
144
|
+
This library does **not** auto-read OTP on iOS.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## How iOS OTP AutoFill Works
|
|
149
|
+
|
|
150
|
+
1. User receives an SMS containing an OTP.
|
|
151
|
+
2. iOS detects the code.
|
|
152
|
+
3. The OTP appears above the keyboard.
|
|
153
|
+
4. User taps the suggestion.
|
|
154
|
+
5. The code fills automatically into the input field.
|
|
155
|
+
|
|
156
|
+
No SMS permissions required.
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## React Native Setup
|
|
161
|
+
|
|
162
|
+
Use the following configuration in your OTP input field:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
<TextInput
|
|
166
|
+
style={styles.input}
|
|
167
|
+
keyboardType="number-pad"
|
|
168
|
+
textContentType="oneTimeCode"
|
|
169
|
+
autoComplete="sms-otp"
|
|
170
|
+
importantForAutofill="yes"
|
|
171
|
+
maxLength={6}
|
|
172
|
+
/>
|
|
173
|
+
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
|
|
133
177
|
## react-native-otp-auto-verify Architecture Flow
|
|
134
178
|
<img width="1536" height="1024" alt="react-native-otp-auto-verify Architecture Flow" src="https://github.com/user-attachments/assets/11582523-81cb-4904-9de0-56af05b3a3b4" />
|
|
135
179
|
|
|
@@ -149,6 +193,7 @@ Use this on your OTP screen. It manages:
|
|
|
149
193
|
| `otp` | `string \| null` | `null` | Extracted OTP |
|
|
150
194
|
| `sms` | `string \| null` | `null` | Full SMS text |
|
|
151
195
|
| `timeoutError` | `boolean` | `false` | Timeout occurred |
|
|
196
|
+
| `error` | `Error \| null` | `null` | Set when getHash or startListening fails |
|
|
152
197
|
| `startListening` | `() => Promise<void>` | — | Start listening |
|
|
153
198
|
| `stopListening` | `() => void` | — | Stop listening |
|
|
154
199
|
|
|
@@ -243,10 +288,13 @@ See [`./example`](./example).
|
|
|
243
288
|
|
|
244
289
|
See [`CONTRIBUTING.md`](CONTRIBUTING.md).
|
|
245
290
|
|
|
291
|
+
## Publishing
|
|
292
|
+
|
|
293
|
+
Maintainers: see [RELEASE_CHECKLIST.md](./RELEASE_CHECKLIST.md) before publishing a new version to npm.
|
|
246
294
|
|
|
247
|
-
##
|
|
295
|
+
## Keywords
|
|
248
296
|
react native otp auto verify, react native sms retriever api, automatic otp detection android, react native otp autofill, sms retriever react native, otp verification library react native, google play compliant otp library
|
|
249
297
|
|
|
250
298
|
## License
|
|
251
299
|
|
|
252
|
-
MIT
|
|
300
|
+
[MIT](./LICENSE) — see [LICENSE](./LICENSE) in the repo.
|
package/lib/module/index.js
CHANGED
|
@@ -18,7 +18,9 @@ const OTP_REGEX = {
|
|
|
18
18
|
/** Extracts a numeric OTP of 4–6 digits from SMS text. */
|
|
19
19
|
export function extractOtp(sms, numberOfDigits = DEFAULT_DIGITS) {
|
|
20
20
|
if (!sms || typeof sms !== 'string') return null;
|
|
21
|
-
const
|
|
21
|
+
const trimmed = sms.trim();
|
|
22
|
+
if (!trimmed) return null;
|
|
23
|
+
const match = trimmed.match(OTP_REGEX[numberOfDigits]);
|
|
22
24
|
return match ? match[1] : null;
|
|
23
25
|
}
|
|
24
26
|
|
|
@@ -55,13 +57,14 @@ export function removeListener() {
|
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
59
|
|
|
58
|
-
/** Hook for OTP verification.
|
|
60
|
+
/** Hook for OTP verification. Call startListening() to begin; listener is stopped on unmount. */
|
|
59
61
|
export function useOtpVerification(options = {}) {
|
|
60
62
|
const numberOfDigits = options.numberOfDigits ?? DEFAULT_DIGITS;
|
|
61
63
|
const [hashCode, setHashCode] = React.useState('');
|
|
62
64
|
const [otp, setOtp] = React.useState(null);
|
|
63
65
|
const [sms, setSms] = React.useState(null);
|
|
64
66
|
const [timeoutError, setTimeoutError] = React.useState(false);
|
|
67
|
+
const [error, setError] = React.useState(null);
|
|
65
68
|
const subscriptionRef = React.useRef(null);
|
|
66
69
|
const stopListening = React.useCallback(() => {
|
|
67
70
|
subscriptionRef.current?.remove();
|
|
@@ -73,11 +76,12 @@ export function useOtpVerification(options = {}) {
|
|
|
73
76
|
setOtp(null);
|
|
74
77
|
setSms(null);
|
|
75
78
|
setTimeoutError(false);
|
|
79
|
+
setError(null);
|
|
76
80
|
try {
|
|
77
81
|
const hashes = await getHash();
|
|
78
82
|
setHashCode(hashes[0] ?? '');
|
|
79
|
-
} catch {
|
|
80
|
-
|
|
83
|
+
} catch (err) {
|
|
84
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
81
85
|
}
|
|
82
86
|
try {
|
|
83
87
|
const sub = await activateOtpListener((smsText, extractedOtp) => {
|
|
@@ -91,9 +95,13 @@ export function useOtpVerification(options = {}) {
|
|
|
91
95
|
numberOfDigits
|
|
92
96
|
});
|
|
93
97
|
subscriptionRef.current = sub;
|
|
94
|
-
} catch {
|
|
98
|
+
} catch (err) {
|
|
95
99
|
subscriptionRef.current = null;
|
|
96
|
-
|
|
100
|
+
const wrapped = new Error('Failed to start OTP listener', {
|
|
101
|
+
cause: err
|
|
102
|
+
});
|
|
103
|
+
setError(wrapped);
|
|
104
|
+
throw wrapped;
|
|
97
105
|
}
|
|
98
106
|
}, [numberOfDigits]);
|
|
99
107
|
React.useEffect(() => () => stopListening(), [stopListening]);
|
|
@@ -102,9 +110,10 @@ export function useOtpVerification(options = {}) {
|
|
|
102
110
|
otp,
|
|
103
111
|
sms,
|
|
104
112
|
timeoutError,
|
|
113
|
+
error,
|
|
105
114
|
startListening,
|
|
106
115
|
stopListening
|
|
107
|
-
}), [hashCode, otp, sms, timeoutError, startListening, stopListening]);
|
|
116
|
+
}), [hashCode, otp, sms, timeoutError, error, startListening, stopListening]);
|
|
108
117
|
}
|
|
109
118
|
export { OTP_RECEIVED_EVENT };
|
|
110
119
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["React","NativeEventEmitter","NativeModules","Platform","NativeOtpAutoVerify","OtpAutoVerify","eventEmitter","OS","OTP_RECEIVED_EVENT","getConstants","TIMEOUT_MESSAGE","DEFAULT_DIGITS","OTP_REGEX","extractOtp","sms","numberOfDigits","match","getHash","arr","Array","from","activateOtpListener","handler","options","Error","subscription","addListener","args","smsText","String","startSmsRetriever","remove","removeListeners","removeListener","useOtpVerification","hashCode","setHashCode","useState","otp","setOtp","setSms","timeoutError","setTimeoutError","subscriptionRef","useRef","stopListening","useCallback","current","startListening","hashes","sub","extractedOtp","useEffect","useMemo"],"sourceRoot":"..\\..\\src","sources":["index.tsx"],"mappings":";;AAAA,OAAO,KAAKA,KAAK,MAAM,OAAO;AAC9B,SAASC,kBAAkB,EAAEC,aAAa,EAAEC,QAAQ,QAAQ,cAAc;AAC1E,OAAOC,mBAAmB,MAAM,uBAAuB;AAEvD,MAAM;EAAEC;AAAc,CAAC,GAAGH,aAAa;AACvC,MAAMI,YAAY,GAChBH,QAAQ,CAACI,EAAE,KAAK,SAAS,IAAIF,aAAa,GACtC,IAAIJ,kBAAkB,CAACI,aAAa,CAAC,GACrC,IAAI;AAEV,MAAMG,kBAAkB,GACrBJ,mBAAmB,CAACK,YAAY,GAAG,CAAC,EAAED,kBAAkB,IACzD,aAAa;AAEf,MAAME,eAAe,GAAG,gBAAgB;AACxC,MAAMC,cAAc,GAAG,CAAC;AAIxB,MAAMC,SAAoC,GAAG;EAC3C,CAAC,EAAE,aAAa;EAChB,CAAC,EAAE,aAAa;EAChB,CAAC,EAAE;AACL,CAAC;
|
|
1
|
+
{"version":3,"names":["React","NativeEventEmitter","NativeModules","Platform","NativeOtpAutoVerify","OtpAutoVerify","eventEmitter","OS","OTP_RECEIVED_EVENT","getConstants","TIMEOUT_MESSAGE","DEFAULT_DIGITS","OTP_REGEX","extractOtp","sms","numberOfDigits","trimmed","trim","match","getHash","arr","Array","from","activateOtpListener","handler","options","Error","subscription","addListener","args","smsText","String","startSmsRetriever","remove","removeListeners","removeListener","useOtpVerification","hashCode","setHashCode","useState","otp","setOtp","setSms","timeoutError","setTimeoutError","error","setError","subscriptionRef","useRef","stopListening","useCallback","current","startListening","hashes","err","sub","extractedOtp","wrapped","cause","useEffect","useMemo"],"sourceRoot":"..\\..\\src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -13,6 +13,8 @@ export interface UseOtpVerificationResult {
|
|
|
13
13
|
sms: string | null;
|
|
14
14
|
/** True when the 5-minute SMS Retriever timeout occurred. */
|
|
15
15
|
timeoutError: boolean;
|
|
16
|
+
/** Set when getHash fails (non-fatal) or when startListening fails. Cleared when startListening is called again. */
|
|
17
|
+
error: Error | null;
|
|
16
18
|
/** Start listening for OTP again (e.g. after timeout or error). */
|
|
17
19
|
startListening: () => Promise<void>;
|
|
18
20
|
/** Stop listening and clean up. Call on unmount. */
|
|
@@ -31,7 +33,7 @@ export declare function activateOtpListener(handler: (sms: string, extractedOtp?
|
|
|
31
33
|
}): Promise<OtpListenerSubscription>;
|
|
32
34
|
/** Stops SMS listening and removes all listeners. */
|
|
33
35
|
export declare function removeListener(): void;
|
|
34
|
-
/** Hook for OTP verification.
|
|
36
|
+
/** Hook for OTP verification. Call startListening() to begin; listener is stopped on unmount. */
|
|
35
37
|
export declare function useOtpVerification(options?: UseOtpVerificationOptions): UseOtpVerificationResult;
|
|
36
38
|
export { OTP_RECEIVED_EVENT };
|
|
37
39
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAUA,QAAA,MAAM,kBAAkB,QAET,CAAC;AAKhB,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAQlC,MAAM,WAAW,yBAAyB;IACxC,uFAAuF;IACvF,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,mCAAmC;IACnC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,6DAA6D;IAC7D,YAAY,EAAE,OAAO,CAAC;IACtB,mEAAmE;IACnE,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,oDAAoD;IACpD,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,cAAc,GAAE,SAA0B,GACzC,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAUA,QAAA,MAAM,kBAAkB,QAET,CAAC;AAKhB,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAQlC,MAAM,WAAW,yBAAyB;IACxC,uFAAuF;IACvF,cAAc,CAAC,EAAE,SAAS,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,oFAAoF;IACpF,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,mCAAmC;IACnC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,6DAA6D;IAC7D,YAAY,EAAE,OAAO,CAAC;IACtB,oHAAoH;IACpH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,mEAAmE;IACnE,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,oDAAoD;IACpD,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAED,0DAA0D;AAC1D,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,cAAc,GAAE,SAA0B,GACzC,MAAM,GAAG,IAAI,CAMf;AAED,kFAAkF;AAClF,wBAAsB,OAAO,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAIjD;AAED,6FAA6F;AAC7F,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,EAC5D,OAAO,CAAC,EAAE;IAAE,cAAc,CAAC,EAAE,SAAS,CAAA;CAAE,GACvC,OAAO,CAAC,uBAAuB,CAAC,CAqBlC;AAED,qDAAqD;AACrD,wBAAgB,cAAc,IAAI,IAAI,CAIrC;AAED,iGAAiG;AACjG,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,yBAA8B,GACtC,wBAAwB,CA8D1B;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-otp-auto-verify",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"description": "react-native-otp-auto-verify is a React Native library for automatic OTP verification on Android and iOS. It uses the Google SMS Retriever API to detect OTP codes automatically without requiring the READ_SMS permission. The library is fully Play Store compliant, improves user login experience, supports TurboModule, and works with the React Native New Architecture",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -35,9 +35,6 @@
|
|
|
35
35
|
"type": "commonjs",
|
|
36
36
|
"main": "./lib/module/index.js",
|
|
37
37
|
"types": "./lib/typescript/src/index.d.ts",
|
|
38
|
-
"directories": {
|
|
39
|
-
"example": "example"
|
|
40
|
-
},
|
|
41
38
|
"files": [
|
|
42
39
|
"src",
|
|
43
40
|
"lib",
|
|
@@ -58,11 +55,11 @@
|
|
|
58
55
|
"!**/.*"
|
|
59
56
|
],
|
|
60
57
|
"scripts": {
|
|
61
|
-
"clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
|
|
62
58
|
"prepare": "bob build",
|
|
63
59
|
"typecheck": "tsc",
|
|
64
60
|
"lint": "eslint \"**/*.{js,ts,tsx}\"",
|
|
65
61
|
"test": "jest",
|
|
62
|
+
"check": "yarn typecheck && yarn lint && yarn test",
|
|
66
63
|
"release": "release-it --only-version"
|
|
67
64
|
},
|
|
68
65
|
"devDependencies": {
|
|
@@ -71,7 +68,7 @@
|
|
|
71
68
|
"@eslint/eslintrc": "^3.3.1",
|
|
72
69
|
"@eslint/js": "^9.35.0",
|
|
73
70
|
"@react-native/babel-preset": "0.83.0",
|
|
74
|
-
"@react-native/eslint-config": "^
|
|
71
|
+
"@react-native-community/eslint-config": "^3.2.0",
|
|
75
72
|
"@release-it/conventional-changelog": "^10.0.1",
|
|
76
73
|
"@types/jest": "^29.5.14",
|
|
77
74
|
"@types/react": "^19.2.0",
|
|
@@ -95,6 +92,29 @@
|
|
|
95
92
|
"publishConfig": {
|
|
96
93
|
"registry": "https://registry.npmjs.org/"
|
|
97
94
|
},
|
|
95
|
+
"eslintConfig": {
|
|
96
|
+
"root": true,
|
|
97
|
+
"extends": [
|
|
98
|
+
"@react-native-community",
|
|
99
|
+
"prettier"
|
|
100
|
+
],
|
|
101
|
+
"rules": {
|
|
102
|
+
"prettier/prettier": [
|
|
103
|
+
"error",
|
|
104
|
+
{
|
|
105
|
+
"quoteProps": "consistent",
|
|
106
|
+
"singleQuote": true,
|
|
107
|
+
"tabWidth": 2,
|
|
108
|
+
"trailingComma": "es5",
|
|
109
|
+
"useTabs": false
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"eslintIgnore": [
|
|
115
|
+
"node_modules/",
|
|
116
|
+
"lib/"
|
|
117
|
+
],
|
|
98
118
|
"packageManager": "yarn@4.11.0",
|
|
99
119
|
"react-native-builder-bob": {
|
|
100
120
|
"source": "src",
|
package/src/index.tsx
CHANGED
|
@@ -37,6 +37,8 @@ export interface UseOtpVerificationResult {
|
|
|
37
37
|
sms: string | null;
|
|
38
38
|
/** True when the 5-minute SMS Retriever timeout occurred. */
|
|
39
39
|
timeoutError: boolean;
|
|
40
|
+
/** Set when getHash fails (non-fatal) or when startListening fails. Cleared when startListening is called again. */
|
|
41
|
+
error: Error | null;
|
|
40
42
|
/** Start listening for OTP again (e.g. after timeout or error). */
|
|
41
43
|
startListening: () => Promise<void>;
|
|
42
44
|
/** Stop listening and clean up. Call on unmount. */
|
|
@@ -53,7 +55,9 @@ export function extractOtp(
|
|
|
53
55
|
numberOfDigits: OtpDigits = DEFAULT_DIGITS
|
|
54
56
|
): string | null {
|
|
55
57
|
if (!sms || typeof sms !== 'string') return null;
|
|
56
|
-
const
|
|
58
|
+
const trimmed = sms.trim();
|
|
59
|
+
if (!trimmed) return null;
|
|
60
|
+
const match = trimmed.match(OTP_REGEX[numberOfDigits]);
|
|
57
61
|
return match ? match[1]! : null;
|
|
58
62
|
}
|
|
59
63
|
|
|
@@ -98,7 +102,7 @@ export function removeListener(): void {
|
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
/** Hook for OTP verification.
|
|
105
|
+
/** Hook for OTP verification. Call startListening() to begin; listener is stopped on unmount. */
|
|
102
106
|
export function useOtpVerification(
|
|
103
107
|
options: UseOtpVerificationOptions = {}
|
|
104
108
|
): UseOtpVerificationResult {
|
|
@@ -107,6 +111,7 @@ export function useOtpVerification(
|
|
|
107
111
|
const [otp, setOtp] = React.useState<string | null>(null);
|
|
108
112
|
const [sms, setSms] = React.useState<string | null>(null);
|
|
109
113
|
const [timeoutError, setTimeoutError] = React.useState(false);
|
|
114
|
+
const [error, setError] = React.useState<Error | null>(null);
|
|
110
115
|
const subscriptionRef = React.useRef<OtpListenerSubscription | null>(null);
|
|
111
116
|
|
|
112
117
|
const stopListening = React.useCallback(() => {
|
|
@@ -120,15 +125,16 @@ export function useOtpVerification(
|
|
|
120
125
|
setOtp(null);
|
|
121
126
|
setSms(null);
|
|
122
127
|
setTimeoutError(false);
|
|
128
|
+
setError(null);
|
|
123
129
|
try {
|
|
124
130
|
const hashes = await getHash();
|
|
125
131
|
setHashCode(hashes[0] ?? '');
|
|
126
|
-
} catch {
|
|
127
|
-
|
|
132
|
+
} catch (err) {
|
|
133
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
128
134
|
}
|
|
129
135
|
try {
|
|
130
136
|
const sub = await activateOtpListener(
|
|
131
|
-
(smsText
|
|
137
|
+
(smsText, extractedOtp) => {
|
|
132
138
|
setSms(smsText);
|
|
133
139
|
if (smsText === TIMEOUT_MESSAGE) {
|
|
134
140
|
setTimeoutError(true);
|
|
@@ -139,9 +145,11 @@ export function useOtpVerification(
|
|
|
139
145
|
{ numberOfDigits }
|
|
140
146
|
);
|
|
141
147
|
subscriptionRef.current = sub;
|
|
142
|
-
} catch {
|
|
148
|
+
} catch (err) {
|
|
143
149
|
subscriptionRef.current = null;
|
|
144
|
-
|
|
150
|
+
const wrapped = new Error('Failed to start OTP listener', { cause: err });
|
|
151
|
+
setError(wrapped);
|
|
152
|
+
throw wrapped;
|
|
145
153
|
}
|
|
146
154
|
}, [numberOfDigits]);
|
|
147
155
|
|
|
@@ -153,10 +161,11 @@ export function useOtpVerification(
|
|
|
153
161
|
otp,
|
|
154
162
|
sms,
|
|
155
163
|
timeoutError,
|
|
164
|
+
error,
|
|
156
165
|
startListening,
|
|
157
166
|
stopListening,
|
|
158
167
|
}),
|
|
159
|
-
[hashCode, otp, sms, timeoutError, startListening, stopListening]
|
|
168
|
+
[hashCode, otp, sms, timeoutError, error, startListening, stopListening]
|
|
160
169
|
);
|
|
161
170
|
}
|
|
162
171
|
|