@incodetech/core 2.0.0-alpha.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.
Files changed (84) hide show
  1. package/package.json +51 -0
  2. package/src/camera/cameraActor.ts +21 -0
  3. package/src/camera/cameraService.test.ts +437 -0
  4. package/src/camera/cameraService.ts +165 -0
  5. package/src/camera/cameraServices.test.ts +66 -0
  6. package/src/camera/cameraServices.ts +26 -0
  7. package/src/camera/cameraStateMachine.test.ts +602 -0
  8. package/src/camera/cameraStateMachine.ts +264 -0
  9. package/src/camera/index.ts +5 -0
  10. package/src/camera/types.ts +17 -0
  11. package/src/device/getBrowser.ts +31 -0
  12. package/src/device/getDeviceClass.ts +29 -0
  13. package/src/device/index.ts +2 -0
  14. package/src/email/__mocks__/emailMocks.ts +59 -0
  15. package/src/email/emailActor.ts +15 -0
  16. package/src/email/emailManager.test.ts +573 -0
  17. package/src/email/emailManager.ts +427 -0
  18. package/src/email/emailServices.ts +66 -0
  19. package/src/email/emailStateMachine.test.ts +741 -0
  20. package/src/email/emailStateMachine.ts +367 -0
  21. package/src/email/index.ts +39 -0
  22. package/src/email/types.ts +60 -0
  23. package/src/events/addEvent.ts +20 -0
  24. package/src/events/types.ts +7 -0
  25. package/src/flow/__mocks__/flowMocks.ts +84 -0
  26. package/src/flow/flowActor.ts +13 -0
  27. package/src/flow/flowAnalyzer.test.ts +266 -0
  28. package/src/flow/flowAnalyzer.ts +37 -0
  29. package/src/flow/flowCompletionService.ts +21 -0
  30. package/src/flow/flowManager.test.ts +560 -0
  31. package/src/flow/flowManager.ts +235 -0
  32. package/src/flow/flowServices.test.ts +109 -0
  33. package/src/flow/flowServices.ts +13 -0
  34. package/src/flow/flowStateMachine.test.ts +334 -0
  35. package/src/flow/flowStateMachine.ts +182 -0
  36. package/src/flow/index.ts +21 -0
  37. package/src/flow/moduleLoader.test.ts +136 -0
  38. package/src/flow/moduleLoader.ts +73 -0
  39. package/src/flow/orchestratedFlowManager.test.ts +240 -0
  40. package/src/flow/orchestratedFlowManager.ts +231 -0
  41. package/src/flow/orchestratedFlowStateMachine.test.ts +199 -0
  42. package/src/flow/orchestratedFlowStateMachine.ts +325 -0
  43. package/src/flow/types.ts +434 -0
  44. package/src/http/__mocks__/api.ts +88 -0
  45. package/src/http/api.test.ts +231 -0
  46. package/src/http/api.ts +90 -0
  47. package/src/http/endpoints.ts +17 -0
  48. package/src/index.ts +33 -0
  49. package/src/permissions/index.ts +2 -0
  50. package/src/permissions/permissionServices.ts +31 -0
  51. package/src/permissions/types.ts +3 -0
  52. package/src/phone/__mocks__/phoneMocks.ts +71 -0
  53. package/src/phone/index.ts +39 -0
  54. package/src/phone/phoneActor.ts +15 -0
  55. package/src/phone/phoneManager.test.ts +393 -0
  56. package/src/phone/phoneManager.ts +458 -0
  57. package/src/phone/phoneServices.ts +98 -0
  58. package/src/phone/phoneStateMachine.test.ts +918 -0
  59. package/src/phone/phoneStateMachine.ts +422 -0
  60. package/src/phone/types.ts +83 -0
  61. package/src/recordings/recordingsRepository.test.ts +87 -0
  62. package/src/recordings/recordingsRepository.ts +48 -0
  63. package/src/recordings/streamingEvents.ts +10 -0
  64. package/src/selfie/__mocks__/selfieMocks.ts +26 -0
  65. package/src/selfie/index.ts +14 -0
  66. package/src/selfie/selfieActor.ts +17 -0
  67. package/src/selfie/selfieErrorUtils.test.ts +116 -0
  68. package/src/selfie/selfieErrorUtils.ts +66 -0
  69. package/src/selfie/selfieManager.test.ts +297 -0
  70. package/src/selfie/selfieManager.ts +301 -0
  71. package/src/selfie/selfieServices.ts +362 -0
  72. package/src/selfie/selfieStateMachine.test.ts +283 -0
  73. package/src/selfie/selfieStateMachine.ts +804 -0
  74. package/src/selfie/selfieUploadService.test.ts +90 -0
  75. package/src/selfie/selfieUploadService.ts +81 -0
  76. package/src/selfie/types.ts +103 -0
  77. package/src/session/index.ts +5 -0
  78. package/src/session/sessionService.ts +78 -0
  79. package/src/setup.test.ts +61 -0
  80. package/src/setup.ts +171 -0
  81. package/tsconfig.json +13 -0
  82. package/tsdown.config.ts +22 -0
  83. package/vitest.config.ts +37 -0
  84. package/vitest.setup.ts +135 -0
@@ -0,0 +1,434 @@
1
+ export type EmptyConfig = Record<string, never>;
2
+
3
+ export type RegulationTypes =
4
+ | 'US'
5
+ | 'Worldwide'
6
+ | 'Other'
7
+ | 'US_Illinois'
8
+ | 'US_Texas'
9
+ | 'US_California'
10
+ | 'US_Washington';
11
+
12
+ export type TutorialIdConfig = {
13
+ showTutorial: boolean;
14
+ enableId: boolean;
15
+ enablePassport: boolean;
16
+ onlyFront: boolean;
17
+ onlyBack: boolean;
18
+ barcodeCapture: boolean;
19
+ fetchAdditionalPage: boolean;
20
+ secondId: boolean;
21
+ thirdId: boolean;
22
+ autoCaptureTimeout: number;
23
+ deviceIdleTimeout: number;
24
+ captureAttempts: number;
25
+ manualUploadIdCapture: boolean;
26
+ digitalIdsUpload: boolean;
27
+ showDocumentChooserScreen: boolean;
28
+ enableIdRecording: boolean;
29
+ usSmartCapture: boolean;
30
+ perCountryPerDocOverrides: Record<
31
+ string,
32
+ Record<
33
+ string,
34
+ {
35
+ onlyFront: boolean;
36
+ onlyBack: boolean;
37
+ fetchAdditionalPage: boolean;
38
+ }
39
+ >
40
+ >;
41
+ };
42
+
43
+ export type FlowModuleConfig = {
44
+ AUTHENTICATION: {
45
+ showTutorial: boolean;
46
+ autoCaptureTimeout: number;
47
+ numberOfAttempts: number;
48
+ type: 'ONE_TO_ONE';
49
+ deepsightLiveness: 'SINGLE_FRAME' | 'MULTIMODAL' | 'VIDEOLIVENESS';
50
+ validateClosedEyes: boolean;
51
+ validateFaceMask: boolean;
52
+ validateHeadCover: boolean;
53
+ validateLenses: boolean;
54
+ };
55
+ ADDRESS: {
56
+ disableSkipPoa: boolean;
57
+ title: string;
58
+ text: string;
59
+ };
60
+ AE_SIGNATURE: {
61
+ uploadDocument: boolean;
62
+ downloadDocument: boolean;
63
+ issuePermanentCertificate: boolean;
64
+ allowWithoutScoreValidation: boolean;
65
+ validationsToSkip: ('ID' | 'FACE_RECOGNITION' | 'OTP' | 'TOTAL_SCORE')[];
66
+ };
67
+ CURP_VALIDATION: {
68
+ curpDataMatch: boolean;
69
+ deceasedStatusVerification: boolean;
70
+ };
71
+ CUSTOM_FIELDS: {
72
+ title: string;
73
+ customFields: {
74
+ name: string;
75
+ alias: string;
76
+ type: 'INTEGER' | 'DOUBLE' | 'BOOLEAN' | 'STRING';
77
+ }[];
78
+ };
79
+ DOCUMENT_CAPTURE: {
80
+ processingType:
81
+ | 'capture'
82
+ | 'processPoaOcr'
83
+ | 'processLoaOcr'
84
+ | 'processAsylumSeekerVisaZaf'
85
+ | 'processBankStatementOCR'
86
+ | 'processBankCheck'
87
+ | 'processV5CLogbook'
88
+ | 'processCarInvoice'
89
+ | 'processCirculationCard'
90
+ | 'processFinanceSettlement';
91
+ title: string;
92
+ text: string;
93
+ allowSkipDocumentCapture: boolean;
94
+ };
95
+ EKYB: {
96
+ checkBusinessName: boolean;
97
+ businessNameSource: 'userInput';
98
+ checkAddress: boolean;
99
+ address: 'userInput';
100
+ checkTaxId: boolean;
101
+ taxIdSource: 'userInput';
102
+ checkUniqueBeneficialOwner: boolean;
103
+ uniqueBeneficialOwnerSource: 'userInput';
104
+ };
105
+ EXTERNAL_VERIFICATION: {
106
+ source:
107
+ | 'US_DRIVERS_LICENSE_1'
108
+ | 'US_TELCO_1'
109
+ | 'US_TELCO_2'
110
+ | 'US_CONSUMER_1'
111
+ | 'US_CREDIT_BUREAU_1'
112
+ | 'MX_CONSUMER_1'
113
+ | 'BR_GOVT_1'
114
+ | 'CA_RES_CREDIT'
115
+ | 'UK_CREDIT_BUREAU_1'
116
+ | 'ES_1'
117
+ | 'CL_1'
118
+ | 'AR_1'
119
+ | 'GR_1'
120
+ | 'GT_1'
121
+ | 'BR_CPF_1';
122
+ checkName: boolean;
123
+ nameSource:
124
+ | 'userInput'
125
+ | 'document'
126
+ | 'poa'
127
+ | 'phoneModuleInput'
128
+ | 'emailModuleInput';
129
+ checkEmail: boolean;
130
+ emailSource:
131
+ | 'userInput'
132
+ | 'document'
133
+ | 'poa'
134
+ | 'phoneModuleInput'
135
+ | 'emailModuleInput';
136
+ checkAddress: boolean;
137
+ addressSource:
138
+ | 'userInput'
139
+ | 'document'
140
+ | 'poa'
141
+ | 'phoneModuleInput'
142
+ | 'emailModuleInput';
143
+ checkPhone: boolean;
144
+ phoneSource:
145
+ | 'userInput'
146
+ | 'document'
147
+ | 'poa'
148
+ | 'phoneModuleInput'
149
+ | 'emailModuleInput';
150
+ checkSsn: boolean;
151
+ ssnSource:
152
+ | 'userInput'
153
+ | 'document'
154
+ | 'poa'
155
+ | 'phoneModuleInput'
156
+ | 'emailModuleInput';
157
+ checkDob: boolean;
158
+ dobSource:
159
+ | 'userInput'
160
+ | 'document'
161
+ | 'poa'
162
+ | 'phoneModuleInput'
163
+ | 'emailModuleInput';
164
+ checkNationality: boolean;
165
+ nationalitySource:
166
+ | 'userInput'
167
+ | 'document'
168
+ | 'poa'
169
+ | 'phoneModuleInput'
170
+ | 'emailModuleInput';
171
+ checkDlNumber: boolean;
172
+ dlNumberSource:
173
+ | 'userInput'
174
+ | 'document'
175
+ | 'poa'
176
+ | 'phoneModuleInput'
177
+ | 'emailModuleInput';
178
+ checkDlState: boolean;
179
+ dlStateSource:
180
+ | 'userInput'
181
+ | 'document'
182
+ | 'poa'
183
+ | 'phoneModuleInput'
184
+ | 'emailModuleInput';
185
+ checkDlExpireAt: boolean;
186
+ dlExpireAtSource:
187
+ | 'userInput'
188
+ | 'document'
189
+ | 'poa'
190
+ | 'phoneModuleInput'
191
+ | 'emailModuleInput';
192
+ checkLast4SSN: boolean;
193
+ last4SSNSource:
194
+ | 'userInput'
195
+ | 'document'
196
+ | 'poa'
197
+ | 'phoneModuleInput'
198
+ | 'emailModuleInput';
199
+ checkIdNum: boolean;
200
+ idNumSource:
201
+ | 'userInput'
202
+ | 'document'
203
+ | 'poa'
204
+ | 'phoneModuleInput'
205
+ | 'emailModuleInput';
206
+ checkIdNum1: boolean;
207
+ idNum1Source:
208
+ | 'userInput'
209
+ | 'document'
210
+ | 'poa'
211
+ | 'phoneModuleInput'
212
+ | 'emailModuleInput';
213
+ checkGender: boolean;
214
+ genderSource:
215
+ | 'userInput'
216
+ | 'document'
217
+ | 'poa'
218
+ | 'phoneModuleInput'
219
+ | 'emailModuleInput';
220
+ };
221
+ EMAIL: {
222
+ otpVerification: boolean;
223
+ otpExpirationInMinutes: number;
224
+ prefill?: boolean;
225
+ };
226
+ FACE_MATCH: {
227
+ matchingType: 'selfieVsId' | 'selfieVsNfc' | 'idVsNfc' | 'nfc3Way';
228
+ disableFaceMatchAnimation: boolean;
229
+ };
230
+ FINISH_GPT: {
231
+ finishgptCompanyName: string;
232
+ };
233
+ GEOLOCATION: {
234
+ allowUserToSkipGeolocation: boolean;
235
+ };
236
+ INE_VALIDATION: {
237
+ facialValidation: boolean;
238
+ alternativeFacialValidation: boolean;
239
+ fallbackEnabled: boolean;
240
+ scrapingMethod: boolean;
241
+ scrapingV2: boolean;
242
+ scrapingV3: boolean;
243
+ failUnsupportedId: boolean;
244
+ dataValidation: boolean;
245
+ backgroundExecution: boolean;
246
+ mockConnectionError: boolean;
247
+ mockUserNotFoundError: boolean;
248
+ mockOK: boolean;
249
+ };
250
+ GOVT_VALIDATION_PROVISIONING: {
251
+ validationCountries: string[];
252
+ facialValidation: boolean;
253
+ dataValidation: boolean;
254
+ faceAndDataValidation: boolean;
255
+ addressValidation: boolean;
256
+ backgroundExecution: boolean;
257
+ faceMatchOverrideDataScore: boolean;
258
+ useCroppedIdFacePhoto: boolean;
259
+ };
260
+ TUTORIAL_ID: TutorialIdConfig;
261
+ ID: TutorialIdConfig;
262
+ SECOND_ID: TutorialIdConfig;
263
+ THIRD_ID: TutorialIdConfig;
264
+ ID_OCR: {
265
+ editableOcr: boolean;
266
+ };
267
+ INCODE_WATCHLIST: {
268
+ failIfFaceOnBlocklist: boolean;
269
+ addSuspectedFraudAutomatically: boolean;
270
+ autoExecution: boolean;
271
+ };
272
+ INSTANT_BAV: {
273
+ bavVendorCountry:
274
+ | 'US'
275
+ | 'CA'
276
+ | 'AU'
277
+ | 'NZ'
278
+ | 'BR'
279
+ | 'MX'
280
+ | 'CO'
281
+ | 'UK'
282
+ | 'EU';
283
+ bavNumberOfRetries: number;
284
+ };
285
+ ML_CONSENT: {
286
+ consentType: RegulationTypes;
287
+ };
288
+ NFC_SCAN: {
289
+ nfcAvailability: boolean;
290
+ nfcValidation: boolean;
291
+ showInitialDataConfirmationScreen: boolean;
292
+ };
293
+ PHONE: {
294
+ otpVerification: boolean;
295
+ otpExpirationInMinutes: number;
296
+ prefill: boolean;
297
+ };
298
+ SELFIE: {
299
+ showTutorial: boolean;
300
+ showPreview: boolean;
301
+ assistedOnboarding: boolean;
302
+ enableFaceRecording: boolean;
303
+ autoCaptureTimeout: number;
304
+ captureAttempts: number;
305
+ validateLenses: boolean;
306
+ validateFaceMask: boolean;
307
+ validateHeadCover: boolean;
308
+ validateClosedEyes: boolean;
309
+ validateBrightness: boolean;
310
+ deepsightLiveness: 'SINGLE_FRAME' | 'MULTIMODAL' | 'VIDEOLIVENESS';
311
+ };
312
+ SIGNATURE: {
313
+ title: string;
314
+ subTitle: string;
315
+ };
316
+ USER_CONSENT: {
317
+ title: string;
318
+ text: string;
319
+ };
320
+ CONFERENCE: {
321
+ enableConferenceOtp: boolean;
322
+ };
323
+ VIDEO_ONBOARDING: {
324
+ useAsSelfie: boolean;
325
+ showTutorials: boolean;
326
+ companyName: string;
327
+ checkLiveness: boolean;
328
+ checkIdScan: boolean;
329
+ checkDocumentScan: boolean;
330
+ compareIdEnabled: boolean;
331
+ compareOcrEnabled: boolean;
332
+ compareBackIdEnabled: boolean;
333
+ compareBackOcrEnabled: boolean;
334
+ checkVoiceConsent: boolean;
335
+ voiceConsentQuestions: number;
336
+ selfieQualityAffectsScore: boolean;
337
+ maxWaitingVideoSelfieFile: number;
338
+ lastSecondsVideoQualityCheck: boolean;
339
+ lastSecondsVideoQualityCheckDuration: number;
340
+ validateClosedEyes: boolean;
341
+ validateFaceMask: boolean;
342
+ validateHeadCover: boolean;
343
+ validateLenses: boolean;
344
+ };
345
+ DYNAMIC_FORMS: {
346
+ screens: {
347
+ title: string;
348
+ hideTitle: boolean;
349
+ questions: {
350
+ questionId: string;
351
+ overrides: string | null;
352
+ isPredefined: boolean;
353
+ predefinedQuestionType: string | null;
354
+ question: string;
355
+ inputType:
356
+ | 'NUMBER'
357
+ | 'CPF'
358
+ | 'COUNTRY'
359
+ | 'NATIONALITY'
360
+ | 'DATE'
361
+ | 'PHONE'
362
+ | 'EMAIL'
363
+ | 'TEXT'
364
+ | 'MULTISELECT'
365
+ | 'YESNO'
366
+ | 'SELECT';
367
+ options: string[];
368
+ }[];
369
+ }[];
370
+ };
371
+ COMBINED_CONSENT: {
372
+ combinedConsents: string;
373
+ };
374
+ QE_SIGNATURE: {
375
+ uploadDocument: boolean;
376
+ downloadDocument: boolean;
377
+ };
378
+ CERTIFICATE_ISSUANCE: {
379
+ region: string;
380
+ type: 'ONE_TIME' | 'SHORT_TERM' | 'LONG_TERM';
381
+ };
382
+ // Empty configs
383
+ ANTIFRAUD: EmptyConfig;
384
+ CHECKBOX_SIGNATURE: EmptyConfig;
385
+ CROSS_DOCUMENT_DATA_MATCH: EmptyConfig;
386
+ DEVICE_FINGERPRINT: EmptyConfig;
387
+ FACE_ONBOARDING: EmptyConfig;
388
+ FIELD_COMPARISON: EmptyConfig;
389
+ FISCAL_QR: EmptyConfig;
390
+ GENERATE_QR: EmptyConfig;
391
+ INSTANT_VERIFY: EmptyConfig;
392
+ IP_ADDRESS: EmptyConfig;
393
+ NAME_CAPTURE: EmptyConfig;
394
+ SHOW_RESULTS: EmptyConfig;
395
+ STADIUM_SELECTOR: EmptyConfig;
396
+ UNIVERSAL_IDENTITY: EmptyConfig;
397
+ WATCHLIST: EmptyConfig;
398
+ TRUST_GRAPH: EmptyConfig;
399
+ WATCHLIST_BUSINESS: EmptyConfig;
400
+ };
401
+
402
+ export type FlowModule = {
403
+ [K in keyof FlowModuleConfig]: {
404
+ key: K;
405
+ configuration: FlowModuleConfig[K];
406
+ };
407
+ }[keyof FlowModuleConfig];
408
+
409
+ export type Flow = {
410
+ flowId: string;
411
+ name: string;
412
+ autoApproveEnabled?: boolean;
413
+ autoApproveLevel?: 'LOW' | 'MEDIUM' | 'HIGH';
414
+ checkTutorials?: boolean;
415
+ checkAuthorization?: boolean;
416
+ redirectDesktopToMobile?: boolean;
417
+ disableUnsupportedBrowserScreen?: boolean;
418
+ qrPhishingResistance?: boolean;
419
+ addContinueToDesktop?: boolean;
420
+ redirectOriginOnly?: boolean;
421
+ displayOnboardingResultOnDesktop?: boolean;
422
+ enableMultipleOnboardings?: boolean;
423
+ disableLaunchScreen?: boolean;
424
+ enableSardineRisk?: boolean;
425
+ mandatoryConsentCheck?: boolean;
426
+ disableSmsOption?: boolean;
427
+ mergeSessionRecordings?: boolean;
428
+ ageAssurance?: boolean;
429
+ flowModules: FlowModule[];
430
+ enforceCaptureAttemptLimits?: boolean;
431
+ enableFraudAi?: boolean;
432
+ getEnableIdOnlyIdentity?: boolean;
433
+ ds?: boolean;
434
+ };
@@ -0,0 +1,88 @@
1
+ import type { HttpResponse } from '@incodetech/infra';
2
+ import type { Mock } from 'vitest';
3
+ import { vi } from 'vitest';
4
+
5
+ export function createMockResponse<T>(data: T, ok = true): HttpResponse<T> {
6
+ return {
7
+ ok,
8
+ status: ok ? 200 : 400,
9
+ statusText: ok ? 'OK' : 'Bad Request',
10
+ url: '',
11
+ headers: {},
12
+ data,
13
+ };
14
+ }
15
+
16
+ type MockHttpClient = {
17
+ defaults: {
18
+ baseURL: string;
19
+ headers: Record<string, string>;
20
+ };
21
+ request: Mock;
22
+ get: Mock;
23
+ post: Mock;
24
+ put: Mock;
25
+ patch: Mock;
26
+ delete: Mock;
27
+ head: Mock;
28
+ options: Mock;
29
+ setHeader: Mock;
30
+ };
31
+
32
+ export function createMockHttpClient(): MockHttpClient {
33
+ return {
34
+ defaults: {
35
+ baseURL: 'https://mock-api.test',
36
+ headers: {},
37
+ },
38
+ request: vi.fn(),
39
+ get: vi.fn(),
40
+ post: vi.fn(),
41
+ put: vi.fn(),
42
+ patch: vi.fn(),
43
+ delete: vi.fn(),
44
+ head: vi.fn(),
45
+ options: vi.fn(),
46
+ setHeader: vi.fn(),
47
+ };
48
+ }
49
+
50
+ const mockClient = createMockHttpClient();
51
+
52
+ export const setClient = vi.fn();
53
+ export const getApi = vi.fn().mockReturnValue(mockClient);
54
+ export const isApiConfigured = vi.fn().mockReturnValue(true);
55
+ export const resetApi = vi.fn();
56
+
57
+ export const api = {
58
+ get defaults() {
59
+ return mockClient.defaults;
60
+ },
61
+ get: mockClient.get,
62
+ post: mockClient.post,
63
+ put: mockClient.put,
64
+ patch: mockClient.patch,
65
+ delete: mockClient.delete,
66
+ head: mockClient.head,
67
+ options: mockClient.options,
68
+ request: mockClient.request,
69
+ setHeader: mockClient.setHeader,
70
+ };
71
+
72
+ export function resetMocks(): void {
73
+ mockClient.request.mockReset();
74
+ mockClient.get.mockReset();
75
+ mockClient.post.mockReset();
76
+ mockClient.put.mockReset();
77
+ mockClient.patch.mockReset();
78
+ mockClient.delete.mockReset();
79
+ mockClient.head.mockReset();
80
+ mockClient.options.mockReset();
81
+ mockClient.setHeader.mockReset();
82
+ setClient.mockReset();
83
+ getApi.mockReset().mockReturnValue(mockClient);
84
+ isApiConfigured.mockReset().mockReturnValue(true);
85
+ resetApi.mockReset();
86
+ }
87
+
88
+ export { mockClient };