@sd-jwt/core 0.4.0 → 0.4.1-next.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +8 -5
- package/dist/index.d.ts +8 -5
- package/dist/index.js +33 -17
- package/dist/index.mjs +34 -18
- package/package.json +7 -7
- package/src/decoy.ts +1 -1
- package/src/index.ts +7 -7
- package/src/jwt.ts +31 -10
- package/src/kbjwt.ts +6 -7
- package/src/sdjwt.ts +9 -9
- package/src/test/index.spec.ts +40 -5
- package/src/test/jwt.spec.ts +62 -1
- package/src/test/kbjwt.spec.ts +6 -6
- package/src/test/sdjwt.spec.ts +4 -2
- package/test/app-e2e.spec.ts +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -6,11 +6,13 @@ type JwtData<Header extends Record<string, unknown>, Payload extends Record<stri
|
|
|
6
6
|
header?: Header;
|
|
7
7
|
payload?: Payload;
|
|
8
8
|
signature?: Base64urlString;
|
|
9
|
+
encoded?: string;
|
|
9
10
|
};
|
|
10
11
|
declare class Jwt<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>> {
|
|
11
12
|
header?: Header;
|
|
12
13
|
payload?: Payload;
|
|
13
14
|
signature?: Base64urlString;
|
|
15
|
+
private encoded?;
|
|
14
16
|
constructor(data?: JwtData<Header, Payload>);
|
|
15
17
|
static decodeJWT<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>>(jwt: string): {
|
|
16
18
|
header: Header;
|
|
@@ -20,11 +22,12 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
|
|
|
20
22
|
static fromEncode<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>>(encodedJwt: string): Jwt<Header, Payload>;
|
|
21
23
|
setHeader(header: Header): Jwt<Header, Payload>;
|
|
22
24
|
setPayload(payload: Payload): Jwt<Header, Payload>;
|
|
25
|
+
protected getUnsignedToken(): string;
|
|
23
26
|
sign(signer: Signer): Promise<string>;
|
|
24
27
|
encodeJwt(): string;
|
|
25
28
|
verify(verifier: Verifier): Promise<{
|
|
26
|
-
payload: Payload;
|
|
27
|
-
header: Header;
|
|
29
|
+
payload: Payload | undefined;
|
|
30
|
+
header: Header | undefined;
|
|
28
31
|
}>;
|
|
29
32
|
}
|
|
30
33
|
|
|
@@ -92,11 +95,11 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
92
95
|
}): Promise<SDJWTCompact>;
|
|
93
96
|
verify(encodedSDJwt: string, requiredClaimKeys?: string[], requireKeyBindings?: boolean): Promise<{
|
|
94
97
|
payload: unknown;
|
|
95
|
-
header: Record<string, unknown
|
|
98
|
+
header: Record<string, unknown> | undefined;
|
|
96
99
|
kb?: undefined;
|
|
97
100
|
} | {
|
|
98
101
|
payload: unknown;
|
|
99
|
-
header: Record<string, unknown
|
|
102
|
+
header: Record<string, unknown> | undefined;
|
|
100
103
|
kb: {
|
|
101
104
|
payload: _sd_jwt_types.kbPayload;
|
|
102
105
|
header: _sd_jwt_types.kbHeader;
|
|
@@ -105,7 +108,7 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
105
108
|
private calculateSDHash;
|
|
106
109
|
validate(encodedSDJwt: string): Promise<{
|
|
107
110
|
payload: unknown;
|
|
108
|
-
header: Record<string, unknown
|
|
111
|
+
header: Record<string, unknown> | undefined;
|
|
109
112
|
}>;
|
|
110
113
|
config(newConfig: SDJWTConfig): void;
|
|
111
114
|
encode(sdJwt: SDJwt): SDJWTCompact;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,11 +6,13 @@ type JwtData<Header extends Record<string, unknown>, Payload extends Record<stri
|
|
|
6
6
|
header?: Header;
|
|
7
7
|
payload?: Payload;
|
|
8
8
|
signature?: Base64urlString;
|
|
9
|
+
encoded?: string;
|
|
9
10
|
};
|
|
10
11
|
declare class Jwt<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>> {
|
|
11
12
|
header?: Header;
|
|
12
13
|
payload?: Payload;
|
|
13
14
|
signature?: Base64urlString;
|
|
15
|
+
private encoded?;
|
|
14
16
|
constructor(data?: JwtData<Header, Payload>);
|
|
15
17
|
static decodeJWT<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>>(jwt: string): {
|
|
16
18
|
header: Header;
|
|
@@ -20,11 +22,12 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
|
|
|
20
22
|
static fromEncode<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>>(encodedJwt: string): Jwt<Header, Payload>;
|
|
21
23
|
setHeader(header: Header): Jwt<Header, Payload>;
|
|
22
24
|
setPayload(payload: Payload): Jwt<Header, Payload>;
|
|
25
|
+
protected getUnsignedToken(): string;
|
|
23
26
|
sign(signer: Signer): Promise<string>;
|
|
24
27
|
encodeJwt(): string;
|
|
25
28
|
verify(verifier: Verifier): Promise<{
|
|
26
|
-
payload: Payload;
|
|
27
|
-
header: Header;
|
|
29
|
+
payload: Payload | undefined;
|
|
30
|
+
header: Header | undefined;
|
|
28
31
|
}>;
|
|
29
32
|
}
|
|
30
33
|
|
|
@@ -92,11 +95,11 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
92
95
|
}): Promise<SDJWTCompact>;
|
|
93
96
|
verify(encodedSDJwt: string, requiredClaimKeys?: string[], requireKeyBindings?: boolean): Promise<{
|
|
94
97
|
payload: unknown;
|
|
95
|
-
header: Record<string, unknown
|
|
98
|
+
header: Record<string, unknown> | undefined;
|
|
96
99
|
kb?: undefined;
|
|
97
100
|
} | {
|
|
98
101
|
payload: unknown;
|
|
99
|
-
header: Record<string, unknown
|
|
102
|
+
header: Record<string, unknown> | undefined;
|
|
100
103
|
kb: {
|
|
101
104
|
payload: _sd_jwt_types.kbPayload;
|
|
102
105
|
header: _sd_jwt_types.kbHeader;
|
|
@@ -105,7 +108,7 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
105
108
|
private calculateSDHash;
|
|
106
109
|
validate(encodedSDJwt: string): Promise<{
|
|
107
110
|
payload: unknown;
|
|
108
|
-
header: Record<string, unknown
|
|
111
|
+
header: Record<string, unknown> | undefined;
|
|
109
112
|
}>;
|
|
110
113
|
config(newConfig: SDJWTConfig): void;
|
|
111
114
|
encode(sdJwt: SDJwt): SDJWTCompact;
|
package/dist/index.js
CHANGED
|
@@ -76,6 +76,7 @@ var Jwt = class _Jwt {
|
|
|
76
76
|
this.header = data == null ? void 0 : data.header;
|
|
77
77
|
this.payload = data == null ? void 0 : data.payload;
|
|
78
78
|
this.signature = data == null ? void 0 : data.signature;
|
|
79
|
+
this.encoded = data == null ? void 0 : data.encoded;
|
|
79
80
|
}
|
|
80
81
|
static decodeJWT(jwt) {
|
|
81
82
|
return (0, import_decode.decodeJwt)(jwt);
|
|
@@ -87,31 +88,48 @@ var Jwt = class _Jwt {
|
|
|
87
88
|
const jwt = new _Jwt({
|
|
88
89
|
header,
|
|
89
90
|
payload,
|
|
90
|
-
signature
|
|
91
|
+
signature,
|
|
92
|
+
encoded: encodedJwt
|
|
91
93
|
});
|
|
92
94
|
return jwt;
|
|
93
95
|
}
|
|
94
96
|
setHeader(header) {
|
|
95
97
|
this.header = header;
|
|
98
|
+
this.encoded = void 0;
|
|
96
99
|
return this;
|
|
97
100
|
}
|
|
98
101
|
setPayload(payload) {
|
|
99
102
|
this.payload = payload;
|
|
103
|
+
this.encoded = void 0;
|
|
100
104
|
return this;
|
|
101
105
|
}
|
|
106
|
+
getUnsignedToken() {
|
|
107
|
+
if (!this.header || !this.payload) {
|
|
108
|
+
throw new import_utils.SDJWTException("Serialize Error: Invalid JWT");
|
|
109
|
+
}
|
|
110
|
+
if (this.encoded) {
|
|
111
|
+
const parts = this.encoded.split(".");
|
|
112
|
+
if (parts.length !== 3) {
|
|
113
|
+
throw new import_utils.SDJWTException(`Invalid JWT format: ${this.encoded}`);
|
|
114
|
+
}
|
|
115
|
+
const unsignedToken = parts.slice(0, 2).join(".");
|
|
116
|
+
return unsignedToken;
|
|
117
|
+
}
|
|
118
|
+
const header = (0, import_utils.Base64urlEncode)(JSON.stringify(this.header));
|
|
119
|
+
const payload = (0, import_utils.Base64urlEncode)(JSON.stringify(this.payload));
|
|
120
|
+
return `${header}.${payload}`;
|
|
121
|
+
}
|
|
102
122
|
sign(signer) {
|
|
103
123
|
return __async(this, null, function* () {
|
|
104
|
-
|
|
105
|
-
throw new import_utils.SDJWTException("Sign Error: Invalid JWT");
|
|
106
|
-
}
|
|
107
|
-
const header = (0, import_utils.Base64urlEncode)(JSON.stringify(this.header));
|
|
108
|
-
const payload = (0, import_utils.Base64urlEncode)(JSON.stringify(this.payload));
|
|
109
|
-
const data = `${header}.${payload}`;
|
|
124
|
+
const data = this.getUnsignedToken();
|
|
110
125
|
this.signature = yield signer(data);
|
|
111
126
|
return this.encodeJwt();
|
|
112
127
|
});
|
|
113
128
|
}
|
|
114
129
|
encodeJwt() {
|
|
130
|
+
if (this.encoded) {
|
|
131
|
+
return this.encoded;
|
|
132
|
+
}
|
|
115
133
|
if (!this.header || !this.payload || !this.signature) {
|
|
116
134
|
throw new import_utils.SDJWTException("Serialize Error: Invalid JWT");
|
|
117
135
|
}
|
|
@@ -119,16 +137,15 @@ var Jwt = class _Jwt {
|
|
|
119
137
|
const payload = (0, import_utils.Base64urlEncode)(JSON.stringify(this.payload));
|
|
120
138
|
const signature = this.signature;
|
|
121
139
|
const compact = `${header}.${payload}.${signature}`;
|
|
140
|
+
this.encoded = compact;
|
|
122
141
|
return compact;
|
|
123
142
|
}
|
|
124
143
|
verify(verifier) {
|
|
125
144
|
return __async(this, null, function* () {
|
|
126
|
-
if (!this.
|
|
127
|
-
throw new import_utils.SDJWTException("Verify Error:
|
|
145
|
+
if (!this.signature) {
|
|
146
|
+
throw new import_utils.SDJWTException("Verify Error: no signature in JWT");
|
|
128
147
|
}
|
|
129
|
-
const
|
|
130
|
-
const payload = (0, import_utils.Base64urlEncode)(JSON.stringify(this.payload));
|
|
131
|
-
const data = `${header}.${payload}`;
|
|
148
|
+
const data = this.getUnsignedToken();
|
|
132
149
|
const verified = yield verifier(data, this.signature);
|
|
133
150
|
if (!verified) {
|
|
134
151
|
throw new import_utils.SDJWTException("Verify Error: Invalid JWT Signature");
|
|
@@ -154,9 +171,7 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
154
171
|
!(this.payload.sd_hash || ((_a = this.payload) == null ? void 0 : _a._sd_hash))) {
|
|
155
172
|
throw new import_utils2.SDJWTException("Invalid Key Binding Jwt");
|
|
156
173
|
}
|
|
157
|
-
const
|
|
158
|
-
const payload = (0, import_utils2.Base64urlEncode)(JSON.stringify(this.payload));
|
|
159
|
-
const data = `${header}.${payload}`;
|
|
174
|
+
const data = this.getUnsignedToken();
|
|
160
175
|
const verified = yield values.verifier(
|
|
161
176
|
data,
|
|
162
177
|
this.signature,
|
|
@@ -176,7 +191,8 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
176
191
|
const jwt = new _KBJwt({
|
|
177
192
|
header,
|
|
178
193
|
payload,
|
|
179
|
-
signature
|
|
194
|
+
signature,
|
|
195
|
+
encoded: encodedJwt
|
|
180
196
|
});
|
|
181
197
|
return jwt;
|
|
182
198
|
}
|
|
@@ -341,7 +357,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
341
357
|
const recursivePackedClaims2 = {};
|
|
342
358
|
for (const key in disclosureFrame) {
|
|
343
359
|
if (key !== import_types2.SD_DIGEST) {
|
|
344
|
-
const idx = parseInt(key);
|
|
360
|
+
const idx = Number.parseInt(key);
|
|
345
361
|
const packed = yield pack(
|
|
346
362
|
claims[idx],
|
|
347
363
|
disclosureFrame[idx],
|
package/dist/index.mjs
CHANGED
|
@@ -49,6 +49,7 @@ var Jwt = class _Jwt {
|
|
|
49
49
|
this.header = data == null ? void 0 : data.header;
|
|
50
50
|
this.payload = data == null ? void 0 : data.payload;
|
|
51
51
|
this.signature = data == null ? void 0 : data.signature;
|
|
52
|
+
this.encoded = data == null ? void 0 : data.encoded;
|
|
52
53
|
}
|
|
53
54
|
static decodeJWT(jwt) {
|
|
54
55
|
return decodeJwt(jwt);
|
|
@@ -60,31 +61,48 @@ var Jwt = class _Jwt {
|
|
|
60
61
|
const jwt = new _Jwt({
|
|
61
62
|
header,
|
|
62
63
|
payload,
|
|
63
|
-
signature
|
|
64
|
+
signature,
|
|
65
|
+
encoded: encodedJwt
|
|
64
66
|
});
|
|
65
67
|
return jwt;
|
|
66
68
|
}
|
|
67
69
|
setHeader(header) {
|
|
68
70
|
this.header = header;
|
|
71
|
+
this.encoded = void 0;
|
|
69
72
|
return this;
|
|
70
73
|
}
|
|
71
74
|
setPayload(payload) {
|
|
72
75
|
this.payload = payload;
|
|
76
|
+
this.encoded = void 0;
|
|
73
77
|
return this;
|
|
74
78
|
}
|
|
79
|
+
getUnsignedToken() {
|
|
80
|
+
if (!this.header || !this.payload) {
|
|
81
|
+
throw new SDJWTException("Serialize Error: Invalid JWT");
|
|
82
|
+
}
|
|
83
|
+
if (this.encoded) {
|
|
84
|
+
const parts = this.encoded.split(".");
|
|
85
|
+
if (parts.length !== 3) {
|
|
86
|
+
throw new SDJWTException(`Invalid JWT format: ${this.encoded}`);
|
|
87
|
+
}
|
|
88
|
+
const unsignedToken = parts.slice(0, 2).join(".");
|
|
89
|
+
return unsignedToken;
|
|
90
|
+
}
|
|
91
|
+
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
92
|
+
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
93
|
+
return `${header}.${payload}`;
|
|
94
|
+
}
|
|
75
95
|
sign(signer) {
|
|
76
96
|
return __async(this, null, function* () {
|
|
77
|
-
|
|
78
|
-
throw new SDJWTException("Sign Error: Invalid JWT");
|
|
79
|
-
}
|
|
80
|
-
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
81
|
-
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
82
|
-
const data = `${header}.${payload}`;
|
|
97
|
+
const data = this.getUnsignedToken();
|
|
83
98
|
this.signature = yield signer(data);
|
|
84
99
|
return this.encodeJwt();
|
|
85
100
|
});
|
|
86
101
|
}
|
|
87
102
|
encodeJwt() {
|
|
103
|
+
if (this.encoded) {
|
|
104
|
+
return this.encoded;
|
|
105
|
+
}
|
|
88
106
|
if (!this.header || !this.payload || !this.signature) {
|
|
89
107
|
throw new SDJWTException("Serialize Error: Invalid JWT");
|
|
90
108
|
}
|
|
@@ -92,16 +110,15 @@ var Jwt = class _Jwt {
|
|
|
92
110
|
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
93
111
|
const signature = this.signature;
|
|
94
112
|
const compact = `${header}.${payload}.${signature}`;
|
|
113
|
+
this.encoded = compact;
|
|
95
114
|
return compact;
|
|
96
115
|
}
|
|
97
116
|
verify(verifier) {
|
|
98
117
|
return __async(this, null, function* () {
|
|
99
|
-
if (!this.
|
|
100
|
-
throw new SDJWTException("Verify Error:
|
|
118
|
+
if (!this.signature) {
|
|
119
|
+
throw new SDJWTException("Verify Error: no signature in JWT");
|
|
101
120
|
}
|
|
102
|
-
const
|
|
103
|
-
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
104
|
-
const data = `${header}.${payload}`;
|
|
121
|
+
const data = this.getUnsignedToken();
|
|
105
122
|
const verified = yield verifier(data, this.signature);
|
|
106
123
|
if (!verified) {
|
|
107
124
|
throw new SDJWTException("Verify Error: Invalid JWT Signature");
|
|
@@ -112,7 +129,7 @@ var Jwt = class _Jwt {
|
|
|
112
129
|
};
|
|
113
130
|
|
|
114
131
|
// src/kbjwt.ts
|
|
115
|
-
import {
|
|
132
|
+
import { SDJWTException as SDJWTException2 } from "@sd-jwt/utils";
|
|
116
133
|
import {
|
|
117
134
|
KB_JWT_TYP
|
|
118
135
|
} from "@sd-jwt/types";
|
|
@@ -129,9 +146,7 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
129
146
|
!(this.payload.sd_hash || ((_a = this.payload) == null ? void 0 : _a._sd_hash))) {
|
|
130
147
|
throw new SDJWTException2("Invalid Key Binding Jwt");
|
|
131
148
|
}
|
|
132
|
-
const
|
|
133
|
-
const payload = Base64urlEncode2(JSON.stringify(this.payload));
|
|
134
|
-
const data = `${header}.${payload}`;
|
|
149
|
+
const data = this.getUnsignedToken();
|
|
135
150
|
const verified = yield values.verifier(
|
|
136
151
|
data,
|
|
137
152
|
this.signature,
|
|
@@ -151,7 +166,8 @@ var KBJwt = class _KBJwt extends Jwt {
|
|
|
151
166
|
const jwt = new _KBJwt({
|
|
152
167
|
header,
|
|
153
168
|
payload,
|
|
154
|
-
signature
|
|
169
|
+
signature,
|
|
170
|
+
encoded: encodedJwt
|
|
155
171
|
});
|
|
156
172
|
return jwt;
|
|
157
173
|
}
|
|
@@ -321,7 +337,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
321
337
|
const recursivePackedClaims2 = {};
|
|
322
338
|
for (const key in disclosureFrame) {
|
|
323
339
|
if (key !== SD_DIGEST) {
|
|
324
|
-
const idx = parseInt(key);
|
|
340
|
+
const idx = Number.parseInt(key);
|
|
325
341
|
const packed = yield pack(
|
|
326
342
|
claims[idx],
|
|
327
343
|
disclosureFrame[idx],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sd-jwt/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1-next.12+eb259c7",
|
|
4
4
|
"description": "sd-jwt draft 7 implementation in typescript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
},
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@sd-jwt/crypto-nodejs": "0.4.
|
|
41
|
+
"@sd-jwt/crypto-nodejs": "0.4.1-next.12+eb259c7"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@sd-jwt/decode": "0.4.
|
|
45
|
-
"@sd-jwt/present": "0.4.
|
|
46
|
-
"@sd-jwt/types": "0.4.
|
|
47
|
-
"@sd-jwt/utils": "0.4.
|
|
44
|
+
"@sd-jwt/decode": "0.4.1-next.12+eb259c7",
|
|
45
|
+
"@sd-jwt/present": "0.4.1-next.12+eb259c7",
|
|
46
|
+
"@sd-jwt/types": "0.4.1-next.12+eb259c7",
|
|
47
|
+
"@sd-jwt/utils": "0.4.1-next.12+eb259c7"
|
|
48
48
|
},
|
|
49
49
|
"publishConfig": {
|
|
50
50
|
"access": "public"
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"esm"
|
|
63
63
|
]
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "eb259c74a386b0ca867b373f6ffa08b6b6b78d7b"
|
|
66
66
|
}
|
package/src/decoy.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HasherAndAlg, SaltGenerator } from '@sd-jwt/types';
|
|
1
|
+
import type { HasherAndAlg, SaltGenerator } from '@sd-jwt/types';
|
|
2
2
|
import { Uint8ArrayToBase64Url } from '@sd-jwt/utils';
|
|
3
3
|
|
|
4
4
|
// This function creates a decoy value that can be used to obscure SD JWT payload.
|
package/src/index.ts
CHANGED
|
@@ -3,16 +3,16 @@ import { Jwt } from './jwt';
|
|
|
3
3
|
import { KBJwt } from './kbjwt';
|
|
4
4
|
import { SDJwt, pack } from './sdjwt';
|
|
5
5
|
import {
|
|
6
|
-
DisclosureFrame,
|
|
7
|
-
Hasher,
|
|
8
|
-
KBOptions,
|
|
6
|
+
type DisclosureFrame,
|
|
7
|
+
type Hasher,
|
|
8
|
+
type KBOptions,
|
|
9
9
|
KB_JWT_TYP,
|
|
10
|
-
PresentationFrame,
|
|
11
|
-
SDJWTCompact,
|
|
12
|
-
SDJWTConfig,
|
|
10
|
+
type PresentationFrame,
|
|
11
|
+
type SDJWTCompact,
|
|
12
|
+
type SDJWTConfig,
|
|
13
13
|
} from '@sd-jwt/types';
|
|
14
14
|
import { getSDAlgAndPayload } from '@sd-jwt/decode';
|
|
15
|
-
import { JwtPayload } from '@sd-jwt/types';
|
|
15
|
+
import type { JwtPayload } from '@sd-jwt/types';
|
|
16
16
|
|
|
17
17
|
export * from './sdjwt';
|
|
18
18
|
export * from './kbjwt';
|
package/src/jwt.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Base64urlEncode, SDJWTException } from '@sd-jwt/utils';
|
|
2
|
-
import { Base64urlString, Signer, Verifier } from '@sd-jwt/types';
|
|
2
|
+
import type { Base64urlString, Signer, Verifier } from '@sd-jwt/types';
|
|
3
3
|
import { decodeJwt } from '@sd-jwt/decode';
|
|
4
4
|
|
|
5
5
|
export type JwtData<
|
|
@@ -9,6 +9,7 @@ export type JwtData<
|
|
|
9
9
|
header?: Header;
|
|
10
10
|
payload?: Payload;
|
|
11
11
|
signature?: Base64urlString;
|
|
12
|
+
encoded?: string;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
// This class is used to create and verify JWT
|
|
@@ -20,11 +21,13 @@ export class Jwt<
|
|
|
20
21
|
public header?: Header;
|
|
21
22
|
public payload?: Payload;
|
|
22
23
|
public signature?: Base64urlString;
|
|
24
|
+
private encoded?: string;
|
|
23
25
|
|
|
24
26
|
constructor(data?: JwtData<Header, Payload>) {
|
|
25
27
|
this.header = data?.header;
|
|
26
28
|
this.payload = data?.payload;
|
|
27
29
|
this.signature = data?.signature;
|
|
30
|
+
this.encoded = data?.encoded;
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
public static decodeJWT<
|
|
@@ -48,6 +51,7 @@ export class Jwt<
|
|
|
48
51
|
header,
|
|
49
52
|
payload,
|
|
50
53
|
signature,
|
|
54
|
+
encoded: encodedJwt,
|
|
51
55
|
});
|
|
52
56
|
|
|
53
57
|
return jwt;
|
|
@@ -55,28 +59,47 @@ export class Jwt<
|
|
|
55
59
|
|
|
56
60
|
public setHeader(header: Header): Jwt<Header, Payload> {
|
|
57
61
|
this.header = header;
|
|
62
|
+
this.encoded = undefined;
|
|
58
63
|
return this;
|
|
59
64
|
}
|
|
60
65
|
|
|
61
66
|
public setPayload(payload: Payload): Jwt<Header, Payload> {
|
|
62
67
|
this.payload = payload;
|
|
68
|
+
this.encoded = undefined;
|
|
63
69
|
return this;
|
|
64
70
|
}
|
|
65
71
|
|
|
66
|
-
|
|
72
|
+
protected getUnsignedToken() {
|
|
67
73
|
if (!this.header || !this.payload) {
|
|
68
|
-
throw new SDJWTException('
|
|
74
|
+
throw new SDJWTException('Serialize Error: Invalid JWT');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (this.encoded) {
|
|
78
|
+
const parts = this.encoded.split('.');
|
|
79
|
+
if (parts.length !== 3) {
|
|
80
|
+
throw new SDJWTException(`Invalid JWT format: ${this.encoded}`);
|
|
81
|
+
}
|
|
82
|
+
const unsignedToken = parts.slice(0, 2).join('.');
|
|
83
|
+
return unsignedToken;
|
|
69
84
|
}
|
|
70
85
|
|
|
71
86
|
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
72
87
|
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
73
|
-
|
|
88
|
+
return `${header}.${payload}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public async sign(signer: Signer) {
|
|
92
|
+
const data = this.getUnsignedToken();
|
|
74
93
|
this.signature = await signer(data);
|
|
75
94
|
|
|
76
95
|
return this.encodeJwt();
|
|
77
96
|
}
|
|
78
97
|
|
|
79
98
|
public encodeJwt(): string {
|
|
99
|
+
if (this.encoded) {
|
|
100
|
+
return this.encoded;
|
|
101
|
+
}
|
|
102
|
+
|
|
80
103
|
if (!this.header || !this.payload || !this.signature) {
|
|
81
104
|
throw new SDJWTException('Serialize Error: Invalid JWT');
|
|
82
105
|
}
|
|
@@ -85,18 +108,16 @@ export class Jwt<
|
|
|
85
108
|
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
86
109
|
const signature = this.signature;
|
|
87
110
|
const compact = `${header}.${payload}.${signature}`;
|
|
111
|
+
this.encoded = compact;
|
|
88
112
|
|
|
89
113
|
return compact;
|
|
90
114
|
}
|
|
91
115
|
|
|
92
116
|
public async verify(verifier: Verifier) {
|
|
93
|
-
if (!this.
|
|
94
|
-
throw new SDJWTException('Verify Error:
|
|
117
|
+
if (!this.signature) {
|
|
118
|
+
throw new SDJWTException('Verify Error: no signature in JWT');
|
|
95
119
|
}
|
|
96
|
-
|
|
97
|
-
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
98
|
-
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
99
|
-
const data = `${header}.${payload}`;
|
|
120
|
+
const data = this.getUnsignedToken();
|
|
100
121
|
|
|
101
122
|
const verified = await verifier(data, this.signature);
|
|
102
123
|
if (!verified) {
|
package/src/kbjwt.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Base64urlEncode, SDJWTException } from '@sd-jwt/utils';
|
|
2
2
|
import { Jwt } from './jwt';
|
|
3
3
|
import {
|
|
4
|
-
JwtPayload,
|
|
4
|
+
type JwtPayload,
|
|
5
5
|
KB_JWT_TYP,
|
|
6
|
-
kbHeader,
|
|
7
|
-
kbPayload,
|
|
8
|
-
KbVerifier,
|
|
6
|
+
type kbHeader,
|
|
7
|
+
type kbPayload,
|
|
8
|
+
type KbVerifier,
|
|
9
9
|
} from '@sd-jwt/types';
|
|
10
10
|
|
|
11
11
|
export class KBJwt<
|
|
@@ -36,9 +36,7 @@ export class KBJwt<
|
|
|
36
36
|
throw new SDJWTException('Invalid Key Binding Jwt');
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
const
|
|
40
|
-
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
41
|
-
const data = `${header}.${payload}`;
|
|
39
|
+
const data = this.getUnsignedToken();
|
|
42
40
|
const verified = await values.verifier(
|
|
43
41
|
data,
|
|
44
42
|
this.signature,
|
|
@@ -63,6 +61,7 @@ export class KBJwt<
|
|
|
63
61
|
header,
|
|
64
62
|
payload,
|
|
65
63
|
signature,
|
|
64
|
+
encoded: encodedJwt,
|
|
66
65
|
});
|
|
67
66
|
|
|
68
67
|
return jwt;
|
package/src/sdjwt.ts
CHANGED
|
@@ -3,18 +3,18 @@ import { SDJWTException, Disclosure } from '@sd-jwt/utils';
|
|
|
3
3
|
import { Jwt } from './jwt';
|
|
4
4
|
import { KBJwt } from './kbjwt';
|
|
5
5
|
import {
|
|
6
|
-
DisclosureFrame,
|
|
7
|
-
Hasher,
|
|
8
|
-
HasherAndAlg,
|
|
9
|
-
PresentationFrame,
|
|
10
|
-
SDJWTCompact,
|
|
6
|
+
type DisclosureFrame,
|
|
7
|
+
type Hasher,
|
|
8
|
+
type HasherAndAlg,
|
|
9
|
+
type PresentationFrame,
|
|
10
|
+
type SDJWTCompact,
|
|
11
11
|
SD_DECOY,
|
|
12
12
|
SD_DIGEST,
|
|
13
13
|
SD_LIST_KEY,
|
|
14
14
|
SD_SEPARATOR,
|
|
15
|
-
SaltGenerator,
|
|
16
|
-
kbHeader,
|
|
17
|
-
kbPayload,
|
|
15
|
+
type SaltGenerator,
|
|
16
|
+
type kbHeader,
|
|
17
|
+
type kbPayload,
|
|
18
18
|
} from '@sd-jwt/types';
|
|
19
19
|
import { createHashMapping, getSDAlgAndPayload, unpack } from '@sd-jwt/decode';
|
|
20
20
|
import { transformPresentationFrame } from '@sd-jwt/present';
|
|
@@ -236,7 +236,7 @@ export const pack = async <T extends Record<string, unknown>>(
|
|
|
236
236
|
|
|
237
237
|
for (const key in disclosureFrame) {
|
|
238
238
|
if (key !== SD_DIGEST) {
|
|
239
|
-
const idx = parseInt(key);
|
|
239
|
+
const idx = Number.parseInt(key);
|
|
240
240
|
const packed = await pack(
|
|
241
241
|
claims[idx],
|
|
242
242
|
disclosureFrame[idx],
|
package/src/test/index.spec.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import { SDJwtInstance, SdJwtPayload } from '../index';
|
|
2
|
-
import { Signer, Verifier, KbVerifier, JwtPayload } from '@sd-jwt/types';
|
|
3
|
-
import Crypto, { KeyLike } from 'node:crypto';
|
|
1
|
+
import { SDJwtInstance, type SdJwtPayload } from '../index';
|
|
2
|
+
import type { Signer, Verifier, KbVerifier, JwtPayload } from '@sd-jwt/types';
|
|
3
|
+
import Crypto, { type KeyLike } from 'node:crypto';
|
|
4
4
|
import { describe, expect, test } from 'vitest';
|
|
5
|
-
import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
|
|
6
|
-
import { importJWK, exportJWK, JWK } from 'jose';
|
|
5
|
+
import { digest, generateSalt, ES256 } from '@sd-jwt/crypto-nodejs';
|
|
6
|
+
import { importJWK, exportJWK, type JWK } from 'jose';
|
|
7
|
+
|
|
8
|
+
// Extract the major version as a number
|
|
9
|
+
const nodeVersionMajor = Number.parseInt(
|
|
10
|
+
process.version.split('.')[0].substring(1),
|
|
11
|
+
10,
|
|
12
|
+
);
|
|
7
13
|
|
|
8
14
|
export const createSignerVerifier = () => {
|
|
9
15
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
@@ -590,4 +596,33 @@ describe('index', () => {
|
|
|
590
596
|
expect(decoded.disclosures).toBeDefined();
|
|
591
597
|
expect(decoded.kbJwt).toBeDefined();
|
|
592
598
|
});
|
|
599
|
+
|
|
600
|
+
(nodeVersionMajor < 20 ? test.skip : test)(
|
|
601
|
+
'validate sd-jwt that created in other implemenation',
|
|
602
|
+
async () => {
|
|
603
|
+
const publicKeyExampleJwt: JsonWebKey = {
|
|
604
|
+
kty: 'EC',
|
|
605
|
+
crv: 'P-256',
|
|
606
|
+
x: 'b28d4MwZMjw8-00CG4xfnn9SLMVMM19SlqZpVb_uNtQ',
|
|
607
|
+
y: 'Xv5zWwuoaTgdS6hV43yI6gBwTnjukmFQQnJ_kCxzqk8',
|
|
608
|
+
};
|
|
609
|
+
const kbPubkey: JsonWebKey = {
|
|
610
|
+
kty: 'EC',
|
|
611
|
+
crv: 'P-256',
|
|
612
|
+
x: 'TCAER19Zvu3OHF4j4W4vfSVoHIP1ILilDls7vCeGemc',
|
|
613
|
+
y: 'ZxjiWWbZMQGHVWKVQ4hbSIirsVfuecCE6t4jT9F2HZQ',
|
|
614
|
+
};
|
|
615
|
+
const encodedJwt =
|
|
616
|
+
'eyJhbGciOiAiRVMyNTYiLCAidHlwIjogInZjK3NkLWp3dCIsICJraWQiOiAiZG9jLXNpZ25lci0wNS0yNS0yMDIyIn0.eyJfc2QiOiBbIjA5dktySk1PbHlUV00wc2pwdV9wZE9CVkJRMk0xeTNLaHBINTE1blhrcFkiLCAiMnJzakdiYUMwa3k4bVQwcEpyUGlvV1RxMF9kYXcxc1g3NnBvVWxnQ3diSSIsICJFa084ZGhXMGRIRUpidlVIbEVfVkNldUM5dVJFTE9pZUxaaGg3WGJVVHRBIiwgIklsRHpJS2VpWmREd3BxcEs2WmZieXBoRnZ6NUZnbldhLXNONndxUVhDaXciLCAiSnpZakg0c3ZsaUgwUjNQeUVNZmVadTZKdDY5dTVxZWhabzdGN0VQWWxTRSIsICJQb3JGYnBLdVZ1Nnh5bUphZ3ZrRnNGWEFiUm9jMkpHbEFVQTJCQTRvN2NJIiwgIlRHZjRvTGJnd2Q1SlFhSHlLVlFaVTlVZEdFMHc1cnREc3JaemZVYW9tTG8iLCAiamRyVEU4WWNiWTRFaWZ1Z2loaUFlX0JQZWt4SlFaSUNlaVVRd1k5UXF4SSIsICJqc3U5eVZ1bHdRUWxoRmxNXzNKbHpNYVNGemdsaFFHMERwZmF5UXdMVUs0Il0sICJpc3MiOiAiaHR0cHM6Ly9leGFtcGxlLmNvbS9pc3N1ZXIiLCAiaWF0IjogMTY4MzAwMDAwMCwgImV4cCI6IDE4ODMwMDAwMDAsICJ2Y3QiOiAiaHR0cHM6Ly9jcmVkZW50aWFscy5leGFtcGxlLmNvbS9pZGVudGl0eV9jcmVkZW50aWFsIiwgIl9zZF9hbGciOiAic2hhLTI1NiIsICJjbmYiOiB7Imp3ayI6IHsia3R5IjogIkVDIiwgImNydiI6ICJQLTI1NiIsICJ4IjogIlRDQUVSMTladnUzT0hGNGo0VzR2ZlNWb0hJUDFJTGlsRGxzN3ZDZUdlbWMiLCAieSI6ICJaeGppV1diWk1RR0hWV0tWUTRoYlNJaXJzVmZ1ZWNDRTZ0NGpUOUYySFpRIn19fQ.QXgzrePAdq_WZVGCwDxP-l8h0iyckrHBNidxVqGtKJ0LMzObqgaXUD1cgGEf7d9TexPkBcgQYqjuzlfbeCxxuA~WyJRZ19PNjR6cUF4ZTQxMmExMDhpcm9BIiwgImFkZHJlc3MiLCB7InN0cmVldF9hZGRyZXNzIjogIjEyMyBNYWluIFN0IiwgImxvY2FsaXR5IjogIkFueXRvd24iLCAicmVnaW9uIjogIkFueXN0YXRlIiwgImNvdW50cnkiOiAiVVMifV0~WyI2SWo3dE0tYTVpVlBHYm9TNXRtdlZBIiwgImVtYWlsIiwgImpvaG5kb2VAZXhhbXBsZS5jb20iXQ~WyJlbHVWNU9nM2dTTklJOEVZbnN4QV9BIiwgImZhbWlseV9uYW1lIiwgIkRvZSJd~WyIyR0xDNDJzS1F2ZUNmR2ZyeU5STjl3IiwgImdpdmVuX25hbWUiLCAiSm9obiJd~eyJhbGciOiAiRVMyNTYiLCAidHlwIjogImtiK2p3dCJ9.eyJub25jZSI6ICIxMjM0NTY3ODkwIiwgImF1ZCI6ICJodHRwczovL2V4YW1wbGUuY29tL3ZlcmlmaWVyIiwgImlhdCI6IDE3MDk5OTYxODUsICJzZF9oYXNoIjogIjc4cFFEazJOblNEM1dKQm5SN015aWpmeUVqcGJ5a01yRnlpb2ZYSjlsN0kifQ.7k4goAlxM4a3tHnvCBCe70j_I-BCwtzhBRXQNk9cWJnQWxxt2kIqCyzcwzzUc0gTwtbGWVQoeWCiL5K6y3a4VQ';
|
|
617
|
+
|
|
618
|
+
const sdjwt = new SDJwtInstance({
|
|
619
|
+
hasher: digest,
|
|
620
|
+
verifier: await ES256.getVerifier(publicKeyExampleJwt),
|
|
621
|
+
kbVerifier: await ES256.getVerifier(kbPubkey),
|
|
622
|
+
});
|
|
623
|
+
|
|
624
|
+
const decode = await sdjwt.verify(encodedJwt, undefined, true);
|
|
625
|
+
expect(decode).toBeDefined();
|
|
626
|
+
},
|
|
627
|
+
);
|
|
593
628
|
});
|
package/src/test/jwt.spec.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SDJWTException } from '@sd-jwt/utils';
|
|
2
2
|
import { Jwt } from '../jwt';
|
|
3
3
|
import Crypto from 'node:crypto';
|
|
4
|
-
import { Signer, Verifier } from '@sd-jwt/types';
|
|
4
|
+
import type { Signer, Verifier } from '@sd-jwt/types';
|
|
5
5
|
import { describe, expect, test } from 'vitest';
|
|
6
6
|
|
|
7
7
|
describe('JWT', () => {
|
|
@@ -138,4 +138,65 @@ describe('JWT', () => {
|
|
|
138
138
|
expect(e).toBeInstanceOf(SDJWTException);
|
|
139
139
|
}
|
|
140
140
|
});
|
|
141
|
+
|
|
142
|
+
test('getUnsignedToken failed', async () => {
|
|
143
|
+
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
144
|
+
const testSigner: Signer = async (data: string) => {
|
|
145
|
+
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
146
|
+
return Buffer.from(sig).toString('base64url');
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const jwt = new Jwt({
|
|
150
|
+
header: { alg: 'EdDSA' },
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
await jwt.sign(testSigner);
|
|
155
|
+
} catch (e: unknown) {
|
|
156
|
+
expect(e).toBeInstanceOf(SDJWTException);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test('wrong encoded field', async () => {
|
|
161
|
+
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
162
|
+
const testSigner: Signer = async (data: string) => {
|
|
163
|
+
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
164
|
+
return Buffer.from(sig).toString('base64url');
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const jwt = new Jwt({
|
|
168
|
+
header: { alg: 'EdDSA' },
|
|
169
|
+
payload: { foo: 'bar' },
|
|
170
|
+
encoded: 'asfasfafaf.dfasfafafasf', // it has to be 3 parts
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
try {
|
|
174
|
+
await jwt.sign(testSigner);
|
|
175
|
+
} catch (e: unknown) {
|
|
176
|
+
expect(e).toBeInstanceOf(SDJWTException);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
test('verify failed no signature', async () => {
|
|
181
|
+
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
182
|
+
const testVerifier: Verifier = async (data: string, sig: string) => {
|
|
183
|
+
return Crypto.verify(
|
|
184
|
+
null,
|
|
185
|
+
Buffer.from(data),
|
|
186
|
+
publicKey,
|
|
187
|
+
Buffer.from(sig, 'base64url'),
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const jwt = new Jwt({
|
|
192
|
+
header: { alg: 'EdDSA' },
|
|
193
|
+
payload: { foo: 'bar' },
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
await jwt.verify(testVerifier);
|
|
198
|
+
} catch (e: unknown) {
|
|
199
|
+
expect(e).toBeInstanceOf(SDJWTException);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
141
202
|
});
|
package/src/test/kbjwt.spec.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { SDJWTException } from '@sd-jwt/utils';
|
|
1
|
+
import type { SDJWTException } from '@sd-jwt/utils';
|
|
2
2
|
import { KBJwt } from '../kbjwt';
|
|
3
3
|
import {
|
|
4
|
-
JwtPayload,
|
|
4
|
+
type JwtPayload,
|
|
5
5
|
KB_JWT_TYP,
|
|
6
|
-
KbVerifier,
|
|
7
|
-
Signer,
|
|
6
|
+
type KbVerifier,
|
|
7
|
+
type Signer,
|
|
8
8
|
Verifier,
|
|
9
9
|
} from '@sd-jwt/types';
|
|
10
|
-
import Crypto, { KeyLike } from 'node:crypto';
|
|
10
|
+
import Crypto, { type KeyLike } from 'node:crypto';
|
|
11
11
|
import { describe, expect, test } from 'vitest';
|
|
12
|
-
import { JWK, exportJWK, importJWK } from 'jose';
|
|
12
|
+
import { type JWK, exportJWK, importJWK } from 'jose';
|
|
13
13
|
|
|
14
14
|
describe('KB JWT', () => {
|
|
15
15
|
test('create', async () => {
|
package/src/test/sdjwt.spec.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Jwt } from '../jwt';
|
|
|
3
3
|
import { SDJwt, listKeys, pack } from '../sdjwt';
|
|
4
4
|
import Crypto from 'node:crypto';
|
|
5
5
|
import { describe, test, expect } from 'vitest';
|
|
6
|
-
import { DisclosureFrame, Signer } from '@sd-jwt/types';
|
|
6
|
+
import type { DisclosureFrame, Signer } from '@sd-jwt/types';
|
|
7
7
|
import { generateSalt, digest as hasher } from '@sd-jwt/crypto-nodejs';
|
|
8
8
|
import { unpack, createHashMapping } from '@sd-jwt/decode';
|
|
9
9
|
|
|
@@ -376,7 +376,9 @@ describe('SD JWT', () => {
|
|
|
376
376
|
|
|
377
377
|
const credential = sdJwt.encodeSDJwt();
|
|
378
378
|
const decoded = await SDJwt.decodeSDJwt(credential, hasher);
|
|
379
|
-
expect(jwt).toEqual(decoded.jwt);
|
|
379
|
+
expect(jwt.header).toEqual(decoded.jwt.header);
|
|
380
|
+
expect(jwt.payload).toEqual(decoded.jwt.payload);
|
|
381
|
+
expect(jwt.signature).toEqual(decoded.jwt.signature);
|
|
380
382
|
expect(decoded.disclosures).toEqual([]);
|
|
381
383
|
});
|
|
382
384
|
});
|
package/test/app-e2e.spec.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import Crypto from 'node:crypto';
|
|
2
|
-
import { SDJwtInstance, SdJwtPayload } from '../src';
|
|
3
|
-
import {
|
|
2
|
+
import { SDJwtInstance, type SdJwtPayload } from '../src';
|
|
3
|
+
import type {
|
|
4
4
|
DisclosureFrame,
|
|
5
5
|
PresentationFrame,
|
|
6
6
|
Signer,
|
|
7
7
|
Verifier,
|
|
8
8
|
} from '@sd-jwt/types';
|
|
9
|
-
import fs from 'fs';
|
|
10
|
-
import path from 'path';
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
11
|
import { describe, expect, test } from 'vitest';
|
|
12
12
|
import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
|
|
13
13
|
|