@sd-jwt/core 0.20.1-next.5 → 0.20.1-next.6
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/dist/index.d.mts +35 -8
- package/dist/index.d.ts +35 -8
- package/dist/index.js +262 -60
- package/dist/index.mjs +257 -59
- package/package.json +3 -3
- package/src/decode/decode.ts +59 -28
- package/src/generalJSON.ts +9 -0
- package/src/index.ts +68 -6
- package/src/jwt.ts +109 -13
- package/src/kbjwt.ts +30 -10
- package/src/present/present.ts +11 -5
- package/src/sdjwt.ts +40 -10
- package/src/test/decode/decode.spec.ts +12 -17
- package/src/test/index.spec.ts +5 -38
- package/src/test/kbjwt.spec.ts +7 -17
- package/src/types/type.ts +21 -0
- package/src/utils/disclosure.ts +24 -4
- package/test/rfc9901-audit-fixes.spec.ts +252 -0
package/dist/index.js
CHANGED
|
@@ -69,6 +69,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
69
69
|
// src/index.ts
|
|
70
70
|
var index_exports = {};
|
|
71
71
|
__export(index_exports, {
|
|
72
|
+
DEFAULT_SECURE_HASH_ALGORITHMS: () => DEFAULT_SECURE_HASH_ALGORITHMS,
|
|
72
73
|
Disclosure: () => Disclosure,
|
|
73
74
|
FlattenJSON: () => FlattenJSON,
|
|
74
75
|
GeneralJSON: () => GeneralJSON,
|
|
@@ -94,6 +95,8 @@ __export(index_exports, {
|
|
|
94
95
|
decodeJwt: () => decodeJwt,
|
|
95
96
|
decodeSdJwt: () => decodeSdJwt,
|
|
96
97
|
decodeSdJwtSync: () => decodeSdJwtSync,
|
|
98
|
+
encodePath: () => encodePath,
|
|
99
|
+
encodePathSegment: () => encodePathSegment,
|
|
97
100
|
ensureError: () => ensureError,
|
|
98
101
|
getClaims: () => getClaims,
|
|
99
102
|
getClaimsSync: () => getClaimsSync,
|
|
@@ -110,7 +113,8 @@ __export(index_exports, {
|
|
|
110
113
|
uint8ArrayToBase64Url: () => import_identity_common.uint8ArrayToBase64Url,
|
|
111
114
|
unpack: () => unpack,
|
|
112
115
|
unpackObj: () => unpackObj,
|
|
113
|
-
unpackSync: () => unpackSync
|
|
116
|
+
unpackSync: () => unpackSync,
|
|
117
|
+
validateJwtPayload: () => validateJwtPayload
|
|
114
118
|
});
|
|
115
119
|
module.exports = __toCommonJS(index_exports);
|
|
116
120
|
|
|
@@ -120,6 +124,8 @@ var SD_LIST_KEY = "...";
|
|
|
120
124
|
var SD_DIGEST = "_sd";
|
|
121
125
|
var SD_DECOY = "_sd_decoy";
|
|
122
126
|
var KB_JWT_TYP = "kb+jwt";
|
|
127
|
+
var encodePathSegment = (segment) => segment.replace(/~/g, "~0").replace(/\./g, "~1");
|
|
128
|
+
var encodePath = (segments) => segments.map(encodePathSegment).join(".");
|
|
123
129
|
var IANA_HASH_ALGORITHMS = [
|
|
124
130
|
"sha-256",
|
|
125
131
|
"sha-256-128",
|
|
@@ -139,6 +145,19 @@ var IANA_HASH_ALGORITHMS = [
|
|
|
139
145
|
"k12-256",
|
|
140
146
|
"k12-512"
|
|
141
147
|
];
|
|
148
|
+
var DEFAULT_SECURE_HASH_ALGORITHMS = [
|
|
149
|
+
"sha-256",
|
|
150
|
+
"sha-384",
|
|
151
|
+
"sha-512",
|
|
152
|
+
"sha3-256",
|
|
153
|
+
"sha3-384",
|
|
154
|
+
"sha3-512",
|
|
155
|
+
"blake2s-256",
|
|
156
|
+
"blake2b-256",
|
|
157
|
+
"blake2b-512",
|
|
158
|
+
"k12-256",
|
|
159
|
+
"k12-512"
|
|
160
|
+
];
|
|
142
161
|
|
|
143
162
|
// src/utils/base64url.ts
|
|
144
163
|
var import_identity_common = require("@owf/identity-common");
|
|
@@ -176,6 +195,12 @@ var decodeBase64urlJsonStrict = (encoded, errorMessage) => {
|
|
|
176
195
|
// src/utils/disclosure.ts
|
|
177
196
|
var Disclosure = class _Disclosure {
|
|
178
197
|
constructor(data, _meta) {
|
|
198
|
+
if (!Array.isArray(data) || data.length !== 2 && data.length !== 3) {
|
|
199
|
+
throw new SDJWTException("Invalid disclosure data");
|
|
200
|
+
}
|
|
201
|
+
if (typeof data[0] !== "string") {
|
|
202
|
+
throw new SDJWTException("Invalid disclosure salt");
|
|
203
|
+
}
|
|
179
204
|
this._digest = _meta == null ? void 0 : _meta.digest;
|
|
180
205
|
this._encoded = _meta == null ? void 0 : _meta.encoded;
|
|
181
206
|
if (data.length === 2) {
|
|
@@ -184,12 +209,19 @@ var Disclosure = class _Disclosure {
|
|
|
184
209
|
return;
|
|
185
210
|
}
|
|
186
211
|
if (data.length === 3) {
|
|
212
|
+
if (typeof data[1] !== "string") {
|
|
213
|
+
throw new SDJWTException("Invalid disclosure claim name");
|
|
214
|
+
}
|
|
215
|
+
if (data[1] === SD_DIGEST || data[1] === SD_LIST_KEY) {
|
|
216
|
+
throw new SDJWTException(
|
|
217
|
+
`Reserved disclosure claim name "${data[1]}" is not allowed`
|
|
218
|
+
);
|
|
219
|
+
}
|
|
187
220
|
this.salt = data[0];
|
|
188
221
|
this.key = data[1];
|
|
189
222
|
this.value = data[2];
|
|
190
223
|
return;
|
|
191
224
|
}
|
|
192
|
-
throw new SDJWTException("Invalid disclosure data");
|
|
193
225
|
}
|
|
194
226
|
// We need to digest of the original encoded data.
|
|
195
227
|
// After decode process, we use JSON.stringify to encode the data.
|
|
@@ -263,10 +295,7 @@ var decodeJwt = (jwt) => {
|
|
|
263
295
|
var splitSdJwt = (sdjwt) => {
|
|
264
296
|
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
265
297
|
if (encodedDisclosures.length === 0) {
|
|
266
|
-
|
|
267
|
-
jwt: encodedJwt,
|
|
268
|
-
disclosures: []
|
|
269
|
-
};
|
|
298
|
+
throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
|
|
270
299
|
}
|
|
271
300
|
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
272
301
|
return {
|
|
@@ -279,10 +308,7 @@ var decodeSdJwt = (sdjwt, hasher) => __async(null, null, function* () {
|
|
|
279
308
|
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
280
309
|
const jwt = decodeJwt(encodedJwt);
|
|
281
310
|
if (encodedDisclosures.length === 0) {
|
|
282
|
-
|
|
283
|
-
jwt,
|
|
284
|
-
disclosures: []
|
|
285
|
-
};
|
|
311
|
+
throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
|
|
286
312
|
}
|
|
287
313
|
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
288
314
|
const kbJwt = encodedKeyBindingJwt ? decodeJwt(encodedKeyBindingJwt) : void 0;
|
|
@@ -302,10 +328,7 @@ var decodeSdJwtSync = (sdjwt, hasher) => {
|
|
|
302
328
|
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
303
329
|
const jwt = decodeJwt(encodedJwt);
|
|
304
330
|
if (encodedDisclosures.length === 0) {
|
|
305
|
-
|
|
306
|
-
jwt,
|
|
307
|
-
disclosures: []
|
|
308
|
-
};
|
|
331
|
+
throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
|
|
309
332
|
}
|
|
310
333
|
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
311
334
|
const kbJwt = encodedKeyBindingJwt ? decodeJwt(encodedKeyBindingJwt) : void 0;
|
|
@@ -334,7 +357,10 @@ var unpackArray = (arr, map, prefix = "", seenDigests) => {
|
|
|
334
357
|
arr.forEach((item, idx) => {
|
|
335
358
|
if (isRecord(item)) {
|
|
336
359
|
const hash = item[SD_LIST_KEY];
|
|
337
|
-
if (
|
|
360
|
+
if (SD_LIST_KEY in item) {
|
|
361
|
+
if (Object.keys(item).length !== 1 || typeof hash !== "string") {
|
|
362
|
+
throw new SDJWTException("Invalid array disclosure placeholder");
|
|
363
|
+
}
|
|
338
364
|
if (seenDigests) {
|
|
339
365
|
if (seenDigests.has(hash)) {
|
|
340
366
|
throw new SDJWTException(
|
|
@@ -345,6 +371,11 @@ var unpackArray = (arr, map, prefix = "", seenDigests) => {
|
|
|
345
371
|
}
|
|
346
372
|
const disclosed = map[hash];
|
|
347
373
|
if (disclosed) {
|
|
374
|
+
if (typeof disclosed.key === "string") {
|
|
375
|
+
throw new SDJWTException(
|
|
376
|
+
"Object-property disclosure cannot be used as an array element"
|
|
377
|
+
);
|
|
378
|
+
}
|
|
348
379
|
const presentKey = prefix ? `${prefix}.${idx}` : `${idx}`;
|
|
349
380
|
keys[presentKey] = hash;
|
|
350
381
|
const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(disclosed.value, map, presentKey, seenDigests);
|
|
@@ -387,8 +418,12 @@ var unpackObjInternal = (obj, map, prefix = "", seenDigests) => {
|
|
|
387
418
|
}
|
|
388
419
|
const record = obj;
|
|
389
420
|
for (const key in record) {
|
|
421
|
+
if (prefix && key === "_sd_alg") {
|
|
422
|
+
throw new SDJWTException("Nested _sd_alg is not allowed");
|
|
423
|
+
}
|
|
390
424
|
if (key !== SD_DIGEST && key !== SD_LIST_KEY && typeof record[key] === "object") {
|
|
391
|
-
const
|
|
425
|
+
const escapedKey = encodePathSegment(key);
|
|
426
|
+
const newKey = prefix ? `${prefix}.${escapedKey}` : escapedKey;
|
|
392
427
|
const { unpackedObj: unpackedObj2, disclosureKeymap: disclosureKeys } = unpackObjInternal(record[key], map, newKey, seenDigests);
|
|
393
428
|
record[key] = unpackedObj2;
|
|
394
429
|
Object.assign(keys, disclosureKeys);
|
|
@@ -396,7 +431,12 @@ var unpackObjInternal = (obj, map, prefix = "", seenDigests) => {
|
|
|
396
431
|
}
|
|
397
432
|
const _a = record, { _sd } = _a, payload = __objRest(_a, ["_sd"]);
|
|
398
433
|
const claims = {};
|
|
399
|
-
if (_sd) {
|
|
434
|
+
if (_sd !== void 0) {
|
|
435
|
+
if (!Array.isArray(_sd) || !_sd.every((hash) => typeof hash === "string")) {
|
|
436
|
+
throw new SDJWTException(
|
|
437
|
+
"Invalid _sd claim: expected array of strings"
|
|
438
|
+
);
|
|
439
|
+
}
|
|
400
440
|
for (const hash of _sd) {
|
|
401
441
|
if (seenDigests) {
|
|
402
442
|
if (seenDigests.has(hash)) {
|
|
@@ -407,13 +447,24 @@ var unpackObjInternal = (obj, map, prefix = "", seenDigests) => {
|
|
|
407
447
|
seenDigests.add(hash);
|
|
408
448
|
}
|
|
409
449
|
const disclosed = map[hash];
|
|
410
|
-
if (disclosed
|
|
450
|
+
if (disclosed) {
|
|
451
|
+
if (typeof disclosed.key !== "string") {
|
|
452
|
+
throw new SDJWTException(
|
|
453
|
+
"Array disclosure cannot be used as an object property"
|
|
454
|
+
);
|
|
455
|
+
}
|
|
411
456
|
if (disclosed.key in payload) {
|
|
412
457
|
throw new SDJWTException(
|
|
413
458
|
`Disclosed claim name "${disclosed.key}" conflicts with existing payload key`
|
|
414
459
|
);
|
|
415
460
|
}
|
|
416
|
-
|
|
461
|
+
if (disclosed.key in claims) {
|
|
462
|
+
throw new SDJWTException(
|
|
463
|
+
`Disclosed claim name "${disclosed.key}" conflicts with another disclosure`
|
|
464
|
+
);
|
|
465
|
+
}
|
|
466
|
+
const escapedKey = encodePathSegment(disclosed.key);
|
|
467
|
+
const presentKey = prefix ? `${prefix}.${escapedKey}` : escapedKey;
|
|
417
468
|
keys[presentKey] = hash;
|
|
418
469
|
const { unpackedObj: unpackedObj2, disclosureKeymap: disclosureKeys } = unpackObjInternal(disclosed.value, map, presentKey, seenDigests);
|
|
419
470
|
claims[disclosed.key] = unpackedObj2;
|
|
@@ -431,6 +482,9 @@ var createHashMapping = (disclosures, hash) => __async(null, null, function* ()
|
|
|
431
482
|
for (let i = 0; i < disclosures.length; i++) {
|
|
432
483
|
const disclosure = disclosures[i];
|
|
433
484
|
const digest = yield disclosure.digest(hash);
|
|
485
|
+
if (digest in map) {
|
|
486
|
+
throw new SDJWTException("Duplicate disclosure digest detected");
|
|
487
|
+
}
|
|
434
488
|
map[digest] = disclosure;
|
|
435
489
|
}
|
|
436
490
|
return map;
|
|
@@ -440,20 +494,29 @@ var createHashMappingSync = (disclosures, hash) => {
|
|
|
440
494
|
for (let i = 0; i < disclosures.length; i++) {
|
|
441
495
|
const disclosure = disclosures[i];
|
|
442
496
|
const digest = disclosure.digestSync(hash);
|
|
497
|
+
if (digest in map) {
|
|
498
|
+
throw new SDJWTException("Duplicate disclosure digest detected");
|
|
499
|
+
}
|
|
443
500
|
map[digest] = disclosure;
|
|
444
501
|
}
|
|
445
502
|
return map;
|
|
446
503
|
};
|
|
447
|
-
var getSDAlgAndPayload = (SdJwtPayload) => {
|
|
504
|
+
var getSDAlgAndPayload = (SdJwtPayload, allowedAlgorithms = DEFAULT_SECURE_HASH_ALGORITHMS) => {
|
|
448
505
|
const _a = SdJwtPayload, { _sd_alg } = _a, payload = __objRest(_a, ["_sd_alg"]);
|
|
449
|
-
if (
|
|
506
|
+
if (_sd_alg === void 0) {
|
|
450
507
|
return { _sd_alg: "sha-256", payload };
|
|
451
508
|
}
|
|
509
|
+
if (typeof _sd_alg !== "string") {
|
|
510
|
+
throw new SDJWTException("Invalid _sd_alg: expected string");
|
|
511
|
+
}
|
|
452
512
|
if (!IANA_HASH_ALGORITHMS.includes(
|
|
453
513
|
_sd_alg
|
|
454
514
|
)) {
|
|
455
515
|
throw new SDJWTException(`Invalid _sd_alg: ${_sd_alg}`);
|
|
456
516
|
}
|
|
517
|
+
if (!allowedAlgorithms.includes(_sd_alg)) {
|
|
518
|
+
throw new SDJWTException(`Disallowed _sd_alg: ${_sd_alg}`);
|
|
519
|
+
}
|
|
457
520
|
return { _sd_alg, payload };
|
|
458
521
|
};
|
|
459
522
|
var unpack = (SdJwtPayload, disclosures, hasher) => __async(null, null, function* () {
|
|
@@ -562,6 +625,14 @@ var GeneralJSON = class _GeneralJSON {
|
|
|
562
625
|
if (!json.signatures[0]) {
|
|
563
626
|
throw new SDJWTException("Invalid JSON");
|
|
564
627
|
}
|
|
628
|
+
for (let index = 1; index < json.signatures.length; index++) {
|
|
629
|
+
const header = json.signatures[index].header;
|
|
630
|
+
if (header && ("disclosures" in header || "kb_jwt" in header)) {
|
|
631
|
+
throw new SDJWTException(
|
|
632
|
+
"disclosures and kb_jwt MUST only appear in the first unprotected header"
|
|
633
|
+
);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
565
636
|
const disclosures = (_b = (_a = json.signatures[0].header) == null ? void 0 : _a.disclosures) != null ? _b : [];
|
|
566
637
|
const kb_jwt = (_c = json.signatures[0].header) == null ? void 0 : _c.kb_jwt;
|
|
567
638
|
return new _GeneralJSON({
|
|
@@ -634,6 +705,49 @@ var GeneralJSON = class _GeneralJSON {
|
|
|
634
705
|
};
|
|
635
706
|
|
|
636
707
|
// src/jwt.ts
|
|
708
|
+
var isStringArray = (value) => Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
709
|
+
var validateNumericDate = (payload, claim) => {
|
|
710
|
+
const value = payload[claim];
|
|
711
|
+
if (value === void 0) return void 0;
|
|
712
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
713
|
+
throw new SDJWTException(`Verify Error: JWT ${claim} must be a number`);
|
|
714
|
+
}
|
|
715
|
+
return value;
|
|
716
|
+
};
|
|
717
|
+
var getAudiences = (audience) => {
|
|
718
|
+
if (typeof audience === "string") return [audience];
|
|
719
|
+
if (isStringArray(audience)) return audience;
|
|
720
|
+
return void 0;
|
|
721
|
+
};
|
|
722
|
+
var validateAudience = (payload, expectedAudience) => {
|
|
723
|
+
if (expectedAudience === void 0) return;
|
|
724
|
+
const expectedAudiences = Array.isArray(expectedAudience) ? expectedAudience : [expectedAudience];
|
|
725
|
+
const audiences = getAudiences(payload.aud);
|
|
726
|
+
if (!audiences || !expectedAudiences.some((expected) => audiences.includes(expected))) {
|
|
727
|
+
throw new SDJWTException("Verify Error: Invalid audience");
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
var validateJwtPayload = (payload, options) => {
|
|
731
|
+
var _a;
|
|
732
|
+
if (!payload) {
|
|
733
|
+
throw new SDJWTException("Verify Error: JWT payload is missing");
|
|
734
|
+
}
|
|
735
|
+
const skew = (options == null ? void 0 : options.skewSeconds) ? options.skewSeconds : 0;
|
|
736
|
+
const currentDate = (_a = options == null ? void 0 : options.currentDate) != null ? _a : Math.floor(Date.now() / 1e3);
|
|
737
|
+
const iat = validateNumericDate(payload, "iat");
|
|
738
|
+
const nbf = validateNumericDate(payload, "nbf");
|
|
739
|
+
const exp = validateNumericDate(payload, "exp");
|
|
740
|
+
if (iat !== void 0 && iat - skew > currentDate) {
|
|
741
|
+
throw new SDJWTException("Verify Error: JWT is not yet valid");
|
|
742
|
+
}
|
|
743
|
+
if (nbf !== void 0 && nbf - skew > currentDate) {
|
|
744
|
+
throw new SDJWTException("Verify Error: JWT is not yet valid");
|
|
745
|
+
}
|
|
746
|
+
if (exp !== void 0 && exp + skew <= currentDate) {
|
|
747
|
+
throw new SDJWTException("Verify Error: JWT is expired");
|
|
748
|
+
}
|
|
749
|
+
validateAudience(payload, options == null ? void 0 : options.expectedAudience);
|
|
750
|
+
};
|
|
637
751
|
var Jwt = class _Jwt {
|
|
638
752
|
constructor(data) {
|
|
639
753
|
this.header = data == null ? void 0 : data.header;
|
|
@@ -684,6 +798,9 @@ var Jwt = class _Jwt {
|
|
|
684
798
|
}
|
|
685
799
|
sign(signer) {
|
|
686
800
|
return __async(this, null, function* () {
|
|
801
|
+
if (!this.header || this.header.alg === "none") {
|
|
802
|
+
throw new SDJWTException('Sign Error: alg "none" is not allowed');
|
|
803
|
+
}
|
|
687
804
|
const data = this.getUnsignedToken();
|
|
688
805
|
this.signature = yield signer(data);
|
|
689
806
|
return this.encodeJwt();
|
|
@@ -712,20 +829,16 @@ var Jwt = class _Jwt {
|
|
|
712
829
|
*/
|
|
713
830
|
verify(verifier, options) {
|
|
714
831
|
return __async(this, null, function* () {
|
|
715
|
-
var _a
|
|
716
|
-
const
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
const nbf = (_c = this.payload) == null ? void 0 : _c.nbf;
|
|
720
|
-
const exp = (_d = this.payload) == null ? void 0 : _d.exp;
|
|
721
|
-
if (typeof iat === "number" && iat - skew > currentDate) {
|
|
722
|
-
throw new SDJWTException("Verify Error: JWT is not yet valid");
|
|
832
|
+
var _a;
|
|
833
|
+
const alg = (_a = this.header) == null ? void 0 : _a.alg;
|
|
834
|
+
if (typeof alg !== "string" || alg === "none") {
|
|
835
|
+
throw new SDJWTException('Verify Error: alg "none" is not allowed');
|
|
723
836
|
}
|
|
724
|
-
if (
|
|
725
|
-
throw new SDJWTException(
|
|
837
|
+
if ((options == null ? void 0 : options.allowedIssuerAlgorithms) && !options.allowedIssuerAlgorithms.includes(alg)) {
|
|
838
|
+
throw new SDJWTException(`Verify Error: Disallowed alg ${alg}`);
|
|
726
839
|
}
|
|
727
|
-
if (
|
|
728
|
-
|
|
840
|
+
if (!(options == null ? void 0 : options.skipJwtClaimValidation)) {
|
|
841
|
+
validateJwtPayload(this.payload, options);
|
|
729
842
|
}
|
|
730
843
|
if (!this.signature) {
|
|
731
844
|
throw new SDJWTException("Verify Error: no signature in JWT");
|
|
@@ -746,16 +859,31 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
746
859
|
// the type unknown is not good, but we don't know at this point how to get the public key of the signer, this is defined in the kbVerifier
|
|
747
860
|
verifyKB(values) {
|
|
748
861
|
return __async(this, null, function* () {
|
|
862
|
+
var _a, _b, _c, _d;
|
|
749
863
|
if (!this.header || !this.payload || !this.signature) {
|
|
750
864
|
throw new SDJWTException("Verify Error: Invalid JWT");
|
|
751
865
|
}
|
|
752
|
-
if (
|
|
753
|
-
!(this.payload.sd_hash || "_sd_hash" in this.payload && this.payload._sd_hash)) {
|
|
866
|
+
if (typeof this.header.alg !== "string" || this.header.alg === "none" || typeof this.header.typ !== "string" || this.header.typ !== KB_JWT_TYP || typeof this.payload.iat !== "number" || typeof this.payload.aud !== "string" || typeof this.payload.nonce !== "string" || typeof this.payload.sd_hash !== "string" || this.payload.sd_hash.length === 0) {
|
|
754
867
|
throw new SDJWTException("Invalid Key Binding Jwt");
|
|
755
868
|
}
|
|
756
869
|
if (this.payload.nonce !== values.nonce) {
|
|
757
870
|
throw new SDJWTException("Verify Error: Invalid Nonce");
|
|
758
871
|
}
|
|
872
|
+
if (((_a = values.options) == null ? void 0 : _a.expectedKeyBindingAudience) !== void 0) {
|
|
873
|
+
const expectedAudiences = Array.isArray(
|
|
874
|
+
values.options.expectedKeyBindingAudience
|
|
875
|
+
) ? values.options.expectedKeyBindingAudience : [values.options.expectedKeyBindingAudience];
|
|
876
|
+
if (!expectedAudiences.includes(this.payload.aud)) {
|
|
877
|
+
throw new SDJWTException("Verify Error: Invalid Key Binding audience");
|
|
878
|
+
}
|
|
879
|
+
}
|
|
880
|
+
if (((_b = values.options) == null ? void 0 : _b.keyBindingMaxAgeSeconds) !== void 0) {
|
|
881
|
+
const currentDate = (_c = values.options.currentDate) != null ? _c : Math.floor(Date.now() / 1e3);
|
|
882
|
+
const skew = (_d = values.options.skewSeconds) != null ? _d : 0;
|
|
883
|
+
if (this.payload.iat + values.options.keyBindingMaxAgeSeconds + skew < currentDate) {
|
|
884
|
+
throw new SDJWTException("Verify Error: Key Binding JWT is too old");
|
|
885
|
+
}
|
|
886
|
+
}
|
|
759
887
|
yield this.verify(
|
|
760
888
|
(data, sig) => values.verifier(data, sig, values.payload),
|
|
761
889
|
values.options
|
|
@@ -831,16 +959,17 @@ var presentSync = (sdJwt, presentFrame, hasher) => {
|
|
|
831
959
|
kbJwt != null ? kbJwt : ""
|
|
832
960
|
].join(SD_SEPARATOR);
|
|
833
961
|
};
|
|
834
|
-
var transformPresentationFrame = (obj, prefix =
|
|
962
|
+
var transformPresentationFrame = (obj, prefix = []) => {
|
|
835
963
|
return Object.entries(obj).reduce((acc, [key, value]) => {
|
|
836
|
-
const newPrefix = prefix
|
|
964
|
+
const newPrefix = [...prefix, key];
|
|
965
|
+
const encodedPrefix = encodePath(newPrefix);
|
|
837
966
|
if (typeof value === "boolean") {
|
|
838
967
|
if (value) {
|
|
839
|
-
acc.push(
|
|
968
|
+
acc.push(encodedPrefix);
|
|
840
969
|
}
|
|
841
970
|
} else if (typeof value === "object" && value !== null) {
|
|
842
971
|
acc.push(
|
|
843
|
-
|
|
972
|
+
encodedPrefix,
|
|
844
973
|
...transformPresentationFrame(
|
|
845
974
|
value,
|
|
846
975
|
newPrefix
|
|
@@ -891,6 +1020,23 @@ var selectDisclosures = (payload, disclosures, presentationFrame) => {
|
|
|
891
1020
|
};
|
|
892
1021
|
|
|
893
1022
|
// src/sdjwt.ts
|
|
1023
|
+
var createDisclosureSalt = (saltGenerator, seenSalts) => __async(null, null, function* () {
|
|
1024
|
+
const salt = yield saltGenerator(16);
|
|
1025
|
+
if (typeof salt !== "string") {
|
|
1026
|
+
throw new SDJWTException("SaltGenerator must return a string");
|
|
1027
|
+
}
|
|
1028
|
+
if (seenSalts.has(salt)) {
|
|
1029
|
+
throw new SDJWTException("Duplicate disclosure salt detected");
|
|
1030
|
+
}
|
|
1031
|
+
seenSalts.add(salt);
|
|
1032
|
+
return salt;
|
|
1033
|
+
});
|
|
1034
|
+
var addDisclosureDigest = (digest, seenDigests) => {
|
|
1035
|
+
if (seenDigests.has(digest)) {
|
|
1036
|
+
throw new SDJWTException("Duplicate disclosure digest detected");
|
|
1037
|
+
}
|
|
1038
|
+
seenDigests.add(digest);
|
|
1039
|
+
};
|
|
894
1040
|
var SDJwt = class _SDJwt {
|
|
895
1041
|
constructor(data) {
|
|
896
1042
|
this.jwt = data == null ? void 0 : data.jwt;
|
|
@@ -900,16 +1046,13 @@ var SDJwt = class _SDJwt {
|
|
|
900
1046
|
static decodeSDJwt(sdjwt, hasher) {
|
|
901
1047
|
return __async(this, null, function* () {
|
|
902
1048
|
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
|
|
1049
|
+
if (encodedDisclosures.length === 0) {
|
|
1050
|
+
throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
|
|
1051
|
+
}
|
|
903
1052
|
const jwt = Jwt.fromEncode(encodedJwt);
|
|
904
1053
|
if (!jwt.payload) {
|
|
905
1054
|
throw new Error("Payload is undefined on the JWT. Invalid state reached");
|
|
906
1055
|
}
|
|
907
|
-
if (encodedDisclosures.length === 0) {
|
|
908
|
-
return {
|
|
909
|
-
jwt,
|
|
910
|
-
disclosures: []
|
|
911
|
-
};
|
|
912
|
-
}
|
|
913
1056
|
const encodedKeyBindingJwt = encodedDisclosures.pop();
|
|
914
1057
|
const kbJwt = encodedKeyBindingJwt ? KBJwt.fromKBEncode(encodedKeyBindingJwt) : void 0;
|
|
915
1058
|
const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
|
|
@@ -1023,7 +1166,8 @@ var listKeys = (obj, prefix = "") => {
|
|
|
1023
1166
|
const keys = [];
|
|
1024
1167
|
for (const key in obj) {
|
|
1025
1168
|
if (obj[key] === void 0) continue;
|
|
1026
|
-
const
|
|
1169
|
+
const escapedKey = encodePathSegment(key);
|
|
1170
|
+
const newKey = prefix ? `${prefix}.${escapedKey}` : escapedKey;
|
|
1027
1171
|
keys.push(newKey);
|
|
1028
1172
|
const value = obj[key];
|
|
1029
1173
|
if (value && typeof value === "object") {
|
|
@@ -1032,7 +1176,7 @@ var listKeys = (obj, prefix = "") => {
|
|
|
1032
1176
|
}
|
|
1033
1177
|
return keys;
|
|
1034
1178
|
};
|
|
1035
|
-
var pack = (
|
|
1179
|
+
var pack = (_0, _1, _2, _3, ..._4) => __async(null, [_0, _1, _2, _3, ..._4], function* (claims, disclosureFrame, hash, saltGenerator, seenSalts = /* @__PURE__ */ new Set(), seenDigests = /* @__PURE__ */ new Set()) {
|
|
1036
1180
|
var _a, _b;
|
|
1037
1181
|
if (!disclosureFrame) {
|
|
1038
1182
|
return {
|
|
@@ -1053,7 +1197,9 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
1053
1197
|
claims[idx],
|
|
1054
1198
|
disclosureFrame[idx],
|
|
1055
1199
|
hash,
|
|
1056
|
-
saltGenerator
|
|
1200
|
+
saltGenerator,
|
|
1201
|
+
seenSalts,
|
|
1202
|
+
seenDigests
|
|
1057
1203
|
);
|
|
1058
1204
|
recursivePackedClaims2[idx] = packed.packedClaims;
|
|
1059
1205
|
disclosures2.push(...packed.disclosures);
|
|
@@ -1062,9 +1208,10 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
1062
1208
|
for (let i = 0; i < claims.length; i++) {
|
|
1063
1209
|
const claim = recursivePackedClaims2[i] ? recursivePackedClaims2[i] : claims[i];
|
|
1064
1210
|
if (sd.includes(i)) {
|
|
1065
|
-
const salt = yield saltGenerator
|
|
1211
|
+
const salt = yield createDisclosureSalt(saltGenerator, seenSalts);
|
|
1066
1212
|
const disclosure = new Disclosure([salt, claim]);
|
|
1067
1213
|
const digest = yield disclosure.digest(hash);
|
|
1214
|
+
addDisclosureDigest(digest, seenDigests);
|
|
1068
1215
|
packedClaims2.push({ [SD_LIST_KEY]: digest });
|
|
1069
1216
|
disclosures2.push(disclosure);
|
|
1070
1217
|
} else {
|
|
@@ -1073,6 +1220,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
1073
1220
|
}
|
|
1074
1221
|
for (let j = 0; j < decoyCount; j++) {
|
|
1075
1222
|
const decoyDigest = yield createDecoy(hash, saltGenerator);
|
|
1223
|
+
addDisclosureDigest(decoyDigest, seenDigests);
|
|
1076
1224
|
packedClaims2.push({ [SD_LIST_KEY]: decoyDigest });
|
|
1077
1225
|
}
|
|
1078
1226
|
return { packedClaims: packedClaims2, disclosures: disclosures2 };
|
|
@@ -1087,7 +1235,9 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
1087
1235
|
claims[key],
|
|
1088
1236
|
disclosureFrame[key],
|
|
1089
1237
|
hash,
|
|
1090
|
-
saltGenerator
|
|
1238
|
+
saltGenerator,
|
|
1239
|
+
seenSalts,
|
|
1240
|
+
seenDigests
|
|
1091
1241
|
);
|
|
1092
1242
|
recursivePackedClaims[key] = packed.packedClaims;
|
|
1093
1243
|
disclosures.push(...packed.disclosures);
|
|
@@ -1097,9 +1247,10 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
1097
1247
|
for (const key in claims) {
|
|
1098
1248
|
const claim = recursivePackedClaims[key] ? recursivePackedClaims[key] : claims[key];
|
|
1099
1249
|
if (sd.includes(key)) {
|
|
1100
|
-
const salt = yield saltGenerator
|
|
1250
|
+
const salt = yield createDisclosureSalt(saltGenerator, seenSalts);
|
|
1101
1251
|
const disclosure = new Disclosure([salt, key, claim]);
|
|
1102
1252
|
const digest = yield disclosure.digest(hash);
|
|
1253
|
+
addDisclosureDigest(digest, seenDigests);
|
|
1103
1254
|
_sd.push(digest);
|
|
1104
1255
|
disclosures.push(disclosure);
|
|
1105
1256
|
} else {
|
|
@@ -1108,6 +1259,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(null, null,
|
|
|
1108
1259
|
}
|
|
1109
1260
|
for (let j = 0; j < decoyCount; j++) {
|
|
1110
1261
|
const decoyDigest = yield createDecoy(hash, saltGenerator);
|
|
1262
|
+
addDisclosureDigest(decoyDigest, seenDigests);
|
|
1111
1263
|
_sd.push(decoyDigest);
|
|
1112
1264
|
}
|
|
1113
1265
|
if (_sd.length > 0) {
|
|
@@ -1137,12 +1289,19 @@ function validateReservedFieldsInternal(payload) {
|
|
|
1137
1289
|
var _SDJwtInstance = class _SDJwtInstance {
|
|
1138
1290
|
constructor(userConfig) {
|
|
1139
1291
|
this.userConfig = {};
|
|
1292
|
+
var _a;
|
|
1140
1293
|
if (userConfig) {
|
|
1141
1294
|
if (userConfig.hashAlg && !IANA_HASH_ALGORITHMS.includes(userConfig.hashAlg)) {
|
|
1142
1295
|
throw new SDJWTException(
|
|
1143
1296
|
`Invalid hash algorithm: ${userConfig.hashAlg}`
|
|
1144
1297
|
);
|
|
1145
1298
|
}
|
|
1299
|
+
const allowedDisclosureHashAlgorithms = (_a = userConfig.allowedDisclosureHashAlgorithms) != null ? _a : DEFAULT_SECURE_HASH_ALGORITHMS;
|
|
1300
|
+
if (userConfig.hashAlg && !allowedDisclosureHashAlgorithms.includes(userConfig.hashAlg)) {
|
|
1301
|
+
throw new SDJWTException(
|
|
1302
|
+
`Disallowed hash algorithm: ${userConfig.hashAlg}`
|
|
1303
|
+
);
|
|
1304
|
+
}
|
|
1146
1305
|
this.userConfig = userConfig;
|
|
1147
1306
|
}
|
|
1148
1307
|
}
|
|
@@ -1185,7 +1344,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1185
1344
|
}
|
|
1186
1345
|
issue(payload, disclosureFrame, options) {
|
|
1187
1346
|
return __async(this, null, function* () {
|
|
1188
|
-
var _a, _b;
|
|
1347
|
+
var _a, _b, _c;
|
|
1189
1348
|
if (!this.userConfig.hasher) {
|
|
1190
1349
|
throw new SDJWTException("Hasher not found");
|
|
1191
1350
|
}
|
|
@@ -1195,10 +1354,17 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1195
1354
|
if (!this.userConfig.signAlg) {
|
|
1196
1355
|
throw new SDJWTException("sign alogrithm not specified");
|
|
1197
1356
|
}
|
|
1357
|
+
if (this.userConfig.signAlg === "none") {
|
|
1358
|
+
throw new SDJWTException('sign algorithm "none" is not allowed');
|
|
1359
|
+
}
|
|
1198
1360
|
this.validateReservedFields(payload);
|
|
1199
1361
|
this.validateDisclosureFrame(disclosureFrame);
|
|
1200
1362
|
const hasher = this.userConfig.hasher;
|
|
1201
1363
|
const hashAlg = (_a = this.userConfig.hashAlg) != null ? _a : _SDJwtInstance.DEFAULT_hashAlg;
|
|
1364
|
+
const allowedDisclosureHashAlgorithms = (_b = this.userConfig.allowedDisclosureHashAlgorithms) != null ? _b : DEFAULT_SECURE_HASH_ALGORITHMS;
|
|
1365
|
+
if (!allowedDisclosureHashAlgorithms.includes(hashAlg)) {
|
|
1366
|
+
throw new SDJWTException(`Disallowed hash algorithm: ${hashAlg}`);
|
|
1367
|
+
}
|
|
1202
1368
|
const { packedClaims, disclosures } = yield pack(
|
|
1203
1369
|
payload,
|
|
1204
1370
|
disclosureFrame,
|
|
@@ -1206,7 +1372,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1206
1372
|
this.userConfig.saltGenerator
|
|
1207
1373
|
);
|
|
1208
1374
|
const alg = this.userConfig.signAlg;
|
|
1209
|
-
const OptionHeader = (
|
|
1375
|
+
const OptionHeader = (_c = options == null ? void 0 : options.header) != null ? _c : {};
|
|
1210
1376
|
const CustomHeader = this.userConfig.omitTyp ? OptionHeader : __spreadValues({ typ: this.type }, OptionHeader);
|
|
1211
1377
|
const header = __spreadProps(__spreadValues({}, CustomHeader), { alg });
|
|
1212
1378
|
const jwt = new Jwt({
|
|
@@ -1242,6 +1408,9 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1242
1408
|
}
|
|
1243
1409
|
const hasher = this.userConfig.hasher;
|
|
1244
1410
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1411
|
+
if (sdjwt.kbJwt) {
|
|
1412
|
+
throw new SDJWTException("Holder cannot present an SD-JWT with KB-JWT");
|
|
1413
|
+
}
|
|
1245
1414
|
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new SDJWTException("Payload not found");
|
|
1246
1415
|
const presentSdJwtWithoutKb = yield sdjwt.present(
|
|
1247
1416
|
presentationFrame,
|
|
@@ -1384,10 +1553,13 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1384
1553
|
}
|
|
1385
1554
|
if (sdjwt == null ? void 0 : sdjwt.jwt) {
|
|
1386
1555
|
try {
|
|
1387
|
-
const result = yield this.VerifyJwt(sdjwt.jwt, options)
|
|
1556
|
+
const result = yield this.VerifyJwt(sdjwt.jwt, __spreadProps(__spreadValues({}, options), {
|
|
1557
|
+
skipJwtClaimValidation: true
|
|
1558
|
+
}));
|
|
1388
1559
|
header = result.header;
|
|
1389
1560
|
const claims = yield sdjwt.getClaims(hasher);
|
|
1390
1561
|
payload = claims;
|
|
1562
|
+
validateJwtPayload(payload, options);
|
|
1391
1563
|
} catch (e) {
|
|
1392
1564
|
const error = ensureError(e);
|
|
1393
1565
|
const code = exceptionToCode(error);
|
|
@@ -1513,9 +1685,12 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
1513
1685
|
if (!sdjwt.jwt) {
|
|
1514
1686
|
throw new SDJWTException("Invalid SD JWT");
|
|
1515
1687
|
}
|
|
1516
|
-
const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, options)
|
|
1688
|
+
const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, __spreadProps(__spreadValues({}, options), {
|
|
1689
|
+
skipJwtClaimValidation: true
|
|
1690
|
+
}));
|
|
1517
1691
|
const claims = yield sdjwt.getClaims(hasher);
|
|
1518
1692
|
validateReservedFieldsInternal(claims);
|
|
1693
|
+
validateJwtPayload(claims, options);
|
|
1519
1694
|
return { payload: claims, header: verifiedPayloads.header };
|
|
1520
1695
|
});
|
|
1521
1696
|
}
|
|
@@ -1570,12 +1745,19 @@ var SDJwtInstance = _SDJwtInstance;
|
|
|
1570
1745
|
var SDJwtGeneralJSONInstance = class {
|
|
1571
1746
|
constructor(userConfig) {
|
|
1572
1747
|
this.userConfig = {};
|
|
1748
|
+
var _a;
|
|
1573
1749
|
if (userConfig) {
|
|
1574
1750
|
if (userConfig.hashAlg && !IANA_HASH_ALGORITHMS.includes(userConfig.hashAlg)) {
|
|
1575
1751
|
throw new SDJWTException(
|
|
1576
1752
|
`Invalid hash algorithm: ${userConfig.hashAlg}`
|
|
1577
1753
|
);
|
|
1578
1754
|
}
|
|
1755
|
+
const allowedDisclosureHashAlgorithms = (_a = userConfig.allowedDisclosureHashAlgorithms) != null ? _a : DEFAULT_SECURE_HASH_ALGORITHMS;
|
|
1756
|
+
if (userConfig.hashAlg && !allowedDisclosureHashAlgorithms.includes(userConfig.hashAlg)) {
|
|
1757
|
+
throw new SDJWTException(
|
|
1758
|
+
`Disallowed hash algorithm: ${userConfig.hashAlg}`
|
|
1759
|
+
);
|
|
1760
|
+
}
|
|
1579
1761
|
this.userConfig = userConfig;
|
|
1580
1762
|
}
|
|
1581
1763
|
}
|
|
@@ -1669,6 +1851,9 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1669
1851
|
const hasher = this.userConfig.hasher;
|
|
1670
1852
|
const encodedSDJwt = generalJSON.toEncoded(0);
|
|
1671
1853
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1854
|
+
if (sdjwt.kbJwt) {
|
|
1855
|
+
throw new SDJWTException("Holder cannot present an SD-JWT with KB-JWT");
|
|
1856
|
+
}
|
|
1672
1857
|
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new SDJWTException("Payload not found");
|
|
1673
1858
|
const disclosures = yield sdjwt.getPresentDisclosures(
|
|
1674
1859
|
presentationFrame,
|
|
@@ -1708,7 +1893,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1708
1893
|
throw new SDJWTException("Hasher not found");
|
|
1709
1894
|
}
|
|
1710
1895
|
const hasher = this.userConfig.hasher;
|
|
1711
|
-
const { payload, headers } = yield this.validate(generalJSON);
|
|
1896
|
+
const { payload, headers } = yield this.validate(generalJSON, options);
|
|
1712
1897
|
const encodedSDJwt = generalJSON.toEncoded(0);
|
|
1713
1898
|
const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
|
|
1714
1899
|
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) {
|
|
@@ -1774,7 +1959,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1774
1959
|
}
|
|
1775
1960
|
// This function is for validating the SD JWT
|
|
1776
1961
|
// Just checking signature and return its the claims
|
|
1777
|
-
validate(generalJSON) {
|
|
1962
|
+
validate(generalJSON, options) {
|
|
1778
1963
|
return __async(this, null, function* () {
|
|
1779
1964
|
if (!this.userConfig.hasher) {
|
|
1780
1965
|
throw new SDJWTException("Hasher not found");
|
|
@@ -1790,9 +1975,21 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1790
1975
|
const { protected: encodedHeader, signature } = s;
|
|
1791
1976
|
const verified2 = yield verifier(
|
|
1792
1977
|
`${encodedHeader}.${payload}`,
|
|
1793
|
-
signature
|
|
1978
|
+
signature,
|
|
1979
|
+
__spreadProps(__spreadValues({}, options), { skipJwtClaimValidation: true })
|
|
1980
|
+
);
|
|
1981
|
+
const header = decodeBase64urlJsonStrict(
|
|
1982
|
+
encodedHeader,
|
|
1983
|
+
"Invalid JWT"
|
|
1794
1984
|
);
|
|
1795
|
-
|
|
1985
|
+
if (typeof header.alg !== "string" || header.alg === "none") {
|
|
1986
|
+
throw new SDJWTException('Verify Error: alg "none" is not allowed');
|
|
1987
|
+
}
|
|
1988
|
+
if ((options == null ? void 0 : options.allowedIssuerAlgorithms) && !options.allowedIssuerAlgorithms.includes(header.alg)) {
|
|
1989
|
+
throw new SDJWTException(
|
|
1990
|
+
`Verify Error: Disallowed alg ${header.alg}`
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1796
1993
|
return { verified: verified2, header };
|
|
1797
1994
|
}))
|
|
1798
1995
|
);
|
|
@@ -1807,6 +2004,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1807
2004
|
}
|
|
1808
2005
|
const claims = yield sdjwt.getClaims(hasher);
|
|
1809
2006
|
validateReservedFieldsInternal(claims);
|
|
2007
|
+
validateJwtPayload(claims, options);
|
|
1810
2008
|
return { payload: claims, headers: results.map((r) => r.header) };
|
|
1811
2009
|
});
|
|
1812
2010
|
}
|
|
@@ -1853,6 +2051,7 @@ var SDJwtGeneralJSONInstance = class {
|
|
|
1853
2051
|
SDJwtGeneralJSONInstance.DEFAULT_hashAlg = "sha-256";
|
|
1854
2052
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1855
2053
|
0 && (module.exports = {
|
|
2054
|
+
DEFAULT_SECURE_HASH_ALGORITHMS,
|
|
1856
2055
|
Disclosure,
|
|
1857
2056
|
FlattenJSON,
|
|
1858
2057
|
GeneralJSON,
|
|
@@ -1878,6 +2077,8 @@ SDJwtGeneralJSONInstance.DEFAULT_hashAlg = "sha-256";
|
|
|
1878
2077
|
decodeJwt,
|
|
1879
2078
|
decodeSdJwt,
|
|
1880
2079
|
decodeSdJwtSync,
|
|
2080
|
+
encodePath,
|
|
2081
|
+
encodePathSegment,
|
|
1881
2082
|
ensureError,
|
|
1882
2083
|
getClaims,
|
|
1883
2084
|
getClaimsSync,
|
|
@@ -1894,5 +2095,6 @@ SDJwtGeneralJSONInstance.DEFAULT_hashAlg = "sha-256";
|
|
|
1894
2095
|
uint8ArrayToBase64Url,
|
|
1895
2096
|
unpack,
|
|
1896
2097
|
unpackObj,
|
|
1897
|
-
unpackSync
|
|
2098
|
+
unpackSync,
|
|
2099
|
+
validateJwtPayload
|
|
1898
2100
|
});
|