@sd-jwt/core 0.3.2-next.94 → 0.3.2-next.95
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/README.md +2 -1
- package/dist/index.d.mts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +8 -0
- package/dist/index.mjs +8 -0
- package/package.json +8 -9
- package/src/index.ts +11 -4
- package/src/test/index.spec.ts +64 -27
- package/test/app-e2e.spec.ts +6 -7
package/README.md
CHANGED
|
@@ -32,7 +32,8 @@ Ensure you have Node.js installed as a prerequisite.
|
|
|
32
32
|
|
|
33
33
|
### Usage
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
The library can be used to create sd-jwt based credentials. To be compliant with the `sd-jwt-vc` standard, you can use the `@sd-jwt/sd-jwt-vc` that is implementing this spec.
|
|
36
|
+
If you want to use the pure sd-jwt class or implement your own sd-jwt credential approach, you can use this library.
|
|
36
37
|
|
|
37
38
|
### Dependencies
|
|
38
39
|
|
package/dist/index.d.mts
CHANGED
|
@@ -67,8 +67,8 @@ declare const pack: <T extends Record<string, unknown>>(claims: T, disclosureFra
|
|
|
67
67
|
declare const createDecoy: (hash: HasherAndAlg, saltGenerator: SaltGenerator) => Promise<string>;
|
|
68
68
|
|
|
69
69
|
type SdJwtPayload = Record<string, unknown>;
|
|
70
|
-
declare
|
|
71
|
-
protected
|
|
70
|
+
declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
71
|
+
protected type?: string;
|
|
72
72
|
static DEFAULT_hashAlg: string;
|
|
73
73
|
private userConfig;
|
|
74
74
|
constructor(userConfig?: SDJWTConfig);
|
|
@@ -78,7 +78,12 @@ declare abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
78
78
|
issue<Payload extends ExtendedPayload>(payload: Payload, disclosureFrame?: DisclosureFrame<Payload>, options?: {
|
|
79
79
|
header?: object;
|
|
80
80
|
}): Promise<SDJWTCompact>;
|
|
81
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
|
|
83
|
+
* @param disclosureFrame
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
protected validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
|
|
82
87
|
present(encodedSDJwt: string, presentationKeys?: string[], options?: {
|
|
83
88
|
kb?: KBOptions;
|
|
84
89
|
}): Promise<SDJWTCompact>;
|
package/dist/index.d.ts
CHANGED
|
@@ -67,8 +67,8 @@ declare const pack: <T extends Record<string, unknown>>(claims: T, disclosureFra
|
|
|
67
67
|
declare const createDecoy: (hash: HasherAndAlg, saltGenerator: SaltGenerator) => Promise<string>;
|
|
68
68
|
|
|
69
69
|
type SdJwtPayload = Record<string, unknown>;
|
|
70
|
-
declare
|
|
71
|
-
protected
|
|
70
|
+
declare class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
71
|
+
protected type?: string;
|
|
72
72
|
static DEFAULT_hashAlg: string;
|
|
73
73
|
private userConfig;
|
|
74
74
|
constructor(userConfig?: SDJWTConfig);
|
|
@@ -78,7 +78,12 @@ declare abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
78
78
|
issue<Payload extends ExtendedPayload>(payload: Payload, disclosureFrame?: DisclosureFrame<Payload>, options?: {
|
|
79
79
|
header?: object;
|
|
80
80
|
}): Promise<SDJWTCompact>;
|
|
81
|
-
|
|
81
|
+
/**
|
|
82
|
+
* Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
|
|
83
|
+
* @param disclosureFrame
|
|
84
|
+
* @returns
|
|
85
|
+
*/
|
|
86
|
+
protected validateReservedFields<T extends ExtendedPayload>(disclosureFrame: DisclosureFrame<T>): void;
|
|
82
87
|
present(encodedSDJwt: string, presentationKeys?: string[], options?: {
|
|
83
88
|
kb?: KBOptions;
|
|
84
89
|
}): Promise<SDJWTCompact>;
|
package/dist/index.js
CHANGED
|
@@ -489,6 +489,14 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
489
489
|
return sdJwt.encodeSDJwt();
|
|
490
490
|
});
|
|
491
491
|
}
|
|
492
|
+
/**
|
|
493
|
+
* Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
|
|
494
|
+
* @param disclosureFrame
|
|
495
|
+
* @returns
|
|
496
|
+
*/
|
|
497
|
+
validateReservedFields(disclosureFrame) {
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
492
500
|
present(encodedSDJwt, presentationKeys, options) {
|
|
493
501
|
return __async(this, null, function* () {
|
|
494
502
|
var _a;
|
package/dist/index.mjs
CHANGED
|
@@ -469,6 +469,14 @@ var _SDJwtInstance = class _SDJwtInstance {
|
|
|
469
469
|
return sdJwt.encodeSDJwt();
|
|
470
470
|
});
|
|
471
471
|
}
|
|
472
|
+
/**
|
|
473
|
+
* Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
|
|
474
|
+
* @param disclosureFrame
|
|
475
|
+
* @returns
|
|
476
|
+
*/
|
|
477
|
+
validateReservedFields(disclosureFrame) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
472
480
|
present(encodedSDJwt, presentationKeys, options) {
|
|
473
481
|
return __async(this, null, function* () {
|
|
474
482
|
var _a;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sd-jwt/core",
|
|
3
|
-
"version": "0.3.2-next.
|
|
3
|
+
"version": "0.3.2-next.95+a2daee4",
|
|
4
4
|
"description": "sd-jwt draft 7 implementation in typescript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -14,10 +14,9 @@
|
|
|
14
14
|
"scripts": {
|
|
15
15
|
"build": "rm -rf **/dist && tsup",
|
|
16
16
|
"lint": "biome lint ./src",
|
|
17
|
-
"test": "pnpm run test:node && pnpm run test:browser && pnpm run test:
|
|
18
|
-
"test:node": "vitest run ./src/test/*.spec.ts
|
|
17
|
+
"test": "pnpm run test:node && pnpm run test:browser && pnpm run test:cov",
|
|
18
|
+
"test:node": "vitest run ./src/test/*.spec.ts",
|
|
19
19
|
"test:browser": "vitest run ./src/test/*.spec.ts --environment jsdom",
|
|
20
|
-
"test:e2e": "vitest run ./test/*e2e.spec.ts --environment node",
|
|
21
20
|
"test:cov": "vitest run --coverage"
|
|
22
21
|
},
|
|
23
22
|
"keywords": [
|
|
@@ -39,12 +38,12 @@
|
|
|
39
38
|
},
|
|
40
39
|
"license": "Apache-2.0",
|
|
41
40
|
"devDependencies": {
|
|
42
|
-
"@sd-jwt/crypto-nodejs": "0.3.2-next.
|
|
41
|
+
"@sd-jwt/crypto-nodejs": "0.3.2-next.95+a2daee4"
|
|
43
42
|
},
|
|
44
43
|
"dependencies": {
|
|
45
|
-
"@sd-jwt/decode": "0.3.2-next.
|
|
46
|
-
"@sd-jwt/types": "0.3.2-next.
|
|
47
|
-
"@sd-jwt/utils": "0.3.2-next.
|
|
44
|
+
"@sd-jwt/decode": "0.3.2-next.95+a2daee4",
|
|
45
|
+
"@sd-jwt/types": "0.3.2-next.95+a2daee4",
|
|
46
|
+
"@sd-jwt/utils": "0.3.2-next.95+a2daee4"
|
|
48
47
|
},
|
|
49
48
|
"publishConfig": {
|
|
50
49
|
"access": "public"
|
|
@@ -62,5 +61,5 @@
|
|
|
62
61
|
"esm"
|
|
63
62
|
]
|
|
64
63
|
},
|
|
65
|
-
"gitHead": "
|
|
64
|
+
"gitHead": "a2daee4acc8def8b4d5871b36f740f0f5d50479d"
|
|
66
65
|
}
|
package/src/index.ts
CHANGED
|
@@ -19,9 +19,9 @@ export * from './decoy';
|
|
|
19
19
|
|
|
20
20
|
export type SdJwtPayload = Record<string, unknown>;
|
|
21
21
|
|
|
22
|
-
export
|
|
22
|
+
export class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
23
23
|
//header type
|
|
24
|
-
protected
|
|
24
|
+
protected type?: string;
|
|
25
25
|
|
|
26
26
|
public static DEFAULT_hashAlg = 'sha-256';
|
|
27
27
|
|
|
@@ -127,9 +127,16 @@ export abstract class SDJwtInstance<ExtendedPayload extends SdJwtPayload> {
|
|
|
127
127
|
return sdJwt.encodeSDJwt();
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Validates if the disclosureFrame contains any reserved fields. If so it will throw an error.
|
|
132
|
+
* @param disclosureFrame
|
|
133
|
+
* @returns
|
|
134
|
+
*/
|
|
135
|
+
protected validateReservedFields<T extends ExtendedPayload>(
|
|
131
136
|
disclosureFrame: DisclosureFrame<T>,
|
|
132
|
-
)
|
|
137
|
+
) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
133
140
|
|
|
134
141
|
public async present(
|
|
135
142
|
encodedSDJwt: string,
|
package/src/test/index.spec.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import { SDJwtInstance, SdJwtPayload } from '../index';
|
|
2
|
-
import {
|
|
2
|
+
import { Signer, Verifier } from '@sd-jwt/types';
|
|
3
3
|
import Crypto from 'node:crypto';
|
|
4
4
|
import { describe, expect, test } from 'vitest';
|
|
5
5
|
import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
|
|
6
6
|
|
|
7
|
-
export class TestInstance extends SDJwtInstance<SdJwtPayload> {
|
|
8
|
-
protected type = 'sd-jwt';
|
|
9
|
-
|
|
10
|
-
protected validateReservedFields(
|
|
11
|
-
disclosureFrame: DisclosureFrame<SdJwtPayload>,
|
|
12
|
-
): void {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
|
|
17
7
|
export const createSignerVerifier = () => {
|
|
18
8
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
19
9
|
const signer: Signer = async (data: string) => {
|
|
@@ -33,13 +23,13 @@ export const createSignerVerifier = () => {
|
|
|
33
23
|
|
|
34
24
|
describe('index', () => {
|
|
35
25
|
test('create', async () => {
|
|
36
|
-
const sdjwt = new
|
|
26
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>();
|
|
37
27
|
expect(sdjwt).toBeDefined();
|
|
38
28
|
});
|
|
39
29
|
|
|
40
30
|
test('kbJwt', async () => {
|
|
41
31
|
const { signer, verifier } = createSignerVerifier();
|
|
42
|
-
const sdjwt = new
|
|
32
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
43
33
|
signer,
|
|
44
34
|
signAlg: 'EdDSA',
|
|
45
35
|
verifier,
|
|
@@ -77,7 +67,7 @@ describe('index', () => {
|
|
|
77
67
|
|
|
78
68
|
test('issue', async () => {
|
|
79
69
|
const { signer, verifier } = createSignerVerifier();
|
|
80
|
-
const sdjwt = new
|
|
70
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
81
71
|
signer,
|
|
82
72
|
signAlg: 'EdDSA',
|
|
83
73
|
verifier,
|
|
@@ -111,7 +101,7 @@ describe('index', () => {
|
|
|
111
101
|
);
|
|
112
102
|
};
|
|
113
103
|
|
|
114
|
-
const sdjwt = new
|
|
104
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
115
105
|
signer,
|
|
116
106
|
signAlg: 'EdDSA',
|
|
117
107
|
verifier: failedverifier,
|
|
@@ -149,7 +139,7 @@ describe('index', () => {
|
|
|
149
139
|
Buffer.from(sig, 'base64url'),
|
|
150
140
|
);
|
|
151
141
|
};
|
|
152
|
-
const sdjwt = new
|
|
142
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
153
143
|
signer,
|
|
154
144
|
signAlg: 'EdDSA',
|
|
155
145
|
verifier,
|
|
@@ -191,7 +181,7 @@ describe('index', () => {
|
|
|
191
181
|
|
|
192
182
|
test('verify with kbJwt', async () => {
|
|
193
183
|
const { signer, verifier } = createSignerVerifier();
|
|
194
|
-
const sdjwt = new
|
|
184
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
195
185
|
signer,
|
|
196
186
|
signAlg: 'EdDSA',
|
|
197
187
|
verifier,
|
|
@@ -229,7 +219,7 @@ describe('index', () => {
|
|
|
229
219
|
});
|
|
230
220
|
|
|
231
221
|
test('Hasher not found', async () => {
|
|
232
|
-
const sdjwt = new
|
|
222
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({});
|
|
233
223
|
try {
|
|
234
224
|
const credential = await sdjwt.issue(
|
|
235
225
|
{
|
|
@@ -250,7 +240,7 @@ describe('index', () => {
|
|
|
250
240
|
});
|
|
251
241
|
|
|
252
242
|
test('SaltGenerator not found', async () => {
|
|
253
|
-
const sdjwt = new
|
|
243
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
254
244
|
hasher: digest,
|
|
255
245
|
});
|
|
256
246
|
try {
|
|
@@ -273,7 +263,7 @@ describe('index', () => {
|
|
|
273
263
|
});
|
|
274
264
|
|
|
275
265
|
test('Signer not found', async () => {
|
|
276
|
-
const sdjwt = new
|
|
266
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
277
267
|
hasher: digest,
|
|
278
268
|
saltGenerator: generateSalt,
|
|
279
269
|
});
|
|
@@ -298,7 +288,7 @@ describe('index', () => {
|
|
|
298
288
|
|
|
299
289
|
test('Verifier not found', async () => {
|
|
300
290
|
const { signer, verifier } = createSignerVerifier();
|
|
301
|
-
const sdjwt = new
|
|
291
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
302
292
|
signer,
|
|
303
293
|
hasher: digest,
|
|
304
294
|
saltGenerator: generateSalt,
|
|
@@ -338,7 +328,7 @@ describe('index', () => {
|
|
|
338
328
|
|
|
339
329
|
test('kbSigner not found', async () => {
|
|
340
330
|
const { signer, verifier } = createSignerVerifier();
|
|
341
|
-
const sdjwt = new
|
|
331
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
342
332
|
signer,
|
|
343
333
|
verifier,
|
|
344
334
|
hasher: digest,
|
|
@@ -376,7 +366,7 @@ describe('index', () => {
|
|
|
376
366
|
|
|
377
367
|
test('kbVerifier not found', async () => {
|
|
378
368
|
const { signer, verifier } = createSignerVerifier();
|
|
379
|
-
const sdjwt = new
|
|
369
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
380
370
|
signer,
|
|
381
371
|
verifier,
|
|
382
372
|
hasher: digest,
|
|
@@ -416,7 +406,7 @@ describe('index', () => {
|
|
|
416
406
|
|
|
417
407
|
test('kbSignAlg not found', async () => {
|
|
418
408
|
const { signer, verifier } = createSignerVerifier();
|
|
419
|
-
const sdjwt = new
|
|
409
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
420
410
|
signer,
|
|
421
411
|
verifier,
|
|
422
412
|
hasher: digest,
|
|
@@ -440,7 +430,6 @@ describe('index', () => {
|
|
|
440
430
|
const presentation = sdjwt.present(credential, ['foo'], {
|
|
441
431
|
kb: {
|
|
442
432
|
payload: {
|
|
443
|
-
sd_hash: 'sha-256',
|
|
444
433
|
aud: '1',
|
|
445
434
|
iat: 1,
|
|
446
435
|
nonce: '342',
|
|
@@ -452,8 +441,56 @@ describe('index', () => {
|
|
|
452
441
|
);
|
|
453
442
|
});
|
|
454
443
|
|
|
455
|
-
test('hasher is not found', () => {
|
|
456
|
-
const
|
|
444
|
+
test('hasher is not found', async () => {
|
|
445
|
+
const { signer } = createSignerVerifier();
|
|
446
|
+
const sdjwt_create = new SDJwtInstance<SdJwtPayload>({
|
|
447
|
+
signer,
|
|
448
|
+
hasher: digest,
|
|
449
|
+
saltGenerator: generateSalt,
|
|
450
|
+
signAlg: 'EdDSA',
|
|
451
|
+
});
|
|
452
|
+
const credential = await sdjwt_create.issue(
|
|
453
|
+
{
|
|
454
|
+
foo: 'bar',
|
|
455
|
+
iss: 'Issuer',
|
|
456
|
+
iat: new Date().getTime(),
|
|
457
|
+
vct: '',
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
_sd: ['foo'],
|
|
461
|
+
},
|
|
462
|
+
);
|
|
463
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({});
|
|
457
464
|
expect(sdjwt.keys('')).rejects.toThrow('Hasher not found');
|
|
465
|
+
expect(sdjwt.presentableKeys('')).rejects.toThrow('Hasher not found');
|
|
466
|
+
expect(sdjwt.getClaims('')).rejects.toThrow('Hasher not found');
|
|
467
|
+
expect(() => sdjwt.decode('')).toThrowError('Hasher not found');
|
|
468
|
+
expect(sdjwt.present(credential, ['foo'])).rejects.toThrow(
|
|
469
|
+
'Hasher not found',
|
|
470
|
+
);
|
|
471
|
+
});
|
|
472
|
+
|
|
473
|
+
test('presentableKeys', async () => {
|
|
474
|
+
const { signer } = createSignerVerifier();
|
|
475
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
476
|
+
signer,
|
|
477
|
+
hasher: digest,
|
|
478
|
+
saltGenerator: generateSalt,
|
|
479
|
+
signAlg: 'EdDSA',
|
|
480
|
+
});
|
|
481
|
+
const credential = await sdjwt.issue(
|
|
482
|
+
{
|
|
483
|
+
foo: 'bar',
|
|
484
|
+
iss: 'Issuer',
|
|
485
|
+
iat: new Date().getTime(),
|
|
486
|
+
vct: '',
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
_sd: ['foo'],
|
|
490
|
+
},
|
|
491
|
+
);
|
|
492
|
+
const keys = await sdjwt.presentableKeys(credential);
|
|
493
|
+
expect(keys).toBeDefined();
|
|
494
|
+
expect(keys).toEqual(['foo']);
|
|
458
495
|
});
|
|
459
496
|
});
|
package/test/app-e2e.spec.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import Crypto from 'node:crypto';
|
|
2
|
-
import { SdJwtPayload } from '../src';
|
|
3
|
-
import { DisclosureFrame,
|
|
2
|
+
import { SDJwtInstance, SdJwtPayload } from '../src';
|
|
3
|
+
import { DisclosureFrame, Signer, Verifier } from '@sd-jwt/types';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import path from 'path';
|
|
6
6
|
import { describe, expect, test } from 'vitest';
|
|
7
7
|
import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
|
|
8
|
-
import { TestInstance } from '../src/test/index.spec';
|
|
9
8
|
|
|
10
9
|
export const createSignerVerifier = () => {
|
|
11
10
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
@@ -27,7 +26,7 @@ export const createSignerVerifier = () => {
|
|
|
27
26
|
describe('App', () => {
|
|
28
27
|
test('Example', async () => {
|
|
29
28
|
const { signer, verifier } = createSignerVerifier();
|
|
30
|
-
const sdjwt = new
|
|
29
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
31
30
|
signer,
|
|
32
31
|
signAlg: 'EdDSA',
|
|
33
32
|
verifier,
|
|
@@ -193,7 +192,7 @@ describe('App', () => {
|
|
|
193
192
|
async function JSONtest(filename: string) {
|
|
194
193
|
const test = loadTestJsonFile(filename);
|
|
195
194
|
const { signer, verifier } = createSignerVerifier();
|
|
196
|
-
const sdjwt = new
|
|
195
|
+
const sdjwt = new SDJwtInstance<SdJwtPayload>({
|
|
197
196
|
signer,
|
|
198
197
|
signAlg: 'EdDSA',
|
|
199
198
|
verifier,
|
|
@@ -210,7 +209,7 @@ async function JSONtest(filename: string) {
|
|
|
210
209
|
|
|
211
210
|
expect(validated).toBeDefined();
|
|
212
211
|
expect(validated).toStrictEqual({
|
|
213
|
-
header: { alg: 'EdDSA'
|
|
212
|
+
header: { alg: 'EdDSA' },
|
|
214
213
|
payload: test.claims,
|
|
215
214
|
});
|
|
216
215
|
|
|
@@ -229,7 +228,7 @@ async function JSONtest(filename: string) {
|
|
|
229
228
|
|
|
230
229
|
expect(verified).toBeDefined();
|
|
231
230
|
expect(verified).toStrictEqual({
|
|
232
|
-
header: { alg: 'EdDSA'
|
|
231
|
+
header: { alg: 'EdDSA' },
|
|
233
232
|
payload: test.claims,
|
|
234
233
|
});
|
|
235
234
|
}
|