@hawcx/react-native-sdk 1.0.8 → 1.1.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.
Files changed (134) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/HawcxReactNative.podspec +2 -2
  3. package/README.md +327 -109
  4. package/android/build.gradle +2 -2
  5. package/android/src/main/java/com/hawcx/reactnative/HawcxEventDispatcher.kt +4 -0
  6. package/android/src/main/java/com/hawcx/reactnative/HawcxReactNativeModule.kt +324 -1
  7. package/android/src/main/java/com/hawcx/reactnative/v6/HawcxV6Bridge.kt +402 -0
  8. package/ios/Frameworks/HawcxFramework.xcframework/Info.plist +5 -5
  9. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/HawcxFramework +0 -0
  10. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Info.plist +0 -0
  11. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.abi.json +22145 -2
  12. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.private.swiftinterface +628 -0
  13. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.swiftdoc +0 -0
  14. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios.swiftinterface +628 -0
  15. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/HawcxFramework +0 -0
  16. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Info.plist +0 -0
  17. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.abi.json +22145 -2
  18. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.private.swiftinterface +628 -0
  19. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.swiftdoc +0 -0
  20. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/arm64-apple-ios-simulator.swiftinterface +628 -0
  21. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.abi.json +22145 -2
  22. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.private.swiftinterface +628 -0
  23. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.swiftdoc +0 -0
  24. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/Modules/HawcxFramework.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +628 -0
  25. package/ios/Frameworks/HawcxFramework.xcframework/ios-arm64_x86_64-simulator/HawcxFramework.framework/_CodeSignature/CodeResources +21 -21
  26. package/ios/HawcxReactNative.m +56 -0
  27. package/ios/HawcxReactNative.swift +380 -1
  28. package/ios/HawcxV6BridgeSupport.swift +468 -0
  29. package/lib/commonjs/index.js +326 -3
  30. package/lib/commonjs/index.js.map +1 -1
  31. package/lib/commonjs/v6Normalization.js +325 -0
  32. package/lib/commonjs/v6Normalization.js.map +1 -0
  33. package/lib/commonjs/v6State.js +186 -0
  34. package/lib/commonjs/v6State.js.map +1 -0
  35. package/lib/commonjs/v6Types.js +2 -0
  36. package/lib/commonjs/v6Types.js.map +1 -0
  37. package/lib/commonjs/v6WebLogin.js +101 -0
  38. package/lib/commonjs/v6WebLogin.js.map +1 -0
  39. package/lib/module/index.js +287 -1
  40. package/lib/module/index.js.map +1 -1
  41. package/lib/module/v6Normalization.js +318 -0
  42. package/lib/module/v6Normalization.js.map +1 -0
  43. package/lib/module/v6State.js +173 -0
  44. package/lib/module/v6State.js.map +1 -0
  45. package/lib/module/v6Types.js +2 -0
  46. package/lib/module/v6Types.js.map +1 -0
  47. package/lib/module/v6WebLogin.js +92 -0
  48. package/lib/module/v6WebLogin.js.map +1 -0
  49. package/lib/typescript/index.d.ts +83 -0
  50. package/lib/typescript/index.d.ts.map +1 -1
  51. package/lib/typescript/v6Normalization.d.ts +3 -0
  52. package/lib/typescript/v6Normalization.d.ts.map +1 -0
  53. package/lib/typescript/v6State.d.ts +13 -0
  54. package/lib/typescript/v6State.d.ts.map +1 -0
  55. package/lib/typescript/v6Types.d.ts +157 -0
  56. package/lib/typescript/v6Types.d.ts.map +1 -0
  57. package/lib/typescript/v6WebLogin.d.ts +32 -0
  58. package/lib/typescript/v6WebLogin.d.ts.map +1 -0
  59. package/package.json +21 -9
  60. package/src/index.ts +477 -0
  61. package/src/v6Normalization.ts +356 -0
  62. package/src/v6State.ts +238 -0
  63. package/src/v6Types.ts +194 -0
  64. package/src/v6WebLogin.ts +154 -0
  65. package/android/.settings/org.eclipse.buildship.core.prefs +0 -2
  66. package/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  67. package/android/gradle/wrapper/gradle-wrapper.properties +0 -6
  68. package/android/gradlew +0 -185
  69. package/android/gradlew.bat +0 -89
  70. package/android/libs/hawcx-5.1.4.aar +0 -0
  71. package/docs/RELEASE.md +0 -129
  72. package/example/README.md +0 -59
  73. package/example/android/app/build.gradle +0 -126
  74. package/example/android/app/debug.keystore +0 -0
  75. package/example/android/app/proguard-rules.pro +0 -10
  76. package/example/android/app/src/debug/AndroidManifest.xml +0 -9
  77. package/example/android/app/src/main/AndroidManifest.xml +0 -27
  78. package/example/android/app/src/main/java/com/hawcx/example/MainActivity.kt +0 -22
  79. package/example/android/app/src/main/java/com/hawcx/example/MainApplication.kt +0 -45
  80. package/example/android/app/src/main/res/drawable/rn_edit_text_material.xml +0 -36
  81. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  82. package/example/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png +0 -0
  83. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  84. package/example/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png +0 -0
  85. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  86. package/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
  87. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  88. package/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
  89. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  90. package/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
  91. package/example/android/app/src/main/res/values/strings.xml +0 -3
  92. package/example/android/app/src/main/res/values/styles.xml +0 -9
  93. package/example/android/build.gradle +0 -35
  94. package/example/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  95. package/example/android/gradle/wrapper/gradle-wrapper.properties +0 -7
  96. package/example/android/gradle.properties +0 -41
  97. package/example/android/gradlew +0 -249
  98. package/example/android/gradlew.bat +0 -92
  99. package/example/android/local.properties +0 -2
  100. package/example/android/settings.gradle +0 -38
  101. package/example/app.json +0 -4
  102. package/example/babel.config.js +0 -3
  103. package/example/e2e/README.md +0 -17
  104. package/example/e2e/hawcx-login.yaml +0 -14
  105. package/example/index.js +0 -5
  106. package/example/ios/.xcode.env +0 -11
  107. package/example/ios/HawcxExampleApp/AppDelegate.h +0 -6
  108. package/example/ios/HawcxExampleApp/AppDelegate.mm +0 -31
  109. package/example/ios/HawcxExampleApp/Images.xcassets/AppIcon.appiconset/Contents.json +0 -53
  110. package/example/ios/HawcxExampleApp/Images.xcassets/Contents.json +0 -6
  111. package/example/ios/HawcxExampleApp/Info.plist +0 -55
  112. package/example/ios/HawcxExampleApp/LaunchScreen.storyboard +0 -47
  113. package/example/ios/HawcxExampleApp/PrivacyInfo.xcprivacy +0 -37
  114. package/example/ios/HawcxExampleApp/main.m +0 -10
  115. package/example/ios/HawcxExampleApp.xcodeproj/project.pbxproj +0 -704
  116. package/example/ios/HawcxExampleApp.xcodeproj/project.xcworkspace/xcuserdata/agambhullar.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  117. package/example/ios/HawcxExampleApp.xcodeproj/xcshareddata/xcschemes/HawcxExampleApp.xcscheme +0 -90
  118. package/example/ios/HawcxExampleApp.xcodeproj/xcuserdata/agambhullar.xcuserdatad/xcschemes/xcschememanagement.plist +0 -16
  119. package/example/ios/HawcxExampleApp.xcworkspace/contents.xcworkspacedata +0 -10
  120. package/example/ios/HawcxExampleAppTests/HawcxExampleAppTests.m +0 -66
  121. package/example/ios/HawcxExampleAppTests/Info.plist +0 -24
  122. package/example/ios/Podfile +0 -79
  123. package/example/ios/Podfile.lock +0 -1290
  124. package/example/metro.config.js +0 -16
  125. package/example/package-lock.json +0 -13220
  126. package/example/package.json +0 -30
  127. package/example/src/App.tsx +0 -755
  128. package/example/src/hawcx.config.ts +0 -25
  129. package/example/tsconfig.json +0 -8
  130. package/ios/Frameworks/.keep +0 -0
  131. package/lib/typescript/__tests__/index.test.d.ts +0 -2
  132. package/lib/typescript/__tests__/index.test.d.ts.map +0 -1
  133. package/react_mobile_sdk_plan.md +0 -242
  134. package/src/__tests__/index.test.ts +0 -206
@@ -6,19 +6,25 @@ import com.facebook.react.bridge.Arguments
6
6
  import com.facebook.react.bridge.Promise
7
7
  import com.facebook.react.bridge.ReactApplicationContext
8
8
  import com.facebook.react.bridge.ReactContextBaseJavaModule
9
+ import com.facebook.react.bridge.LifecycleEventListener
9
10
  import com.facebook.react.bridge.ReactMethod
10
11
  import com.facebook.react.bridge.ReadableMap
11
12
  import com.facebook.react.module.annotations.ReactModule
12
13
  import com.hawcx.internal.HawcxSDK
14
+ import com.hawcx.reactnative.v6.HawcxV6Bridge
15
+ import com.hawcx.reactnative.v6.HawcxV6InitializeOptions
16
+ import com.hawcx.reactnative.v6.HawcxV6StartOptions
13
17
  import com.hawcx.utils.AuthV5Callback
14
18
 
15
19
  internal const val AUTH_EVENT_NAME = "hawcx.auth.event"
16
20
  internal const val SESSION_EVENT_NAME = "hawcx.session.event"
17
21
  internal const val PUSH_EVENT_NAME = "hawcx.push.event"
22
+ internal const val V6_FLOW_EVENT_NAME = "hawcx.v6.flow.event"
18
23
 
19
24
  @ReactModule(name = HawcxReactNativeModule.NAME)
20
25
  class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
21
- ReactContextBaseJavaModule(reactContext) {
26
+ ReactContextBaseJavaModule(reactContext),
27
+ LifecycleEventListener {
22
28
 
23
29
  companion object {
24
30
  const val NAME = "HawcxReactNative"
@@ -41,6 +47,12 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
41
47
  private var sessionCallbackProxy: SessionCallbackProxy? = null
42
48
  @Volatile
43
49
  private var pushDelegateProxy: PushDelegateProxy? = null
50
+ @Volatile
51
+ private var hawcxV6Bridge: HawcxV6Bridge? = null
52
+
53
+ init {
54
+ reactContext.addLifecycleEventListener(this)
55
+ }
44
56
 
45
57
  override fun getName(): String = NAME
46
58
 
@@ -80,6 +92,7 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
80
92
 
81
93
  runOnUiThread {
82
94
  try {
95
+ resetNativeLanes(resetV6Flow = true)
83
96
  val sdk = HawcxSDK(
84
97
  context = applicationContext,
85
98
  projectApiKey = projectApiKey,
@@ -93,8 +106,16 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
93
106
  sessionCallbackProxy = sessionProxy
94
107
  pushDelegateProxy = pushProxy
95
108
  sdk.pushAuthDelegate = pushProxy
109
+ val v6Bridge = HawcxV6Bridge(eventDispatcher)
110
+ v6Bridge.configure(
111
+ legacySdk = sdk,
112
+ configId = projectApiKey,
113
+ options = HawcxV6InitializeOptions.from(configMap)
114
+ )
115
+ hawcxV6Bridge = v6Bridge
96
116
  promise.resolve(null)
97
117
  } catch (error: Exception) {
118
+ resetNativeLanes(resetV6Flow = true)
98
119
  promise.reject(CODE_SDK, error.message, error)
99
120
  }
100
121
  }
@@ -140,6 +161,260 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
140
161
  }
141
162
  }
142
163
 
164
+ @ReactMethod
165
+ fun v6Start(options: ReadableMap?, promise: Promise) {
166
+ val bridge = hawcxV6Bridge ?: run {
167
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
168
+ return
169
+ }
170
+ val config = options ?: run {
171
+ promise.reject(CODE_INPUT, "options are required")
172
+ return
173
+ }
174
+
175
+ val startOptions = runCatching { HawcxV6StartOptions.from(config) }
176
+ .getOrElse { error ->
177
+ promise.reject(CODE_INPUT, error.message, error)
178
+ return
179
+ }
180
+
181
+ runOnUiThread {
182
+ runCatching {
183
+ bridge.start(startOptions)
184
+ }.onSuccess {
185
+ promise.resolve(null)
186
+ }.onFailure { error ->
187
+ promise.reject(CODE_SDK, error.message, error)
188
+ }
189
+ }
190
+ }
191
+
192
+ @ReactMethod
193
+ fun v6SelectMethod(methodId: String?, promise: Promise) {
194
+ val bridge = hawcxV6Bridge ?: run {
195
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
196
+ return
197
+ }
198
+ val sanitizedMethodId = methodId?.trim().orEmpty()
199
+ if (sanitizedMethodId.isEmpty()) {
200
+ promise.reject(CODE_INPUT, "methodId is required")
201
+ return
202
+ }
203
+
204
+ runOnUiThread {
205
+ runCatching {
206
+ bridge.selectMethod(sanitizedMethodId)
207
+ }.onSuccess {
208
+ promise.resolve(null)
209
+ }.onFailure { error ->
210
+ promise.reject(CODE_SDK, error.message, error)
211
+ }
212
+ }
213
+ }
214
+
215
+ @ReactMethod
216
+ fun v6SubmitCode(code: String?, promise: Promise) {
217
+ val bridge = hawcxV6Bridge ?: run {
218
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
219
+ return
220
+ }
221
+ val sanitizedCode = code?.trim().orEmpty()
222
+ if (sanitizedCode.isEmpty()) {
223
+ promise.reject(CODE_INPUT, "code is required")
224
+ return
225
+ }
226
+
227
+ runOnUiThread {
228
+ runCatching {
229
+ bridge.submitCode(sanitizedCode)
230
+ }.onSuccess {
231
+ promise.resolve(null)
232
+ }.onFailure { error ->
233
+ promise.reject(CODE_SDK, error.message, error)
234
+ }
235
+ }
236
+ }
237
+
238
+ @ReactMethod
239
+ fun v6SubmitTotp(code: String?, promise: Promise) {
240
+ val bridge = hawcxV6Bridge ?: run {
241
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
242
+ return
243
+ }
244
+ val sanitizedCode = code?.trim().orEmpty()
245
+ if (sanitizedCode.isEmpty()) {
246
+ promise.reject(CODE_INPUT, "code is required")
247
+ return
248
+ }
249
+
250
+ runOnUiThread {
251
+ runCatching {
252
+ bridge.submitTotp(sanitizedCode)
253
+ }.onSuccess {
254
+ promise.resolve(null)
255
+ }.onFailure { error ->
256
+ promise.reject(CODE_SDK, error.message, error)
257
+ }
258
+ }
259
+ }
260
+
261
+ @ReactMethod
262
+ fun v6SubmitPhone(phone: String?, promise: Promise) {
263
+ val bridge = hawcxV6Bridge ?: run {
264
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
265
+ return
266
+ }
267
+ val sanitizedPhone = phone?.trim().orEmpty()
268
+ if (sanitizedPhone.isEmpty()) {
269
+ promise.reject(CODE_INPUT, "phone is required")
270
+ return
271
+ }
272
+
273
+ runOnUiThread {
274
+ runCatching {
275
+ bridge.submitPhone(sanitizedPhone)
276
+ }.onSuccess {
277
+ promise.resolve(null)
278
+ }.onFailure { error ->
279
+ promise.reject(CODE_SDK, error.message, error)
280
+ }
281
+ }
282
+ }
283
+
284
+ @ReactMethod
285
+ fun v6Resend(promise: Promise) {
286
+ val bridge = hawcxV6Bridge ?: run {
287
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
288
+ return
289
+ }
290
+
291
+ runOnUiThread {
292
+ runCatching {
293
+ bridge.resend()
294
+ }.onSuccess { dispatched ->
295
+ promise.resolve(dispatched)
296
+ }.onFailure { error ->
297
+ promise.reject(CODE_SDK, error.message, error)
298
+ }
299
+ }
300
+ }
301
+
302
+ @ReactMethod
303
+ fun v6Poll(promise: Promise) {
304
+ val bridge = hawcxV6Bridge ?: run {
305
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
306
+ return
307
+ }
308
+
309
+ runOnUiThread {
310
+ runCatching {
311
+ bridge.poll()
312
+ }.onSuccess {
313
+ promise.resolve(null)
314
+ }.onFailure { error ->
315
+ promise.reject(CODE_SDK, error.message, error)
316
+ }
317
+ }
318
+ }
319
+
320
+ @ReactMethod
321
+ fun v6Cancel(promise: Promise) {
322
+ val bridge = hawcxV6Bridge ?: run {
323
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
324
+ return
325
+ }
326
+
327
+ runOnUiThread {
328
+ runCatching {
329
+ bridge.cancel()
330
+ }.onSuccess {
331
+ promise.resolve(null)
332
+ }.onFailure { error ->
333
+ promise.reject(CODE_SDK, error.message, error)
334
+ }
335
+ }
336
+ }
337
+
338
+ @ReactMethod
339
+ fun v6Reset(promise: Promise) {
340
+ val bridge = hawcxV6Bridge ?: run {
341
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
342
+ return
343
+ }
344
+
345
+ runOnUiThread {
346
+ runCatching {
347
+ bridge.reset()
348
+ }.onSuccess {
349
+ promise.resolve(null)
350
+ }.onFailure { error ->
351
+ promise.reject(CODE_SDK, error.message, error)
352
+ }
353
+ }
354
+ }
355
+
356
+ @ReactMethod
357
+ fun v6ApproveQr(rawPayload: String?, identifier: String?, rememberDevice: Boolean, promise: Promise) {
358
+ val bridge = hawcxV6Bridge ?: run {
359
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
360
+ return
361
+ }
362
+ val sanitizedPayload = rawPayload?.trim().orEmpty()
363
+ if (sanitizedPayload.isEmpty()) {
364
+ promise.reject(CODE_INPUT, "rawPayload is required")
365
+ return
366
+ }
367
+
368
+ val sanitizedIdentifier = identifier?.trim().orEmpty()
369
+ if (sanitizedIdentifier.isEmpty()) {
370
+ promise.reject(CODE_INPUT, "identifier is required")
371
+ return
372
+ }
373
+
374
+ runOnUiThread {
375
+ bridge.approveQr(
376
+ rawPayload = sanitizedPayload,
377
+ identifier = sanitizedIdentifier,
378
+ rememberDevice = rememberDevice
379
+ ) { result ->
380
+ result.onSuccess { outcome ->
381
+ promise.resolve(
382
+ Arguments.createMap().apply {
383
+ putString("outcome", outcome.outcome)
384
+ putString("payloadType", outcome.payloadType)
385
+ outcome.userId?.takeIf { it.isNotBlank() }?.let { putString("userId", it) }
386
+ }
387
+ )
388
+ }.onFailure { error ->
389
+ promise.reject(CODE_SDK, error.message, error)
390
+ }
391
+ }
392
+ }
393
+ }
394
+
395
+ @ReactMethod
396
+ fun v6HandleRedirectUrl(url: String?, promise: Promise) {
397
+ val bridge = hawcxV6Bridge ?: run {
398
+ promise.reject(CODE_SDK, "initialize must be called before using V6 bridge methods")
399
+ return
400
+ }
401
+ val sanitizedUrl = url?.trim().orEmpty()
402
+ if (sanitizedUrl.isEmpty()) {
403
+ promise.reject(CODE_INPUT, "url is required")
404
+ return
405
+ }
406
+
407
+ runOnUiThread {
408
+ runCatching {
409
+ bridge.handleRedirectUrl(sanitizedUrl)
410
+ }.onSuccess {
411
+ promise.resolve(null)
412
+ }.onFailure { error ->
413
+ promise.reject(CODE_INPUT, error.message, error)
414
+ }
415
+ }
416
+ }
417
+
143
418
  @ReactMethod
144
419
  fun getDeviceDetails(promise: Promise) {
145
420
  val sdk = hawcxSDK ?: run {
@@ -260,6 +535,7 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
260
535
  }
261
536
 
262
537
  runOnUiThread {
538
+ resetV6FlowIfAvailable()
263
539
  sdk.clearSessionTokens(sanitizedUserId)
264
540
  promise.resolve(null)
265
541
  }
@@ -278,11 +554,25 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
278
554
  }
279
555
 
280
556
  runOnUiThread {
557
+ resetV6FlowIfAvailable()
281
558
  sdk.clearUserKeychainData(sanitizedUserId)
282
559
  promise.resolve(null)
283
560
  }
284
561
  }
285
562
 
563
+ @ReactMethod
564
+ fun clearLastLoggedInUser(promise: Promise) {
565
+ val sdk = hawcxSDK ?: run {
566
+ promise.reject(CODE_SDK, "initialize must be called before clearLastLoggedInUser")
567
+ return
568
+ }
569
+
570
+ runOnUiThread {
571
+ sdk.clearLastLoggedInUser()
572
+ promise.resolve(null)
573
+ }
574
+ }
575
+
286
576
  @ReactMethod
287
577
  fun setFcmToken(token: String?, promise: Promise) {
288
578
  val sdk = hawcxSDK ?: run {
@@ -384,4 +674,37 @@ class HawcxReactNativeModule(reactContext: ReactApplicationContext) :
384
674
  mainHandler.post(block)
385
675
  }
386
676
  }
677
+
678
+ private fun resetV6FlowIfAvailable() {
679
+ hawcxV6Bridge?.let { bridge ->
680
+ runCatching { bridge.reset() }
681
+ .onFailure { error ->
682
+ HawcxReactNativeLogger.w("Failed to reset V6 flow while clearing local state.", error)
683
+ }
684
+ }
685
+ }
686
+
687
+ override fun onHostResume() = Unit
688
+
689
+ override fun onHostPause() = Unit
690
+
691
+ override fun onHostDestroy() {
692
+ resetNativeLanes(resetV6Flow = true)
693
+ }
694
+
695
+ override fun invalidate() {
696
+ reactApplicationContext.removeLifecycleEventListener(this)
697
+ resetNativeLanes(resetV6Flow = true)
698
+ super.invalidate()
699
+ }
700
+
701
+ private fun resetNativeLanes(resetV6Flow: Boolean) {
702
+ hawcxV6Bridge?.dispose(resetFlow = resetV6Flow)
703
+ hawcxV6Bridge = null
704
+ hawcxSDK?.pushAuthDelegate = null
705
+ pushDelegateProxy = null
706
+ sessionCallbackProxy = null
707
+ authCallbackProxy = null
708
+ hawcxSDK = null
709
+ }
387
710
  }