@sd-jwt/core 0.20.1 → 0.21.0-alpha-20260916100413

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 (68) hide show
  1. package/LICENSE +2 -2
  2. package/README.md +82 -80
  3. package/dist/index.cjs +1526 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +696 -0
  6. package/dist/index.d.mts +537 -527
  7. package/dist/index.mjs +1422 -1998
  8. package/dist/index.mjs.map +1 -0
  9. package/package.json +29 -49
  10. package/CHANGELOG.md +0 -39
  11. package/dist/index.d.ts +0 -686
  12. package/dist/index.js +0 -2100
  13. package/src/decode/decode.ts +0 -407
  14. package/src/decode/index.ts +0 -1
  15. package/src/decoy.ts +0 -15
  16. package/src/flattenJSON.ts +0 -99
  17. package/src/generalJSON.ts +0 -157
  18. package/src/index.ts +0 -1000
  19. package/src/jwt.ts +0 -286
  20. package/src/kbjwt.ts +0 -101
  21. package/src/present/index.ts +0 -1
  22. package/src/present/present.ts +0 -216
  23. package/src/sdjwt.ts +0 -384
  24. package/src/test/decode/decode.spec.ts +0 -197
  25. package/src/test/decoy.spec.ts +0 -30
  26. package/src/test/flattenJSON.spec.ts +0 -122
  27. package/src/test/generalJSON.spec.ts +0 -198
  28. package/src/test/index.spec.ts +0 -986
  29. package/src/test/jwt.spec.ts +0 -301
  30. package/src/test/kbjwt.spec.ts +0 -555
  31. package/src/test/pass.spec.ts +0 -7
  32. package/src/test/present/present.spec.ts +0 -305
  33. package/src/test/sdjwt.spec.ts +0 -384
  34. package/src/test/types/type.spec.ts +0 -88
  35. package/src/test/utils/base64url.spec.ts +0 -33
  36. package/src/test/utils/disclosure.spec.ts +0 -170
  37. package/src/test/utils/error.spec.ts +0 -15
  38. package/src/types/index.ts +0 -2
  39. package/src/types/type.ts +0 -270
  40. package/src/types/verification-error.ts +0 -55
  41. package/src/utils/base64url.ts +0 -6
  42. package/src/utils/disclosure.ts +0 -121
  43. package/src/utils/error.ts +0 -25
  44. package/src/utils/index.ts +0 -3
  45. package/src/utils/strict-json.ts +0 -17
  46. package/test/app-e2e.spec.ts +0 -292
  47. package/test/array_data_types.json +0 -31
  48. package/test/array_full_sd.json +0 -21
  49. package/test/array_in_sd.json +0 -13
  50. package/test/array_nested_in_plain.json +0 -29
  51. package/test/array_none_disclosed.json +0 -17
  52. package/test/array_of_nulls.json +0 -15
  53. package/test/array_of_objects.json +0 -65
  54. package/test/array_of_scalars.json +0 -19
  55. package/test/array_recursive_sd.json +0 -35
  56. package/test/array_recursive_sd_some_disclosed.json +0 -63
  57. package/test/complex.json +0 -43
  58. package/test/header_mod.json +0 -48
  59. package/test/json_serialization.json +0 -48
  60. package/test/key_binding.json +0 -48
  61. package/test/no_sd.json +0 -36
  62. package/test/object_data_types.json +0 -62
  63. package/test/recursions.json +0 -117
  64. package/test/rfc9901-audit-fixes.spec.ts +0 -252
  65. package/test/rfc9901-validation.spec.ts +0 -150
  66. package/test/tsconfig.json +0 -4
  67. package/tsconfig.json +0 -7
  68. package/vitest.config.mts +0 -4
package/dist/index.js DELETED
@@ -1,2100 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __defProps = Object.defineProperties;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
- var __objRest = (source, exclude) => {
24
- var target = {};
25
- for (var prop in source)
26
- if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
27
- target[prop] = source[prop];
28
- if (source != null && __getOwnPropSymbols)
29
- for (var prop of __getOwnPropSymbols(source)) {
30
- if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
31
- target[prop] = source[prop];
32
- }
33
- return target;
34
- };
35
- var __export = (target, all) => {
36
- for (var name in all)
37
- __defProp(target, name, { get: all[name], enumerable: true });
38
- };
39
- var __copyProps = (to, from, except, desc) => {
40
- if (from && typeof from === "object" || typeof from === "function") {
41
- for (let key of __getOwnPropNames(from))
42
- if (!__hasOwnProp.call(to, key) && key !== except)
43
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
44
- }
45
- return to;
46
- };
47
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
48
- var __async = (__this, __arguments, generator) => {
49
- return new Promise((resolve, reject) => {
50
- var fulfilled = (value) => {
51
- try {
52
- step(generator.next(value));
53
- } catch (e) {
54
- reject(e);
55
- }
56
- };
57
- var rejected = (value) => {
58
- try {
59
- step(generator.throw(value));
60
- } catch (e) {
61
- reject(e);
62
- }
63
- };
64
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
65
- step((generator = generator.apply(__this, __arguments)).next());
66
- });
67
- };
68
-
69
- // src/index.ts
70
- var index_exports = {};
71
- __export(index_exports, {
72
- DEFAULT_SECURE_HASH_ALGORITHMS: () => DEFAULT_SECURE_HASH_ALGORITHMS,
73
- Disclosure: () => Disclosure,
74
- FlattenJSON: () => FlattenJSON,
75
- GeneralJSON: () => GeneralJSON,
76
- IANA_HASH_ALGORITHMS: () => IANA_HASH_ALGORITHMS,
77
- Jwt: () => Jwt,
78
- KBJwt: () => KBJwt,
79
- KB_JWT_TYP: () => KB_JWT_TYP,
80
- SDJWTException: () => SDJWTException,
81
- SDJwt: () => SDJwt,
82
- SDJwtGeneralJSONInstance: () => SDJwtGeneralJSONInstance,
83
- SDJwtInstance: () => SDJwtInstance,
84
- SD_DECOY: () => SD_DECOY,
85
- SD_DIGEST: () => SD_DIGEST,
86
- SD_LIST_KEY: () => SD_LIST_KEY,
87
- SD_SEPARATOR: () => SD_SEPARATOR,
88
- base64UrlToUint8Array: () => import_identity_common.base64UrlToUint8Array,
89
- base64urlDecode: () => import_identity_common.base64urlDecode,
90
- base64urlEncode: () => import_identity_common.base64urlEncode,
91
- createDecoy: () => createDecoy,
92
- createHashMapping: () => createHashMapping,
93
- createHashMappingForSerializedDisclosure: () => createHashMappingForSerializedDisclosure,
94
- createHashMappingSync: () => createHashMappingSync,
95
- decodeJwt: () => decodeJwt,
96
- decodeSdJwt: () => decodeSdJwt,
97
- decodeSdJwtSync: () => decodeSdJwtSync,
98
- encodePath: () => encodePath,
99
- encodePathSegment: () => encodePathSegment,
100
- ensureError: () => ensureError,
101
- getClaims: () => getClaims,
102
- getClaimsSync: () => getClaimsSync,
103
- getSDAlgAndPayload: () => getSDAlgAndPayload,
104
- listKeys: () => listKeys,
105
- pack: () => pack,
106
- present: () => present,
107
- presentSync: () => presentSync,
108
- presentableKeys: () => presentableKeys,
109
- presentableKeysSync: () => presentableKeysSync,
110
- selectDisclosures: () => selectDisclosures,
111
- splitSdJwt: () => splitSdJwt,
112
- transformPresentationFrame: () => transformPresentationFrame,
113
- uint8ArrayToBase64Url: () => import_identity_common.uint8ArrayToBase64Url,
114
- unpack: () => unpack,
115
- unpackObj: () => unpackObj,
116
- unpackSync: () => unpackSync,
117
- validateJwtPayload: () => validateJwtPayload
118
- });
119
- module.exports = __toCommonJS(index_exports);
120
-
121
- // src/types/type.ts
122
- var SD_SEPARATOR = "~";
123
- var SD_LIST_KEY = "...";
124
- var SD_DIGEST = "_sd";
125
- var SD_DECOY = "_sd_decoy";
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(".");
129
- var IANA_HASH_ALGORITHMS = [
130
- "sha-256",
131
- "sha-256-128",
132
- "sha-256-120",
133
- "sha-256-96",
134
- "sha-256-64",
135
- "sha-256-32",
136
- "sha-384",
137
- "sha-512",
138
- "sha3-224",
139
- "sha3-256",
140
- "sha3-384",
141
- "sha3-512",
142
- "blake2s-256",
143
- "blake2b-256",
144
- "blake2b-512",
145
- "k12-256",
146
- "k12-512"
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
- ];
161
-
162
- // src/utils/base64url.ts
163
- var import_identity_common = require("@owf/identity-common");
164
-
165
- // src/utils/error.ts
166
- var SDJWTException = class _SDJWTException extends Error {
167
- constructor(message, details) {
168
- super(message);
169
- Object.setPrototypeOf(this, _SDJWTException.prototype);
170
- this.name = "SDJWTException";
171
- this.details = details;
172
- }
173
- getFullMessage() {
174
- return `${this.name}: ${this.message} ${this.details ? `- ${JSON.stringify(this.details)}` : ""}`;
175
- }
176
- };
177
- function ensureError(value) {
178
- if (value instanceof Error) return value;
179
- if (typeof value === "string") return new Error(value);
180
- return new Error(String(value));
181
- }
182
-
183
- // src/utils/strict-json.ts
184
- var utf8Decoder = new TextDecoder("utf-8", { fatal: true });
185
- var decodeBase64urlJsonStrict = (encoded, errorMessage) => {
186
- try {
187
- const bytes = (0, import_identity_common.base64UrlToUint8Array)(encoded);
188
- const decoded = utf8Decoder.decode(bytes);
189
- return JSON.parse(decoded);
190
- } catch (e) {
191
- throw new SDJWTException(errorMessage);
192
- }
193
- };
194
-
195
- // src/utils/disclosure.ts
196
- var Disclosure = class _Disclosure {
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
- }
204
- this._digest = _meta == null ? void 0 : _meta.digest;
205
- this._encoded = _meta == null ? void 0 : _meta.encoded;
206
- if (data.length === 2) {
207
- this.salt = data[0];
208
- this.value = data[1];
209
- return;
210
- }
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
- }
220
- this.salt = data[0];
221
- this.key = data[1];
222
- this.value = data[2];
223
- return;
224
- }
225
- }
226
- // We need to digest of the original encoded data.
227
- // After decode process, we use JSON.stringify to encode the data.
228
- // This can be different from the original encoded data.
229
- static fromEncode(s, hash) {
230
- return __async(this, null, function* () {
231
- const { hasher, alg } = hash;
232
- const digest = yield hasher(s, alg);
233
- const digestStr = (0, import_identity_common.uint8ArrayToBase64Url)(digest);
234
- const item = decodeBase64urlJsonStrict(
235
- s,
236
- "Invalid disclosure data"
237
- );
238
- return _Disclosure.fromArray(item, { digest: digestStr, encoded: s });
239
- });
240
- }
241
- static fromEncodeSync(s, hash) {
242
- const { hasher, alg } = hash;
243
- const digest = hasher(s, alg);
244
- const digestStr = (0, import_identity_common.uint8ArrayToBase64Url)(digest);
245
- const item = decodeBase64urlJsonStrict(
246
- s,
247
- "Invalid disclosure data"
248
- );
249
- return _Disclosure.fromArray(item, { digest: digestStr, encoded: s });
250
- }
251
- static fromArray(item, _meta) {
252
- return new _Disclosure(item, _meta);
253
- }
254
- encode() {
255
- if (!this._encoded) {
256
- this._encoded = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.decode()));
257
- }
258
- return this._encoded;
259
- }
260
- decode() {
261
- return this.key ? [this.salt, this.key, this.value] : [this.salt, this.value];
262
- }
263
- digest(hash) {
264
- return __async(this, null, function* () {
265
- const { hasher, alg } = hash;
266
- if (!this._digest) {
267
- const hash2 = yield hasher(this.encode(), alg);
268
- this._digest = (0, import_identity_common.uint8ArrayToBase64Url)(hash2);
269
- }
270
- return this._digest;
271
- });
272
- }
273
- digestSync(hash) {
274
- const { hasher, alg } = hash;
275
- if (!this._digest) {
276
- const hash2 = hasher(this.encode(), alg);
277
- this._digest = (0, import_identity_common.uint8ArrayToBase64Url)(hash2);
278
- }
279
- return this._digest;
280
- }
281
- };
282
-
283
- // src/decode/decode.ts
284
- var decodeJwt = (jwt) => {
285
- const { 0: header, 1: payload, 2: signature, length } = jwt.split(".");
286
- if (length !== 3) {
287
- throw new SDJWTException("Invalid JWT as input");
288
- }
289
- return {
290
- header: decodeBase64urlJsonStrict(header, "Invalid JWT as input"),
291
- payload: decodeBase64urlJsonStrict(payload, "Invalid JWT as input"),
292
- signature
293
- };
294
- };
295
- var splitSdJwt = (sdjwt) => {
296
- const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
297
- if (encodedDisclosures.length === 0) {
298
- throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
299
- }
300
- const encodedKeyBindingJwt = encodedDisclosures.pop();
301
- return {
302
- jwt: encodedJwt,
303
- disclosures: encodedDisclosures,
304
- kbJwt: encodedKeyBindingJwt || void 0
305
- };
306
- };
307
- var decodeSdJwt = (sdjwt, hasher) => __async(null, null, function* () {
308
- const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
309
- const jwt = decodeJwt(encodedJwt);
310
- if (encodedDisclosures.length === 0) {
311
- throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
312
- }
313
- const encodedKeyBindingJwt = encodedDisclosures.pop();
314
- const kbJwt = encodedKeyBindingJwt ? decodeJwt(encodedKeyBindingJwt) : void 0;
315
- const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
316
- const disclosures = yield Promise.all(
317
- encodedDisclosures.map(
318
- (ed) => Disclosure.fromEncode(ed, { alg: _sd_alg, hasher })
319
- )
320
- );
321
- return {
322
- jwt,
323
- disclosures,
324
- kbJwt
325
- };
326
- });
327
- var decodeSdJwtSync = (sdjwt, hasher) => {
328
- const [encodedJwt, ...encodedDisclosures] = sdjwt.split(SD_SEPARATOR);
329
- const jwt = decodeJwt(encodedJwt);
330
- if (encodedDisclosures.length === 0) {
331
- throw new SDJWTException("Invalid SD-JWT: missing SD-JWT separator");
332
- }
333
- const encodedKeyBindingJwt = encodedDisclosures.pop();
334
- const kbJwt = encodedKeyBindingJwt ? decodeJwt(encodedKeyBindingJwt) : void 0;
335
- const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
336
- const disclosures = encodedDisclosures.map(
337
- (ed) => Disclosure.fromEncodeSync(ed, { alg: _sd_alg, hasher })
338
- );
339
- return {
340
- jwt,
341
- disclosures,
342
- kbJwt
343
- };
344
- };
345
- var getClaims = (rawPayload, disclosures, hasher) => __async(null, null, function* () {
346
- const { unpackedObj } = yield unpack(rawPayload, disclosures, hasher);
347
- return unpackedObj;
348
- });
349
- var getClaimsSync = (rawPayload, disclosures, hasher) => {
350
- const { unpackedObj } = unpackSync(rawPayload, disclosures, hasher);
351
- return unpackedObj;
352
- };
353
- var isRecord = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
354
- var unpackArray = (arr, map, prefix = "", seenDigests) => {
355
- const keys = {};
356
- const unpackedArray = [];
357
- arr.forEach((item, idx) => {
358
- if (isRecord(item)) {
359
- const hash = item[SD_LIST_KEY];
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
- }
364
- if (seenDigests) {
365
- if (seenDigests.has(hash)) {
366
- throw new SDJWTException(
367
- "Duplicate digest found in SD-JWT payload"
368
- );
369
- }
370
- seenDigests.add(hash);
371
- }
372
- const disclosed = map[hash];
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
- }
379
- const presentKey = prefix ? `${prefix}.${idx}` : `${idx}`;
380
- keys[presentKey] = hash;
381
- const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(disclosed.value, map, presentKey, seenDigests);
382
- unpackedArray.push(unpackedObj);
383
- Object.assign(keys, disclosureKeys);
384
- }
385
- } else {
386
- const newKey = prefix ? `${prefix}.${idx}` : `${idx}`;
387
- const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(item, map, newKey, seenDigests);
388
- unpackedArray.push(unpackedObj);
389
- Object.assign(keys, disclosureKeys);
390
- }
391
- } else if (Array.isArray(item)) {
392
- const newKey = prefix ? `${prefix}.${idx}` : `${idx}`;
393
- const { unpackedObj, disclosureKeymap: disclosureKeys } = unpackObjInternal(item, map, newKey, seenDigests);
394
- unpackedArray.push(unpackedObj);
395
- Object.assign(keys, disclosureKeys);
396
- } else {
397
- unpackedArray.push(item);
398
- }
399
- });
400
- return { unpackedObj: unpackedArray, disclosureKeymap: keys };
401
- };
402
- var unpackObj = (obj, map) => {
403
- const copiedObj = JSON.parse(JSON.stringify(obj));
404
- const seenDigests = /* @__PURE__ */ new Set();
405
- const result = unpackObjInternal(copiedObj, map, "", seenDigests);
406
- const mapDigests = Object.keys(map);
407
- const unusedDigests = mapDigests.filter((d) => !seenDigests.has(d));
408
- if (unusedDigests.length > 0) {
409
- throw new SDJWTException("Unreferenced disclosure(s) detected in SD-JWT");
410
- }
411
- return result;
412
- };
413
- var unpackObjInternal = (obj, map, prefix = "", seenDigests) => {
414
- const keys = {};
415
- if (typeof obj === "object" && obj !== null) {
416
- if (Array.isArray(obj)) {
417
- return unpackArray(obj, map, prefix, seenDigests);
418
- }
419
- const record = obj;
420
- for (const key in record) {
421
- if (prefix && key === "_sd_alg") {
422
- throw new SDJWTException("Nested _sd_alg is not allowed");
423
- }
424
- if (key !== SD_DIGEST && key !== SD_LIST_KEY && typeof record[key] === "object") {
425
- const escapedKey = encodePathSegment(key);
426
- const newKey = prefix ? `${prefix}.${escapedKey}` : escapedKey;
427
- const { unpackedObj: unpackedObj2, disclosureKeymap: disclosureKeys } = unpackObjInternal(record[key], map, newKey, seenDigests);
428
- record[key] = unpackedObj2;
429
- Object.assign(keys, disclosureKeys);
430
- }
431
- }
432
- const _a = record, { _sd } = _a, payload = __objRest(_a, ["_sd"]);
433
- const claims = {};
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
- }
440
- for (const hash of _sd) {
441
- if (seenDigests) {
442
- if (seenDigests.has(hash)) {
443
- throw new SDJWTException(
444
- "Duplicate digest found in SD-JWT payload"
445
- );
446
- }
447
- seenDigests.add(hash);
448
- }
449
- const disclosed = map[hash];
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
- }
456
- if (disclosed.key in payload) {
457
- throw new SDJWTException(
458
- `Disclosed claim name "${disclosed.key}" conflicts with existing payload key`
459
- );
460
- }
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;
468
- keys[presentKey] = hash;
469
- const { unpackedObj: unpackedObj2, disclosureKeymap: disclosureKeys } = unpackObjInternal(disclosed.value, map, presentKey, seenDigests);
470
- claims[disclosed.key] = unpackedObj2;
471
- Object.assign(keys, disclosureKeys);
472
- }
473
- }
474
- }
475
- const unpackedObj = Object.assign(payload, claims);
476
- return { unpackedObj, disclosureKeymap: keys };
477
- }
478
- return { unpackedObj: obj, disclosureKeymap: keys };
479
- };
480
- var createHashMapping = (disclosures, hash) => __async(null, null, function* () {
481
- const map = {};
482
- for (let i = 0; i < disclosures.length; i++) {
483
- const disclosure = disclosures[i];
484
- const digest = yield disclosure.digest(hash);
485
- if (digest in map) {
486
- throw new SDJWTException("Duplicate disclosure digest detected");
487
- }
488
- map[digest] = disclosure;
489
- }
490
- return map;
491
- });
492
- var createHashMappingSync = (disclosures, hash) => {
493
- const map = {};
494
- for (let i = 0; i < disclosures.length; i++) {
495
- const disclosure = disclosures[i];
496
- const digest = disclosure.digestSync(hash);
497
- if (digest in map) {
498
- throw new SDJWTException("Duplicate disclosure digest detected");
499
- }
500
- map[digest] = disclosure;
501
- }
502
- return map;
503
- };
504
- var getSDAlgAndPayload = (SdJwtPayload, allowedAlgorithms = DEFAULT_SECURE_HASH_ALGORITHMS) => {
505
- const _a = SdJwtPayload, { _sd_alg } = _a, payload = __objRest(_a, ["_sd_alg"]);
506
- if (_sd_alg === void 0) {
507
- return { _sd_alg: "sha-256", payload };
508
- }
509
- if (typeof _sd_alg !== "string") {
510
- throw new SDJWTException("Invalid _sd_alg: expected string");
511
- }
512
- if (!IANA_HASH_ALGORITHMS.includes(
513
- _sd_alg
514
- )) {
515
- throw new SDJWTException(`Invalid _sd_alg: ${_sd_alg}`);
516
- }
517
- if (!allowedAlgorithms.includes(_sd_alg)) {
518
- throw new SDJWTException(`Disallowed _sd_alg: ${_sd_alg}`);
519
- }
520
- return { _sd_alg, payload };
521
- };
522
- var unpack = (SdJwtPayload, disclosures, hasher) => __async(null, null, function* () {
523
- const { _sd_alg, payload } = getSDAlgAndPayload(SdJwtPayload);
524
- const hash = { hasher, alg: _sd_alg };
525
- const map = yield createHashMapping(disclosures, hash);
526
- return unpackObj(payload, map);
527
- });
528
- var unpackSync = (SdJwtPayload, disclosures, hasher) => {
529
- const { _sd_alg, payload } = getSDAlgAndPayload(SdJwtPayload);
530
- const hash = { hasher, alg: _sd_alg };
531
- const map = createHashMappingSync(disclosures, hash);
532
- return unpackObj(payload, map);
533
- };
534
-
535
- // src/flattenJSON.ts
536
- var FlattenJSON = class _FlattenJSON {
537
- constructor(data) {
538
- this.disclosures = data.disclosures;
539
- this.kb_jwt = data.kb_jwt;
540
- this.payload = data.jwtData.payload;
541
- this.signature = data.jwtData.signature;
542
- this.protected = data.jwtData.protected;
543
- }
544
- static fromEncode(encodedSdJwt) {
545
- const { jwt, disclosures, kbJwt } = splitSdJwt(encodedSdJwt);
546
- const { 0: protectedHeader, 1: payload, 2: signature } = jwt.split(".");
547
- if (!protectedHeader || !payload || !signature) {
548
- throw new SDJWTException("Invalid JWT");
549
- }
550
- return new _FlattenJSON({
551
- jwtData: {
552
- protected: protectedHeader,
553
- payload,
554
- signature
555
- },
556
- disclosures,
557
- kb_jwt: kbJwt
558
- });
559
- }
560
- static fromSerialized(json) {
561
- return new _FlattenJSON({
562
- jwtData: {
563
- protected: json.protected,
564
- payload: json.payload,
565
- signature: json.signature
566
- },
567
- disclosures: json.header.disclosures,
568
- kb_jwt: json.header.kb_jwt
569
- });
570
- }
571
- toJson() {
572
- return {
573
- payload: this.payload,
574
- signature: this.signature,
575
- protected: this.protected,
576
- header: {
577
- disclosures: this.disclosures,
578
- kb_jwt: this.kb_jwt
579
- }
580
- };
581
- }
582
- toEncoded() {
583
- var _a;
584
- const data = [];
585
- const jwt = `${this.protected}.${this.payload}.${this.signature}`;
586
- data.push(jwt);
587
- if (this.disclosures && this.disclosures.length > 0) {
588
- const disclosures = this.disclosures.join(SD_SEPARATOR);
589
- data.push(disclosures);
590
- }
591
- const kb_jwt = (_a = this.kb_jwt) != null ? _a : "";
592
- data.push(kb_jwt);
593
- return data.join(SD_SEPARATOR);
594
- }
595
- };
596
-
597
- // src/generalJSON.ts
598
- var GeneralJSON = class _GeneralJSON {
599
- constructor(data) {
600
- this.payload = data.payload;
601
- this.disclosures = data.disclosures;
602
- this.kb_jwt = data.kb_jwt;
603
- this.signatures = data.signatures;
604
- }
605
- static fromEncode(encodedSdJwt) {
606
- const { jwt, disclosures, kbJwt } = splitSdJwt(encodedSdJwt);
607
- const { 0: protectedHeader, 1: payload, 2: signature } = jwt.split(".");
608
- if (!protectedHeader || !payload || !signature) {
609
- throw new SDJWTException("Invalid JWT");
610
- }
611
- return new _GeneralJSON({
612
- payload,
613
- disclosures,
614
- kb_jwt: kbJwt,
615
- signatures: [
616
- {
617
- protected: protectedHeader,
618
- signature
619
- }
620
- ]
621
- });
622
- }
623
- static fromSerialized(json) {
624
- var _a, _b, _c;
625
- if (!json.signatures[0]) {
626
- throw new SDJWTException("Invalid JSON");
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
- }
636
- const disclosures = (_b = (_a = json.signatures[0].header) == null ? void 0 : _a.disclosures) != null ? _b : [];
637
- const kb_jwt = (_c = json.signatures[0].header) == null ? void 0 : _c.kb_jwt;
638
- return new _GeneralJSON({
639
- payload: json.payload,
640
- disclosures,
641
- kb_jwt,
642
- signatures: json.signatures.map((s) => {
643
- var _a2;
644
- return {
645
- protected: s.protected,
646
- signature: s.signature,
647
- kid: (_a2 = s.header) == null ? void 0 : _a2.kid
648
- };
649
- })
650
- });
651
- }
652
- toJson() {
653
- return {
654
- payload: this.payload,
655
- signatures: this.signatures.map((s, i) => {
656
- if (i !== 0) {
657
- return {
658
- header: {
659
- kid: s.kid
660
- },
661
- protected: s.protected,
662
- signature: s.signature
663
- };
664
- }
665
- return {
666
- header: {
667
- disclosures: this.disclosures,
668
- kid: s.kid,
669
- kb_jwt: this.kb_jwt
670
- },
671
- protected: s.protected,
672
- signature: s.signature
673
- };
674
- })
675
- };
676
- }
677
- toEncoded(index) {
678
- var _a;
679
- if (index < 0 || index >= this.signatures.length) {
680
- throw new SDJWTException("Index out of bounds");
681
- }
682
- const data = [];
683
- const { protected: protectedHeader, signature } = this.signatures[index];
684
- const jwt = `${protectedHeader}.${this.payload}.${signature}`;
685
- data.push(jwt);
686
- if (this.disclosures && this.disclosures.length > 0) {
687
- const disclosures = this.disclosures.join(SD_SEPARATOR);
688
- data.push(disclosures);
689
- }
690
- const kb = (_a = this.kb_jwt) != null ? _a : "";
691
- data.push(kb);
692
- return data.join(SD_SEPARATOR);
693
- }
694
- addSignature(protectedHeader, signer, kid) {
695
- return __async(this, null, function* () {
696
- const header = (0, import_identity_common.base64urlEncode)(JSON.stringify(protectedHeader));
697
- const signature = yield signer(`${header}.${this.payload}`);
698
- this.signatures.push({
699
- protected: header,
700
- signature,
701
- kid
702
- });
703
- });
704
- }
705
- };
706
-
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
- };
751
- var Jwt = class _Jwt {
752
- constructor(data) {
753
- this.header = data == null ? void 0 : data.header;
754
- this.payload = data == null ? void 0 : data.payload;
755
- this.signature = data == null ? void 0 : data.signature;
756
- this.encoded = data == null ? void 0 : data.encoded;
757
- }
758
- static decodeJWT(jwt) {
759
- return decodeJwt(jwt);
760
- }
761
- static fromEncode(encodedJwt) {
762
- const { header, payload, signature } = _Jwt.decodeJWT(
763
- encodedJwt
764
- );
765
- const jwt = new _Jwt({
766
- header,
767
- payload,
768
- signature,
769
- encoded: encodedJwt
770
- });
771
- return jwt;
772
- }
773
- setHeader(header) {
774
- this.header = header;
775
- this.encoded = void 0;
776
- return this;
777
- }
778
- setPayload(payload) {
779
- this.payload = payload;
780
- this.encoded = void 0;
781
- return this;
782
- }
783
- getUnsignedToken() {
784
- if (!this.header || !this.payload) {
785
- throw new SDJWTException("Serialize Error: Invalid JWT");
786
- }
787
- if (this.encoded) {
788
- const parts = this.encoded.split(".");
789
- if (parts.length !== 3) {
790
- throw new SDJWTException(`Invalid JWT format: ${this.encoded}`);
791
- }
792
- const unsignedToken = parts.slice(0, 2).join(".");
793
- return unsignedToken;
794
- }
795
- const header = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.header));
796
- const payload = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.payload));
797
- return `${header}.${payload}`;
798
- }
799
- sign(signer) {
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
- }
804
- const data = this.getUnsignedToken();
805
- this.signature = yield signer(data);
806
- return this.encodeJwt();
807
- });
808
- }
809
- encodeJwt() {
810
- if (this.encoded) {
811
- return this.encoded;
812
- }
813
- if (!this.header || !this.payload || !this.signature) {
814
- throw new SDJWTException("Serialize Error: Invalid JWT");
815
- }
816
- const header = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.header));
817
- const payload = (0, import_identity_common.base64urlEncode)(JSON.stringify(this.payload));
818
- const signature = this.signature;
819
- const compact = `${header}.${payload}.${signature}`;
820
- this.encoded = compact;
821
- return compact;
822
- }
823
- /**
824
- * Verify the JWT using the provided verifier function.
825
- * It checks the signature and validates the iat, nbf, and exp claims if they are present.
826
- * @param verifier
827
- * @param options - Options for verification, such as current date and skew seconds
828
- * @returns
829
- */
830
- verify(verifier, options) {
831
- return __async(this, null, function* () {
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');
836
- }
837
- if ((options == null ? void 0 : options.allowedIssuerAlgorithms) && !options.allowedIssuerAlgorithms.includes(alg)) {
838
- throw new SDJWTException(`Verify Error: Disallowed alg ${alg}`);
839
- }
840
- if (!(options == null ? void 0 : options.skipJwtClaimValidation)) {
841
- validateJwtPayload(this.payload, options);
842
- }
843
- if (!this.signature) {
844
- throw new SDJWTException("Verify Error: no signature in JWT");
845
- }
846
- const data = this.getUnsignedToken();
847
- const verified = yield verifier(data, this.signature, options);
848
- if (!verified) {
849
- throw new SDJWTException("Verify Error: Invalid JWT Signature");
850
- }
851
- return { payload: this.payload, header: this.header };
852
- });
853
- }
854
- };
855
-
856
- // src/kbjwt.ts
857
- var KBJwt = class _KBJwt extends Jwt {
858
- // Checking the validity of the key binding jwt
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
860
- verifyKB(values) {
861
- return __async(this, null, function* () {
862
- var _a, _b, _c, _d;
863
- if (!this.header || !this.payload || !this.signature) {
864
- throw new SDJWTException("Verify Error: Invalid JWT");
865
- }
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) {
867
- throw new SDJWTException("Invalid Key Binding Jwt");
868
- }
869
- if (this.payload.nonce !== values.nonce) {
870
- throw new SDJWTException("Verify Error: Invalid Nonce");
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
- }
887
- yield this.verify(
888
- (data, sig) => values.verifier(data, sig, values.payload),
889
- values.options
890
- );
891
- return { payload: this.payload, header: this.header };
892
- });
893
- }
894
- // This function is for creating KBJwt object for verify properly
895
- static fromKBEncode(encodedJwt) {
896
- const { header, payload, signature } = Jwt.decodeJWT(
897
- encodedJwt
898
- );
899
- const jwt = new _KBJwt({
900
- header,
901
- payload,
902
- signature,
903
- encoded: encodedJwt
904
- });
905
- return jwt;
906
- }
907
- };
908
-
909
- // src/decoy.ts
910
- var createDecoy = (hash, saltGenerator) => __async(null, null, function* () {
911
- const { hasher, alg } = hash;
912
- const salt = yield saltGenerator(16);
913
- const decoy = yield hasher(salt, alg);
914
- return (0, import_identity_common.uint8ArrayToBase64Url)(decoy);
915
- });
916
-
917
- // src/present/present.ts
918
- var presentableKeys = (rawPayload, disclosures, hasher) => __async(null, null, function* () {
919
- const { disclosureKeymap } = yield unpack(rawPayload, disclosures, hasher);
920
- return Object.keys(disclosureKeymap).sort();
921
- });
922
- var presentableKeysSync = (rawPayload, disclosures, hasher) => {
923
- const { disclosureKeymap } = unpackSync(rawPayload, disclosures, hasher);
924
- return Object.keys(disclosureKeymap).sort();
925
- };
926
- var present = (sdJwt, presentFrame, hasher) => __async(null, null, function* () {
927
- const { jwt, kbJwt } = splitSdJwt(sdJwt);
928
- const {
929
- jwt: { payload },
930
- disclosures
931
- } = yield decodeSdJwt(sdJwt, hasher);
932
- const { _sd_alg: alg } = getSDAlgAndPayload(payload);
933
- const hash = { alg, hasher };
934
- const keys = transformPresentationFrame(presentFrame);
935
- const hashmap = yield createHashMapping(disclosures, hash);
936
- const { disclosureKeymap } = yield unpack(payload, disclosures, hasher);
937
- const presentedDisclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
938
- return [
939
- jwt,
940
- ...presentedDisclosures.map((d) => d.encode()),
941
- kbJwt != null ? kbJwt : ""
942
- ].join(SD_SEPARATOR);
943
- });
944
- var presentSync = (sdJwt, presentFrame, hasher) => {
945
- const { jwt, kbJwt } = splitSdJwt(sdJwt);
946
- const {
947
- jwt: { payload },
948
- disclosures
949
- } = decodeSdJwtSync(sdJwt, hasher);
950
- const { _sd_alg: alg } = getSDAlgAndPayload(payload);
951
- const hash = { alg, hasher };
952
- const keys = transformPresentationFrame(presentFrame);
953
- const hashmap = createHashMappingSync(disclosures, hash);
954
- const { disclosureKeymap } = unpackSync(payload, disclosures, hasher);
955
- const presentedDisclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
956
- return [
957
- jwt,
958
- ...presentedDisclosures.map((d) => d.encode()),
959
- kbJwt != null ? kbJwt : ""
960
- ].join(SD_SEPARATOR);
961
- };
962
- var transformPresentationFrame = (obj, prefix = []) => {
963
- return Object.entries(obj).reduce((acc, [key, value]) => {
964
- const newPrefix = [...prefix, key];
965
- const encodedPrefix = encodePath(newPrefix);
966
- if (typeof value === "boolean") {
967
- if (value) {
968
- acc.push(encodedPrefix);
969
- }
970
- } else if (typeof value === "object" && value !== null) {
971
- acc.push(
972
- encodedPrefix,
973
- ...transformPresentationFrame(
974
- value,
975
- newPrefix
976
- )
977
- );
978
- }
979
- return acc;
980
- }, []);
981
- };
982
- var createHashMappingForSerializedDisclosure = (disclosures) => {
983
- const map = {};
984
- for (let i = 0; i < disclosures.length; i++) {
985
- const disclosure = disclosures[i];
986
- const { digest, encoded, key, salt, value } = disclosure;
987
- map[digest] = Disclosure.fromArray(
988
- key ? [salt, key, value] : [salt, value],
989
- { digest, encoded }
990
- );
991
- }
992
- return map;
993
- };
994
- var selectDisclosures = (payload, disclosures, presentationFrame) => {
995
- if (disclosures.length === 0) {
996
- return [];
997
- }
998
- const hashmap = createHashMappingForSerializedDisclosure(disclosures);
999
- const { disclosureKeymap } = unpackObj(payload, hashmap);
1000
- const keys = transformPresentationFrame(presentationFrame);
1001
- const presentedDisclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
1002
- const selectedDisclosures = presentedDisclosures.map(
1003
- (d) => {
1004
- const { salt, key, value, _digest } = d;
1005
- if (!_digest) {
1006
- throw new SDJWTException(
1007
- "Implementation error: _digest is not defined"
1008
- );
1009
- }
1010
- return {
1011
- digest: _digest,
1012
- encoded: d.encode(),
1013
- salt,
1014
- key,
1015
- value
1016
- };
1017
- }
1018
- );
1019
- return selectedDisclosures;
1020
- };
1021
-
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
- };
1040
- var SDJwt = class _SDJwt {
1041
- constructor(data) {
1042
- this.jwt = data == null ? void 0 : data.jwt;
1043
- this.disclosures = data == null ? void 0 : data.disclosures;
1044
- this.kbJwt = data == null ? void 0 : data.kbJwt;
1045
- }
1046
- static decodeSDJwt(sdjwt, hasher) {
1047
- return __async(this, null, function* () {
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
- }
1052
- const jwt = Jwt.fromEncode(encodedJwt);
1053
- if (!jwt.payload) {
1054
- throw new Error("Payload is undefined on the JWT. Invalid state reached");
1055
- }
1056
- const encodedKeyBindingJwt = encodedDisclosures.pop();
1057
- const kbJwt = encodedKeyBindingJwt ? KBJwt.fromKBEncode(encodedKeyBindingJwt) : void 0;
1058
- const { _sd_alg } = getSDAlgAndPayload(jwt.payload);
1059
- const disclosures = yield Promise.all(
1060
- encodedDisclosures.map(
1061
- (ed) => Disclosure.fromEncode(ed, { alg: _sd_alg, hasher })
1062
- )
1063
- );
1064
- return {
1065
- jwt,
1066
- disclosures,
1067
- kbJwt
1068
- };
1069
- });
1070
- }
1071
- static extractJwt(encodedSdJwt) {
1072
- return __async(this, null, function* () {
1073
- const [encodedJwt, ..._encodedDisclosures] = encodedSdJwt.split(SD_SEPARATOR);
1074
- return Jwt.fromEncode(encodedJwt);
1075
- });
1076
- }
1077
- static fromEncode(encodedSdJwt, hasher) {
1078
- return __async(this, null, function* () {
1079
- const { jwt, disclosures, kbJwt } = yield _SDJwt.decodeSDJwt(encodedSdJwt, hasher);
1080
- return new _SDJwt({
1081
- jwt,
1082
- disclosures,
1083
- kbJwt
1084
- });
1085
- });
1086
- }
1087
- present(presentFrame, hasher) {
1088
- return __async(this, null, function* () {
1089
- const disclosures = yield this.getPresentDisclosures(presentFrame, hasher);
1090
- const presentSDJwt = new _SDJwt({
1091
- jwt: this.jwt,
1092
- disclosures,
1093
- kbJwt: this.kbJwt
1094
- });
1095
- return presentSDJwt.encodeSDJwt();
1096
- });
1097
- }
1098
- getPresentDisclosures(presentFrame, hasher) {
1099
- return __async(this, null, function* () {
1100
- var _a;
1101
- if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
1102
- throw new SDJWTException("Invalid sd-jwt: jwt or disclosures is missing");
1103
- }
1104
- const { _sd_alg: alg } = getSDAlgAndPayload(this.jwt.payload);
1105
- const hash = { alg, hasher };
1106
- const hashmap = yield createHashMapping(this.disclosures, hash);
1107
- const { disclosureKeymap } = yield unpack(
1108
- this.jwt.payload,
1109
- this.disclosures,
1110
- hasher
1111
- );
1112
- const keys = presentFrame ? transformPresentationFrame(presentFrame) : yield this.presentableKeys(hasher);
1113
- const disclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
1114
- return disclosures;
1115
- });
1116
- }
1117
- encodeSDJwt() {
1118
- const data = [];
1119
- if (!this.jwt) {
1120
- throw new SDJWTException("Invalid sd-jwt: jwt is missing");
1121
- }
1122
- const encodedJwt = this.jwt.encodeJwt();
1123
- data.push(encodedJwt);
1124
- if (this.disclosures && this.disclosures.length > 0) {
1125
- const encodeddisclosures = this.disclosures.map((dc) => dc.encode()).join(SD_SEPARATOR);
1126
- data.push(encodeddisclosures);
1127
- }
1128
- data.push(this.kbJwt ? this.kbJwt.encodeJwt() : "");
1129
- return data.join(SD_SEPARATOR);
1130
- }
1131
- keys(hasher) {
1132
- return __async(this, null, function* () {
1133
- return listKeys(yield this.getClaims(hasher)).sort();
1134
- });
1135
- }
1136
- presentableKeys(hasher) {
1137
- return __async(this, null, function* () {
1138
- var _a, _b;
1139
- if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
1140
- throw new SDJWTException("Invalid sd-jwt: jwt or disclosures is missing");
1141
- }
1142
- const { disclosureKeymap } = yield unpack(
1143
- (_b = this.jwt) == null ? void 0 : _b.payload,
1144
- this.disclosures,
1145
- hasher
1146
- );
1147
- return Object.keys(disclosureKeymap).sort();
1148
- });
1149
- }
1150
- getClaims(hasher) {
1151
- return __async(this, null, function* () {
1152
- var _a;
1153
- if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
1154
- throw new SDJWTException("Invalid sd-jwt: jwt or disclosures is missing");
1155
- }
1156
- const { unpackedObj } = yield unpack(
1157
- this.jwt.payload,
1158
- this.disclosures,
1159
- hasher
1160
- );
1161
- return unpackedObj;
1162
- });
1163
- }
1164
- };
1165
- var listKeys = (obj, prefix = "") => {
1166
- const keys = [];
1167
- for (const key in obj) {
1168
- if (obj[key] === void 0) continue;
1169
- const escapedKey = encodePathSegment(key);
1170
- const newKey = prefix ? `${prefix}.${escapedKey}` : escapedKey;
1171
- keys.push(newKey);
1172
- const value = obj[key];
1173
- if (value && typeof value === "object") {
1174
- keys.push(...listKeys(value, newKey));
1175
- }
1176
- }
1177
- return keys;
1178
- };
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()) {
1180
- var _a, _b;
1181
- if (!disclosureFrame) {
1182
- return {
1183
- packedClaims: claims,
1184
- disclosures: []
1185
- };
1186
- }
1187
- const sd = (_a = disclosureFrame[SD_DIGEST]) != null ? _a : [];
1188
- const decoyCount = (_b = disclosureFrame[SD_DECOY]) != null ? _b : 0;
1189
- if (Array.isArray(claims)) {
1190
- const packedClaims2 = [];
1191
- const disclosures2 = [];
1192
- const recursivePackedClaims2 = {};
1193
- for (const key in disclosureFrame) {
1194
- if (key !== SD_DIGEST) {
1195
- const idx = Number.parseInt(key, 10);
1196
- const packed = yield pack(
1197
- claims[idx],
1198
- disclosureFrame[idx],
1199
- hash,
1200
- saltGenerator,
1201
- seenSalts,
1202
- seenDigests
1203
- );
1204
- recursivePackedClaims2[idx] = packed.packedClaims;
1205
- disclosures2.push(...packed.disclosures);
1206
- }
1207
- }
1208
- for (let i = 0; i < claims.length; i++) {
1209
- const claim = recursivePackedClaims2[i] ? recursivePackedClaims2[i] : claims[i];
1210
- if (sd.includes(i)) {
1211
- const salt = yield createDisclosureSalt(saltGenerator, seenSalts);
1212
- const disclosure = new Disclosure([salt, claim]);
1213
- const digest = yield disclosure.digest(hash);
1214
- addDisclosureDigest(digest, seenDigests);
1215
- packedClaims2.push({ [SD_LIST_KEY]: digest });
1216
- disclosures2.push(disclosure);
1217
- } else {
1218
- packedClaims2.push(claim);
1219
- }
1220
- }
1221
- for (let j = 0; j < decoyCount; j++) {
1222
- const decoyDigest = yield createDecoy(hash, saltGenerator);
1223
- addDisclosureDigest(decoyDigest, seenDigests);
1224
- packedClaims2.push({ [SD_LIST_KEY]: decoyDigest });
1225
- }
1226
- return { packedClaims: packedClaims2, disclosures: disclosures2 };
1227
- }
1228
- const packedClaims = {};
1229
- const disclosures = [];
1230
- const recursivePackedClaims = {};
1231
- for (const key in disclosureFrame) {
1232
- if (key !== SD_DIGEST) {
1233
- const packed = yield pack(
1234
- // @ts-expect-error
1235
- claims[key],
1236
- disclosureFrame[key],
1237
- hash,
1238
- saltGenerator,
1239
- seenSalts,
1240
- seenDigests
1241
- );
1242
- recursivePackedClaims[key] = packed.packedClaims;
1243
- disclosures.push(...packed.disclosures);
1244
- }
1245
- }
1246
- const _sd = [];
1247
- for (const key in claims) {
1248
- const claim = recursivePackedClaims[key] ? recursivePackedClaims[key] : claims[key];
1249
- if (sd.includes(key)) {
1250
- const salt = yield createDisclosureSalt(saltGenerator, seenSalts);
1251
- const disclosure = new Disclosure([salt, key, claim]);
1252
- const digest = yield disclosure.digest(hash);
1253
- addDisclosureDigest(digest, seenDigests);
1254
- _sd.push(digest);
1255
- disclosures.push(disclosure);
1256
- } else {
1257
- packedClaims[key] = claim;
1258
- }
1259
- }
1260
- for (let j = 0; j < decoyCount; j++) {
1261
- const decoyDigest = yield createDecoy(hash, saltGenerator);
1262
- addDisclosureDigest(decoyDigest, seenDigests);
1263
- _sd.push(decoyDigest);
1264
- }
1265
- if (_sd.length > 0) {
1266
- packedClaims[SD_DIGEST] = _sd.sort();
1267
- }
1268
- return { packedClaims, disclosures };
1269
- });
1270
-
1271
- // src/index.ts
1272
- function validateReservedFieldsInternal(payload) {
1273
- const reservedFields = /* @__PURE__ */ new Set([SD_DIGEST, "_sd_alg", SD_DECOY, SD_LIST_KEY]);
1274
- const visit = (node) => {
1275
- if (!node || typeof node !== "object") {
1276
- return;
1277
- }
1278
- for (const [key, value] of Object.entries(
1279
- node
1280
- )) {
1281
- if (reservedFields.has(key)) {
1282
- throw new SDJWTException(`Reserved field name "${key}" is not allowed`);
1283
- }
1284
- visit(value);
1285
- }
1286
- };
1287
- visit(payload);
1288
- }
1289
- var _SDJwtInstance = class _SDJwtInstance {
1290
- constructor(userConfig) {
1291
- this.userConfig = {};
1292
- var _a;
1293
- if (userConfig) {
1294
- if (userConfig.hashAlg && !IANA_HASH_ALGORITHMS.includes(userConfig.hashAlg)) {
1295
- throw new SDJWTException(
1296
- `Invalid hash algorithm: ${userConfig.hashAlg}`
1297
- );
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
- }
1305
- this.userConfig = userConfig;
1306
- }
1307
- }
1308
- createKBJwt(options, sdHash) {
1309
- return __async(this, null, function* () {
1310
- if (!this.userConfig.kbSigner) {
1311
- throw new SDJWTException("Key Binding Signer not found");
1312
- }
1313
- if (!this.userConfig.kbSignAlg) {
1314
- throw new SDJWTException("Key Binding sign algorithm not specified");
1315
- }
1316
- const { payload } = options;
1317
- const kbJwt = new KBJwt({
1318
- header: {
1319
- typ: KB_JWT_TYP,
1320
- alg: this.userConfig.kbSignAlg
1321
- },
1322
- payload: __spreadProps(__spreadValues({}, payload), { sd_hash: sdHash })
1323
- });
1324
- yield kbJwt.sign(this.userConfig.kbSigner);
1325
- return kbJwt;
1326
- });
1327
- }
1328
- SignJwt(jwt) {
1329
- return __async(this, null, function* () {
1330
- if (!this.userConfig.signer) {
1331
- throw new SDJWTException("Signer not found");
1332
- }
1333
- yield jwt.sign(this.userConfig.signer);
1334
- return jwt;
1335
- });
1336
- }
1337
- VerifyJwt(jwt, options) {
1338
- return __async(this, null, function* () {
1339
- if (!this.userConfig.verifier) {
1340
- throw new SDJWTException("Verifier not found");
1341
- }
1342
- return jwt.verify(this.userConfig.verifier, options);
1343
- });
1344
- }
1345
- issue(payload, disclosureFrame, options) {
1346
- return __async(this, null, function* () {
1347
- var _a, _b, _c;
1348
- if (!this.userConfig.hasher) {
1349
- throw new SDJWTException("Hasher not found");
1350
- }
1351
- if (!this.userConfig.saltGenerator) {
1352
- throw new SDJWTException("SaltGenerator not found");
1353
- }
1354
- if (!this.userConfig.signAlg) {
1355
- throw new SDJWTException("sign alogrithm not specified");
1356
- }
1357
- if (this.userConfig.signAlg === "none") {
1358
- throw new SDJWTException('sign algorithm "none" is not allowed');
1359
- }
1360
- this.validateReservedFields(payload);
1361
- this.validateDisclosureFrame(disclosureFrame);
1362
- const hasher = this.userConfig.hasher;
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
- }
1368
- const { packedClaims, disclosures } = yield pack(
1369
- payload,
1370
- disclosureFrame,
1371
- { hasher, alg: hashAlg },
1372
- this.userConfig.saltGenerator
1373
- );
1374
- const alg = this.userConfig.signAlg;
1375
- const OptionHeader = (_c = options == null ? void 0 : options.header) != null ? _c : {};
1376
- const CustomHeader = this.userConfig.omitTyp ? OptionHeader : __spreadValues({ typ: this.type }, OptionHeader);
1377
- const header = __spreadProps(__spreadValues({}, CustomHeader), { alg });
1378
- const jwt = new Jwt({
1379
- header,
1380
- payload: __spreadProps(__spreadValues({}, packedClaims), {
1381
- _sd_alg: disclosureFrame ? hashAlg : void 0
1382
- })
1383
- });
1384
- yield this.SignJwt(jwt);
1385
- const sdJwt = new SDJwt({
1386
- jwt,
1387
- disclosures
1388
- });
1389
- return sdJwt.encodeSDJwt();
1390
- });
1391
- }
1392
- /**
1393
- * Validates if the payload contains any reserved claim names. If so it will throw an error.
1394
- * @param payload
1395
- * @returns
1396
- */
1397
- validateReservedFields(payload) {
1398
- validateReservedFieldsInternal(payload);
1399
- }
1400
- validateDisclosureFrame(_disclosureFrame) {
1401
- return;
1402
- }
1403
- present(encodedSDJwt, presentationFrame, options) {
1404
- return __async(this, null, function* () {
1405
- var _a;
1406
- if (!this.userConfig.hasher) {
1407
- throw new SDJWTException("Hasher not found");
1408
- }
1409
- const hasher = this.userConfig.hasher;
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
- }
1414
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new SDJWTException("Payload not found");
1415
- const presentSdJwtWithoutKb = yield sdjwt.present(
1416
- presentationFrame,
1417
- hasher
1418
- );
1419
- if (!(options == null ? void 0 : options.kb)) {
1420
- return presentSdJwtWithoutKb;
1421
- }
1422
- const sdHashStr = yield this.calculateSDHash(
1423
- presentSdJwtWithoutKb,
1424
- sdjwt,
1425
- hasher
1426
- );
1427
- sdjwt.kbJwt = yield this.createKBJwt(options.kb, sdHashStr);
1428
- return sdjwt.present(presentationFrame, hasher);
1429
- });
1430
- }
1431
- // This function is for verifying the SD JWT
1432
- // If requiredClaimKeys is provided, it will check if the required claim keys are presentation in the SD JWT
1433
- // If requireKeyBindings is true, it will check if the key binding JWT is presentation and verify it
1434
- verify(encodedSDJwt, options) {
1435
- return __async(this, null, function* () {
1436
- var _a;
1437
- if (!this.userConfig.hasher) {
1438
- throw new SDJWTException("Hasher not found");
1439
- }
1440
- const hasher = this.userConfig.hasher;
1441
- const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
1442
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) {
1443
- throw new SDJWTException("Invalid SD JWT");
1444
- }
1445
- const { payload, header } = yield this.validate(encodedSDJwt, options);
1446
- if (options == null ? void 0 : options.requiredClaimKeys) {
1447
- const keys = yield sdjwt.keys(hasher);
1448
- const missingKeys = options.requiredClaimKeys.filter(
1449
- (k) => !keys.includes(k)
1450
- );
1451
- if (missingKeys.length > 0) {
1452
- throw new SDJWTException(
1453
- `Missing required claim keys: ${missingKeys.join(", ")}`
1454
- );
1455
- }
1456
- }
1457
- if (!(options == null ? void 0 : options.keyBindingNonce)) {
1458
- return { payload, header };
1459
- }
1460
- if (!sdjwt.kbJwt) {
1461
- throw new SDJWTException("Key Binding JWT not exist");
1462
- }
1463
- if (!this.userConfig.kbVerifier) {
1464
- throw new SDJWTException("Key Binding Verifier not found");
1465
- }
1466
- const kb = yield sdjwt.kbJwt.verifyKB({
1467
- verifier: this.userConfig.kbVerifier,
1468
- payload,
1469
- nonce: options.keyBindingNonce,
1470
- options
1471
- });
1472
- if (!kb) {
1473
- throw new Error("signature is not valid");
1474
- }
1475
- const sdHashfromKb = kb.payload.sd_hash;
1476
- const sdjwtWithoutKb = new SDJwt({
1477
- jwt: sdjwt.jwt,
1478
- disclosures: sdjwt.disclosures
1479
- });
1480
- const presentSdJwtWithoutKb = sdjwtWithoutKb.encodeSDJwt();
1481
- const sdHashStr = yield this.calculateSDHash(
1482
- presentSdJwtWithoutKb,
1483
- sdjwt,
1484
- hasher
1485
- );
1486
- if (sdHashStr !== sdHashfromKb) {
1487
- throw new SDJWTException("Invalid sd_hash in Key Binding JWT");
1488
- }
1489
- return { payload, header, kb };
1490
- });
1491
- }
1492
- /**
1493
- * Safe verification that collects all errors instead of failing fast.
1494
- * Returns a result object with either the verified data or an array of all errors.
1495
- *
1496
- * @param encodedSDJwt - The encoded SD-JWT to verify
1497
- * @param options - Verification options
1498
- * @returns A SafeVerifyResult containing either success data or collected errors
1499
- */
1500
- safeVerify(encodedSDJwt, options) {
1501
- return __async(this, null, function* () {
1502
- var _a;
1503
- const errors = [];
1504
- const addError = (code, message, details) => {
1505
- errors.push({ code, message, details });
1506
- };
1507
- const exceptionToCode = (error) => {
1508
- const message = error.message.toLowerCase();
1509
- if (message.includes("hasher not found")) return "HASHER_NOT_FOUND";
1510
- if (message.includes("verifier not found")) return "VERIFIER_NOT_FOUND";
1511
- if (message.includes("invalid sd jwt") || message.includes("invalid jwt"))
1512
- return "INVALID_SD_JWT";
1513
- if (message.includes("not yet valid")) return "JWT_NOT_YET_VALID";
1514
- if (message.includes("expired")) return "JWT_EXPIRED";
1515
- if (message.includes("signature")) return "INVALID_JWT_SIGNATURE";
1516
- if (message.includes("missing required claim"))
1517
- return "MISSING_REQUIRED_CLAIMS";
1518
- if (message.includes("key binding jwt not exist"))
1519
- return "KEY_BINDING_JWT_MISSING";
1520
- if (message.includes("key binding verifier not found"))
1521
- return "KEY_BINDING_VERIFIER_NOT_FOUND";
1522
- if (message.includes("sd_hash")) return "KEY_BINDING_SD_HASH_INVALID";
1523
- return "UNKNOWN_ERROR";
1524
- };
1525
- if (!this.userConfig.hasher) {
1526
- addError("HASHER_NOT_FOUND", "Hasher not found");
1527
- }
1528
- if (!this.userConfig.verifier) {
1529
- addError("VERIFIER_NOT_FOUND", "Verifier not found");
1530
- }
1531
- if (errors.length > 0) {
1532
- return { success: false, errors };
1533
- }
1534
- if (!this.userConfig.hasher) {
1535
- throw new SDJWTException("Hasher not found");
1536
- }
1537
- const hasher = this.userConfig.hasher;
1538
- let sdjwt;
1539
- let payload;
1540
- let header;
1541
- try {
1542
- sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
1543
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) {
1544
- addError("INVALID_SD_JWT", "Invalid SD JWT: missing JWT or payload");
1545
- }
1546
- } catch (e) {
1547
- const error = ensureError(e);
1548
- addError(
1549
- "INVALID_SD_JWT",
1550
- `Failed to decode SD-JWT: ${error.message}`,
1551
- error
1552
- );
1553
- }
1554
- if (sdjwt == null ? void 0 : sdjwt.jwt) {
1555
- try {
1556
- const result = yield this.VerifyJwt(sdjwt.jwt, __spreadProps(__spreadValues({}, options), {
1557
- skipJwtClaimValidation: true
1558
- }));
1559
- header = result.header;
1560
- const claims = yield sdjwt.getClaims(hasher);
1561
- payload = claims;
1562
- validateJwtPayload(payload, options);
1563
- } catch (e) {
1564
- const error = ensureError(e);
1565
- const code = exceptionToCode(error);
1566
- addError(code, error.message, error);
1567
- }
1568
- }
1569
- if (sdjwt && (options == null ? void 0 : options.requiredClaimKeys)) {
1570
- try {
1571
- const keys = yield sdjwt.keys(hasher);
1572
- const missingKeys = options.requiredClaimKeys.filter(
1573
- (k) => !keys.includes(k)
1574
- );
1575
- if (missingKeys.length > 0) {
1576
- addError(
1577
- "MISSING_REQUIRED_CLAIMS",
1578
- `Missing required claim keys: ${missingKeys.join(", ")}`,
1579
- { missingKeys }
1580
- );
1581
- }
1582
- } catch (e) {
1583
- const error = ensureError(e);
1584
- addError(
1585
- "UNKNOWN_ERROR",
1586
- `Failed to check required claims: ${error.message}`,
1587
- error
1588
- );
1589
- }
1590
- }
1591
- let kb;
1592
- if ((options == null ? void 0 : options.keyBindingNonce) && sdjwt) {
1593
- if (!sdjwt.kbJwt) {
1594
- addError("KEY_BINDING_JWT_MISSING", "Key Binding JWT not exist");
1595
- } else if (!this.userConfig.kbVerifier) {
1596
- addError(
1597
- "KEY_BINDING_VERIFIER_NOT_FOUND",
1598
- "Key Binding Verifier not found"
1599
- );
1600
- } else if (payload) {
1601
- try {
1602
- const kbResult = yield sdjwt.kbJwt.verifyKB({
1603
- verifier: this.userConfig.kbVerifier,
1604
- payload,
1605
- nonce: options.keyBindingNonce,
1606
- options
1607
- });
1608
- if (!kbResult) {
1609
- addError(
1610
- "KEY_BINDING_SIGNATURE_INVALID",
1611
- "Key binding signature is not valid"
1612
- );
1613
- } else {
1614
- kb = kbResult;
1615
- const sdjwtWithoutKb = new SDJwt({
1616
- jwt: sdjwt.jwt,
1617
- disclosures: sdjwt.disclosures
1618
- });
1619
- const presentSdJwtWithoutKb = sdjwtWithoutKb.encodeSDJwt();
1620
- const sdHashStr = yield this.calculateSDHash(
1621
- presentSdJwtWithoutKb,
1622
- sdjwt,
1623
- hasher
1624
- );
1625
- if (sdHashStr !== kbResult.payload.sd_hash) {
1626
- addError(
1627
- "KEY_BINDING_SD_HASH_INVALID",
1628
- "Invalid sd_hash in Key Binding JWT",
1629
- {
1630
- expected: sdHashStr,
1631
- received: kbResult.payload.sd_hash
1632
- }
1633
- );
1634
- }
1635
- }
1636
- } catch (e) {
1637
- const error = ensureError(e);
1638
- addError(
1639
- "KEY_BINDING_SIGNATURE_INVALID",
1640
- `Key binding verification failed: ${error.message}`,
1641
- error
1642
- );
1643
- }
1644
- }
1645
- }
1646
- if (errors.length > 0) {
1647
- return { success: false, errors };
1648
- }
1649
- return {
1650
- success: true,
1651
- data: {
1652
- payload,
1653
- header,
1654
- kb
1655
- }
1656
- };
1657
- });
1658
- }
1659
- calculateSDHash(presentSdJwtWithoutKb, sdjwt, hasher) {
1660
- return __async(this, null, function* () {
1661
- var _a;
1662
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) {
1663
- throw new SDJWTException("Invalid SD JWT");
1664
- }
1665
- const { _sd_alg } = getSDAlgAndPayload(sdjwt.jwt.payload);
1666
- const sdHash = yield hasher(presentSdJwtWithoutKb, _sd_alg);
1667
- const sdHashStr = (0, import_identity_common.uint8ArrayToBase64Url)(sdHash);
1668
- return sdHashStr;
1669
- });
1670
- }
1671
- /**
1672
- * This function is for validating the SD JWT
1673
- * Checking signature, if provided the iat and exp when provided and return its the claims
1674
- * @param encodedSDJwt
1675
- * @param options
1676
- * @returns
1677
- */
1678
- validate(encodedSDJwt, options) {
1679
- return __async(this, null, function* () {
1680
- if (!this.userConfig.hasher) {
1681
- throw new SDJWTException("Hasher not found");
1682
- }
1683
- const hasher = this.userConfig.hasher;
1684
- const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
1685
- if (!sdjwt.jwt) {
1686
- throw new SDJWTException("Invalid SD JWT");
1687
- }
1688
- const verifiedPayloads = yield this.VerifyJwt(sdjwt.jwt, __spreadProps(__spreadValues({}, options), {
1689
- skipJwtClaimValidation: true
1690
- }));
1691
- const claims = yield sdjwt.getClaims(hasher);
1692
- validateReservedFieldsInternal(claims);
1693
- validateJwtPayload(claims, options);
1694
- return { payload: claims, header: verifiedPayloads.header };
1695
- });
1696
- }
1697
- config(newConfig) {
1698
- this.userConfig = __spreadValues(__spreadValues({}, this.userConfig), newConfig);
1699
- }
1700
- encode(sdJwt) {
1701
- return sdJwt.encodeSDJwt();
1702
- }
1703
- decode(endcodedSDJwt) {
1704
- if (!this.userConfig.hasher) {
1705
- throw new SDJWTException("Hasher not found");
1706
- }
1707
- return SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
1708
- }
1709
- keys(endcodedSDJwt) {
1710
- return __async(this, null, function* () {
1711
- if (!this.userConfig.hasher) {
1712
- throw new SDJWTException("Hasher not found");
1713
- }
1714
- const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
1715
- return sdjwt.keys(this.userConfig.hasher);
1716
- });
1717
- }
1718
- presentableKeys(endcodedSDJwt) {
1719
- return __async(this, null, function* () {
1720
- if (!this.userConfig.hasher) {
1721
- throw new SDJWTException("Hasher not found");
1722
- }
1723
- const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
1724
- return sdjwt.presentableKeys(this.userConfig.hasher);
1725
- });
1726
- }
1727
- getClaims(endcodedSDJwt) {
1728
- return __async(this, null, function* () {
1729
- if (!this.userConfig.hasher) {
1730
- throw new SDJWTException("Hasher not found");
1731
- }
1732
- const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
1733
- return sdjwt.getClaims(this.userConfig.hasher);
1734
- });
1735
- }
1736
- toFlattenJSON(endcodedSDJwt) {
1737
- return FlattenJSON.fromEncode(endcodedSDJwt);
1738
- }
1739
- toGeneralJSON(endcodedSDJwt) {
1740
- return GeneralJSON.fromEncode(endcodedSDJwt);
1741
- }
1742
- };
1743
- _SDJwtInstance.DEFAULT_hashAlg = "sha-256";
1744
- var SDJwtInstance = _SDJwtInstance;
1745
- var SDJwtGeneralJSONInstance = class {
1746
- constructor(userConfig) {
1747
- this.userConfig = {};
1748
- var _a;
1749
- if (userConfig) {
1750
- if (userConfig.hashAlg && !IANA_HASH_ALGORITHMS.includes(userConfig.hashAlg)) {
1751
- throw new SDJWTException(
1752
- `Invalid hash algorithm: ${userConfig.hashAlg}`
1753
- );
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
- }
1761
- this.userConfig = userConfig;
1762
- }
1763
- }
1764
- createKBJwt(options, sdHash) {
1765
- return __async(this, null, function* () {
1766
- if (!this.userConfig.kbSigner) {
1767
- throw new SDJWTException("Key Binding Signer not found");
1768
- }
1769
- if (!this.userConfig.kbSignAlg) {
1770
- throw new SDJWTException("Key Binding sign algorithm not specified");
1771
- }
1772
- const { payload } = options;
1773
- const kbJwt = new KBJwt({
1774
- header: {
1775
- typ: KB_JWT_TYP,
1776
- alg: this.userConfig.kbSignAlg
1777
- },
1778
- payload: __spreadProps(__spreadValues({}, payload), { sd_hash: sdHash })
1779
- });
1780
- yield kbJwt.sign(this.userConfig.kbSigner);
1781
- return kbJwt;
1782
- });
1783
- }
1784
- encodeObj(obj) {
1785
- return (0, import_identity_common.base64urlEncode)(JSON.stringify(obj));
1786
- }
1787
- issue(payload, disclosureFrame, options) {
1788
- return __async(this, null, function* () {
1789
- var _a;
1790
- if (!this.userConfig.hasher) {
1791
- throw new SDJWTException("Hasher not found");
1792
- }
1793
- if (!this.userConfig.saltGenerator) {
1794
- throw new SDJWTException("SaltGenerator not found");
1795
- }
1796
- this.validateReservedFields(payload);
1797
- this.validateDisclosureFrame(disclosureFrame);
1798
- const hasher = this.userConfig.hasher;
1799
- const hashAlg = (_a = this.userConfig.hashAlg) != null ? _a : SDJwtInstance.DEFAULT_hashAlg;
1800
- const { packedClaims, disclosures } = yield pack(
1801
- payload,
1802
- disclosureFrame,
1803
- { hasher, alg: hashAlg },
1804
- this.userConfig.saltGenerator
1805
- );
1806
- const encodedSDJwtPayload = this.encodeObj(__spreadProps(__spreadValues({}, packedClaims), {
1807
- _sd_alg: disclosureFrame ? hashAlg : void 0
1808
- }));
1809
- const encodedDisclosures = disclosures.map(
1810
- (disclosure) => disclosure.encode()
1811
- );
1812
- const signatures = yield Promise.all(
1813
- options.sigs.map((s) => __async(this, null, function* () {
1814
- const { signer, alg, kid, header } = s;
1815
- const protectedHeader = __spreadValues({ typ: this.type, alg, kid }, header);
1816
- const encodedProtectedHeader = this.encodeObj(protectedHeader);
1817
- const signature = yield signer(
1818
- `${encodedProtectedHeader}.${encodedSDJwtPayload}`
1819
- );
1820
- return {
1821
- protected: encodedProtectedHeader,
1822
- signature
1823
- };
1824
- }))
1825
- );
1826
- const generalJson = new GeneralJSON({
1827
- payload: encodedSDJwtPayload,
1828
- disclosures: encodedDisclosures,
1829
- signatures
1830
- });
1831
- return generalJson;
1832
- });
1833
- }
1834
- /**
1835
- * Validates if the payload contains any reserved claim names. If so it will throw an error.
1836
- * @param payload
1837
- * @returns
1838
- */
1839
- validateReservedFields(payload) {
1840
- validateReservedFieldsInternal(payload);
1841
- }
1842
- validateDisclosureFrame(_disclosureFrame) {
1843
- return;
1844
- }
1845
- present(generalJSON, presentationFrame, options) {
1846
- return __async(this, null, function* () {
1847
- var _a;
1848
- if (!this.userConfig.hasher) {
1849
- throw new SDJWTException("Hasher not found");
1850
- }
1851
- const hasher = this.userConfig.hasher;
1852
- const encodedSDJwt = generalJSON.toEncoded(0);
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
- }
1857
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) throw new SDJWTException("Payload not found");
1858
- const disclosures = yield sdjwt.getPresentDisclosures(
1859
- presentationFrame,
1860
- hasher
1861
- );
1862
- const encodedDisclosures = disclosures.map((d) => d.encode());
1863
- const presentedGeneralJSON = new GeneralJSON({
1864
- payload: generalJSON.payload,
1865
- disclosures: encodedDisclosures,
1866
- signatures: generalJSON.signatures
1867
- });
1868
- if (!(options == null ? void 0 : options.kb)) {
1869
- return presentedGeneralJSON;
1870
- }
1871
- const presentSdJwtWithoutKb = yield sdjwt.present(
1872
- presentationFrame,
1873
- hasher
1874
- );
1875
- const sdHashStr = yield this.calculateSDHash(
1876
- presentSdJwtWithoutKb,
1877
- sdjwt,
1878
- hasher
1879
- );
1880
- const kbJwt = yield this.createKBJwt(options.kb, sdHashStr);
1881
- const encodedKbJwt = kbJwt.encodeJwt();
1882
- presentedGeneralJSON.kb_jwt = encodedKbJwt;
1883
- return presentedGeneralJSON;
1884
- });
1885
- }
1886
- // This function is for verifying the SD JWT
1887
- // If requiredClaimKeys is provided, it will check if the required claim keys are presentation in the SD JWT
1888
- // If requireKeyBindings is true, it will check if the key binding JWT is presentation and verify it
1889
- verify(generalJSON, options) {
1890
- return __async(this, null, function* () {
1891
- var _a;
1892
- if (!this.userConfig.hasher) {
1893
- throw new SDJWTException("Hasher not found");
1894
- }
1895
- const hasher = this.userConfig.hasher;
1896
- const { payload, headers } = yield this.validate(generalJSON, options);
1897
- const encodedSDJwt = generalJSON.toEncoded(0);
1898
- const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
1899
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) {
1900
- throw new SDJWTException("Invalid SD JWT");
1901
- }
1902
- if (options == null ? void 0 : options.requiredClaimKeys) {
1903
- const keys = yield sdjwt.keys(hasher);
1904
- const missingKeys = options == null ? void 0 : options.requiredClaimKeys.filter(
1905
- (k) => !keys.includes(k)
1906
- );
1907
- if (missingKeys.length > 0) {
1908
- throw new SDJWTException(
1909
- `Missing required claim keys: ${missingKeys.join(", ")}`
1910
- );
1911
- }
1912
- }
1913
- if (!(options == null ? void 0 : options.keyBindingNonce)) {
1914
- return { payload, headers };
1915
- }
1916
- if (!sdjwt.kbJwt) {
1917
- throw new SDJWTException("Key Binding JWT not exist");
1918
- }
1919
- if (!this.userConfig.kbVerifier) {
1920
- throw new SDJWTException("Key Binding Verifier not found");
1921
- }
1922
- const kb = yield sdjwt.kbJwt.verifyKB({
1923
- verifier: this.userConfig.kbVerifier,
1924
- payload,
1925
- nonce: options.keyBindingNonce,
1926
- options
1927
- });
1928
- if (!kb) {
1929
- throw new Error("signature is not valid");
1930
- }
1931
- const sdHashfromKb = kb.payload.sd_hash;
1932
- const sdjwtWithoutKb = new SDJwt({
1933
- jwt: sdjwt.jwt,
1934
- disclosures: sdjwt.disclosures
1935
- });
1936
- const presentSdJwtWithoutKb = sdjwtWithoutKb.encodeSDJwt();
1937
- const sdHashStr = yield this.calculateSDHash(
1938
- presentSdJwtWithoutKb,
1939
- sdjwt,
1940
- hasher
1941
- );
1942
- if (sdHashStr !== sdHashfromKb) {
1943
- throw new SDJWTException("Invalid sd_hash in Key Binding JWT");
1944
- }
1945
- return { payload, headers, kb };
1946
- });
1947
- }
1948
- calculateSDHash(presentSdJwtWithoutKb, sdjwt, hasher) {
1949
- return __async(this, null, function* () {
1950
- var _a;
1951
- if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload)) {
1952
- throw new SDJWTException("Invalid SD JWT");
1953
- }
1954
- const { _sd_alg } = getSDAlgAndPayload(sdjwt.jwt.payload);
1955
- const sdHash = yield hasher(presentSdJwtWithoutKb, _sd_alg);
1956
- const sdHashStr = (0, import_identity_common.uint8ArrayToBase64Url)(sdHash);
1957
- return sdHashStr;
1958
- });
1959
- }
1960
- // This function is for validating the SD JWT
1961
- // Just checking signature and return its the claims
1962
- validate(generalJSON, options) {
1963
- return __async(this, null, function* () {
1964
- if (!this.userConfig.hasher) {
1965
- throw new SDJWTException("Hasher not found");
1966
- }
1967
- if (!this.userConfig.verifier) {
1968
- throw new SDJWTException("Verifier not found");
1969
- }
1970
- const hasher = this.userConfig.hasher;
1971
- const verifier = this.userConfig.verifier;
1972
- const { payload, signatures } = generalJSON;
1973
- const results = yield Promise.all(
1974
- signatures.map((s) => __async(this, null, function* () {
1975
- const { protected: encodedHeader, signature } = s;
1976
- const verified2 = yield verifier(
1977
- `${encodedHeader}.${payload}`,
1978
- signature,
1979
- __spreadProps(__spreadValues({}, options), { skipJwtClaimValidation: true })
1980
- );
1981
- const header = decodeBase64urlJsonStrict(
1982
- encodedHeader,
1983
- "Invalid JWT"
1984
- );
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
- }
1993
- return { verified: verified2, header };
1994
- }))
1995
- );
1996
- const verified = results.every((r) => r.verified);
1997
- if (!verified) {
1998
- throw new SDJWTException("Signature is not valid");
1999
- }
2000
- const encodedSDJwt = generalJSON.toEncoded(0);
2001
- const sdjwt = yield SDJwt.fromEncode(encodedSDJwt, hasher);
2002
- if (!sdjwt.jwt) {
2003
- throw new SDJWTException("Invalid SD JWT");
2004
- }
2005
- const claims = yield sdjwt.getClaims(hasher);
2006
- validateReservedFieldsInternal(claims);
2007
- validateJwtPayload(claims, options);
2008
- return { payload: claims, headers: results.map((r) => r.header) };
2009
- });
2010
- }
2011
- config(newConfig) {
2012
- this.userConfig = __spreadValues(__spreadValues({}, this.userConfig), newConfig);
2013
- }
2014
- encode(sdJwt, index) {
2015
- return sdJwt.toEncoded(index);
2016
- }
2017
- decode(endcodedSDJwt) {
2018
- return GeneralJSON.fromEncode(endcodedSDJwt);
2019
- }
2020
- keys(generalSdjwt) {
2021
- return __async(this, null, function* () {
2022
- if (!this.userConfig.hasher) {
2023
- throw new SDJWTException("Hasher not found");
2024
- }
2025
- const endcodedSDJwt = generalSdjwt.toEncoded(0);
2026
- const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
2027
- return sdjwt.keys(this.userConfig.hasher);
2028
- });
2029
- }
2030
- presentableKeys(generalSdjwt) {
2031
- return __async(this, null, function* () {
2032
- if (!this.userConfig.hasher) {
2033
- throw new SDJWTException("Hasher not found");
2034
- }
2035
- const endcodedSDJwt = generalSdjwt.toEncoded(0);
2036
- const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
2037
- return sdjwt.presentableKeys(this.userConfig.hasher);
2038
- });
2039
- }
2040
- getClaims(generalSdjwt) {
2041
- return __async(this, null, function* () {
2042
- if (!this.userConfig.hasher) {
2043
- throw new SDJWTException("Hasher not found");
2044
- }
2045
- const endcodedSDJwt = generalSdjwt.toEncoded(0);
2046
- const sdjwt = yield SDJwt.fromEncode(endcodedSDJwt, this.userConfig.hasher);
2047
- return sdjwt.getClaims(this.userConfig.hasher);
2048
- });
2049
- }
2050
- };
2051
- SDJwtGeneralJSONInstance.DEFAULT_hashAlg = "sha-256";
2052
- // Annotate the CommonJS export names for ESM import in node:
2053
- 0 && (module.exports = {
2054
- DEFAULT_SECURE_HASH_ALGORITHMS,
2055
- Disclosure,
2056
- FlattenJSON,
2057
- GeneralJSON,
2058
- IANA_HASH_ALGORITHMS,
2059
- Jwt,
2060
- KBJwt,
2061
- KB_JWT_TYP,
2062
- SDJWTException,
2063
- SDJwt,
2064
- SDJwtGeneralJSONInstance,
2065
- SDJwtInstance,
2066
- SD_DECOY,
2067
- SD_DIGEST,
2068
- SD_LIST_KEY,
2069
- SD_SEPARATOR,
2070
- base64UrlToUint8Array,
2071
- base64urlDecode,
2072
- base64urlEncode,
2073
- createDecoy,
2074
- createHashMapping,
2075
- createHashMappingForSerializedDisclosure,
2076
- createHashMappingSync,
2077
- decodeJwt,
2078
- decodeSdJwt,
2079
- decodeSdJwtSync,
2080
- encodePath,
2081
- encodePathSegment,
2082
- ensureError,
2083
- getClaims,
2084
- getClaimsSync,
2085
- getSDAlgAndPayload,
2086
- listKeys,
2087
- pack,
2088
- present,
2089
- presentSync,
2090
- presentableKeys,
2091
- presentableKeysSync,
2092
- selectDisclosures,
2093
- splitSdJwt,
2094
- transformPresentationFrame,
2095
- uint8ArrayToBase64Url,
2096
- unpack,
2097
- unpackObj,
2098
- unpackSync,
2099
- validateJwtPayload
2100
- });