@sd-jwt/core 0.2.1-alpha.0 → 0.2.1

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 (40) hide show
  1. package/build/base64url.d.ts +28 -0
  2. package/build/base64url.js +40 -0
  3. package/build/base64url.js.map +1 -0
  4. package/build/hasherAlgorithm.d.ts +70 -0
  5. package/build/hasherAlgorithm.js +75 -0
  6. package/build/hasherAlgorithm.js.map +1 -0
  7. package/build/jwt/compact.d.ts +6 -0
  8. package/build/jwt/compact.js +27 -0
  9. package/build/jwt/compact.js.map +1 -0
  10. package/build/sdJwt/compact.d.ts +8 -0
  11. package/build/sdJwt/compact.js +39 -0
  12. package/build/sdJwt/compact.js.map +1 -0
  13. package/build/sdJwt/disclosureMapping.d.ts +43 -0
  14. package/build/sdJwt/disclosureMapping.js +278 -0
  15. package/build/sdJwt/disclosureMapping.js.map +1 -0
  16. package/build/sdJwt/presentationFrame.d.ts +3 -0
  17. package/build/sdJwt/presentationFrame.js +64 -0
  18. package/build/sdJwt/presentationFrame.js.map +1 -0
  19. package/build/sdJwt/swapClaim.d.ts +2 -0
  20. package/build/sdJwt/swapClaim.js +79 -0
  21. package/build/sdJwt/swapClaim.js.map +1 -0
  22. package/build/types/frame.d.ts +5 -0
  23. package/build/types/frame.js +3 -0
  24. package/build/types/frame.js.map +1 -0
  25. package/build/types/hasher.d.ts +14 -0
  26. package/build/types/hasher.js +3 -0
  27. package/build/types/hasher.js.map +1 -0
  28. package/build/types/present.d.ts +2 -0
  29. package/build/types/present.js +3 -0
  30. package/build/types/present.js.map +1 -0
  31. package/build/utils/index.d.ts +2 -0
  32. package/build/utils/index.js +19 -0
  33. package/build/utils/index.js.map +1 -0
  34. package/build/utils/traverse.d.ts +8 -0
  35. package/build/utils/traverse.js +29 -0
  36. package/build/utils/traverse.js.map +1 -0
  37. package/build/utils/utils.d.ts +8 -0
  38. package/build/utils/utils.js +118 -0
  39. package/build/utils/utils.js.map +1 -0
  40. package/package.json +6 -6
@@ -0,0 +1,28 @@
1
+ /// <reference types="node" />
2
+ import { Buffer } from 'buffer';
3
+ export declare class Base64url {
4
+ /**
5
+ *
6
+ * Encode into base64url string
7
+ *
8
+ */
9
+ static encode(input: string | Uint8Array | Buffer): string;
10
+ /**
11
+ *
12
+ * Encode from JSON into a base64url string
13
+ *
14
+ */
15
+ static encodeFromJson(input: Record<string, unknown> | Array<unknown>): string;
16
+ /**
17
+ *
18
+ * Decode from base64url into JSON
19
+ *
20
+ */
21
+ static decodeToJson<T extends Record<string, unknown> | Array<unknown> = Record<string, unknown>>(input: string): T;
22
+ /**
23
+ *
24
+ * Decode from base64url into a byte array
25
+ *
26
+ */
27
+ static decode(input: string): Uint8Array;
28
+ }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Base64url = void 0;
4
+ const buffer_1 = require("buffer");
5
+ class Base64url {
6
+ /**
7
+ *
8
+ * Encode into base64url string
9
+ *
10
+ */
11
+ static encode(input) {
12
+ return buffer_1.Buffer.from(input).toString('base64url');
13
+ }
14
+ /**
15
+ *
16
+ * Encode from JSON into a base64url string
17
+ *
18
+ */
19
+ static encodeFromJson(input) {
20
+ return buffer_1.Buffer.from(JSON.stringify(input)).toString('base64url');
21
+ }
22
+ /**
23
+ *
24
+ * Decode from base64url into JSON
25
+ *
26
+ */
27
+ static decodeToJson(input) {
28
+ return JSON.parse(buffer_1.Buffer.from(input, 'base64url').toString());
29
+ }
30
+ /**
31
+ *
32
+ * Decode from base64url into a byte array
33
+ *
34
+ */
35
+ static decode(input) {
36
+ return Uint8Array.from(buffer_1.Buffer.from(input, 'base64url'));
37
+ }
38
+ }
39
+ exports.Base64url = Base64url;
40
+ //# sourceMappingURL=base64url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base64url.js","sourceRoot":"","sources":["../src/base64url.ts"],"names":[],"mappings":";;;AAAA,mCAA+B;AAE/B,MAAa,SAAS;IAClB;;;;OAIG;IACI,MAAM,CAAC,MAAM,CAAC,KAAmC;QACpD,OAAO,eAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IACnD,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,cAAc,CACxB,KAA+C;QAE/C,OAAO,eAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;IACnE,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,YAAY,CAKxB,KAAa;QACX,OAAO,IAAI,CAAC,KAAK,CAAC,eAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAM,CAAA;IACtE,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,MAAM,CAAC,KAAa;QAC9B,OAAO,UAAU,CAAC,IAAI,CAAC,eAAM,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;IAC3D,CAAC;CACJ;AA3CD,8BA2CC"}
@@ -0,0 +1,70 @@
1
+ export declare enum HasherAlgorithm {
2
+ /**
3
+ * Sha-256: 256 bits. [RFC6920] (current)
4
+ */
5
+ Sha256 = "sha-256",
6
+ /**
7
+ * Sha-256-128: 128 bits. [RFC6920] (current)
8
+ */
9
+ Sha256_128 = "sha-256-128",
10
+ /**
11
+ * Sha-256-120: 120 bits. [RFC6920] (current)
12
+ */
13
+ Sha256_120 = "sha-256-120",
14
+ /**
15
+ * Sha-256-96: 96 bits. [RFC6920] (current)
16
+ */
17
+ Sha256_96 = "sha-256-96",
18
+ /**
19
+ * Sha-256-64: 64 bits. [RFC6920] (current)
20
+ */
21
+ Sha256_64 = "sha-256-64",
22
+ /**
23
+ * Sha-256-32: 32 bits. [RFC6920] (current)
24
+ */
25
+ Sha256_32 = "sha-256-32",
26
+ /**
27
+ * Sha-384: 384 bits. [FIPS 180-4] (current)
28
+ */
29
+ Sha384 = "sha-384",
30
+ /**
31
+ * Sha-512: 512 bits. [FIPS 180-4] (current)
32
+ */
33
+ Sha512 = "sha-512",
34
+ /**
35
+ * Sha3-224: 224 bits. [FIPS 202] (current)
36
+ */
37
+ Sha3_224 = "sha3-224",
38
+ /**
39
+ * Sha3-256: 256 bits. [FIPS 202] (current)
40
+ */
41
+ Sha3_256 = "sha3-256",
42
+ /**
43
+ * Sha3-384: 384 bits. [FIPS 202] (current)
44
+ */
45
+ Sha3_384 = "sha3-384",
46
+ /**
47
+ * Sha3-512: 512 bits. [FIPS 202] (current)
48
+ */
49
+ Sha3_512 = "sha3-512",
50
+ /**
51
+ * Blake2s-256: 256 bits. [RFC7693] (current)
52
+ */
53
+ Blake2s_256 = "blake2s-256",
54
+ /**
55
+ * Blake2b-256: 256 bits. [RFC7693] (current)
56
+ */
57
+ Blake2b_256 = "blake2b-256",
58
+ /**
59
+ * Blake2b-512: 512 bits. [RFC7693] (current)
60
+ */
61
+ Blake2b_512 = "blake2b-512",
62
+ /**
63
+ * K12-256: 256 bits. [draft-irtf-cfrg-kangarootwelve-06] (current)
64
+ */
65
+ K12_256 = "k12-256",
66
+ /**
67
+ * K12-512: 512 bits. [draft-irtf-cfrg-kangarootwelve-06] (current)
68
+ */
69
+ K12_512 = "k12-512"
70
+ }
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HasherAlgorithm = void 0;
4
+ var HasherAlgorithm;
5
+ (function (HasherAlgorithm) {
6
+ /**
7
+ * Sha-256: 256 bits. [RFC6920] (current)
8
+ */
9
+ HasherAlgorithm["Sha256"] = "sha-256";
10
+ /**
11
+ * Sha-256-128: 128 bits. [RFC6920] (current)
12
+ */
13
+ HasherAlgorithm["Sha256_128"] = "sha-256-128";
14
+ /**
15
+ * Sha-256-120: 120 bits. [RFC6920] (current)
16
+ */
17
+ HasherAlgorithm["Sha256_120"] = "sha-256-120";
18
+ /**
19
+ * Sha-256-96: 96 bits. [RFC6920] (current)
20
+ */
21
+ HasherAlgorithm["Sha256_96"] = "sha-256-96";
22
+ /**
23
+ * Sha-256-64: 64 bits. [RFC6920] (current)
24
+ */
25
+ HasherAlgorithm["Sha256_64"] = "sha-256-64";
26
+ /**
27
+ * Sha-256-32: 32 bits. [RFC6920] (current)
28
+ */
29
+ HasherAlgorithm["Sha256_32"] = "sha-256-32";
30
+ /**
31
+ * Sha-384: 384 bits. [FIPS 180-4] (current)
32
+ */
33
+ HasherAlgorithm["Sha384"] = "sha-384";
34
+ /**
35
+ * Sha-512: 512 bits. [FIPS 180-4] (current)
36
+ */
37
+ HasherAlgorithm["Sha512"] = "sha-512";
38
+ /**
39
+ * Sha3-224: 224 bits. [FIPS 202] (current)
40
+ */
41
+ HasherAlgorithm["Sha3_224"] = "sha3-224";
42
+ /**
43
+ * Sha3-256: 256 bits. [FIPS 202] (current)
44
+ */
45
+ HasherAlgorithm["Sha3_256"] = "sha3-256";
46
+ /**
47
+ * Sha3-384: 384 bits. [FIPS 202] (current)
48
+ */
49
+ HasherAlgorithm["Sha3_384"] = "sha3-384";
50
+ /**
51
+ * Sha3-512: 512 bits. [FIPS 202] (current)
52
+ */
53
+ HasherAlgorithm["Sha3_512"] = "sha3-512";
54
+ /**
55
+ * Blake2s-256: 256 bits. [RFC7693] (current)
56
+ */
57
+ HasherAlgorithm["Blake2s_256"] = "blake2s-256";
58
+ /**
59
+ * Blake2b-256: 256 bits. [RFC7693] (current)
60
+ */
61
+ HasherAlgorithm["Blake2b_256"] = "blake2b-256";
62
+ /**
63
+ * Blake2b-512: 512 bits. [RFC7693] (current)
64
+ */
65
+ HasherAlgorithm["Blake2b_512"] = "blake2b-512";
66
+ /**
67
+ * K12-256: 256 bits. [draft-irtf-cfrg-kangarootwelve-06] (current)
68
+ */
69
+ HasherAlgorithm["K12_256"] = "k12-256";
70
+ /**
71
+ * K12-512: 512 bits. [draft-irtf-cfrg-kangarootwelve-06] (current)
72
+ */
73
+ HasherAlgorithm["K12_512"] = "k12-512";
74
+ })(HasherAlgorithm || (exports.HasherAlgorithm = HasherAlgorithm = {}));
75
+ //# sourceMappingURL=hasherAlgorithm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasherAlgorithm.js","sourceRoot":"","sources":["../src/hasherAlgorithm.ts"],"names":[],"mappings":";;;AAAA,IAAY,eAqEX;AArED,WAAY,eAAe;IACvB;;OAEG;IACH,qCAAkB,CAAA;IAClB;;OAEG;IACH,6CAA0B,CAAA;IAC1B;;OAEG;IACH,6CAA0B,CAAA;IAC1B;;OAEG;IACH,2CAAwB,CAAA;IACxB;;OAEG;IACH,2CAAwB,CAAA;IACxB;;OAEG;IACH,2CAAwB,CAAA;IACxB;;OAEG;IACH,qCAAkB,CAAA;IAClB;;OAEG;IACH,qCAAkB,CAAA;IAClB;;OAEG;IACH,wCAAqB,CAAA;IACrB;;OAEG;IACH,wCAAqB,CAAA;IACrB;;OAEG;IACH,wCAAqB,CAAA;IACrB;;OAEG;IACH,wCAAqB,CAAA;IACrB;;OAEG;IACH,8CAA2B,CAAA;IAC3B;;OAEG;IACH,8CAA2B,CAAA;IAC3B;;OAEG;IACH,8CAA2B,CAAA;IAC3B;;OAEG;IACH,sCAAmB,CAAA;IACnB;;OAEG;IACH,sCAAmB,CAAA;AACvB,CAAC,EArEW,eAAe,+BAAf,eAAe,QAqE1B"}
@@ -0,0 +1,6 @@
1
+ export type ExpandedJwt<H extends Record<string, unknown> = Record<string, unknown>, P extends Record<string, unknown> = Record<string, unknown>> = {
2
+ header: H;
3
+ payload: P;
4
+ signature: Uint8Array;
5
+ };
6
+ export declare const jwtFromCompact: <H extends Record<string, unknown> = Record<string, unknown>, P extends Record<string, unknown> = Record<string, unknown>>(compact: string) => ExpandedJwt<H, P>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jwtFromCompact = void 0;
4
+ const base64url_1 = require("../base64url");
5
+ const error_1 = require("./error");
6
+ const jwtFromCompact = (compact) => {
7
+ if (compact.includes('~')) {
8
+ throw new error_1.JwtError('compact JWT includes `~` which is only allowed in an sd-jwt. Please use sdJwtFromCompact() instead.');
9
+ }
10
+ if ((compact.match(/\./g) || []).length !== 2) {
11
+ throw new error_1.JwtError('compact JWT must include two periods (.)');
12
+ }
13
+ const [compactHeader, compactPayload, encodedSignature] = compact.split('.');
14
+ if (!encodedSignature || encodedSignature.length === 0) {
15
+ throw new error_1.JwtError('A signature must be provided within the context of sd-jwt');
16
+ }
17
+ const header = base64url_1.Base64url.decodeToJson(compactHeader);
18
+ const payload = base64url_1.Base64url.decodeToJson(compactPayload);
19
+ const signature = base64url_1.Base64url.decode(encodedSignature);
20
+ return {
21
+ header,
22
+ payload,
23
+ signature
24
+ };
25
+ };
26
+ exports.jwtFromCompact = jwtFromCompact;
27
+ //# sourceMappingURL=compact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.js","sourceRoot":"","sources":["../../src/jwt/compact.ts"],"names":[],"mappings":";;;AAAA,4CAAwC;AACxC,mCAAkC;AAW3B,MAAM,cAAc,GAAG,CAI1B,OAAe,EACE,EAAE;IACnB,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,gBAAQ,CACd,qGAAqG,CACxG,CAAA;IACL,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,gBAAQ,CAAC,0CAA0C,CAAC,CAAA;IAClE,CAAC;IAED,MAAM,CAAC,aAAa,EAAE,cAAc,EAAE,gBAAgB,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAE5E,IAAI,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,gBAAQ,CACd,2DAA2D,CAC9D,CAAA;IACL,CAAC;IAED,MAAM,MAAM,GAAG,qBAAS,CAAC,YAAY,CAAI,aAAa,CAAC,CAAA;IACvD,MAAM,OAAO,GAAG,qBAAS,CAAC,YAAY,CAAI,cAAc,CAAC,CAAA;IACzD,MAAM,SAAS,GAAG,qBAAS,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IAEpD,OAAO;QACH,MAAM;QACN,OAAO;QACP,SAAS;KACZ,CAAA;AACL,CAAC,CAAA;AAjCY,QAAA,cAAc,kBAiC1B"}
@@ -0,0 +1,8 @@
1
+ import { KeyBinding } from '../keyBinding';
2
+ import { Disclosure } from './disclosures';
3
+ import { ExpandedJwt } from '../jwt';
4
+ export type ExpandedSdJwt<H extends Record<string, unknown> = Record<string, unknown>, P extends Record<string, unknown> = Record<string, unknown>> = ExpandedJwt<H, P> & {
5
+ disclosures?: Array<Disclosure>;
6
+ keyBinding?: KeyBinding;
7
+ };
8
+ export declare const sdJwtFromCompact: <H extends Record<string, unknown> = Record<string, unknown>, P extends Record<string, unknown> = Record<string, unknown>>(compact: string) => any;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sdJwtFromCompact = void 0;
4
+ const keyBinding_1 = require("../keyBinding");
5
+ const disclosures_1 = require("./disclosures");
6
+ const jwt_1 = require("../jwt");
7
+ const sdJwtFromCompact = (compact) => {
8
+ const [jwtWithoutDisclosures, ...encodedDisclosures] = compact.split('~');
9
+ const { header, payload, signature } = (0, jwt_1.jwtFromCompact)(jwtWithoutDisclosures);
10
+ if (encodedDisclosures.length === 0) {
11
+ return {
12
+ header,
13
+ payload,
14
+ signature
15
+ };
16
+ }
17
+ const hasKeyBinding = !compact.endsWith('~');
18
+ // If the disclosure array ends with an `~` we do not have
19
+ // a key binding and `String.split` takes it as an empty string
20
+ // as element which we would not like to include in the disclosures.
21
+ if (!hasKeyBinding)
22
+ encodedDisclosures.pop();
23
+ const compactKeyBinding = hasKeyBinding
24
+ ? encodedDisclosures.pop()
25
+ : undefined;
26
+ const keyBinding = compactKeyBinding
27
+ ? keyBinding_1.KeyBinding.fromCompact(compactKeyBinding)
28
+ : undefined;
29
+ const disclosures = encodedDisclosures.map(disclosures_1.Disclosure.fromString);
30
+ return {
31
+ header,
32
+ payload,
33
+ signature,
34
+ keyBinding,
35
+ disclosures
36
+ };
37
+ };
38
+ exports.sdJwtFromCompact = sdJwtFromCompact;
39
+ //# sourceMappingURL=compact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compact.js","sourceRoot":"","sources":["../../src/sdJwt/compact.ts"],"names":[],"mappings":";;;AAAA,8CAA0C;AAC1C,+CAA0C;AAC1C,gCAAoD;AAU7C,MAAM,gBAAgB,GAAG,CAI5B,OAAe,EACI,EAAE;IACrB,MAAM,CAAC,qBAAqB,EAAE,GAAG,kBAAkB,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEzE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAA,oBAAc,EACjD,qBAAqB,CACxB,CAAA;IAED,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO;YACH,MAAM;YACN,OAAO;YACP,SAAS;SACZ,CAAA;IACL,CAAC;IAED,MAAM,aAAa,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;IAE5C,0DAA0D;IAC1D,+DAA+D;IAC/D,oEAAoE;IACpE,IAAI,CAAC,aAAa;QAAE,kBAAkB,CAAC,GAAG,EAAE,CAAA;IAE5C,MAAM,iBAAiB,GAAG,aAAa;QACnC,CAAC,CAAC,kBAAkB,CAAC,GAAG,EAAE;QAC1B,CAAC,CAAC,SAAS,CAAA;IAEf,MAAM,UAAU,GAAG,iBAAiB;QAChC,CAAC,CAAC,uBAAU,CAAC,WAAW,CAAC,iBAAiB,CAAC;QAC3C,CAAC,CAAC,SAAS,CAAA;IAEf,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,wBAAU,CAAC,UAAU,CAAC,CAAA;IAEjE,OAAO;QACH,MAAM;QACN,OAAO;QACP,SAAS;QACT,UAAU;QACV,WAAW;KACd,CAAA;AACL,CAAC,CAAA;AA5CY,QAAA,gBAAgB,oBA4C5B"}
@@ -0,0 +1,43 @@
1
+ import { DisclosureWithDigest } from './disclosures';
2
+ /**
3
+ * Mapping from a digest to the corresponding disclosure and its parent disclosures.
4
+ */
5
+ export type DisclosureMap = {
6
+ [digest: string]: {
7
+ disclosure: DisclosureWithDigest;
8
+ parentDisclosures: DisclosureWithDigest[];
9
+ };
10
+ };
11
+ /**
12
+ * Get a mapping in the structure of the pretty payload, to indicate which digests should be disclosed for a
13
+ * given entry.
14
+ *
15
+ * For example if you call this method with the following payload:
16
+ * ```ts
17
+ * {
18
+ * _sd: ['iss_digest', 'nested_field_digest'],
19
+ * }
20
+ * ```
21
+ *
22
+ * It can return the following mapping:
23
+ * ```ts
24
+ * {
25
+ * iss: 'iss_digest',
26
+ * nested_field: {
27
+ * __digest: 'nested_field_digest',
28
+ * more_nested_field: {
29
+ * // index 1 is null, as it's always in the payload, so doesn't need to be disclosed
30
+ * // separately
31
+ * a: ['a_0_digest', null, 'a_2_digest'],
32
+ * }
33
+ * }
34
+ * }
35
+ * ```
36
+ *
37
+ * This method will recursively call itself and `getArrayPayloadDisclosureMapping` if the value of a property is an object or array.
38
+ */
39
+ export declare function getPayloadDisclosureMapping(payload: any, map: DisclosureMap): any[] | Record<string, unknown> | null;
40
+ /**
41
+ * Get a mapping from a digest to the corresponding disclosure and its parent disclosures.
42
+ */
43
+ export declare const getDisclosureMap: (disclosures: DisclosureWithDigest[]) => DisclosureMap;
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ // This file contains helpers functions for mapping between disclosures entries and the payload of an SD-JWT.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.getDisclosureMap = exports.getPayloadDisclosureMapping = void 0;
5
+ const utils_1 = require("../utils");
6
+ const error_1 = require("./error");
7
+ /**
8
+ * Returns an array that includes the digests that should be disclosed for each item in the array.
9
+ *
10
+ * E.g. if the following array is passed:
11
+ * ```ts
12
+ * [ { '...': <SD_HASH_DIGEST_1> }, 'string_value', { '...': <SD_HASH_DIGEST_2> } ]
13
+ * ```
14
+ *
15
+ * The return value will be:
16
+ * ```ts
17
+ * ['<SD_HASH_DIGEST_1>', null, '<SD_HASH_DIGEST_2>']
18
+ * ```
19
+ *
20
+ * The second value will be null, as it's already disclosed, and thus there's no digests that
21
+ * need to be disclosed to reveal it. For the other values, it will include the digest that needs
22
+ * to be disclosed to reveal that array entry.
23
+ *
24
+ * In the case the array entry contains nested disclosures, the value will not be a digest, but rather
25
+ * the structure of the nested disclosures.
26
+ *
27
+ * Let's say the `<SD_HASH_DIGEST_1>` is the digest of the following disclosure:
28
+ * ```ts
29
+ * {
30
+ * // `<SD_HASH_DIGEST_3>` is the digest of the dateOfBirth property
31
+ * _sd: ['<SD_HASH_DIGEST_3>'],
32
+ * name: 'Jane Doe',
33
+ * }
34
+ * ```
35
+ *
36
+ * In this case the return value will be:
37
+ * ```ts
38
+ * [{ __digest: '<SD_HASH_DIGEST_1>', dateOfBirth: '<SD_HASH_DIGEST_3>' }, null, '<SD_HASH_DIGEST_2>']
39
+ * ```
40
+ * The `__digest` property indicates the digest of the encapsulating disclosure, and it being an object
41
+ * indicates that there's nested disclosures that need to be revealed.
42
+ *
43
+ * In the end the result value is an array, and all the string values in the return value are the digests.
44
+ * This allows you to easily build a path of digests to disclose to reveal a certain value.
45
+ *
46
+ * The return value can be endlessly nested, and will also call `getPayloadDisclosureMapping` recursively
47
+ * if the inner values are not arrays, but objects. That method in turn can call this method if the value
48
+ * of an object property is an array.
49
+ */
50
+ function getArrayPayloadDisclosureMapping(array, map) {
51
+ const arrayPayloadDisclosureMapping = [];
52
+ // Loop through all the payload values of the array
53
+ for (const item of array) {
54
+ // If the item is an object, (both array and object are objects)
55
+ // it means there may be some values in here that need to be disclosed to
56
+ // reveal this array entry
57
+ if (item instanceof Object) {
58
+ // if Array item is { '...': <SD_HASH_DIGEST> }
59
+ // It means this item can be disclosed.
60
+ if ('...' in item) {
61
+ const digest = item['...'];
62
+ if (typeof digest !== 'string') {
63
+ throw new error_1.SdJwtError(`Expected value of key '...' to be of type string, but found ${typeof digest}`);
64
+ }
65
+ // Look up disclosure. It's valid that the disclosure is not present (decoy digests)
66
+ const disclosed = map[digest];
67
+ if (disclosed) {
68
+ // value is always the last item in the disclosure array
69
+ const value = [...disclosed.disclosure.decoded].pop();
70
+ // Recursively look if the disclosed value contains any disclosure references
71
+ // of itself. Based on the type we can decide how to handle it.
72
+ if ((0, utils_1.isObject)(value)) {
73
+ // Get nested disclosures for the object value
74
+ const unpacked = getPayloadDisclosureMapping(value, map);
75
+ // If there's any nested disclosures, we need to include both this item's
76
+ // disclosure, as well as the nested disclosures
77
+ if (unpacked && Object.keys(unpacked).length > 0) {
78
+ arrayPayloadDisclosureMapping.push(Object.assign(Object.assign({}, unpacked), { __digest: digest }));
79
+ }
80
+ else {
81
+ arrayPayloadDisclosureMapping.push(digest);
82
+ }
83
+ }
84
+ else if (Array.isArray(value)) {
85
+ // Get nested disclosures for the array value
86
+ const nestedUnpackedArray = getArrayPayloadDisclosureMapping(value, map);
87
+ // If all entries are null, it means there's no nested disclosures
88
+ // And thus we push the digest directly
89
+ if (nestedUnpackedArray.every((item) => item === null)) {
90
+ arrayPayloadDisclosureMapping.push(digest);
91
+ }
92
+ else {
93
+ arrayPayloadDisclosureMapping.push(Object.assign(Object.assign({}, nestedUnpackedArray), {
94
+ // __digest is for encapsulating disclosure
95
+ __digest: digest }));
96
+ }
97
+ }
98
+ // If the value is not an object or a array, it means there's no nested disclosures
99
+ // and thus we can push the digest directly
100
+ else {
101
+ arrayPayloadDisclosureMapping.push(digest);
102
+ }
103
+ }
104
+ else {
105
+ // Value is not a disclosure for an array ('...') so we unpack the object recursively
106
+ const claims = getPayloadDisclosureMapping(item, map);
107
+ if (claims && Object.keys(claims).length > 0) {
108
+ arrayPayloadDisclosureMapping.push(claims);
109
+ }
110
+ else {
111
+ arrayPayloadDisclosureMapping.push(null);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ // If the value is not an Object it means the actual value is disclosed
117
+ // in the array directly (so we don't need to disclose anything to reveal it)
118
+ else {
119
+ arrayPayloadDisclosureMapping.push(null);
120
+ }
121
+ }
122
+ return arrayPayloadDisclosureMapping;
123
+ }
124
+ /**
125
+ * Get a mapping in the structure of the pretty payload, to indicate which digests should be disclosed for a
126
+ * given entry.
127
+ *
128
+ * For example if you call this method with the following payload:
129
+ * ```ts
130
+ * {
131
+ * _sd: ['iss_digest', 'nested_field_digest'],
132
+ * }
133
+ * ```
134
+ *
135
+ * It can return the following mapping:
136
+ * ```ts
137
+ * {
138
+ * iss: 'iss_digest',
139
+ * nested_field: {
140
+ * __digest: 'nested_field_digest',
141
+ * more_nested_field: {
142
+ * // index 1 is null, as it's always in the payload, so doesn't need to be disclosed
143
+ * // separately
144
+ * a: ['a_0_digest', null, 'a_2_digest'],
145
+ * }
146
+ * }
147
+ * }
148
+ * ```
149
+ *
150
+ * This method will recursively call itself and `getArrayPayloadDisclosureMapping` if the value of a property is an object or array.
151
+ */
152
+ function getPayloadDisclosureMapping(payload, map) {
153
+ // Handle array
154
+ if (payload instanceof Array) {
155
+ return getArrayPayloadDisclosureMapping(payload, map);
156
+ }
157
+ // Not an array or object, so it means the top-level value is already disclosed
158
+ if (!(0, utils_1.isObject)(payload)) {
159
+ return null;
160
+ }
161
+ const payloadDisclosureMapping = {};
162
+ for (const key in payload) {
163
+ // if obj property value is an object or array
164
+ // recursively unpack
165
+ if (key !== '_sd' && key !== '...' && payload[key] instanceof Object) {
166
+ const claim = getPayloadDisclosureMapping(payload[key], map);
167
+ if (claim && Object.keys(claim).length > 0) {
168
+ payloadDisclosureMapping[key] = claim;
169
+ }
170
+ }
171
+ }
172
+ // If the payload contains a _sd property, it means there's disclosures
173
+ if (payload._sd) {
174
+ if (!Array.isArray(payload._sd)) {
175
+ throw new error_1.SdJwtError(`Expect value of '_sd' to be of type array, but found ${typeof payload._sd}`);
176
+ }
177
+ // We are going to resolve all digests
178
+ for (const digest of payload._sd) {
179
+ if (typeof digest !== 'string') {
180
+ throw new error_1.SdJwtError(`Expected entries in '_sd' property to be of type string, found ${typeof digest}`);
181
+ }
182
+ // Look up disclosure. It's valid that the disclosure is not present (decoy digests)
183
+ const disclosed = map[digest];
184
+ if (disclosed) {
185
+ // value is always the last item in the disclosure array
186
+ // We know this is an object, so the associated disclosure MUST have length 3
187
+ const value = [...disclosed.disclosure.decoded].pop();
188
+ if (disclosed.disclosure.decoded.length !== 3) {
189
+ throw new error_1.SdJwtError(`Expected disclosure for value ${value} to have 3 items, but found ${disclosed.disclosure.decoded.length}`);
190
+ }
191
+ const key = disclosed.disclosure.decoded[1];
192
+ // This checks if there's a nested disclosure anywhere down the tree
193
+ // So when a disclosure value is an object or array, it can contain disclosures
194
+ // of itself (using `_sd` and `...` keys)
195
+ if ((0, utils_1.isObject)(value)) {
196
+ const unpacked = getPayloadDisclosureMapping(value, map);
197
+ if (unpacked && Object.keys(unpacked).length > 0) {
198
+ payloadDisclosureMapping[key] = Object.assign(Object.assign({}, unpacked), { __digest: digest });
199
+ }
200
+ // If there's no nested disclosures, we add the digest directly
201
+ else {
202
+ payloadDisclosureMapping[key] = digest;
203
+ }
204
+ }
205
+ else if (Array.isArray(value)) {
206
+ // Get nested disclosures for the array value
207
+ const nestedUnpackedArray = getArrayPayloadDisclosureMapping(value, map);
208
+ // If all entries are null, it means there's no nested disclosures
209
+ // And thus we push the digest directly
210
+ if (nestedUnpackedArray.every((item) => item === null)) {
211
+ payloadDisclosureMapping[key] = digest;
212
+ }
213
+ else {
214
+ payloadDisclosureMapping[key] = Object.assign(Object.assign({}, nestedUnpackedArray), {
215
+ // __digest is for encapsulating disclosure
216
+ __digest: digest });
217
+ }
218
+ }
219
+ else {
220
+ payloadDisclosureMapping[key] = digest;
221
+ }
222
+ }
223
+ }
224
+ }
225
+ return payloadDisclosureMapping;
226
+ }
227
+ exports.getPayloadDisclosureMapping = getPayloadDisclosureMapping;
228
+ const getParentDisclosure = (disclosure, digestMap) => {
229
+ const parent = digestMap[disclosure.digest];
230
+ if (!parent) {
231
+ return [];
232
+ }
233
+ if (digestMap[disclosure.digest]) {
234
+ return [parent].concat(getParentDisclosure(parent, digestMap));
235
+ }
236
+ return [parent];
237
+ };
238
+ /**
239
+ * Get a mapping from a digest to the corresponding disclosure and its parent disclosures.
240
+ */
241
+ const getDisclosureMap = (disclosures) => {
242
+ const map = {};
243
+ const parentMap = {};
244
+ for (const disclosure of disclosures) {
245
+ // value is always the last item in the disclosure array
246
+ const value = [...disclosure.decoded].pop();
247
+ (0, utils_1.traverseNodes)(value).forEach(({ path, value }) => {
248
+ const lastPathItem = path[path.length - 1];
249
+ if (lastPathItem === '_sd') {
250
+ if (!Array.isArray(value)) {
251
+ throw new error_1.SdJwtError(`Expect value of '_sd' to be of type array, but found ${typeof value}`);
252
+ }
253
+ value.forEach((digest) => {
254
+ if (typeof digest !== 'string') {
255
+ throw new error_1.SdJwtError(`Expected entries in '_sd' property to be of type string, found ${typeof digest}`);
256
+ }
257
+ parentMap[digest] = disclosure;
258
+ });
259
+ }
260
+ else if (lastPathItem === '...') {
261
+ if (typeof value !== 'string') {
262
+ throw new error_1.SdJwtError(`Expected value of '...' to be of type string, but found ${typeof value}`);
263
+ }
264
+ parentMap[value] = disclosure;
265
+ }
266
+ });
267
+ }
268
+ for (const disclosure of disclosures) {
269
+ const parent = getParentDisclosure(disclosure, parentMap);
270
+ map[disclosure.digest] = {
271
+ disclosure,
272
+ parentDisclosures: parent
273
+ };
274
+ }
275
+ return map;
276
+ };
277
+ exports.getDisclosureMap = getDisclosureMap;
278
+ //# sourceMappingURL=disclosureMapping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"disclosureMapping.js","sourceRoot":"","sources":["../../src/sdJwt/disclosureMapping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { DisclosureWithDigest } from './disclosures';
2
+ import { PresentationFrame } from '../types/present';
3
+ export declare const getDisclosuresForPresentationFrame: <Payload extends Record<string, unknown> = Record<string, unknown>>(signedPayload: Payload, presentationFrame: PresentationFrame<Payload>, prettyClaims: Payload, disclosures?: Array<DisclosureWithDigest>) => Array<DisclosureWithDigest>;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDisclosuresForPresentationFrame = void 0;
4
+ const utils_1 = require("../utils");
5
+ const error_1 = require("./error");
6
+ const disclosureMapping_1 = require("./disclosureMapping");
7
+ const getDisclosuresForPresentationFrame = (signedPayload, presentationFrame, prettyClaims, disclosures = []) => {
8
+ const requiredDisclosureDigests = new Set();
9
+ const disclosureMap = (0, disclosureMapping_1.getDisclosureMap)(disclosures);
10
+ const payloadDisclosureMapping = (0, disclosureMapping_1.getPayloadDisclosureMapping)(signedPayload, disclosureMap);
11
+ // No disclosures needed
12
+ if (payloadDisclosureMapping === null) {
13
+ if (disclosures.length > 0) {
14
+ throw new error_1.SdJwtError('Payload disclosure mapping is null, but disclosures are present.');
15
+ }
16
+ return [];
17
+ }
18
+ for (const node of (0, utils_1.traverseNodes)(presentationFrame)) {
19
+ // We only want to process leaf nodes here
20
+ if (!node.isLeaf)
21
+ continue;
22
+ if (typeof node.value !== 'boolean') {
23
+ throw new error_1.SdJwtError(`Expected leaf value in presentation frame to be of type boolean, but found ${typeof node.value}`);
24
+ }
25
+ // If the value is false, it means we don't want to disclose it
26
+ if (node.value === false)
27
+ continue;
28
+ if (!(0, utils_1.hasByPath)(prettyClaims, node.path)) {
29
+ throw new error_1.SdJwtError(`Path ${node.path.join('.')} from presentation frame is not present in pretty SD-JWT payload. The presentation frame may only include properties that are present in the SD-JWT payload.`);
30
+ }
31
+ let path = [...node.path];
32
+ while (!(0, utils_1.hasByPath)(payloadDisclosureMapping, path)) {
33
+ if (path.pop() === undefined)
34
+ break;
35
+ }
36
+ // There are no disclosures on this path, meaning the property is disclosed by default in the signed payload
37
+ if (path.length === 0)
38
+ continue;
39
+ const disclosure = (0, utils_1.getByPath)(payloadDisclosureMapping, path);
40
+ // If disclosure is string, it means it's already the digest
41
+ if (typeof disclosure === 'string')
42
+ requiredDisclosureDigests.add(disclosure);
43
+ // Otherwise we want to get all the child digests as well
44
+ else {
45
+ for (const nestedItem of (0, utils_1.traverseNodes)(disclosure)) {
46
+ if (!nestedItem.isLeaf ||
47
+ typeof nestedItem.value !== 'string') {
48
+ continue;
49
+ }
50
+ requiredDisclosureDigests.add(nestedItem.value);
51
+ }
52
+ }
53
+ }
54
+ for (const disclosureDigest of requiredDisclosureDigests.values()) {
55
+ const disclosure = disclosureMap[disclosureDigest];
56
+ if (!disclosure) {
57
+ throw new Error('disclosure not found');
58
+ }
59
+ disclosure.parentDisclosures.forEach((d) => requiredDisclosureDigests.add(d.digest));
60
+ }
61
+ return Array.from(requiredDisclosureDigests).map((digest) => disclosureMap[digest].disclosure);
62
+ };
63
+ exports.getDisclosuresForPresentationFrame = getDisclosuresForPresentationFrame;
64
+ //# sourceMappingURL=presentationFrame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presentationFrame.js","sourceRoot":"","sources":["../../src/sdJwt/presentationFrame.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { DisclosureWithDigest } from './disclosures';
2
+ export declare const swapClaims: (payload: Record<string, unknown>, disclosures: DisclosureWithDigest[], newPayload?: Record<string, unknown>) => Record<string, unknown>;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.swapClaims = void 0;
4
+ const shouldInsertDisclosure = (key, value, disclosures) => {
5
+ if (key !== '_sd')
6
+ return [];
7
+ if (!Array.isArray(value))
8
+ return [];
9
+ const filteredDisclosures = [];
10
+ for (const d of disclosures) {
11
+ if (value.includes(d.digest)) {
12
+ filteredDisclosures.push(d);
13
+ }
14
+ }
15
+ return filteredDisclosures;
16
+ };
17
+ const shouldIncludeCleartextClaim = (key, value) => key !== '_sd' && key !== '_sd_alg' && typeof value !== 'object';
18
+ const swapClaims = (payload, disclosures, newPayload = {}) => {
19
+ const entries = Object.entries(payload);
20
+ // Loop over de payload
21
+ for (let i = 0; i < entries.length; i++) {
22
+ const [key, value] = entries[i];
23
+ // See whether we have an `_sd` key with an array of disclosures.
24
+ const foundDisclosures = shouldInsertDisclosure(key, value, disclosures);
25
+ // Add the disclosed items to the pretty payload
26
+ foundDisclosures.forEach((d) => {
27
+ const [, disclosureKey, disclosureValue] = d.decoded;
28
+ newPayload[disclosureKey] = disclosureValue;
29
+ });
30
+ // Skip the rest as `_sd` is a special case
31
+ if (key === '_sd') {
32
+ continue;
33
+ }
34
+ // Include all the primitive claims into the new payload
35
+ if (shouldIncludeCleartextClaim(key, value)) {
36
+ newPayload[key] = value;
37
+ continue;
38
+ }
39
+ if (typeof value === 'object' && Array.isArray(value)) {
40
+ newPayload[key] = swapClaimsInsideArray(value, disclosures);
41
+ continue;
42
+ }
43
+ if (typeof value === 'object' &&
44
+ value !== null &&
45
+ !Array.isArray(value)) {
46
+ newPayload[key] = (0, exports.swapClaims)(value, disclosures);
47
+ }
48
+ }
49
+ return newPayload;
50
+ };
51
+ exports.swapClaims = swapClaims;
52
+ const swapClaimsInsideArray = (array, disclosures) => {
53
+ const processedArray = [];
54
+ for (const el of array) {
55
+ if (typeof el === 'object' && el !== null && '...' in el) {
56
+ const hash = el['...'];
57
+ let disclosureFound = false;
58
+ let disclosureValue;
59
+ for (const d of disclosures) {
60
+ if (d.digest === hash && d.decoded[2] === undefined) {
61
+ disclosureValue = d.decoded[1];
62
+ disclosureFound = true;
63
+ break;
64
+ }
65
+ }
66
+ if (disclosureFound) {
67
+ processedArray.push(disclosureValue);
68
+ }
69
+ else {
70
+ processedArray.push(el);
71
+ }
72
+ }
73
+ else {
74
+ processedArray.push(el);
75
+ }
76
+ }
77
+ return processedArray;
78
+ };
79
+ //# sourceMappingURL=swapClaim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swapClaim.js","sourceRoot":"","sources":["../../src/sdJwt/swapClaim.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export type BaseFrame<Payload, ExtraProperties> = Payload extends Array<unknown> ? {
2
+ [K in keyof Payload]?: Payload[K] extends Record<string | number, unknown> ? BaseFrame<Payload[K], ExtraProperties> | boolean : boolean;
3
+ } : Payload extends Record<string, unknown> ? {
4
+ [K in keyof Payload]?: Payload[K] extends Array<unknown> ? BaseFrame<Payload[K], ExtraProperties> | boolean : Payload[K] extends Record<string, unknown> ? (ExtraProperties & BaseFrame<Payload[K], ExtraProperties>) | boolean : boolean;
5
+ } & ExtraProperties & Record<string, unknown> : boolean;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=frame.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/types/frame.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ import { HasherAlgorithm } from '@sd-jwt/utils';
2
+ import { OrPromise } from './utils';
3
+ /**
4
+ * A simple hash function that takes the base64url encoded variant of the disclosure and returns the digest as a byte array
5
+ */
6
+ export type Hasher = (input: string) => OrPromise<Uint8Array>;
7
+ /**
8
+ * hasher: A simple hash function that takes the base64url encoded variant of the disclosure and returns the digest as a byte array
9
+ * algorithm: IANA defined string for the hashing algorithm used
10
+ */
11
+ export type HasherAndAlgorithm = {
12
+ hasher: Hasher;
13
+ algorithm: string | HasherAlgorithm;
14
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=hasher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hasher.js","sourceRoot":"","sources":["../../src/types/hasher.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ import { BaseFrame } from './frame';
2
+ export type PresentationFrame<T> = BaseFrame<T, {}>;
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=present.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/types/present.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from './traverse';
2
+ export * from './utils';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./traverse"), exports);
18
+ __exportStar(require("./utils"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA0B;AAC1B,0CAAuB"}
@@ -0,0 +1,8 @@
1
+ export declare const traverseNodes: (object: any, path?: PathNode[]) => LeafNode[];
2
+ type PathNode = string | number;
3
+ interface LeafNode {
4
+ path: PathNode[];
5
+ value: any;
6
+ isLeaf: boolean;
7
+ }
8
+ export {};
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.traverseNodes = void 0;
4
+ const traverseNodes = (object, path = []) => {
5
+ const result = [];
6
+ if (typeof object !== 'object' || object === null) {
7
+ return [{ path: [], value: object, isLeaf: true }];
8
+ }
9
+ for (const key in object) {
10
+ if (object.hasOwnProperty(key)) {
11
+ const currentPath = [...path, key];
12
+ const value = object[key];
13
+ // Value must be object / array, and have at least some values in it
14
+ if (typeof value === 'object' &&
15
+ value !== null &&
16
+ Object.keys(value).length > 0) {
17
+ // Recursively traverse nested objects or arrays
18
+ result.push(...(0, exports.traverseNodes)(value, currentPath));
19
+ }
20
+ else {
21
+ // Leaf node found
22
+ result.push({ path: currentPath, value, isLeaf: true });
23
+ }
24
+ }
25
+ }
26
+ return result;
27
+ };
28
+ exports.traverseNodes = traverseNodes;
29
+ //# sourceMappingURL=traverse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traverse.js","sourceRoot":"","sources":["../../src/utils/traverse.ts"],"names":[],"mappings":";;;AAAO,MAAM,aAAa,GAAG,CACzB,MAAW,EACX,OAAmB,EAAE,EACX,EAAE;IACZ,MAAM,MAAM,GAAe,EAAE,CAAA;IAE7B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QAChD,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;IACtD,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACvB,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,CAAA;YAClC,MAAM,KAAK,GAAG,MAAM,CAAC,GAA0B,CAAC,CAAA;YAEhD,oEAAoE;YACpE,IACI,OAAO,KAAK,KAAK,QAAQ;gBACzB,KAAK,KAAK,IAAI;gBACd,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAC/B,CAAC;gBACC,gDAAgD;gBAChD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAA,qBAAa,EAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;YACrD,CAAC;iBAAM,CAAC;gBACJ,kBAAkB;gBAClB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;YAC3D,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC,CAAA;AA/BY,QAAA,aAAa,iBA+BzB"}
@@ -0,0 +1,8 @@
1
+ export declare const getAllKeys: (object: unknown, keys?: Array<string>) => Array<string>;
2
+ export declare const getValueByKeyAnyLevel: <T = unknown>(obj: Record<string, unknown>, key: string) => T | undefined;
3
+ export declare const simpleDeepEqual: (lhs: unknown, rhs: unknown) => boolean;
4
+ export declare const deleteByPath: (object: Record<string, unknown>, path: string[]) => void;
5
+ export declare const getByPath: (item: any[] | Record<string, unknown>, path: Array<string | number>) => unknown;
6
+ export declare const hasByPath: (item: any[] | Record<string, unknown>, path: Array<string | number>) => boolean;
7
+ export declare function isObject(input: any): boolean;
8
+ export declare function isPromise<T>(value: Promise<T> | T): value is Promise<T>;
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPromise = exports.isObject = exports.hasByPath = exports.getByPath = exports.deleteByPath = exports.simpleDeepEqual = exports.getValueByKeyAnyLevel = exports.getAllKeys = void 0;
4
+ const sdJwt_1 = require("../sdJwt");
5
+ const getAllKeys = (object, keys = []) => {
6
+ if (typeof object !== 'object' || typeof object === null)
7
+ return keys;
8
+ const record = object;
9
+ const objectKeys = Object.keys(record);
10
+ const objectValues = Object.values(record);
11
+ keys.push(...objectKeys);
12
+ for (const objectValue of objectValues) {
13
+ if (typeof objectValue === 'object' &&
14
+ objectValue !== null &&
15
+ !Array.isArray(objectValue)) {
16
+ (0, exports.getAllKeys)(objectValue, keys);
17
+ }
18
+ }
19
+ return keys;
20
+ };
21
+ exports.getAllKeys = getAllKeys;
22
+ const getValueByKeyAnyLevel = (obj, key) => {
23
+ // Check if the current object has the key
24
+ if (obj && obj.hasOwnProperty(key)) {
25
+ return obj[key];
26
+ }
27
+ // If not found in the current object, iterate over its properties
28
+ for (const prop in obj) {
29
+ if (obj.hasOwnProperty(prop) && typeof obj[prop] === 'object') {
30
+ const result = (0, exports.getValueByKeyAnyLevel)(obj[prop], key);
31
+ if (result !== undefined) {
32
+ return result;
33
+ }
34
+ }
35
+ }
36
+ };
37
+ exports.getValueByKeyAnyLevel = getValueByKeyAnyLevel;
38
+ const simpleDeepEqual = (lhs, rhs) => {
39
+ if (lhs === rhs)
40
+ return true;
41
+ if (typeof lhs !== 'object' || typeof rhs !== 'object')
42
+ return false;
43
+ const l = Object.assign({}, lhs);
44
+ const r = Object.assign({}, rhs);
45
+ Object.keys(l).forEach((key) => l[key] === undefined && delete l[key]);
46
+ Object.keys(r).forEach((key) => r[key] === undefined && delete r[key]);
47
+ const keys1 = Object.keys(l);
48
+ const keys2 = Object.keys(r);
49
+ if (keys1.length !== keys2.length)
50
+ return false;
51
+ return keys1.every((key) => (0, exports.simpleDeepEqual)(l[key], r[key]));
52
+ };
53
+ exports.simpleDeepEqual = simpleDeepEqual;
54
+ const deleteByPath = (object, path) => {
55
+ let currentObject = object;
56
+ const parts = [...path];
57
+ const last = parts.pop();
58
+ for (const part of parts) {
59
+ currentObject = currentObject[part];
60
+ if (!currentObject) {
61
+ return;
62
+ }
63
+ }
64
+ if (last) {
65
+ delete currentObject[last];
66
+ }
67
+ };
68
+ exports.deleteByPath = deleteByPath;
69
+ const getByPath = (item, path) => {
70
+ let current = item;
71
+ for (const key of path) {
72
+ if (Array.isArray(current)) {
73
+ const keyAsNumber = Number(key);
74
+ if (isNaN(keyAsNumber)) {
75
+ throw new sdJwt_1.SdJwtError(`Unable to get ${path.join('.')} from array ${item}. ${key} is not a number.`);
76
+ }
77
+ if (keyAsNumber >= current.length) {
78
+ throw new sdJwt_1.SdJwtError(`Unable to get ${path.join('.')} from array ${item}. ${key} is out of bounds.`);
79
+ }
80
+ current = current[keyAsNumber];
81
+ }
82
+ else if (typeof current === 'object' && current !== null) {
83
+ if (!(key in current)) {
84
+ throw new sdJwt_1.SdJwtError(`Unable to get ${path.join('.')} from ${item}. ${key} does not exists in ${current}.`);
85
+ }
86
+ current = current[key];
87
+ }
88
+ else {
89
+ throw new sdJwt_1.SdJwtError(`Unable to get ${path.join('.')} from ${item}. ${key} is not an object or array.`);
90
+ }
91
+ }
92
+ return current;
93
+ };
94
+ exports.getByPath = getByPath;
95
+ const hasByPath = (item, path) => {
96
+ try {
97
+ (0, exports.getByPath)(item, path);
98
+ return true;
99
+ }
100
+ catch (_a) {
101
+ return false;
102
+ }
103
+ };
104
+ exports.hasByPath = hasByPath;
105
+ function isObject(input) {
106
+ return typeof input === 'object' && input !== null && !Array.isArray(input);
107
+ }
108
+ exports.isObject = isObject;
109
+ function isPromise(value) {
110
+ return (value instanceof Promise ||
111
+ (value &&
112
+ typeof value === 'object' &&
113
+ value !== null &&
114
+ 'then' in value &&
115
+ value.then === 'function'));
116
+ }
117
+ exports.isPromise = isPromise;
118
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sd-jwt/core",
3
- "version": "0.2.1-alpha.0",
3
+ "version": "0.2.1",
4
4
  "description": "Core implementation of sd-jwt Draft 06 and sd-jwt-vc Draft 01",
5
5
  "license": "(MIT OR Apache-2.0)",
6
6
  "author": "Berend Sliedrecht <sliedrecht@berend.io>",
@@ -37,15 +37,15 @@
37
37
  "test": "node --require ts-node/register --test ./tests/*.test.ts"
38
38
  },
39
39
  "dependencies": {
40
- "@sd-jwt/decode": "0.2.1-alpha.0",
41
- "@sd-jwt/present": "0.2.1-alpha.0",
42
- "@sd-jwt/types": "0.2.1-alpha.0",
43
- "@sd-jwt/utils": "0.2.1-alpha.0"
40
+ "@sd-jwt/decode": "0.2.1",
41
+ "@sd-jwt/present": "0.2.1",
42
+ "@sd-jwt/types": "0.2.1",
43
+ "@sd-jwt/utils": "0.2.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "*",
47
47
  "ts-node": "*",
48
48
  "typescript": "*"
49
49
  },
50
- "gitHead": "97e9d3699113bb04fb99d6421797cbd404e4a626"
50
+ "gitHead": "a1fb5fad0b938081e033233bae5569ae3b9fe8cb"
51
51
  }