otpless-headless-rn 1.0.7 → 1.0.8
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/README.md
CHANGED
|
@@ -2,14 +2,227 @@
|
|
|
2
2
|
<img src="https://github.com/otpless-tech/Otpless-iOS-SDK/blob/main/otpless.svg" height="80"/>
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
# OTPLESS react native headless SDK
|
|
7
|
+
|
|
8
|
+
The new Authentication SDK offers significantly improved speed, reliability, and security, ensuring a seamless authentication and integration experience. We strongly recommend upgrading by removing the old SDK and following the steps below.
|
|
9
|
+
|
|
10
|
+
## Install OTPLESS SDK Dependency
|
|
11
|
+
|
|
6
12
|
[](https://badge.fury.io/js/otpless-headless-rn)
|
|
7
13
|
[](https://www.npmjs.com/package/otpless-headless-rn)
|
|
8
14
|
|
|
9
15
|
|
|
10
16
|
## Installation
|
|
17
|
+
Install the OTPLESS SDK dependency by running the following command in your terminal at the root of your React Native project:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
npm i otpless-headless-rn
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
# Configure Sign up/Sign in
|
|
24
|
+
|
|
25
|
+
### Import
|
|
26
|
+
|
|
27
|
+
```javascript
|
|
28
|
+
import { OtplessHeadlessModule } from 'otpless-headless-rn';
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
```javascript
|
|
33
|
+
const headlessModule = new OtplessHeadlessModule();
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
headlessModule.initialize("YOUR_APPID")
|
|
39
|
+
headlessModule.setResponseCallback(onHeadlessResult);
|
|
40
|
+
return () => {
|
|
41
|
+
headlessModule.clearListener();
|
|
42
|
+
headlessModule.cleanup();
|
|
43
|
+
};
|
|
44
|
+
}, []);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
# Initiate Authentication
|
|
48
|
+
|
|
49
|
+
## Phone Auth
|
|
50
|
+
|
|
51
|
+
### Request
|
|
52
|
+
```javascript
|
|
53
|
+
const startPhoneAuth = (phoneNumber: string, countryCode: string) => {
|
|
54
|
+
const request = {
|
|
55
|
+
phone: phoneNumber,
|
|
56
|
+
countryCode
|
|
57
|
+
};
|
|
58
|
+
headlessModule.start(request);
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Verify
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
const verifyPhoneOtp = (phoneNumber: string, countryCode: string, otp: string) => {
|
|
66
|
+
const request = {
|
|
67
|
+
phone: phoneNumber,
|
|
68
|
+
countryCode,
|
|
69
|
+
otp
|
|
70
|
+
};
|
|
71
|
+
headlessModule.start(request);
|
|
72
|
+
};
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
# Response Handling
|
|
76
|
+
|
|
77
|
+
```javascript
|
|
78
|
+
const onHeadlessResult = (result: any) => {
|
|
79
|
+
headlessModule.commitResponse(result);
|
|
80
|
+
const responseType = result.responseType;
|
|
81
|
+
|
|
82
|
+
switch (responseType) {
|
|
83
|
+
case "SDK_READY": {
|
|
84
|
+
// Notify that SDK is ready
|
|
85
|
+
console.log("SDK is ready");
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case "FAILED": {
|
|
89
|
+
console.log("SDK initialization failed");
|
|
90
|
+
// Handle SDK initialization failure
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case "INITIATE": {
|
|
94
|
+
// Notify that headless authentication has been initiated
|
|
95
|
+
if (result.statusCode == 200) {
|
|
96
|
+
console.log("Headless authentication initiated");
|
|
97
|
+
const authType = result.response.authType; // This is the authentication type
|
|
98
|
+
if (authType === "OTP") {
|
|
99
|
+
// Take user to OTP verification screen
|
|
100
|
+
} else if (authType === "SILENT_AUTH") {
|
|
101
|
+
// Handle Silent Authentication initiation by showing
|
|
102
|
+
// loading status for SNA flow.
|
|
103
|
+
}
|
|
104
|
+
} else {
|
|
105
|
+
// Handle initiation error.
|
|
106
|
+
// To handle initiation error response, please refer to the error handling section.
|
|
107
|
+
if (Platform.OS === 'ios') {
|
|
108
|
+
handleInitiateErrorIOS(result.response);
|
|
109
|
+
} else if (Platform.OS === 'android') {
|
|
110
|
+
handleInitiateErrorAndroid(result.response);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "OTP_AUTO_READ": {
|
|
116
|
+
// OTP_AUTO_READ is triggered only in Android devices for WhatsApp and SMS.
|
|
117
|
+
if (Platform.OS === "android") {
|
|
118
|
+
const otp = result.response.otp;
|
|
119
|
+
console.log(`OTP Received: ${otp}`);
|
|
120
|
+
}
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
case "VERIFY": {
|
|
124
|
+
// notify that verification has failed.
|
|
125
|
+
if (result.response.authType == "SILENT_AUTH") {
|
|
126
|
+
if (result.statusCode == 9106) {
|
|
127
|
+
// Silent Authentication and all fallback authentication methods in SmartAuth have failed.
|
|
128
|
+
// The transaction cannot proceed further.
|
|
129
|
+
// Handle the scenario to gracefully exit the authentication flow
|
|
130
|
+
} else {
|
|
131
|
+
// Silent Authentication failed.
|
|
132
|
+
// If SmartAuth is enabled, the INITIATE response
|
|
133
|
+
// will include the next available authentication method configured in the dashboard.
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
// To handle verification failed response, please refer to the error handling section.
|
|
137
|
+
if (Platform.OS === 'ios') {
|
|
138
|
+
handleVerifyErrorIOS(result.response);
|
|
139
|
+
} else if (Platform.OS === 'android') {
|
|
140
|
+
handleVerifyErrorAndroid(result.response);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case "DELIVERY_STATUS": {
|
|
147
|
+
// This function is called when delivery is successful for your authType.
|
|
148
|
+
const authType = result.response.authType;
|
|
149
|
+
// It is the authentication type (OTP, MAGICLINK, OTP_LINK) for which the delivery status is being sent
|
|
150
|
+
const deliveryChannel = result.response.deliveryChannel;
|
|
151
|
+
// It is the delivery channel (SMS, WHATSAPP, etc) on which the authType has been delivered
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
case "ONETAP": {
|
|
155
|
+
const token = result.response.token;
|
|
156
|
+
if (token != null) {
|
|
157
|
+
console.log(`OneTap Data: ${token}`);
|
|
158
|
+
// Process token and proceed.
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
case "FALLBACK_TRIGGERED": {
|
|
163
|
+
// A fallback occurs when an OTP delivery attempt on one channel fails,
|
|
164
|
+
// and the system automatically retries via the subsequent channel selected on Otpless Dashboard.
|
|
165
|
+
// For example, if a merchant opts for SmartAuth with primary channal as WhatsApp and secondary channel as SMS,
|
|
166
|
+
// in that case, if OTP delivery on WhatsApp fails, the system will automatically retry via SMS.
|
|
167
|
+
// The response will contain the deliveryChannel to which the OTP has been sent.
|
|
168
|
+
if (response.response.deliveryChannel != null) {
|
|
169
|
+
const newDeliveryChannel = response.response.deliveryChannel
|
|
170
|
+
// This is the deliveryChannel to which the OTP has been sent
|
|
171
|
+
}
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
default: {
|
|
175
|
+
console.warn(`Unknown response type: ${responseType}`);
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
};
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Android manifest update
|
|
184
|
+
Add Network Security Config inside your android/app/src/main/AndroidManifest.xml file into your <application> code block (Only required if you are using the SNA feature):
|
|
185
|
+
|
|
186
|
+
```xml
|
|
187
|
+
android:networkSecurityConfig="@xml/otpless_network_security_config"
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## Ios info.plist update
|
|
191
|
+
|
|
192
|
+
Add the following block to your info.plist file (Only required if you are using the SNA feature):
|
|
193
|
+
|
|
194
|
+
```xml
|
|
195
|
+
<dict>
|
|
196
|
+
<key>NSAllowsArbitraryLoads</key>
|
|
197
|
+
<true/>
|
|
198
|
+
<key>NSExceptionDomains</key>
|
|
199
|
+
<dict>
|
|
200
|
+
<key>80.in.safr.sekuramobile.com</key>
|
|
201
|
+
<dict>
|
|
202
|
+
<key>NSIncludesSubdomains</key>
|
|
203
|
+
<true/>
|
|
204
|
+
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
|
|
205
|
+
<true/>
|
|
206
|
+
<key>NSTemporaryExceptionMinimumTLSVersion</key>
|
|
207
|
+
<string>TLSv1.1</string>
|
|
208
|
+
</dict>
|
|
209
|
+
<key>partnerapi.jio.com</key>
|
|
210
|
+
<dict>
|
|
211
|
+
<key>NSIncludesSubdomains</key>
|
|
212
|
+
<true/>
|
|
213
|
+
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
|
|
214
|
+
<true/>
|
|
215
|
+
<key>NSTemporaryExceptionMinimumTLSVersion</key>
|
|
216
|
+
<string>TLSv1.1</string>
|
|
217
|
+
</dict>
|
|
218
|
+
</dict>
|
|
219
|
+
</dict>
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
</br></br></br>
|
|
223
|
+
# Note
|
|
11
224
|
|
|
12
|
-
|
|
225
|
+
For complete documentation and other login feature explore, follow the following guide here: [installation guide here](https://otpless.com/docs/frontend-sdks/app-sdks/react-native/new/headless/headless)
|
|
13
226
|
|
|
14
227
|
## Author
|
|
15
228
|
|
package/android/build.gradle
CHANGED
|
@@ -74,7 +74,7 @@ dependencies {
|
|
|
74
74
|
//noinspection GradleDynamicVersion
|
|
75
75
|
implementation "com.facebook.react:react-native:+"
|
|
76
76
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
77
|
-
implementation ("io.github.otpless-tech:otpless-headless-sdk:0.
|
|
77
|
+
implementation ("io.github.otpless-tech:otpless-headless-sdk:0.3.0")
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
if (isNewArchitectureEnabled()) {
|
|
@@ -160,7 +160,7 @@ internal fun parseTrueCallerRequest(requestMap: ReadableMap): OtplessTruecallerR
|
|
|
160
160
|
// parsing locale
|
|
161
161
|
val locale: Locale? = trueCallerRequestMap.getString("locale")?.let { str ->
|
|
162
162
|
try {
|
|
163
|
-
|
|
163
|
+
parseLocale(str)
|
|
164
164
|
} catch (ignore: Exception) {
|
|
165
165
|
null
|
|
166
166
|
}
|
|
@@ -204,3 +204,13 @@ internal fun debugLog(message: String) {
|
|
|
204
204
|
Log.d(LOGTAG, message)
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
|
+
|
|
208
|
+
// locale parsing language and country
|
|
209
|
+
internal fun parseLocale(str: String): Locale? {
|
|
210
|
+
val parts = str.split('-', '_')
|
|
211
|
+
return if (parts.size == 2) {
|
|
212
|
+
Locale(parts[0], parts[1])
|
|
213
|
+
} else {
|
|
214
|
+
null
|
|
215
|
+
}
|
|
216
|
+
}
|