react-native-kalapa-ekyc 1.1.2 → 1.2.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.
- package/README.md +534 -142
- package/android/.gradle/8.9/checksums/checksums.lock +0 -0
- package/android/.gradle/8.9/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.9/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.9/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.9/gc.properties +0 -0
- package/android/build.gradle +10 -8
- package/android/src/main/java/com/reactnativekalapaekyc/KalapaEkycModule.java +72 -60
- package/ios/KalapaEkyc.m +20 -9
- package/ios/KalapaEkyc.xcodeproj/project.xcworkspace/xcuserdata/iosdev.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/ios/KalapaEkyc.xcodeproj/project.xcworkspace/xcuserdata/leo.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- package/package.json +11 -12
- package/react-native-kalapa-ekyc.podspec +1 -0
- package/src/KalapaResult.ts +326 -0
- package/src/index.tsx +4 -1
- package/lib/typescript/babel.config.d.ts +0 -1
- package/lib/typescript/lib/commonjs/index.d.ts +0 -3
- package/lib/typescript/lib/module/index.d.ts +0 -2
- package/lib/typescript/scripts/bootstrap.d.ts +0 -1
- /package/lib/typescript/{src/index.d.ts → index.d.ts} +0 -0
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
package/android/build.gradle
CHANGED
|
@@ -6,9 +6,8 @@ buildscript {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
dependencies {
|
|
9
|
-
classpath
|
|
10
|
-
//
|
|
11
|
-
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.0}"
|
|
9
|
+
classpath("com.android.tools.build:gradle:4.2.2")
|
|
10
|
+
// classpath 'com.android.tools.build:gradle:3.5.3'
|
|
12
11
|
}
|
|
13
12
|
}
|
|
14
13
|
}
|
|
@@ -20,11 +19,10 @@ def safeExtGet(prop, fallback) {
|
|
|
20
19
|
}
|
|
21
20
|
|
|
22
21
|
android {
|
|
23
|
-
|
|
24
|
-
compileSdkVersion safeExtGet('KalapaEkyc_compileSdkVersion', 35)
|
|
22
|
+
compileSdkVersion safeExtGet('KalapaEkyc_compileSdkVersion', 33)
|
|
25
23
|
defaultConfig {
|
|
26
|
-
minSdkVersion safeExtGet('KalapaEkyc_minSdkVersion',
|
|
27
|
-
targetSdkVersion safeExtGet('KalapaEkyc_targetSdkVersion',
|
|
24
|
+
minSdkVersion safeExtGet('KalapaEkyc_minSdkVersion', 24)
|
|
25
|
+
targetSdkVersion safeExtGet('KalapaEkyc_targetSdkVersion', 33)
|
|
28
26
|
versionCode 1
|
|
29
27
|
versionName "1.8"
|
|
30
28
|
|
|
@@ -38,6 +36,10 @@ android {
|
|
|
38
36
|
lintOptions {
|
|
39
37
|
disable 'GradleCompatible'
|
|
40
38
|
}
|
|
39
|
+
compileOptions {
|
|
40
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
41
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
42
|
+
}
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
repositories {
|
|
@@ -54,5 +56,5 @@ dependencies {
|
|
|
54
56
|
//noinspection GradleDynamicVersion
|
|
55
57
|
implementation "com.facebook.react:react-native:+" // From node_modules
|
|
56
58
|
//kalapasdk
|
|
57
|
-
implementation 'vn.kalapa
|
|
59
|
+
implementation 'vn.kalapa:ekyc:2.10.9'
|
|
58
60
|
}
|
|
@@ -44,73 +44,85 @@ public class KalapaEkycModule extends ReactContextBaseJavaModule {
|
|
|
44
44
|
public void multiply(int a, int b, Promise promise) {
|
|
45
45
|
promise.resolve(a * b);
|
|
46
46
|
}
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
|
|
49
49
|
@ReactMethod
|
|
50
50
|
public void start(String session, String flow, ReadableMap data, Promise promise) {
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
52
|
+
String domain = data.getString("domain");
|
|
53
|
+
String mainColor = data.getString("main_color") != null ? data.getString("main_color") : "#1F69E6";
|
|
54
|
+
String background = data.getString("background_color") != null ? data.getString("background_color") : "#FFFFFF";
|
|
55
|
+
String mainTextColor = data.getString("main_text_color") != null ? data.getString("main_text_color") : "#000000";
|
|
56
|
+
String btnTextColor = data.getString("btn_text_color") != null ? data.getString("btn_text_color") : "#FFFFFF";
|
|
57
|
+
String language = data.getString("language") != null ? data.getString("language") : "en";
|
|
58
|
+
int livenessVersion = data.getInt("liveness_version");
|
|
59
|
+
|
|
60
|
+
String faceData = data.getString("face_data") != null ? data.getString("face_data") : "";
|
|
61
|
+
String mrzData = data.getString("mrz") != null ? data.getString("mrz") : "";
|
|
62
|
+
String qrCode = data.getString("qr_code") != null ? data.getString("qr_code") : "";
|
|
63
|
+
String sessionId = data.getString("session_id") != null ? data.getString("session_id") : "";
|
|
64
|
+
boolean allowMrzRescanOnNfcMismatch = data.getBoolean("allow_mrz_rescan_on_nfc_mismatch");
|
|
65
|
+
Context context = getReactApplicationContext();
|
|
66
|
+
if (getCurrentActivity() != null) {
|
|
67
67
|
KalapaSDKConfig klpConfig = new KalapaSDKConfig.KalapaSDKConfigBuilder(getCurrentActivity())
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
68
|
+
.withBaseURL(domain)
|
|
69
|
+
.withMainColor(mainColor)
|
|
70
|
+
.withBackgroundColor(background)
|
|
71
|
+
.withMainTextColor(mainTextColor)
|
|
72
|
+
.withBtnTextColor(btnTextColor)
|
|
73
|
+
.withLanguage(language)
|
|
74
|
+
.withLivenessVersion(livenessVersion)
|
|
75
|
+
.withAllowMRZRescanOnNFCMismatch(allowMrzRescanOnNfcMismatch)
|
|
76
|
+
.build();
|
|
77
|
+
|
|
78
|
+
KalapaSDK.KalapaSDKBuilder builder = new KalapaSDK.KalapaSDKBuilder(getCurrentActivity(), klpConfig);
|
|
79
|
+
if (qrCode != null && !qrCode.isEmpty()) builder.withRawQRCode(qrCode);
|
|
80
|
+
if (faceData != null && !faceData.isEmpty()) builder.withFaceData(faceData);
|
|
81
|
+
if (mrzData != null && !mrzData.isEmpty()) builder.withMrz(mrzData);
|
|
82
|
+
if (sessionId != null && !sessionId.isEmpty()) builder.withLeftoverSession(sessionId);
|
|
83
|
+
|
|
84
|
+
builder.build().start(session, flow, new KalapaHandler() {
|
|
85
|
+
@Override
|
|
86
|
+
public void onExpired() {
|
|
87
|
+
promise.reject("EXPIRED", "Session expired");
|
|
85
88
|
// promise.reject("401", "EXPIRED");
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
res.putString("kalapa_result", resultMap);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
@Override
|
|
92
|
+
public void onComplete(@NonNull KalapaResult kalapaResult) {
|
|
93
|
+
String resultMap = kalapaResult.toJson();
|
|
94
|
+
WritableMap res = new WritableNativeMap();
|
|
95
|
+
res.putString("kalapa_result", resultMap);
|
|
94
96
|
// callback.invoke(res);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
97
|
+
promise.resolve(res);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@Override
|
|
101
|
+
public void onError(@NonNull KalapaSDKResultCode kalapaSDKResultCode, @NonNull String message) {
|
|
102
|
+
switch (kalapaSDKResultCode) {
|
|
103
|
+
case USER_LEAVE:
|
|
104
|
+
promise.reject("CANCELED", message);
|
|
105
|
+
case DEVICE_NOT_SUPPORTED:
|
|
106
|
+
promise.reject("UNSUPPORTED", message);
|
|
107
|
+
case CONFIGURATION_NOT_ACCEPTABLE:
|
|
108
|
+
promise.reject("CONFIG_ERROR", message);
|
|
109
|
+
case INVALID_NFC:
|
|
110
|
+
promise.reject("MRZ_INVALID", message);
|
|
111
|
+
case WRONG_CCCDID:
|
|
112
|
+
promise.reject("NFC_NOT_MATCH", message);
|
|
113
|
+
case PERMISSION_DENIED:
|
|
114
|
+
promise.reject("PERMISSION_DENIED", message);
|
|
115
|
+
case VIRTUAL_CAMERA_DETECTED:
|
|
116
|
+
case ROOTED_DEVICE_DETECTED:
|
|
117
|
+
case EMULATOR_DETECTED:
|
|
118
|
+
promise.reject("DEVICE_NOT_ACCEPTABLE", message);
|
|
119
|
+
default:
|
|
120
|
+
promise.reject("OTHER", message);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
} else
|
|
125
|
+
Toast.makeText(getReactApplicationContext(), "Activity is null", Toast.LENGTH_LONG).show();
|
|
114
126
|
}
|
|
115
127
|
|
|
116
128
|
public static native int nativeMultiply(int a, int b);
|
package/ios/KalapaEkyc.m
CHANGED
|
@@ -26,7 +26,9 @@ RCT_EXPORT_METHOD(start:(NSString *)session
|
|
|
26
26
|
NSString *faceData = data[@"face_data"];
|
|
27
27
|
NSString *mrz = data[@"mrz"];
|
|
28
28
|
NSString *sessionID = data[@"session_id"];
|
|
29
|
-
|
|
29
|
+
id val = data[@"allow_mrz_rescan_on_nfc_mismatch"];
|
|
30
|
+
BOOL allowMRZRescanOnNfcMismatch = [val isKindOfClass:NSNumber.class] ? [val boolValue] : NO;
|
|
31
|
+
|
|
30
32
|
KLPAppearance *klpAppearance = [[[[[[KLPAppearance Builder]
|
|
31
33
|
withLanguage:language]
|
|
32
34
|
withMainColor:mainColor]
|
|
@@ -39,18 +41,26 @@ RCT_EXPORT_METHOD(start:(NSString *)session
|
|
|
39
41
|
livenessVersion:livenessVersion
|
|
40
42
|
appearance:klpAppearance
|
|
41
43
|
mrz:mrz
|
|
42
|
-
faceData:faceData
|
|
44
|
+
faceData:faceData
|
|
45
|
+
allowMRZRescanOnNfcMismatch:allowMRZRescanOnNfcMismatch];
|
|
43
46
|
|
|
44
47
|
if (sessionID != nil) {
|
|
45
48
|
[klpConfig withSession:sessionID];
|
|
46
49
|
}
|
|
47
50
|
|
|
48
|
-
[klpConfig
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
[klpConfig withEventHandler:^(enum Event event) {
|
|
52
|
+
switch (event) {
|
|
53
|
+
case EventSessionTerminated:
|
|
54
|
+
reject(@"CANCELED", @"Người dùng hủy bỏ xác thực", nil);
|
|
55
|
+
break;
|
|
56
|
+
case EventSessionExpired:
|
|
57
|
+
reject(@"UNAUTHORIZED", @"Quá trình xác thực thất bại, vui lòng kiểm tra lại", nil);
|
|
58
|
+
break;
|
|
59
|
+
default:
|
|
60
|
+
reject(@"OTHER", @"Đã có lỗi xảy ra", nil);
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
|
|
54
64
|
}];
|
|
55
65
|
|
|
56
66
|
[klpConfig withResultHandler:^(KalapaResult * _Nullable result) {
|
|
@@ -81,7 +91,8 @@ RCT_EXPORT_METHOD(start:(NSString *)session
|
|
|
81
91
|
livenessVersion:(NSInteger)livenessVersion
|
|
82
92
|
appearance:(KLPAppearance *)appearance
|
|
83
93
|
mrz:(NSString *)mrz
|
|
84
|
-
faceData:(NSString *)faceData
|
|
94
|
+
faceData:(NSString *)faceData
|
|
95
|
+
allowMRZRescanOnNfcMismatch:(BOOL)allowMRZRescanOnNfcMismatch {
|
|
85
96
|
KLPConfig *config = [[[[[[KLPConfig BuilderWithSession:session]
|
|
86
97
|
withBaseUrl:domain]
|
|
87
98
|
withLivenessVersion:livenessVersion]
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-kalapa-ekyc",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "React Native SDK for Kalapa eKYC integration",
|
|
5
|
-
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
6
|
"module": "lib/module/index.js",
|
|
7
7
|
"types": "lib/typescript/src/index.d.ts",
|
|
8
8
|
"react-native": "src/index.tsx",
|
|
9
|
-
"source": "src/index
|
|
9
|
+
"source": "src/index",
|
|
10
10
|
"files": [
|
|
11
11
|
"src",
|
|
12
12
|
"lib",
|
|
@@ -16,17 +16,15 @@
|
|
|
16
16
|
"android",
|
|
17
17
|
"ios",
|
|
18
18
|
"cpp",
|
|
19
|
-
"Frameworks",
|
|
20
19
|
"react-native-kalapa-ekyc.podspec",
|
|
20
|
+
"!lib/typescript/example",
|
|
21
21
|
"!android/build",
|
|
22
22
|
"!ios/build"
|
|
23
23
|
],
|
|
24
24
|
"scripts": {
|
|
25
25
|
"test": "jest",
|
|
26
26
|
"typescript": "tsc --noEmit",
|
|
27
|
-
"lint": "eslint \"**/*.{js,ts,tsx}\""
|
|
28
|
-
"prepare": "npm run build",
|
|
29
|
-
"build": "echo 'Build completed'"
|
|
27
|
+
"lint": "eslint \"**/*.{js,ts,tsx}\""
|
|
30
28
|
},
|
|
31
29
|
"keywords": [
|
|
32
30
|
"react-native",
|
|
@@ -49,8 +47,8 @@
|
|
|
49
47
|
"@react-native-community/eslint-config": "^2.0.0",
|
|
50
48
|
"@release-it/conventional-changelog": "^2.0.0",
|
|
51
49
|
"@types/jest": "^26.0.0",
|
|
52
|
-
"@types/react": "
|
|
53
|
-
"@types/react-native": "0.
|
|
50
|
+
"@types/react": "^16.9.19",
|
|
51
|
+
"@types/react-native": "0.62.13",
|
|
54
52
|
"commitlint": "^11.0.0",
|
|
55
53
|
"eslint": "^7.2.0",
|
|
56
54
|
"eslint-config-prettier": "^7.0.0",
|
|
@@ -59,14 +57,15 @@
|
|
|
59
57
|
"jest": "^26.0.1",
|
|
60
58
|
"pod-install": "^0.1.0",
|
|
61
59
|
"prettier": "^2.0.5",
|
|
60
|
+
"react": "16.13.1",
|
|
61
|
+
"react-native": "0.63.4",
|
|
62
62
|
"react-native-builder-bob": "^0.18.0",
|
|
63
63
|
"release-it": "^14.2.2",
|
|
64
64
|
"typescript": "^4.1.3"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"react": "
|
|
68
|
-
"react-native": "
|
|
69
|
-
"react-native-reanimated": ">1.9.0"
|
|
67
|
+
"react": "*",
|
|
68
|
+
"react-native": "*"
|
|
70
69
|
},
|
|
71
70
|
"jest": {
|
|
72
71
|
"preset": "react-native",
|
|
@@ -14,6 +14,7 @@ Pod::Spec.new do |s|
|
|
|
14
14
|
s.source = { :git => "https://gitlab.com/littlepjg/klp-ekyc-react-native.git", :tag => "#{s.version}" }
|
|
15
15
|
|
|
16
16
|
s.source_files = "ios/**/*.{h,m,mm}"
|
|
17
|
+
#s.ios.vendored_frameworks = "Frameworks/KalapaSDK.xcframework"
|
|
17
18
|
|
|
18
19
|
s.dependency "React-Core"
|
|
19
20
|
s.dependency "KalapaEkycSDK"
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KalapaResult - Simplified and standardized result parser for NFC-only mode
|
|
3
|
+
* Handles both Android and iOS response formats
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export interface SelfieData {
|
|
7
|
+
is_matched: boolean;
|
|
8
|
+
matching_score: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface NfcData {
|
|
12
|
+
// Personal Information
|
|
13
|
+
name: string;
|
|
14
|
+
id_number: string;
|
|
15
|
+
old_id_number: string;
|
|
16
|
+
date_of_birth: string;
|
|
17
|
+
date_of_expiry: string;
|
|
18
|
+
date_of_issuance: string;
|
|
19
|
+
gender: string;
|
|
20
|
+
nationality: string;
|
|
21
|
+
nation: string;
|
|
22
|
+
|
|
23
|
+
// Address Information
|
|
24
|
+
address: string;
|
|
25
|
+
hometown: string;
|
|
26
|
+
|
|
27
|
+
// Family Information
|
|
28
|
+
father_name: string;
|
|
29
|
+
mother_name: string;
|
|
30
|
+
spouse_name: string;
|
|
31
|
+
|
|
32
|
+
// Additional Information
|
|
33
|
+
religion: string;
|
|
34
|
+
personal_identification: string;
|
|
35
|
+
|
|
36
|
+
// Technical Data
|
|
37
|
+
face_image: string; // Base64 image from NFC chip
|
|
38
|
+
mrz: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface AddressEntities {
|
|
42
|
+
district: string;
|
|
43
|
+
ward: string;
|
|
44
|
+
province: string;
|
|
45
|
+
unknown: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface MrzDataFields {
|
|
49
|
+
birthday?: string;
|
|
50
|
+
doe?: string;
|
|
51
|
+
gender?: string;
|
|
52
|
+
id_number?: string;
|
|
53
|
+
name?: string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface MrzDataError {
|
|
57
|
+
code: number;
|
|
58
|
+
message: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface MrzData {
|
|
62
|
+
data?: {
|
|
63
|
+
fields?: MrzDataFields;
|
|
64
|
+
raw_mrz?: string;
|
|
65
|
+
};
|
|
66
|
+
error?: MrzDataError;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface QrCodeData {
|
|
70
|
+
decoded_text?: string;
|
|
71
|
+
stage?: number;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface QrCode {
|
|
75
|
+
data?: QrCodeData;
|
|
76
|
+
error?: {
|
|
77
|
+
code: number;
|
|
78
|
+
message: string;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export type DecisionType = 'APPROVED' | 'MANUAL' | 'REJECTED' | 'UNKNOWN';
|
|
83
|
+
|
|
84
|
+
export class KalapaResult {
|
|
85
|
+
// Root level common fields
|
|
86
|
+
public birthday!: string;
|
|
87
|
+
public country!: string;
|
|
88
|
+
public decision!: DecisionType;
|
|
89
|
+
public doe!: string; // Date of expiry
|
|
90
|
+
public doi!: string; // Date of issuance
|
|
91
|
+
public ethnicity!: string;
|
|
92
|
+
public features!: string;
|
|
93
|
+
public gender!: string;
|
|
94
|
+
public home!: string;
|
|
95
|
+
public home_entities!: AddressEntities;
|
|
96
|
+
public id_number!: string;
|
|
97
|
+
public mrz_data!: MrzData | null;
|
|
98
|
+
public name!: string;
|
|
99
|
+
public national!: string;
|
|
100
|
+
public nfc_data!: NfcData;
|
|
101
|
+
public poi!: string;
|
|
102
|
+
public qr_code!: QrCode | null;
|
|
103
|
+
public religion!: string;
|
|
104
|
+
public resident!: string;
|
|
105
|
+
public resident_entities!: AddressEntities;
|
|
106
|
+
public selfie_data!: SelfieData;
|
|
107
|
+
public session!: string;
|
|
108
|
+
public type!: string;
|
|
109
|
+
public rawResult: any;
|
|
110
|
+
|
|
111
|
+
constructor(rawResult: any) {
|
|
112
|
+
this.rawResult = rawResult;
|
|
113
|
+
this._parseResult();
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
private _parseResult(): void {
|
|
117
|
+
// Handle both wrapped (kalapa_result) and unwrapped responses
|
|
118
|
+
const kalapaData = this.rawResult?.kalapa_result || this.rawResult || {};
|
|
119
|
+
|
|
120
|
+
// Parse root level common fields
|
|
121
|
+
this.birthday = kalapaData.birthday || '';
|
|
122
|
+
this.country = kalapaData.country || '';
|
|
123
|
+
this.decision = (kalapaData.decision || 'UNKNOWN') as DecisionType;
|
|
124
|
+
this.doe = kalapaData.doe || '';
|
|
125
|
+
this.doi = kalapaData.doi || '';
|
|
126
|
+
this.ethnicity = kalapaData.ethnicity || '';
|
|
127
|
+
this.features = kalapaData.features || '';
|
|
128
|
+
this.gender = kalapaData.gender || '';
|
|
129
|
+
this.home = kalapaData.home || '';
|
|
130
|
+
this.home_entities = {
|
|
131
|
+
district: kalapaData.home_entities?.district || '',
|
|
132
|
+
ward: kalapaData.home_entities?.ward || '',
|
|
133
|
+
province: kalapaData.home_entities?.province || '',
|
|
134
|
+
unknown: kalapaData.home_entities?.unknown || ''
|
|
135
|
+
};
|
|
136
|
+
// Handle both idNumber (Android) and id_number (iOS)
|
|
137
|
+
this.id_number = kalapaData.id_number || kalapaData.idNumber || '';
|
|
138
|
+
this.name = kalapaData.name || '';
|
|
139
|
+
this.national = kalapaData.national || '';
|
|
140
|
+
this.poi = kalapaData.poi || '';
|
|
141
|
+
this.religion = kalapaData.religion || '';
|
|
142
|
+
this.resident = kalapaData.resident || '';
|
|
143
|
+
this.resident_entities = {
|
|
144
|
+
district: kalapaData.resident_entities?.district || '',
|
|
145
|
+
ward: kalapaData.resident_entities?.ward || '',
|
|
146
|
+
province: kalapaData.resident_entities?.province || '',
|
|
147
|
+
unknown: kalapaData.resident_entities?.unknown || ''
|
|
148
|
+
};
|
|
149
|
+
this.session = kalapaData.session || '';
|
|
150
|
+
this.type = kalapaData.type || '';
|
|
151
|
+
|
|
152
|
+
// Parse MRZ data (available on both platforms)
|
|
153
|
+
const mrzRaw = kalapaData.mrz_data;
|
|
154
|
+
if (mrzRaw && typeof mrzRaw === 'object' && mrzRaw !== null) {
|
|
155
|
+
this.mrz_data = {
|
|
156
|
+
data: mrzRaw.data ? {
|
|
157
|
+
fields: mrzRaw.data.fields || {},
|
|
158
|
+
raw_mrz: mrzRaw.data.raw_mrz || ''
|
|
159
|
+
} : undefined,
|
|
160
|
+
error: mrzRaw.error ? {
|
|
161
|
+
code: mrzRaw.error.code || 0,
|
|
162
|
+
message: mrzRaw.error.message || ''
|
|
163
|
+
} : undefined
|
|
164
|
+
};
|
|
165
|
+
} else {
|
|
166
|
+
this.mrz_data = null;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Parse QR code data (available on both platforms)
|
|
170
|
+
const qrRaw = kalapaData.qr_code;
|
|
171
|
+
if (qrRaw && typeof qrRaw === 'object' && qrRaw !== null) {
|
|
172
|
+
this.qr_code = {
|
|
173
|
+
data: qrRaw.data ? {
|
|
174
|
+
decoded_text: qrRaw.data.decoded_text || '',
|
|
175
|
+
stage: qrRaw.data.stage || undefined
|
|
176
|
+
} : undefined,
|
|
177
|
+
error: qrRaw.error ? {
|
|
178
|
+
code: qrRaw.error.code || 0,
|
|
179
|
+
message: qrRaw.error.message || ''
|
|
180
|
+
} : undefined
|
|
181
|
+
};
|
|
182
|
+
} else {
|
|
183
|
+
this.qr_code = null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Parse selfie data (identical structure on both platforms)
|
|
187
|
+
const selfieRaw = kalapaData.selfie_data || {};
|
|
188
|
+
this.selfie_data = {
|
|
189
|
+
is_matched: selfieRaw.is_matched || false,
|
|
190
|
+
matching_score: selfieRaw.matching_score || 0
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Parse NFC data (core fields available on both platforms)
|
|
194
|
+
const nfcRaw = kalapaData.nfc_data || {};
|
|
195
|
+
this.nfc_data = {
|
|
196
|
+
// Personal Information
|
|
197
|
+
name: nfcRaw.name || '',
|
|
198
|
+
id_number: nfcRaw.id_number || '',
|
|
199
|
+
old_id_number: nfcRaw.old_id_number || '',
|
|
200
|
+
date_of_birth: nfcRaw.date_of_birth || '',
|
|
201
|
+
date_of_expiry: nfcRaw.date_of_expiry || '',
|
|
202
|
+
date_of_issuance: nfcRaw.date_of_issuance || '',
|
|
203
|
+
gender: nfcRaw.gender || '',
|
|
204
|
+
nationality: nfcRaw.nationality || '',
|
|
205
|
+
nation: nfcRaw.nation || '',
|
|
206
|
+
|
|
207
|
+
// Address Information
|
|
208
|
+
address: nfcRaw.address || '',
|
|
209
|
+
hometown: nfcRaw.hometown || '',
|
|
210
|
+
|
|
211
|
+
// Family Information
|
|
212
|
+
father_name: nfcRaw.father_name || '',
|
|
213
|
+
mother_name: nfcRaw.mother_name || '',
|
|
214
|
+
spouse_name: nfcRaw.spouse_name || '',
|
|
215
|
+
|
|
216
|
+
// Additional Information
|
|
217
|
+
religion: nfcRaw.religion || '',
|
|
218
|
+
personal_identification: nfcRaw.personal_identification || '',
|
|
219
|
+
|
|
220
|
+
// Technical Data
|
|
221
|
+
face_image: nfcRaw.face_image || '', // Base64 image from NFC chip
|
|
222
|
+
mrz: nfcRaw.mrz || '',
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Convenience methods
|
|
227
|
+
public isApproved(): boolean {
|
|
228
|
+
return this.decision === 'APPROVED';
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
public isManualReview(): boolean {
|
|
232
|
+
return this.decision === 'MANUAL';
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
public isRejected(): boolean {
|
|
236
|
+
return this.decision === 'REJECTED';
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
public isFaceMatched(): boolean {
|
|
240
|
+
return this.selfie_data.is_matched === true;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
public getFaceMatchingScore(): number {
|
|
244
|
+
return this.selfie_data.matching_score;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Get formatted display name
|
|
248
|
+
public getDisplayName(): string {
|
|
249
|
+
return this.nfc_data.name || 'N/A';
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Get formatted ID number
|
|
253
|
+
public getIdNumber(): string {
|
|
254
|
+
return this.nfc_data.id_number || 'N/A';
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Get formatted date of birth
|
|
258
|
+
public getDateOfBirth(): string {
|
|
259
|
+
return this.nfc_data.date_of_birth || 'N/A';
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Get face image (Base64)
|
|
263
|
+
public getFaceImage(): string {
|
|
264
|
+
return this.nfc_data.face_image;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Export essential data as plain object
|
|
268
|
+
public toJSON(): {
|
|
269
|
+
birthday: string;
|
|
270
|
+
country: string;
|
|
271
|
+
decision: DecisionType;
|
|
272
|
+
doe: string;
|
|
273
|
+
doi: string;
|
|
274
|
+
ethnicity: string;
|
|
275
|
+
features: string;
|
|
276
|
+
gender: string;
|
|
277
|
+
home: string;
|
|
278
|
+
home_entities: AddressEntities;
|
|
279
|
+
id_number: string;
|
|
280
|
+
mrz_data: MrzData | null;
|
|
281
|
+
name: string;
|
|
282
|
+
national: string;
|
|
283
|
+
nfc_data: NfcData;
|
|
284
|
+
poi: string;
|
|
285
|
+
qr_code: QrCode | null;
|
|
286
|
+
religion: string;
|
|
287
|
+
resident: string;
|
|
288
|
+
resident_entities: AddressEntities;
|
|
289
|
+
selfie_data: SelfieData;
|
|
290
|
+
session: string;
|
|
291
|
+
type: string;
|
|
292
|
+
} {
|
|
293
|
+
return {
|
|
294
|
+
birthday: this.birthday,
|
|
295
|
+
country: this.country,
|
|
296
|
+
decision: this.decision,
|
|
297
|
+
doe: this.doe,
|
|
298
|
+
doi: this.doi,
|
|
299
|
+
ethnicity: this.ethnicity,
|
|
300
|
+
features: this.features,
|
|
301
|
+
gender: this.gender,
|
|
302
|
+
home: this.home,
|
|
303
|
+
home_entities: this.home_entities,
|
|
304
|
+
id_number: this.id_number,
|
|
305
|
+
mrz_data: this.mrz_data,
|
|
306
|
+
name: this.name,
|
|
307
|
+
national: this.national,
|
|
308
|
+
nfc_data: this.nfc_data,
|
|
309
|
+
poi: this.poi,
|
|
310
|
+
qr_code: this.qr_code,
|
|
311
|
+
religion: this.religion,
|
|
312
|
+
resident: this.resident,
|
|
313
|
+
resident_entities: this.resident_entities,
|
|
314
|
+
selfie_data: this.selfie_data,
|
|
315
|
+
session: this.session,
|
|
316
|
+
type: this.type
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Static factory method to create from raw result
|
|
321
|
+
public static fromRawResult(rawResult: any): KalapaResult {
|
|
322
|
+
return new KalapaResult(rawResult);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export default KalapaResult;
|