otpless-headless-rn 2.2.0 → 2.3.0

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.
@@ -8,7 +8,7 @@ buildscript {
8
8
  }
9
9
 
10
10
  dependencies {
11
- classpath "com.android.tools.build:gradle:8.3.0"
11
+ classpath "com.android.tools.build:gradle:8.10.0"
12
12
  // noinspection DifferentKotlinGradleVersion
13
13
  classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
14
14
  }
@@ -37,7 +37,7 @@ def getExtOrIntegerDefault(name) {
37
37
  }
38
38
 
39
39
  android {
40
- compileSdk 35
40
+ compileSdk 36
41
41
  namespace "com.otplessheadlessrn"
42
42
  defaultConfig {
43
43
  minSdkVersion 21
@@ -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.8.1")
77
+ implementation ("io.github.otpless-tech:otpless-headless-sdk:0.9.0")
78
78
  }
79
79
 
80
80
  if (isNewArchitectureEnabled()) {
@@ -1,5 +1,5 @@
1
- OtplessHeadlessRN_kotlinVersion=1.9.25
1
+ OtplessHeadlessRN_kotlinVersion=2.0.21
2
2
  OtplessHeadlessRN_minSdkVersion=24
3
3
  OtplessHeadlessRN_targetSdkVersion=35
4
- OtplessHeadlessRN_compileSdkVersion=35
4
+ OtplessHeadlessRN_compileSdkVersion=36
5
5
  OtplessHeadlessRN_ndkversion=21.4.7075529
@@ -2,30 +2,27 @@ package com.otplessheadlessrn
2
2
 
3
3
  import android.app.Activity
4
4
  import android.content.Intent
5
- import androidx.appcompat.app.AppCompatActivity
5
+ import android.util.Log
6
6
  import androidx.fragment.app.FragmentActivity
7
- import androidx.lifecycle.lifecycleScope
8
7
  import com.facebook.react.bridge.ActivityEventListener
9
8
  import com.facebook.react.bridge.Promise
10
9
  import com.facebook.react.bridge.ReactApplicationContext
11
10
  import com.facebook.react.bridge.ReactContextBaseJavaModule
12
11
  import com.facebook.react.bridge.ReactMethod
13
12
  import com.facebook.react.bridge.ReadableMap
14
- import com.facebook.react.bridge.ReadableType
15
13
  import com.facebook.react.modules.core.DeviceEventManagerModule
16
14
  import com.otpless.longclaw.tc.OTScopeRequest
17
- import com.otpless.v2.android.sdk.dto.AuthEvent
18
- import com.otpless.v2.android.sdk.dto.OtplessChannelType
19
- import com.otpless.v2.android.sdk.dto.ProviderType
20
- import com.otpless.v2.android.sdk.dto.OtplessRequest
21
15
  import com.otpless.v2.android.sdk.dto.OtplessResponse
22
- import com.otpless.v2.android.sdk.dto.ResponseTypes
23
16
  import com.otpless.v2.android.sdk.main.OtplessSDK
24
17
  import com.otpless.v2.android.sdk.utils.OtplessUtils
18
+ import kotlinx.coroutines.CoroutineExceptionHandler
25
19
  import kotlinx.coroutines.CoroutineScope
26
20
  import kotlinx.coroutines.Dispatchers
27
21
  import kotlinx.coroutines.Job
22
+ import kotlinx.coroutines.SupervisorJob
28
23
  import kotlinx.coroutines.launch
24
+ import kotlinx.coroutines.sync.Mutex
25
+ import kotlinx.coroutines.sync.withLock
29
26
  import org.json.JSONException
30
27
  import org.json.JSONObject
31
28
 
@@ -33,6 +30,10 @@ class OtplessHeadlessRNModule(private val reactContext: ReactApplicationContext)
33
30
  ReactContextBaseJavaModule(reactContext), ActivityEventListener {
34
31
 
35
32
  private var otplessJob: Job? = null
33
+ private val lifecycleMutex = Mutex()
34
+ private val ioScope = CoroutineScope(Dispatchers.IO + SupervisorJob() + CoroutineExceptionHandler { context, throwable ->
35
+ Log.d("OTPLESS", "Error in coroutine", throwable)
36
+ })
36
37
 
37
38
  init {
38
39
  reactContext.addActivityEventListener(this)
@@ -72,23 +73,12 @@ class OtplessHeadlessRNModule(private val reactContext: ReactApplicationContext)
72
73
 
73
74
  @ReactMethod
74
75
  fun initialize(appId: String, loginUri: String? = null) {
75
- if (currentActivity == null) return
76
- (currentActivity as? AppCompatActivity)?.lifecycleScope?.let { scope ->
77
- scope.launch(Dispatchers.IO) {
76
+ val activity = currentActivity ?: return
77
+ ioScope.launch {
78
+ lifecycleMutex.withLock {
78
79
  OtplessSDK.initialize(
79
- appId = appId,
80
- activity = currentActivity!!,
81
- loginUri = loginUri,
82
- callback = this@OtplessHeadlessRNModule::sendHeadlessEventCallback
83
- )
84
- }
85
- } ?: run {
86
- CoroutineScope(Dispatchers.IO).launch {
87
- OtplessSDK.initialize(
88
- appId = appId,
89
- activity = currentActivity!!,
90
- loginUri = loginUri,
91
- callback = this@OtplessHeadlessRNModule::sendHeadlessEventCallback
80
+ appId = appId, activity = activity,
81
+ loginUri = loginUri, callback = this@OtplessHeadlessRNModule::sendHeadlessEventCallback
92
82
  )
93
83
  }
94
84
  }
@@ -96,11 +86,11 @@ class OtplessHeadlessRNModule(private val reactContext: ReactApplicationContext)
96
86
 
97
87
  @ReactMethod
98
88
  fun initTrueCaller(requestMap: ReadableMap, promise: Promise) {
99
- if (currentActivity == null) return
89
+ val activity = currentActivity ?: return
100
90
  val request = parseTrueCallerRequest(requestMap)
101
91
  val scopes = parseTrueCallerScope(requestMap)
102
- val result = OtplessSDK.initTrueCaller(currentActivity!!, request) {
103
- OTScopeRequest.ActivityRequest(currentActivity as FragmentActivity, scopes)
92
+ val result = OtplessSDK.initTrueCaller(activity, request) {
93
+ OTScopeRequest.ActivityRequest(activity as FragmentActivity, scopes)
104
94
  }
105
95
  debugLog("init truecaller result: $result")
106
96
  promise.resolve(result)
@@ -108,100 +98,32 @@ class OtplessHeadlessRNModule(private val reactContext: ReactApplicationContext)
108
98
 
109
99
  @ReactMethod
110
100
  fun userAuthEvent(event: String, fallback: Boolean, providerType: String, providerInfo: ReadableMap?) {
111
- // Defensive enum parsing unknown values log and return rather than crashing the bridge.
112
- val authEvent = runCatching { AuthEvent.valueOf(event) }.getOrElse {
101
+ val authEvent = parseAuthEvent(event) ?: run {
113
102
  debugLog("userAuthEvent: unknown AuthEvent '$event', ignoring call")
114
103
  return
115
104
  }
116
- val provider = runCatching { ProviderType.valueOf(providerType) }.getOrElse {
105
+ val provider = parseProviderType(providerType) ?: run {
117
106
  debugLog("userAuthEvent: unknown ProviderType '$providerType', ignoring call")
118
107
  return
119
108
  }
120
- // Defensive providerInfo parsing — JS passes `any`, so coerce each value to String:
121
- // primitives via toString(), Maps/Arrays via JSON serialisation, Null skipped.
122
- val infoMap = mutableMapOf<String, String>()
123
- if (providerInfo != null) {
124
- try {
125
- val iterator = providerInfo.keySetIterator()
126
- while (iterator.hasNextKey()) {
127
- val key = iterator.nextKey() ?: continue
128
- val value: String? = when (providerInfo.getType(key)) {
129
- ReadableType.String -> providerInfo.getString(key)
130
- ReadableType.Number -> providerInfo.getDouble(key).toString()
131
- ReadableType.Boolean -> providerInfo.getBoolean(key).toString()
132
- ReadableType.Map -> convertMapToJson(providerInfo.getMap(key))?.toString()
133
- ReadableType.Array -> convertArrayToJson(providerInfo.getArray(key))?.toString()
134
- else -> null // Null — skip
135
- }
136
- if (value != null) infoMap[key] = value
137
- }
138
- } catch (_: Exception) {
139
- // swallow any unexpected bridge parsing errors
140
- }
141
- }
109
+ val infoMap = parseProviderInfo(providerInfo)
142
110
  debugLog("pushing the user auth event\nauthEvent: $authEvent, providerType: $providerType")
143
111
  OtplessSDK.userAuthEvent(authEvent, fallback, provider, infoMap)
144
112
  }
145
113
 
146
114
  @ReactMethod
147
115
  fun start(data: ReadableMap) {
148
- val otplessRequest = OtplessRequest()
149
- val phone = data.getString("phone") ?: ""
150
- var isOtpPresent = false
151
-
152
- // phone number authentication
153
- if (phone.isNotEmpty()) {
154
- val countryCode = data.getString("countryCode") ?: ""
155
- otplessRequest.setPhoneNumber(number = phone, countryCode = countryCode)
156
- data.getString("otp")?.let {
157
- otplessRequest.setOtp(it)
158
- isOtpPresent = true
159
- }
160
- } else {
161
- // email authentication
162
- val email = data.getString("email") ?: ""
163
- if (email.isNotEmpty()) {
164
- otplessRequest.setEmail(email)
165
- data.getString("otp")?.let {
166
- otplessRequest.setOtp(it)
167
- isOtpPresent = true
168
- }
169
- } else {
170
- // oauth case
171
- otplessRequest.setChannelType(
172
- OtplessChannelType.fromString(
173
- data.getString("channelType") ?: ""
174
- )
175
- )
176
- }
177
- }
178
- data.getString("expiry")?.takeIf { it.isNotBlank() }?.let {
179
- otplessRequest.setExpiry(it)
180
- }
181
-
182
- data.getString("otpLength")?.takeIf { it.isNotBlank() }?.let {
183
- otplessRequest.setOtpLength(it)
184
- }
116
+ val otplessRequest = parseOtplessRequest(data)
117
+ val isOtpVerification = !data.getString("otp").isNullOrEmpty()
185
118
 
186
- data.getString("deliveryChannel")?.takeIf { it.isNotBlank() }?.let { deliveryChannel ->
187
- otplessRequest.setDeliveryChannel(deliveryChannel.uppercase())
188
- }
189
-
190
- data.getString("tid")?.takeIf { it.isNotBlank() }?.let { templateId ->
191
- otplessRequest.setTemplateId(templateId)
192
- }
193
-
194
- otplessJob?.cancel()
195
- currentActivity?.let {
196
- if (isOtpPresent) (it as AppCompatActivity).lifecycleScope.launch(Dispatchers.IO) {
119
+ if (isOtpVerification) {
120
+ // OTP submit — slot into the current auth flow; don't cancel, don't track
121
+ ioScope.launch {
197
122
  OtplessSDK.start(request = otplessRequest, this@OtplessHeadlessRNModule::sendHeadlessEventCallback)
198
- } else {
199
- otplessJob = (it as AppCompatActivity).lifecycleScope.launch {
200
- OtplessSDK.start(request = otplessRequest, this@OtplessHeadlessRNModule::sendHeadlessEventCallback)
201
- }
202
123
  }
203
- } ?: run {
204
- CoroutineScope(Dispatchers.IO).launch {
124
+ } else {
125
+ otplessJob?.cancel()
126
+ otplessJob = ioScope.launch {
205
127
  OtplessSDK.start(request = otplessRequest, this@OtplessHeadlessRNModule::sendHeadlessEventCallback)
206
128
  }
207
129
  }
@@ -215,7 +137,11 @@ class OtplessHeadlessRNModule(private val reactContext: ReactApplicationContext)
215
137
  @ReactMethod
216
138
  fun cleanup() {
217
139
  otplessJob?.cancel()
218
- OtplessSDK.cleanup()
140
+ ioScope.launch {
141
+ lifecycleMutex.withLock {
142
+ OtplessSDK.cleanup()
143
+ }
144
+ }
219
145
  }
220
146
 
221
147
  @ReactMethod
@@ -224,47 +150,82 @@ class OtplessHeadlessRNModule(private val reactContext: ReactApplicationContext)
224
150
  OtplessSDK.devLogging = devLogging
225
151
  }
226
152
 
227
- companion object {
228
- const val NAME = "OtplessHeadlessRN"
153
+ @ReactMethod
154
+ fun setMfaEnabled(enabled: Boolean) {
155
+ OtplessSDK.isMfaEnabled = enabled
156
+ }
157
+
158
+ @ReactMethod
159
+ fun setSimBindingEnabled(enabled: Boolean) {
160
+ OtplessSDK.isSimBindingEnabled = enabled
161
+ }
162
+
163
+ @ReactMethod
164
+ fun checkSimBindingStatus(promise: Promise) {
165
+ ioScope.launch {
166
+ try {
167
+ val bound = OtplessSDK.checkSimBindingStatus(reactContext.applicationContext)
168
+ promise.resolve(bound)
169
+ } catch (_: Throwable) {
170
+ promise.resolve(false)
171
+ }
172
+ }
173
+ }
174
+
175
+ @ReactMethod
176
+ fun clearSimBinding(promise: Promise) {
177
+ ioScope.launch {
178
+ try {
179
+ OtplessSDK.clearSimBinding(reactContext.applicationContext)
180
+ promise.resolve(null)
181
+ } catch (_: Throwable) {
182
+ promise.resolve(null)
183
+ }
184
+ }
185
+ }
186
+
187
+ @ReactMethod
188
+ fun startInBackground(data: ReadableMap) {
189
+ val otplessRequest = parseOtplessRequest(data)
190
+ otplessJob?.cancel()
191
+ otplessJob = ioScope.launch(Dispatchers.IO) {
192
+ OtplessSDK.startInBackground(otplessRequest, this@OtplessHeadlessRNModule::sendHeadlessEventCallback)
193
+ }
194
+ }
195
+
196
+ @ReactMethod
197
+ fun startBackgroundAuth(config: ReadableMap, promise: Promise) {
198
+ val activity = currentActivity
199
+ if (activity == null) {
200
+ promise.resolve(false)
201
+ return
202
+ }
203
+ val authConfig = parseOtplessAuthConfig(config)
204
+ ioScope.launch {
205
+ val result = OtplessSDK.start(authConfig)
206
+ promise.resolve(result)
207
+ }
229
208
  }
230
209
 
231
210
  override fun onActivityResult(
232
- activity: Activity?,
233
- requestCode: Int,
234
- resultCode: Int,
235
- data: Intent?
211
+ activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?
236
212
  ) {
237
213
  OtplessSDK.onActivityResult(requestCode, resultCode, data)
238
214
  }
239
215
 
240
216
  override fun onNewIntent(intent: Intent?) {
241
217
  intent ?: return
242
- (currentActivity as? AppCompatActivity)?.let { ac ->
243
- ac.lifecycleScope.launch(Dispatchers.IO) {
244
- OtplessSDK.onNewIntent(intent)
245
- }
246
- }
218
+ ioScope.launch { OtplessSDK.onNewIntent(intent) }
247
219
  }
248
220
 
249
221
  @ReactMethod
250
222
  fun commitResponse(data: ReadableMap?) {
251
- val dataMap = data?.toHashMap() ?: return
252
- val jsonResponse = JSONObject(dataMap as Map<*, *>)
253
- val otplessResponse = OtplessResponse(
254
- responseType = getResponseType(
255
- responseTypeString = jsonResponse.optString(
256
- "responseType",
257
- ""
258
- )
259
- ),
260
- jsonResponse.optJSONObject("response"),
261
- jsonResponse.optInt("statusCode", 0),
262
- )
223
+ val otplessResponse = parseOtplessResponse(data) ?: return
263
224
  OtplessSDK.commit(otplessResponse)
264
225
  }
265
226
 
266
- private fun getResponseType(responseTypeString: String): ResponseTypes {
267
- return ResponseTypes.valueOf(responseTypeString)
227
+ companion object {
228
+ const val NAME = "OtplessHeadlessRN"
268
229
  }
269
230
  }
270
231
 
@@ -17,6 +17,14 @@ import com.otpless.longclaw.tc.OTLoginPrefixText
17
17
  import com.otpless.longclaw.tc.OTScope
18
18
  import com.otpless.longclaw.tc.OTVerifyOption
19
19
  import com.otpless.longclaw.tc.OtplessTruecallerRequest
20
+ import com.otpless.v2.android.sdk.dto.AuthEvent
21
+ import com.otpless.v2.android.sdk.dto.DeviceFingerprintMode
22
+ import com.otpless.v2.android.sdk.dto.OtplessChannelType
23
+ import com.otpless.v2.android.sdk.dto.OtplessRequest
24
+ import com.otpless.v2.android.sdk.dto.OtplessResponse
25
+ import com.otpless.v2.android.sdk.dto.ProviderType
26
+ import com.otpless.v2.android.sdk.dto.ResponseTypes
27
+ import com.otpless.v2.android.sdk.view.models.OtplessAuthConfig
20
28
  import org.json.JSONArray
21
29
  import org.json.JSONException
22
30
  import org.json.JSONObject
@@ -131,6 +139,94 @@ internal fun convertJsonToArray(jsonArray: JSONArray): WritableArray {
131
139
  return array
132
140
  }
133
141
 
142
+ internal fun parseOtplessRequest(data: ReadableMap): OtplessRequest {
143
+ val otplessRequest = OtplessRequest()
144
+ data.getString("phone")?.takeIf { it.isNotBlank() }?.let { phone ->
145
+ val countryCode = data.getString("countryCode") ?: ""
146
+ otplessRequest.setPhoneNumber(number = phone, countryCode = countryCode)
147
+ }
148
+ data.getString("email")?.takeIf { it.isNotBlank() }?.let { otplessRequest.setEmail(it) }
149
+ data.getString("channelType")?.takeIf { it.isNotBlank() }?.let {
150
+ otplessRequest.setChannelType(OtplessChannelType.fromString(it))
151
+ }
152
+ data.getString("otp")?.takeIf { it.isNotBlank() }?.let { otplessRequest.setOtp(it) }
153
+ data.getString("requestId")?.takeIf { it.isNotBlank() }?.let { otplessRequest.requestId = it }
154
+ data.getString("expiry")?.takeIf { it.isNotBlank() }?.let { otplessRequest.setExpiry(it) }
155
+ data.getString("otpLength")?.takeIf { it.isNotBlank() }?.let { otplessRequest.setOtpLength(it) }
156
+ data.getString("deliveryChannel")?.takeIf { it.isNotBlank() }?.let {
157
+ otplessRequest.setDeliveryChannel(it.uppercase())
158
+ }
159
+ data.getString("tid")?.takeIf { it.isNotBlank() }?.let { otplessRequest.setTemplateId(it) }
160
+ data.getString("deviceFingerprintMode")?.takeIf { it.isNotBlank() }?.let { mode ->
161
+ runCatching { DeviceFingerprintMode.valueOf(mode.uppercase()) }.getOrNull()?.let {
162
+ otplessRequest.deviceFingerprintMode = it
163
+ }
164
+ }
165
+ return otplessRequest
166
+ }
167
+
168
+ internal fun parseOtplessAuthConfig(config: ReadableMap): OtplessAuthConfig {
169
+ val isForeground = if (config.hasKey("isForeground")) config.getBoolean("isForeground") else false
170
+ val otp = config.getString("otp") ?: ""
171
+ val tid = config.getString("tid")
172
+ val fingerprintMode = config.getString("deviceFingerprintMode")
173
+ ?.takeIf { it.isNotBlank() }
174
+ ?.let { runCatching { DeviceFingerprintMode.valueOf(it.uppercase()) }.getOrNull() }
175
+ ?: DeviceFingerprintMode.NONE
176
+ return OtplessAuthConfig(
177
+ isForeground = isForeground,
178
+ otp = otp,
179
+ tid = tid,
180
+ deviceFingerprintMode = fingerprintMode
181
+ )
182
+ }
183
+
184
+ internal fun parseOtplessResponse(data: ReadableMap?): OtplessResponse? {
185
+ val dataMap = data?.toHashMap() ?: return null
186
+ val jsonResponse = JSONObject(dataMap as Map<*, *>)
187
+ val responseTypeString = jsonResponse.optString("responseType", "")
188
+ val responseType = runCatching { ResponseTypes.valueOf(responseTypeString) }.getOrElse {
189
+ debugLog("commitResponse: unknown ResponseType '$responseTypeString', ignoring call")
190
+ return null
191
+ }
192
+ return OtplessResponse(
193
+ responseType = responseType,
194
+ jsonResponse.optJSONObject("response"),
195
+ jsonResponse.optInt("statusCode", 0),
196
+ )
197
+ }
198
+
199
+ internal fun parseAuthEvent(event: String): AuthEvent? =
200
+ runCatching { AuthEvent.valueOf(event) }.getOrNull()
201
+
202
+ internal fun parseProviderType(providerType: String): ProviderType? =
203
+ runCatching { ProviderType.valueOf(providerType) }.getOrNull()
204
+
205
+ // Defensive providerInfo parsing — JS passes `any`, so coerce each value to String:
206
+ // primitives via toString(), Maps/Arrays via JSON serialisation, Null skipped.
207
+ internal fun parseProviderInfo(providerInfo: ReadableMap?): Map<String, String> {
208
+ val infoMap = mutableMapOf<String, String>()
209
+ if (providerInfo == null) return infoMap
210
+ try {
211
+ val iterator = providerInfo.keySetIterator()
212
+ while (iterator.hasNextKey()) {
213
+ val key = iterator.nextKey() ?: continue
214
+ val value: String? = when (providerInfo.getType(key)) {
215
+ ReadableType.String -> providerInfo.getString(key)
216
+ ReadableType.Number -> providerInfo.getDouble(key).toString()
217
+ ReadableType.Boolean -> providerInfo.getBoolean(key).toString()
218
+ ReadableType.Map -> convertMapToJson(providerInfo.getMap(key))?.toString()
219
+ ReadableType.Array -> convertArrayToJson(providerInfo.getArray(key))?.toString()
220
+ else -> null
221
+ }
222
+ if (value != null) infoMap[key] = value
223
+ }
224
+ } catch (_: Exception) {
225
+ // swallow any unexpected bridge parsing errors
226
+ }
227
+ return infoMap
228
+ }
229
+
134
230
  internal fun parseTrueCallerRequest(requestMap: ReadableMap): OtplessTruecallerRequest {
135
231
  val trueCallerRequestMap = requestMap.getMap("trueCallerRequest") ?: return OtplessTruecallerRequest()
136
232
  // parsing footer type
@@ -23,7 +23,18 @@ RCT_EXTERN_METHOD(authorizeViaPasskey: (NSDictionary *)request)
23
23
 
24
24
  RCT_EXTERN_METHOD(setDevLogging:(BOOL)enable)
25
25
 
26
+ RCT_EXTERN_METHOD(userAuthEvent:(NSString *)event
27
+ fallback:(BOOL)fallback
28
+ providerType:(NSString *)providerType
29
+ providerInfo:(nullable NSDictionary *)providerInfo)
30
+
26
31
  RCT_EXTERN_METHOD(isSdkReady: (RCTPromiseResolveBlock*)resolve reject: (RCTPromiseRejectBlock*)reject)
27
32
 
33
+ RCT_EXTERN_METHOD(setMfaEnabled:(BOOL)enabled)
34
+
35
+ RCT_EXTERN_METHOD(startBackgroundAuth:(NSDictionary *)config
36
+ resolver:(RCTPromiseResolveBlock)resolve
37
+ rejecter:(RCTPromiseRejectBlock)reject)
38
+
28
39
  @end
29
40
 
@@ -11,13 +11,15 @@ class OtplessHeadlessRN: RCTEventEmitter, OtplessResponseDelegate {
11
11
 
12
12
  @objc(commitResponse:)
13
13
  func commitResponse(response: [String: Any]?) {
14
- guard let response = response else {
14
+ guard let response = response else { return }
15
+ guard let responseTypeString = response["responseType"] as? String,
16
+ let responseType = ResponseTypes(rawValue: responseTypeString) else {
17
+ print("OtplessHeadlessRN: commitResponse — unknown responseType, ignoring call")
15
18
  return
16
19
  }
17
- let responseType = response["responseType"] as? String ?? "FAILED"
18
- let statusCode = response["statusCode"] as? Int ?? -25000
20
+ let statusCode = response["statusCode"] as? Int ?? 0
19
21
  let responseDict = response["response"] as? [String: Any]
20
- let otplessResponse = OtplessResponse(responseType: ResponseTypes(rawValue: responseType) ?? .FAILED, response: responseDict, statusCode: statusCode)
22
+ let otplessResponse = OtplessResponse(responseType: responseType, response: responseDict, statusCode: statusCode)
21
23
  Otpless.shared.commitOtplessResponse(otplessResponse)
22
24
  }
23
25
 
@@ -34,35 +36,40 @@ class OtplessHeadlessRN: RCTEventEmitter, OtplessResponseDelegate {
34
36
 
35
37
  private func createOtplessRequest(args: [String: Any]) -> OtplessRequest {
36
38
  let otplessRequest = OtplessRequest()
37
- if let phone = args["phone"] as? String,
38
- let countryCode = args["countryCode"] as? String {
39
+
40
+ if let phone = args["phone"] as? String, !phone.isEmpty {
41
+ let countryCode = args["countryCode"] as? String ?? ""
39
42
  otplessRequest.set(phoneNumber: phone, withCountryCode: countryCode)
40
- } else if let email = args["email"] as? String {
43
+ }
44
+ if let email = args["email"] as? String, !email.isEmpty {
41
45
  otplessRequest.set(email: email)
42
- } else if let channelType = args["channelType"] as? String {
46
+ }
47
+ if let channelType = args["channelType"] as? String, !channelType.isEmpty {
43
48
  otplessRequest.set(channelType: OtplessChannelType.fromString(channelType))
44
49
  }
45
- if let otp = args["otp"] as? String {
50
+ if let requestId = args["requestId"] as? String, !requestId.isEmpty {
51
+ otplessRequest.set(fromBackend: requestId)
52
+ }
53
+ if let otp = args["otp"] as? String, !otp.isEmpty {
46
54
  otplessRequest.set(otp: otp)
47
55
  }
48
- if let deliveryChannel = args["deliveryChannel"] as? String,
49
- !deliveryChannel.isEmpty {
50
- otplessRequest.set(deliveryChannelForTransaction: deliveryChannel)
56
+ if let deliveryChannel = args["deliveryChannel"] as? String, !deliveryChannel.isEmpty {
57
+ otplessRequest.set(deliveryChannelForTransaction: deliveryChannel.uppercased())
51
58
  }
52
- if let otpExpiry = args["expiry"] as? String,
53
- !otpExpiry.isEmpty {
59
+ if let otpExpiry = args["expiry"] as? String, !otpExpiry.isEmpty {
54
60
  otplessRequest.set(otpExpiry: otpExpiry)
55
61
  }
56
- if let otpLength = args["otpLength"] as? String,
57
- !otpLength.isEmpty {
62
+ if let otpLength = args["otpLength"] as? String, !otpLength.isEmpty {
58
63
  otplessRequest.set(otpLength: otpLength)
59
64
  }
60
-
61
- if let tid = args["tid"] as? String,
62
- !tid.isEmpty {
65
+ if let tid = args["tid"] as? String, !tid.isEmpty {
63
66
  otplessRequest.set(tid: tid)
64
67
  }
65
-
68
+ if let modeString = args["deviceFingerprintMode"] as? String,
69
+ let mode = fingerprintModeFromString(modeString.uppercased()) {
70
+ otplessRequest.set(deviceFingerprintMode: mode)
71
+ }
72
+
66
73
  return otplessRequest
67
74
  }
68
75
 
@@ -84,7 +91,86 @@ class OtplessHeadlessRN: RCTEventEmitter, OtplessResponseDelegate {
84
91
  Otpless.shared.setLoggerDelegate(self)
85
92
  }
86
93
  }
94
+
95
+ @objc(setMfaEnabled:)
96
+ func setMfaEnabled(enabled: Bool) {
97
+ Otpless.shared.setMfaEnabled(enabled)
98
+ }
99
+
100
+ private func fingerprintModeFromString(_ name: String) -> DeviceFingerprintMode? {
101
+ switch name {
102
+ case "NONE": return .NONE
103
+ case "ASYNC": return .ASYNC
104
+ case "SYNC": return .SYNC
105
+ default: return nil
106
+ }
107
+ }
108
+
109
+ @objc(startBackgroundAuth:resolver:rejecter:)
110
+ func startBackgroundAuth(config: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
111
+ let isForeground = (config["isForeground"] as? Bool) ?? true
112
+ let otp = config["otp"] as? String
113
+ let tid = config["tid"] as? String
114
+ let mode = (config["deviceFingerprintMode"] as? String)
115
+ .flatMap { fingerprintModeFromString($0.uppercased()) } ?? .NONE
116
+ Otpless.shared.setDeviceFingerprintMode(mode)
117
+ let authConfig = OtplessAuthCofig(isForeground: isForeground, otp: otp, tid: tid)
118
+ DispatchQueue.main.async {
119
+ let rvc = UIApplication.shared.delegate?.window??.rootViewController
120
+ ?? self.getRootViewControllerFromWindowScene()
121
+ guard let vc = rvc else {
122
+ resolve(false)
123
+ return
124
+ }
125
+ Task(priority: .userInitiated) {
126
+ let result = await Otpless.shared.startAuth(parent: vc, config: authConfig)
127
+ resolve(result)
128
+ }
129
+ }
130
+ }
87
131
 
132
+ private func authEventFromString(_ name: String) -> AuthEvent? {
133
+ switch name {
134
+ case "AUTH_INITIATED": return .AUTH_INITIATED
135
+ case "AUTH_SUCCESS": return .AUTH_SUCCESS
136
+ case "AUTH_FAILED": return .AUTH_FAILED
137
+ default: return nil
138
+ }
139
+ }
140
+
141
+ private func providerTypeFromString(_ name: String) -> ProviderType? {
142
+ switch name {
143
+ case "CLIENT": return .CLIENT
144
+ case "OTPLESS": return .OTPLESS
145
+ default: return nil
146
+ }
147
+ }
148
+
149
+ @objc(userAuthEvent:fallback:providerType:providerInfo:)
150
+ func userAuthEvent(event: String, fallback: Bool, providerType: String, providerInfo: [String: Any]?) {
151
+ guard let authEvent = authEventFromString(event) else { return }
152
+ guard let provider = providerTypeFromString(providerType) else { return }
153
+ var info: [String: String] = [:]
154
+ if let raw = providerInfo {
155
+ for (key, value) in raw {
156
+ if let s = value as? String {
157
+ info[key] = s
158
+ } else if let n = value as? NSNumber {
159
+ info[key] = n.stringValue
160
+ } else if let arr = value as? [Any],
161
+ let data = try? JSONSerialization.data(withJSONObject: arr),
162
+ let s = String(data: data, encoding: .utf8) {
163
+ info[key] = s
164
+ } else if let dict = value as? [String: Any],
165
+ let data = try? JSONSerialization.data(withJSONObject: dict),
166
+ let s = String(data: data, encoding: .utf8) {
167
+ info[key] = s
168
+ }
169
+ }
170
+ }
171
+ Otpless.shared.userAuthEvent(event: authEvent, fallback: fallback, providerType: provider, providerInfo: info)
172
+ }
173
+
88
174
  override func supportedEvents() -> [String]! {
89
175
  return ["OTPlessEventResult"]
90
176
  }
@@ -98,19 +184,16 @@ class OtplessHeadlessRN: RCTEventEmitter, OtplessResponseDelegate {
98
184
  func initialize(appId: String, loginUri: String?) {
99
185
  DispatchQueue.main.async {
100
186
  let rootViewController = UIApplication.shared.delegate?.window??.rootViewController
101
- if rootViewController != nil {
187
+ if let rvc = rootViewController {
102
188
  Otpless.shared.setResponseDelegate(self)
103
- Otpless.shared.initialise(withAppId: appId, vc: rootViewController!)
189
+ Otpless.shared.initialise(withAppId: appId, loginUri: loginUri, vc: rvc)
104
190
  return
105
191
  }
106
-
107
- // Could not get an instance of RootViewController. Try to get RootViewController from `windowScene`.
192
+
108
193
  if #available(iOS 13.0, *) {
109
- let windowSceneVC = self.getRootViewControllerFromWindowScene()
110
- if windowSceneVC != nil {
194
+ if let windowSceneVC = self.getRootViewControllerFromWindowScene() {
111
195
  Otpless.shared.setResponseDelegate(self)
112
- Otpless.shared.initialise(withAppId: appId, vc: rootViewController!)
113
- return
196
+ Otpless.shared.initialise(withAppId: appId, loginUri: loginUri, vc: windowSceneVC)
114
197
  }
115
198
  }
116
199
  }
@@ -76,6 +76,33 @@ class OtplessHeadlessModule {
76
76
  setDevLogging(enable) {
77
77
  OtplessHeadlessRN.setDevLogging(enable);
78
78
  }
79
+ setMfaEnabled(enabled) {
80
+ OtplessHeadlessRN.setMfaEnabled(enabled);
81
+ }
82
+ async startBackgroundAuth(config) {
83
+ return await OtplessHeadlessRN.startBackgroundAuth(config);
84
+ }
85
+ startInBackground(input) {
86
+ if (_reactNative.Platform.OS === 'android') {
87
+ OtplessHeadlessRN.startInBackground(input);
88
+ }
89
+ }
90
+ setSimBindingEnabled(enabled) {
91
+ if (_reactNative.Platform.OS === 'android') {
92
+ OtplessHeadlessRN.setSimBindingEnabled(enabled);
93
+ }
94
+ }
95
+ async checkSimBindingStatus() {
96
+ if (_reactNative.Platform.OS === 'android') {
97
+ return await OtplessHeadlessRN.checkSimBindingStatus();
98
+ }
99
+ return false;
100
+ }
101
+ async clearSimBinding() {
102
+ if (_reactNative.Platform.OS === 'android') {
103
+ await OtplessHeadlessRN.clearSimBinding();
104
+ }
105
+ }
79
106
  async isSdkReady() {
80
107
  return await OtplessHeadlessRN.isSdkReady();
81
108
  }
@@ -85,14 +112,8 @@ class OtplessHeadlessModule {
85
112
  }
86
113
  return false;
87
114
  }
88
-
89
- // Android only — OtplessBM (iOS) has no equivalent.
90
- userAuthEvent(event, providerType, fallback = false, providerInfo = {} // `any` avoids Record<string,string> conflicts across RN versions
91
- ) {
92
- if (_reactNative.Platform.OS === 'android') {
93
- // args reordered to match Kotlin bridge: (event, fallback, providerType, providerInfo)
94
- OtplessHeadlessRN.userAuthEvent(event, fallback, providerType, providerInfo);
95
- }
115
+ userAuthEvent(event, providerType, fallback = false, providerInfo = {}) {
116
+ OtplessHeadlessRN.userAuthEvent(event, fallback, providerType, providerInfo);
96
117
  }
97
118
  }
98
119
  exports.OtplessHeadlessModule = OtplessHeadlessModule;
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_models","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","LINKING_ERROR","Platform","select","ios","default","OtplessHeadlessRN","NativeModules","Proxy","Error","OtplessHeadlessModule","eventEmitter","constructor","clearListener","_this$eventEmitter","removeAllListeners","initialize","appId","loginUri","NativeEventEmitter","setResponseCallback","callback","_this$eventEmitter2","addListener","start","input","commitResponse","response","isWhatsappInstalledForAndroid","OS","isWhatsappInstalled","cleanup","decimateAll","toLowerCase","setDevLogging","enable","isSdkReady","initTrueCaller","requestMap","userAuthEvent","event","providerType","fallback","providerInfo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_models","Object","keys","forEach","key","prototype","hasOwnProperty","call","_exportNames","exports","defineProperty","enumerable","get","LINKING_ERROR","Platform","select","ios","default","OtplessHeadlessRN","NativeModules","Proxy","Error","OtplessHeadlessModule","eventEmitter","constructor","clearListener","_this$eventEmitter","removeAllListeners","initialize","appId","loginUri","NativeEventEmitter","setResponseCallback","callback","_this$eventEmitter2","addListener","start","input","commitResponse","response","isWhatsappInstalledForAndroid","OS","isWhatsappInstalled","cleanup","decimateAll","toLowerCase","setDevLogging","enable","setMfaEnabled","enabled","startBackgroundAuth","config","startInBackground","setSimBindingEnabled","checkSimBindingStatus","clearSimBinding","isSdkReady","initTrueCaller","requestMap","userAuthEvent","event","providerType","fallback","providerInfo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;;;;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAmJA,IAAAC,OAAA,GAAAD,OAAA;AAAAE,MAAA,CAAAC,IAAA,CAAAF,OAAA,EAAAG,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAH,MAAA,CAAAI,SAAA,CAAAC,cAAA,CAAAC,IAAA,CAAAC,YAAA,EAAAJ,GAAA;EAAA,IAAAA,GAAA,IAAAK,OAAA,IAAAA,OAAA,CAAAL,GAAA,MAAAJ,OAAA,CAAAI,GAAA;EAAAH,MAAA,CAAAS,cAAA,CAAAD,OAAA,EAAAL,GAAA;IAAAO,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAZ,OAAA,CAAAI,GAAA;IAAA;EAAA;AAAA;AA1IA,MAAMS,aAAa,GACjB,8EAA8E,GAC9EC,qBAAQ,CAACC,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,iBAAiB,GAAGC,0BAAa,CAACD,iBAAiB,GACrDC,0BAAa,CAACD,iBAAiB,GAC/B,IAAIE,KAAK,CACP,CAAC,CAAC,EACF;EACER,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIS,KAAK,CAACR,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAML,MAAMS,qBAAqB,CAAC;EAClBC,YAAY,GAA8B,IAAI;EAEtDC,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACD,YAAY,GAAG,IAAI;EAC1B;EAEAE,aAAaA,CAAA,EAAG;IAAA,IAAAC,kBAAA;IACd,CAAAA,kBAAA,OAAI,CAACH,YAAY,cAAAG,kBAAA,eAAjBA,kBAAA,CAAmBC,kBAAkB,CAAC,oBAAoB,CAAC;EAC7D;EAEAC,UAAUA,CAACC,KAAa,EAAEC,QAAuB,GAAG,IAAI,EAAE;IACxD,IAAI,IAAI,CAACP,YAAY,IAAI,IAAI,EAAE;MAC7B,IAAI,CAACA,YAAY,GAAG,IAAIQ,+BAAkB,CAACb,iBAAiB,CAAC;IAC/D;IACA;IACAA,iBAAiB,CAACU,UAAU,CAACC,KAAK,EAAEC,QAAQ,CAAC;EAC/C;EAEAE,mBAAmBA,CAACC,QAA+B,EAAE;IAAA,IAAAC,mBAAA;IACnD,CAAAA,mBAAA,OAAI,CAACX,YAAY,cAAAW,mBAAA,eAAjBA,mBAAA,CAAmBC,WAAW,CAAC,oBAAoB,EAAEF,QAAQ,CAAC;EAChE;EAEAG,KAAKA,CAACC,KAA0B,EAAE;IAChCnB,iBAAiB,CAACkB,KAAK,CAACC,KAAK,CAAC;EAChC;EAEAC,cAAcA,CAACC,QAAa,EAAE;IAC5BrB,iBAAiB,CAACoB,cAAc,CAACC,QAAQ,CAAC;EAC5C;;EAEA;EACA,MAAMC,6BAA6BA,CAAA,EAAqB;IACtD,IAAI1B,qBAAQ,CAAC2B,EAAE,KAAK,SAAS,EAAE;MAC7B;MACA,OAAO,MAAMvB,iBAAiB,CAACwB,mBAAmB,CAAC,CAAC;IACtD,CAAC,MAAM;MACL,OAAO,KAAK;IACd;EACF;EAEAC,OAAOA,CAAA,EAAG;IACRzB,iBAAiB,CAACyB,OAAO,CAAC,CAAC;EAC7B;EAEAC,WAAWA,CAAA,EAAG;IACZ,IAAI9B,qBAAQ,CAAC2B,EAAE,CAACI,WAAW,CAAC,CAAC,KAAK,KAAK,EAAE;MACvC3B,iBAAiB,CAAC0B,WAAW,CAAC,CAAC;IACjC;EACF;EAEAE,aAAaA,CAACC,MAAe,EAAE;IAC7B7B,iBAAiB,CAAC4B,aAAa,CAACC,MAAM,CAAC;EACzC;EAEAC,aAAaA,CAACC,OAAgB,EAAE;IAC9B/B,iBAAiB,CAAC8B,aAAa,CAACC,OAAO,CAAC;EAC1C;EAEA,MAAMC,mBAAmBA,CACvBC,MAAmC,EACjB;IAClB,OAAO,MAAMjC,iBAAiB,CAACgC,mBAAmB,CAACC,MAAM,CAAC;EAC5D;EAEAC,iBAAiBA,CAACf,KAA0B,EAAE;IAC5C,IAAIvB,qBAAQ,CAAC2B,EAAE,KAAK,SAAS,EAAE;MAC7BvB,iBAAiB,CAACkC,iBAAiB,CAACf,KAAK,CAAC;IAC5C;EACF;EAEAgB,oBAAoBA,CAACJ,OAAgB,EAAE;IACrC,IAAInC,qBAAQ,CAAC2B,EAAE,KAAK,SAAS,EAAE;MAC7BvB,iBAAiB,CAACmC,oBAAoB,CAACJ,OAAO,CAAC;IACjD;EACF;EAEA,MAAMK,qBAAqBA,CAAA,EAAqB;IAC9C,IAAIxC,qBAAQ,CAAC2B,EAAE,KAAK,SAAS,EAAE;MAC7B,OAAO,MAAMvB,iBAAiB,CAACoC,qBAAqB,CAAC,CAAC;IACxD;IACA,OAAO,KAAK;EACd;EAEA,MAAMC,eAAeA,CAAA,EAAkB;IACrC,IAAIzC,qBAAQ,CAAC2B,EAAE,KAAK,SAAS,EAAE;MAC7B,MAAMvB,iBAAiB,CAACqC,eAAe,CAAC,CAAC;IAC3C;EACF;EAEA,MAAMC,UAAUA,CAAA,EAAqB;IACnC,OAAO,MAAMtC,iBAAiB,CAACsC,UAAU,CAAC,CAAC;EAC7C;EAEA,MAAMC,cAAcA,CAACC,UAAoC,EAAoB;IAC3E,IAAI5C,qBAAQ,CAAC2B,EAAE,KAAK,SAAS,EAAE;MAC7B,OAAO,MAAMvB,iBAAiB,CAACuC,cAAc,CAACC,UAAU,CAAC;IAC3D;IACA,OAAO,KAAK;EACd;EAEAC,aAAaA,CACXC,KAAuB,EACvBC,YAAiC,EACjCC,QAAiB,GAAG,KAAK,EACzBC,YAAiB,GAAG,CAAC,CAAC,EACtB;IACA7C,iBAAiB,CAACyC,aAAa,CAC7BC,KAAK,EACLE,QAAQ,EACRD,YAAY,EACZE,YACF,CAAC;EACH;AACF;AAACtD,OAAA,CAAAa,qBAAA,GAAAA,qBAAA","ignoreList":[]}
@@ -55,6 +55,33 @@ class OtplessHeadlessModule {
55
55
  setDevLogging(enable) {
56
56
  OtplessHeadlessRN.setDevLogging(enable);
57
57
  }
58
+ setMfaEnabled(enabled) {
59
+ OtplessHeadlessRN.setMfaEnabled(enabled);
60
+ }
61
+ async startBackgroundAuth(config) {
62
+ return await OtplessHeadlessRN.startBackgroundAuth(config);
63
+ }
64
+ startInBackground(input) {
65
+ if (Platform.OS === 'android') {
66
+ OtplessHeadlessRN.startInBackground(input);
67
+ }
68
+ }
69
+ setSimBindingEnabled(enabled) {
70
+ if (Platform.OS === 'android') {
71
+ OtplessHeadlessRN.setSimBindingEnabled(enabled);
72
+ }
73
+ }
74
+ async checkSimBindingStatus() {
75
+ if (Platform.OS === 'android') {
76
+ return await OtplessHeadlessRN.checkSimBindingStatus();
77
+ }
78
+ return false;
79
+ }
80
+ async clearSimBinding() {
81
+ if (Platform.OS === 'android') {
82
+ await OtplessHeadlessRN.clearSimBinding();
83
+ }
84
+ }
58
85
  async isSdkReady() {
59
86
  return await OtplessHeadlessRN.isSdkReady();
60
87
  }
@@ -64,14 +91,8 @@ class OtplessHeadlessModule {
64
91
  }
65
92
  return false;
66
93
  }
67
-
68
- // Android only — OtplessBM (iOS) has no equivalent.
69
- userAuthEvent(event, providerType, fallback = false, providerInfo = {} // `any` avoids Record<string,string> conflicts across RN versions
70
- ) {
71
- if (Platform.OS === 'android') {
72
- // args reordered to match Kotlin bridge: (event, fallback, providerType, providerInfo)
73
- OtplessHeadlessRN.userAuthEvent(event, fallback, providerType, providerInfo);
74
- }
94
+ userAuthEvent(event, providerType, fallback = false, providerInfo = {}) {
95
+ OtplessHeadlessRN.userAuthEvent(event, fallback, providerType, providerInfo);
75
96
  }
76
97
  }
77
98
  export { OtplessHeadlessModule };
@@ -1 +1 @@
1
- {"version":3,"names":["NativeModules","Platform","NativeEventEmitter","LINKING_ERROR","select","ios","default","OtplessHeadlessRN","Proxy","get","Error","OtplessHeadlessModule","eventEmitter","constructor","clearListener","_this$eventEmitter","removeAllListeners","initialize","appId","loginUri","setResponseCallback","callback","_this$eventEmitter2","addListener","start","input","commitResponse","response","isWhatsappInstalledForAndroid","OS","isWhatsappInstalled","cleanup","decimateAll","toLowerCase","setDevLogging","enable","isSdkReady","initTrueCaller","requestMap","userAuthEvent","event","providerType","fallback","providerInfo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"AAAA,SAASA,aAAa,EAAEC,QAAQ,EAAEC,kBAAkB,QAAQ,cAAc;AAO1E,MAAMC,aAAa,GACjB,8EAA8E,GAC9EF,QAAQ,CAACG,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;AAEjC,MAAMC,iBAAiB,GAAGP,aAAa,CAACO,iBAAiB,GACrDP,aAAa,CAACO,iBAAiB,GAC/B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAML,MAAMQ,qBAAqB,CAAC;EAClBC,YAAY,GAA8B,IAAI;EAEtDC,WAAWA,CAAA,EAAG;IACZ,IAAI,CAACD,YAAY,GAAG,IAAI;EAC1B;EAEAE,aAAaA,CAAA,EAAG;IAAA,IAAAC,kBAAA;IACd,CAAAA,kBAAA,OAAI,CAACH,YAAY,cAAAG,kBAAA,eAAjBA,kBAAA,CAAmBC,kBAAkB,CAAC,oBAAoB,CAAC;EAC7D;EAEAC,UAAUA,CAACC,KAAa,EAAEC,QAAuB,GAAG,IAAI,EAAE;IACxD,IAAI,IAAI,CAACP,YAAY,IAAI,IAAI,EAAE;MAC7B,IAAI,CAACA,YAAY,GAAG,IAAIV,kBAAkB,CAACK,iBAAiB,CAAC;IAC/D;IACA;IACAA,iBAAiB,CAACU,UAAU,CAACC,KAAK,EAAEC,QAAQ,CAAC;EAC/C;EAEAC,mBAAmBA,CAACC,QAA+B,EAAE;IAAA,IAAAC,mBAAA;IACnD,CAAAA,mBAAA,OAAI,CAACV,YAAY,cAAAU,mBAAA,eAAjBA,mBAAA,CAAmBC,WAAW,CAAC,oBAAoB,EAAEF,QAAQ,CAAC;EAChE;EAEAG,KAAKA,CAACC,KAAU,EAAE;IAChBlB,iBAAiB,CAACiB,KAAK,CAACC,KAAK,CAAC;EAChC;EAEAC,cAAcA,CAACC,QAAa,EAAE;IAC5BpB,iBAAiB,CAACmB,cAAc,CAACC,QAAQ,CAAC;EAC5C;;EAEA;EACA,MAAMC,6BAA6BA,CAAA,EAAqB;IACtD,IAAI3B,QAAQ,CAAC4B,EAAE,KAAK,SAAS,EAAE;MAC7B;MACA,OAAO,MAAMtB,iBAAiB,CAACuB,mBAAmB,CAAC,CAAC;IACtD,CAAC,MAAM;MACL,OAAO,KAAK;IACd;EACF;EAEAC,OAAOA,CAAA,EAAG;IACRxB,iBAAiB,CAACwB,OAAO,CAAC,CAAC;EAC7B;EAEAC,WAAWA,CAAA,EAAG;IACZ,IAAI/B,QAAQ,CAAC4B,EAAE,CAACI,WAAW,CAAC,CAAC,KAAK,KAAK,EAAE;MACvC1B,iBAAiB,CAACyB,WAAW,CAAC,CAAC;IACjC;EACF;EAEAE,aAAaA,CAACC,MAAe,EAAE;IAC7B5B,iBAAiB,CAAC2B,aAAa,CAACC,MAAM,CAAC;EACzC;EAEA,MAAMC,UAAUA,CAAA,EAAqB;IACnC,OAAO,MAAM7B,iBAAiB,CAAC6B,UAAU,CAAC,CAAC;EAC7C;EAEA,MAAMC,cAAcA,CAACC,UAAoC,EAAoB;IAC3E,IAAIrC,QAAQ,CAAC4B,EAAE,KAAK,SAAS,EAAE;MAC7B,OAAO,MAAMtB,iBAAiB,CAAC8B,cAAc,CAACC,UAAU,CAAC;IAC3D;IACA,OAAO,KAAK;EACd;;EAEA;EACAC,aAAaA,CACXC,KAAuB,EACvBC,YAAiC,EACjCC,QAAiB,GAAG,KAAK,EACzBC,YAAiB,GAAG,CAAC,CAAC,CAAC;EAAA,EACvB;IACA,IAAI1C,QAAQ,CAAC4B,EAAE,KAAK,SAAS,EAAE;MAC7B;MACAtB,iBAAiB,CAACgC,aAAa,CAC7BC,KAAK,EACLE,QAAQ,EACRD,YAAY,EACZE,YACF,CAAC;IACH;EACF;AACF;AAEA,SAAShC,qBAAqB;AAC9B,cAAc,UAAU","ignoreList":[]}
1
+ {"version":3,"names":["NativeModules","Platform","NativeEventEmitter","LINKING_ERROR","select","ios","default","OtplessHeadlessRN","Proxy","get","Error","OtplessHeadlessModule","eventEmitter","constructor","clearListener","_this$eventEmitter","removeAllListeners","initialize","appId","loginUri","setResponseCallback","callback","_this$eventEmitter2","addListener","start","input","commitResponse","response","isWhatsappInstalledForAndroid","OS","isWhatsappInstalled","cleanup","decimateAll","toLowerCase","setDevLogging","enable","setMfaEnabled","enabled","startBackgroundAuth","config","startInBackground","setSimBindingEnabled","checkSimBindingStatus","clearSimBinding","isSdkReady","initTrueCaller","requestMap","userAuthEvent","event","providerType","fallback","providerInfo"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":"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","ignoreList":[]}
@@ -1,4 +1,4 @@
1
- import type { OtplessTruecallerRequest, OtplessAuthEvent, OtplessProviderType } from './models';
1
+ import type { OtplessTruecallerRequest, OtplessAuthEvent, OtplessProviderType, OtplessRequestInput, OtplessBackgroundAuthConfig } from './models';
2
2
  interface OtplessResultCallback {
3
3
  (result: any): void;
4
4
  }
@@ -8,12 +8,18 @@ declare class OtplessHeadlessModule {
8
8
  clearListener(): void;
9
9
  initialize(appId: String, loginUri?: string | null): void;
10
10
  setResponseCallback(callback: OtplessResultCallback): void;
11
- start(input: any): void;
11
+ start(input: OtplessRequestInput): void;
12
12
  commitResponse(response: any): void;
13
13
  isWhatsappInstalledForAndroid(): Promise<boolean>;
14
14
  cleanup(): void;
15
15
  decimateAll(): void;
16
16
  setDevLogging(enable: boolean): void;
17
+ setMfaEnabled(enabled: boolean): void;
18
+ startBackgroundAuth(config: OtplessBackgroundAuthConfig): Promise<boolean>;
19
+ startInBackground(input: OtplessRequestInput): void;
20
+ setSimBindingEnabled(enabled: boolean): void;
21
+ checkSimBindingStatus(): Promise<boolean>;
22
+ clearSimBinding(): Promise<void>;
17
23
  isSdkReady(): Promise<boolean>;
18
24
  initTrueCaller(requestMap: OtplessTruecallerRequest): Promise<boolean>;
19
25
  userAuthEvent(event: OtplessAuthEvent, providerType: OtplessProviderType, fallback?: boolean, providerInfo?: any): void;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAmBlB,UAAU,qBAAqB;IAC7B,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;CACrB;AAED,cAAM,qBAAqB;IACzB,OAAO,CAAC,YAAY,CAAmC;;IAMvD,aAAa;IAIb,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW;IAQxD,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB;IAInD,KAAK,CAAC,KAAK,EAAE,GAAG;IAIhB,cAAc,CAAC,QAAQ,EAAE,GAAG;IAKtB,6BAA6B,IAAI,OAAO,CAAC,OAAO,CAAC;IASvD,OAAO;IAIP,WAAW;IAMX,aAAa,CAAC,MAAM,EAAE,OAAO;IAIvB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAI9B,cAAc,CAAC,UAAU,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQ5E,aAAa,CACX,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,mBAAmB,EACjC,QAAQ,GAAE,OAAe,EACzB,YAAY,GAAE,GAAQ;CAYzB;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC;AACjC,cAAc,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,gBAAgB,EAChB,mBAAmB,EACnB,mBAAmB,EACnB,2BAA2B,EAC5B,MAAM,UAAU,CAAC;AAmBlB,UAAU,qBAAqB;IAC7B,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAAC;CACrB;AAED,cAAM,qBAAqB;IACzB,OAAO,CAAC,YAAY,CAAmC;;IAMvD,aAAa;IAIb,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAM,GAAG,IAAW;IAQxD,mBAAmB,CAAC,QAAQ,EAAE,qBAAqB;IAInD,KAAK,CAAC,KAAK,EAAE,mBAAmB;IAIhC,cAAc,CAAC,QAAQ,EAAE,GAAG;IAKtB,6BAA6B,IAAI,OAAO,CAAC,OAAO,CAAC;IASvD,OAAO;IAIP,WAAW;IAMX,aAAa,CAAC,MAAM,EAAE,OAAO;IAI7B,aAAa,CAAC,OAAO,EAAE,OAAO;IAIxB,mBAAmB,CACvB,MAAM,EAAE,2BAA2B,GAClC,OAAO,CAAC,OAAO,CAAC;IAInB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB;IAM5C,oBAAoB,CAAC,OAAO,EAAE,OAAO;IAM/B,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC;IAOzC,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAMhC,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAI9B,cAAc,CAAC,UAAU,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC;IAO5E,aAAa,CACX,KAAK,EAAE,gBAAgB,EACvB,YAAY,EAAE,mBAAmB,EACjC,QAAQ,GAAE,OAAe,EACzB,YAAY,GAAE,GAAQ;CASzB;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC;AACjC,cAAc,UAAU,CAAC"}
@@ -13,7 +13,7 @@ export interface OtplessTruecallerConfig {
13
13
  buttonColor?: number;
14
14
  buttonTextColor?: number;
15
15
  }
16
- export type OTScope = "profile" | "phone" | "open_id" | "offline_access" | "email" | "address";
16
+ export type OTScope = 'profile' | 'phone' | 'open_id' | 'offline_access' | 'email' | 'address';
17
17
  export type OTFooterType = 'footer_type_skip' | 'footer_type_another_mobile_no' | 'footer_type_another_method' | 'footer_type_manually' | 'footer_type_later';
18
18
  export type OTButtonShape = 'button_shape_rounded' | 'button_shape_rectangle';
19
19
  export type OTVerifyOption = 'option_verify_only_tc_users' | 'option_verify_all_users';
@@ -22,4 +22,28 @@ export type OTLoginPrefixText = 'login_text_prefix_to_get_started' | 'login_text
22
22
  export type OTCtaText = 'cta_text_proceed' | 'cta_text_continue' | 'cta_text_accept' | 'cta_text_confirm';
23
23
  export type OtplessAuthEvent = 'AUTH_INITIATED' | 'AUTH_SUCCESS' | 'AUTH_FAILED';
24
24
  export type OtplessProviderType = 'CLIENT' | 'OTPLESS';
25
+ export interface OtplessRequestInput {
26
+ phone?: string;
27
+ /** Required together with `phone`. */
28
+ countryCode?: string;
29
+ email?: string;
30
+ channelType?: OtplessChannelType;
31
+ otp?: string;
32
+ expiry?: string;
33
+ otpLength?: string;
34
+ deliveryChannel?: string;
35
+ tid?: string;
36
+ /** Backend-generated or WebAuthn request ID. */
37
+ requestId?: string;
38
+ deviceFingerprintMode?: OtplessDeviceFingerprintMode;
39
+ }
40
+ export interface OtplessBackgroundAuthConfig {
41
+ /** Defaults to `true` — presents the OneTap bottom sheet. `false` runs in background when possible. */
42
+ isForeground?: boolean;
43
+ otp?: string;
44
+ tid?: string;
45
+ deviceFingerprintMode?: OtplessDeviceFingerprintMode;
46
+ }
47
+ export type OtplessChannelType = 'WHATSAPP' | 'GOOGLE_SDK' | 'FACEBOOK_SDK' | 'APPLE' | 'APPLE_SDK' | 'GMAIL' | 'TWITTER' | 'DISCORD' | 'SLACK' | 'FACEBOOK' | 'LINKEDIN' | 'MICROSOFT' | 'LINE' | 'LINEAR' | 'NOTION' | 'TWITCH' | 'GITHUB' | 'BITBUCKET' | 'ATLASSIAN' | 'GITLAB' | 'TRUE_CALLER';
48
+ export type OtplessDeviceFingerprintMode = 'NONE' | 'ASYNC' | 'SYNC';
25
49
  //# sourceMappingURL=models.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/models.tsx"],"names":[],"mappings":"AACA,MAAM,WAAW,wBAAwB;IACrC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;CACzB;AAGD,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,YAAY,CAAC,EAAE,cAAc,CAAC;IAC9B,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,eAAe,CAAC,EAAE,iBAAiB,CAAC;IACpC,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AAE/F,MAAM,MAAM,YAAY,GAClB,kBAAkB,GAClB,+BAA+B,GAC/B,4BAA4B,GAC5B,sBAAsB,GACtB,mBAAmB,CAAC;AAE1B,MAAM,MAAM,aAAa,GACnB,sBAAsB,GACtB,wBAAwB,CAAC;AAG/B,MAAM,MAAM,cAAc,GACpB,6BAA6B,GAC7B,yBAAyB,CAAC;AAGhC,MAAM,MAAM,gBAAgB,GACtB,+BAA+B,GAC/B,kCAAkC,GAClC,gCAAgC,GAChC,wCAAwC,GACxC,mCAAmC,GACnC,sCAAsC,GACtC,kCAAkC,GAClC,iCAAiC,GACjC,yCAAyC,GACzC,8CAA8C,GAC9C,0CAA0C,GAC1C,yCAAyC,GACzC,mCAAmC,GACnC,yCAAyC,GACzC,sCAAsC,GACtC,2CAA2C,GAC3C,mCAAmC,GACnC,yCAAyC,GACzC,8CAA8C,GAC9C,2CAA2C,GAC3C,kCAAkC,GAClC,sCAAsC,GACtC,yCAAyC,GACzC,0CAA0C,GAC1C,uCAAuC,CAAC;AAG9C,MAAM,MAAM,iBAAiB,GACvB,kCAAkC,GAClC,+BAA+B,GAC/B,kCAAkC,GAClC,6CAA6C,GAC7C,+BAA+B,GAC/B,4CAA4C,GAC5C,gDAAgD,GAChD,iDAAiD,GACjD,kCAAkC,GAClC,gCAAgC,GAChC,uCAAuC,GACvC,8BAA8B,GAC9B,mCAAmC,GACnC,kCAAkC,GAClC,gCAAgC,GAChC,gDAAgD,CAAC;AAGvD,MAAM,MAAM,SAAS,GACf,kBAAkB,GAClB,mBAAmB,GACnB,iBAAiB,GACjB,kBAAkB,CAAC;AAEzB,MAAM,MAAM,gBAAgB,GAAG,gBAAgB,GAAG,cAAc,GAAG,aAAa,CAAC;AAEjF,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/models.tsx"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ Pod::Spec.new do |s|
17
17
  s.source_files = "ios/**/*.{h,m,mm,swift}"
18
18
 
19
19
  s.dependency "React-Core"
20
- s.dependency 'OtplessBM/Core', '2.0.9'
20
+ s.dependency 'OtplessBM/Core', '2.4.0'
21
21
  s.swift_versions = ['5.5']
22
22
 
23
23
  # Don't install the dependencies when we run `pod install` in the old architecture.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "otpless-headless-rn",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "react native plugin for otpless headless android and ios",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
package/src/index.tsx CHANGED
@@ -3,6 +3,8 @@ import type {
3
3
  OtplessTruecallerRequest,
4
4
  OtplessAuthEvent,
5
5
  OtplessProviderType,
6
+ OtplessRequestInput,
7
+ OtplessBackgroundAuthConfig,
6
8
  } from './models';
7
9
 
8
10
  const LINKING_ERROR =
@@ -49,7 +51,7 @@ class OtplessHeadlessModule {
49
51
  this.eventEmitter?.addListener('OTPlessEventResult', callback);
50
52
  }
51
53
 
52
- start(input: any) {
54
+ start(input: OtplessRequestInput) {
53
55
  OtplessHeadlessRN.start(input);
54
56
  }
55
57
 
@@ -81,6 +83,41 @@ class OtplessHeadlessModule {
81
83
  OtplessHeadlessRN.setDevLogging(enable);
82
84
  }
83
85
 
86
+ setMfaEnabled(enabled: boolean) {
87
+ OtplessHeadlessRN.setMfaEnabled(enabled);
88
+ }
89
+
90
+ async startBackgroundAuth(
91
+ config: OtplessBackgroundAuthConfig
92
+ ): Promise<boolean> {
93
+ return await OtplessHeadlessRN.startBackgroundAuth(config);
94
+ }
95
+
96
+ startInBackground(input: OtplessRequestInput) {
97
+ if (Platform.OS === 'android') {
98
+ OtplessHeadlessRN.startInBackground(input);
99
+ }
100
+ }
101
+
102
+ setSimBindingEnabled(enabled: boolean) {
103
+ if (Platform.OS === 'android') {
104
+ OtplessHeadlessRN.setSimBindingEnabled(enabled);
105
+ }
106
+ }
107
+
108
+ async checkSimBindingStatus(): Promise<boolean> {
109
+ if (Platform.OS === 'android') {
110
+ return await OtplessHeadlessRN.checkSimBindingStatus();
111
+ }
112
+ return false;
113
+ }
114
+
115
+ async clearSimBinding(): Promise<void> {
116
+ if (Platform.OS === 'android') {
117
+ await OtplessHeadlessRN.clearSimBinding();
118
+ }
119
+ }
120
+
84
121
  async isSdkReady(): Promise<boolean> {
85
122
  return await OtplessHeadlessRN.isSdkReady();
86
123
  }
@@ -92,22 +129,18 @@ class OtplessHeadlessModule {
92
129
  return false;
93
130
  }
94
131
 
95
- // Android only — OtplessBM (iOS) has no equivalent.
96
132
  userAuthEvent(
97
133
  event: OtplessAuthEvent,
98
134
  providerType: OtplessProviderType,
99
135
  fallback: boolean = false,
100
- providerInfo: any = {} // `any` avoids Record<string,string> conflicts across RN versions
136
+ providerInfo: any = {}
101
137
  ) {
102
- if (Platform.OS === 'android') {
103
- // args reordered to match Kotlin bridge: (event, fallback, providerType, providerInfo)
104
- OtplessHeadlessRN.userAuthEvent(
105
- event,
106
- fallback,
107
- providerType,
108
- providerInfo
109
- );
110
- }
138
+ OtplessHeadlessRN.userAuthEvent(
139
+ event,
140
+ fallback,
141
+ providerType,
142
+ providerInfo
143
+ );
111
144
  }
112
145
  }
113
146
 
package/src/models.tsx CHANGED
@@ -1,10 +1,8 @@
1
-
2
1
  export interface OtplessTruecallerRequest {
3
- trueCallerRequest?: OtplessTruecallerConfig;
4
- scope: Array<OTScope>;
2
+ trueCallerRequest?: OtplessTruecallerConfig;
3
+ scope: Array<OTScope>;
5
4
  }
6
5
 
7
-
8
6
  export interface OtplessTruecallerConfig {
9
7
  footerType?: OTFooterType;
10
8
  shape?: OTButtonShape;
@@ -17,78 +15,130 @@ export interface OtplessTruecallerConfig {
17
15
  buttonTextColor?: number;
18
16
  }
19
17
 
20
- export type OTScope = "profile" | "phone" | "open_id" | "offline_access" | "email" | "address";
18
+ export type OTScope =
19
+ | 'profile'
20
+ | 'phone'
21
+ | 'open_id'
22
+ | 'offline_access'
23
+ | 'email'
24
+ | 'address';
21
25
 
22
26
  export type OTFooterType =
23
- | 'footer_type_skip'
24
- | 'footer_type_another_mobile_no'
25
- | 'footer_type_another_method'
26
- | 'footer_type_manually'
27
- | 'footer_type_later';
28
-
29
- export type OTButtonShape =
30
- | 'button_shape_rounded'
31
- | 'button_shape_rectangle';
27
+ | 'footer_type_skip'
28
+ | 'footer_type_another_mobile_no'
29
+ | 'footer_type_another_method'
30
+ | 'footer_type_manually'
31
+ | 'footer_type_later';
32
32
 
33
+ export type OTButtonShape = 'button_shape_rounded' | 'button_shape_rectangle';
33
34
 
34
35
  export type OTVerifyOption =
35
- | 'option_verify_only_tc_users'
36
- | 'option_verify_all_users';
37
-
36
+ | 'option_verify_only_tc_users'
37
+ | 'option_verify_all_users';
38
38
 
39
39
  export type OTHeadingConsent =
40
- | 'sdk_consent_heading_log_in_to'
41
- | 'sdk_consent_heading_sign_up_with'
42
- | 'sdk_consent_heading_sign_in_to'
43
- | 'sdk_consent_heading_verify_number_with'
44
- | 'sdk_consent_heading_register_with'
45
- | 'sdk_consent_heading_get_started_with'
46
- | 'sdk_consent_heading_proceed_with'
47
- | 'sdk_consent_heading_verify_with'
48
- | 'sdk_consent_heading_verify_profile_with'
49
- | 'sdk_consent_heading_verify_your_profile_with'
50
- | 'sdk_consent_heading_verify_phone_no_with'
51
- | 'sdk_consent_heading_verify_your_no_with'
52
- | 'sdk_consent_heading_continue_with'
53
- | 'sdk_consent_heading_complete_order_with'
54
- | 'sdk_consent_heading_place_order_with'
55
- | 'sdk_consent_heading_complete_booking_with'
56
- | 'sdk_consent_heading_checkout_with'
57
- | 'sdk_consent_heading_manage_details_with'
58
- | 'sdk_consent_heading_manage_your_details_with'
59
- | 'sdk_consent_heading_login_to_with_one_tap'
60
- | 'sdk_consent_heading_subscribe_to'
61
- | 'sdk_consent_heading_get_updates_from'
62
- | 'sdk_consent_heading_continue_reading_on'
63
- | 'sdk_consent_heading_get_new_updates_from'
64
- | 'sdk_consent_heading_login_signup_with';
65
-
40
+ | 'sdk_consent_heading_log_in_to'
41
+ | 'sdk_consent_heading_sign_up_with'
42
+ | 'sdk_consent_heading_sign_in_to'
43
+ | 'sdk_consent_heading_verify_number_with'
44
+ | 'sdk_consent_heading_register_with'
45
+ | 'sdk_consent_heading_get_started_with'
46
+ | 'sdk_consent_heading_proceed_with'
47
+ | 'sdk_consent_heading_verify_with'
48
+ | 'sdk_consent_heading_verify_profile_with'
49
+ | 'sdk_consent_heading_verify_your_profile_with'
50
+ | 'sdk_consent_heading_verify_phone_no_with'
51
+ | 'sdk_consent_heading_verify_your_no_with'
52
+ | 'sdk_consent_heading_continue_with'
53
+ | 'sdk_consent_heading_complete_order_with'
54
+ | 'sdk_consent_heading_place_order_with'
55
+ | 'sdk_consent_heading_complete_booking_with'
56
+ | 'sdk_consent_heading_checkout_with'
57
+ | 'sdk_consent_heading_manage_details_with'
58
+ | 'sdk_consent_heading_manage_your_details_with'
59
+ | 'sdk_consent_heading_login_to_with_one_tap'
60
+ | 'sdk_consent_heading_subscribe_to'
61
+ | 'sdk_consent_heading_get_updates_from'
62
+ | 'sdk_consent_heading_continue_reading_on'
63
+ | 'sdk_consent_heading_get_new_updates_from'
64
+ | 'sdk_consent_heading_login_signup_with';
66
65
 
67
66
  export type OTLoginPrefixText =
68
- | 'login_text_prefix_to_get_started'
69
- | 'login_text_prefix_to_continue'
70
- | 'login_text_prefix_to_place_order'
71
- | 'login_text_prefix_to_complete_your_purchase'
72
- | 'login_text_prefix_to_checkout'
73
- | 'login_text_prefix_to_complete_your_booking'
74
- | 'login_text_prefix_to_proceed_with_your_booking'
75
- | 'login_text_prefix_to_continue_with_your_booking'
76
- | 'login_text_prefix_to_get_details'
77
- | 'login_text_prefix_to_view_more'
78
- | 'login_text_prefix_to_continue_reading'
79
- | 'login_text_prefix_to_proceed'
80
- | 'login_text_prefix_for_new_updates'
81
- | 'login_text_prefix_to_get_updates'
82
- | 'login_text_prefix_to_subscribe'
83
- | 'login_text_prefix_to_subscribe_and_get_updates';
84
-
67
+ | 'login_text_prefix_to_get_started'
68
+ | 'login_text_prefix_to_continue'
69
+ | 'login_text_prefix_to_place_order'
70
+ | 'login_text_prefix_to_complete_your_purchase'
71
+ | 'login_text_prefix_to_checkout'
72
+ | 'login_text_prefix_to_complete_your_booking'
73
+ | 'login_text_prefix_to_proceed_with_your_booking'
74
+ | 'login_text_prefix_to_continue_with_your_booking'
75
+ | 'login_text_prefix_to_get_details'
76
+ | 'login_text_prefix_to_view_more'
77
+ | 'login_text_prefix_to_continue_reading'
78
+ | 'login_text_prefix_to_proceed'
79
+ | 'login_text_prefix_for_new_updates'
80
+ | 'login_text_prefix_to_get_updates'
81
+ | 'login_text_prefix_to_subscribe'
82
+ | 'login_text_prefix_to_subscribe_and_get_updates';
85
83
 
86
84
  export type OTCtaText =
87
- | 'cta_text_proceed'
88
- | 'cta_text_continue'
89
- | 'cta_text_accept'
90
- | 'cta_text_confirm';
85
+ | 'cta_text_proceed'
86
+ | 'cta_text_continue'
87
+ | 'cta_text_accept'
88
+ | 'cta_text_confirm';
91
89
 
92
- export type OtplessAuthEvent = 'AUTH_INITIATED' | 'AUTH_SUCCESS' | 'AUTH_FAILED';
90
+ export type OtplessAuthEvent =
91
+ | 'AUTH_INITIATED'
92
+ | 'AUTH_SUCCESS'
93
+ | 'AUTH_FAILED';
93
94
 
94
95
  export type OtplessProviderType = 'CLIENT' | 'OTPLESS';
96
+
97
+ export interface OtplessRequestInput {
98
+ phone?: string;
99
+ /** Required together with `phone`. */
100
+ countryCode?: string;
101
+ email?: string;
102
+ channelType?: OtplessChannelType;
103
+ otp?: string;
104
+ expiry?: string;
105
+ otpLength?: string;
106
+ deliveryChannel?: string;
107
+ tid?: string;
108
+ /** Backend-generated or WebAuthn request ID. */
109
+ requestId?: string;
110
+ deviceFingerprintMode?: OtplessDeviceFingerprintMode;
111
+ }
112
+
113
+ export interface OtplessBackgroundAuthConfig {
114
+ /** Defaults to `true` — presents the OneTap bottom sheet. `false` runs in background when possible. */
115
+ isForeground?: boolean;
116
+ otp?: string;
117
+ tid?: string;
118
+ deviceFingerprintMode?: OtplessDeviceFingerprintMode;
119
+ }
120
+
121
+ export type OtplessChannelType =
122
+ | 'WHATSAPP'
123
+ | 'GOOGLE_SDK'
124
+ | 'FACEBOOK_SDK'
125
+ | 'APPLE'
126
+ | 'APPLE_SDK'
127
+ | 'GMAIL'
128
+ | 'TWITTER'
129
+ | 'DISCORD'
130
+ | 'SLACK'
131
+ | 'FACEBOOK'
132
+ | 'LINKEDIN'
133
+ | 'MICROSOFT'
134
+ | 'LINE'
135
+ | 'LINEAR'
136
+ | 'NOTION'
137
+ | 'TWITCH'
138
+ | 'GITHUB'
139
+ | 'BITBUCKET'
140
+ | 'ATLASSIAN'
141
+ | 'GITLAB'
142
+ | 'TRUE_CALLER';
143
+
144
+ export type OtplessDeviceFingerprintMode = 'NONE' | 'ASYNC' | 'SYNC';