@gwydion-id/icao-9303-models 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/CC0-1.0.txt +121 -0
- package/LICENSES/LGPL-3.0-or-later.txt +304 -0
- package/README.md +79 -0
- package/package.json +17 -0
- package/package.json.license +3 -0
- package/src/digitalseal.js +234 -0
- package/src/digitalsealv3.js +359 -0
- package/src/digitalsealv4.js +369 -0
- package/src/index.js +41 -0
- package/src/mrvadocument.js +465 -0
- package/src/mrvadocumentwithvds3.js +559 -0
- package/src/mrvadocumentwithvds4.js +559 -0
- package/src/mrvbdocument.js +466 -0
- package/src/mrvbdocumentwithvds3.js +560 -0
- package/src/mrvbdocumentwithvds4.js +560 -0
- package/src/td1document.js +408 -0
- package/src/td1documentwithvds3.js +479 -0
- package/src/td1documentwithvds4.js +479 -0
- package/src/td2document.js +379 -0
- package/src/td2documentwithvds3.js +466 -0
- package/src/td2documentwithvds4.js +466 -0
- package/src/td3document.js +391 -0
- package/src/td3documentwithvds3.js +466 -0
- package/src/td3documentwithvds4.js +466 -0
- package/src/traveldocument.js +306 -0
- package/src/utilities/bytes-to-date.js +23 -0
- package/src/utilities/c40-decode.js +225 -0
- package/src/utilities/c40-encode.js +254 -0
- package/src/utilities/c40-shift1.js +10 -0
- package/src/utilities/date-to-bytes.js +38 -0
- package/src/utilities/der-length-to-length.js +33 -0
- package/src/utilities/expand-year.js +26 -0
- package/src/utilities/gender-marker-to-mrz.js +14 -0
- package/src/utilities/generate-mrz-check-digit.js +139 -0
- package/src/utilities/icao-date.js +234 -0
- package/src/utilities/length-to-der-length.js +41 -0
- package/src/utilities/nationality-codes.js +303 -0
- package/src/utilities/normalize-mrz-string.js +19 -0
- package/src/utilities/optional-data-mrz.js +29 -0
- package/src/utilities/pad-mrz-string.js +16 -0
- package/src/utilities/set-signature-zone.js +34 -0
- package/src/utilities/stringify-validation-array.js +27 -0
- package/src/utilities/validate-hex-string.js +41 -0
- package/src/utilities/validate-identifier-code.js +38 -0
- package/src/utilities/validate-mrz-string.js +44 -0
- package/src/utilities/vds-magic.js +9 -0
- package/src/utilities/vds-signature-marker.js +9 -0
- package/src/utilities/vds-version-3.js +9 -0
- package/src/utilities/vds-version-4.js +9 -0
- package/src/visadocument.js +114 -0
- package/tests/models/digitalsealv4.test.js +67 -0
- package/tests/models/mrvadocument.test.js +61 -0
- package/tests/models/mrvbdocument.test.js +61 -0
- package/tests/models/td1document.test.js +50 -0
- package/tests/models/td2document.test.js +49 -0
- package/tests/models/td3document.test.js +88 -0
- package/tests/utilities/c40-encodation-scheme.test.js +34 -0
- package/tests/utilities/der-tlv-length-conversion.test.js +99 -0
- package/tests/utilities/document-utilities.test.js +199 -0
- package/tests/utilities/icao-constants.test.js +35 -0
- package/tests/utilities/icao-date.test.js +141 -0
- package/tests/utilities/vds-date-conversions.test.js +28 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Don Geronimo <https://sentamal.in>
|
|
2
|
+
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
3
|
+
|
|
4
|
+
import { DigitalSeal } from "./digitalseal.js";
|
|
5
|
+
import { c40Encode } from "./utilities/c40-encode.js";
|
|
6
|
+
import { c40Decode } from "./utilities/c40-decode.js";
|
|
7
|
+
import { VDS_MAGIC } from "./utilities/vds-magic.js";
|
|
8
|
+
import { VDS_SIGNATURE_MARKER } from "./utilities/vds-signature-marker.js";
|
|
9
|
+
import { VDS_VERSION_4 } from "./utilities/vds-version-4.js";
|
|
10
|
+
import { lengthToDERLength } from "./utilities/length-to-der-length.js";
|
|
11
|
+
import { derLengthToLength } from "./utilities/der-length-to-length.js";
|
|
12
|
+
import { setSignatureZone } from "./utilities/set-signature-zone.js";
|
|
13
|
+
import { IcaoDate } from "./utilities/icao-date.js";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Stores properties and methods for ICAO 9303 visible digital seals (VDSs)
|
|
17
|
+
* version 4. Consult ICAO 9030 part 13 to see the differences between this
|
|
18
|
+
* version and other versions.
|
|
19
|
+
*
|
|
20
|
+
* `DigitalSealV4` is intended to be used to compose different kinds of
|
|
21
|
+
* machine-readable travel documents (MRTDs) with attached VDSs containing
|
|
22
|
+
* different document features. It is not intended to be instantiated
|
|
23
|
+
* directly.
|
|
24
|
+
*/
|
|
25
|
+
export class DigitalSealV4 {
|
|
26
|
+
/**
|
|
27
|
+
* Create a `DigitalSealV4`.
|
|
28
|
+
* @param { Object } [opt] - An options object.
|
|
29
|
+
* @param { string } [opt.authorityCode] - A 3-character string consisting of
|
|
30
|
+
* the characters A-Z, 0-9, ' ', or <. A code from ISO-3166-1,
|
|
31
|
+
* ICAO 9303-3, or these user-assigned ranges are recommended: AAA-AAZ,
|
|
32
|
+
* QMA-QZZ, XAA-XZZ, or ZZA-ZZZ.
|
|
33
|
+
* @param { string } [opt.identifierCode] - A 4-character string consisting of
|
|
34
|
+
* the characters 0-9 and A-Z.
|
|
35
|
+
* @param { string } [opt.certReference] - A hex-string that uniquely
|
|
36
|
+
* identifies a certificate for a given signer.
|
|
37
|
+
* @param { string | Date | IcaoDate } [opt.issueDate] - A calendar date string in
|
|
38
|
+
* YYYY-MM-DD format, a `Date` object, or an `IcaoDate` object.
|
|
39
|
+
* @param { string | Date | IcaoDate } [opt.signatureDate] - A calendar date string in
|
|
40
|
+
* YYYY-MM-DD format, a `Date` object, or an `IcaoDate` object.
|
|
41
|
+
* @param { number } [opt.featureDefinition] - A number in the range of
|
|
42
|
+
* 0x01-0xFE.
|
|
43
|
+
* @param { number } [opt.typeCategory] - A number in the range of 0x01-0xFE.
|
|
44
|
+
* Odd numbers in the range between 0x01 and 0xFD shall be used for
|
|
45
|
+
* ICAO-specified document type categories.
|
|
46
|
+
* @param { Map<number, number[]> } [opt.features] - A store of
|
|
47
|
+
* digitally-encoded document features used to create the message zone.
|
|
48
|
+
* @param { number[] } [opt.signatureData] - The raw signature data generated
|
|
49
|
+
* by concatenating the header and message zone, hashing the result, and
|
|
50
|
+
* signing the hash with a cryptographic key.
|
|
51
|
+
* @param { number[] } [opt.headerZone] - The header zone of the VDS as
|
|
52
|
+
* defined by ICAO 9303 part 13.
|
|
53
|
+
* @param { number[] } [opt.messageZone] - The message zone of the VDS as
|
|
54
|
+
* defined by ICAO 9303 part 13.
|
|
55
|
+
* @param { number[] } [opt.signatureZone] - The signature zone of the VDS as
|
|
56
|
+
* a TLV of the signature marker, its length in BER/DER definite length
|
|
57
|
+
* form, and the raw signature data.
|
|
58
|
+
* @param { number[] } [opt.unsignedSeal] - A concatenation of the header zone
|
|
59
|
+
* and the message zone of the VDS.
|
|
60
|
+
* @param { number[] } [opt.signedSeal] - A concatenation of the header zone,
|
|
61
|
+
* the message zone, and the signature zone of the VDS.
|
|
62
|
+
*/
|
|
63
|
+
constructor(opt) {
|
|
64
|
+
this.#digitalseal = new DigitalSeal();
|
|
65
|
+
|
|
66
|
+
this.authorityCode = opt?.authorityCode ?? "UTO";
|
|
67
|
+
this.identifierCode = opt?.identifierCode ?? "UTSS";
|
|
68
|
+
this.certReference = opt?.certReference ?? "00000";
|
|
69
|
+
this.issueDate = opt?.issueDate ?? "2007-04-15";
|
|
70
|
+
this.signatureDate = opt?.signatureDate ?? "2007-04-15";
|
|
71
|
+
this.featureDefinition = opt?.featureDefinition ?? 0x01;
|
|
72
|
+
this.typeCategory = opt?.typeCategory ?? 0x01;
|
|
73
|
+
this.features = opt?.features ?? new Map();
|
|
74
|
+
this.signatureData = opt?.signatureData ?? Array(64).fill(0);
|
|
75
|
+
|
|
76
|
+
if (opt?.headerZone) { this.headerZone = opt.headerZone; }
|
|
77
|
+
if (opt?.messageZone) { this.messageZone = opt.messageZone; }
|
|
78
|
+
if (opt?.signatureZone) { this.signatureZone = opt.signatureZone; }
|
|
79
|
+
if (opt?.unsignedSeal) { this.unsignedSeal = opt.unsignedSeal; }
|
|
80
|
+
if (opt?.signedSeal) { this.signedSeal = opt.signedSeal; }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// The object `DigitalSealV4` uses to compose itself.
|
|
84
|
+
#digitalseal;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* A code identifying the authority who issued this seal.
|
|
88
|
+
* @type { string }
|
|
89
|
+
*/
|
|
90
|
+
get authorityCode() { return this.#digitalseal.authorityCode; }
|
|
91
|
+
/**
|
|
92
|
+
* @param { string } value - A 3-character string consisting of the characters
|
|
93
|
+
* A-Z, 0-9, ' ', or <. A code from ISO-3166-1, ICAO 9303-3, or these
|
|
94
|
+
* user-assigned ranges are recommended: AAA-AAZ, QMA-QZZ, XAA-XZZ, or ZZA-ZZZ.
|
|
95
|
+
*/
|
|
96
|
+
set authorityCode(value) { this.#digitalseal.authorityCode = value; }
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* A combination of a two-letter authority code and of two alphanumeric
|
|
100
|
+
* characters to identify a signer within the issuing authority.
|
|
101
|
+
* @type { string }
|
|
102
|
+
*/
|
|
103
|
+
get identifierCode() { return this.#digitalseal.identifierCode; }
|
|
104
|
+
/**
|
|
105
|
+
* @param { string } value - A 4-character string consisting of the characters
|
|
106
|
+
* 0-9 and A-Z.
|
|
107
|
+
*/
|
|
108
|
+
set identifierCode(value) { this.#digitalseal.identifierCode = value; }
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* A hex-string that uniquely identifies a certificate for a given signer.
|
|
112
|
+
* @type { string }
|
|
113
|
+
*/
|
|
114
|
+
get certReference() { return this.#digitalseal.certReference; }
|
|
115
|
+
/**
|
|
116
|
+
* @param { string } value - A hex string.
|
|
117
|
+
*/
|
|
118
|
+
set certReference(value) { this.#digitalseal.certReference = value; }
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* A date string on which the document was issued.
|
|
122
|
+
* @type { IcaoDate }
|
|
123
|
+
*/
|
|
124
|
+
get issueDate() { return this.#digitalseal.issueDate; }
|
|
125
|
+
/**
|
|
126
|
+
* @param { string | Date | IcaoDate } value - A calendar date string in YYYY-MM-DD
|
|
127
|
+
* format, a `Date` object, or an `IcaoDate` object.
|
|
128
|
+
*/
|
|
129
|
+
set issueDate(value) { this.#digitalseal.issueDate = value; }
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* A date string on which the seal was signed.
|
|
133
|
+
* @type { IcaoDate }
|
|
134
|
+
*/
|
|
135
|
+
get signatureDate() { return this.#digitalseal.signatureDate; }
|
|
136
|
+
/**
|
|
137
|
+
* @param { string | Date | IcaoDate } value - A calendar date string in YYYY-MM-DD
|
|
138
|
+
* format, a `Date` object, or an `IcaoDate` object.
|
|
139
|
+
*/
|
|
140
|
+
set signatureDate(value) { this.#digitalseal.signatureDate = value; }
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* A reference code to a document that defines the number and encoding of VDS
|
|
144
|
+
* features.
|
|
145
|
+
* @type { number }
|
|
146
|
+
*/
|
|
147
|
+
get featureDefinition() { return this.#digitalseal.featureDefinition; }
|
|
148
|
+
/**
|
|
149
|
+
* @param { number } value - A number in the range of 0x01-0xFE.
|
|
150
|
+
*/
|
|
151
|
+
set featureDefinition(value) { this.#digitalseal.featureDefinition = value; }
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* A code defining the document type category to which the seal is attached.
|
|
155
|
+
* @type { number }
|
|
156
|
+
*/
|
|
157
|
+
get typeCategory() { return this.#digitalseal.typeCategory; }
|
|
158
|
+
/**
|
|
159
|
+
* @param { number } value - A number in the range of 0x01-0xFE. Odd numbers
|
|
160
|
+
* in the range between 0x01 and 0xFD shall be used for ICAO-specified
|
|
161
|
+
* document type categories.
|
|
162
|
+
*/
|
|
163
|
+
set typeCategory(value) { this.#digitalseal.typeCategory = value; }
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* A store of digitally-encoded document features used to create the message
|
|
167
|
+
* zone.
|
|
168
|
+
* @type { Map<number, number[]>}
|
|
169
|
+
*/
|
|
170
|
+
get features() { return this.#digitalseal.features; }
|
|
171
|
+
/**
|
|
172
|
+
* @param { Map<number, number[]> } value
|
|
173
|
+
*/
|
|
174
|
+
set features(value) { this.#digitalseal.features = value; }
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* The raw signature data generated by concatenating the header and message
|
|
178
|
+
* zone, hashing the result, and signing the hash with a cryptographic
|
|
179
|
+
* key.
|
|
180
|
+
* @type { number[] }
|
|
181
|
+
*/
|
|
182
|
+
get signatureData() { return this.#digitalseal.signatureData; }
|
|
183
|
+
/**
|
|
184
|
+
* @param { number[] } value
|
|
185
|
+
*/
|
|
186
|
+
set signatureData(value) { this.#digitalseal.signatureData = value; }
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* The header zone of the VDS as defined by ICAO 9303 part 13.
|
|
190
|
+
* @type { number[] }
|
|
191
|
+
*/
|
|
192
|
+
get headerZone() {
|
|
193
|
+
let output = [];
|
|
194
|
+
output.push(VDS_MAGIC);
|
|
195
|
+
output.push(VDS_VERSION_4);
|
|
196
|
+
output =
|
|
197
|
+
output.concat(c40Encode(this.authorityCode.padEnd(3, "<")));
|
|
198
|
+
output = output.concat(c40Encode(
|
|
199
|
+
this.identifierCode +
|
|
200
|
+
this.certReference.length.toString(16).padStart(2, "0") +
|
|
201
|
+
this.certReference
|
|
202
|
+
));
|
|
203
|
+
output = output.concat(this.issueDate.toVDSArray());
|
|
204
|
+
output = output.concat(this.signatureDate.toVDSArray());
|
|
205
|
+
output.push(this.featureDefinition);
|
|
206
|
+
output.push(this.typeCategory);
|
|
207
|
+
return output;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* @param { number[] } value
|
|
211
|
+
*/
|
|
212
|
+
set headerZone(value) {
|
|
213
|
+
this.#setHeader(0, value);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Given a point 'start' in an array 'value', extract the header data.
|
|
217
|
+
* @param { number } start
|
|
218
|
+
* @param { number[] } value
|
|
219
|
+
* @returns { number } The point in the array where the method stopped
|
|
220
|
+
* reading.
|
|
221
|
+
*/
|
|
222
|
+
#setHeader(start, value) {
|
|
223
|
+
if (value[0] !== VDS_MAGIC) {
|
|
224
|
+
throw new TypeError(
|
|
225
|
+
`Value '${value[0].toString(16).padStart(2, "0").toUpperCase()}' is ` +
|
|
226
|
+
`not an ICAO Digital Seal (` +
|
|
227
|
+
`${VDS_MAGIC.toString(16).padStart(2, "0").toUpperCase()}).`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
if (value[1] !== VDS_VERSION_4) {
|
|
231
|
+
throw new TypeError(
|
|
232
|
+
`Value '${value[0].toString(16).padStart(2, "0").toUpperCase()}' is ` +
|
|
233
|
+
`not version 4 of an ICAO Digital Seal (` +
|
|
234
|
+
`${VDS_VERSION_4.toString(16).padStart(
|
|
235
|
+
2, "0"
|
|
236
|
+
).toUpperCase()}).`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
start += 2;
|
|
240
|
+
this.authorityCode =
|
|
241
|
+
c40Decode(value.slice(start, start + 2)).trim();
|
|
242
|
+
start += 2;
|
|
243
|
+
const ID_LENGTH = c40Decode(value.slice(start, start + 4));
|
|
244
|
+
this.identifierCode = ID_LENGTH.substring(0, 4);
|
|
245
|
+
const CERT_REF_LENGTH = parseInt(ID_LENGTH.substring(4, 6), 16);
|
|
246
|
+
let certRefC40Length = Math.floor(CERT_REF_LENGTH / 3) * 2;
|
|
247
|
+
const CERT_REF_MODULUS = CERT_REF_LENGTH % 3;
|
|
248
|
+
if (CERT_REF_MODULUS) {
|
|
249
|
+
certRefC40Length += 2;
|
|
250
|
+
}
|
|
251
|
+
start += 4;
|
|
252
|
+
const CERT_REF_DECODE =
|
|
253
|
+
c40Decode(value.slice(start, start + certRefC40Length));
|
|
254
|
+
if (CERT_REF_LENGTH !== CERT_REF_DECODE.length) {
|
|
255
|
+
throw new RangeError(
|
|
256
|
+
`Length '${CERT_REF_LENGTH}' of certificate reference does not match ` +
|
|
257
|
+
`the actual length (${CERT_REF_DECODE.length}).`
|
|
258
|
+
);
|
|
259
|
+
} else {
|
|
260
|
+
this.certReference = CERT_REF_DECODE;
|
|
261
|
+
}
|
|
262
|
+
start += certRefC40Length;
|
|
263
|
+
this.issueDate = new IcaoDate(value.slice(start, start + 3));
|
|
264
|
+
start += 3;
|
|
265
|
+
this.signatureDate = new IcaoDate(value.slice(start, start + 3));
|
|
266
|
+
start += 3;
|
|
267
|
+
this.featureDefinition = value[start];
|
|
268
|
+
start += 1;
|
|
269
|
+
this.typeCategory = value[start];
|
|
270
|
+
start += 1;
|
|
271
|
+
return start;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* The message zone of the VDS as defined by ICAO 9303 part 13.
|
|
276
|
+
* @type { number[] }
|
|
277
|
+
*/
|
|
278
|
+
get messageZone() {
|
|
279
|
+
let output = [];
|
|
280
|
+
for (const [tag, value] of this.features) {
|
|
281
|
+
output.push(tag);
|
|
282
|
+
output = output.concat(lengthToDERLength(value.length));
|
|
283
|
+
output = output.concat(value);
|
|
284
|
+
}
|
|
285
|
+
return output;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* @param { number[] } value
|
|
289
|
+
*/
|
|
290
|
+
set messageZone(value) {
|
|
291
|
+
this.#setMessage(0, value);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Given a point 'start' in an array 'value', extract the document feature
|
|
295
|
+
* data.
|
|
296
|
+
* @param { number } start
|
|
297
|
+
* @param { number[] } value
|
|
298
|
+
* @returns { number } The point in the array where the method stopped
|
|
299
|
+
* reading.
|
|
300
|
+
*/
|
|
301
|
+
#setMessage(start, value) {
|
|
302
|
+
this.features.clear();
|
|
303
|
+
while (start < value.length) {
|
|
304
|
+
if (value[start] === VDS_SIGNATURE_MARKER) {
|
|
305
|
+
break;
|
|
306
|
+
}
|
|
307
|
+
const TAG = value[start];
|
|
308
|
+
start += 1;
|
|
309
|
+
const LENGTH = derLengthToLength(value.slice(start));
|
|
310
|
+
start += lengthToDERLength(LENGTH).length;
|
|
311
|
+
const slicedValue = value.slice(start, start + LENGTH);
|
|
312
|
+
if (slicedValue.length !== LENGTH) {
|
|
313
|
+
throw new RangeError(
|
|
314
|
+
`Length '${LENGTH}' of document feature does not match the actual ` +
|
|
315
|
+
`length (${slicedValue.length}).`
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
this.features.set(TAG, slicedValue);
|
|
319
|
+
start += LENGTH;
|
|
320
|
+
}
|
|
321
|
+
return start;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* The signature zone of the VDS as a TLV of the signature marker, its length
|
|
326
|
+
* in BER/DER definite length form, and the raw signature data.
|
|
327
|
+
* @type { number[] }
|
|
328
|
+
*/
|
|
329
|
+
get signatureZone() { return this.#digitalseal.signatureZone; }
|
|
330
|
+
/**
|
|
331
|
+
* @param { number[] } value
|
|
332
|
+
*/
|
|
333
|
+
set signatureZone(value) { this.#digitalseal.signatureZone = value; }
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* A concatenation of the header zone and the message zone of the VDS.
|
|
337
|
+
* @type { number[] }
|
|
338
|
+
*/
|
|
339
|
+
get unsignedSeal() {
|
|
340
|
+
return this.headerZone.concat(this.messageZone);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* @param { number[] } value
|
|
344
|
+
*/
|
|
345
|
+
set unsignedSeal(value) {
|
|
346
|
+
let start = 0;
|
|
347
|
+
start = this.#setHeader(start, value);
|
|
348
|
+
this.#setMessage(start, value);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* A concatenation of the header zone, the message zone, and the signature
|
|
353
|
+
* zone of the VDS.
|
|
354
|
+
* @type { number[] }
|
|
355
|
+
*/
|
|
356
|
+
get signedSeal() {
|
|
357
|
+
return this.headerZone.concat(this.messageZone.concat(this.signatureZone));
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* @param { number[] } value
|
|
361
|
+
*/
|
|
362
|
+
set signedSeal(value) {
|
|
363
|
+
let start = 0;
|
|
364
|
+
start = this.#setHeader(start, value);
|
|
365
|
+
start = this.#setMessage(start, value);
|
|
366
|
+
this.signatureData = setSignatureZone(start, value);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
package/src/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SPDX-FileCopyrightText: 2026 Don Geronimo <https://sentamal.in>
|
|
2
|
+
// SPDX-License-Identifier: CC0-1.0
|
|
3
|
+
|
|
4
|
+
// Utility exports
|
|
5
|
+
export { NATIONALITY_CODES } from './utilities/nationality-codes.js';
|
|
6
|
+
export { IcaoDate } from './utilities/icao-date.js';
|
|
7
|
+
export { dateToBytes } from './utilities/dates-to-bytes.js';
|
|
8
|
+
export { bytesToDate } from './utilities/bytes-to-date.js';
|
|
9
|
+
export { c40Decode } from './utilities/c40-decode.js';
|
|
10
|
+
export { c40Encode } from './utilities/c40-encode.js';
|
|
11
|
+
export { derLengthToLength } from './utilities/der-length-to-length.js';
|
|
12
|
+
export { lengthToDERLength } from './utilities/length-to-der-length.js';
|
|
13
|
+
|
|
14
|
+
// Abstract models
|
|
15
|
+
export { DigitalSeal } from './digitalseal.js'; // TODO: Test Suite
|
|
16
|
+
export { TravelDocument } from './traveldocument.js'; // TODO: Test Suite
|
|
17
|
+
export { VisaDocument } from './visadocument.js'; // TODO: Test Suite
|
|
18
|
+
|
|
19
|
+
// Digital seals
|
|
20
|
+
export { DigitalSealV3 } from './digitalsealv3.js'; // TODO: Test Suite
|
|
21
|
+
export { DigitalSealV4 } from './digitalsealv4.js';
|
|
22
|
+
|
|
23
|
+
// Base document models
|
|
24
|
+
export { TD1Document } from './td1document.js';
|
|
25
|
+
export { TD2Document } from './td2document.js';
|
|
26
|
+
export { TD3Document } from './td3document.js';
|
|
27
|
+
export { MRVADocument } from './mrvadocument.js';
|
|
28
|
+
export { MRVBDocument } from './mrvbdocument.js';
|
|
29
|
+
|
|
30
|
+
// Composed document models
|
|
31
|
+
export { TD1DocumentWithVDS3 } from './td1documentwithvds3.js'; // TODO: Test Suite
|
|
32
|
+
export { TD1DocumentWithVDS4 } from './td1documentwithvds4.js'; // TODO: Test Suite
|
|
33
|
+
export { TD2DocumentWithVDS3 } from './td2documentwithvds3.js'; // TODO: Test Suite
|
|
34
|
+
export { TD2DocumentWithVDS4 } from './td2documentwithvds4.js'; // TODO: Test Suite
|
|
35
|
+
export { TD3DocumentWithVDS3 } from './td3documentwithvds3.js'; // TODO: Test Suite
|
|
36
|
+
export { TD3DocumentWithVDS4 } from './td3documentwithvds4.js'; // TODO: Test Suite
|
|
37
|
+
export { MRVADocumentWithVDS3 } from './mrvadocumentwithvds3.js'; // TODO: Test Suite
|
|
38
|
+
export { MRVADocumentWithVDS4 } from './mrvadocumentwithvds4.js'; // TODO: Test Suite
|
|
39
|
+
export { MRVBDocumentWithVDS3 } from './mrvbdocumentwithvds3.js'; // TODO: Test Suite
|
|
40
|
+
export { MRVBDocumentWithVDS4 } from './mrvbdocumentwithvds4.js'; // TODO: Test Suite
|
|
41
|
+
|