@sd-jwt/sd-jwt-vc 0.9.2-next.6 → 0.9.2-next.8
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.js +2 -9
- package/dist/index.mjs +2 -9
- package/package.json +7 -7
- package/src/sd-jwt-vc-instance.ts +2 -11
- package/src/test/vct.spec.ts +48 -21
package/dist/index.js
CHANGED
|
@@ -179,14 +179,9 @@ var SDJwtVcInstance = class _SDJwtVcInstance extends import_core.SDJwtInstance {
|
|
|
179
179
|
fetch(url, integrity) {
|
|
180
180
|
return __async(this, null, function* () {
|
|
181
181
|
var _a;
|
|
182
|
-
const controller = new AbortController();
|
|
183
|
-
const timeoutId = setTimeout(
|
|
184
|
-
() => controller.abort(),
|
|
185
|
-
(_a = this.userConfig.timeout) != null ? _a : 1e4
|
|
186
|
-
);
|
|
187
182
|
try {
|
|
188
183
|
const response = yield fetch(url, {
|
|
189
|
-
signal:
|
|
184
|
+
signal: AbortSignal.timeout((_a = this.userConfig.timeout) != null ? _a : 1e4)
|
|
190
185
|
});
|
|
191
186
|
if (!response.ok) {
|
|
192
187
|
const errorText = yield response.text();
|
|
@@ -197,12 +192,10 @@ var SDJwtVcInstance = class _SDJwtVcInstance extends import_core.SDJwtInstance {
|
|
|
197
192
|
yield this.validateIntegrity(response.clone(), url, integrity);
|
|
198
193
|
return response.json();
|
|
199
194
|
} catch (error) {
|
|
200
|
-
if (error
|
|
195
|
+
if (error.name === "TimeoutError") {
|
|
201
196
|
throw new Error(`Request to ${url} timed out`);
|
|
202
197
|
}
|
|
203
198
|
throw error;
|
|
204
|
-
} finally {
|
|
205
|
-
clearTimeout(timeoutId);
|
|
206
199
|
}
|
|
207
200
|
});
|
|
208
201
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -147,14 +147,9 @@ var SDJwtVcInstance = class _SDJwtVcInstance extends SDJwtInstance {
|
|
|
147
147
|
fetch(url, integrity) {
|
|
148
148
|
return __async(this, null, function* () {
|
|
149
149
|
var _a;
|
|
150
|
-
const controller = new AbortController();
|
|
151
|
-
const timeoutId = setTimeout(
|
|
152
|
-
() => controller.abort(),
|
|
153
|
-
(_a = this.userConfig.timeout) != null ? _a : 1e4
|
|
154
|
-
);
|
|
155
150
|
try {
|
|
156
151
|
const response = yield fetch(url, {
|
|
157
|
-
signal:
|
|
152
|
+
signal: AbortSignal.timeout((_a = this.userConfig.timeout) != null ? _a : 1e4)
|
|
158
153
|
});
|
|
159
154
|
if (!response.ok) {
|
|
160
155
|
const errorText = yield response.text();
|
|
@@ -165,12 +160,10 @@ var SDJwtVcInstance = class _SDJwtVcInstance extends SDJwtInstance {
|
|
|
165
160
|
yield this.validateIntegrity(response.clone(), url, integrity);
|
|
166
161
|
return response.json();
|
|
167
162
|
} catch (error) {
|
|
168
|
-
if (error
|
|
163
|
+
if (error.name === "TimeoutError") {
|
|
169
164
|
throw new Error(`Request to ${url} timed out`);
|
|
170
165
|
}
|
|
171
166
|
throw error;
|
|
172
|
-
} finally {
|
|
173
|
-
clearTimeout(timeoutId);
|
|
174
167
|
}
|
|
175
168
|
});
|
|
176
169
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sd-jwt/sd-jwt-vc",
|
|
3
|
-
"version": "0.9.2-next.
|
|
3
|
+
"version": "0.9.2-next.8+ed907e3",
|
|
4
4
|
"description": "sd-jwt draft 7 implementation in typescript",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
},
|
|
40
40
|
"license": "Apache-2.0",
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@sd-jwt/core": "0.9.2-next.
|
|
43
|
-
"@sd-jwt/jwt-status-list": "0.9.2-next.
|
|
44
|
-
"@sd-jwt/utils": "0.9.2-next.
|
|
42
|
+
"@sd-jwt/core": "0.9.2-next.8+ed907e3",
|
|
43
|
+
"@sd-jwt/jwt-status-list": "0.9.2-next.8+ed907e3",
|
|
44
|
+
"@sd-jwt/utils": "0.9.2-next.8+ed907e3",
|
|
45
45
|
"ajv": "^8.17.1",
|
|
46
46
|
"ajv-formats": "^3.0.1"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@sd-jwt/crypto-nodejs": "0.9.2-next.
|
|
50
|
-
"@sd-jwt/types": "0.9.2-next.
|
|
49
|
+
"@sd-jwt/crypto-nodejs": "0.9.2-next.8+ed907e3",
|
|
50
|
+
"@sd-jwt/types": "0.9.2-next.8+ed907e3",
|
|
51
51
|
"jose": "^5.2.2",
|
|
52
52
|
"msw": "^2.3.5"
|
|
53
53
|
},
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"esm"
|
|
68
68
|
]
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "ed907e33c79f140268a03098af1e8c5cc1003ce9"
|
|
71
71
|
}
|
|
@@ -167,17 +167,10 @@ export class SDJwtVcInstance extends SDJwtInstance<SdJwtVcPayload> {
|
|
|
167
167
|
* @returns
|
|
168
168
|
*/
|
|
169
169
|
private async fetch<T>(url: string, integrity?: string): Promise<T> {
|
|
170
|
-
const controller = new AbortController();
|
|
171
|
-
const timeoutId = setTimeout(
|
|
172
|
-
() => controller.abort(),
|
|
173
|
-
this.userConfig.timeout ?? 10000,
|
|
174
|
-
);
|
|
175
|
-
|
|
176
170
|
try {
|
|
177
171
|
const response = await fetch(url, {
|
|
178
|
-
signal:
|
|
172
|
+
signal: AbortSignal.timeout(this.userConfig.timeout ?? 10000),
|
|
179
173
|
});
|
|
180
|
-
|
|
181
174
|
if (!response.ok) {
|
|
182
175
|
const errorText = await response.text();
|
|
183
176
|
throw new Error(
|
|
@@ -187,12 +180,10 @@ export class SDJwtVcInstance extends SDJwtInstance<SdJwtVcPayload> {
|
|
|
187
180
|
await this.validateIntegrity(response.clone(), url, integrity);
|
|
188
181
|
return response.json() as Promise<T>;
|
|
189
182
|
} catch (error) {
|
|
190
|
-
if (error
|
|
183
|
+
if ((error as Error).name === 'TimeoutError') {
|
|
191
184
|
throw new Error(`Request to ${url} timed out`);
|
|
192
185
|
}
|
|
193
186
|
throw error;
|
|
194
|
-
} finally {
|
|
195
|
-
clearTimeout(timeoutId);
|
|
196
187
|
}
|
|
197
188
|
}
|
|
198
189
|
|
package/src/test/vct.spec.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { digest, generateSalt } from '@sd-jwt/crypto-nodejs';
|
|
2
2
|
import type { DisclosureFrame, Signer, Verifier } from '@sd-jwt/types';
|
|
3
|
-
import { describe, test, beforeAll, afterAll } from 'vitest';
|
|
3
|
+
import { describe, test, beforeAll, afterAll, expect } from 'vitest';
|
|
4
4
|
import { SDJwtVcInstance } from '..';
|
|
5
5
|
import type { SdJwtVcPayload } from '../sd-jwt-vc-payload';
|
|
6
6
|
import Crypto from 'node:crypto';
|
|
@@ -41,7 +41,7 @@ const restHandlers = [
|
|
|
41
41
|
};
|
|
42
42
|
return HttpResponse.json(res);
|
|
43
43
|
}),
|
|
44
|
-
http.get('http://
|
|
44
|
+
http.get('http://example.com/example', () => {
|
|
45
45
|
const res: TypeMetadataFormat = {
|
|
46
46
|
vct: 'http://example.com/example',
|
|
47
47
|
name: 'ExampleCredentialType',
|
|
@@ -53,6 +53,13 @@ const restHandlers = [
|
|
|
53
53
|
};
|
|
54
54
|
return HttpResponse.json(res);
|
|
55
55
|
}),
|
|
56
|
+
http.get('http://example.com/timeout', () => {
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
resolve(HttpResponse.json({}));
|
|
60
|
+
}, 10000);
|
|
61
|
+
});
|
|
62
|
+
}),
|
|
56
63
|
];
|
|
57
64
|
|
|
58
65
|
//this value could be generated on demand to make it easier when changing the values
|
|
@@ -62,7 +69,7 @@ const vctIntegrity =
|
|
|
62
69
|
const server = setupServer(...restHandlers);
|
|
63
70
|
|
|
64
71
|
const iss = 'ExampleIssuer';
|
|
65
|
-
const vct = 'http://
|
|
72
|
+
const vct = 'http://example.com/example';
|
|
66
73
|
const iat = new Date().getTime() / 1000;
|
|
67
74
|
|
|
68
75
|
const { privateKey, publicKey } = Crypto.generateKeyPairSync('ed25519');
|
|
@@ -84,6 +91,26 @@ const createSignerVerifier = () => {
|
|
|
84
91
|
};
|
|
85
92
|
|
|
86
93
|
describe('App', () => {
|
|
94
|
+
const { signer, verifier } = createSignerVerifier();
|
|
95
|
+
|
|
96
|
+
const sdjwt = new SDJwtVcInstance({
|
|
97
|
+
signer,
|
|
98
|
+
signAlg: 'EdDSA',
|
|
99
|
+
verifier,
|
|
100
|
+
hasher: digest,
|
|
101
|
+
hashAlg: 'sha-256',
|
|
102
|
+
saltGenerator: generateSalt,
|
|
103
|
+
loadTypeMetadataFormat: true,
|
|
104
|
+
timeout: 1000,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const claims = {
|
|
108
|
+
firstname: 'John',
|
|
109
|
+
};
|
|
110
|
+
const disclosureFrame = {
|
|
111
|
+
_sd: ['firstname'],
|
|
112
|
+
};
|
|
113
|
+
|
|
87
114
|
beforeAll(() => server.listen({ onUnhandledRequest: 'warn' }));
|
|
88
115
|
|
|
89
116
|
afterAll(() => server.close());
|
|
@@ -91,24 +118,6 @@ describe('App', () => {
|
|
|
91
118
|
afterEach(() => server.resetHandlers());
|
|
92
119
|
|
|
93
120
|
test('VCT Validation', async () => {
|
|
94
|
-
const { signer, verifier } = createSignerVerifier();
|
|
95
|
-
const sdjwt = new SDJwtVcInstance({
|
|
96
|
-
signer,
|
|
97
|
-
signAlg: 'EdDSA',
|
|
98
|
-
verifier,
|
|
99
|
-
hasher: digest,
|
|
100
|
-
hashAlg: 'sha-256',
|
|
101
|
-
saltGenerator: generateSalt,
|
|
102
|
-
loadTypeMetadataFormat: true,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const claims = {
|
|
106
|
-
firstname: 'John',
|
|
107
|
-
};
|
|
108
|
-
const disclosureFrame = {
|
|
109
|
-
_sd: ['firstname'],
|
|
110
|
-
};
|
|
111
|
-
|
|
112
121
|
const expectedPayload: SdJwtVcPayload = {
|
|
113
122
|
iat,
|
|
114
123
|
iss,
|
|
@@ -124,5 +133,23 @@ describe('App', () => {
|
|
|
124
133
|
await sdjwt.verify(encodedSdjwt);
|
|
125
134
|
});
|
|
126
135
|
|
|
136
|
+
test('VCT Validation with timeout', async () => {
|
|
137
|
+
const vct = 'http://example.com/timeout';
|
|
138
|
+
const expectedPayload: SdJwtVcPayload = {
|
|
139
|
+
iat,
|
|
140
|
+
iss,
|
|
141
|
+
vct,
|
|
142
|
+
...claims,
|
|
143
|
+
};
|
|
144
|
+
const encodedSdjwt = await sdjwt.issue(
|
|
145
|
+
expectedPayload,
|
|
146
|
+
disclosureFrame as unknown as DisclosureFrame<SdJwtVcPayload>,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
expect(sdjwt.verify(encodedSdjwt)).rejects.toThrowError(
|
|
150
|
+
`Request to ${vct} timed out`,
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
127
154
|
//TODO: we need tests with an embedded schema, extended and maybe also to test the errors when schema information is not available or the integrity is not valid
|
|
128
155
|
});
|