uqudosdk-react-native 2.7.4 → 3.0.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,40 @@
1
+ ## 3.0.1
2
+
3
+ * Important improvement in the id photo tampering detection during document scanning to identify any alterations to the ID photo.
4
+ * Reduced the level of sensitivity for detecting glares during document scanning.
5
+ * Small improvement during scanning to identify printed copies. As per our previous release, the SDK will not reject scans of printed documents but will provide a score indicating the likelihood of a printed copy under the verification object in the SDK result.
6
+ * Included a new obfuscation type called "FILLED_WHITE" within the facial recognition configuration, which completely substitutes the background with a white color.
7
+ * Introduced a new configuration option called "disableTamperingRejection", directing the SDK not to dismiss the scan upon detecting tampering, specifically for ID photo tampering detection.
8
+ * Deprecated the configuration option called "enrollFace" within the facial recognition configuration, as it is related to the "Account Recovery Flow" deprecated in version 3.0.0. It is planned for removal in a future release.
9
+ * Android: upgraded the camera library to the latest stable version that fixes an important bug that could affect the scan on Samsung A24 devices.
10
+ * iOS: Addressed an issue on iPhone 14 and iPhone 15 base version where the camera failed to focus when documents were in close proximity.
11
+ * iOS: Refactored the implementation to identify whether the device has been rooted.
12
+
13
+ ## 3.0.0
14
+
15
+ * Introduced a new verification object result within the SDK, including all details pertinent to the verification process. This feature supports your business logic by easily identifying potential issues. Refer to https://docs.uqudo.com/docs/kyc/uqudo-sdk/sdk-result/data-structure/verification-object for comprehensive information.
16
+ * Added Data Consistency Check within the verification object, supporting your business logic by highlighting inconsistencies throughout the entire KYC journey, including optical scanning, NFC, and lookup stages.
17
+ * Added source detection during document scanning to ensure that users display physical documents, eliminating screens and printed copies. In this release, the SDK will not reject scans of printed documents but will provide a score indicating the likelihood of a printed copy under the verification object in the SDK result. Please note that low-light conditions may affect the result, potentially increasing the score for printed copies and leading to false positives. We are committed to improving this aspect in future releases, refining quality check procedures to ensure optimal image quality. Eventually, printed documents above a certain score will be rejected directly from the SDK, similar to how screens are handled.
18
+ * Added an option to permit scanning of non-physical documents (where the SDK won't reject scans upon detecting a screen). The SDK result includes a score indicating whether the document was scanned from a screen, as described in the verification object above.
19
+ * Added ID photo tampering detection during document scanning to identify any alterations to the ID photo. The SDK will reject scans above a certain score and provide an appropriate message. Score information is returned in the SDK result within the verification object.
20
+ * Enhanced identification of low-light conditions during document scanning by introducing stricter criteria. Suboptimal lighting can affect document recognition, particularly for non-physical documents.
21
+ * Improved scanning capabilities for Turkish IDs.
22
+ * Added NFC support for the latest version of the QAT ID for residents.
23
+ * Added NFC support for IRQ ID.
24
+ * Added support for passport chip authentication during NFC reading.
25
+ * Implemented countermeasures for NFC replay attacks on documents lacking authentication mechanisms.
26
+ * Addressed an issue on iPhone 14 Pro/Pro Max and iPhone 15 Pro/Pro Max where the camera failed to focus when documents were in close proximity.
27
+ * Resolved an issue where a specific version of the QAT ID's back side for citizens was not being recognized.
28
+ * In the Lookup Flow, removed NGA virtual NIN in favor of the actual NIN (National Identification Number) written on the document, as the virtual NIN service has been suspended by the Nigerian government.
29
+ * Overall enhancements to the scanning process to improve scan quality.
30
+ * Backported the latest changes from SDK version 2.7.4.
31
+ * For Android application development, targeting SDK 34 is now mandatory.
32
+ * Deprecated the enableUpload feature in the SDK, planned for removal in a future release.
33
+ * Deprecated the forceReadingIfSupported function in the ReadingConfiguration builder and made it the default behavior, eliminating the option to skip the reading step (NFC) unless the device lacks NFC support. The forceReading option remains available for those wishing to restrict usage to devices with NFC support only.
34
+ * Deprecated the forceReadingTimeout function in the ReadingConfiguration, making it a no-op operation.
35
+ * Deprecated the Account Recovery Flow feature in the SDK, planned for removal in a future release. Use Face Session Flow instead.
36
+ * Various minor bug fixes and improvements.
37
+
1
38
  ## 2.7.4
2
39
 
3
40
  * Added compatibility for applications designed to target targetSdk version 34 on the Android platform
@@ -1,7 +1,7 @@
1
- def DEFAULT_COMPILE_SDK_VERSION = 33
1
+ def DEFAULT_COMPILE_SDK_VERSION = 34
2
2
  def DEFAULT_BUILD_TOOLS_VERSION = '30.0.3'
3
3
  def DEFAULT_MIN_SDK_VERSION = 21
4
- def DEFAULT_TARGET_SDK_VERSION = 33
4
+ def DEFAULT_TARGET_SDK_VERSION = 34
5
5
 
6
6
  def safeExtGet(prop, fallback) {
7
7
  rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
@@ -33,5 +33,5 @@ android {
33
33
 
34
34
  dependencies {
35
35
  implementation 'com.facebook.react:react-native:+'
36
- implementation 'io.uqudo.sdk:Uqudo:2.7.4'
36
+ implementation 'io.uqudo.sdk:Uqudo:3.0.1'
37
37
  }
@@ -39,6 +39,7 @@ import io.uqudo.sdk.core.builder.BackgroundCheckConfigurationBuilder;
39
39
  import io.uqudo.sdk.core.builder.FacialRecognitionConfigurationBuilder;
40
40
  import io.uqudo.sdk.core.builder.ReadingConfigurationBuilder;
41
41
  import io.uqudo.sdk.core.domain.model.BackgroundCheckType;
42
+ import io.uqudo.sdk.core.domain.model.ObfuscationType;
42
43
  import io.uqudo.sdk.core.domain.model.Document;
43
44
  import io.uqudo.sdk.core.domain.model.DocumentType;
44
45
  import java.text.SimpleDateFormat;
@@ -126,6 +127,12 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
126
127
  if (json.has("sessionId")) {
127
128
  enrollment.setSessionId(json.getString("sessionId"));
128
129
  }
130
+ if(json.has("isAllowNonPhysicalDocuments")){
131
+ enrollment.allowNonPhysicalDocuments();
132
+ }
133
+ if (json.has("isDisableTamperingRejection")) {
134
+ enrollment.disableTamperingRejection();
135
+ }
129
136
  if (json.has("userIdentifier")) {
130
137
  enrollment.setUserIdentifier(UUID.fromString(json.getString("userIdentifier")));
131
138
  }
@@ -150,6 +157,15 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
150
157
  if (faceObject.has("allowClosedEyes") && faceObject.getBoolean("allowClosedEyes")) {
151
158
  faceBuilder.allowClosedEyes();
152
159
  }
160
+ if (faceObject.has("obfuscationType")){
161
+ if (faceObject.getString("obfuscationType").equals("FILLED")){
162
+ faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
163
+ } else if (faceObject.getString("obfuscationType").equals("BLURRED")){
164
+ faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
165
+ } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")){
166
+ faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
167
+ }
168
+ }
153
169
  enrollment.enableFacialRecognition(faceBuilder.build());
154
170
  }
155
171
  if (json.has("lookupConfiguration")) {
@@ -338,6 +354,15 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
338
354
  if (json.has("isReturnDataForIncompleteSession") && json.getBoolean("isReturnDataForIncompleteSession")) {
339
355
  faceSession.returnDataForIncompleteSession();
340
356
  }
357
+ if (json.has("obfuscationType")){
358
+ if (json.getString("obfuscationType").equals("FILLED")){
359
+ faceSession.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
360
+ } else if (json.getString("obfuscationType").equals("BLURRED")){
361
+ faceSession.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
362
+ } else if (json.getString("obfuscationType").equals("FILLED_WHITE")){
363
+ faceSession.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
364
+ }
365
+ }
341
366
  Intent intent = faceSession.build(context);
342
367
  if (json.has("appearanceMode")) {
343
368
  if ("LIGHT".equals(json.getString("appearanceMode"))) {
@@ -397,6 +422,15 @@ public class UqudoIdModule extends ReactContextBaseJavaModule implements Activit
397
422
  if (faceObject.has("allowClosedEyes") && faceObject.getBoolean("allowClosedEyes")) {
398
423
  faceBuilder.allowClosedEyes();
399
424
  }
425
+ if (faceObject.has("obfuscationType")){
426
+ if (faceObject.getString("obfuscationType").equals("FILLED")){
427
+ faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED);
428
+ } else if (faceObject.getString("obfuscationType").equals("BLURRED")){
429
+ faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.BLURRED);
430
+ } else if (faceObject.getString("obfuscationType").equals("FILLED_WHITE")){
431
+ faceBuilder.enableAuditTrailImageObfuscation(ObfuscationType.FILLED_WHITE);
432
+ }
433
+ }
400
434
  lookupBuilder.enableFacialRecognition(faceBuilder.build());
401
435
  }
402
436
  if (json.has("backgroundCheckConfiguration")) {
package/ios/UqudoId.m CHANGED
@@ -58,6 +58,12 @@ RCT_EXPORT_METHOD(enroll:(NSString *)enrollObj resolver:(RCTPromiseResolveBlock)
58
58
  if (json[@"isReturnDataForIncompleteSession"]) {
59
59
  enrollmentBuilder.returnDataForIncompleteSession = [[json valueForKey:@"isReturnDataForIncompleteSession"] boolValue];
60
60
  }
61
+ if(json[@"isAllowNonPhysicalDocuments"]){
62
+ enrollmentBuilder.allowNonPhysicalDocuments = [[json valueForKey:@"isAllowNonPhysicalDocuments"] boolValue];
63
+ }
64
+ if (json[@"isDisableTamperingRejection"]) {
65
+ enrollmentBuilder.disableTamperingRejection = [[json valueForKey:@"isDisableTamperingRejection"] boolValue];
66
+ }
61
67
  if (facialRecognitionSpecification) {
62
68
  // Enable help page for face recognition
63
69
  UQFacialRecognitionConfig *config = [[UQFacialRecognitionConfig alloc] init];
@@ -84,6 +90,15 @@ RCT_EXPORT_METHOD(enroll:(NSString *)enrollObj resolver:(RCTPromiseResolveBlock)
84
90
  if (facialRecognitionSpecification[@"allowClosedEyes"]) {
85
91
  config.allowClosedEyes = [[facialRecognitionSpecification valueForKey:@"allowClosedEyes"] boolValue];
86
92
  }
93
+ if (facialRecognitionSpecification[@"obfuscationType"]) {
94
+ if ([facialRecognitionSpecification[@"obfuscationType"] isEqualToString:@"BLURRED"]) {
95
+ config.obfuscationType = BLURRED;
96
+ } else if ([facialRecognitionSpecification[@"obfuscationType"] isEqualToString:@"FILLED"]) {
97
+ config.obfuscationType = FILLED;
98
+ } else if ([facialRecognitionSpecification[@"obfuscationType"] isEqualToString:@"FILLED_WHITE"]) {
99
+ config.obfuscationType = FILLED_WHITE;
100
+ }
101
+ }
87
102
  enrollmentBuilder.facialRecognitionConfig = config;
88
103
  }
89
104
 
@@ -355,6 +370,16 @@ RCT_EXPORT_METHOD(faceSession:(NSString *)configuration resolver:(RCTPromiseReso
355
370
  if (json[@"isReturnDataForIncompleteSession"]) {
356
371
  faceSessionBuilder.returnDataForIncompleteSession = [[json valueForKey:@"isReturnDataForIncompleteSession"] boolValue];
357
372
  }
373
+ if (json[@"obfuscationType"]) {
374
+ if ([json[@"obfuscationType"] isEqualToString:@"BLURRED"]) {
375
+ [faceSessionBuilder enableAuditTrailImageObfuscation:BLURRED];
376
+ } else if ([json[@"obfuscationType"] isEqualToString:@"FILLED"]) {
377
+ [faceSessionBuilder enableAuditTrailImageObfuscation:FILLED];
378
+ } else if ([json[@"obfuscationType"] isEqualToString:@"FILLED_WHITE"]) {
379
+ [faceSessionBuilder enableAuditTrailImageObfuscation:FILLED_WHITE];
380
+ }
381
+ }
382
+
358
383
  builderController.delegate = self;
359
384
  UIViewController *rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
360
385
  builderController.appViewController = rootViewController;
@@ -459,6 +484,15 @@ RCT_EXPORT_METHOD(lookup:(NSString *)lookupObj resolver:(RCTPromiseResolveBlock)
459
484
  if (facialRecognitionSpecification[@"allowClosedEyes"]) {
460
485
  config.allowClosedEyes = [[facialRecognitionSpecification valueForKey:@"allowClosedEyes"] boolValue];
461
486
  }
487
+ if (facialRecognitionSpecification[@"obfuscationType"]) {
488
+ if ([facialRecognitionSpecification[@"obfuscationType"] isEqualToString:@"BLURRED"]) {
489
+ config.obfuscationType = BLURRED;
490
+ } else if ([facialRecognitionSpecification[@"obfuscationType"] isEqualToString:@"FILLED"]) {
491
+ config.obfuscationType = FILLED;
492
+ } else if ([facialRecognitionSpecification[@"obfuscationType"] isEqualToString:@"FILLED_WHITE"]) {
493
+ config.obfuscationType = FILLED_WHITE;
494
+ }
495
+ }
462
496
  lookupBuilder.facialRecognitionConfig = config;
463
497
 
464
498
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "uqudosdk-react-native",
3
3
  "title": "React Native UqudoId",
4
- "version": "2.7.4",
4
+ "version": "3.0.1",
5
5
  "description": "Uqudo SDK react native module",
6
6
  "main": "index.js",
7
7
  "author": {
@@ -131,10 +131,18 @@ export const AppearanceMode = Object.freeze(
131
131
  }
132
132
  );
133
133
 
134
+ export const ObfuscationType = Object.freeze(
135
+ {
136
+ FILLED: 'FILLED',
137
+ BLURRED: 'BLURRED',
138
+ FILLED_WHITE: 'FILLED_WHITE'
139
+ }
140
+ );
141
+
134
142
  export class Enrollment {
135
143
  constructor(documentList, authorizationToken, nonce,
136
144
  isRootedDeviceAllowed, isSecuredWindowsDisabled, facialRecognitionSpecification,
137
- backgroundCheckConfiguration, lookupConfiguration, sessionId, userIdentifier, isReturnDataForIncompleteSession, appearanceMode) {
145
+ backgroundCheckConfiguration, lookupConfiguration, sessionId, userIdentifier, isReturnDataForIncompleteSession, appearanceMode,isAllowNonPhysicalDocuments,isDisableTamperingRejection) {
138
146
  this.documentList = documentList;
139
147
  this.authorizationToken = authorizationToken;
140
148
  this.nonce = nonce;
@@ -147,6 +155,8 @@ export class Enrollment {
147
155
  this.userIdentifier = userIdentifier;
148
156
  this.isReturnDataForIncompleteSession = isReturnDataForIncompleteSession;
149
157
  this.appearanceMode = appearanceMode;
158
+ this.isAllowNonPhysicalDocuments = isAllowNonPhysicalDocuments;
159
+ this.isDisableTamperingRejection = isDisableTamperingRejection;
150
160
  }
151
161
  }
152
162
 
@@ -160,6 +170,14 @@ export class EnrollmentBuilder {
160
170
  this.nonce = nonce;
161
171
  return this;
162
172
  }
173
+ allowNonPhysicalDocuments() {
174
+ this.isAllowNonPhysicalDocuments = true;
175
+ return this;
176
+ }
177
+ disableTamperingRejection() {
178
+ this.isDisableTamperingRejection = true;
179
+ return this;
180
+ }
163
181
 
164
182
  setSessionId(sessionId) {
165
183
  this.sessionId = sessionId;
@@ -230,7 +248,7 @@ export class EnrollmentBuilder {
230
248
  return new Enrollment(this.documentList, this.authorizationToken, this.nonce,
231
249
  this.isRootedDeviceAllowed, this.isSecuredWindowsDisabled, this.facialRecognitionSpecification,
232
250
  this.backgroundCheckConfiguration, this.lookupConfiguration, this.sessionId, this.userIdentifier, this.isReturnDataForIncompleteSession,
233
- this.appearanceMode);
251
+ this.appearanceMode,this.isAllowNonPhysicalDocuments,this.isDisableTamperingRejection);
234
252
  }
235
253
  }
236
254
 
@@ -269,8 +287,14 @@ export class FacialRecognitionConfigurationBuilder {
269
287
  return this;
270
288
  },
271
289
 
290
+
291
+ enableAuditTrailImageObfuscation: function (obfuscationType) {
292
+ this.obfuscationType = obfuscationType;
293
+ return this;
294
+ },
295
+
272
296
  build: function () {
273
- return new FacialRecognitionConfiguration(this.enrollFace, this.scanMinimumMatchLevel, this.readMinimumMatchLevel, this.lookupMinimumMatchLevel, this.maxAttempts,this.isAllowClosedEyes);
297
+ return new FacialRecognitionConfiguration(this.enrollFace, this.scanMinimumMatchLevel, this.readMinimumMatchLevel, this.lookupMinimumMatchLevel, this.maxAttempts,this.isAllowClosedEyes,this.obfuscationType);
274
298
  }
275
299
  };
276
300
  }
@@ -278,13 +302,14 @@ export class FacialRecognitionConfigurationBuilder {
278
302
 
279
303
 
280
304
  export class FacialRecognitionConfiguration {
281
- constructor(enrollFace, scanMinimumMatchLevel, readMinimumMatchLevel, lookupMinimumMatchLevel, maxAttempts,isAllowClosedEyes) {
305
+ constructor(enrollFace, scanMinimumMatchLevel, readMinimumMatchLevel, lookupMinimumMatchLevel, maxAttempts,isAllowClosedEyes,obfuscationType) {
282
306
  this.enrollFace = enrollFace;
283
307
  this.scanMinimumMatchLevel = scanMinimumMatchLevel;
284
308
  this.readMinimumMatchLevel = readMinimumMatchLevel;
285
309
  this.lookupMinimumMatchLevel = lookupMinimumMatchLevel;
286
310
  this.maxAttempts = maxAttempts;
287
311
  this.allowClosedEyes = isAllowClosedEyes;
312
+ this.obfuscationType = obfuscationType;
288
313
  }
289
314
  }
290
315
 
@@ -633,17 +658,22 @@ export class FaceSessionBuilder {
633
658
  this.appearanceMode = appearanceMode;
634
659
  return this;
635
660
  },
661
+
662
+ enableAuditTrailImageObfuscation: function (obfuscationType) {
663
+ this.obfuscationType = obfuscationType;
664
+ return this;
665
+ },
636
666
 
637
667
 
638
668
  build: function () {
639
- return new FaceSessionConfiguration(this.authorizationToken, this.sessionId, this.nonce, this.isRootedDeviceAllowed, this.isSecuredWindowsDisabled, this.minimumMatchLevel, this.maxAttempts, this.isReturnDataForIncompleteSession, this.appearanceMode,this.isAllowClosedEyes);
669
+ return new FaceSessionConfiguration(this.authorizationToken, this.sessionId, this.nonce, this.isRootedDeviceAllowed, this.isSecuredWindowsDisabled, this.minimumMatchLevel, this.maxAttempts, this.isReturnDataForIncompleteSession, this.appearanceMode,this.isAllowClosedEyes,this.obfuscationType);
640
670
  }
641
671
  }
642
672
  }
643
673
  }
644
674
 
645
675
  export class FaceSessionConfiguration {
646
- constructor(token, sessionId, nonce, isRootedDeviceAllowed, isSecuredWindowsDisabled, minimumMatchLevel,maxAttempts,isReturnDataForIncompleteSession,appearanceMode,isAllowClosedEyes) {
676
+ constructor(token, sessionId, nonce, isRootedDeviceAllowed, isSecuredWindowsDisabled, minimumMatchLevel,maxAttempts,isReturnDataForIncompleteSession,appearanceMode,isAllowClosedEyes,obfuscationType) {
647
677
  this.token = token;
648
678
  this.sessionId = sessionId;
649
679
  this.nonce = nonce;
@@ -654,6 +684,7 @@ export class FaceSessionConfiguration {
654
684
  this.isReturnDataForIncompleteSession = isReturnDataForIncompleteSession;
655
685
  this.appearanceMode = appearanceMode;
656
686
  this.allowClosedEyes = isAllowClosedEyes;
687
+ this.obfuscationType = obfuscationType;
657
688
  }
658
689
  }
659
690
 
@@ -13,5 +13,5 @@ Pod::Spec.new do |s|
13
13
  s.source = { :http => 'https://uqudo.com' }
14
14
  s.header_dir = 'UqudoSDK'
15
15
  s.dependency 'React'
16
- s.dependency 'UqudoSDK', '2.7.4'
16
+ s.dependency 'UqudoSDK', '3.0.1'
17
17
  end