@transfergratis/react-native-sdk 0.1.28 → 0.1.29

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 (39) hide show
  1. package/build/components/EnhancedCameraView.js +1 -1
  2. package/build/components/EnhancedCameraView.js.map +1 -1
  3. package/build/components/KYCElements/CountrySelectionTemplate.d.ts.map +1 -1
  4. package/build/components/KYCElements/CountrySelectionTemplate.js +13 -42
  5. package/build/components/KYCElements/CountrySelectionTemplate.js.map +1 -1
  6. package/build/components/KYCElements/IDCardCapture.d.ts.map +1 -1
  7. package/build/components/KYCElements/IDCardCapture.js +64 -31
  8. package/build/components/KYCElements/IDCardCapture.js.map +1 -1
  9. package/build/components/KYCElements/SelfieCaptureTemplate.js +2 -2
  10. package/build/components/KYCElements/SelfieCaptureTemplate.js.map +1 -1
  11. package/build/hooks/useTemplateKYCFlow.js +1 -1
  12. package/build/hooks/useTemplateKYCFlow.js.map +1 -1
  13. package/build/modules/api/CardAuthentification.d.ts +15 -7
  14. package/build/modules/api/CardAuthentification.d.ts.map +1 -1
  15. package/build/modules/api/CardAuthentification.js +215 -50
  16. package/build/modules/api/CardAuthentification.js.map +1 -1
  17. package/build/modules/api/KYCService.d.ts +2 -0
  18. package/build/modules/api/KYCService.d.ts.map +1 -1
  19. package/build/modules/api/KYCService.js +16 -19
  20. package/build/modules/api/KYCService.js.map +1 -1
  21. package/build/modules/camera/VisionCameraModule.js +2 -2
  22. package/build/modules/camera/VisionCameraModule.js.map +1 -1
  23. package/build/utils/cropByObb.d.ts +8 -0
  24. package/build/utils/cropByObb.d.ts.map +1 -1
  25. package/build/utils/cropByObb.js +20 -3
  26. package/build/utils/cropByObb.js.map +1 -1
  27. package/build/utils/pathToBase64.js +1 -1
  28. package/build/utils/pathToBase64.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/components/EnhancedCameraView.tsx +1 -1
  31. package/src/components/KYCElements/CountrySelectionTemplate.tsx +24 -52
  32. package/src/components/KYCElements/IDCardCapture.tsx +115 -86
  33. package/src/components/KYCElements/SelfieCaptureTemplate.tsx +2 -2
  34. package/src/hooks/useTemplateKYCFlow.tsx +1 -1
  35. package/src/modules/api/CardAuthentification.ts +289 -64
  36. package/src/modules/api/KYCService.ts +25 -33
  37. package/src/modules/camera/VisionCameraModule.ts +2 -2
  38. package/src/utils/cropByObb.ts +22 -3
  39. package/src/utils/pathToBase64.ts +1 -1
@@ -1,21 +1,27 @@
1
1
  import kycService, { authentification, errorMessage, truncateFields } from "./KYCService";
2
- import { cropByObb, getCardInFrame, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from "../../utils/cropByObb";
2
+ import { cropByObb, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from "../../utils/cropByObb";
3
3
  import { logger } from "../../utils/logger";
4
+ import { countryData } from "../../config/countriesData";
4
5
  export async function frontVerification(result, env = 'PRODUCTION') {
5
6
  try {
6
7
  console.log("Front verification START", JSON.stringify({ result }, null, 2));
7
8
  logger.log("Front verification", JSON.stringify({ result }, null, 2));
8
- // SANDBOX mode: skip AI verification and return mock response
9
+ // SANDBOX mode
9
10
  if (env === 'SANDBOX') {
10
11
  console.log("SANDBOX mode: Skipping AI verification for front document");
11
12
  logger.log("SANDBOX mode: Returning mock front verification response");
12
- const mockBbox = { minX: 50, minY: 50, width: 200, height: 200 };
13
+ const mockBbox = { minX: 400, minY: 800, width: 2200, height: 1400 };
13
14
  const mockResponse = {
14
15
  result: true,
15
16
  detail: [{ confidence: 0.95 }],
16
- card_obb: { x: 50, y: 50, width: 200, height: 200 },
17
+ card_obb: [{
18
+ obb: [[400, 800], [2600, 800], [2600, 2200], [400, 2200]],
19
+ confidence: 0.95,
20
+ card_in_frame: true,
21
+ cropped_sides: []
22
+ }],
17
23
  bbox: mockBbox,
18
- ...(result.regionMapping.authMethod.includes('MRZ') ? {
24
+ ...(result.regionMapping?.authMethod?.includes('MRZ') ? {
19
25
  mrz: {
20
26
  success: true,
21
27
  parsed_data: {
@@ -29,21 +35,30 @@ export async function frontVerification(result, env = 'PRODUCTION') {
29
35
  return mockResponse;
30
36
  }
31
37
  const token = await authentification();
38
+ // Cast the response so TypeScript knows about card_obb
32
39
  const detected = await kycService.detectFaceOnId(result?.path || '', token, result?.selectedDocumentType || '', env);
33
40
  if (!detected.result) {
34
41
  throw new Error('Aucun visage détecté sur la carte. Veuillez reprendre.');
35
42
  }
36
- // If the backend indicates that the card is not fully in frame, stop early
37
- const cardInFrame = getCardInFrame(detected.card_obb);
38
- if (cardInFrame === false) {
39
- // Use a stable error code; the UI maps this to a localized i18n message (cardNotFullyInFrame)
40
- throw new Error('CARD_NOT_FULLY_IN_FRAME');
43
+ const cardData = detected.card_obb && Array.isArray(detected.card_obb) && detected.card_obb.length > 0
44
+ ? detected.card_obb[0]
45
+ : null;
46
+ // --- STRICT FRAMING CHECK ---
47
+ if (cardData && typeof cardData.card_in_frame !== 'undefined') {
48
+ const isCardInFrame = cardData.card_in_frame === true;
49
+ const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;
50
+ // If it is NOT in the frame, OR if any side is cropped, block progression
51
+ if (!isCardInFrame || hasCroppedSides) {
52
+ logger.log(`Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);
53
+ throw new Error('CARD_NOT_FULLY_IN_FRAME');
54
+ }
41
55
  }
56
+ // Check Confidence Threshold
42
57
  const obbConfidence = getObbConfidence(detected.card_obb);
43
58
  if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {
44
59
  throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
45
60
  }
46
- // Optional: crop image using card_obb for better MRZ/barcode extraction (only when confidence >= threshold)
61
+ // Optional: crop image using card_obb for better MRZ/barcode extraction
47
62
  let croppedBase64;
48
63
  let bbox;
49
64
  let mrz;
@@ -53,7 +68,8 @@ export async function frontVerification(result, env = 'PRODUCTION') {
53
68
  bbox = crop.bbox;
54
69
  }
55
70
  catch { }
56
- if (result.regionMapping.authMethod.length > 0 && result.regionMapping.authMethod.includes('MRZ')) {
71
+ // MRZ Extraction
72
+ if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('MRZ')) {
57
73
  mrz = await kycService.extractMrzText({
58
74
  fileUri: result.path || '',
59
75
  docType: result?.selectedDocumentType || '',
@@ -71,17 +87,125 @@ export async function frontVerification(result, env = 'PRODUCTION') {
71
87
  throw new Error(e?.message || 'Erreur de détection du visage');
72
88
  }
73
89
  }
90
+ // export async function frontVerification(
91
+ // result: { path?: string, regionMapping: { authMethod: string[], mrzTypes: string[] }, selectedDocumentType: string, code: string, currentSide: string, templatePath?: string, mrzType?: string },
92
+ // env: KycEnvironment = 'PRODUCTION'
93
+ // ) {
94
+ // try {
95
+ // console.log("Front verification START", JSON.stringify({ result }, null, 2));
96
+ // logger.log("Front verification", JSON.stringify({ result }, null, 2));
97
+ // // SANDBOX mode
98
+ // if (env === 'SANDBOX') {
99
+ // console.log("SANDBOX mode: Skipping AI verification for front document");
100
+ // logger.log("SANDBOX mode: Returning mock front verification response");
101
+ // const mockBbox: IBbox = { minX: 400, minY: 800, width: 2200, height: 1400 };
102
+ // // ==========================================
103
+ // // 🧪 TEST OVERRIDE (SANDBOX) 🧪
104
+ // // Immediately throw the error to test the UI
105
+ // // ==========================================
106
+ // throw new Error('CARD_NOT_FULLY_IN_FRAME');
107
+ // const mockResponse = {
108
+ // result: true,
109
+ // detail: [{ confidence: 0.95 }],
110
+ // card_obb: [{
111
+ // obb: [[400,800], [2600,800], [2600,2200], [400,2200]],
112
+ // confidence: 0.95,
113
+ // card_in_frame: false, // Hardcoded to false
114
+ // cropped_sides: ['left', 'top'] // Hardcoded cropped sides
115
+ // }],
116
+ // bbox: mockBbox,
117
+ // ...(result.regionMapping?.authMethod?.includes('MRZ') ? {
118
+ // mrz: {
119
+ // success: true,
120
+ // parsed_data: {
121
+ // status: 'success',
122
+ // document_type: result.selectedDocumentType,
123
+ // mrz_type: result.mrzType || 'TD1'
124
+ // }
125
+ // }
126
+ // } : {})
127
+ // };
128
+ // return mockResponse;
129
+ // }
130
+ // const token = await authentification();
131
+ // // Cast the response so TypeScript knows about card_obb
132
+ // const detected = await kycService.detectFaceOnId(result?.path || '', token, result?.selectedDocumentType || '', env) as ApiVerificationResponse;
133
+ // // ==========================================
134
+ // // 🧪 TEST OVERRIDE (PRODUCTION) 🧪
135
+ // // Hijack the real API response and force it to look cropped
136
+ // // ==========================================
137
+ // if (detected.card_obb && Array.isArray(detected.card_obb) && detected.card_obb.length > 0) {
138
+ // detected.card_obb[0].card_in_frame = false;
139
+ // detected.card_obb[0].cropped_sides = ['left', 'top'];
140
+ // console.warn("⚠️ FORCING CROPPED ERROR FOR UI TESTING ⚠️");
141
+ // }
142
+ // // ==========================================
143
+ // if (!detected.result) {
144
+ // throw new Error('Aucun visage détecté sur la carte. Veuillez reprendre.');
145
+ // }
146
+ // const cardData = detected.card_obb && Array.isArray(detected.card_obb) && detected.card_obb.length > 0
147
+ // ? detected.card_obb[0]
148
+ // : null;
149
+ // // --- STRICT FRAMING CHECK ---
150
+ // if (cardData && typeof cardData.card_in_frame !== 'undefined') {
151
+ // const isCardInFrame = cardData.card_in_frame === true;
152
+ // const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;
153
+ // // If it is NOT in the frame, OR if any side is cropped, block progression
154
+ // if (!isCardInFrame || hasCroppedSides) {
155
+ // logger.log(`Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);
156
+ // throw new Error('CARD_NOT_FULLY_IN_FRAME');
157
+ // }
158
+ // }
159
+ // // Check Confidence Threshold
160
+ // const obbConfidence = getObbConfidence(detected.card_obb);
161
+ // if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {
162
+ // throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
163
+ // }
164
+ // // Optional: crop image using card_obb for better MRZ/barcode extraction
165
+ // let croppedBase64: string | undefined;
166
+ // let bbox: IBbox | undefined;
167
+ // let mrz: any | undefined;
168
+ // try {
169
+ // const crop = await cropByObb(result?.path || '', detected.card_obb);
170
+ // croppedBase64 = crop.base64;
171
+ // bbox = crop.bbox;
172
+ // } catch { }
173
+ // // MRZ Extraction
174
+ // if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('MRZ')) {
175
+ // mrz = await kycService.extractMrzText(
176
+ // {
177
+ // fileUri: result.path || '',
178
+ // docType: result?.selectedDocumentType || '',
179
+ // docRegion: result?.code || "",
180
+ // postfix: result?.currentSide,
181
+ // token: token,
182
+ // template_path: result?.templatePath || '',
183
+ // mrz_type: result?.mrzType || ''
184
+ // },
185
+ // env
186
+ // );
187
+ // }
188
+ // return { ...detected, croppedBase64, bbox, ...(mrz ? { mrz } : {}) };
189
+ // } catch (e: any) {
190
+ // logger.error('Error front verification:', JSON.stringify(errorMessage(e), null, 2));
191
+ // throw new Error(e?.message || 'Erreur de détection du visage');
192
+ // }
193
+ // }
74
194
  export async function backVerification(result, env = 'PRODUCTION') {
75
195
  try {
76
196
  if (!result.path)
77
197
  throw new Error('No path provided');
78
198
  logger.log("result.regionMapping", result.regionMapping, result.currentSide, result.code);
79
- // SANDBOX mode: skip AI verification and return mock response
80
199
  if (env === 'SANDBOX') {
81
200
  console.log("SANDBOX mode: Skipping AI verification for back document");
82
- logger.log("SANDBOX mode: Returning mock back verification response");
83
- const mockBbox = { minX: 50, minY: 50, width: 200, height: 200 };
84
- if (result.regionMapping.authMethod.includes('MRZ')) {
201
+ const mockBbox = { minX: 400, minY: 800, width: 2200, height: 1400 };
202
+ const mockCardObb = [{
203
+ obb: [[400, 800], [2600, 800], [2600, 2200], [400, 2200]],
204
+ confidence: 0.95,
205
+ card_in_frame: true,
206
+ cropped_sides: []
207
+ }];
208
+ if (result.regionMapping?.authMethod?.includes('MRZ')) {
85
209
  return {
86
210
  success: true,
87
211
  parsed_data: {
@@ -90,20 +214,54 @@ export async function backVerification(result, env = 'PRODUCTION') {
90
214
  mrz_type: result.mrzType || 'TD1'
91
215
  },
92
216
  bbox: mockBbox,
93
- card_obb: { x: 50, y: 50, width: 200, height: 200 }
217
+ card_obb: mockCardObb
94
218
  };
95
219
  }
96
- else if (result.regionMapping.authMethod.includes('2D_barcode')) {
220
+ else if (result.regionMapping?.authMethod?.includes('2D_barcode')) {
97
221
  return {
98
222
  barcode_data: 'SANDBOX_MOCK_BARCODE',
99
223
  bbox: mockBbox,
100
- card_obb: { x: 50, y: 50, width: 200, height: 200 }
224
+ card_obb: mockCardObb
101
225
  };
102
226
  }
103
227
  return { bbox: mockBbox };
104
228
  }
105
229
  const token = await authentification();
106
- // Fonction helper pour essayer MRZ puis barcode en fallback
230
+ logger.log("1. Checking template and framing for back document...");
231
+ const templateResponse = await kycService.checkTemplateType({
232
+ fileUri: result.path,
233
+ docType: result.selectedDocumentType,
234
+ docRegion: result.code,
235
+ postfix: 'back',
236
+ token: token
237
+ }, env);
238
+ // STRICT FRAMING CHECK
239
+ const cardData = templateResponse?.card_obb && Array.isArray(templateResponse.card_obb) && templateResponse.card_obb.length > 0
240
+ ? templateResponse.card_obb[0]
241
+ : null;
242
+ if (cardData && typeof cardData.card_in_frame !== 'undefined') {
243
+ const isCardInFrame = cardData.card_in_frame === true;
244
+ const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;
245
+ if (!isCardInFrame || hasCroppedSides) {
246
+ logger.log(`Back Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);
247
+ throw new Error('CARD_NOT_FULLY_IN_FRAME');
248
+ }
249
+ }
250
+ const obbConf = getObbConfidence(templateResponse?.card_obb);
251
+ if (obbConf !== null && obbConf < OBB_CONFIDENCE_THRESHOLD) {
252
+ throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
253
+ }
254
+ const activeTemplatePath = templateResponse.template_path || result.templatePath || '';
255
+ if (activeTemplatePath) {
256
+ const expectedCountryName = countryData[result.code]?.name_en || '';
257
+ const hasCodeMatch = activeTemplatePath.includes(`_${result.code}_`);
258
+ const hasNameMatch = expectedCountryName && activeTemplatePath.toLowerCase().includes(expectedCountryName.toLowerCase());
259
+ if (!hasCodeMatch && !hasNameMatch) {
260
+ logger.log(`Template mismatch! Expected country: ${result.code} (${expectedCountryName}), Detected: ${activeTemplatePath}`);
261
+ throw new Error(`Le document ne correspond pas au pays sélectionné (${result.code}).`);
262
+ }
263
+ }
264
+ logger.log("Framing and Country Template verified successfully. Proceeding to Data Extraction.");
107
265
  const tryMrzWithBarcodeFallback = async () => {
108
266
  try {
109
267
  logger.log("Tentative d'extraction MRZ");
@@ -113,17 +271,14 @@ export async function backVerification(result, env = 'PRODUCTION') {
113
271
  docRegion: result?.code || '',
114
272
  postfix: 'back',
115
273
  token: token,
116
- template_path: result?.templatePath || '',
274
+ template_path: activeTemplatePath, // Use the verified template
117
275
  mrz_type: result?.mrzType || ''
118
276
  }, env);
119
- const mrzObbConf = getObbConfidence(mrz.card_obb);
120
- if (mrzObbConf !== null && mrzObbConf < OBB_CONFIDENCE_THRESHOLD) {
121
- throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
122
- }
123
277
  let bbox;
124
278
  let croppedBase64;
125
279
  try {
126
- const crop = await cropByObb(result?.path || '', mrz.card_obb);
280
+ // We use the OBB from our template check to ensure clean cropping
281
+ const crop = await cropByObb(result?.path || '', templateResponse.card_obb);
127
282
  bbox = crop.bbox;
128
283
  croppedBase64 = crop.base64;
129
284
  }
@@ -134,10 +289,6 @@ export async function backVerification(result, env = 'PRODUCTION') {
134
289
  logger.log("MRZ échoué, tentative d'extraction barcode");
135
290
  try {
136
291
  const barcode = await kycService.extractBarcode({ fileUri: result.path, token: token }, env);
137
- const barcodeObbConf = getObbConfidence(barcode.card_obb);
138
- if (barcodeObbConf !== null && barcodeObbConf < OBB_CONFIDENCE_THRESHOLD) {
139
- throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
140
- }
141
292
  return barcode;
142
293
  }
143
294
  catch (barcodeError) {
@@ -145,28 +296,23 @@ export async function backVerification(result, env = 'PRODUCTION') {
145
296
  }
146
297
  }
147
298
  };
148
- if (result.regionMapping.authMethod.length > 2 && (!result?.mrzType || result?.mrzType.length === 0)) {
299
+ if (result.regionMapping?.authMethod?.length > 2 && (!result?.mrzType || result?.mrzType.length === 0)) {
149
300
  return await tryMrzWithBarcodeFallback();
150
301
  }
151
- if (result.regionMapping.authMethod.length > 0 && result.regionMapping.authMethod.includes('MRZ') && result?.mrzType && result?.mrzType.length > 0) {
302
+ if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('MRZ') && result?.mrzType && result?.mrzType.length > 0) {
152
303
  try {
153
- let mrz;
154
- mrz = await kycService.extractMrzText({
304
+ const mrz = await kycService.extractMrzText({
155
305
  fileUri: result.path,
156
306
  docType: result?.selectedDocumentType || '',
157
307
  docRegion: result?.code || '',
158
308
  postfix: 'back',
159
309
  token: token,
160
- template_path: result?.templatePath || '',
310
+ template_path: activeTemplatePath,
161
311
  mrz_type: result?.mrzType || ''
162
312
  }, env);
163
- const mrzObbConf = getObbConfidence(mrz.card_obb);
164
- if (mrzObbConf !== null && mrzObbConf < OBB_CONFIDENCE_THRESHOLD) {
165
- throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
166
- }
167
313
  let bbox;
168
314
  try {
169
- const crop = await cropByObb(result?.path || '', mrz.card_obb);
315
+ const crop = await cropByObb(result?.path || '', templateResponse.card_obb);
170
316
  bbox = crop.bbox;
171
317
  }
172
318
  catch { }
@@ -176,17 +322,13 @@ export async function backVerification(result, env = 'PRODUCTION') {
176
322
  throw new Error(`MRZ et barcode ont échoué. MRZ: ${mrzError?.message}, Barcode: ${mrzError?.message}`);
177
323
  }
178
324
  }
179
- if (result.regionMapping.authMethod.length > 0 && result.regionMapping.authMethod.includes('2D_barcode')) {
325
+ if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('2D_barcode')) {
180
326
  try {
181
327
  logger.log("Tentative d'extraction barcode");
182
328
  const barcode = await kycService.extractBarcode({ fileUri: result.path, token: token }, env);
183
- const barcodeObbConf = getObbConfidence(barcode.card_obb);
184
- if (barcodeObbConf !== null && barcodeObbConf < OBB_CONFIDENCE_THRESHOLD) {
185
- throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');
186
- }
187
329
  let bbox;
188
330
  try {
189
- const crop = await cropByObb(result?.path || '', barcode.card_obb);
331
+ const crop = await cropByObb(result?.path || '', templateResponse.card_obb);
190
332
  bbox = crop.bbox;
191
333
  }
192
334
  catch { }
@@ -199,6 +341,8 @@ export async function backVerification(result, env = 'PRODUCTION') {
199
341
  return null;
200
342
  }
201
343
  catch (e) {
344
+ if (e?.message === 'CARD_NOT_FULLY_IN_FRAME')
345
+ throw e; // Bubble the strict framing error specifically
202
346
  throw new Error(e?.message || 'Erreur de détection du MRZ ou barcode');
203
347
  }
204
348
  }
@@ -209,22 +353,43 @@ export async function backVerification(result, env = 'PRODUCTION') {
209
353
  */
210
354
  export async function checkTemplateType(result, env = 'PRODUCTION') {
211
355
  try {
212
- // SANDBOX mode: skip AI verification and return mock response
213
356
  if (env === 'SANDBOX') {
214
- console.log("SANDBOX mode: Skipping AI template type check");
215
- logger.log("SANDBOX mode: Returning mock template type response");
216
357
  return {
217
358
  template_path: `templates/${result.docType}_${result.docRegion}_${result.postfix}.jpg`,
218
- card_obb: { x: 50, y: 50, width: 200, height: 200 }
359
+ card_obb: [{
360
+ obb: [[400, 800], [2600, 800], [2600, 2200], [400, 2200]],
361
+ confidence: 0.95,
362
+ card_in_frame: true,
363
+ cropped_sides: []
364
+ }]
219
365
  };
220
366
  }
221
367
  const token = await authentification();
222
368
  const templateType = await kycService.checkTemplateType({ fileUri: result.path || '', docType: result?.docType, docRegion: result?.docRegion || "", postfix: result?.postfix, token: token }, env);
369
+ const cardData = templateType.card_obb && Array.isArray(templateType.card_obb) && templateType.card_obb.length > 0
370
+ ? templateType.card_obb[0]
371
+ : null;
372
+ if (cardData && typeof cardData.card_in_frame !== 'undefined') {
373
+ const isCardInFrame = cardData.card_in_frame === true;
374
+ const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;
375
+ if (!isCardInFrame || hasCroppedSides) {
376
+ logger.log(`Template Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);
377
+ throw new Error('CARD_NOT_FULLY_IN_FRAME');
378
+ }
379
+ }
380
+ const LPIPS_THRESHOLD = 0.75;
381
+ if (templateType.lpips_score !== undefined && templateType.lpips_score > LPIPS_THRESHOLD) {
382
+ logger.log(`🛑 Country Mismatch! LPIPS Score too high: ${templateType.lpips_score}`);
383
+ throw new Error(`Le document présenté ne correspond pas au pays sélectionné (${result.docRegion}).`);
384
+ }
223
385
  logger.log("templateType result", JSON.stringify(truncateFields(templateType), null, 2));
224
386
  return templateType;
225
387
  }
226
388
  catch (e) {
227
389
  logger.error('Error checking template type:', JSON.stringify(errorMessage(e), null, 2));
390
+ if (e?.message === 'CARD_NOT_FULLY_IN_FRAME' || e?.message?.includes('ne correspond pas')) {
391
+ throw e;
392
+ }
228
393
  throw new Error(e?.message || 'Erreur de vérification du template');
229
394
  }
230
395
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CardAuthentification.js","sourceRoot":"","sources":["../../../src/modules/api/CardAuthentification.ts"],"names":[],"mappings":"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","sourcesContent":["import kycService, { authentification, errorMessage, truncateFields } from \"./KYCService\";\nimport { cropByObb, getCardInFrame, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from \"../../utils/cropByObb\";\nimport { GovernmentDocumentType, IBbox } from \"../../types/KYC.types\";\nimport { KycEnvironment } from \"../../types/env.types\";\nimport { logger } from \"../../utils/logger\";\n\nexport async function frontVerification(result: { path?: string, regionMapping: { authMethod: string[], mrzTypes: string[] }, selectedDocumentType: string, code: string, currentSide: string, templatePath?: string, mrzType?: string }, env: KycEnvironment = 'PRODUCTION') {\n try {\n console.log(\"Front verification START\", JSON.stringify({ result }, null, 2));\n logger.log(\"Front verification\", JSON.stringify({ result }, null, 2));\n \n // SANDBOX mode: skip AI verification and return mock response\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI verification for front document\");\n logger.log(\"SANDBOX mode: Returning mock front verification response\");\n const mockBbox: IBbox = { minX: 50, minY: 50, width: 200, height: 200 };\n const mockResponse = {\n result: true,\n detail: [{ confidence: 0.95 }],\n card_obb: { x: 50, y: 50, width: 200, height: 200 },\n bbox: mockBbox,\n ...(result.regionMapping.authMethod.includes('MRZ') ? {\n mrz: {\n success: true,\n parsed_data: {\n status: 'success',\n document_type: result.selectedDocumentType,\n mrz_type: result.mrzType || 'TD1'\n }\n }\n } : {})\n };\n return mockResponse;\n }\n \n const token = await authentification();\n const detected = await kycService.detectFaceOnId(result?.path || '', token, result?.selectedDocumentType || '', env)\n\n if (!detected.result) {\n throw new Error('Aucun visage détecté sur la carte. Veuillez reprendre.');\n }\n\n // If the backend indicates that the card is not fully in frame, stop early\n const cardInFrame = getCardInFrame((detected as any).card_obb);\n if (cardInFrame === false) {\n // Use a stable error code; the UI maps this to a localized i18n message (cardNotFullyInFrame)\n throw new Error('CARD_NOT_FULLY_IN_FRAME');\n }\n\n const obbConfidence = getObbConfidence((detected as any).card_obb);\n if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n\n // Optional: crop image using card_obb for better MRZ/barcode extraction (only when confidence >= threshold)\n let croppedBase64: string | undefined;\n let bbox: IBbox | undefined;\n let mrz: any | undefined;\n try {\n const crop = await cropByObb(result?.path || '', (detected as any).card_obb);\n croppedBase64 = crop.base64;\n bbox = crop.bbox;\n } catch { }\n\n if (result.regionMapping.authMethod.length > 0 && result.regionMapping.authMethod.includes('MRZ')) {\n\n\n mrz = await kycService.extractMrzText(\n {\n fileUri: result.path || '',\n docType: result?.selectedDocumentType || '',\n docRegion: result?.code || \"\",\n postfix: result?.currentSide,\n token: token,\n template_path: result?.templatePath || '',\n mrz_type: result?.mrzType || ''\n },\n env)\n\n }\n\n return { ...detected, croppedBase64, bbox, ...(mrz ? { mrz } : {}) };\n } catch (e: any) {\n logger.error('Error front verification:', JSON.stringify(errorMessage(e), null, 2));\n throw new Error(e?.message || 'Erreur de détection du visage');\n }\n}\n\nexport async function backVerification(result: { path?: string, regionMapping: { authMethod: string[], mrzTypes: string[] }, selectedDocumentType: string, code: string, currentSide: string, templatePath?: string, mrzType?: string }, env: KycEnvironment = 'PRODUCTION') {\n try {\n if (!result.path) throw new Error('No path provided');\n logger.log(\"result.regionMapping\", result.regionMapping, result.currentSide, result.code);\n \n // SANDBOX mode: skip AI verification and return mock response\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI verification for back document\");\n logger.log(\"SANDBOX mode: Returning mock back verification response\");\n const mockBbox: IBbox = { minX: 50, minY: 50, width: 200, height: 200 };\n \n if (result.regionMapping.authMethod.includes('MRZ')) {\n return {\n success: true,\n parsed_data: {\n status: 'success',\n document_type: result.selectedDocumentType,\n mrz_type: result.mrzType || 'TD1'\n },\n bbox: mockBbox,\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n } else if (result.regionMapping.authMethod.includes('2D_barcode')) {\n return {\n barcode_data: 'SANDBOX_MOCK_BARCODE',\n bbox: mockBbox,\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n return { bbox: mockBbox };\n }\n \n const token = await authentification();\n\n\n\n // Fonction helper pour essayer MRZ puis barcode en fallback\n const tryMrzWithBarcodeFallback = async () => {\n try {\n\n logger.log(\"Tentative d'extraction MRZ\");\n const mrz = await kycService.extractMrzText({\n fileUri: result.path!,\n docType: result?.selectedDocumentType || '',\n docRegion: result?.code || '',\n postfix: 'back',\n token: token,\n template_path: result?.templatePath || '',\n mrz_type: result?.mrzType || ''\n }, env);\n const mrzObbConf = getObbConfidence((mrz as any).card_obb);\n if (mrzObbConf !== null && mrzObbConf < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n let bbox: IBbox | undefined;\n let croppedBase64: string | undefined;\n\n try {\n const crop = await cropByObb(result?.path || '', (mrz as any).card_obb);\n bbox = crop.bbox;\n croppedBase64 = crop.base64;\n\n } catch { }\n return { ...mrz, bbox, croppedBase64 }\n } catch (mrzError: any) {\n logger.log(\"MRZ échoué, tentative d'extraction barcode\");\n try {\n const barcode = await kycService.extractBarcode({ fileUri: result.path!, token: token }, env);\n const barcodeObbConf = getObbConfidence((barcode as any).card_obb);\n if (barcodeObbConf !== null && barcodeObbConf < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n return barcode;\n } catch (barcodeError: any) {\n throw new Error(`MRZ et barcode ont échoué. MRZ: ${mrzError?.message}, Barcode: ${barcodeError?.message}`);\n }\n }\n };\n\n\n\n if (result.regionMapping.authMethod.length > 2 && (!result?.mrzType || result?.mrzType.length === 0)) {\n return await tryMrzWithBarcodeFallback();\n }\n\n if (result.regionMapping.authMethod.length > 0 && result.regionMapping.authMethod.includes('MRZ') && result?.mrzType && result?.mrzType.length > 0) {\n try {\n\n let mrz: any | undefined;\n mrz = await kycService.extractMrzText({\n fileUri: result.path!,\n docType: result?.selectedDocumentType || '',\n docRegion: result?.code || '',\n postfix: 'back',\n token: token,\n template_path: result?.templatePath || '',\n mrz_type: result?.mrzType || ''\n }, env);\n const mrzObbConf = getObbConfidence((mrz as any).card_obb);\n if (mrzObbConf !== null && mrzObbConf < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n let bbox: IBbox | undefined;\n try {\n const crop = await cropByObb(result?.path || '', (mrz as any).card_obb);\n bbox = crop.bbox;\n } catch { }\n return { ...mrz, bbox };\n } catch (mrzError: any) {\n throw new Error(`MRZ et barcode ont échoué. MRZ: ${mrzError?.message}, Barcode: ${mrzError?.message}`);\n }\n }\n\n if (result.regionMapping.authMethod.length > 0 && result.regionMapping.authMethod.includes('2D_barcode')) {\n try {\n logger.log(\"Tentative d'extraction barcode\");\n const barcode = await kycService.extractBarcode({ fileUri: result.path!, token: token }, env);\n const barcodeObbConf = getObbConfidence((barcode as any).card_obb);\n if (barcodeObbConf !== null && barcodeObbConf < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n let bbox: IBbox | undefined;\n try {\n const crop = await cropByObb(result?.path || '', (barcode as any).card_obb);\n bbox = crop.bbox;\n } catch { }\n return { ...barcode, bbox };\n } catch (barcodeError: any) {\n throw new Error(`Barcode et MRZ ont échoué. Barcode: ${barcodeError?.message}, MRZ: ${barcodeError?.message}`);\n }\n }\n return null;\n } catch (e: any) {\n throw new Error(e?.message || 'Erreur de détection du MRZ ou barcode');\n }\n}\n\n/**\n * Check template type\n * @param result \n * @returns \n */\nexport async function checkTemplateType(result: { path?: string, docType: string, docRegion: string, postfix: string }, env: KycEnvironment = 'PRODUCTION') {\n try {\n // SANDBOX mode: skip AI verification and return mock response\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI template type check\");\n logger.log(\"SANDBOX mode: Returning mock template type response\");\n return {\n template_path: `templates/${result.docType}_${result.docRegion}_${result.postfix}.jpg`,\n card_obb: { x: 50, y: 50, width: 200, height: 200 }\n };\n }\n \n const token = await authentification();\n const templateType = await kycService.checkTemplateType({ fileUri: result.path || '', docType: result?.docType as GovernmentDocumentType, docRegion: result?.docRegion || \"\", postfix: result?.postfix, token: token }, env);\n\n logger.log(\"templateType result\", JSON.stringify(truncateFields(templateType), null, 2));\n return templateType;\n } catch (e: any) {\n logger.error('Error checking template type:', JSON.stringify(errorMessage(e), null, 2));\n throw new Error(e?.message || 'Erreur de vérification du template');\n }\n}"]}
1
+ {"version":3,"file":"CardAuthentification.js","sourceRoot":"","sources":["../../../src/modules/api/CardAuthentification.ts"],"names":[],"mappings":"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","sourcesContent":["import kycService, { authentification, errorMessage, truncateFields } from \"./KYCService\";\nimport { cropByObb, getObbConfidence, OBB_CONFIDENCE_THRESHOLD } from \"../../utils/cropByObb\";\nimport { GovernmentDocumentType, IBbox } from \"../../types/KYC.types\";\nimport { KycEnvironment } from \"../../types/env.types\";\nimport { logger } from \"../../utils/logger\";\nimport { countryData } from \"../../config/countriesData\";\n\n// 1. Add this interface to tell TypeScript what the AI response actually looks like\ninterface CardObbData {\n obb: number[][];\n confidence: number;\n card_in_frame?: boolean;\n cropped_sides?: string[];\n}\n\ninterface ApiVerificationResponse {\n result?: boolean;\n detail?: any[];\n card_obb?: CardObbData[] | any; \n [key: string]: any; \n}\n\nexport async function frontVerification(\n result: { path?: string, regionMapping: { authMethod: string[], mrzTypes: string[] }, selectedDocumentType: string, code: string, currentSide: string, templatePath?: string, mrzType?: string }, \n env: KycEnvironment = 'PRODUCTION'\n) {\n try {\n console.log(\"Front verification START\", JSON.stringify({ result }, null, 2));\n logger.log(\"Front verification\", JSON.stringify({ result }, null, 2));\n \n // SANDBOX mode\n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI verification for front document\");\n logger.log(\"SANDBOX mode: Returning mock front verification response\");\n const mockBbox: IBbox = { minX: 400, minY: 800, width: 2200, height: 1400 };\n \n const mockResponse = {\n result: true,\n detail: [{ confidence: 0.95 }],\n card_obb: [{\n obb: [[400,800], [2600,800], [2600,2200], [400,2200]],\n confidence: 0.95,\n card_in_frame: true,\n cropped_sides: []\n }],\n bbox: mockBbox,\n ...(result.regionMapping?.authMethod?.includes('MRZ') ? {\n mrz: {\n success: true,\n parsed_data: {\n status: 'success',\n document_type: result.selectedDocumentType,\n mrz_type: result.mrzType || 'TD1'\n }\n }\n } : {})\n };\n return mockResponse;\n }\n \n const token = await authentification();\n \n // Cast the response so TypeScript knows about card_obb\n const detected = await kycService.detectFaceOnId(result?.path || '', token, result?.selectedDocumentType || '', env) as ApiVerificationResponse;\n\n if (!detected.result) {\n throw new Error('Aucun visage détecté sur la carte. Veuillez reprendre.');\n }\n\n const cardData = detected.card_obb && Array.isArray(detected.card_obb) && detected.card_obb.length > 0 \n ? detected.card_obb[0] \n : null;\n\n // --- STRICT FRAMING CHECK ---\n if (cardData && typeof cardData.card_in_frame !== 'undefined') {\n const isCardInFrame = cardData.card_in_frame === true;\n const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;\n\n // If it is NOT in the frame, OR if any side is cropped, block progression\n if (!isCardInFrame || hasCroppedSides) {\n logger.log(`Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);\n throw new Error('CARD_NOT_FULLY_IN_FRAME');\n }\n }\n\n // Check Confidence Threshold\n const obbConfidence = getObbConfidence(detected.card_obb);\n if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n\n // Optional: crop image using card_obb for better MRZ/barcode extraction\n let croppedBase64: string | undefined;\n let bbox: IBbox | undefined;\n let mrz: any | undefined;\n try {\n const crop = await cropByObb(result?.path || '', detected.card_obb);\n croppedBase64 = crop.base64;\n bbox = crop.bbox;\n } catch { }\n\n // MRZ Extraction\n if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('MRZ')) {\n mrz = await kycService.extractMrzText(\n {\n fileUri: result.path || '',\n docType: result?.selectedDocumentType || '',\n docRegion: result?.code || \"\",\n postfix: result?.currentSide,\n token: token,\n template_path: result?.templatePath || '',\n mrz_type: result?.mrzType || ''\n },\n env\n );\n }\n\n return { ...detected, croppedBase64, bbox, ...(mrz ? { mrz } : {}) };\n } catch (e: any) {\n logger.error('Error front verification:', JSON.stringify(errorMessage(e), null, 2));\n throw new Error(e?.message || 'Erreur de détection du visage');\n }\n}\n\n// export async function frontVerification(\n// result: { path?: string, regionMapping: { authMethod: string[], mrzTypes: string[] }, selectedDocumentType: string, code: string, currentSide: string, templatePath?: string, mrzType?: string }, \n// env: KycEnvironment = 'PRODUCTION'\n// ) {\n// try {\n// console.log(\"Front verification START\", JSON.stringify({ result }, null, 2));\n// logger.log(\"Front verification\", JSON.stringify({ result }, null, 2));\n \n// // SANDBOX mode\n// if (env === 'SANDBOX') {\n// console.log(\"SANDBOX mode: Skipping AI verification for front document\");\n// logger.log(\"SANDBOX mode: Returning mock front verification response\");\n// const mockBbox: IBbox = { minX: 400, minY: 800, width: 2200, height: 1400 };\n \n// // ==========================================\n// // 🧪 TEST OVERRIDE (SANDBOX) 🧪\n// // Immediately throw the error to test the UI\n// // ==========================================\n// throw new Error('CARD_NOT_FULLY_IN_FRAME'); \n\n// const mockResponse = {\n// result: true,\n// detail: [{ confidence: 0.95 }],\n// card_obb: [{\n// obb: [[400,800], [2600,800], [2600,2200], [400,2200]],\n// confidence: 0.95,\n// card_in_frame: false, // Hardcoded to false\n// cropped_sides: ['left', 'top'] // Hardcoded cropped sides\n// }],\n// bbox: mockBbox,\n// ...(result.regionMapping?.authMethod?.includes('MRZ') ? {\n// mrz: {\n// success: true,\n// parsed_data: {\n// status: 'success',\n// document_type: result.selectedDocumentType,\n// mrz_type: result.mrzType || 'TD1'\n// }\n// }\n// } : {})\n// };\n// return mockResponse;\n// }\n \n// const token = await authentification();\n \n// // Cast the response so TypeScript knows about card_obb\n// const detected = await kycService.detectFaceOnId(result?.path || '', token, result?.selectedDocumentType || '', env) as ApiVerificationResponse;\n\n// // ==========================================\n// // 🧪 TEST OVERRIDE (PRODUCTION) 🧪\n// // Hijack the real API response and force it to look cropped\n// // ==========================================\n// if (detected.card_obb && Array.isArray(detected.card_obb) && detected.card_obb.length > 0) {\n// detected.card_obb[0].card_in_frame = false;\n// detected.card_obb[0].cropped_sides = ['left', 'top'];\n// console.warn(\"⚠️ FORCING CROPPED ERROR FOR UI TESTING ⚠️\");\n// }\n// // ==========================================\n\n// if (!detected.result) {\n// throw new Error('Aucun visage détecté sur la carte. Veuillez reprendre.');\n// }\n\n// const cardData = detected.card_obb && Array.isArray(detected.card_obb) && detected.card_obb.length > 0 \n// ? detected.card_obb[0] \n// : null;\n\n// // --- STRICT FRAMING CHECK ---\n// if (cardData && typeof cardData.card_in_frame !== 'undefined') {\n// const isCardInFrame = cardData.card_in_frame === true;\n// const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;\n\n// // If it is NOT in the frame, OR if any side is cropped, block progression\n// if (!isCardInFrame || hasCroppedSides) {\n// logger.log(`Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);\n// throw new Error('CARD_NOT_FULLY_IN_FRAME');\n// }\n// }\n\n// // Check Confidence Threshold\n// const obbConfidence = getObbConfidence(detected.card_obb);\n// if (obbConfidence !== null && obbConfidence < OBB_CONFIDENCE_THRESHOLD) {\n// throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n// }\n\n// // Optional: crop image using card_obb for better MRZ/barcode extraction\n// let croppedBase64: string | undefined;\n// let bbox: IBbox | undefined;\n// let mrz: any | undefined;\n// try {\n// const crop = await cropByObb(result?.path || '', detected.card_obb);\n// croppedBase64 = crop.base64;\n// bbox = crop.bbox;\n// } catch { }\n\n// // MRZ Extraction\n// if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('MRZ')) {\n// mrz = await kycService.extractMrzText(\n// {\n// fileUri: result.path || '',\n// docType: result?.selectedDocumentType || '',\n// docRegion: result?.code || \"\",\n// postfix: result?.currentSide,\n// token: token,\n// template_path: result?.templatePath || '',\n// mrz_type: result?.mrzType || ''\n// },\n// env\n// );\n// }\n\n// return { ...detected, croppedBase64, bbox, ...(mrz ? { mrz } : {}) };\n// } catch (e: any) {\n// logger.error('Error front verification:', JSON.stringify(errorMessage(e), null, 2));\n// throw new Error(e?.message || 'Erreur de détection du visage');\n// }\n// }\n\n\nexport async function backVerification(\n result: { path?: string, regionMapping: { authMethod: string[], mrzTypes: string[] }, selectedDocumentType: string, code: string, currentSide: string, templatePath?: string, mrzType?: string }, \n env: KycEnvironment = 'PRODUCTION'\n) {\n try {\n if (!result.path) throw new Error('No path provided');\n logger.log(\"result.regionMapping\", result.regionMapping, result.currentSide, result.code);\n \n \n if (env === 'SANDBOX') {\n console.log(\"SANDBOX mode: Skipping AI verification for back document\");\n \n const mockBbox: IBbox = { minX: 400, minY: 800, width: 2200, height: 1400 };\n const mockCardObb = [{\n obb: [[400,800], [2600,800], [2600,2200], [400,2200]],\n confidence: 0.95,\n card_in_frame: true,\n cropped_sides: []\n }];\n \n if (result.regionMapping?.authMethod?.includes('MRZ')) {\n return {\n success: true,\n parsed_data: {\n status: 'success',\n document_type: result.selectedDocumentType,\n mrz_type: result.mrzType || 'TD1'\n },\n bbox: mockBbox,\n card_obb: mockCardObb\n };\n } else if (result.regionMapping?.authMethod?.includes('2D_barcode')) {\n return {\n barcode_data: 'SANDBOX_MOCK_BARCODE',\n bbox: mockBbox,\n card_obb: mockCardObb\n };\n }\n return { bbox: mockBbox };\n }\n \n const token = await authentification();\n\n \n logger.log(\"1. Checking template and framing for back document...\");\n \n const templateResponse = await kycService.checkTemplateType({\n fileUri: result.path,\n docType: result.selectedDocumentType as any,\n docRegion: result.code,\n postfix: 'back',\n token: token\n }, env) as ApiVerificationResponse;\n\n // STRICT FRAMING CHECK\n const cardData = templateResponse?.card_obb && Array.isArray(templateResponse.card_obb) && templateResponse.card_obb.length > 0 \n ? templateResponse.card_obb[0] \n : null;\n\n if (cardData && typeof cardData.card_in_frame !== 'undefined') {\n const isCardInFrame = cardData.card_in_frame === true;\n const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;\n\n if (!isCardInFrame || hasCroppedSides) {\n logger.log(`Back Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);\n throw new Error('CARD_NOT_FULLY_IN_FRAME');\n }\n }\n \n const obbConf = getObbConfidence(templateResponse?.card_obb);\n if (obbConf !== null && obbConf < OBB_CONFIDENCE_THRESHOLD) {\n throw new Error('Carte non entièrement visible. Positionnez toute la carte dans le cadre.');\n }\n\n\n const activeTemplatePath = templateResponse.template_path || result.templatePath || '';\n \n if (activeTemplatePath) {\n const expectedCountryName = countryData[result.code]?.name_en || '';\n \n const hasCodeMatch = activeTemplatePath.includes(`_${result.code}_`);\n const hasNameMatch = expectedCountryName && activeTemplatePath.toLowerCase().includes(expectedCountryName.toLowerCase());\n\n if (!hasCodeMatch && !hasNameMatch) {\n logger.log(`Template mismatch! Expected country: ${result.code} (${expectedCountryName}), Detected: ${activeTemplatePath}`);\n throw new Error(`Le document ne correspond pas au pays sélectionné (${result.code}).`);\n }\n }\n\n logger.log(\"Framing and Country Template verified successfully. Proceeding to Data Extraction.\");\n\n \n const tryMrzWithBarcodeFallback = async () => {\n try {\n logger.log(\"Tentative d'extraction MRZ\");\n const mrz = await kycService.extractMrzText({\n fileUri: result.path!,\n docType: result?.selectedDocumentType || '',\n docRegion: result?.code || '',\n postfix: 'back',\n token: token,\n template_path: activeTemplatePath, // Use the verified template\n mrz_type: result?.mrzType || ''\n }, env);\n \n let bbox: IBbox | undefined;\n let croppedBase64: string | undefined;\n\n try {\n // We use the OBB from our template check to ensure clean cropping\n const crop = await cropByObb(result?.path || '', templateResponse.card_obb);\n bbox = crop.bbox;\n croppedBase64 = crop.base64;\n } catch { }\n return { ...mrz, bbox, croppedBase64 }\n \n } catch (mrzError: any) {\n logger.log(\"MRZ échoué, tentative d'extraction barcode\");\n try {\n const barcode = await kycService.extractBarcode({ fileUri: result.path!, token: token }, env);\n return barcode;\n } catch (barcodeError: any) {\n throw new Error(`MRZ et barcode ont échoué. MRZ: ${mrzError?.message}, Barcode: ${barcodeError?.message}`);\n }\n }\n };\n\n if (result.regionMapping?.authMethod?.length > 2 && (!result?.mrzType || result?.mrzType.length === 0)) {\n return await tryMrzWithBarcodeFallback();\n }\n\n if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('MRZ') && result?.mrzType && result?.mrzType.length > 0) {\n try {\n const mrz = await kycService.extractMrzText({\n fileUri: result.path!,\n docType: result?.selectedDocumentType || '',\n docRegion: result?.code || '',\n postfix: 'back',\n token: token,\n template_path: activeTemplatePath,\n mrz_type: result?.mrzType || ''\n }, env);\n \n let bbox: IBbox | undefined;\n try {\n const crop = await cropByObb(result?.path || '', templateResponse.card_obb);\n bbox = crop.bbox;\n } catch { }\n return { ...mrz, bbox };\n } catch (mrzError: any) {\n throw new Error(`MRZ et barcode ont échoué. MRZ: ${mrzError?.message}, Barcode: ${mrzError?.message}`);\n }\n }\n\n if (result.regionMapping?.authMethod?.length > 0 && result.regionMapping.authMethod.includes('2D_barcode')) {\n try {\n logger.log(\"Tentative d'extraction barcode\");\n const barcode = await kycService.extractBarcode({ fileUri: result.path!, token: token }, env);\n \n let bbox: IBbox | undefined;\n try {\n const crop = await cropByObb(result?.path || '', templateResponse.card_obb);\n bbox = crop.bbox;\n } catch { }\n return { ...barcode, bbox };\n } catch (barcodeError: any) {\n throw new Error(`Barcode et MRZ ont échoué. Barcode: ${barcodeError?.message}, MRZ: ${barcodeError?.message}`);\n }\n }\n return null;\n } catch (e: any) {\n if (e?.message === 'CARD_NOT_FULLY_IN_FRAME') throw e; // Bubble the strict framing error specifically\n throw new Error(e?.message || 'Erreur de détection du MRZ ou barcode');\n }\n}\n\n\n/**\n * Check template type\n * @param result \n * @returns \n */\nexport async function checkTemplateType(result: { path?: string, docType: string, docRegion: string, postfix: string }, env: KycEnvironment = 'PRODUCTION') {\n try {\n if (env === 'SANDBOX') {\n return {\n template_path: `templates/${result.docType}_${result.docRegion}_${result.postfix}.jpg`,\n card_obb: [{\n obb: [[400,800], [2600,800], [2600,2200], [400,2200]],\n confidence: 0.95,\n card_in_frame: true,\n cropped_sides: []\n }]\n };\n }\n \n const token = await authentification();\n const templateType = await kycService.checkTemplateType({ fileUri: result.path || '', docType: result?.docType as GovernmentDocumentType, docRegion: result?.docRegion || \"\", postfix: result?.postfix, token: token }, env);\n\n const cardData = templateType.card_obb && Array.isArray(templateType.card_obb) && templateType.card_obb.length > 0 \n ? templateType.card_obb[0] \n : null;\n\n if (cardData && typeof cardData.card_in_frame !== 'undefined') {\n const isCardInFrame = cardData.card_in_frame === true;\n const hasCroppedSides = Array.isArray(cardData.cropped_sides) && cardData.cropped_sides.length > 0;\n\n if (!isCardInFrame || hasCroppedSides) {\n logger.log(`Template Framing failed. Cropped sides: ${hasCroppedSides ? cardData.cropped_sides?.join(', ') : 'none'}`);\n throw new Error('CARD_NOT_FULLY_IN_FRAME');\n }\n }\n\n \n const LPIPS_THRESHOLD = 0.75; \n \n if (templateType.lpips_score !== undefined && templateType.lpips_score > LPIPS_THRESHOLD) {\n logger.log(`🛑 Country Mismatch! LPIPS Score too high: ${templateType.lpips_score}`);\n throw new Error(`Le document présenté ne correspond pas au pays sélectionné (${result.docRegion}).`);\n }\n\n logger.log(\"templateType result\", JSON.stringify(truncateFields(templateType), null, 2));\n return templateType;\n } catch (e: any) {\n logger.error('Error checking template type:', JSON.stringify(errorMessage(e), null, 2));\n \n if (e?.message === 'CARD_NOT_FULLY_IN_FRAME' || e?.message?.includes('ne correspond pas')) {\n throw e; \n }\n \n throw new Error(e?.message || 'Erreur de vérification du template');\n }\n}"]}
@@ -62,10 +62,12 @@ export declare class KYCService {
62
62
  docType: string;
63
63
  docRegion: string;
64
64
  token: string;
65
+ postfix?: string;
65
66
  }): Promise<any>;
66
67
  extractBarcode(params: {
67
68
  fileUri: string;
68
69
  token: string;
70
+ postfix?: string;
69
71
  }, env?: KycEnvironment): Promise<any>;
70
72
  extractMrzText(params: {
71
73
  fileUri: string;
@@ -1 +1 @@
1
- {"version":3,"file":"KYCService.d.ts","sourceRoot":"","sources":["../../../src/modules/api/KYCService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KYCService.d.ts","sourceRoot":"","sources":["../../../src/modules/api/KYCService.ts"],"names":[],"mappings":"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"}