@sd-jwt/core 0.3.2-next.98 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/dist/index.d.mts +7 -4
- package/dist/index.d.ts +7 -4
- package/dist/index.js +49 -37
- package/dist/index.mjs +39 -25
- package/package.json +7 -6
- package/src/index.ts +13 -6
- package/src/jwt.ts +1 -1
- package/src/kbjwt.ts +34 -9
- package/src/sdjwt.ts +12 -13
- package/src/test/index.spec.ts +154 -57
- package/src/test/kbjwt.spec.ts +111 -45
- package/test/app-e2e.spec.ts +12 -4
- package/test/array_data_types.json +10 -8
- package/test/array_full_sd.json +1 -1
- package/test/array_in_sd.json +1 -1
- package/test/array_nested_in_plain.json +10 -1
- package/test/array_none_disclosed.json +1 -1
- package/test/array_of_nulls.json +1 -1
- package/test/array_of_objects.json +8 -1
- package/test/array_of_scalars.json +5 -1
- package/test/array_recursive_sd.json +1 -1
- package/test/array_recursive_sd_some_disclosed.json +14 -6
- package/test/complex.json +1 -1
- package/test/header_mod.json +5 -1
- package/test/json_serialization.json +5 -1
- package/test/key_binding.json +5 -1
- package/test/no_sd.json +1 -1
- package/test/object_data_types.json +11 -9
- package/test/recursions.json +36 -17
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
|
+
|
|
6
|
+
# 0.4.0 (2024-03-08)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* add publish config ([#93](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/93)) ([2e4c5c1](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/2e4c5c176dc88e58e49d06783b7658d8ad872313))
|
|
12
|
+
* add the payload that is required ([6c53580](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/6c53580d12e4361c40435b90628302749fa32b1c))
|
|
13
|
+
* change SDJwtPayload to SdJwtPayload ([9f06ef7](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/9f06ef7bd31a1dff4e9bf988e425200a5e1aa82d))
|
|
14
|
+
* convert any usage into or typed version ([#80](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/80)) ([de4df54](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/de4df54f2a0a77fdbf97e10abac555a98e70c6e0))
|
|
15
|
+
* implement kbverify function ([#127](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/127)) ([e5609f2](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/e5609f26fab8c4991d3bd6c36066a95a30cfb972))
|
|
16
|
+
* make sdjwt instance non abstract ([#122](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/122)) ([e85aae8](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/e85aae89910f5d9468e29ef14ef3b3d3215b86fd))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Features
|
|
20
|
+
|
|
21
|
+
* add jwk type ([#130](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/130)) ([8ce255a](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/8ce255a64b0940e92e647aa544bf5990b48279b7))
|
|
22
|
+
* add new package for sd-jwt-vc ([ed99188](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/ed99188f13184d58db64b4211e39fb67f3f78cb5))
|
|
23
|
+
* Apply lerna to move src to core ([#67](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/67)) ([49e272b](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/49e272b6b51c5226e22732c469e566fd3c14c57c))
|
|
24
|
+
* calcuate sd_hash in kb JWT ([#117](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/117)) ([3415550](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/3415550fbcd99f97babff442a4928cc827c5c9cc))
|
|
25
|
+
* checking kb header value ([#133](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/133)) ([cd2991b](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/cd2991b88a0522e39251c5ca2b67593130baa585))
|
|
26
|
+
* create kb jwt when present all ([#129](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/129)) ([72ed1ad](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/72ed1ad64b850876ba3b5d5e5df6128471fb44ac))
|
|
27
|
+
* fix async handling in jwt verify ([#131](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/131)) ([76cb930](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/76cb93021dd62c241c87656975f74dd44b3766cf))
|
|
28
|
+
* fixing exclude _sd_alg when no disclosure ([#120](https://github.com/openwallet-foundation-labs/sd-jwt-js/issues/120)) ([dcaf1f6](https://github.com/openwallet-foundation-labs/sd-jwt-js/commit/dcaf1f6fad3289ea7cbe0f3f410fdc15c0f77fda))
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _sd_jwt_types from '@sd-jwt/types';
|
|
2
|
-
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, SDJWTCompact, Hasher, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
2
|
+
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, KbVerifier, JwtPayload, SDJWTCompact, Hasher, PresentationFrame, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
3
3
|
import { Disclosure } from '@sd-jwt/utils';
|
|
4
4
|
|
|
5
5
|
type JwtData<Header extends Record<string, unknown>, Payload extends Record<string, unknown>> = {
|
|
@@ -29,7 +29,10 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
declare class KBJwt<Header extends kbHeader = kbHeader, Payload extends kbPayload = kbPayload> extends Jwt<Header, Payload> {
|
|
32
|
-
|
|
32
|
+
verifyKB(values: {
|
|
33
|
+
verifier: KbVerifier;
|
|
34
|
+
payload: JwtPayload;
|
|
35
|
+
}): Promise<{
|
|
33
36
|
payload: Payload;
|
|
34
37
|
header: Header;
|
|
35
38
|
}>;
|
|
@@ -52,7 +55,7 @@ declare class SDJwt<Header extends Record<string, unknown> = Record<string, unkn
|
|
|
52
55
|
kbJwt?: KBJwt<KBHeader, KBPayload>;
|
|
53
56
|
}>;
|
|
54
57
|
static fromEncode<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>, KBHeader extends kbHeader = kbHeader, KBPayload extends kbPayload = kbPayload>(encodedSdJwt: SDJWTCompact, hasher: Hasher): Promise<SDJwt<Header, Payload>>;
|
|
55
|
-
present(
|
|
58
|
+
present<T extends Record<string, unknown>>(presentFrame: PresentationFrame<T> | undefined, hasher: Hasher): Promise<SDJWTCompact>;
|
|
56
59
|
encodeSDJwt(): SDJWTCompact;
|
|
57
60
|
keys(hasher: Hasher): Promise<string[]>;
|
|
58
61
|
presentableKeys(hasher: Hasher): Promise<string[]>;
|
|
@@ -84,7 +87,7 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
84
87
|
* @returns
|
|
85
88
|
*/
|
|
86
89
|
protected validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
|
|
87
|
-
present(encodedSDJwt: string,
|
|
90
|
+
present<T extends Record<string, unknown>>(encodedSDJwt: string, presentationFrame?: PresentationFrame<T>, options?: {
|
|
88
91
|
kb?: KBOptions;
|
|
89
92
|
}): Promise<SDJWTCompact>;
|
|
90
93
|
verify(encodedSDJwt: string, requiredClaimKeys?: string[], requireKeyBindings?: boolean): Promise<{
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as _sd_jwt_types from '@sd-jwt/types';
|
|
2
|
-
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, SDJWTCompact, Hasher, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
2
|
+
import { Base64urlString, Signer, Verifier, kbHeader, kbPayload, KbVerifier, JwtPayload, SDJWTCompact, Hasher, PresentationFrame, DisclosureFrame, HasherAndAlg, SaltGenerator, SDJWTConfig, KBOptions } from '@sd-jwt/types';
|
|
3
3
|
import { Disclosure } from '@sd-jwt/utils';
|
|
4
4
|
|
|
5
5
|
type JwtData<Header extends Record<string, unknown>, Payload extends Record<string, unknown>> = {
|
|
@@ -29,7 +29,10 @@ declare class Jwt<Header extends Record<string, unknown> = Record<string, unknow
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
declare class KBJwt<Header extends kbHeader = kbHeader, Payload extends kbPayload = kbPayload> extends Jwt<Header, Payload> {
|
|
32
|
-
|
|
32
|
+
verifyKB(values: {
|
|
33
|
+
verifier: KbVerifier;
|
|
34
|
+
payload: JwtPayload;
|
|
35
|
+
}): Promise<{
|
|
33
36
|
payload: Payload;
|
|
34
37
|
header: Header;
|
|
35
38
|
}>;
|
|
@@ -52,7 +55,7 @@ declare class SDJwt<Header extends Record<string, unknown> = Record<string, unkn
|
|
|
52
55
|
kbJwt?: KBJwt<KBHeader, KBPayload>;
|
|
53
56
|
}>;
|
|
54
57
|
static fromEncode<Header extends Record<string, unknown> = Record<string, unknown>, Payload extends Record<string, unknown> = Record<string, unknown>, KBHeader extends kbHeader = kbHeader, KBPayload extends kbPayload = kbPayload>(encodedSdJwt: SDJWTCompact, hasher: Hasher): Promise<SDJwt<Header, Payload>>;
|
|
55
|
-
present(
|
|
58
|
+
present<T extends Record<string, unknown>>(presentFrame: PresentationFrame<T> | undefined, hasher: Hasher): Promise<SDJWTCompact>;
|
|
56
59
|
encodeSDJwt(): SDJWTCompact;
|
|
57
60
|
keys(hasher: Hasher): Promise<string[]>;
|
|
58
61
|
presentableKeys(hasher: Hasher): Promise<string[]>;
|
|
@@ -84,7 +87,7 @@ declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
84
87
|
* @returns
|
|
85
88
|
*/
|
|
86
89
|
protected validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
|
|
87
|
-
present(encodedSDJwt: string,
|
|
90
|
+
present<T extends Record<string, unknown>>(encodedSDJwt: string, presentationFrame?: PresentationFrame<T>, options?: {
|
|
88
91
|
kb?: KBOptions;
|
|
89
92
|
}): Promise<SDJWTCompact>;
|
|
90
93
|
verify(encodedSDJwt: string, requiredClaimKeys?: string[], requireKeyBindings?: boolean): Promise<{
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,8 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
5
5
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
9
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
9
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
11
|
-
var __reflectGet = Reflect.get;
|
|
12
10
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
13
11
|
var __spreadValues = (a, b) => {
|
|
14
12
|
for (var prop in b || (b = {}))
|
|
@@ -35,7 +33,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
35
33
|
return to;
|
|
36
34
|
};
|
|
37
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
38
|
-
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
|
|
39
36
|
var __async = (__this, __arguments, generator) => {
|
|
40
37
|
return new Promise((resolve, reject) => {
|
|
41
38
|
var fulfilled = (value) => {
|
|
@@ -132,7 +129,7 @@ var Jwt = class _Jwt {
|
|
|
132
129
|
const header = (0, import_utils.Base64urlEncode)(JSON.stringify(this.header));
|
|
133
130
|
const payload = (0, import_utils.Base64urlEncode)(JSON.stringify(this.payload));
|
|
134
131
|
const data = `${header}.${payload}`;
|
|
135
|
-
const verified = verifier(data, this.signature);
|
|
132
|
+
const verified = yield verifier(data, this.signature);
|
|
136
133
|
if (!verified) {
|
|
137
134
|
throw new import_utils.SDJWTException("Verify Error: Invalid JWT Signature");
|
|
138
135
|
}
|
|
@@ -143,16 +140,32 @@ var Jwt = class _Jwt {
|
|
|
143
140
|
|
|
144
141
|
// src/kbjwt.ts
|
|
145
142
|
var import_utils2 = require("@sd-jwt/utils");
|
|
143
|
+
var import_types = require("@sd-jwt/types");
|
|
146
144
|
var KBJwt = class _KBJwt extends Jwt {
|
|
147
145
|
// Checking the validity of the key binding jwt
|
|
148
|
-
|
|
146
|
+
// 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
|
|
147
|
+
verifyKB(values) {
|
|
149
148
|
return __async(this, null, function* () {
|
|
150
|
-
var _a
|
|
151
|
-
if (!
|
|
152
|
-
|
|
149
|
+
var _a;
|
|
150
|
+
if (!this.header || !this.payload || !this.signature) {
|
|
151
|
+
throw new import_utils2.SDJWTException("Verify Error: Invalid JWT");
|
|
152
|
+
}
|
|
153
|
+
if (!this.header.alg || this.header.alg === "none" || !this.header.typ || this.header.typ !== import_types.KB_JWT_TYP || !this.payload.iat || !this.payload.aud || !this.payload.nonce || // this is for backward compatibility with version 06
|
|
154
|
+
!(this.payload.sd_hash || ((_a = this.payload) == null ? void 0 : _a._sd_hash))) {
|
|
153
155
|
throw new import_utils2.SDJWTException("Invalid Key Binding Jwt");
|
|
154
156
|
}
|
|
155
|
-
|
|
157
|
+
const header = (0, import_utils2.Base64urlEncode)(JSON.stringify(this.header));
|
|
158
|
+
const payload = (0, import_utils2.Base64urlEncode)(JSON.stringify(this.payload));
|
|
159
|
+
const data = `${header}.${payload}`;
|
|
160
|
+
const verified = yield values.verifier(
|
|
161
|
+
data,
|
|
162
|
+
this.signature,
|
|
163
|
+
values.payload
|
|
164
|
+
);
|
|
165
|
+
if (!verified) {
|
|
166
|
+
throw new import_utils2.SDJWTException("Verify Error: Invalid JWT Signature");
|
|
167
|
+
}
|
|
168
|
+
return { payload: this.payload, header: this.header };
|
|
156
169
|
});
|
|
157
170
|
}
|
|
158
171
|
// This function is for creating KBJwt object for verify properly
|
|
@@ -180,8 +193,9 @@ var createDecoy = (hash, saltGenerator) => __async(void 0, null, function* () {
|
|
|
180
193
|
|
|
181
194
|
// src/sdjwt.ts
|
|
182
195
|
var import_utils4 = require("@sd-jwt/utils");
|
|
183
|
-
var
|
|
196
|
+
var import_types2 = require("@sd-jwt/types");
|
|
184
197
|
var import_decode2 = require("@sd-jwt/decode");
|
|
198
|
+
var import_present = require("@sd-jwt/present");
|
|
185
199
|
var SDJwt = class _SDJwt {
|
|
186
200
|
constructor(data) {
|
|
187
201
|
this.jwt = data == null ? void 0 : data.jwt;
|
|
@@ -190,7 +204,7 @@ var SDJwt = class _SDJwt {
|
|
|
190
204
|
}
|
|
191
205
|
static decodeSDJwt(sdjwt, hasher) {
|
|
192
206
|
return __async(this, null, function* () {
|
|
193
|
-
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(
|
|
207
|
+
const [encodedJwt, ...encodedDisclosures] = sdjwt.split(import_types2.SD_SEPARATOR);
|
|
194
208
|
const jwt = Jwt.fromEncode(encodedJwt);
|
|
195
209
|
if (!jwt.payload) {
|
|
196
210
|
throw new Error("Payload is undefined on the JWT. Invalid state reached");
|
|
@@ -226,7 +240,7 @@ var SDJwt = class _SDJwt {
|
|
|
226
240
|
});
|
|
227
241
|
});
|
|
228
242
|
}
|
|
229
|
-
present(
|
|
243
|
+
present(presentFrame, hasher) {
|
|
230
244
|
return __async(this, null, function* () {
|
|
231
245
|
var _a;
|
|
232
246
|
if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
|
|
@@ -240,14 +254,8 @@ var SDJwt = class _SDJwt {
|
|
|
240
254
|
this.disclosures,
|
|
241
255
|
hasher
|
|
242
256
|
);
|
|
243
|
-
const
|
|
244
|
-
const
|
|
245
|
-
if (missingKeys.length > 0) {
|
|
246
|
-
throw new import_utils4.SDJWTException(
|
|
247
|
-
`Invalid sd-jwt: invalid present keys: ${missingKeys.join(", ")}`
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
const disclosures = keys.map((k) => hashmap[disclosureKeymap[k]]);
|
|
257
|
+
const keys = presentFrame ? (0, import_present.transformPresentationFrame)(presentFrame) : yield this.presentableKeys(hasher);
|
|
258
|
+
const disclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
|
|
251
259
|
const presentSDJwt = new _SDJwt({
|
|
252
260
|
jwt: this.jwt,
|
|
253
261
|
disclosures,
|
|
@@ -264,11 +272,11 @@ var SDJwt = class _SDJwt {
|
|
|
264
272
|
const encodedJwt = this.jwt.encodeJwt();
|
|
265
273
|
data.push(encodedJwt);
|
|
266
274
|
if (this.disclosures && this.disclosures.length > 0) {
|
|
267
|
-
const encodeddisclosures = this.disclosures.map((dc) => dc.encode()).join(
|
|
275
|
+
const encodeddisclosures = this.disclosures.map((dc) => dc.encode()).join(import_types2.SD_SEPARATOR);
|
|
268
276
|
data.push(encodeddisclosures);
|
|
269
277
|
}
|
|
270
278
|
data.push(this.kbJwt ? this.kbJwt.encodeJwt() : "");
|
|
271
|
-
return data.join(
|
|
279
|
+
return data.join(import_types2.SD_SEPARATOR);
|
|
272
280
|
}
|
|
273
281
|
keys(hasher) {
|
|
274
282
|
return __async(this, null, function* () {
|
|
@@ -325,14 +333,14 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
325
333
|
disclosures: []
|
|
326
334
|
};
|
|
327
335
|
}
|
|
328
|
-
const sd = (_a = disclosureFrame[
|
|
329
|
-
const decoyCount = (_b = disclosureFrame[
|
|
336
|
+
const sd = (_a = disclosureFrame[import_types2.SD_DIGEST]) != null ? _a : [];
|
|
337
|
+
const decoyCount = (_b = disclosureFrame[import_types2.SD_DECOY]) != null ? _b : 0;
|
|
330
338
|
if (Array.isArray(claims)) {
|
|
331
339
|
const packedClaims2 = [];
|
|
332
340
|
const disclosures2 = [];
|
|
333
341
|
const recursivePackedClaims2 = {};
|
|
334
342
|
for (const key in disclosureFrame) {
|
|
335
|
-
if (key !==
|
|
343
|
+
if (key !== import_types2.SD_DIGEST) {
|
|
336
344
|
const idx = parseInt(key);
|
|
337
345
|
const packed = yield pack(
|
|
338
346
|
claims[idx],
|
|
@@ -350,7 +358,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
350
358
|
const salt = yield saltGenerator(16);
|
|
351
359
|
const disclosure = new import_utils4.Disclosure([salt, claim]);
|
|
352
360
|
const digest = yield disclosure.digest(hash);
|
|
353
|
-
packedClaims2.push({ [
|
|
361
|
+
packedClaims2.push({ [import_types2.SD_LIST_KEY]: digest });
|
|
354
362
|
disclosures2.push(disclosure);
|
|
355
363
|
} else {
|
|
356
364
|
packedClaims2.push(claim);
|
|
@@ -358,7 +366,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
358
366
|
}
|
|
359
367
|
for (let j = 0; j < decoyCount; j++) {
|
|
360
368
|
const decoyDigest = yield createDecoy(hash, saltGenerator);
|
|
361
|
-
packedClaims2.push({ [
|
|
369
|
+
packedClaims2.push({ [import_types2.SD_LIST_KEY]: decoyDigest });
|
|
362
370
|
}
|
|
363
371
|
return { packedClaims: packedClaims2, disclosures: disclosures2 };
|
|
364
372
|
}
|
|
@@ -366,7 +374,7 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
366
374
|
const disclosures = [];
|
|
367
375
|
const recursivePackedClaims = {};
|
|
368
376
|
for (const key in disclosureFrame) {
|
|
369
|
-
if (key !==
|
|
377
|
+
if (key !== import_types2.SD_DIGEST) {
|
|
370
378
|
const packed = yield pack(
|
|
371
379
|
// @ts-ignore
|
|
372
380
|
claims[key],
|
|
@@ -396,13 +404,13 @@ var pack = (claims, disclosureFrame, hash, saltGenerator) => __async(void 0, nul
|
|
|
396
404
|
_sd.push(decoyDigest);
|
|
397
405
|
}
|
|
398
406
|
if (_sd.length > 0) {
|
|
399
|
-
packedClaims[
|
|
407
|
+
packedClaims[import_types2.SD_DIGEST] = _sd.sort();
|
|
400
408
|
}
|
|
401
409
|
return { packedClaims, disclosures };
|
|
402
410
|
});
|
|
403
411
|
|
|
404
412
|
// src/index.ts
|
|
405
|
-
var
|
|
413
|
+
var import_types3 = require("@sd-jwt/types");
|
|
406
414
|
var import_decode3 = require("@sd-jwt/decode");
|
|
407
415
|
var _SDJwtInstance = class _SDJwtInstance {
|
|
408
416
|
constructor(userConfig) {
|
|
@@ -422,7 +430,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
422
430
|
const { payload } = options;
|
|
423
431
|
const kbJwt = new KBJwt({
|
|
424
432
|
header: {
|
|
425
|
-
typ:
|
|
433
|
+
typ: import_types3.KB_JWT_TYP,
|
|
426
434
|
alg: this.userConfig.kbSignAlg
|
|
427
435
|
},
|
|
428
436
|
payload: __spreadProps(__spreadValues({}, payload), { sd_hash: sdHash })
|
|
@@ -497,11 +505,9 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
497
505
|
validateReservedFields(disclosureFrame) {
|
|
498
506
|
return;
|
|
499
507
|
}
|
|
500
|
-
present(encodedSDJwt,
|
|
508
|
+
present(encodedSDJwt, presentationFrame, options) {
|
|
501
509
|
return __async(this, null, function* () {
|
|
502
510
|
var _a;
|
|
503
|
-
if (!presentationKeys)
|
|
504
|
-
return encodedSDJwt;
|
|
505
511
|
if (!this.userConfig.hasher) {
|
|
506
512
|
throw new import_utils5.SDJWTException("Hasher not found");
|
|
507
513
|
}
|
|
@@ -510,7 +516,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
510
516
|
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload))
|
|
511
517
|
throw new import_utils5.SDJWTException("Payload not found");
|
|
512
518
|
const presentSdJwtWithoutKb = yield sdjwt.present(
|
|
513
|
-
|
|
519
|
+
presentationFrame,
|
|
514
520
|
hasher
|
|
515
521
|
);
|
|
516
522
|
if (!(options == null ? void 0 : options.kb)) {
|
|
@@ -522,7 +528,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
522
528
|
hasher
|
|
523
529
|
);
|
|
524
530
|
sdjwt.kbJwt = yield this.createKBJwt(options.kb, sdHashStr);
|
|
525
|
-
return sdjwt.present(
|
|
531
|
+
return sdjwt.present(presentationFrame, hasher);
|
|
526
532
|
});
|
|
527
533
|
}
|
|
528
534
|
// This function is for verifying the SD JWT
|
|
@@ -557,7 +563,13 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
557
563
|
if (!this.userConfig.kbVerifier) {
|
|
558
564
|
throw new import_utils5.SDJWTException("Key Binding Verifier not found");
|
|
559
565
|
}
|
|
560
|
-
const kb = yield sdjwt.kbJwt.
|
|
566
|
+
const kb = yield sdjwt.kbJwt.verifyKB({
|
|
567
|
+
verifier: this.userConfig.kbVerifier,
|
|
568
|
+
payload
|
|
569
|
+
});
|
|
570
|
+
if (!kb) {
|
|
571
|
+
throw new Error("signature is not valid");
|
|
572
|
+
}
|
|
561
573
|
const sdHashfromKb = kb.payload.sd_hash;
|
|
562
574
|
const sdjwtWithoutKb = new SDJwt({
|
|
563
575
|
jwt: sdjwt.jwt,
|
package/dist/index.mjs
CHANGED
|
@@ -2,10 +2,8 @@ var __defProp = Object.defineProperty;
|
|
|
2
2
|
var __defProps = Object.defineProperties;
|
|
3
3
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
-
var __reflectGet = Reflect.get;
|
|
9
7
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
10
8
|
var __spreadValues = (a, b) => {
|
|
11
9
|
for (var prop in b || (b = {}))
|
|
@@ -19,7 +17,6 @@ var __spreadValues = (a, b) => {
|
|
|
19
17
|
return a;
|
|
20
18
|
};
|
|
21
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
22
|
-
var __superGet = (cls, obj, key) => __reflectGet(__getProtoOf(cls), key, obj);
|
|
23
20
|
var __async = (__this, __arguments, generator) => {
|
|
24
21
|
return new Promise((resolve, reject) => {
|
|
25
22
|
var fulfilled = (value) => {
|
|
@@ -105,7 +102,7 @@ var Jwt = class _Jwt {
|
|
|
105
102
|
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
106
103
|
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
107
104
|
const data = `${header}.${payload}`;
|
|
108
|
-
const verified = verifier(data, this.signature);
|
|
105
|
+
const verified = yield verifier(data, this.signature);
|
|
109
106
|
if (!verified) {
|
|
110
107
|
throw new SDJWTException("Verify Error: Invalid JWT Signature");
|
|
111
108
|
}
|
|
@@ -115,17 +112,35 @@ var Jwt = class _Jwt {
|
|
|
115
112
|
};
|
|
116
113
|
|
|
117
114
|
// src/kbjwt.ts
|
|
118
|
-
import { SDJWTException as SDJWTException2 } from "@sd-jwt/utils";
|
|
115
|
+
import { Base64urlEncode as Base64urlEncode2, SDJWTException as SDJWTException2 } from "@sd-jwt/utils";
|
|
116
|
+
import {
|
|
117
|
+
KB_JWT_TYP
|
|
118
|
+
} from "@sd-jwt/types";
|
|
119
119
|
var KBJwt = class _KBJwt extends Jwt {
|
|
120
120
|
// Checking the validity of the key binding jwt
|
|
121
|
-
|
|
121
|
+
// 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
|
|
122
|
+
verifyKB(values) {
|
|
122
123
|
return __async(this, null, function* () {
|
|
123
|
-
var _a
|
|
124
|
-
if (!
|
|
125
|
-
|
|
124
|
+
var _a;
|
|
125
|
+
if (!this.header || !this.payload || !this.signature) {
|
|
126
|
+
throw new SDJWTException2("Verify Error: Invalid JWT");
|
|
127
|
+
}
|
|
128
|
+
if (!this.header.alg || this.header.alg === "none" || !this.header.typ || this.header.typ !== KB_JWT_TYP || !this.payload.iat || !this.payload.aud || !this.payload.nonce || // this is for backward compatibility with version 06
|
|
129
|
+
!(this.payload.sd_hash || ((_a = this.payload) == null ? void 0 : _a._sd_hash))) {
|
|
126
130
|
throw new SDJWTException2("Invalid Key Binding Jwt");
|
|
127
131
|
}
|
|
128
|
-
|
|
132
|
+
const header = Base64urlEncode2(JSON.stringify(this.header));
|
|
133
|
+
const payload = Base64urlEncode2(JSON.stringify(this.payload));
|
|
134
|
+
const data = `${header}.${payload}`;
|
|
135
|
+
const verified = yield values.verifier(
|
|
136
|
+
data,
|
|
137
|
+
this.signature,
|
|
138
|
+
values.payload
|
|
139
|
+
);
|
|
140
|
+
if (!verified) {
|
|
141
|
+
throw new SDJWTException2("Verify Error: Invalid JWT Signature");
|
|
142
|
+
}
|
|
143
|
+
return { payload: this.payload, header: this.header };
|
|
129
144
|
});
|
|
130
145
|
}
|
|
131
146
|
// This function is for creating KBJwt object for verify properly
|
|
@@ -160,6 +175,7 @@ import {
|
|
|
160
175
|
SD_SEPARATOR
|
|
161
176
|
} from "@sd-jwt/types";
|
|
162
177
|
import { createHashMapping, getSDAlgAndPayload, unpack } from "@sd-jwt/decode";
|
|
178
|
+
import { transformPresentationFrame } from "@sd-jwt/present";
|
|
163
179
|
var SDJwt = class _SDJwt {
|
|
164
180
|
constructor(data) {
|
|
165
181
|
this.jwt = data == null ? void 0 : data.jwt;
|
|
@@ -204,7 +220,7 @@ var SDJwt = class _SDJwt {
|
|
|
204
220
|
});
|
|
205
221
|
});
|
|
206
222
|
}
|
|
207
|
-
present(
|
|
223
|
+
present(presentFrame, hasher) {
|
|
208
224
|
return __async(this, null, function* () {
|
|
209
225
|
var _a;
|
|
210
226
|
if (!((_a = this.jwt) == null ? void 0 : _a.payload) || !this.disclosures) {
|
|
@@ -218,14 +234,8 @@ var SDJwt = class _SDJwt {
|
|
|
218
234
|
this.disclosures,
|
|
219
235
|
hasher
|
|
220
236
|
);
|
|
221
|
-
const
|
|
222
|
-
const
|
|
223
|
-
if (missingKeys.length > 0) {
|
|
224
|
-
throw new SDJWTException3(
|
|
225
|
-
`Invalid sd-jwt: invalid present keys: ${missingKeys.join(", ")}`
|
|
226
|
-
);
|
|
227
|
-
}
|
|
228
|
-
const disclosures = keys.map((k) => hashmap[disclosureKeymap[k]]);
|
|
237
|
+
const keys = presentFrame ? transformPresentationFrame(presentFrame) : yield this.presentableKeys(hasher);
|
|
238
|
+
const disclosures = keys.map((k) => hashmap[disclosureKeymap[k]]).filter((d) => d !== void 0);
|
|
229
239
|
const presentSDJwt = new _SDJwt({
|
|
230
240
|
jwt: this.jwt,
|
|
231
241
|
disclosures,
|
|
@@ -477,11 +487,9 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
477
487
|
validateReservedFields(disclosureFrame) {
|
|
478
488
|
return;
|
|
479
489
|
}
|
|
480
|
-
present(encodedSDJwt,
|
|
490
|
+
present(encodedSDJwt, presentationFrame, options) {
|
|
481
491
|
return __async(this, null, function* () {
|
|
482
492
|
var _a;
|
|
483
|
-
if (!presentationKeys)
|
|
484
|
-
return encodedSDJwt;
|
|
485
493
|
if (!this.userConfig.hasher) {
|
|
486
494
|
throw new SDJWTException4("Hasher not found");
|
|
487
495
|
}
|
|
@@ -490,7 +498,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
490
498
|
if (!((_a = sdjwt.jwt) == null ? void 0 : _a.payload))
|
|
491
499
|
throw new SDJWTException4("Payload not found");
|
|
492
500
|
const presentSdJwtWithoutKb = yield sdjwt.present(
|
|
493
|
-
|
|
501
|
+
presentationFrame,
|
|
494
502
|
hasher
|
|
495
503
|
);
|
|
496
504
|
if (!(options == null ? void 0 : options.kb)) {
|
|
@@ -502,7 +510,7 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
502
510
|
hasher
|
|
503
511
|
);
|
|
504
512
|
sdjwt.kbJwt = yield this.createKBJwt(options.kb, sdHashStr);
|
|
505
|
-
return sdjwt.present(
|
|
513
|
+
return sdjwt.present(presentationFrame, hasher);
|
|
506
514
|
});
|
|
507
515
|
}
|
|
508
516
|
// This function is for verifying the SD JWT
|
|
@@ -537,7 +545,13 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
537
545
|
if (!this.userConfig.kbVerifier) {
|
|
538
546
|
throw new SDJWTException4("Key Binding Verifier not found");
|
|
539
547
|
}
|
|
540
|
-
const kb = yield sdjwt.kbJwt.
|
|
548
|
+
const kb = yield sdjwt.kbJwt.verifyKB({
|
|
549
|
+
verifier: this.userConfig.kbVerifier,
|
|
550
|
+
payload
|
|
551
|
+
});
|
|
552
|
+
if (!kb) {
|
|
553
|
+
throw new Error("signature is not valid");
|
|
554
|
+
}
|
|
541
555
|
const sdHashfromKb = kb.payload.sd_hash;
|
|
542
556
|
const sdjwtWithoutKb = new SDJwt({
|
|
543
557
|
jwt: sdjwt.jwt,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sd-jwt/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "sd-jwt draft 7 implementation in typescript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -38,12 +38,13 @@
|
|
|
38
38
|
},
|
|
39
39
|
"license": "Apache-2.0",
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@sd-jwt/crypto-nodejs": "0.
|
|
41
|
+
"@sd-jwt/crypto-nodejs": "0.4.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@sd-jwt/decode": "0.
|
|
45
|
-
"@sd-jwt/
|
|
46
|
-
"@sd-jwt/
|
|
44
|
+
"@sd-jwt/decode": "0.4.0",
|
|
45
|
+
"@sd-jwt/present": "0.4.0",
|
|
46
|
+
"@sd-jwt/types": "0.4.0",
|
|
47
|
+
"@sd-jwt/utils": "0.4.0"
|
|
47
48
|
},
|
|
48
49
|
"publishConfig": {
|
|
49
50
|
"access": "public"
|
|
@@ -61,5 +62,5 @@
|
|
|
61
62
|
"esm"
|
|
62
63
|
]
|
|
63
64
|
},
|
|
64
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "391a36550a66833b3d393ff0deb699b1b72cca59"
|
|
65
66
|
}
|
package/src/index.ts
CHANGED
|
@@ -7,10 +7,12 @@ import {
|
|
|
7
7
|
Hasher,
|
|
8
8
|
KBOptions,
|
|
9
9
|
KB_JWT_TYP,
|
|
10
|
+
PresentationFrame,
|
|
10
11
|
SDJWTCompact,
|
|
11
12
|
SDJWTConfig,
|
|
12
13
|
} from '@sd-jwt/types';
|
|
13
14
|
import { getSDAlgAndPayload } from '@sd-jwt/decode';
|
|
15
|
+
import { JwtPayload } from '@sd-jwt/types';
|
|
14
16
|
|
|
15
17
|
export * from './sdjwt';
|
|
16
18
|
export * from './kbjwt';
|
|
@@ -138,14 +140,13 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
138
140
|
return;
|
|
139
141
|
}
|
|
140
142
|
|
|
141
|
-
public async present(
|
|
143
|
+
public async present<T extends Record<string, unknown>>(
|
|
142
144
|
encodedSDJwt: string,
|
|
143
|
-
|
|
145
|
+
presentationFrame?: PresentationFrame<T>,
|
|
144
146
|
options?: {
|
|
145
147
|
kb?: KBOptions;
|
|
146
148
|
},
|
|
147
149
|
): Promise<SDJWTCompact> {
|
|
148
|
-
if (!presentationKeys) return encodedSDJwt;
|
|
149
150
|
if (!this.userConfig.hasher) {
|
|
150
151
|
throw new SDJWTException('Hasher not found');
|
|
151
152
|
}
|
|
@@ -155,7 +156,7 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
155
156
|
|
|
156
157
|
if (!sdjwt.jwt?.payload) throw new SDJWTException('Payload not found');
|
|
157
158
|
const presentSdJwtWithoutKb = await sdjwt.present(
|
|
158
|
-
|
|
159
|
+
presentationFrame,
|
|
159
160
|
hasher,
|
|
160
161
|
);
|
|
161
162
|
|
|
@@ -170,7 +171,7 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
170
171
|
);
|
|
171
172
|
|
|
172
173
|
sdjwt.kbJwt = await this.createKBJwt(options.kb, sdHashStr);
|
|
173
|
-
return sdjwt.present(
|
|
174
|
+
return sdjwt.present(presentationFrame, hasher);
|
|
174
175
|
}
|
|
175
176
|
|
|
176
177
|
// This function is for verifying the SD JWT
|
|
@@ -212,7 +213,13 @@ export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
212
213
|
if (!this.userConfig.kbVerifier) {
|
|
213
214
|
throw new SDJWTException('Key Binding Verifier not found');
|
|
214
215
|
}
|
|
215
|
-
const kb = await sdjwt.kbJwt.
|
|
216
|
+
const kb = await sdjwt.kbJwt.verifyKB({
|
|
217
|
+
verifier: this.userConfig.kbVerifier,
|
|
218
|
+
payload: payload as JwtPayload,
|
|
219
|
+
});
|
|
220
|
+
if (!kb) {
|
|
221
|
+
throw new Error('signature is not valid');
|
|
222
|
+
}
|
|
216
223
|
const sdHashfromKb = kb.payload.sd_hash;
|
|
217
224
|
const sdjwtWithoutKb = new SDJwt({
|
|
218
225
|
jwt: sdjwt.jwt,
|
package/src/jwt.ts
CHANGED
|
@@ -98,7 +98,7 @@ export class Jwt<
|
|
|
98
98
|
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
99
99
|
const data = `${header}.${payload}`;
|
|
100
100
|
|
|
101
|
-
const verified = verifier(data, this.signature);
|
|
101
|
+
const verified = await verifier(data, this.signature);
|
|
102
102
|
if (!verified) {
|
|
103
103
|
throw new SDJWTException('Verify Error: Invalid JWT Signature');
|
|
104
104
|
}
|
package/src/kbjwt.ts
CHANGED
|
@@ -1,28 +1,53 @@
|
|
|
1
|
-
import { SDJWTException } from '@sd-jwt/utils';
|
|
1
|
+
import { Base64urlEncode, SDJWTException } from '@sd-jwt/utils';
|
|
2
2
|
import { Jwt } from './jwt';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
JwtPayload,
|
|
5
|
+
KB_JWT_TYP,
|
|
6
|
+
kbHeader,
|
|
7
|
+
kbPayload,
|
|
8
|
+
KbVerifier,
|
|
9
|
+
} from '@sd-jwt/types';
|
|
4
10
|
|
|
5
11
|
export class KBJwt<
|
|
6
12
|
Header extends kbHeader = kbHeader,
|
|
7
13
|
Payload extends kbPayload = kbPayload,
|
|
8
14
|
> extends Jwt<Header, Payload> {
|
|
9
15
|
// Checking the validity of the key binding jwt
|
|
10
|
-
public
|
|
16
|
+
// 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
|
|
17
|
+
public async verifyKB(values: { verifier: KbVerifier; payload: JwtPayload }) {
|
|
18
|
+
if (!this.header || !this.payload || !this.signature) {
|
|
19
|
+
throw new SDJWTException('Verify Error: Invalid JWT');
|
|
20
|
+
}
|
|
21
|
+
|
|
11
22
|
if (
|
|
12
|
-
!this.header
|
|
23
|
+
!this.header.alg ||
|
|
24
|
+
this.header.alg === 'none' ||
|
|
13
25
|
!this.header.typ ||
|
|
14
|
-
|
|
15
|
-
!this.payload
|
|
16
|
-
!this.payload
|
|
26
|
+
this.header.typ !== KB_JWT_TYP ||
|
|
27
|
+
!this.payload.iat ||
|
|
28
|
+
!this.payload.aud ||
|
|
29
|
+
!this.payload.nonce ||
|
|
17
30
|
// this is for backward compatibility with version 06
|
|
18
31
|
!(
|
|
19
|
-
this.payload
|
|
32
|
+
this.payload.sd_hash ||
|
|
20
33
|
(this.payload as Record<string, unknown> | undefined)?._sd_hash
|
|
21
34
|
)
|
|
22
35
|
) {
|
|
23
36
|
throw new SDJWTException('Invalid Key Binding Jwt');
|
|
24
37
|
}
|
|
25
|
-
|
|
38
|
+
|
|
39
|
+
const header = Base64urlEncode(JSON.stringify(this.header));
|
|
40
|
+
const payload = Base64urlEncode(JSON.stringify(this.payload));
|
|
41
|
+
const data = `${header}.${payload}`;
|
|
42
|
+
const verified = await values.verifier(
|
|
43
|
+
data,
|
|
44
|
+
this.signature,
|
|
45
|
+
values.payload,
|
|
46
|
+
);
|
|
47
|
+
if (!verified) {
|
|
48
|
+
throw new SDJWTException('Verify Error: Invalid JWT Signature');
|
|
49
|
+
}
|
|
50
|
+
return { payload: this.payload, header: this.header };
|
|
26
51
|
}
|
|
27
52
|
|
|
28
53
|
// This function is for creating KBJwt object for verify properly
|