@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.
- package/.localdev.env +15 -0
- package/.standalone.env +5 -0
- package/LICENSE +201 -0
- package/docker/compose.yml +25 -0
- package/jest.config.js +20 -0
- package/multilingual-string.schema.json +40 -0
- package/package.json +70 -0
- package/src/config/config.js +55 -0
- package/src/controllers/api/accepted-offers/controller.js +9 -0
- package/src/controllers/api/accepted-offers/repo.js +25 -0
- package/src/controllers/api/applicants/controller.js +9 -0
- package/src/controllers/api/applicants/repo.js +30 -0
- package/src/controllers/api/create_did_key/controller.js +29 -0
- package/src/controllers/api/create_did_key/schemas/index.js +4 -0
- package/src/controllers/api/create_did_key/schemas/jwk-did-request.schema.js +20 -0
- package/src/controllers/api/create_did_key/schemas/jwk-did-response.schema.js +41 -0
- package/src/controllers/api/create_jwk/controller.js +35 -0
- package/src/controllers/api/create_jwk/schemas/index.js +3 -0
- package/src/controllers/api/create_jwk/schemas/jwk-response.schema.js +33 -0
- package/src/controllers/api/credential-submissions/controller.js +59 -0
- package/src/controllers/api/credential-submissions/repo.js +16 -0
- package/src/controllers/api/identifications/controller.js +67 -0
- package/src/controllers/api/identifications/repo.js +22 -0
- package/src/controllers/api/issuing-exchanges/controller.js +218 -0
- package/src/controllers/api/issuing-exchanges/fetchers.js +45 -0
- package/src/controllers/api/issuing-exchanges/repo.js +27 -0
- package/src/controllers/api/jwt/controller.js +69 -0
- package/src/controllers/api/jwt/schemas/index.js +6 -0
- package/src/controllers/api/jwt/schemas/jwt-request.schema.js +40 -0
- package/src/controllers/api/jwt/schemas/jwt-response.schema.js +14 -0
- package/src/controllers/api/jwt/schemas/jwt-verify-request.schema.js +17 -0
- package/src/controllers/api/jwt/schemas/jwt-verify-response.schema.js +17 -0
- package/src/controllers/api/offers/autohooks.js +5 -0
- package/src/controllers/api/offers/controller.js +87 -0
- package/src/controllers/api/offers/new-mockvendor-offer.schema.js +22 -0
- package/src/controllers/api/offers/repo.js +33 -0
- package/src/controllers/api/users/controller.js +20 -0
- package/src/controllers/api/users/repo.js +29 -0
- package/src/controllers/autohooks.js +22 -0
- package/src/controllers/inspection/controller.js +39 -0
- package/src/controllers/issuing/controller.js +158 -0
- package/src/controllers/registrar/controller.js +67 -0
- package/src/controllers/registrar/repo.js +24 -0
- package/src/controllers/root/controller.js +15 -0
- package/src/controllers/schemas/index.js +21 -0
- package/src/controllers/schemas/issuer-data.schema.json +26 -0
- package/src/entities/index.js +4 -0
- package/src/entities/key-pairs/index.js +3 -0
- package/src/entities/key-pairs/key-pairs.js +73 -0
- package/src/entities/offers/index.js +3 -0
- package/src/entities/offers/schemas/generate-offers.schema.js +30 -0
- package/src/entities/offers/schemas/index.js +3 -0
- package/src/index.js +19 -0
- package/src/init-server.js +34 -0
- package/src/main.js +18 -0
- package/src/standalone.js +8 -0
- package/src/start-app-server.js +32 -0
- package/test/accepted-offers.test.js +47 -0
- package/test/api-users.test.js +170 -0
- package/test/create_did_key-controller.test.js +94 -0
- package/test/create_jwk-controller.test.js +86 -0
- package/test/credential-submissions.test.js +331 -0
- package/test/factories/accepted-offers.factory.js +16 -0
- package/test/factories/delayed-offer.factory.js +17 -0
- package/test/factories/identifications.factory.js +33 -0
- package/test/factories/offers.factory.js +64 -0
- package/test/factories/users.factory.js +24 -0
- package/test/helpers/PastEmploymentPosition-2007-2009-Junior-Project-Manager.json +26 -0
- package/test/helpers/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
- package/test/helpers/helpers/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
- package/test/helpers/latest-Adam-Smith.json +49 -0
- package/test/helpers/legacy-Adam-Smith.json +33 -0
- package/test/helpers/mockvendor-build-fastify.js +16 -0
- package/test/helpers/tools/verifgen/templates/PastEmploymentPosition-2009-2015-Project-Manager.json +26 -0
- package/test/identifications.test.js +56 -0
- package/test/issuing-exchanges.test.js +335 -0
- package/test/issuing-identify.test.js +137 -0
- package/test/jwt-controller.test.js +320 -0
- package/test/offers.test.js +682 -0
- package/test/registrar.test.js +276 -0
- package/test/root.test.js +25 -0
- package/test/swagger.test.js +21 -0
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const { reverse, map, flow } = require('lodash/fp');
|
|
2
|
+
const { mongoDb } = require('@spencejs/spence-mongo-repos');
|
|
3
|
+
const buildFastify = require('./helpers/mockvendor-build-fastify');
|
|
4
|
+
const initIdentificationsFactory = require('./factories/identifications.factory');
|
|
5
|
+
|
|
6
|
+
describe('identifications endpoints', () => {
|
|
7
|
+
let fastify;
|
|
8
|
+
let persistIdentification;
|
|
9
|
+
|
|
10
|
+
beforeAll(async () => {
|
|
11
|
+
fastify = buildFastify();
|
|
12
|
+
await fastify.ready();
|
|
13
|
+
({ persistIdentification } = initIdentificationsFactory(fastify));
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
beforeEach(async () => {
|
|
17
|
+
await mongoDb().collection('identifications').deleteMany({});
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterAll(async () => {
|
|
21
|
+
await fastify.close();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
describe('get endpoint', () => {
|
|
25
|
+
it('should handle if there are no identifications', async () => {
|
|
26
|
+
const response = await fastify.injectJson({
|
|
27
|
+
method: 'GET',
|
|
28
|
+
url: '/api/identifications',
|
|
29
|
+
});
|
|
30
|
+
expect(response.statusCode).toEqual(200);
|
|
31
|
+
expect(response.json).toEqual({ identifications: [] });
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should retrieve multiple identifications', async () => {
|
|
35
|
+
const records = [];
|
|
36
|
+
records[0] = await persistIdentification();
|
|
37
|
+
records[1] = await persistIdentification();
|
|
38
|
+
const response = await fastify.injectJson({
|
|
39
|
+
method: 'GET',
|
|
40
|
+
url: '/api/identifications',
|
|
41
|
+
});
|
|
42
|
+
expect(response.statusCode).toEqual(200);
|
|
43
|
+
expect(response.json).toEqual({
|
|
44
|
+
identifications: flow(
|
|
45
|
+
reverse,
|
|
46
|
+
map((record) => {
|
|
47
|
+
return {
|
|
48
|
+
...record,
|
|
49
|
+
id: record._id,
|
|
50
|
+
};
|
|
51
|
+
})
|
|
52
|
+
)(records),
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
const { mongoDb } = require('@spencejs/spence-mongo-repos');
|
|
2
|
+
const { ObjectId } = require('mongodb');
|
|
3
|
+
const {
|
|
4
|
+
ISO_DATETIME_FORMAT,
|
|
5
|
+
OBJECT_ID_FORMAT,
|
|
6
|
+
} = require('@verii/test-regexes');
|
|
7
|
+
const { testAuthToken } = require('@verii/tests-helpers');
|
|
8
|
+
const { first } = require('lodash/fp');
|
|
9
|
+
const nock = require('nock');
|
|
10
|
+
const { nanoid } = require('nanoid/non-secure');
|
|
11
|
+
const buildFastify = require('./helpers/mockvendor-build-fastify');
|
|
12
|
+
const initOfferFactory = require('./factories/offers.factory');
|
|
13
|
+
const initissuingExchangeFactory = require('./factories/delayed-offer.factory');
|
|
14
|
+
|
|
15
|
+
describe('Issuing Exchanges routes', () => {
|
|
16
|
+
let fastify;
|
|
17
|
+
let newOffer;
|
|
18
|
+
let persistIssuingExchanges;
|
|
19
|
+
|
|
20
|
+
beforeAll(async () => {
|
|
21
|
+
fastify = buildFastify();
|
|
22
|
+
await fastify.ready();
|
|
23
|
+
({ newOffer } = initOfferFactory(fastify));
|
|
24
|
+
({ persistIssuingExchanges } = initissuingExchangeFactory(fastify));
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
beforeEach(async () => {
|
|
28
|
+
await mongoDb().collection('offers').deleteMany({});
|
|
29
|
+
await mongoDb().collection('issuingExchanges').deleteMany({});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
afterAll(async () => {
|
|
33
|
+
await mongoDb().collection('offers').deleteMany({});
|
|
34
|
+
await mongoDb().collection('issuingExchanges').deleteMany({});
|
|
35
|
+
await fastify.close();
|
|
36
|
+
nock.cleanAll();
|
|
37
|
+
nock.restore();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
describe('issuing exchanges management', () => {
|
|
41
|
+
describe('getting delayed offer exchanges', () => {
|
|
42
|
+
it('should be able to get a delayed offer by exchangeId', async () => {
|
|
43
|
+
const issuingExchange = await persistIssuingExchanges();
|
|
44
|
+
const {
|
|
45
|
+
issuer: { id: tenantDID },
|
|
46
|
+
} = issuingExchange;
|
|
47
|
+
const response = await fastify.injectJson({
|
|
48
|
+
method: 'GET',
|
|
49
|
+
url: `/api/issuing-exchanges/${tenantDID}?exchangeId=${issuingExchange.exchangeId}`,
|
|
50
|
+
});
|
|
51
|
+
expect(response.statusCode).toEqual(200);
|
|
52
|
+
expect(response.json).toEqual(
|
|
53
|
+
expect.arrayContaining([
|
|
54
|
+
{
|
|
55
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
56
|
+
_id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
57
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
58
|
+
exchangeId: issuingExchange.exchangeId,
|
|
59
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
60
|
+
issuer: { id: tenantDID },
|
|
61
|
+
vendorUserId: issuingExchange.vendorUserId,
|
|
62
|
+
},
|
|
63
|
+
])
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
it('should be able to get a delayed offer by issuer', async () => {
|
|
67
|
+
const issuingExchange = await persistIssuingExchanges();
|
|
68
|
+
const {
|
|
69
|
+
issuer: { id: tenantDID },
|
|
70
|
+
} = issuingExchange;
|
|
71
|
+
const response = await fastify.injectJson({
|
|
72
|
+
method: 'GET',
|
|
73
|
+
url: `/api/issuing-exchanges/${tenantDID}?issuer=${issuingExchange.issuer}`,
|
|
74
|
+
});
|
|
75
|
+
expect(response.statusCode).toEqual(200);
|
|
76
|
+
expect(response.json).toEqual(
|
|
77
|
+
expect.arrayContaining([
|
|
78
|
+
{
|
|
79
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
80
|
+
_id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
81
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
82
|
+
exchangeId: issuingExchange.exchangeId,
|
|
83
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
84
|
+
issuer: { id: tenantDID },
|
|
85
|
+
vendorUserId: issuingExchange.vendorUserId,
|
|
86
|
+
},
|
|
87
|
+
])
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
it('should be able to get a delayed offer by vendorUserId', async () => {
|
|
91
|
+
const issuingExchange = await persistIssuingExchanges();
|
|
92
|
+
const {
|
|
93
|
+
issuer: { id: tenantDID },
|
|
94
|
+
} = issuingExchange;
|
|
95
|
+
const response = await fastify.injectJson({
|
|
96
|
+
method: 'GET',
|
|
97
|
+
url: `/api/issuing-exchanges/${tenantDID}?vendorUserId=${issuingExchange.vendorUserId}`,
|
|
98
|
+
});
|
|
99
|
+
expect(response.statusCode).toEqual(200);
|
|
100
|
+
expect(response.json).toEqual(
|
|
101
|
+
expect.arrayContaining([
|
|
102
|
+
{
|
|
103
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
104
|
+
_id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
105
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
106
|
+
exchangeId: issuingExchange.exchangeId,
|
|
107
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
108
|
+
issuer: { id: tenantDID },
|
|
109
|
+
vendorUserId: issuingExchange.vendorUserId,
|
|
110
|
+
},
|
|
111
|
+
])
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe('creating a delayed offer exchange', () => {
|
|
117
|
+
const imageBytes = Buffer.from([137, 80, 78, 71]);
|
|
118
|
+
|
|
119
|
+
it('should be able create a set of offers and get a qr code', async () => {
|
|
120
|
+
const offer = await newOffer();
|
|
121
|
+
const exchangeId = nanoid();
|
|
122
|
+
const offerId = nanoid();
|
|
123
|
+
const tenant = { did: offer.issuer.id };
|
|
124
|
+
nock('http://credentialagent.localhost.test')
|
|
125
|
+
.post(`/operator-api/v0.8/tenants/${tenant.did}/exchanges`)
|
|
126
|
+
.reply(200, {
|
|
127
|
+
id: exchangeId,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
nock('http://credentialagent.localhost.test')
|
|
131
|
+
.post(
|
|
132
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${exchangeId}/offers`
|
|
133
|
+
)
|
|
134
|
+
.reply(200, {
|
|
135
|
+
...offer,
|
|
136
|
+
createdAt: new Date().toISOString(),
|
|
137
|
+
updatedAt: new Date().toISOString(),
|
|
138
|
+
id: offerId,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
nock('http://credentialagent.localhost.test')
|
|
142
|
+
.post(
|
|
143
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${exchangeId}/offers/complete`
|
|
144
|
+
)
|
|
145
|
+
.reply(200, { offerIds: [offerId] });
|
|
146
|
+
|
|
147
|
+
nock('http://credentialagent.localhost.test')
|
|
148
|
+
.get(
|
|
149
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${exchangeId}/qrcode.png`
|
|
150
|
+
)
|
|
151
|
+
.reply(200, imageBytes, { 'Content-Type': 'image/png' });
|
|
152
|
+
|
|
153
|
+
const response = await fastify.inject({
|
|
154
|
+
method: 'POST',
|
|
155
|
+
url: `/api/issuing-exchanges/${tenant.did}/create-qrcode`,
|
|
156
|
+
payload: { offer },
|
|
157
|
+
headers: {
|
|
158
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
expect(response.statusCode).toEqual(200);
|
|
162
|
+
expect(response.headers['content-type']).toEqual('image/png');
|
|
163
|
+
expect(response.statusCode).toEqual(200);
|
|
164
|
+
expect(Buffer.byteLength(response.rawPayload)).toEqual(4);
|
|
165
|
+
expect(
|
|
166
|
+
await mongoDb().collection('issuingExchanges').findOne({})
|
|
167
|
+
).toEqual({
|
|
168
|
+
exchangeId,
|
|
169
|
+
tenantDID: tenant.did,
|
|
170
|
+
_id: expect.any(ObjectId),
|
|
171
|
+
createdAt: expect.any(Date),
|
|
172
|
+
updatedAt: expect.any(Date),
|
|
173
|
+
});
|
|
174
|
+
expect(await mongoDb().collection('offers').findOne({})).toEqual({
|
|
175
|
+
...offer,
|
|
176
|
+
exchangeId,
|
|
177
|
+
_id: expect.any(ObjectId),
|
|
178
|
+
createdAt: expect.any(Date),
|
|
179
|
+
updatedAt: expect.any(Date),
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
it('should be able create a set of offers and get a qr code with a vendorOriginContext', async () => {
|
|
184
|
+
const offer = await newOffer();
|
|
185
|
+
const exchangeId = nanoid();
|
|
186
|
+
const offerId = nanoid();
|
|
187
|
+
const tenant = { did: offer.issuer.id };
|
|
188
|
+
nock('http://credentialagent.localhost.test')
|
|
189
|
+
.post(`/operator-api/v0.8/tenants/${tenant.did}/exchanges`)
|
|
190
|
+
.reply(200, {
|
|
191
|
+
id: exchangeId,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
nock('http://credentialagent.localhost.test')
|
|
195
|
+
.post(
|
|
196
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${exchangeId}/offers`
|
|
197
|
+
)
|
|
198
|
+
.reply(200, {
|
|
199
|
+
...offer,
|
|
200
|
+
createdAt: new Date().toISOString(),
|
|
201
|
+
updatedAt: new Date().toISOString(),
|
|
202
|
+
id: offerId,
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
nock('http://credentialagent.localhost.test')
|
|
206
|
+
.post(
|
|
207
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${exchangeId}/offers/complete`
|
|
208
|
+
)
|
|
209
|
+
.reply(200, { offerIds: [offerId] });
|
|
210
|
+
|
|
211
|
+
nock('http://credentialagent.localhost.test')
|
|
212
|
+
.get(
|
|
213
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${exchangeId}/qrcode.png?vendorOriginContext=123`
|
|
214
|
+
)
|
|
215
|
+
.reply(200, imageBytes, { 'Content-Type': 'image/png' });
|
|
216
|
+
|
|
217
|
+
const response = await fastify.inject({
|
|
218
|
+
method: 'POST',
|
|
219
|
+
url: `/api/issuing-exchanges/${tenant.did}/create-qrcode`,
|
|
220
|
+
payload: { offer, vendorOriginContext: '123' },
|
|
221
|
+
headers: {
|
|
222
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
expect(response.statusCode).toEqual(200);
|
|
226
|
+
expect(response.headers['content-type']).toEqual('image/png');
|
|
227
|
+
expect(response.statusCode).toEqual(200);
|
|
228
|
+
expect(Buffer.byteLength(response.rawPayload)).toEqual(4);
|
|
229
|
+
expect(
|
|
230
|
+
await mongoDb().collection('issuingExchanges').findOne({})
|
|
231
|
+
).toEqual({
|
|
232
|
+
exchangeId,
|
|
233
|
+
tenantDID: tenant.did,
|
|
234
|
+
_id: expect.any(ObjectId),
|
|
235
|
+
createdAt: expect.any(Date),
|
|
236
|
+
updatedAt: expect.any(Date),
|
|
237
|
+
});
|
|
238
|
+
expect(await mongoDb().collection('offers').findOne({})).toEqual({
|
|
239
|
+
...offer,
|
|
240
|
+
exchangeId,
|
|
241
|
+
_id: expect.any(ObjectId),
|
|
242
|
+
createdAt: expect.any(Date),
|
|
243
|
+
updatedAt: expect.any(Date),
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it('should properly filter issuingExchanges based on did', async () => {
|
|
248
|
+
const dids = [`did:ion:${nanoid()}`, `did:ion:${nanoid()}`];
|
|
249
|
+
await persistIssuingExchanges({
|
|
250
|
+
issuer: { id: dids[0] },
|
|
251
|
+
});
|
|
252
|
+
await persistIssuingExchanges({
|
|
253
|
+
issuer: { id: dids[1] },
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const response = await fastify.inject({
|
|
257
|
+
method: 'GET',
|
|
258
|
+
url: `/api/issuing-exchanges/${dids[0]}`,
|
|
259
|
+
headers: {
|
|
260
|
+
authorization: `Bearer ${testAuthToken}`,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
expect(response.statusCode).toEqual(200);
|
|
264
|
+
expect(response.json()).toHaveLength(1);
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
describe('pushing offers for a previously created delayed offer exchange', () => {
|
|
269
|
+
let offer;
|
|
270
|
+
let issuingExchange;
|
|
271
|
+
let tenant;
|
|
272
|
+
let offerId;
|
|
273
|
+
|
|
274
|
+
beforeEach(async () => {
|
|
275
|
+
offerId = nanoid();
|
|
276
|
+
offer = await newOffer();
|
|
277
|
+
issuingExchange = await persistIssuingExchanges({
|
|
278
|
+
issuer: { id: offer.issuer.id },
|
|
279
|
+
});
|
|
280
|
+
tenant = {
|
|
281
|
+
did: issuingExchange.issuer.id,
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
nock('http://credentialagent.localhost.test')
|
|
285
|
+
.post(
|
|
286
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${issuingExchange.exchangeId}/offers`
|
|
287
|
+
)
|
|
288
|
+
.reply(200, {
|
|
289
|
+
...offer,
|
|
290
|
+
createdAt: new Date().toISOString(),
|
|
291
|
+
updatedAt: new Date().toISOString(),
|
|
292
|
+
id: offerId,
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
nock('http://credentialagent.localhost.test')
|
|
296
|
+
.post(
|
|
297
|
+
`/operator-api/v0.8/tenants/${tenant.did}/exchanges/${issuingExchange.exchangeId}/offers/complete`
|
|
298
|
+
)
|
|
299
|
+
.reply(200, { offerIds: [offerId] });
|
|
300
|
+
});
|
|
301
|
+
it('should be able to push-offers for existing exchange', async () => {
|
|
302
|
+
const response = await fastify.injectJson({
|
|
303
|
+
method: 'POST',
|
|
304
|
+
url: `/api/issuing-exchanges/${tenant.did}/${issuingExchange.exchangeId}/push-offers`,
|
|
305
|
+
payload: { offer },
|
|
306
|
+
});
|
|
307
|
+
expect(response.statusCode).toEqual(200);
|
|
308
|
+
expect(first(response.json)).toEqual({
|
|
309
|
+
...offer,
|
|
310
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
311
|
+
_id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
312
|
+
exchangeId: issuingExchange.exchangeId,
|
|
313
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
314
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
315
|
+
});
|
|
316
|
+
});
|
|
317
|
+
it('should be able to create a push-offer when an array is passed', async () => {
|
|
318
|
+
const response = await fastify.injectJson({
|
|
319
|
+
method: 'POST',
|
|
320
|
+
url: `/api/issuing-exchanges/${tenant.did}/${issuingExchange.exchangeId}/push-offers`,
|
|
321
|
+
payload: { offer: [offer] },
|
|
322
|
+
});
|
|
323
|
+
expect(response.statusCode).toEqual(200);
|
|
324
|
+
expect(first(response.json)).toEqual({
|
|
325
|
+
...offer,
|
|
326
|
+
exchangeId: issuingExchange.exchangeId,
|
|
327
|
+
id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
328
|
+
_id: expect.stringMatching(OBJECT_ID_FORMAT),
|
|
329
|
+
createdAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
330
|
+
updatedAt: expect.stringMatching(ISO_DATETIME_FORMAT),
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
});
|
|
334
|
+
});
|
|
335
|
+
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
const { mongoDb } = require('@spencejs/spence-mongo-repos');
|
|
2
|
+
const { ObjectId } = require('mongodb');
|
|
3
|
+
const buildFastify = require('./helpers/mockvendor-build-fastify');
|
|
4
|
+
const initUserFactory = require('./factories/users.factory');
|
|
5
|
+
const legacyAdamSmithIdentity = require('./helpers/legacy-Adam-Smith.json');
|
|
6
|
+
const v1AdamSmithIdentity = require('./helpers/latest-Adam-Smith.json');
|
|
7
|
+
|
|
8
|
+
describe('issuing/identify webhook test suite', () => {
|
|
9
|
+
let fastify;
|
|
10
|
+
let persistUser;
|
|
11
|
+
let user1;
|
|
12
|
+
|
|
13
|
+
beforeAll(async () => {
|
|
14
|
+
fastify = buildFastify();
|
|
15
|
+
await fastify.ready();
|
|
16
|
+
({ persistUser } = initUserFactory(fastify));
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
beforeEach(async () => {
|
|
20
|
+
await mongoDb().collection('users').deleteMany({});
|
|
21
|
+
await mongoDb().collection('identifications').deleteMany({});
|
|
22
|
+
|
|
23
|
+
[user1] = await Promise.all([
|
|
24
|
+
persistUser(),
|
|
25
|
+
persistUser({ emails: ['maria.williams@example.com'] }),
|
|
26
|
+
]);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
afterAll(async () => {
|
|
30
|
+
await fastify.close();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should be able to identify a matching user', async () => {
|
|
34
|
+
const response = await fastify.injectJson({
|
|
35
|
+
method: 'POST',
|
|
36
|
+
url: '/issuing/identify',
|
|
37
|
+
payload: {
|
|
38
|
+
...legacyAdamSmithIdentity,
|
|
39
|
+
exchangeId: new ObjectId(),
|
|
40
|
+
tenantDID: 'MY_ID',
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
expect(response.statusCode).toEqual(200);
|
|
44
|
+
expect(response.json).toEqual({
|
|
45
|
+
vendorUserId: user1.emails[0],
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should be able to identify an simple user', async () => {
|
|
50
|
+
const response = await fastify.injectJson({
|
|
51
|
+
method: 'POST',
|
|
52
|
+
url: '/issuing/identify',
|
|
53
|
+
payload: {
|
|
54
|
+
emails: ['adam.smith@example.com'],
|
|
55
|
+
exchangeId: new ObjectId(),
|
|
56
|
+
tenantDID: 'MY_ID',
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
expect(response.statusCode).toEqual(200);
|
|
60
|
+
expect(response.json).toEqual({
|
|
61
|
+
vendorUserId: user1.emails[0],
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should be able to identify a v1.0 user', async () => {
|
|
66
|
+
const response = await fastify.injectJson({
|
|
67
|
+
method: 'POST',
|
|
68
|
+
url: '/issuing/identify',
|
|
69
|
+
payload: {
|
|
70
|
+
...v1AdamSmithIdentity,
|
|
71
|
+
exchangeId: new ObjectId(),
|
|
72
|
+
tenantDID: 'MY_ID',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
expect(response.statusCode).toEqual(200);
|
|
76
|
+
expect(response.json).toEqual({
|
|
77
|
+
vendorUserId: user1.emails[0],
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('should be able to identify a v1.0 user with a uppercase email address', async () => {
|
|
82
|
+
const response = await fastify.injectJson({
|
|
83
|
+
method: 'POST',
|
|
84
|
+
url: '/issuing/identify',
|
|
85
|
+
payload: {
|
|
86
|
+
...v1AdamSmithIdentity,
|
|
87
|
+
emails: ['ADAM.SMITH@example.com'],
|
|
88
|
+
exchangeId: new ObjectId(),
|
|
89
|
+
tenantDID: 'MY_ID',
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
expect(response.statusCode).toEqual(200);
|
|
93
|
+
expect(response.json).toEqual({
|
|
94
|
+
vendorUserId: user1.emails[0],
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should be able to identify using the vendorOriginContext', async () => {
|
|
99
|
+
await persistUser({
|
|
100
|
+
token: 'foo',
|
|
101
|
+
emails: ['foo@example.com'],
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const response = await fastify.injectJson({
|
|
105
|
+
method: 'POST',
|
|
106
|
+
url: '/issuing/identify',
|
|
107
|
+
payload: {
|
|
108
|
+
phoneCredentials: [],
|
|
109
|
+
emailCredentials: [],
|
|
110
|
+
idDocumentCredentials: [],
|
|
111
|
+
emails: [],
|
|
112
|
+
phones: [],
|
|
113
|
+
exchangeId: new ObjectId(),
|
|
114
|
+
tenantDID: 'MY_ID',
|
|
115
|
+
vendorOriginContext: 'foo',
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
expect(response.statusCode).toEqual(200);
|
|
119
|
+
expect(response.json).toEqual({
|
|
120
|
+
vendorUserId: 'foo@example.com',
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should be able to 404 on a user not found', async () => {
|
|
125
|
+
const response = await fastify.injectJson({
|
|
126
|
+
method: 'POST',
|
|
127
|
+
url: '/issuing/identify',
|
|
128
|
+
payload: {
|
|
129
|
+
...legacyAdamSmithIdentity,
|
|
130
|
+
emails: ['unknown.user@example.com'],
|
|
131
|
+
exchangeId: new ObjectId(),
|
|
132
|
+
tenantDID: 'MY_ID',
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
expect(response.statusCode).toEqual(404);
|
|
136
|
+
});
|
|
137
|
+
});
|