@sd-jwt/core 0.7.2 → 0.8.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 +11 -0
- package/dist/index.d.mts +142 -2
- package/dist/index.d.ts +142 -2
- package/dist/index.js +481 -33
- package/dist/index.mjs +479 -29
- package/package.json +7 -7
- package/src/flattenJSON.ts +90 -0
- package/src/generalJSON.ts +140 -0
- package/src/index.ts +350 -3
- package/src/sdjwt.ts +14 -6
- package/src/test/flattenJSON.spec.ts +56 -0
- package/src/test/generalJSON.spec.ts +124 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { describe, expect, test } from 'vitest';
|
|
2
|
+
import { GeneralJSON } from '..';
|
|
3
|
+
import type { Signer, Verifier } from '@sd-jwt/types';
|
|
4
|
+
import Crypto from 'node:crypto';
|
|
5
|
+
|
|
6
|
+
const createSignerVerifier = () => {
|
|
7
|
+
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
8
|
+
const signer: Signer = async (data: string) => {
|
|
9
|
+
const sig = Crypto.sign(null, Buffer.from(data), privateKey);
|
|
10
|
+
return Buffer.from(sig).toString('base64url');
|
|
11
|
+
};
|
|
12
|
+
const verifier: Verifier = async (data: string, sig: string) => {
|
|
13
|
+
return Crypto.verify(
|
|
14
|
+
null,
|
|
15
|
+
Buffer.from(data),
|
|
16
|
+
publicKey,
|
|
17
|
+
Buffer.from(sig, 'base64url'),
|
|
18
|
+
);
|
|
19
|
+
};
|
|
20
|
+
return { signer, verifier };
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
describe('FlattenJSON', () => {
|
|
24
|
+
test('fromEncode', () => {
|
|
25
|
+
const compact =
|
|
26
|
+
'eyJ0eXAiOiJzZCtqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpZCI6IjEyMzQiLCJfc2QiOlsiYkRUUnZtNS1Zbi1IRzdjcXBWUjVPVlJJWHNTYUJrNTdKZ2lPcV9qMVZJNCIsImV0M1VmUnlsd1ZyZlhkUEt6Zzc5aGNqRDFJdHpvUTlvQm9YUkd0TW9zRmsiLCJ6V2ZaTlMxOUF0YlJTVGJvN3NKUm4wQlpRdldSZGNob0M3VVphYkZyalk4Il0sIl9zZF9hbGciOiJzaGEtMjU2In0.n27NCtnuwytlBYtUNjgkesDP_7gN7bhaLhWNL4SWT6MaHsOjZ2ZMp987GgQRL6ZkLbJ7Cd3hlePHS84GBXPuvg~WyI1ZWI4Yzg2MjM0MDJjZjJlIiwiZmlyc3RuYW1lIiwiSm9obiJd~WyJjNWMzMWY2ZWYzNTg4MWJjIiwibGFzdG5hbWUiLCJEb2UiXQ~WyJmYTlkYTUzZWJjOTk3OThlIiwic3NuIiwiMTIzLTQ1LTY3ODkiXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpYXQiOjE3MTAwNjk3MjIsImF1ZCI6ImRpZDpleGFtcGxlOjEyMyIsIm5vbmNlIjoiazh2ZGYwbmQ2Iiwic2RfaGFzaCI6Il8tTmJWSzNmczl3VzNHaDNOUktSNEt1NmZDMUwzN0R2MFFfalBXd0ppRkUifQ.pqw2OB5IA5ya9Mxf60hE3nr2gsJEIoIlnuCa4qIisijHbwg3WzTDFmW2SuNvK_ORN0WU6RoGbJx5uYZh8k4EbA';
|
|
27
|
+
const generalJSON = GeneralJSON.fromEncode(compact);
|
|
28
|
+
expect(generalJSON).toBeDefined();
|
|
29
|
+
|
|
30
|
+
const result = {
|
|
31
|
+
payload:
|
|
32
|
+
'eyJpZCI6IjEyMzQiLCJfc2QiOlsiYkRUUnZtNS1Zbi1IRzdjcXBWUjVPVlJJWHNTYUJrNTdKZ2lPcV9qMVZJNCIsImV0M1VmUnlsd1ZyZlhkUEt6Zzc5aGNqRDFJdHpvUTlvQm9YUkd0TW9zRmsiLCJ6V2ZaTlMxOUF0YlJTVGJvN3NKUm4wQlpRdldSZGNob0M3VVphYkZyalk4Il0sIl9zZF9hbGciOiJzaGEtMjU2In0',
|
|
33
|
+
signatures: [
|
|
34
|
+
{
|
|
35
|
+
protected: 'eyJ0eXAiOiJzZCtqd3QiLCJhbGciOiJFUzI1NiJ9',
|
|
36
|
+
signature:
|
|
37
|
+
'n27NCtnuwytlBYtUNjgkesDP_7gN7bhaLhWNL4SWT6MaHsOjZ2ZMp987GgQRL6ZkLbJ7Cd3hlePHS84GBXPuvg',
|
|
38
|
+
header: {
|
|
39
|
+
disclosures: [
|
|
40
|
+
'WyI1ZWI4Yzg2MjM0MDJjZjJlIiwiZmlyc3RuYW1lIiwiSm9obiJd',
|
|
41
|
+
'WyJjNWMzMWY2ZWYzNTg4MWJjIiwibGFzdG5hbWUiLCJEb2UiXQ',
|
|
42
|
+
'WyJmYTlkYTUzZWJjOTk3OThlIiwic3NuIiwiMTIzLTQ1LTY3ODkiXQ',
|
|
43
|
+
],
|
|
44
|
+
kb_jwt:
|
|
45
|
+
'eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpYXQiOjE3MTAwNjk3MjIsImF1ZCI6ImRpZDpleGFtcGxlOjEyMyIsIm5vbmNlIjoiazh2ZGYwbmQ2Iiwic2RfaGFzaCI6Il8tTmJWSzNmczl3VzNHaDNOUktSNEt1NmZDMUwzN0R2MFFfalBXd0ppRkUifQ.pqw2OB5IA5ya9Mxf60hE3nr2gsJEIoIlnuCa4qIisijHbwg3WzTDFmW2SuNvK_ORN0WU6RoGbJx5uYZh8k4EbA',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
expect(generalJSON.toJson()).toEqual(result);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('fromSerialized', () => {
|
|
54
|
+
const generalJSON = {
|
|
55
|
+
payload:
|
|
56
|
+
'eyJpZCI6IjEyMzQiLCJfc2QiOlsiYkRUUnZtNS1Zbi1IRzdjcXBWUjVPVlJJWHNTYUJrNTdKZ2lPcV9qMVZJNCIsImV0M1VmUnlsd1ZyZlhkUEt6Zzc5aGNqRDFJdHpvUTlvQm9YUkd0TW9zRmsiLCJ6V2ZaTlMxOUF0YlJTVGJvN3NKUm4wQlpRdldSZGNob0M3VVphYkZyalk4Il0sIl9zZF9hbGciOiJzaGEtMjU2In0',
|
|
57
|
+
signatures: [
|
|
58
|
+
{
|
|
59
|
+
protected: 'eyJ0eXAiOiJzZCtqd3QiLCJhbGciOiJFUzI1NiJ9',
|
|
60
|
+
signature:
|
|
61
|
+
'n27NCtnuwytlBYtUNjgkesDP_7gN7bhaLhWNL4SWT6MaHsOjZ2ZMp987GgQRL6ZkLbJ7Cd3hlePHS84GBXPuvg',
|
|
62
|
+
header: {
|
|
63
|
+
disclosures: [
|
|
64
|
+
'WyI1ZWI4Yzg2MjM0MDJjZjJlIiwiZmlyc3RuYW1lIiwiSm9obiJd',
|
|
65
|
+
'WyJjNWMzMWY2ZWYzNTg4MWJjIiwibGFzdG5hbWUiLCJEb2UiXQ',
|
|
66
|
+
'WyJmYTlkYTUzZWJjOTk3OThlIiwic3NuIiwiMTIzLTQ1LTY3ODkiXQ',
|
|
67
|
+
],
|
|
68
|
+
kb_jwt:
|
|
69
|
+
'eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpYXQiOjE3MTAwNjk3MjIsImF1ZCI6ImRpZDpleGFtcGxlOjEyMyIsIm5vbmNlIjoiazh2ZGYwbmQ2Iiwic2RfaGFzaCI6Il8tTmJWSzNmczl3VzNHaDNOUktSNEt1NmZDMUwzN0R2MFFfalBXd0ppRkUifQ.pqw2OB5IA5ya9Mxf60hE3nr2gsJEIoIlnuCa4qIisijHbwg3WzTDFmW2SuNvK_ORN0WU6RoGbJx5uYZh8k4EbA',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
const compact =
|
|
76
|
+
'eyJ0eXAiOiJzZCtqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpZCI6IjEyMzQiLCJfc2QiOlsiYkRUUnZtNS1Zbi1IRzdjcXBWUjVPVlJJWHNTYUJrNTdKZ2lPcV9qMVZJNCIsImV0M1VmUnlsd1ZyZlhkUEt6Zzc5aGNqRDFJdHpvUTlvQm9YUkd0TW9zRmsiLCJ6V2ZaTlMxOUF0YlJTVGJvN3NKUm4wQlpRdldSZGNob0M3VVphYkZyalk4Il0sIl9zZF9hbGciOiJzaGEtMjU2In0.n27NCtnuwytlBYtUNjgkesDP_7gN7bhaLhWNL4SWT6MaHsOjZ2ZMp987GgQRL6ZkLbJ7Cd3hlePHS84GBXPuvg~WyI1ZWI4Yzg2MjM0MDJjZjJlIiwiZmlyc3RuYW1lIiwiSm9obiJd~WyJjNWMzMWY2ZWYzNTg4MWJjIiwibGFzdG5hbWUiLCJEb2UiXQ~WyJmYTlkYTUzZWJjOTk3OThlIiwic3NuIiwiMTIzLTQ1LTY3ODkiXQ~eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpYXQiOjE3MTAwNjk3MjIsImF1ZCI6ImRpZDpleGFtcGxlOjEyMyIsIm5vbmNlIjoiazh2ZGYwbmQ2Iiwic2RfaGFzaCI6Il8tTmJWSzNmczl3VzNHaDNOUktSNEt1NmZDMUwzN0R2MFFfalBXd0ppRkUifQ.pqw2OB5IA5ya9Mxf60hE3nr2gsJEIoIlnuCa4qIisijHbwg3WzTDFmW2SuNvK_ORN0WU6RoGbJx5uYZh8k4EbA';
|
|
77
|
+
const result = GeneralJSON.fromSerialized(generalJSON);
|
|
78
|
+
expect(result).toBeDefined();
|
|
79
|
+
expect(result.toEncoded(0)).toEqual(compact);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('add signature', async () => {
|
|
83
|
+
const { signer } = createSignerVerifier();
|
|
84
|
+
|
|
85
|
+
const generalJSON = {
|
|
86
|
+
payload:
|
|
87
|
+
'eyJpZCI6IjEyMzQiLCJfc2QiOlsiYkRUUnZtNS1Zbi1IRzdjcXBWUjVPVlJJWHNTYUJrNTdKZ2lPcV9qMVZJNCIsImV0M1VmUnlsd1ZyZlhkUEt6Zzc5aGNqRDFJdHpvUTlvQm9YUkd0TW9zRmsiLCJ6V2ZaTlMxOUF0YlJTVGJvN3NKUm4wQlpRdldSZGNob0M3VVphYkZyalk4Il0sIl9zZF9hbGciOiJzaGEtMjU2In0',
|
|
88
|
+
signatures: [
|
|
89
|
+
{
|
|
90
|
+
protected: 'eyJ0eXAiOiJzZCtqd3QiLCJhbGciOiJFUzI1NiJ9',
|
|
91
|
+
signature:
|
|
92
|
+
'n27NCtnuwytlBYtUNjgkesDP_7gN7bhaLhWNL4SWT6MaHsOjZ2ZMp987GgQRL6ZkLbJ7Cd3hlePHS84GBXPuvg',
|
|
93
|
+
header: {
|
|
94
|
+
disclosures: [
|
|
95
|
+
'WyI1ZWI4Yzg2MjM0MDJjZjJlIiwiZmlyc3RuYW1lIiwiSm9obiJd',
|
|
96
|
+
'WyJjNWMzMWY2ZWYzNTg4MWJjIiwibGFzdG5hbWUiLCJEb2UiXQ',
|
|
97
|
+
'WyJmYTlkYTUzZWJjOTk3OThlIiwic3NuIiwiMTIzLTQ1LTY3ODkiXQ',
|
|
98
|
+
],
|
|
99
|
+
kb_jwt:
|
|
100
|
+
'eyJ0eXAiOiJrYitqd3QiLCJhbGciOiJFUzI1NiJ9.eyJpYXQiOjE3MTAwNjk3MjIsImF1ZCI6ImRpZDpleGFtcGxlOjEyMyIsIm5vbmNlIjoiazh2ZGYwbmQ2Iiwic2RfaGFzaCI6Il8tTmJWSzNmczl3VzNHaDNOUktSNEt1NmZDMUwzN0R2MFFfalBXd0ppRkUifQ.pqw2OB5IA5ya9Mxf60hE3nr2gsJEIoIlnuCa4qIisijHbwg3WzTDFmW2SuNvK_ORN0WU6RoGbJx5uYZh8k4EbA',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const result = GeneralJSON.fromSerialized(generalJSON);
|
|
107
|
+
expect(result).toBeDefined();
|
|
108
|
+
|
|
109
|
+
await result.addSignature(
|
|
110
|
+
{ alg: 'ES256', typ: 'sd+jwt', kid: 'key-1' },
|
|
111
|
+
signer,
|
|
112
|
+
'key-1',
|
|
113
|
+
);
|
|
114
|
+
const resultJson = result.toJson();
|
|
115
|
+
console.log(resultJson);
|
|
116
|
+
|
|
117
|
+
expect(resultJson.signatures.length).toEqual(2);
|
|
118
|
+
expect(resultJson.signatures[1].header.kid).toEqual('key-1');
|
|
119
|
+
expect(resultJson.signatures[1].signature).toBeDefined();
|
|
120
|
+
expect(resultJson.signatures[1].protected).toEqual(
|
|
121
|
+
'eyJhbGciOiJFUzI1NiIsInR5cCI6InNkK2p3dCIsImtpZCI6ImtleS0xIn0',
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
});
|