@trustchex/react-native-sdk 1.486.0 → 1.488.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/lib/module/Shared/Components/EIDScanner.js +97 -37
  2. package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +9 -1
  3. package/lib/module/Shared/EIDReader/cardFileInputStream.js +25 -2
  4. package/lib/module/Shared/EIDReader/defaultFileSystem.js +56 -6
  5. package/lib/module/Shared/EIDReader/eidReader.js +124 -14
  6. package/lib/module/Shared/EIDReader/lds/icao/dg11File.js +23 -6
  7. package/lib/module/Shared/EIDReader/nfcManagerCardService.js +79 -9
  8. package/lib/module/Shared/EIDReader/protocol/paceDH.js +101 -0
  9. package/lib/module/Shared/EIDReader/protocol/paceErrors.js +34 -0
  10. package/lib/module/Shared/EIDReader/protocol/paceProtocol.js +53 -4
  11. package/lib/module/Shared/EIDReader/protocol/readBinaryAPDUSender.js +7 -3
  12. package/lib/module/Shared/Libs/country-display.utils.js +13 -1
  13. package/lib/module/Shared/Libs/diagnosticReport.js +24 -1
  14. package/lib/module/Shared/Libs/diagnostics.js +30 -8
  15. package/lib/module/Shared/Libs/mrz.utils.js +172 -25
  16. package/lib/module/Shared/Libs/mrzFrameAggregator.js +29 -1
  17. package/lib/module/Shared/Libs/mrzTransliteration.js +14 -1
  18. package/lib/module/Translation/Resources/en.js +12 -0
  19. package/lib/module/Translation/Resources/tr.js +12 -0
  20. package/lib/module/version.js +1 -1
  21. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  22. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -1
  23. package/lib/typescript/src/Shared/EIDReader/cardFileInputStream.d.ts +3 -0
  24. package/lib/typescript/src/Shared/EIDReader/cardFileInputStream.d.ts.map +1 -1
  25. package/lib/typescript/src/Shared/EIDReader/defaultFileSystem.d.ts +4 -0
  26. package/lib/typescript/src/Shared/EIDReader/defaultFileSystem.d.ts.map +1 -1
  27. package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
  28. package/lib/typescript/src/Shared/EIDReader/lds/icao/dg11File.d.ts.map +1 -1
  29. package/lib/typescript/src/Shared/EIDReader/nfcManagerCardService.d.ts +9 -1
  30. package/lib/typescript/src/Shared/EIDReader/nfcManagerCardService.d.ts.map +1 -1
  31. package/lib/typescript/src/Shared/EIDReader/protocol/paceDH.d.ts +56 -0
  32. package/lib/typescript/src/Shared/EIDReader/protocol/paceDH.d.ts.map +1 -0
  33. package/lib/typescript/src/Shared/EIDReader/protocol/paceErrors.d.ts +26 -0
  34. package/lib/typescript/src/Shared/EIDReader/protocol/paceErrors.d.ts.map +1 -0
  35. package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts.map +1 -1
  36. package/lib/typescript/src/Shared/EIDReader/protocol/readBinaryAPDUSender.d.ts.map +1 -1
  37. package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts.map +1 -1
  38. package/lib/typescript/src/Shared/Libs/diagnosticReport.d.ts.map +1 -1
  39. package/lib/typescript/src/Shared/Libs/diagnostics.d.ts +9 -1
  40. package/lib/typescript/src/Shared/Libs/diagnostics.d.ts.map +1 -1
  41. package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts +1 -0
  42. package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
  43. package/lib/typescript/src/Shared/Libs/mrzFrameAggregator.d.ts.map +1 -1
  44. package/lib/typescript/src/Shared/Libs/mrzTransliteration.d.ts.map +1 -1
  45. package/lib/typescript/src/Translation/Resources/en.d.ts +12 -0
  46. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  47. package/lib/typescript/src/Translation/Resources/tr.d.ts +12 -0
  48. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  49. package/lib/typescript/src/version.d.ts +1 -1
  50. package/package.json +1 -1
  51. package/src/Shared/Components/EIDScanner.tsx +149 -68
  52. package/src/Shared/Components/IdentityDocumentCamera.constants.ts +9 -1
  53. package/src/Shared/EIDReader/cardFileInputStream.ts +30 -6
  54. package/src/Shared/EIDReader/defaultFileSystem.ts +75 -17
  55. package/src/Shared/EIDReader/eidReader.ts +154 -21
  56. package/src/Shared/EIDReader/lds/icao/dg11File.ts +28 -13
  57. package/src/Shared/EIDReader/nfcManagerCardService.ts +91 -13
  58. package/src/Shared/EIDReader/protocol/paceDH.ts +183 -0
  59. package/src/Shared/EIDReader/protocol/paceErrors.ts +41 -0
  60. package/src/Shared/EIDReader/protocol/paceProtocol.ts +72 -6
  61. package/src/Shared/EIDReader/protocol/readBinaryAPDUSender.ts +7 -4
  62. package/src/Shared/Libs/country-display.utils.ts +12 -1
  63. package/src/Shared/Libs/diagnosticReport.ts +32 -1
  64. package/src/Shared/Libs/diagnostics.ts +38 -14
  65. package/src/Shared/Libs/mrz.utils.ts +193 -28
  66. package/src/Shared/Libs/mrzFrameAggregator.ts +38 -3
  67. package/src/Shared/Libs/mrzTransliteration.ts +16 -3
  68. package/src/Translation/Resources/en.ts +19 -0
  69. package/src/Translation/Resources/tr.ts +19 -0
  70. package/src/version.ts +1 -1
@@ -38,7 +38,9 @@ export interface NfcDiagnostics {
38
38
  /** PACE object identifier string when PACE was attempted. */
39
39
  paceOid?: string;
40
40
  /** Why PACE wasn't used / fell back: 'no_card_access' | 'no_pace_info' |
41
- * 'pace_failed'. Distinguishes device/chip-specific PACE issues. */
41
+ * 'pace_failed' | 'pace_unsupported_<agreement|mapping|curve|cipher>'.
42
+ * The pace_unsupported_* reasons mark a CAPABILITY gap (this build can't run
43
+ * the variant the chip advertises) vs pace_failed (a runtime failure). */
42
44
  paceFallbackReason?: string;
43
45
  steps: NfcStep[];
44
46
  /** Name of the first failing step, if any. */
@@ -131,6 +133,12 @@ export declare class DiagnosticsCollector {
131
133
  nfcPaceFellBackToBac(reason?: string): void;
132
134
  /** Record one completed step. Keep messages short and free of PII. */
133
135
  nfcStep(step: NfcStep): void;
136
+ /** The first NFC step that failed in the current attempt (e.g. 'paceAuth',
137
+ * 'readDG2'), or undefined. Lets the caller build a step-specific error code
138
+ * without taking a full snapshot. */
139
+ getFailureStep(): string | undefined;
140
+ /** APDU status word recorded for the failing step, if any (e.g. '6982'). */
141
+ getFailureStatusWord(): string | undefined;
134
142
  nfcResult(succeeded: boolean, errorCategory?: string): void;
135
143
  addError(e: {
136
144
  code?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/diagnostics.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/diagnostics.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,7 @@ declare const _default: {
33
33
  isValidOCRBPattern: (text: string) => boolean;
34
34
  applyOCRBCorrections: (text: string) => string;
35
35
  convertMRZDateToISODate: (mrzDate?: string | null) => string | null;
36
+ normalizeDocumentCode: (code: string | null | undefined) => string | null;
36
37
  };
37
38
  export default _default;
38
39
  //# sourceMappingURL=mrz.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mrz.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/mrz.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA2CpD;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;sBAOwB,MAAM,KAAG,MAAM;2BA8gC7B,MAAM,gBACF,OAAO,KACnB,mBAAmB;0CAsKuB,MAAM,KAAG,mBAAmB;wCAj/B9B,MAAM,KAAG,MAAM,EAAE,EAAE;wCA2/BnB,MAAM,KAAG,MAAM;gCAmDvB,MAAM;;;;;+BAz1BP,MAAM,KAAG,OAAO;iCA4Bd,MAAM,KAAG,MAAM;wCA20BR,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,IAAI;;AAgBxE,wBAUE"}
1
+ {"version":3,"file":"mrz.utils.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/mrz.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA4EpD;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;;sBAOwB,MAAM,KAAG,MAAM;2BA+oC7B,MAAM,gBACF,OAAO,KACnB,mBAAmB;0CAwKuB,MAAM,KAAG,mBAAmB;wCApnC9B,MAAM,KAAG,MAAM,EAAE,EAAE;wCA8nCnB,MAAM,KAAG,MAAM;gCAmDvB,MAAM;;;;;+BA/1BP,MAAM,KAAG,OAAO;iCA4Bd,MAAM,KAAG,MAAM;wCAi1BR,MAAM,GAAG,IAAI,KAAG,MAAM,GAAG,IAAI;kCAn9ChE,MAAM,GAAG,IAAI,GAAG,SAAS,KAC9B,MAAM,GAAG,IAAI;;AAk+ChB,wBAWE"}
@@ -1 +1 @@
1
- {"version":3,"file":"mrzFrameAggregator.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/mrzFrameAggregator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAkCvD,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,+EAA+E;IAC/E,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkFD;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAInC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,cAAc,CAAK;gBAEf,OAAO,GAAE,yBAA8B;IAMnD,KAAK,IAAI,IAAI;IAQb;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IA0B5B,iCAAiC;IACjC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,OAAO,CAAC,WAAW;IAUnB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY;IA+C5C,+EAA+E;IAC/E,OAAO,CAAC,KAAK;IAab;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAiB1B,4DAA4D;IAC5D,OAAO,CAAC,cAAc;IA8BtB,2EAA2E;IAC3E,gBAAgB,IAAI,YAAY;CAiEjC;AAED,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"mrzFrameAggregator.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/mrzFrameAggregator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAkCvD,MAAM,WAAW,aAAa;IAC5B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;;;;;;;OAYG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AASD,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,+EAA+E;IAC/E,UAAU,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACvC,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mFAAmF;IACnF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAqHD;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAInC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IAEnC,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,cAAc,CAAK;gBAEf,OAAO,GAAE,yBAA8B;IAMnD,KAAK,IAAI,IAAI;IAQb;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IA0B5B,iCAAiC;IACjC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,OAAO,CAAC,WAAW;IAUnB;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY;IA+C5C,+EAA+E;IAC/E,OAAO,CAAC,KAAK;IAab;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,oBAAoB;IAI5B;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAiB1B,4DAA4D;IAC5D,OAAO,CAAC,cAAc;IA8BtB,2EAA2E;IAC3E,gBAAgB,IAAI,YAAY;CAiEjC;AAED,eAAe,kBAAkB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"mrzTransliteration.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/mrzTransliteration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAyFhE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACvC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,YAAY,CAmCd"}
1
+ {"version":3,"file":"mrzTransliteration.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Libs/mrzTransliteration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAyFhE,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACvC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,YAAY,CAgDd"}
@@ -48,6 +48,11 @@ declare const _default: {
48
48
  'diagnosticReport.noticeBody': string;
49
49
  'diagnosticReport.continue': string;
50
50
  'diagnosticReport.cancel': string;
51
+ 'diagnosticReport.shareFailedTitle': string;
52
+ 'diagnosticReport.shareFailedBody': string;
53
+ 'diagnosticReport.uploadAction': string;
54
+ 'diagnosticReport.uploadSuccess': string;
55
+ 'diagnosticReport.uploadFailed': string;
51
56
  'livenessDetectionScreen.guideHeader': string;
52
57
  'livenessDetectionScreen.guideText': string;
53
58
  'livenessDetectionScreen.guidePoint1': string;
@@ -70,6 +75,13 @@ declare const _default: {
70
75
  'eidScannerScreen.guideHeader': string;
71
76
  'eidScannerScreen.guideText': string;
72
77
  'eidScannerScreen.invalidMRZFields': string;
78
+ 'eidScannerScreen.error': string;
79
+ 'eidScannerScreen.errorCode': string;
80
+ 'eidScannerScreen.nfcGenericError': string;
81
+ 'eidScannerScreen.nfcReadFailed': string;
82
+ 'eidScannerScreen.nfcAuthFailed': string;
83
+ 'eidScannerScreen.nfcTagLost': string;
84
+ 'eidScannerScreen.nfcTimeout': string;
73
85
  'eidScannerScreen.faceImageNotFound': string;
74
86
  'eidScannerScreen.documentCode': string;
75
87
  'eidScannerScreen.nationality': string;
@@ -1 +1 @@
1
- {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAgQE"}
1
+ {"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/en.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAmRE"}
@@ -48,6 +48,11 @@ declare const _default: {
48
48
  'diagnosticReport.noticeBody': string;
49
49
  'diagnosticReport.continue': string;
50
50
  'diagnosticReport.cancel': string;
51
+ 'diagnosticReport.shareFailedTitle': string;
52
+ 'diagnosticReport.shareFailedBody': string;
53
+ 'diagnosticReport.uploadAction': string;
54
+ 'diagnosticReport.uploadSuccess': string;
55
+ 'diagnosticReport.uploadFailed': string;
51
56
  'livenessDetectionScreen.guideHeader': string;
52
57
  'livenessDetectionScreen.guideText': string;
53
58
  'livenessDetectionScreen.guidePoint1': string;
@@ -70,6 +75,13 @@ declare const _default: {
70
75
  'eidScannerScreen.guideHeader': string;
71
76
  'eidScannerScreen.guideText': string;
72
77
  'eidScannerScreen.invalidMRZFields': string;
78
+ 'eidScannerScreen.error': string;
79
+ 'eidScannerScreen.errorCode': string;
80
+ 'eidScannerScreen.nfcGenericError': string;
81
+ 'eidScannerScreen.nfcReadFailed': string;
82
+ 'eidScannerScreen.nfcAuthFailed': string;
83
+ 'eidScannerScreen.nfcTagLost': string;
84
+ 'eidScannerScreen.nfcTimeout': string;
73
85
  'eidScannerScreen.faceImageNotFound': string;
74
86
  'eidScannerScreen.documentCode': string;
75
87
  'eidScannerScreen.nationality': string;
@@ -1 +1 @@
1
- {"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/tr.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAmQE"}
1
+ {"version":3,"file":"tr.d.ts","sourceRoot":"","sources":["../../../../../src/Translation/Resources/tr.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,wBAsRE"}
@@ -1,2 +1,2 @@
1
- export declare const SDK_VERSION = "1.486.0";
1
+ export declare const SDK_VERSION = "1.488.0";
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.486.0",
3
+ "version": "1.488.0",
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",
@@ -4,12 +4,14 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
  import NFCManager from 'react-native-nfc-manager';
5
5
  import DeviceInfo from 'react-native-device-info';
6
6
  import PermissionManager from '../Libs/permissions.utils';
7
+ import mrzUtils from '../Libs/mrz.utils';
7
8
  import { debugError } from '../Libs/debug.utils';
8
9
  import { MRZInfo } from '../EIDReader/lds/icao/mrzInfo';
9
10
  import { eidReader } from '../EIDReader/eidReader';
10
11
  import NativeProgressBar from './NativeProgressBar';
11
12
  import type { MRZFields } from '../Types/mrzFields';
12
13
  import { buildDocumentName } from '../Libs/mrzTransliteration';
14
+ import type { DocumentName } from '../Types/documentReadResult';
13
15
  import { normalizeFromMRZInfo } from '../Libs/documentDataNormalizer';
14
16
  import { useTranslation } from 'react-i18next';
15
17
  import AppContext from '../Contexts/AppContext';
@@ -54,13 +56,20 @@ const EIDScanner = ({
54
56
  const [documentMRZInfo, setDocumentMRZInfo] = React.useState<MRZInfo>();
55
57
  const [documentFaceImageMimeType, setDocumentFaceImageMimeType] =
56
58
  React.useState<string>();
57
- const [documentName, setDocumentName] = React.useState<import('../Types/documentReadResult').DocumentName>();
59
+ const [documentName, setDocumentName] = React.useState<DocumentName>();
58
60
  const [progress, setProgress] = React.useState(0);
59
61
  const [progressStage, setProgressStage] = React.useState<string>('');
60
62
 
61
63
  // Animation for pulse indicator
62
64
  const pulseAnim = useRef(new Animated.Value(1)).current;
63
65
 
66
+ // Strip MRZ filler (`<`) and trim; returns '' for empty/filler-only input so
67
+ // the UI can hide fields the chip didn't actually provide.
68
+ const cleanField = useCallback((value?: string | null): string => {
69
+ if (!value) return '';
70
+ return value.replace(/</g, ' ').replace(/\s+/g, ' ').trim();
71
+ }, []);
72
+
64
73
  // Format date from YYMMDD to DD/MM/YYYY (matching Flutter SDK)
65
74
  const formatDate = useCallback((dateStr?: string | null) => {
66
75
  if (!dateStr) return '';
@@ -136,20 +145,30 @@ const EIDScanner = ({
136
145
  const [voiceGuidanceMessage, setVoiceGuidanceMessage] = useState<string>();
137
146
  const [attemptNumber, setAttemptNumber] = useState<number>(0);
138
147
 
139
- const getFieldsFromMRZ = useCallback((mrz: MRZInfo) => {
140
- return {
141
- documentCode: mrz.getDocumentCode(),
142
- personalNumber: mrz.getPersonalNumber() || mrz.getOptionalData1(),
143
- documentNumber: mrz.getDocumentNumber(),
144
- firstName: mrz.getSecondaryIdentifier(),
145
- lastName: mrz.getPrimaryIdentifier(),
146
- birthDate: mrz.getDateOfBirth(),
147
- expirationDate: mrz.getDateOfExpiry(),
148
- issuingState: mrz.getIssuingState(),
149
- sex: mrz.getGender().getStrCode(),
150
- nationality: mrz.getNationality(),
151
- } satisfies MRZFields;
152
- }, []);
148
+ const getFieldsFromMRZ = useCallback(
149
+ (mrz: MRZInfo, name?: DocumentName | null) => {
150
+ // Prefer the resolved name (DG11 printed name / transliteration) over the
151
+ // raw DG1 split. Some chips — notably Turkish PACE passports — return a DG1
152
+ // name field with no `<<` separator, so getPrimaryIdentifier() holds the
153
+ // FULL name and getSecondaryIdentifier() is empty ("name as surname"). The
154
+ // resolved name corrects that; fall back to the raw split when absent.
155
+ const firstName = name?.displayFirst || mrz.getSecondaryIdentifier();
156
+ const lastName = name?.displayLast || mrz.getPrimaryIdentifier();
157
+ return {
158
+ documentCode: mrzUtils.normalizeDocumentCode(mrz.getDocumentCode()),
159
+ personalNumber: mrz.getPersonalNumber() || mrz.getOptionalData1(),
160
+ documentNumber: mrz.getDocumentNumber(),
161
+ firstName,
162
+ lastName,
163
+ birthDate: mrz.getDateOfBirth(),
164
+ expirationDate: mrz.getDateOfExpiry(),
165
+ issuingState: mrz.getIssuingState(),
166
+ sex: mrz.getGender().getStrCode(),
167
+ nationality: mrz.getNationality(),
168
+ } satisfies MRZFields;
169
+ },
170
+ []
171
+ );
153
172
 
154
173
  const readNFC = useCallback(async () => {
155
174
  const startTime = Date.now();
@@ -267,7 +286,7 @@ const EIDScanner = ({
267
286
 
268
287
  if (appContext.skipNfcResultScreen && onScanSuccess) {
269
288
  onScanSuccess(
270
- getFieldsFromMRZ(passportData.mrz),
289
+ getFieldsFromMRZ(passportData.mrz, builtName),
271
290
  passportData.faceImage,
272
291
  passportData.mimeType
273
292
  );
@@ -348,7 +367,42 @@ const EIDScanner = ({
348
367
  ).catch(() => {});
349
368
 
350
369
  console.debug('NFC scan error:', error);
351
- // Ignore error - let user retry
370
+
371
+ // Surface an accurate message instead of failing silently. eidReader
372
+ // attaches `nfcCategory` + `nfcCode`.
373
+ // - User-correctable failures (wrong doc data, card moved/too slow, NFC
374
+ // off) get a specific, actionable message and NO code — there's a clear
375
+ // action to take, a support code would just be noise.
376
+ // - Everything else is an unexpected/system error: show a generic message
377
+ // plus the reportable code (e.g. NFC-READ-6A82) so the user can quote it.
378
+ // - user_cancelled stays silent (the user dismissed the native NFC sheet).
379
+ const tagged = error as
380
+ | { nfcCategory?: string; nfcCode?: string }
381
+ | undefined;
382
+ const category = tagged?.nfcCategory ?? errorType;
383
+
384
+ // category -> actionable message key for the user-mistake cases.
385
+ const ACTIONABLE: Record<string, string> = {
386
+ auth_failed: 'eidScannerScreen.nfcAuthFailed',
387
+ tag_lost: 'eidScannerScreen.nfcTagLost',
388
+ timeout: 'eidScannerScreen.nfcTimeout',
389
+ not_enabled: 'eidScannerScreen.nfcNotEnabled',
390
+ };
391
+
392
+ if (category !== 'user_cancelled') {
393
+ const actionableKey = ACTIONABLE[category];
394
+ if (actionableKey) {
395
+ // Clear user action available — meaningful message, no support code.
396
+ Alert.alert(t('eidScannerScreen.error'), t(actionableKey));
397
+ } else {
398
+ // Unexpected/system error — generic message + reportable support code.
399
+ const errorCode = tagged?.nfcCode ?? 'NFC-READ';
400
+ const message = `${t('eidScannerScreen.nfcGenericError')}\n\n${t(
401
+ 'eidScannerScreen.errorCode'
402
+ )}: ${errorCode}`;
403
+ Alert.alert(t('eidScannerScreen.error'), message);
404
+ }
405
+ }
352
406
  } finally {
353
407
  setIsScanning(false);
354
408
  setProgress(0);
@@ -566,59 +620,86 @@ const EIDScanner = ({
566
620
  </View>
567
621
  </View>
568
622
 
569
- {/* Right column: all fields as grid */}
623
+ {/* Right column: all fields as grid. Each field renders only
624
+ when the chip actually provided a value — filler-only /
625
+ empty fields are hidden rather than shown blank. */}
570
626
  <View style={styles.idCardFields}>
571
- <IDCardField
572
- label={t('eidScannerScreen.surname')}
573
- value={documentName?.displayLast ?? documentMRZInfo.getPrimaryIdentifier()}
574
- />
575
- <IDCardField
576
- label={t('eidScannerScreen.name')}
577
- value={documentName?.displayFirst ?? documentMRZInfo.getSecondaryIdentifier()}
578
- />
579
- <IDCardField
580
- label={t('eidScannerScreen.documentNumber')}
581
- value={documentMRZInfo.getDocumentNumber()}
582
- />
583
- <IDCardField
584
- label={t('eidScannerScreen.birthDate')}
585
- value={formatDate(documentMRZInfo.getDateOfBirth())}
586
- />
587
- <IDCardField
588
- label={t('eidScannerScreen.expirationDate')}
589
- value={formatDate(documentMRZInfo.getDateOfExpiry())}
590
- />
591
- <IDCardField
592
- label={t('eidScannerScreen.gender')}
593
- value={formatGender(
627
+ {(() => {
628
+ const surname =
629
+ documentName?.displayLast ??
630
+ cleanField(documentMRZInfo.getPrimaryIdentifier());
631
+ const givenNames =
632
+ documentName?.displayFirst ??
633
+ cleanField(documentMRZInfo.getSecondaryIdentifier());
634
+ const docNumber = cleanField(
635
+ documentMRZInfo.getDocumentNumber()
636
+ );
637
+ const birthDate = formatDate(
638
+ documentMRZInfo.getDateOfBirth()
639
+ );
640
+ const expiry = formatDate(
641
+ documentMRZInfo.getDateOfExpiry()
642
+ );
643
+ const gender = formatGender(
594
644
  documentMRZInfo.getGender().getStrCode()
595
- )}
596
- />
597
- <IDCardField
598
- label={t('eidScannerScreen.nationality')}
599
- value={formatNationality(
645
+ );
646
+ const nationality = formatNationality(
600
647
  documentMRZInfo.getNationality()
601
- )}
602
- />
603
- <IDCardField
604
- label={t('eidScannerScreen.issuingState')}
605
- value={formatNationality(
648
+ );
649
+ const issuingState = formatNationality(
606
650
  documentMRZInfo.getIssuingState()
607
- )}
608
- />
609
- {!!(
610
- documentMRZInfo.getPersonalNumber() ||
611
- documentMRZInfo.getOptionalData1()
612
- ) && (
613
- <IDCardField
614
- label={t('eidScannerScreen.personalNumber')}
615
- value={
616
- documentMRZInfo.getPersonalNumber() ||
617
- documentMRZInfo.getOptionalData1() ||
618
- ''
619
- }
620
- />
621
- )}
651
+ );
652
+ const personalNumber = cleanField(
653
+ documentMRZInfo.getPersonalNumber() ||
654
+ documentMRZInfo.getOptionalData1()
655
+ );
656
+
657
+ const fields: Array<{ label: string; value: string }> = [
658
+ {
659
+ label: t('eidScannerScreen.surname'),
660
+ value: surname,
661
+ },
662
+ {
663
+ label: t('eidScannerScreen.name'),
664
+ value: givenNames,
665
+ },
666
+ {
667
+ label: t('eidScannerScreen.documentNumber'),
668
+ value: docNumber,
669
+ },
670
+ {
671
+ label: t('eidScannerScreen.birthDate'),
672
+ value: birthDate,
673
+ },
674
+ {
675
+ label: t('eidScannerScreen.expirationDate'),
676
+ value: expiry,
677
+ },
678
+ { label: t('eidScannerScreen.gender'), value: gender },
679
+ {
680
+ label: t('eidScannerScreen.nationality'),
681
+ value: nationality,
682
+ },
683
+ {
684
+ label: t('eidScannerScreen.issuingState'),
685
+ value: issuingState,
686
+ },
687
+ {
688
+ label: t('eidScannerScreen.personalNumber'),
689
+ value: personalNumber,
690
+ },
691
+ ];
692
+
693
+ return fields
694
+ .filter((f) => f.value && f.value.trim().length > 0)
695
+ .map((f) => (
696
+ <IDCardField
697
+ key={f.label}
698
+ label={f.label}
699
+ value={f.value}
700
+ />
701
+ ));
702
+ })()}
622
703
  </View>
623
704
  </View>
624
705
  </View>
@@ -636,7 +717,7 @@ const EIDScanner = ({
636
717
  documentFaceImageMimeType
637
718
  ) {
638
719
  onScanSuccess(
639
- getFieldsFromMRZ(documentMRZInfo),
720
+ getFieldsFromMRZ(documentMRZInfo, documentName),
640
721
  documentFaceImage,
641
722
  documentFaceImageMimeType
642
723
  );
@@ -723,7 +804,7 @@ const EIDScanner = ({
723
804
  documentFaceImageMimeType
724
805
  ) {
725
806
  onScanSuccess(
726
- getFieldsFromMRZ(documentMRZInfo),
807
+ getFieldsFromMRZ(documentMRZInfo, documentName),
727
808
  documentFaceImage,
728
809
  documentFaceImageMimeType
729
810
  );
@@ -17,7 +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
- export const PASSPORT_MRZ_PATTERN = /P<[A-Z]{3}/;
20
+ // Matches the line-1 start of ANY ICAO TD3 passport MRZ, so the camera routes
21
+ // every passport variant into the passport flow (not the ID-card back-side
22
+ // flow). Per ICAO 9303 Part 4: `P` + a type char (filler `<` or a subtype
23
+ // letter — `P<`, `PP` German, `PD`/`PS`/`PO` diplomatic/service/official) +
24
+ // the issuing state (3 letters, OR the German 1-letter `D` padded with filler,
25
+ // e.g. `P<D<<` / `PPD<<`). Previously only `P<[A-Z]{3}` matched, so German `PP`
26
+ // and 1-letter-issuer passports fell through to the ID-card flow and were
27
+ // wrongly asked for a back side.
28
+ export const PASSPORT_MRZ_PATTERN = /P[A-Z<](?:[A-Z]{3}|[A-Z]<<)[A-Z<]*<</;
21
29
 
22
30
  // BDDK Madde 7 - Security Feature Validation
23
31
  // When NFC chip reading unavailable, must verify at least 4 visual security features
@@ -4,6 +4,10 @@ import type { FileSystemStructured } from './smartcards/fileSystemStructured';
4
4
  import { Buffer } from 'buffer';
5
5
 
6
6
  export class CardFileInputStream extends InputStream {
7
+ /** Max re-issues of a single block read before failing — mitigates transient
8
+ * iOS NFC transceive drops during large-file reads (e.g. DG2). */
9
+ private static readonly MAX_BLOCK_READ_RETRIES = 5;
10
+
7
11
  private path!: FileInfo[];
8
12
  private buffer!: Buffer;
9
13
  private bufferLength!: number;
@@ -69,12 +73,32 @@ export class CardFileInputStream extends InputStream {
69
73
  newOffsetBufferInFile = this.offsetBufferInFile + this.bufferLength;
70
74
  let newOffsetInBuffer = 0;
71
75
  let newBufferLength = 0;
72
- while (newBufferLength === 0) {
73
- newBufferLength = await this.fillBufferFromFile(
74
- this.path,
75
- newOffsetBufferInFile,
76
- le
77
- );
76
+ // Retry a failed block read. The iOS NFC stack (react-native-nfc-manager)
77
+ // throws transient "READ BINARY" transceive errors during the many
78
+ // block reads of a large file like DG2 (face image); a single drop
79
+ // previously aborted the whole read with "Could not read file". Re-issue
80
+ // the SAME block (offset unchanged) a few times before giving up — this
81
+ // is idempotent (no secure-messaging state advances on a failed read).
82
+ let attempt = 0;
83
+ for (;;) {
84
+ try {
85
+ newBufferLength = 0;
86
+ while (newBufferLength === 0) {
87
+ newBufferLength = await this.fillBufferFromFile(
88
+ this.path,
89
+ newOffsetBufferInFile,
90
+ le
91
+ );
92
+ }
93
+ break;
94
+ } catch (blockError) {
95
+ if (++attempt >= CardFileInputStream.MAX_BLOCK_READ_RETRIES) {
96
+ throw blockError;
97
+ }
98
+ // Brief backoff: an immediate re-issue after a transient NFC drop
99
+ // usually fails again; a short pause lets the RF field re-stabilise.
100
+ await new Promise((r) => setTimeout(r, 80 * attempt));
101
+ }
78
102
  }
79
103
 
80
104
  this.offsetBufferInFile = newOffsetBufferInFile;
@@ -6,10 +6,12 @@ import { FileInfo } from './fileInfo';
6
6
  import { ISO7816_SW } from './smartcards/iso7816';
7
7
  import { SecureMessagingWrapper } from './secureMessagingWrapper';
8
8
  import { TripleDesSecureMessagingWrapper } from './tripleDesSecureMessagingWrapper';
9
+ import { AESSecureMessagingWrapper } from './aesSecureMessagingWrapper';
9
10
  import type { APDUWrapper } from './smartcards/apduWrapper';
10
11
  import { TLVInputStream } from './tlv/tlvInputStream';
11
12
  import { CVCAFile } from './lds/cvcaFile';
12
13
  import { Buffer } from 'buffer';
14
+ import { Platform } from 'react-native';
13
15
  import type { FileSystemStructured } from './smartcards/fileSystemStructured';
14
16
 
15
17
  export class DefaultFileSystem implements FileSystemStructured {
@@ -37,7 +39,37 @@ export class DefaultFileSystem implements FileSystemStructured {
37
39
  this.isSelected = false;
38
40
  this.isSFIEnabled = isSFIEnabled;
39
41
  this.fidToSFI = fidToSFI;
40
- this.maxReadBinaryLength = EID_CONSTANTS.EXTENDED_MAX_TRANSCEIVE_LENGTH;
42
+ // iOS CoreNFC (via react-native-nfc-manager's sendCommandAPDUIOS) does not
43
+ // accept the EXTENDED-length APDU byte form this code emits when ne > 256
44
+ // (a 7-byte "00 XX XX" Le). Such a READ BINARY is rejected outright, so on
45
+ // iOS EVERY DG2 read failed ("Exception during READ BINARY") even though
46
+ // PACE — which only used short Le=256 — succeeded. Start at a short-form
47
+ // length on iOS (ne <= 256) so every READ BINARY stays in the short APDU
48
+ // form. Android's transceive() handles extended APDUs, so keep extended
49
+ // there for speed. JMRTD/NFCPassportReader likewise read in small blocks.
50
+ this.maxReadBinaryLength =
51
+ Platform.OS === 'ios'
52
+ ? EID_CONSTANTS.DEFAULT_MAX_BLOCKSIZE // 223 → short-form Le, SM-safe
53
+ : EID_CONSTANTS.EXTENDED_MAX_TRANSCEIVE_LENGTH;
54
+ }
55
+
56
+ /** Deep-copy a secure-messaging wrapper PRESERVING its cipher type (AES vs
57
+ * 3DES), so the SSC can be rewound for a retry without changing the MAC/enc
58
+ * algorithm. Non-SM wrappers are returned as-is. */
59
+ private cloneWrapper(wrapper: APDUWrapper): APDUWrapper {
60
+ if (!(wrapper instanceof SecureMessagingWrapper)) {
61
+ return wrapper;
62
+ }
63
+ const args: [string, string, number, boolean, bigint] = [
64
+ wrapper.getEncryptionKey(),
65
+ wrapper.getMACKey(),
66
+ wrapper.getMaxTransceiveLength(),
67
+ wrapper.getShouldCheckMAC(),
68
+ wrapper.getSendSequenceCounter(),
69
+ ];
70
+ return wrapper.getType() === 'AES'
71
+ ? new AESSecureMessagingWrapper(...args)
72
+ : new TripleDesSecureMessagingWrapper(...args);
41
73
  }
42
74
 
43
75
  public setWrapper(wrapper: APDUWrapper): void {
@@ -131,19 +163,49 @@ export class DefaultFileSystem implements FileSystemStructured {
131
163
 
132
164
  return result;
133
165
  } catch (error) {
134
- const sw = (error as any).getSW();
166
+ // Only APDU-level errors expose getSW(); a transient native NFC transceive
167
+ // error does NOT, so calling it unguarded threw a TypeError and masked the
168
+ // real failure. Guard it before testing for the WRONG_LENGTH downgrade.
169
+ const sw =
170
+ typeof (error as { getSW?: () => number }).getSW === 'function'
171
+ ? (error as { getSW: () => number }).getSW()
172
+ : undefined;
173
+ const isWrongLength =
174
+ sw != null &&
175
+ (sw & ISO7816_SW.WRONG_LENGTH) === ISO7816_SW.WRONG_LENGTH;
176
+
177
+ // Downgrade the read size and signal a retry (empty result) when EITHER:
178
+ // - the chip returned 6Cxx WRONG_LENGTH (the standard JMRTD path), OR
179
+ // - the read failed transiently with NO status word while we were still
180
+ // at extended length. iOS CoreNFC (via react-native-nfc-manager) drops
181
+ // the connection on too-large extended-length READ BINARY on some chips
182
+ // (e.g. German passport DG2) instead of returning 6Cxx, so the chip
183
+ // never gets to ask for a smaller length. Dropping to the conservative
184
+ // 223-byte block makes the next read succeed. Reference readers
185
+ // (JMRTD, NFCPassportReader) read large files in small blocks (~0xA0).
186
+ // Restore the pre-send secure-messaging wrapper. A failed wrapped READ
187
+ // BINARY still advanced the send-sequence-counter, so a retry MUST reset
188
+ // it or every subsequent read fails the MAC. (This is why the read
189
+ // previously stalled partway through DG2: each retry reused a desynced
190
+ // SSC.) JMRTD does the same reset on its downgrade path.
191
+ this.wrapper = this.oldWrapper;
192
+
135
193
  if (
136
- (sw & ISO7816_SW.WRONG_LENGTH) === ISO7816_SW.WRONG_LENGTH &&
194
+ (isWrongLength || sw == null) &&
137
195
  this.maxReadBinaryLength > EID_CONSTANTS.DEFAULT_MAX_BLOCKSIZE
138
196
  ) {
139
- this.wrapper = this.oldWrapper;
140
197
  this.maxReadBinaryLength = EID_CONSTANTS.DEFAULT_MAX_BLOCKSIZE;
141
198
  return new Uint8Array(0);
142
199
  }
143
200
 
144
- throw new Error(
145
- `Read binary failed on file ${fileInfo == null ? this.selectedFID.toString(16) : fileInfo}`
146
- );
201
+ // Preserve the original error (a transient transceive failure at an
202
+ // already-small block size) so the retry layer above can recognise and
203
+ // re-issue it, instead of flattening every cause into one opaque string.
204
+ throw error instanceof Error
205
+ ? error
206
+ : new Error(
207
+ `Read binary failed on file ${fileInfo == null ? this.selectedFID.toString(16) : fileInfo}`
208
+ );
147
209
  }
148
210
  }
149
211
 
@@ -216,16 +278,12 @@ export class DefaultFileSystem implements FileSystemStructured {
216
278
  le: number,
217
279
  isTLVEncodedOffsetNeeded: boolean
218
280
  ) {
219
- this.oldWrapper =
220
- this.wrapper instanceof SecureMessagingWrapper
221
- ? new TripleDesSecureMessagingWrapper(
222
- this.wrapper.getEncryptionKey(),
223
- this.wrapper.getMACKey(),
224
- this.wrapper.getMaxTransceiveLength(),
225
- this.wrapper.getShouldCheckMAC(),
226
- this.wrapper.getSendSequenceCounter()
227
- )
228
- : this.wrapper;
281
+ // Snapshot the wrapper BEFORE the send so a failed read can rewind the SSC.
282
+ // The copy MUST preserve the actual wrapper type — PACE sessions are AES
283
+ // (the German passport uses AES-CMAC). Previously this always built a 3DES
284
+ // wrapper, so an AES session's retry used a 3DES wrapper with AES keys and
285
+ // every subsequent read failed the MAC — the cause of the DG2 stall.
286
+ this.oldWrapper = this.cloneWrapper(this.wrapper);
229
287
  return this.service.sendReadBinary(
230
288
  this.wrapper,
231
289
  DefaultFileSystem.NO_SFI,