@verii/server-mockvendor 1.0.0-pre.1752076816

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.
Files changed (82) hide show
  1. package/.localdev.env +15 -0
  2. package/.standalone.env +5 -0
  3. package/LICENSE +201 -0
  4. package/docker/compose.yml +25 -0
  5. package/jest.config.js +20 -0
  6. package/multilingual-string.schema.json +40 -0
  7. package/package.json +70 -0
  8. package/src/config/config.js +55 -0
  9. package/src/controllers/api/accepted-offers/controller.js +9 -0
  10. package/src/controllers/api/accepted-offers/repo.js +25 -0
  11. package/src/controllers/api/applicants/controller.js +9 -0
  12. package/src/controllers/api/applicants/repo.js +30 -0
  13. package/src/controllers/api/create_did_key/controller.js +29 -0
  14. package/src/controllers/api/create_did_key/schemas/index.js +4 -0
  15. package/src/controllers/api/create_did_key/schemas/jwk-did-request.schema.js +20 -0
  16. package/src/controllers/api/create_did_key/schemas/jwk-did-response.schema.js +41 -0
  17. package/src/controllers/api/create_jwk/controller.js +35 -0
  18. package/src/controllers/api/create_jwk/schemas/index.js +3 -0
  19. package/src/controllers/api/create_jwk/schemas/jwk-response.schema.js +33 -0
  20. package/src/controllers/api/credential-submissions/controller.js +59 -0
  21. package/src/controllers/api/credential-submissions/repo.js +16 -0
  22. package/src/controllers/api/identifications/controller.js +67 -0
  23. package/src/controllers/api/identifications/repo.js +22 -0
  24. package/src/controllers/api/issuing-exchanges/controller.js +218 -0
  25. package/src/controllers/api/issuing-exchanges/fetchers.js +45 -0
  26. package/src/controllers/api/issuing-exchanges/repo.js +27 -0
  27. package/src/controllers/api/jwt/controller.js +69 -0
  28. package/src/controllers/api/jwt/schemas/index.js +6 -0
  29. package/src/controllers/api/jwt/schemas/jwt-request.schema.js +40 -0
  30. package/src/controllers/api/jwt/schemas/jwt-response.schema.js +14 -0
  31. package/src/controllers/api/jwt/schemas/jwt-verify-request.schema.js +17 -0
  32. package/src/controllers/api/jwt/schemas/jwt-verify-response.schema.js +17 -0
  33. package/src/controllers/api/offers/autohooks.js +5 -0
  34. package/src/controllers/api/offers/controller.js +87 -0
  35. package/src/controllers/api/offers/new-mockvendor-offer.schema.js +22 -0
  36. package/src/controllers/api/offers/repo.js +33 -0
  37. package/src/controllers/api/users/controller.js +20 -0
  38. package/src/controllers/api/users/repo.js +29 -0
  39. package/src/controllers/autohooks.js +22 -0
  40. package/src/controllers/inspection/controller.js +39 -0
  41. package/src/controllers/issuing/controller.js +158 -0
  42. package/src/controllers/registrar/controller.js +67 -0
  43. package/src/controllers/registrar/repo.js +24 -0
  44. package/src/controllers/root/controller.js +15 -0
  45. package/src/controllers/schemas/index.js +21 -0
  46. package/src/controllers/schemas/issuer-data.schema.json +26 -0
  47. package/src/entities/index.js +4 -0
  48. package/src/entities/key-pairs/index.js +3 -0
  49. package/src/entities/key-pairs/key-pairs.js +73 -0
  50. package/src/entities/offers/index.js +3 -0
  51. package/src/entities/offers/schemas/generate-offers.schema.js +30 -0
  52. package/src/entities/offers/schemas/index.js +3 -0
  53. package/src/index.js +19 -0
  54. package/src/init-server.js +34 -0
  55. package/src/main.js +18 -0
  56. package/src/standalone.js +8 -0
  57. package/src/start-app-server.js +32 -0
  58. package/test/accepted-offers.test.js +47 -0
  59. package/test/api-users.test.js +170 -0
  60. package/test/create_did_key-controller.test.js +94 -0
  61. package/test/create_jwk-controller.test.js +86 -0
  62. package/test/credential-submissions.test.js +331 -0
  63. package/test/factories/accepted-offers.factory.js +16 -0
  64. package/test/factories/delayed-offer.factory.js +17 -0
  65. package/test/factories/identifications.factory.js +33 -0
  66. package/test/factories/offers.factory.js +64 -0
  67. package/test/factories/users.factory.js +24 -0
  68. package/test/helpers/PastEmploymentPosition-2007-2009-Junior-Project-Manager.json +26 -0
  69. package/test/helpers/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
  70. package/test/helpers/helpers/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
  71. package/test/helpers/latest-Adam-Smith.json +49 -0
  72. package/test/helpers/legacy-Adam-Smith.json +33 -0
  73. package/test/helpers/mockvendor-build-fastify.js +16 -0
  74. package/test/helpers/tools/verifgen/templates/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
  75. package/test/identifications.test.js +56 -0
  76. package/test/issuing-exchanges.test.js +335 -0
  77. package/test/issuing-identify.test.js +137 -0
  78. package/test/jwt-controller.test.js +320 -0
  79. package/test/offers.test.js +682 -0
  80. package/test/registrar.test.js +276 -0
  81. package/test/root.test.js +25 -0
  82. package/test/swagger.test.js +21 -0
@@ -0,0 +1,320 @@
1
+ const { generateKeyPair } = require('@verii/crypto');
2
+ const { jwtVerify, jwtSign } = require('@verii/jwt');
3
+ const { getDidUriFromJwk } = require('@verii/did-doc');
4
+ const { errorResponseMatcher } = require('@verii/tests-helpers');
5
+ const buildFastify = require('./helpers/mockvendor-build-fastify');
6
+ const { generateJwk } = require('../src/entities');
7
+
8
+ describe('JWT Controller Test Suite', () => {
9
+ let fastify;
10
+
11
+ beforeAll(async () => {
12
+ fastify = await buildFastify({});
13
+ await fastify.ready();
14
+ });
15
+
16
+ afterAll(async () => {
17
+ await fastify.close();
18
+ });
19
+
20
+ describe('JWT signing and verifying', () => {
21
+ const api = '/api/jwt';
22
+
23
+ describe('sign jwt test suite', () => {
24
+ it('should fail to sign a jwt with missing payload in body', async () => {
25
+ const response = await fastify.injectJson({
26
+ method: 'POST',
27
+ url: `${api}/sign`,
28
+ payload: {
29
+ header: {},
30
+ },
31
+ });
32
+ expect(response.statusCode).toEqual(400);
33
+ expect(response.json).toEqual(
34
+ errorResponseMatcher(
35
+ {
36
+ error: 'Bad Request',
37
+ code: 'FST_ERR_VALIDATION',
38
+ message: "body must have required property 'payload'",
39
+ statusCode: 400,
40
+ },
41
+ { omits: ['requestId', 'errorCode'] }
42
+ )
43
+ );
44
+ });
45
+
46
+ it('should fail to sign a jwt with empty keyId in options', async () => {
47
+ const response = await fastify.injectJson({
48
+ method: 'POST',
49
+ url: `${api}/sign`,
50
+ payload: {
51
+ header: {},
52
+ payload: {},
53
+ options: {
54
+ keyId: '',
55
+ },
56
+ },
57
+ });
58
+ expect(response.statusCode).toEqual(400);
59
+ expect(response.json).toEqual(
60
+ errorResponseMatcher(
61
+ {
62
+ error: 'Bad Request',
63
+ code: 'FST_ERR_VALIDATION',
64
+ message:
65
+ // eslint-disable-next-line max-len
66
+ "body/options must have required property 'kid', body/options/keyId must NOT have fewer than 1 characters, body/options must match exactly one schema in oneOf",
67
+ statusCode: 400,
68
+ },
69
+ { omits: ['requestId', 'errorCode'] }
70
+ )
71
+ );
72
+ });
73
+
74
+ it('should fail to sign a jwt with empty kid in options', async () => {
75
+ const response = await fastify.injectJson({
76
+ method: 'POST',
77
+ url: `${api}/sign`,
78
+ payload: {
79
+ header: {},
80
+ payload: {},
81
+ options: {
82
+ kid: '',
83
+ },
84
+ },
85
+ });
86
+ expect(response.statusCode).toEqual(400);
87
+ expect(response.json).toEqual(
88
+ errorResponseMatcher(
89
+ {
90
+ error: 'Bad Request',
91
+ code: 'FST_ERR_VALIDATION',
92
+ message:
93
+ // eslint-disable-next-line max-len
94
+ "body/options/kid must NOT have fewer than 1 characters, body/options must have required property 'keyId', body/options must match exactly one schema in oneOf",
95
+ statusCode: 400,
96
+ },
97
+ { omits: ['requestId', 'errorCode'] }
98
+ )
99
+ );
100
+ });
101
+
102
+ it('should fail when a key pair could not be found by kid', async () => {
103
+ const { publicKey: pubK } = generateKeyPair({
104
+ curve: 'P-256',
105
+ format: 'jwk',
106
+ });
107
+ const didJwk = getDidUriFromJwk(pubK);
108
+ const response = await fastify.injectJson({
109
+ method: 'POST',
110
+ url: `${api}/sign`,
111
+ payload: {
112
+ header: {},
113
+ payload: {
114
+ abc: 'abv',
115
+ },
116
+ options: {
117
+ kid: `${didJwk}#0`,
118
+ },
119
+ },
120
+ });
121
+ expect(response.statusCode).toEqual(400);
122
+ expect(response.json).toEqual(
123
+ errorResponseMatcher(
124
+ {
125
+ error: 'Bad Request',
126
+ message: 'Key pair not found',
127
+ statusCode: 400,
128
+ },
129
+ { omits: ['requestId', 'errorCode'] }
130
+ )
131
+ );
132
+ });
133
+
134
+ it('should fail when a key pair could not be found by keyId', async () => {
135
+ const response = await fastify.injectJson({
136
+ method: 'POST',
137
+ url: `${api}/sign`,
138
+ payload: {
139
+ header: {},
140
+ payload: {
141
+ abc: 'abv',
142
+ },
143
+ options: {
144
+ keyId: '111',
145
+ },
146
+ },
147
+ });
148
+ expect(response.statusCode).toEqual(400);
149
+ expect(response.json).toEqual(
150
+ errorResponseMatcher(
151
+ {
152
+ error: 'Bad Request',
153
+ message: 'Key pair not found',
154
+ statusCode: 400,
155
+ },
156
+ { omits: ['requestId', 'errorCode'] }
157
+ )
158
+ );
159
+ });
160
+
161
+ it('should sign a jwt with keyId', async () => {
162
+ const keyPair = generateJwk('P-256');
163
+ const response = await fastify.injectJson({
164
+ method: 'POST',
165
+ url: `${api}/sign`,
166
+ payload: {
167
+ header: {},
168
+ payload: {
169
+ abc: 'abv',
170
+ },
171
+ options: {
172
+ keyId: keyPair.id,
173
+ },
174
+ },
175
+ });
176
+ expect(response.statusCode).toEqual(200);
177
+ expect(response.json).toEqual({
178
+ compactJwt: expect.any(String),
179
+ });
180
+
181
+ const { payload, header } = await jwtVerify(
182
+ response.json.compactJwt,
183
+ keyPair.privateKey
184
+ );
185
+ expect(payload.abc).toEqual('abv');
186
+ expect(header.jwk).toEqual(keyPair.publicKey);
187
+ });
188
+
189
+ it('should sign a jwt with kid & secp256k1', async () => {
190
+ const keyPair = generateJwk('secp256k1');
191
+ const response = await fastify.injectJson({
192
+ method: 'POST',
193
+ url: `${api}/sign`,
194
+ payload: {
195
+ header: {},
196
+ payload: {
197
+ abc: 'abv',
198
+ },
199
+ options: {
200
+ kid: keyPair.kid,
201
+ },
202
+ },
203
+ });
204
+ expect(response.statusCode).toEqual(200);
205
+ expect(response.json).toEqual({
206
+ compactJwt: expect.any(String),
207
+ });
208
+
209
+ const { payload, header } = await jwtVerify(
210
+ response.json.compactJwt,
211
+ keyPair.privateKey
212
+ );
213
+ expect(payload.abc).toEqual('abv');
214
+ expect(header.jwk).toEqual(keyPair.publicKey);
215
+ });
216
+ });
217
+
218
+ describe('verify jwt test suite', () => {
219
+ it('should 400 with missing jwt in body', async () => {
220
+ const response = await fastify.injectJson({
221
+ method: 'POST',
222
+ url: `${api}/verify`,
223
+ payload: {},
224
+ });
225
+ expect(response.statusCode).toEqual(400);
226
+ expect(response.json).toEqual(
227
+ errorResponseMatcher(
228
+ {
229
+ error: 'Bad Request',
230
+ code: 'FST_ERR_VALIDATION',
231
+ message: "body must have required property 'jwt'",
232
+ statusCode: 400,
233
+ },
234
+ { omits: ['requestId', 'errorCode'] }
235
+ )
236
+ );
237
+ });
238
+
239
+ it('should not verify a jwt with incorrect jwk embedded in the header', async () => {
240
+ const { privateKey } = generateKeyPair({ format: 'jwk' });
241
+ const { publicKey: wrongPublicKey } = generateKeyPair({
242
+ format: 'jwk',
243
+ });
244
+ const jwt = await jwtSign({ foo: 'bar' }, privateKey, {
245
+ jwk: wrongPublicKey,
246
+ });
247
+ const response = await fastify.injectJson({
248
+ method: 'POST',
249
+ url: `${api}/verify`,
250
+ payload: {
251
+ jwt,
252
+ },
253
+ });
254
+ expect(response.statusCode).toEqual(200);
255
+ expect(response.json).toEqual({
256
+ verified: false,
257
+ error:
258
+ 'JWSSignatureVerificationFailed: signature verification failed',
259
+ });
260
+ });
261
+
262
+ it('should not verify a jwt with incorrect publicKey', async () => {
263
+ const { privateKey } = generateKeyPair({ format: 'jwk' });
264
+ const { publicKey: wrongPublicKey } = generateKeyPair({
265
+ format: 'jwk',
266
+ });
267
+ const jwt = await jwtSign({ foo: 'bar' }, privateKey);
268
+ const response = await fastify.injectJson({
269
+ method: 'POST',
270
+ url: `${api}/verify`,
271
+ payload: {
272
+ jwt,
273
+ publicKey: wrongPublicKey,
274
+ },
275
+ });
276
+ expect(response.statusCode).toEqual(200);
277
+ expect(response.json).toEqual({
278
+ verified: false,
279
+ error:
280
+ 'JWSSignatureVerificationFailed: signature verification failed',
281
+ });
282
+ });
283
+
284
+ it('should verify a jwt with correct jwk embedded in the header', async () => {
285
+ const { privateKey, publicKey } = generateKeyPair({ format: 'jwk' });
286
+ const jwt = await jwtSign({ foo: 'bar' }, privateKey, {
287
+ jwk: publicKey,
288
+ });
289
+ const response = await fastify.injectJson({
290
+ method: 'POST',
291
+ url: `${api}/verify`,
292
+ payload: {
293
+ jwt,
294
+ },
295
+ });
296
+ expect(response.statusCode).toEqual(200);
297
+ expect(response.json).toEqual({
298
+ verified: true,
299
+ });
300
+ });
301
+
302
+ it('should verify a jwt with correct publicKey', async () => {
303
+ const { privateKey, publicKey } = generateKeyPair({ format: 'jwk' });
304
+ const jwt = await jwtSign({ foo: 'bar' }, privateKey);
305
+ const response = await fastify.injectJson({
306
+ method: 'POST',
307
+ url: `${api}/verify`,
308
+ payload: {
309
+ jwt,
310
+ publicKey,
311
+ },
312
+ });
313
+ expect(response.statusCode).toEqual(200);
314
+ expect(response.json).toEqual({
315
+ verified: true,
316
+ });
317
+ });
318
+ });
319
+ });
320
+ });