uqudosdk-react-native 3.7.0 → 3.8.0-patch.1

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/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ ## 3.8.0
2
+
3
+ * New Document Support:
4
+ - Added support for Jordanian, Syrian, and Yemeni national IDs
5
+ * Android: Upgraded CameraX library to version 1.5.3. If your application also uses CameraX, you must upgrade to the same version. Please note that this version requires a minimum SDK level of 23, so starting from this release your application must set `minSdkVersion` to 23 in order to build successfully
6
+ * NFC: Added support for eID cards (ID-1 format) issued by countries that include a Machine Readable Zone (MRZ) on the back, comply with ICAO Doc 9303, and contain a contactless chip (ISO/IEC 14443 / NFC). This feature is available in the "Enrollment Flow" and "NFC / Reading Flow" using the document type GENERIC_ID or MRZ (when scanning only the back side). If a country is not supported, the NFC reading step is skipped according to the SDK’s default configuration
7
+ * Tampering Detection: The ID photo tampering detection model has been removed from the SDK, and disableTamperingRejection() is now a no-op
8
+ - What does this mean? From a tampering detection perspective, nothing changes, as all SDK checks continue to be performed on the server along with additional validations
9
+ - How am I impacted? There should be no impact if you follow best practices, specifically, validating SDK results on your side, including reviewing tampering detection scores
10
+ - For more information about this change, please contact support
11
+ * Miscellaneous: Minor bug fixes and improvements
12
+
13
+ ## 3.7.0-patch.1
14
+
15
+ * Resolved possible race condition that triggers a "java.lang.IllegalStateException: Must be called from main thread" on UI and theme updates
16
+
1
17
  ## 3.7.0
2
18
 
3
19
  * Introduced a new SDK feature that performs device attestation and returns the result within the SDK result object. The Device Attestation output must be actively parsed and evaluated in your backend as part of your core business logic. Each flag should be assessed based on your specific risk model and use case. While some attributes may require contextual evaluation depending on your fraud strategy and internal policies, others should be treated as immediate high-risk indicators. Please see "Device Attestation" for more details.
@@ -1,6 +1,6 @@
1
1
  def DEFAULT_COMPILE_SDK_VERSION = 34
2
2
  def DEFAULT_BUILD_TOOLS_VERSION = '30.0.3'
3
- def DEFAULT_MIN_SDK_VERSION = 21
3
+ def DEFAULT_MIN_SDK_VERSION = 23
4
4
  def DEFAULT_TARGET_SDK_VERSION = 34
5
5
 
6
6
  def safeExtGet(prop, fallback) {
@@ -34,5 +34,5 @@ android {
34
34
 
35
35
  dependencies {
36
36
  implementation 'com.facebook.react:react-native:+'
37
- implementation 'io.uqudo.sdk:Uqudo:3.7.0'
37
+ implementation 'io.uqudo.sdk:Uqudo:3.8.0'
38
38
  }
@@ -43,6 +43,8 @@ import io.uqudo.sdk.core.domain.model.ObfuscationType;
43
43
  import io.uqudo.sdk.core.domain.model.Document;
44
44
  import io.uqudo.sdk.core.domain.model.DocumentType;
45
45
  import io.uqudo.sdk.core.domain.model.LivenessGesture;
46
+ import com.facebook.react.bridge.UiThreadUtil;
47
+
46
48
  import java.text.SimpleDateFormat;
47
49
  import java.util.TimeZone;
48
50
 
@@ -129,7 +131,7 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
129
131
  if (json.has("sessionId")) {
130
132
  enrollment.setSessionId(json.getString("sessionId"));
131
133
  }
132
- if(json.has("isAllowNonPhysicalDocuments")){
134
+ if (json.has("isAllowNonPhysicalDocuments")) {
133
135
  enrollment.allowNonPhysicalDocuments();
134
136
  }
135
137
  if (json.has("isDisableTamperingRejection")) {
@@ -159,12 +161,12 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
159
161
  if (faceObject.has("allowClosedEyes") && faceObject.getBoolean("allowClosedEyes")) {
160
162
  faceBuilder.allowClosedEyes();
161
163
  }
162
- if (faceObject.has("obfuscationType")){
163
- if (faceObject.getString("obfuscationType").equals("FILLED")){
164
+ if (faceObject.has("obfuscationType")) {
165
+ if (faceObject.getString("obfuscationType").equals("FILLED")) {
164
166
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
165
- } else if (faceObject.getString("obfuscationType").equals("BLURRED")){
167
+ } else if (faceObject.getString("obfuscationType").equals("BLURRED")) {
166
168
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
167
- } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")){
169
+ } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")) {
168
170
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
169
171
  }
170
172
  }
@@ -172,7 +174,7 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
172
174
  if (faceObject.has("isOneToNVerificationEnabled") && faceObject.getBoolean("isOneToNVerificationEnabled")) {
173
175
  faceBuilder.enableOneToNVerification();
174
176
  }
175
-
177
+
176
178
  if (faceObject.has("enableActiveLiveness") && faceObject.getBoolean("enableActiveLiveness")) {
177
179
  LivenessGesture disableGesture = null;
178
180
  if (faceObject.has("disableLivenessGesture")) {
@@ -281,20 +283,25 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
281
283
  Document document = documentBuilder.build();
282
284
  enrollment.add(document);
283
285
  }
284
- Intent intent = enrollment.build(context);
285
- if (json.has("appearanceMode")) {
286
- if ("LIGHT".equals(json.getString("appearanceMode"))) {
287
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
288
- } else if ("DARK".equals(json.getString("appearanceMode"))) {
289
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
290
- } else if ("SYSTEM".equals(json.getString("appearanceMode"))) {
291
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
286
+ final Intent intent = enrollment.build(context);
287
+ UiThreadUtil.runOnUiThread(new Runnable() {
288
+ @Override
289
+ public void run() {
290
+ try {
291
+ handleAppearanceMode(json);
292
+ Activity currentActivity = getCurrentActivity();
293
+ if (currentActivity != null) {
294
+ mPromises.put(REQUEST_CODE_ENROLLMENT, promise);
295
+ currentActivity.startActivityForResult(intent, REQUEST_CODE_ENROLLMENT);
296
+ } else {
297
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(),
298
+ "The operation could not start because the app is in the background or the activity is unavailable.", null);
299
+ }
300
+ } catch (Exception e) {
301
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
302
+ }
292
303
  }
293
- } else {
294
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
295
- }
296
- getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE_ENROLLMENT, null);
297
- mPromises.put(REQUEST_CODE_ENROLLMENT, promise);
304
+ });
298
305
  } catch (Exception e) {
299
306
  Log.e("UqudoIdModule", e.getMessage(), e);
300
307
  sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
@@ -330,21 +337,26 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
330
337
  if (json.has("isReturnDataForIncompleteSession") && json.getBoolean("isReturnDataForIncompleteSession")) {
331
338
  recovery.returnDataForIncompleteSession();
332
339
  }
333
- Intent intent = recovery.build(context);
334
-
335
- if (json.has("appearanceMode")) {
336
- if ("LIGHT".equals(json.getString("appearanceMode"))) {
337
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
338
- } else if ("DARK".equals(json.getString("appearanceMode"))) {
339
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
340
- } else if ("SYSTEM".equals(json.getString("appearanceMode"))) {
341
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
340
+ final Intent intent = recovery.build(context);
341
+
342
+ UiThreadUtil.runOnUiThread(new Runnable() {
343
+ @Override
344
+ public void run() {
345
+ try {
346
+ handleAppearanceMode(json);
347
+ Activity currentActivity = getCurrentActivity();
348
+ if (currentActivity != null) {
349
+ mPromises.put(REQUEST_CODE_ACCOUNT_RECOVERY, promise);
350
+ currentActivity.startActivityForResult(intent, REQUEST_CODE_ACCOUNT_RECOVERY);
351
+ } else {
352
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(),
353
+ "The operation could not start because the app is in the background or the activity is unavailable.", null);
354
+ }
355
+ } catch (Exception e) {
356
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
357
+ }
342
358
  }
343
- } else {
344
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
345
- }
346
- getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE_ACCOUNT_RECOVERY, null);
347
- mPromises.put(REQUEST_CODE_ACCOUNT_RECOVERY, promise);
359
+ });
348
360
  } catch (Exception e) {
349
361
  Log.e("UqudoIdModule", e.getMessage(), e);
350
362
  sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
@@ -383,12 +395,12 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
383
395
  if (json.has("isReturnDataForIncompleteSession") && json.getBoolean("isReturnDataForIncompleteSession")) {
384
396
  faceSession.returnDataForIncompleteSession();
385
397
  }
386
- if (json.has("obfuscationType")){
387
- if (json.getString("obfuscationType").equals("FILLED")){
398
+ if (json.has("obfuscationType")) {
399
+ if (json.getString("obfuscationType").equals("FILLED")) {
388
400
  faceSession.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
389
- } else if (json.getString("obfuscationType").equals("BLURRED")){
401
+ } else if (json.getString("obfuscationType").equals("BLURRED")) {
390
402
  faceSession.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
391
- } else if (json.getString("obfuscationType").equals("FILLED_WHITE")){
403
+ } else if (json.getString("obfuscationType").equals("FILLED_WHITE")) {
392
404
  faceSession.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
393
405
  }
394
406
  }
@@ -400,20 +412,26 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
400
412
  faceSession.enableActiveLiveness(null);
401
413
  }
402
414
  }
403
- Intent intent = faceSession.build(context);
404
- if (json.has("appearanceMode")) {
405
- if ("LIGHT".equals(json.getString("appearanceMode"))) {
406
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
407
- } else if ("DARK".equals(json.getString("appearanceMode"))) {
408
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
409
- } else if ("SYSTEM".equals(json.getString("appearanceMode"))) {
410
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
415
+ final Intent intent = faceSession.build(context);
416
+
417
+ UiThreadUtil.runOnUiThread(new Runnable() {
418
+ @Override
419
+ public void run() {
420
+ try {
421
+ handleAppearanceMode(json);
422
+ Activity currentActivity = getCurrentActivity();
423
+ if (currentActivity != null) {
424
+ mPromises.put(REQUEST_CODE_FACE_SESSION, promise);
425
+ currentActivity.startActivityForResult(intent, REQUEST_CODE_FACE_SESSION);
426
+ } else {
427
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(),
428
+ "The operation could not start because the app is in the background or the activity is unavailable.", null);
429
+ }
430
+ } catch (Exception e) {
431
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
432
+ }
411
433
  }
412
- } else {
413
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
414
- }
415
- getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE_FACE_SESSION, null);
416
- mPromises.put(REQUEST_CODE_FACE_SESSION, promise);
434
+ });
417
435
  } catch (Exception e) {
418
436
  Log.e("UqudoIdModule", e.getMessage(), e);
419
437
  sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
@@ -459,12 +477,12 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
459
477
  if (faceObject.has("allowClosedEyes") && faceObject.getBoolean("allowClosedEyes")) {
460
478
  faceBuilder.allowClosedEyes();
461
479
  }
462
- if (faceObject.has("obfuscationType")){
463
- if (faceObject.getString("obfuscationType").equals("FILLED")){
480
+ if (faceObject.has("obfuscationType")) {
481
+ if (faceObject.getString("obfuscationType").equals("FILLED")) {
464
482
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
465
- } else if (faceObject.getString("obfuscationType").equals("BLURRED")){
483
+ } else if (faceObject.getString("obfuscationType").equals("BLURRED")) {
466
484
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
467
- } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")){
485
+ } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")) {
468
486
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
469
487
  }
470
488
  }
@@ -472,7 +490,7 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
472
490
  if (faceObject.has("isOneToNVerificationEnabled") && faceObject.getBoolean("isOneToNVerificationEnabled")) {
473
491
  faceBuilder.enableOneToNVerification();
474
492
  }
475
-
493
+
476
494
  if (faceObject.has("enableActiveLiveness") && faceObject.getBoolean("enableActiveLiveness")) {
477
495
  LivenessGesture disableGesture = null;
478
496
  if (faceObject.has("disableLivenessGesture")) {
@@ -512,20 +530,27 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
512
530
  }
513
531
  lookupBuilder.setToken(json.getString("authorizationToken"));
514
532
  lookupBuilder.setDocumentType(DocumentType.valueOf(json.getString("documentType")));
515
- Intent intent = lookupBuilder.build(context);
516
- if (json.has("appearanceMode")) {
517
- if ("LIGHT".equals(json.getString("appearanceMode"))) {
518
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
519
- } else if ("DARK".equals(json.getString("appearanceMode"))) {
520
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
521
- } else if ("SYSTEM".equals(json.getString("appearanceMode"))) {
522
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
523
- }
524
- } else {
525
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
526
- }
527
- getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE_LOOKUP, null);
528
- mPromises.put(REQUEST_CODE_LOOKUP, promise);
533
+
534
+ final Intent intent = lookupBuilder.build(context);
535
+
536
+ UiThreadUtil.runOnUiThread(new Runnable() {
537
+ @Override
538
+ public void run() {
539
+ try {
540
+ handleAppearanceMode(json);
541
+ Activity currentActivity = getCurrentActivity();
542
+ if (currentActivity != null) {
543
+ mPromises.put(REQUEST_CODE_LOOKUP, promise);
544
+ currentActivity.startActivityForResult(intent, REQUEST_CODE_LOOKUP);
545
+ } else {
546
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(),
547
+ "The operation could not start because the app is in the background or the activity is unavailable.", null);
548
+ }
549
+ } catch (Exception e) {
550
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
551
+ }
552
+ }
553
+ });
529
554
  } catch (Exception e) {
530
555
  Log.e("UqudoIdModule", e.getMessage(), e);
531
556
  sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
@@ -579,58 +604,58 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
579
604
  sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), "Expected valid document type as argument", null);
580
605
  }
581
606
  }
582
-
607
+
583
608
  @ReactMethod
584
609
  public void reading(String message, Promise promise) {
585
610
  if (message != null && message.length() > 0) {
586
611
  try {
587
612
  JSONObject json = new JSONObject(message);
588
613
  UqudoBuilder.Reading readingBuilder = new UqudoBuilder.Reading();
589
-
614
+
590
615
  if (json.has("authorizationToken")) {
591
616
  readingBuilder.setToken(json.getString("authorizationToken"));
592
617
  }
593
-
618
+
594
619
  if (json.has("sessionId")) {
595
620
  readingBuilder.setSessionId(json.getString("sessionId"));
596
621
  }
597
-
622
+
598
623
  if (json.has("userIdentifier")) {
599
624
  readingBuilder.setUserIdentifier(UUID.fromString(json.getString("userIdentifier")));
600
625
  }
601
-
626
+
602
627
  if (json.has("nonce")) {
603
628
  readingBuilder.setNonce(json.getString("nonce"));
604
629
  }
605
-
630
+
606
631
  if (json.has("documentType")) {
607
632
  readingBuilder.setDocumentType(DocumentType.valueOf(json.getString("documentType")));
608
633
  }
609
-
634
+
610
635
  if (json.has("documentNumber")) {
611
636
  readingBuilder.setDocumentNumber(json.getString("documentNumber"));
612
637
  }
613
-
638
+
614
639
  if (json.has("dateOfBirth")) {
615
640
  readingBuilder.setDateOfBirth(json.getString("dateOfBirth"));
616
641
  }
617
-
642
+
618
643
  if (json.has("dateOfExpiry")) {
619
644
  readingBuilder.setDateOfExpiry(json.getString("dateOfExpiry"));
620
645
  }
621
-
646
+
622
647
  if (json.has("mrz")) {
623
648
  readingBuilder.setMRZ(json.getString("mrz"));
624
649
  }
625
-
650
+
626
651
  if (json.has("isReturnDataForIncompleteSession") && json.getBoolean("isReturnDataForIncompleteSession")) {
627
652
  readingBuilder.returnDataForIncompleteSession();
628
653
  }
629
-
654
+
630
655
  if (json.has("isSecuredWindowsDisabled") && json.getBoolean("isSecuredWindowsDisabled")) {
631
656
  readingBuilder.disableSecureWindow();
632
657
  }
633
-
658
+
634
659
  if (json.has("facialRecognitionSpecification")) {
635
660
  FacialRecognitionConfigurationBuilder faceBuilder = new FacialRecognitionConfigurationBuilder();
636
661
  JSONObject faceObject = json.getJSONObject("facialRecognitionSpecification");
@@ -652,12 +677,12 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
652
677
  if (faceObject.has("allowClosedEyes") && faceObject.getBoolean("allowClosedEyes")) {
653
678
  faceBuilder.allowClosedEyes();
654
679
  }
655
- if (faceObject.has("obfuscationType")){
656
- if (faceObject.getString("obfuscationType").equals("FILLED")){
680
+ if (faceObject.has("obfuscationType")) {
681
+ if (faceObject.getString("obfuscationType").equals("FILLED")) {
657
682
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
658
- } else if (faceObject.getString("obfuscationType").equals("BLURRED")){
683
+ } else if (faceObject.getString("obfuscationType").equals("BLURRED")) {
659
684
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
660
- } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")){
685
+ } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")) {
661
686
  faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
662
687
  }
663
688
  }
@@ -665,7 +690,7 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
665
690
  if (faceObject.has("isOneToNVerificationEnabled") && faceObject.getBoolean("isOneToNVerificationEnabled")) {
666
691
  faceBuilder.enableOneToNVerification();
667
692
  }
668
-
693
+
669
694
  if (faceObject.has("enableActiveLiveness") && faceObject.getBoolean("enableActiveLiveness")) {
670
695
  LivenessGesture disableGesture = null;
671
696
  if (faceObject.has("disableLivenessGesture")) {
@@ -687,7 +712,7 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
687
712
 
688
713
  readingBuilder.enableFacialRecognition(faceBuilder.build());
689
714
  }
690
-
715
+
691
716
  if (json.has("backgroundCheckConfiguration")) {
692
717
  BackgroundCheckConfigurationBuilder backgroundCheckConfigurationBuilder = new BackgroundCheckConfigurationBuilder();
693
718
  JSONObject backgroundObject = json.getJSONObject("backgroundCheckConfiguration");
@@ -705,25 +730,31 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
705
730
  }
706
731
  readingBuilder.enableBackgroundCheck(backgroundCheckConfigurationBuilder.build());
707
732
  }
708
-
733
+
709
734
  if (json.has("isLookupEnabled") && json.getBoolean("isLookupEnabled")) {
710
735
  readingBuilder.enableLookup();
711
736
  }
712
-
713
- Intent intent = readingBuilder.build(context);
714
- if (json.has("appearanceMode")) {
715
- if ("LIGHT".equals(json.getString("appearanceMode"))) {
716
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
717
- } else if ("DARK".equals(json.getString("appearanceMode"))) {
718
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
719
- } else if ("SYSTEM".equals(json.getString("appearanceMode"))) {
720
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
721
- }
722
- } else {
723
- AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
724
- }
725
- getReactApplicationContext().startActivityForResult(intent, REQUEST_CODE_READING, null);
726
- mPromises.put(REQUEST_CODE_READING, promise);
737
+
738
+ final Intent intent = readingBuilder.build(context);
739
+
740
+ UiThreadUtil.runOnUiThread(new Runnable() {
741
+ @Override
742
+ public void run() {
743
+ try {
744
+ handleAppearanceMode(json);
745
+ Activity currentActivity = getCurrentActivity();
746
+ if (currentActivity != null) {
747
+ mPromises.put(REQUEST_CODE_READING, promise);
748
+ currentActivity.startActivityForResult(intent, REQUEST_CODE_READING);
749
+ } else {
750
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(),
751
+ "The operation could not start because the app is in the background or the activity is unavailable.", null);
752
+ }
753
+ } catch (Exception e) {
754
+ sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
755
+ }
756
+ }
757
+ });
727
758
  } catch (Exception e) {
728
759
  Log.e("UqudoIdModule", e.getMessage(), e);
729
760
  sendError(promise, SessionStatusCode.UNEXPECTED_ERROR.name(), e.getMessage(), null);
@@ -775,4 +806,23 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
775
806
  public void onNewIntent(Intent intent) {
776
807
 
777
808
  }
809
+
810
+ /**
811
+ * Helper method to consolidate appearance mode logic on the UI thread.
812
+ */
813
+ private void handleAppearanceMode(JSONObject json) throws JSONException {
814
+ if (json.has("appearanceMode")) {
815
+ String mode = json.getString("appearanceMode");
816
+ if ("LIGHT".equals(mode)) {
817
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
818
+ } else if ("DARK".equals(mode)) {
819
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
820
+ } else if ("SYSTEM".equals(mode)) {
821
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
822
+ }
823
+ } else {
824
+ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM);
825
+ }
826
+ }
827
+
778
828
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "uqudosdk-react-native",
3
3
  "title": "React Native UqudoId",
4
- "version": "3.7.0",
4
+ "version": "3.8.0-patch.1",
5
5
  "description": "Uqudo SDK react native module",
6
6
  "main": "index.js",
7
7
  "author": {
@@ -133,7 +133,10 @@ export const DocumentType = Object.freeze(
133
133
  QAT_ID_RESIDENT: 'QAT_ID_RESIDENT',
134
134
  KWT_ID_NATIONAL: 'KWT_ID_NATIONAL',
135
135
  KWT_ID_RESIDENT: 'KWT_ID_RESIDENT',
136
- MAR_ID: 'MAR_ID'
136
+ MAR_ID: 'MAR_ID',
137
+ YEM_ID: 'YEM_ID',
138
+ JOR_ID: 'JOR_ID',
139
+ SYR_ID: 'SYR_ID'
137
140
  }
138
141
  );
139
142
 
@@ -14,5 +14,5 @@ Pod::Spec.new do |s|
14
14
  s.source_files = "ios/**/*.{h,m,mm,swift}"
15
15
  s.public_header_files = "ios/Uqudold.h"
16
16
  s.dependency "React"
17
- s.dependency "UqudoSDK", "3.7.0"
17
+ s.dependency "UqudoSDK", "3.8.0"
18
18
  end