@trustchex/react-native-sdk 1.495.10 → 1.495.12

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 (44) hide show
  1. package/android/build.gradle +10 -0
  2. package/android/libs/jj2000-5.2.jar +0 -0
  3. package/android/src/main/java/com/trustchex/reactnativesdk/ImageDecoderModule.kt +88 -0
  4. package/android/src/main/java/com/trustchex/reactnativesdk/Jp2PgxDecoder.kt +135 -0
  5. package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKPackage.kt +12 -0
  6. package/android/src/test/java/com/trustchex/reactnativesdk/Jp2PgxDecoderTest.kt +143 -0
  7. package/android/src/test/resources/jp2/gray.jp2 +0 -0
  8. package/android/src/test/resources/jp2/solid_color.j2k +0 -0
  9. package/android/src/test/resources/jp2/solid_color.jp2 +0 -0
  10. package/lib/module/Shared/Components/EIDScanner.js +8 -5
  11. package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +9 -0
  12. package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +57 -19
  13. package/lib/module/Shared/Components/IdentityDocumentCamera.js +69 -14
  14. package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +33 -4
  15. package/lib/module/Shared/EIDReader/eidReader.js +11 -9
  16. package/lib/module/Shared/Libs/jp2Decode.js +12 -11
  17. package/lib/module/Shared/Services/DataUploadService.js +16 -4
  18. package/lib/module/version.js +1 -1
  19. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  20. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +1 -0
  21. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -1
  22. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  23. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +2 -2
  24. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -1
  25. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +21 -0
  26. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -1
  27. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +15 -0
  28. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -1
  29. package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
  30. package/lib/typescript/src/Shared/Libs/jp2Decode.d.ts +4 -3
  31. package/lib/typescript/src/Shared/Libs/jp2Decode.d.ts.map +1 -1
  32. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -1
  33. package/lib/typescript/src/version.d.ts +1 -1
  34. package/package.json +1 -1
  35. package/src/Shared/Components/EIDScanner.tsx +7 -5
  36. package/src/Shared/Components/IdentityDocumentCamera.constants.ts +9 -0
  37. package/src/Shared/Components/IdentityDocumentCamera.flows.ts +78 -21
  38. package/src/Shared/Components/IdentityDocumentCamera.tsx +83 -27
  39. package/src/Shared/Components/IdentityDocumentCamera.types.ts +21 -0
  40. package/src/Shared/Components/IdentityDocumentCamera.utils.ts +36 -3
  41. package/src/Shared/EIDReader/eidReader.ts +11 -9
  42. package/src/Shared/Libs/jp2Decode.ts +15 -11
  43. package/src/Shared/Services/DataUploadService.ts +41 -8
  44. package/src/version.ts +1 -1
@@ -21,9 +21,9 @@ import { speak, resetLastMessage } from "../Libs/tts.utils.js";
21
21
  import AppContext from "../Contexts/AppContext.js";
22
22
  import { useTheme } from "../Contexts/ThemeContext.js";
23
23
  import DebugOverlay, { TestModePanel } from "./DebugOverlay.js";
24
- import { getStatusMessage, getFrameToScreenTransform, transformBoundsToScreen, getScanAreaBounds, angleBetweenPoints, detectDocumentType, determineDocumentTypeToSet, areMRZFieldsEqual, hasRequiredMRZFields, validateFacePosition } from "./IdentityDocumentCamera.utils.js";
24
+ import { getStatusMessage, getFrameToScreenTransform, transformBoundsToScreen, getScanAreaBounds, angleBetweenPoints, detectDocumentType, determineDocumentTypeToSet, areMRZFieldsEqual, hasRequiredMRZFields, validateFacePosition, isPassportDocumentCode } from "./IdentityDocumentCamera.utils.js";
25
25
  import { handlePassportFlow, handleIDFrontFlow, handleIDBackFlow, getNextStepAfterHologram } from "./IdentityDocumentCamera.flows.js";
26
- import { HOLOGRAM_IMAGE_COUNT, HOLOGRAM_DETECTION_THRESHOLD, HOLOGRAM_DETECTION_RETRY_COUNT, HOLOGRAM_CAPTURE_INTERVAL, HOLOGRAM_MAX_FRAMES_WITHOUT_FACE, MIN_BRIGHTNESS_THRESHOLD, MAX_BRIGHTNESS_THRESHOLD, FACE_EDGE_MARGIN_PERCENT, MAX_CONSECUTIVE_QUALITY_FAILURES, REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS, SIGNATURE_TEXT_REGEX, MRZ_BLOCK_PATTERN, PASSPORT_MRZ_PATTERN, MIN_CARD_FACE_SIZE_PERCENT } from "./IdentityDocumentCamera.constants.js";
26
+ import { HOLOGRAM_IMAGE_COUNT, HOLOGRAM_DETECTION_THRESHOLD, HOLOGRAM_DETECTION_RETRY_COUNT, HOLOGRAM_CAPTURE_INTERVAL, HOLOGRAM_MAX_FRAMES_WITHOUT_FACE, MIN_BRIGHTNESS_THRESHOLD, MAX_BRIGHTNESS_THRESHOLD, FACE_EDGE_MARGIN_PERCENT, MAX_CONSECUTIVE_QUALITY_FAILURES, REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS, SIGNATURE_TEXT_REGEX, MRZ_BLOCK_PATTERN, MIN_CARD_FACE_SIZE_PERCENT } from "./IdentityDocumentCamera.constants.js";
27
27
 
28
28
  // Re-export types for backward compatibility
29
29
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
@@ -104,6 +104,15 @@ const IdentityDocumentCamera = ({
104
104
  const lastDetectedDocType = useRef('UNKNOWN');
105
105
  const consistentDocTypeCount = useRef(0);
106
106
 
107
+ // Latches true the moment a passport MRZ pattern / 'P' document code is seen in
108
+ // ANY front frame this session. The passport MRZ is dense and often OCRs a few
109
+ // frames AFTER the face + signature, so without this a passport can be locked
110
+ // as ID_FRONT (which has no MRZ on its front) and then wrongly asked for a back
111
+ // side that does not exist. Once latched, the front is never accepted as
112
+ // ID_FRONT and the post-hologram routing always completes instead of scanning
113
+ // a back. Reset only when a brand-new scan session starts.
114
+ const sawPassportSignal = useRef(false);
115
+
107
116
  // Frame quality tracking - persist across callbacks
108
117
  const lastFrameQuality = useRef({
109
118
  hasAcceptableQuality: true,
@@ -197,6 +206,7 @@ const IdentityDocumentCamera = ({
197
206
  lastValidMRZText.current = null;
198
207
  lastValidMRZFields.current = null;
199
208
  validMRZConsecutiveCount.current = 0;
209
+ sawPassportSignal.current = false;
200
210
  mrzAggregator.current.reset();
201
211
  setMrzReliable(false);
202
212
  // Start a fresh diagnostics session for the support report.
@@ -441,6 +451,15 @@ const IdentityDocumentCamera = ({
441
451
 
442
452
  // Reset MRZ retry counter for each new step so retries start fresh
443
453
  mrzDetectionCurrentRetryCount.current = 0;
454
+ // A transition back to the initial front step means a brand-new document
455
+ // scan is starting, so the sticky passport signal from any previous
456
+ // document must NOT carry over — otherwise an ID card scanned after a
457
+ // passport (without the camera unfocusing) would be forced into the
458
+ // passport flow and skip its back side. (The focus-based reset above only
459
+ // fires when the camera goes inactive.)
460
+ if (nextStepType === 'SCAN_ID_FRONT_OR_PASSPORT') {
461
+ sawPassportSignal.current = false;
462
+ }
444
463
  // Only clear MRZ text when entering SCAN_ID_BACK (new MRZ expected).
445
464
  // Preserve across SCAN_HOLOGRAM so passport completion has MRZ data.
446
465
  if (nextStepType === 'SCAN_ID_BACK') {
@@ -798,22 +817,38 @@ const IdentityDocumentCamera = ({
798
817
  const hasFaces = primaryFaces.length > 0;
799
818
  const hasSignature = /signature|imza|İmza/i.test(text);
800
819
  const hasPassportMRZ = parsedMRZData?.fields?.documentCode === 'P';
801
- const hasPassportMRZPattern = mrzText && PASSPORT_MRZ_PATTERN.test(mrzText);
802
- if (hasFaces || hasSignature || hasPassportMRZ || hasPassportMRZPattern) {
803
- setStatus('INCORRECT');
804
- return;
805
- }
806
820
 
807
- // Safety: passport somehow reached ID_BACK step
808
- if (detectedDocumentType === 'PASSPORT') {
821
+ // RECOVERY (must run BEFORE the wrong-side guard below): a passport was
822
+ // misrouted to SCAN_ID_BACK. A passport has only its data page, which
823
+ // carries a face + MRZ — exactly what the wrong-side guard treats as
824
+ // "wrong side", so without this it would loop on INCORRECT forever
825
+ // (the reported "stuck asking for ID back" case). If we have positive
826
+ // passport evidence here, the front was already captured, so complete
827
+ // as a passport instead of waiting for a back that does not exist.
828
+ //
829
+ // We deliberately gate ONLY on authoritative signals: a locked PASSPORT
830
+ // classification, or a PARSED MRZ document code of 'P'. We do NOT test
831
+ // the raw OCR `text` against PASSPORT_MRZ_PATTERN here — an ID card's
832
+ // BACK legitimately carries an MRZ whose name line ("PAPPAS<<MARIA…",
833
+ // "…<<PHILIPP…") can false-match the unanchored pattern and would then
834
+ // wrongly complete a real ID card as a passport, skipping the back-side
835
+ // MRZ + barcode validation entirely.
836
+ if (detectedDocumentType === 'PASSPORT' || hasPassportMRZ) {
809
837
  transitionStepWithCallback('COMPLETED', 'SCAN_ID_BACK', {
810
838
  image,
811
839
  documentType: 'PASSPORT',
812
- mrzText: mrzText ?? undefined,
813
- mrzFields: parsedMRZData?.fields
840
+ mrzText: mrzText ?? lastValidMRZText.current ?? undefined,
841
+ mrzFields: parsedMRZData?.fields ?? lastValidMRZFields.current ?? undefined
814
842
  });
815
843
  return;
816
844
  }
845
+
846
+ // Wrong-side detection: a face or signature means we're looking at a
847
+ // front, not an ID-card back (which has neither).
848
+ if (hasFaces || hasSignature) {
849
+ setStatus('INCORRECT');
850
+ return;
851
+ }
817
852
  setElementsOutsideScanArea([]);
818
853
  const flowResult = handleIDBackFlow(mrzText, parsedMRZData?.fields, parsedMRZData?.valid === true, mrzStableAndValid, hasRequiredMRZFields(parsedMRZData?.fields), barcodeToUse?.rawValue, onlyMRZScan);
819
854
  if (!flowResult.shouldProceed) {
@@ -1195,7 +1230,7 @@ const IdentityDocumentCamera = ({
1195
1230
 
1196
1231
  // Use scannedData.mrzFields which we just ensured has preserved MRZ
1197
1232
  const mrzDocCode = scannedData.mrzFields?.documentCode;
1198
- const nextStepAfterHologram = getNextStepAfterHologram(detectedDocumentType, documentType, mrzDocCode);
1233
+ const nextStepAfterHologram = getNextStepAfterHologram(detectedDocumentType, documentType, mrzDocCode, sawPassportSignal.current);
1199
1234
  transitionStepWithCallback(nextStepAfterHologram, 'SCAN_HOLOGRAM', scannedData);
1200
1235
  return;
1201
1236
  }
@@ -1207,10 +1242,30 @@ const IdentityDocumentCamera = ({
1207
1242
  // INITIAL SCAN STEP - Detect document type and validate
1208
1243
  // ============================================================================
1209
1244
  if (nextStep === 'SCAN_ID_FRONT_OR_PASSPORT') {
1245
+ // Latch ANY passport signal seen in a front frame — the parsed 'P' code
1246
+ // OR the raw passport MRZ pattern (which survives even when full MRZ
1247
+ // parsing fails). The passport MRZ often OCRs a few frames after the
1248
+ // face + signature, so we remember it across frames; once latched, this
1249
+ // front can never be accepted as an ID card / asked for a back side.
1250
+ // Only AUTHORITATIVE passport signals latch — a parsed MRZ document code
1251
+ // of 'P', or a settled PASSPORT classification. We deliberately do NOT
1252
+ // latch on a raw PASSPORT_MRZ_PATTERN substring match against OCR text:
1253
+ // that loose test can fire on ID-card MRZ noise, and because the latch is
1254
+ // sticky and one-directional a single false match would force the
1255
+ // passport flow for the rest of the session and silently skip the ID
1256
+ // card's back side. The parsed 'P' code still covers the lagging-MRZ case
1257
+ // (it just requires the MRZ to have actually parsed first).
1258
+ if (isPassportDocumentCode(parsedMRZData?.fields?.documentCode) || documentType === 'PASSPORT' || detectedDocumentType === 'PASSPORT') {
1259
+ sawPassportSignal.current = true;
1260
+ }
1261
+
1210
1262
  // Determine which flow handler to use.
1211
1263
  // Current-frame passport detection always takes precedence over a locked
1212
- // ID_FRONT — passport MRZ may not appear until later frames.
1213
- const flowDocumentType = documentType === 'PASSPORT' ? 'PASSPORT' : detectedDocumentType !== 'UNKNOWN' ? detectedDocumentType : documentType;
1264
+ // ID_FRONT — passport MRZ may not appear until later frames. A latched
1265
+ // passport signal also forces the passport flow, so a passport that was
1266
+ // momentarily locked as ID_FRONT (before its MRZ was read) is corrected
1267
+ // instead of being driven into the ID-card back-side flow.
1268
+ const flowDocumentType = documentType === 'PASSPORT' || sawPassportSignal.current ? 'PASSPORT' : detectedDocumentType !== 'UNKNOWN' ? detectedDocumentType : documentType;
1214
1269
  const handlePassportInitialStep = async () => {
1215
1270
  const flowResult = handlePassportFlow(primaryFaces, mrzText, parsedMRZData?.fields, mrzStableAndValid, onlyMRZScan, hasRequiredMRZFields(parsedMRZData?.fields), !!faceImageToUse);
1216
1271
  if (!flowResult.shouldProceed) {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
 
3
3
  import { Dimensions } from 'react-native';
4
- import { SIGNATURE_REGEX, PASSPORT_MRZ_PATTERN } from "./IdentityDocumentCamera.constants.js";
4
+ import { SIGNATURE_REGEX, PASSPORT_MRZ_PATTERN, MRZ_DENSE_PATTERN } from "./IdentityDocumentCamera.constants.js";
5
5
  import { debugLog, isDebugEnabled } from "../Libs/debug.utils.js";
6
6
 
7
7
  /**
@@ -13,6 +13,28 @@ export function isIDCardDocumentCode(code) {
13
13
  return code.startsWith('I') || code.startsWith('A') || code.startsWith('C');
14
14
  }
15
15
 
16
+ /**
17
+ * Checks if a document code represents a passport (ICAO TD3).
18
+ * Per ICAO 9303 Part 4, the first character of a passport MRZ document code is
19
+ * 'P' — for the ordinary `P<`, the German `PP`, and the diplomatic/service/
20
+ * official `PD`/`PS`/`PO` variants alike.
21
+ */
22
+ export function isPassportDocumentCode(code) {
23
+ if (!code) return false;
24
+ return code.startsWith('P');
25
+ }
26
+
27
+ /**
28
+ * Single source of truth for "does this document have a second side left to
29
+ * scan?". A passport's data all lives on one page, so it has no back; an ID
30
+ * card's MRZ lives on the back, so an ID front always does. Used by the
31
+ * post-front / post-hologram routing so the "ask for the back side?" decision
32
+ * is never re-derived ad-hoc (the bug where passports were sent to SCAN_ID_BACK).
33
+ */
34
+ export function documentHasBackSide(documentType) {
35
+ return documentType === 'ID_FRONT';
36
+ }
37
+
16
38
  /**
17
39
  * Frame-to-screen coordinate transform using FILL_CENTER scaling
18
40
  */
@@ -226,10 +248,17 @@ export function detectDocumentType(faces, ocrText, mrzFields, frameWidth, mrzTex
226
248
  return 'ID_FRONT';
227
249
  }
228
250
 
229
- // If signature present and NO passport MRZ pattern, likely ID_FRONT
230
- // But we can't be 100% sure yet - passport MRZ might appear in next frames
251
+ // If signature present and NO passport MRZ pattern, likely ID_FRONT
252
+ // BUT an ID-card front has no MRZ, so if a real (dense) MRZ is visible here
253
+ // (and it is not a confirmed ID code — that returned above) this is almost
254
+ // certainly a passport data page whose 'P' code just hasn't OCR'd yet.
255
+ // Stay UNKNOWN and let later frames resolve it, rather than locking
256
+ // ID_FRONT and routing a passport to a back side it does not have. We use
257
+ // MRZ_DENSE_PATTERN (needs a `<<` filler run) so a stray single `<` OCR'd
258
+ // from a card-face guilloche cannot wedge a genuine ID front at UNKNOWN.
259
+ const hasUnresolvedMrzBlock = !!mrzText || MRZ_DENSE_PATTERN.test(ocrText);
231
260
  const hasSignature = hasSignatureMatch;
232
- if (hasSignature && !hasPassportMRZPattern) {
261
+ if (hasSignature && !hasPassportMRZPattern && !hasUnresolvedMrzBlock) {
233
262
  return 'ID_FRONT';
234
263
  }
235
264
  }
@@ -229,21 +229,23 @@ async function convertJP2IfNeeded(imageBuffer, mimeType) {
229
229
  };
230
230
  }
231
231
 
232
- // Prefer the native decoder (iOS ImageIO). It decodes JPEG2000 of any size
233
- // without blocking the JS thread, so it both fixes the iOS preview (RN's
234
- // <Image> can't render a raw image/jp2 data URI) and avoids the slow pure-JS
235
- // decoder entirely. Returns null on Android / when unavailable → fall through.
232
+ // Prefer the native decoder (iOS ImageIO / Android jj2000). It decodes
233
+ // JPEG2000 of any size off the JS thread, so it fixes the on-screen preview on
234
+ // BOTH platforms (RN's <Image> can't render a raw image/jp2 data URI on either)
235
+ // and avoids the slow pure-JS decoder entirely. Returns null only when the
236
+ // native module is unavailable/unlinked or it fails → fall through.
236
237
  const native = await decodeJp2ToJpeg(imageBuffer);
237
238
  if (native) {
238
239
  debugLog('EID', `[EID] JP2 decoded natively → ${native.mimeType} (${native.base64.length} base64 chars)`);
239
240
  return native;
240
241
  }
241
242
 
242
- // Too large to decode synchronously without freezing the UI keep the raw
243
- // JP2. The face image is still captured (the verification backend / face-match
244
- // accept JPEG2000); only the on-screen preview can't render it. This lets the
245
- // NFC read COMPLETE instead of hanging. (On Android the raw JP2 still renders
246
- // in <Image>; on iOS the native path above normally handles it.)
243
+ // Native decode unavailable AND too large to decode synchronously in JS
244
+ // without freezing the UI — keep the raw JP2. The face image is still captured
245
+ // (the verification backend / face-match accept JPEG2000); only the on-screen
246
+ // preview can't render it. This lets the NFC read COMPLETE instead of hanging.
247
+ // In normal operation the native path above handles this on both platforms; we
248
+ // only reach here if the native module failed or isn't linked.
247
249
  if (imageBuffer.length > MAX_JP2_DECODE_BYTES) {
248
250
  debugLog('EID', `[EID] JP2 face image is ${imageBuffer.length} bytes (> ${MAX_JP2_DECODE_BYTES}); skipping in-JS decode to avoid blocking, keeping raw JP2`);
249
251
  return {
@@ -6,26 +6,27 @@ import { NativeModules, Platform } from 'react-native';
6
6
  * Native JPEG2000 decoder bridge.
7
7
  *
8
8
  * The passport chip portrait (DG2) is frequently stored as JPEG2000
9
- * (image/jp2). React Native's <Image> renders a JP2 data URI on Android (its
10
- * Fresco/Skia pipeline decodes it) but NOT on iOS (UIImage-backed <Image>
11
- * refuses the data URI), so the chip photo showed as a placeholder on iOS.
12
- *
13
- * iOS's ImageIO *can* decode JPEG2000, so the native `ImageDecoderModule`
14
- * round-trips the JP2 to JPEG. We only need this on iOS; on Android the raw
15
- * JP2 already renders, so there is no native counterpart and we no-op.
9
+ * (image/jp2). React Native's <Image> CANNOT render a JP2 data URI on EITHER
10
+ * platform iOS's UIImage-backed <Image> refuses it, and Android's Fresco/Skia
11
+ * pipeline has no JPEG2000 decoder (the chip photo showed as a blank/white
12
+ * placeholder). Both platforms therefore need a native round-trip to JPEG:
13
+ * - iOS: ImageIO decodes JPEG2000 natively.
14
+ * - Android: the bundled pure-Java jj2000 decoder (no ImageIO/NDK).
15
+ * Both are exposed as the `ImageDecoderModule.decodeJp2ToJpeg` native method.
16
16
  */
17
17
 
18
18
  const ImageDecoder = NativeModules.ImageDecoderModule;
19
19
 
20
20
  /**
21
- * Decode a JPEG2000 buffer to JPEG using the native iOS decoder.
21
+ * Decode a JPEG2000 buffer to JPEG using the native decoder (iOS ImageIO /
22
+ * Android jj2000).
22
23
  *
23
24
  * Returns the JPEG bytes + mime type on success, or null when native decode is
24
- * unavailable (Android, or the module isn't linked) or fails — callers should
25
- * fall back to their existing behaviour (keep raw JP2).
25
+ * unavailable (the module isn't linked) or fails — callers should fall back to
26
+ * their existing behaviour (keep raw JP2).
26
27
  */
27
28
  export async function decodeJp2ToJpeg(jp2Buffer) {
28
- if (Platform.OS !== 'ios' || !ImageDecoder?.decodeJp2ToJpeg) {
29
+ if (Platform.OS !== 'ios' && Platform.OS !== 'android' || !ImageDecoder?.decodeJp2ToJpeg) {
29
30
  return null;
30
31
  }
31
32
  try {
@@ -92,7 +92,7 @@ export class DataUploadService {
92
92
  // every entry is deleted in the finally below, whether the upload succeeds
93
93
  // or not.
94
94
  const tempPaths = [];
95
- const writeTempImage = async (fileName, base64Data) => {
95
+ const writeTempImage = async (fileName, base64Data, mimeType = 'image/jpeg') => {
96
96
  const filePath = decodeURIComponent(`${RNFS.TemporaryDirectoryPath}/${fileName}`);
97
97
  await RNFS.writeFile(filePath, base64Data, 'base64');
98
98
  tempPaths.push(filePath);
@@ -100,10 +100,19 @@ export class DataUploadService {
100
100
  name: 'files',
101
101
  filename: fileName,
102
102
  filepath: filePath,
103
- filetype: 'image/jpeg'
103
+ // The filename extension AND this filetype must reflect the REAL format.
104
+ // The backend keys its jp2→jpeg conversion off the .jp2 extension, so a
105
+ // raw JP2 mislabeled as .jpg/image/jpeg reaches face-verification as a
106
+ // corrupt JPEG and is rejected. Pass the actual mimeType for anything
107
+ // that isn't already JPEG (the chip portrait can be jp2/png).
108
+ filetype: mimeType
104
109
  });
105
110
  return filePath;
106
111
  };
112
+
113
+ // Pick a file extension that matches the image's real mime type so the
114
+ // backend handles it correctly (it converts .jp2 → jpeg on receipt).
115
+ const extensionForMime = mimeType => mimeType === 'image/jp2' ? 'jp2' : mimeType === 'image/png' ? 'png' : 'jpg';
107
116
  try {
108
117
  // Add document front image
109
118
  const frontImage = scannedDocument?.frontImage;
@@ -117,10 +126,13 @@ export class DataUploadService {
117
126
  await writeTempImage('DOCUMENT_BACK_IMAGE.jpg', backImage);
118
127
  }
119
128
 
120
- // Add face image from document
129
+ // Add face image from document. The NFC chip portrait (DG2) can be JPEG,
130
+ // PNG (JS-decoded), or — when native JP2 decode was unavailable — raw JP2,
131
+ // so the extension/filetype must track the real mime type, not assume JPEG.
121
132
  const faceImage = scannedDocument?.faceImage;
122
133
  if (faceImage && faceImage !== '') {
123
- await writeTempImage('FACE_IMAGE.jpg', faceImage);
134
+ const faceMime = scannedDocument?.faceImageMimeType || 'image/jpeg';
135
+ await writeTempImage(`FACE_IMAGE.${extensionForMime(faceMime)}`, faceImage, faceMime);
124
136
  }
125
137
 
126
138
  // Add secondary face image from document (optional)
@@ -2,4 +2,4 @@
2
2
 
3
3
  // This file is auto-generated. Do not edit manually.
4
4
  // Version is synced from package.json during build.
5
- export const SDK_VERSION = '1.495.10';
5
+ export const SDK_VERSION = '1.495.12';
@@ -1 +1 @@
1
- {"version":3,"file":"EIDScanner.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/EIDScanner.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAwBpD,UAAU,eAAe;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CACd,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,KACtB,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAED,QAAA,MAAM,UAAU,GAAI,6FAOjB,eAAe,4CA4yBjB,CAAC;AA4NF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"EIDScanner.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/EIDScanner.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAwBpD,UAAU,eAAe;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CACd,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,KACtB,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;CAC/C;AAED,QAAA,MAAM,UAAU,GAAI,6FAOjB,eAAe,4CA8yBjB,CAAC;AA4NF,eAAe,UAAU,CAAC"}
@@ -14,6 +14,7 @@ export declare const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
14
14
  export declare const SIGNATURE_REGEX: RegExp;
15
15
  export declare const SIGNATURE_TEXT_REGEX: RegExp;
16
16
  export declare const MRZ_BLOCK_PATTERN: RegExp;
17
+ export declare const MRZ_DENSE_PATTERN: RegExp;
17
18
  export declare const PASSPORT_MRZ_PATTERN: RegExp;
18
19
  export declare const MIN_SECURITY_FEATURES_REQUIRED = 4;
19
20
  export declare const SECURITY_FEATURE_NAMES: {
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityDocumentCamera.constants.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,sCAAsC,IAAI,CAAC;AAExD,eAAO,MAAM,eAAe,QAAkC,CAAC;AAC/D,eAAO,MAAM,oBAAoB,QAAyB,CAAC;AAC3D,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AASrD,eAAO,MAAM,oBAAoB,QAAyC,CAAC;AAI3E,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,sBAAsB;;;;;;;;;;CAUzB,CAAC;AAKX,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC"}
1
+ {"version":3,"file":"IdentityDocumentCamera.constants.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,sCAAsC,IAAI,CAAC;AAExD,eAAO,MAAM,eAAe,QAAkC,CAAC;AAC/D,eAAO,MAAM,oBAAoB,QAAyB,CAAC;AAC3D,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AASrD,eAAO,MAAM,iBAAiB,QAA+B,CAAC;AAS9D,eAAO,MAAM,oBAAoB,QAAyC,CAAC;AAI3E,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,sBAAsB;;;;;;;;;;CAUzB,CAAC;AAKX,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AAyEA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAK5B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CAujF7B,CAAC;AAiIF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AAyEA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAK5B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CA+mF7B,CAAC;AAiIF,eAAe,sBAAsB,CAAC"}
@@ -37,7 +37,7 @@ export interface PassportFlowResult {
37
37
  export interface IDFrontFlowResult {
38
38
  shouldProceed: boolean;
39
39
  reason?: string;
40
- nextAction?: 'WAIT_FOR_ELEMENTS' | 'REJECT_AS_PASSPORT' | 'PROCEED_TO_HOLOGRAM';
40
+ nextAction?: 'WAIT_FOR_ELEMENTS' | 'WAIT_FOR_MRZ' | 'REJECT_AS_PASSPORT' | 'PROCEED_TO_HOLOGRAM';
41
41
  }
42
42
  export interface IDBackFlowResult {
43
43
  shouldProceed: boolean;
@@ -105,5 +105,5 @@ export declare function handleIDBackFlow(mrzText: string | null, mrzFields: MRZF
105
105
  * self-corrects: SCAN_ID_BACK simply won't find an ID-back MRZ/barcode and the
106
106
  * user can cancel, which is far better than skipping the back of every real ID.
107
107
  */
108
- export declare function getNextStepAfterHologram(detectedDocumentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', currentFrameDocType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', mrzDocCode: string | undefined): 'COMPLETED' | 'SCAN_ID_BACK';
108
+ export declare function getNextStepAfterHologram(detectedDocumentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', currentFrameDocType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', mrzDocCode: string | undefined, sawPassportSignal?: boolean): 'COMPLETED' | 'SCAN_ID_BACK';
109
109
  //# sourceMappingURL=IdentityDocumentCamera.flows.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityDocumentCamera.flows.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAUpD,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,cAAc,GACd,qBAAqB,GACrB,sBAAsB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,oBAAoB,GACpB,qBAAqB,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;CAC3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,iBAAiB,EAAE,OAAO,EAC1B,WAAW,EAAE,OAAO,EACpB,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,OAAO,GACpB,kBAAkB,CAgEpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,UAAU,EAAE,MAAM,GACjB,iBAAiB,CA0EnB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,QAAQ,EAAE,OAAO,EACjB,iBAAiB,EAAE,OAAO,EAC1B,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,EAAE,OAAO,GACnB,gBAAgB,CA2DlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,wBAAwB,CACtC,oBAAoB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACrE,mBAAmB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACpE,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,WAAW,GAAG,cAAc,CAsB9B"}
1
+ {"version":3,"file":"IdentityDocumentCamera.flows.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAgB,MAAM,gCAAgC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiBpD,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,cAAc,GACd,qBAAqB,GACrB,sBAAsB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,cAAc,GACd,oBAAoB,GACpB,qBAAqB,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;CAC3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,iBAAiB,EAAE,OAAO,EAC1B,WAAW,EAAE,OAAO,EACpB,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,OAAO,GACpB,kBAAkB,CAgEpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,UAAU,EAAE,MAAM,GACjB,iBAAiB,CAoHnB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,QAAQ,EAAE,OAAO,EACjB,iBAAiB,EAAE,OAAO,EAC1B,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,EAAE,OAAO,GACnB,gBAAgB,CA2DlB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,wBAAwB,CACtC,oBAAoB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACrE,mBAAmB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACpE,UAAU,EAAE,MAAM,GAAG,SAAS,EAM9B,iBAAiB,GAAE,OAAe,GACjC,WAAW,GAAG,cAAc,CAuB9B"}
@@ -102,6 +102,27 @@ export interface Barcode {
102
102
  import type { MRZFields } from '../Types/mrzFields';
103
103
  export type ScanStep = 'SCAN_ID_FRONT_OR_PASSPORT' | 'SCAN_ID_BACK' | 'SCAN_HOLOGRAM' | 'COMPLETED';
104
104
  export type ScanStatus = 'SEARCHING' | 'SCANNING' | 'SCANNED' | 'INCORRECT';
105
+ /**
106
+ * What the camera has classified the document in view as.
107
+ *
108
+ * The single most important property of a document type is whether it has a
109
+ * BACK SIDE that still needs scanning — that is what drives the scan flow:
110
+ *
111
+ * PASSPORT — ICAO TD3 booklet. The MRZ, photo and all data live on ONE page
112
+ * (the data page). There is NO second machine-readable side, so a
113
+ * passport must NEVER be routed to SCAN_ID_BACK. Detected by the
114
+ * TD3 MRZ document code 'P' / the passport MRZ pattern.
115
+ * ID_FRONT — the photo/front side of a TD1/TD2 ID card. The front carries the
116
+ * photo + signature but usually NO MRZ (the MRZ is on the back),
117
+ * so the front alone is NOT enough — it MUST be followed by a back
118
+ * scan (SCAN_ID_BACK).
119
+ * ID_BACK — the back side of a TD1/TD2 ID card. Carries the MRZ (document
120
+ * code 'I'/'A'/'C') and usually a barcode. Terminal side.
121
+ * UNKNOWN — not yet classified, or signals conflict.
122
+ *
123
+ * Use `documentHasBackSide()` / `isPassportDocumentCode()` rather than comparing
124
+ * these strings ad-hoc, so the "is this a passport?" rule lives in one place.
125
+ */
105
126
  export type DocumentType = 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN';
106
127
  export type CompletedStep = 'SCAN_ID_FRONT_OR_PASSPORT' | 'SCAN_ID_BACK' | 'SCAN_HOLOGRAM' | null;
107
128
  export type BoundsWithRotation = {
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityDocumentCamera.types.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IdentityDocumentCamera.types.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.types.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,21 @@ import type { MRZFields } from '../Types/mrzFields';
5
5
  * Per ICAO 9303, valid ID card codes start with 'I', 'A', or 'C'.
6
6
  */
7
7
  export declare function isIDCardDocumentCode(code: string | null | undefined): boolean;
8
+ /**
9
+ * Checks if a document code represents a passport (ICAO TD3).
10
+ * Per ICAO 9303 Part 4, the first character of a passport MRZ document code is
11
+ * 'P' — for the ordinary `P<`, the German `PP`, and the diplomatic/service/
12
+ * official `PD`/`PS`/`PO` variants alike.
13
+ */
14
+ export declare function isPassportDocumentCode(code: string | null | undefined): boolean;
15
+ /**
16
+ * Single source of truth for "does this document have a second side left to
17
+ * scan?". A passport's data all lives on one page, so it has no back; an ID
18
+ * card's MRZ lives on the back, so an ID front always does. Used by the
19
+ * post-front / post-hologram routing so the "ask for the back side?" decision
20
+ * is never re-derived ad-hoc (the bug where passports were sent to SCAN_ID_BACK).
21
+ */
22
+ export declare function documentHasBackSide(documentType: DocumentType): boolean;
8
23
  /**
9
24
  * Frame-to-screen coordinate transform using FILL_CENTER scaling
10
25
  */
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityDocumentCamera.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IdentityDocumentCamera.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.utils.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"eidReader.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/EIDReader/eidReader.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAyY7C,QAAA,MAAM,SAAS,GACb,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,cAAc,MAAM,EACpB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAC5C,OAAO,CACN;IACE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD,SAAS,CA+XZ,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
1
+ {"version":3,"file":"eidReader.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/EIDReader/eidReader.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AA2Y7C,QAAA,MAAM,SAAS,GACb,gBAAgB,MAAM,EACtB,aAAa,MAAM,EACnB,cAAc,MAAM,EACpB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAC5C,OAAO,CACN;IACE,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B,GACD,SAAS,CA+XZ,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -1,10 +1,11 @@
1
1
  import { Buffer } from 'buffer';
2
2
  /**
3
- * Decode a JPEG2000 buffer to JPEG using the native iOS decoder.
3
+ * Decode a JPEG2000 buffer to JPEG using the native decoder (iOS ImageIO /
4
+ * Android jj2000).
4
5
  *
5
6
  * Returns the JPEG bytes + mime type on success, or null when native decode is
6
- * unavailable (Android, or the module isn't linked) or fails — callers should
7
- * fall back to their existing behaviour (keep raw JP2).
7
+ * unavailable (the module isn't linked) or fails — callers should fall back to
8
+ * their existing behaviour (keep raw JP2).
8
9
  */
9
10
  export declare function decodeJp2ToJpeg(jp2Buffer: Buffer): Promise<{
10
11
  base64: string;
@@ -1 +1 @@
1
- {"version":3,"file":"jp2Decode.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/jp2Decode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAsBhC;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAetD"}
1
+ {"version":3,"file":"jp2Decode.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/jp2Decode.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAsBhC;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAkBtD"}
@@ -1 +1 @@
1
- {"version":3,"file":"DataUploadService.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Services/DataUploadService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQhE;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM;YAKb,0BAA0B;IAexC;;OAEG;IACG,kBAAkB,CACtB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,uBAAuB,EACxC,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,IAAI,CAAC;IA2DhB;;OAEG;IACG,WAAW,CACf,gBAAgB,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,uBAAuB,EACzC,iBAAiB,CAAC,EAAE,iBAAiB,EACrC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC;IA0JhB;;OAEG;IACG,mBAAmB,CACvB,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EACvC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,OAAO,CAAC;IAkGnB,OAAO,CAAC,iBAAiB;CAY1B"}
1
+ {"version":3,"file":"DataUploadService.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Services/DataUploadService.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQhE;;;GAGG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,EAAE,MAAM;YAKb,0BAA0B;IAexC;;OAEG;IACG,kBAAkB,CACtB,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,uBAAuB,EACxC,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,IAAI,CAAC;IA8DhB;;OAEG;IACG,WAAW,CACf,gBAAgB,EAAE,MAAM,EACxB,eAAe,CAAC,EAAE,uBAAuB,EACzC,iBAAiB,CAAC,EAAE,iBAAiB,EACrC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACtC,OAAO,CAAC,IAAI,CAAC;IAmLhB;;OAEG;IACG,mBAAmB,CACvB,kBAAkB,EAAE,kBAAkB,EACtC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,EACvC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,OAAO,CAAC;IAuGnB,OAAO,CAAC,iBAAiB;CAY1B"}
@@ -1,2 +1,2 @@
1
- export declare const SDK_VERSION = "1.495.10";
1
+ export declare const SDK_VERSION = "1.495.12";
2
2
  //# sourceMappingURL=version.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trustchex/react-native-sdk",
3
- "version": "1.495.10",
3
+ "version": "1.495.12",
4
4
  "description": "Trustchex mobile app react native SDK for android or ios devices",
5
5
  "main": "./lib/module/index.js",
6
6
  "types": "./lib/typescript/src/index.d.ts",
@@ -643,12 +643,14 @@ const EIDScanner = ({
643
643
  <View style={styles.idCardPhotoContainer}>
644
644
  <View style={styles.idCardPhotoFrame}>
645
645
  {documentFaceImage &&
646
+ // The chip portrait (DG2) is JPEG2000, which RN's <Image>
647
+ // can't render on either platform — the native decoder
648
+ // (iOS ImageIO / Android jj2000) converts it to JPEG (or
649
+ // the small-image JS fallback to PNG) before this point.
650
+ // A raw image/jp2 would render as a blank box, so we only
651
+ // accept the decoded formats and otherwise show '?'.
646
652
  (documentFaceImageMimeType === 'image/jpeg' ||
647
- documentFaceImageMimeType === 'image/png' ||
648
- // Android's <Image> decodes a raw JP2 data URI; on iOS
649
- // the chip JP2 is converted to JPEG before this point
650
- // (native ImageIO), so iOS never reaches here as jp2.
651
- documentFaceImageMimeType === 'image/jp2') ? (
653
+ documentFaceImageMimeType === 'image/png') ? (
652
654
  <Image
653
655
  source={{
654
656
  uri: `data:${documentFaceImageMimeType};base64,${documentFaceImage}`,
@@ -17,6 +17,15 @@ export const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
17
17
  export const SIGNATURE_REGEX = /s[gi]g?n[au]?t[u]?r|imz[a]s?/i;
18
18
  export const SIGNATURE_TEXT_REGEX = /signature|imza|İmza/i;
19
19
  export const MRZ_BLOCK_PATTERN = /[A-Z0-9<]{8,}.*</i;
20
+ // A DENSE MRZ run — a contiguous block of MRZ characters that contains a chevron
21
+ // FILLER pair (`<<`). Real machine-readable zones are padded with `<<…`; a card
22
+ // FACE (ID front) has no MRZ, and the occasional stray single `<` OCR'd from a
23
+ // guilloche/chevron glyph will NOT contain a `<<` filler run. Used to decide
24
+ // "is a real MRZ visible on this front?" without the false positives of
25
+ // MRZ_BLOCK_PATTERN (whose `.*<` lets a lone detached `<` anywhere in the frame
26
+ // match) — that looseness could otherwise wedge a legitimate ID front that
27
+ // happens to OCR a stray `<`.
28
+ export const MRZ_DENSE_PATTERN = /[A-Z0-9<]{6,}<<[A-Z0-9<]*/i;
20
29
  // Matches the line-1 start of ANY ICAO TD3 passport MRZ, so the camera routes
21
30
  // every passport variant into the passport flow (not the ID-card back-side
22
31
  // flow). Per ICAO 9303 Part 4: `P` + a type char (filler `<` or a subtype