@velocitycareerlabs/server-webwallet 1.26.0-dev-build.10a394937 → 1.26.0-dev-build.1675a0ab5
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/package.json +3 -3
- package/src/controllers/disclosures/controller.js +18 -1
- package/src/controllers/feeds/autohooks.js +20 -0
- package/src/controllers/feeds/controller.js +181 -0
- package/src/controllers/feeds/schemas/index.js +5 -0
- package/src/controllers/feeds/schemas/webwallet-get-feeds-response.schema.js +39 -0
- package/src/controllers/feeds/schemas/webwallet-share-feed-request-body.schema.js +24 -0
- package/src/controllers/feeds/schemas/webwallet-share-feed-response-body.schema.js +19 -0
- package/src/controllers/issuing/deep-link/controller.js +13 -1
- package/src/entities/disclosures/repos/disclosures.repo.js +1 -0
- package/src/entities/disclosures/schemas/webwallet-disclosure.schema.js +1 -0
- package/src/entities/disclosures/schemas/webwallet-presentation-request.schema.js +3 -0
- package/src/entities/feeds/index.js +4 -0
- package/src/entities/feeds/repos/feeds.repo.js +40 -0
- package/src/entities/feeds/repos/index.js +3 -0
- package/src/entities/feeds/schemas/index.js +3 -0
- package/src/entities/feeds/schemas/webwallet-feed.schema.js +39 -0
- package/src/entities/index.js +1 -0
- package/test/disclosures-controller/disclosure-credentials.test.js +87 -7
- package/test/factories/feeds.js +96 -0
- package/test/feeds-controller.test.js +124 -0
- package/test/issuing-controller/issuing-by-deeplink.test.js +1 -0
- package/test/issuing-controller/mocks/accept-offers-response.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@velocitycareerlabs/server-webwallet",
|
|
3
|
-
"version": "1.26.0-dev-build.
|
|
3
|
+
"version": "1.26.0-dev-build.1675a0ab5",
|
|
4
4
|
"description": "Web Wallet application",
|
|
5
5
|
"repository": "https://github.com/velocitycareerlabs/packages",
|
|
6
6
|
"engines": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@fastify/swagger": "^9.0.0",
|
|
34
34
|
"@fastify/swagger-ui": "^5.0.0",
|
|
35
35
|
"@spencejs/spence-mongo-repos": "^0.10.2",
|
|
36
|
-
"@velocitycareerlabs/migrations": "1.26.0-dev-build.
|
|
36
|
+
"@velocitycareerlabs/migrations": "1.26.0-dev-build.1675a0ab5",
|
|
37
37
|
"@verii/auth": "1.0.0-pre.1754372712",
|
|
38
38
|
"@verii/common-functions": "1.0.0-pre.1754372712",
|
|
39
39
|
"@verii/common-schemas": "1.0.0-pre.1754372712",
|
|
@@ -73,5 +73,5 @@
|
|
|
73
73
|
"nodemon": "3.1.10",
|
|
74
74
|
"prettier": "2.8.8"
|
|
75
75
|
},
|
|
76
|
-
"gitHead": "
|
|
76
|
+
"gitHead": "3b801a773c372d2d73b124d9463cc11dd324ecce"
|
|
77
77
|
}
|
|
@@ -5,6 +5,7 @@ const {
|
|
|
5
5
|
VCLDeepLink,
|
|
6
6
|
VCLPresentationRequestDescriptor,
|
|
7
7
|
VCLDidJwk,
|
|
8
|
+
VCLAuthTokenDescriptor,
|
|
8
9
|
} = require('@verii/vnf-nodejs-wallet-sdk');
|
|
9
10
|
const { getAppConfig } = require('../../fetchers/career-wallet/get-app-config');
|
|
10
11
|
const {
|
|
@@ -119,7 +120,9 @@ const disclosureController = async (fastify) => {
|
|
|
119
120
|
|
|
120
121
|
let authToken = null;
|
|
121
122
|
if (presentationRequest.feed) {
|
|
122
|
-
authToken = await vclSdk.getAuthToken(
|
|
123
|
+
authToken = await vclSdk.getAuthToken(
|
|
124
|
+
new VCLAuthTokenDescriptor(presentationRequest)
|
|
125
|
+
);
|
|
123
126
|
}
|
|
124
127
|
|
|
125
128
|
const { payload: presentation } = jwtDecode(
|
|
@@ -148,6 +151,20 @@ const disclosureController = async (fastify) => {
|
|
|
148
151
|
type: body.type,
|
|
149
152
|
});
|
|
150
153
|
|
|
154
|
+
if (presentationRequest.feed) {
|
|
155
|
+
await repos.feeds.insert({
|
|
156
|
+
auth0UserId: user.sub,
|
|
157
|
+
authToken,
|
|
158
|
+
deeplink: body.link,
|
|
159
|
+
disclosureId: presentation.presentation_definition.id.split('.')[1],
|
|
160
|
+
inspectorDid: presentation.iss,
|
|
161
|
+
credentialTypes:
|
|
162
|
+
presentation.presentation_definition.input_descriptors.map(
|
|
163
|
+
(descriptor) => descriptor.id
|
|
164
|
+
),
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
151
168
|
return { disclosure };
|
|
152
169
|
}
|
|
153
170
|
);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const { oauthPlugin } = require('@verii/auth');
|
|
2
|
+
const { values, forEach } = require('lodash/fp');
|
|
3
|
+
|
|
4
|
+
const controllerSchemas = require('./schemas');
|
|
5
|
+
const disclosureSchemas = require('../../entities/disclosures/schemas');
|
|
6
|
+
|
|
7
|
+
module.exports = async (fastify) => {
|
|
8
|
+
forEach(
|
|
9
|
+
(schema) => fastify.addSchema(schema),
|
|
10
|
+
[...values(disclosureSchemas), ...values(controllerSchemas)]
|
|
11
|
+
);
|
|
12
|
+
fastify
|
|
13
|
+
.autoSchemaPreset({
|
|
14
|
+
tags: ['webwallet'],
|
|
15
|
+
})
|
|
16
|
+
.register(oauthPlugin, {
|
|
17
|
+
domain: fastify.config.auth0Domain,
|
|
18
|
+
audience: [fastify.config.auth0WebWalletAudience],
|
|
19
|
+
});
|
|
20
|
+
};
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
const newError = require('http-errors');
|
|
2
|
+
const { jwtDecode } = require('@verii/jwt');
|
|
3
|
+
const {
|
|
4
|
+
VCLPresentationSubmission,
|
|
5
|
+
VCLDeepLink,
|
|
6
|
+
VCLPresentationRequestDescriptor,
|
|
7
|
+
VCLDidJwk,
|
|
8
|
+
VCLAuthTokenDescriptor,
|
|
9
|
+
} = require('@verii/vnf-nodejs-wallet-sdk');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @param {import('fastify').FastifyInstance} fastify
|
|
13
|
+
*/
|
|
14
|
+
const feedsController = async (fastify) => {
|
|
15
|
+
fastify.get(
|
|
16
|
+
'/',
|
|
17
|
+
{
|
|
18
|
+
preValidation: fastify.verifyAccessToken(),
|
|
19
|
+
schema: fastify.autoSchema({
|
|
20
|
+
tags: ['webwallet'],
|
|
21
|
+
response: {
|
|
22
|
+
200: {
|
|
23
|
+
$ref: 'https://velocitycareerlabs.io/webwallet-get-feeds-response.schema.json',
|
|
24
|
+
},
|
|
25
|
+
'4xx': { $ref: 'error#' },
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
},
|
|
29
|
+
async ({ repos, user }) => {
|
|
30
|
+
const feeds = await repos.feeds.find({
|
|
31
|
+
filter: { auth0UserId: user.sub },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
return feeds;
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
fastify.delete(
|
|
38
|
+
'/:feedId',
|
|
39
|
+
{
|
|
40
|
+
preValidation: fastify.verifyAccessToken(),
|
|
41
|
+
schema: fastify.autoSchema({
|
|
42
|
+
params: {
|
|
43
|
+
type: 'object',
|
|
44
|
+
properties: {
|
|
45
|
+
feedId: { type: 'string' },
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
response: {
|
|
49
|
+
204: { type: 'null' },
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
async (req, reply) => {
|
|
54
|
+
const {
|
|
55
|
+
repos: { feeds: feedsRepo },
|
|
56
|
+
params,
|
|
57
|
+
user,
|
|
58
|
+
} = req;
|
|
59
|
+
const feed = await feedsRepo.findOne({
|
|
60
|
+
filter: { _id: params.feedId, auth0UserId: user.sub },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (!feed) {
|
|
64
|
+
throw newError.NotFound(`Feed ${params.feedId} not found`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
await feedsRepo.update(params.feedId, {
|
|
68
|
+
revokedAt: new Date(),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
reply.code(204);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
fastify.post(
|
|
75
|
+
'/share-feed',
|
|
76
|
+
{
|
|
77
|
+
preValidation: fastify.verifyAccessToken(),
|
|
78
|
+
schema: fastify.autoSchema({
|
|
79
|
+
tags: ['webwallet'],
|
|
80
|
+
body: {
|
|
81
|
+
$ref: 'https://velocitycareerlabs.io/webwalletshare-feed-request-body.schema.json',
|
|
82
|
+
},
|
|
83
|
+
response: {
|
|
84
|
+
200: {
|
|
85
|
+
$ref: 'https://velocitycareerlabs.io/webwallet-share-feed-response.schema.json',
|
|
86
|
+
},
|
|
87
|
+
'4xx': { $ref: 'error#' },
|
|
88
|
+
},
|
|
89
|
+
}),
|
|
90
|
+
},
|
|
91
|
+
async ({
|
|
92
|
+
body,
|
|
93
|
+
vclSdk,
|
|
94
|
+
repos,
|
|
95
|
+
user,
|
|
96
|
+
config: { careerWalletAdminAccessToken },
|
|
97
|
+
}) => {
|
|
98
|
+
const { didKeyMetadatum } = await repos.accounts.findOne({
|
|
99
|
+
filter: { userId: user.sub },
|
|
100
|
+
});
|
|
101
|
+
const didJwk =
|
|
102
|
+
didKeyMetadatum &&
|
|
103
|
+
Array.isArray(didKeyMetadatum) &&
|
|
104
|
+
didKeyMetadatum.length > 0
|
|
105
|
+
? VCLDidJwk.fromJSON(didKeyMetadatum[0])
|
|
106
|
+
: null;
|
|
107
|
+
|
|
108
|
+
const { did: userDid } = await repos.accounts.findOne({
|
|
109
|
+
filter: { userId: user.sub },
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const feeds = await repos.feeds.find({
|
|
113
|
+
filter: {
|
|
114
|
+
auth0UserId: user.sub,
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const disclosurePromises = feeds.map(async (feed) => {
|
|
119
|
+
const credentialsMatch = body.credentials.filter((credential) =>
|
|
120
|
+
feed.credentialTypes.includes(credential.inputDescriptor)
|
|
121
|
+
);
|
|
122
|
+
if (credentialsMatch.length === 0) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const presentationRequest = await vclSdk.getPresentationRequest(
|
|
127
|
+
new VCLPresentationRequestDescriptor(
|
|
128
|
+
new VCLDeepLink(feed.deeplink),
|
|
129
|
+
null,
|
|
130
|
+
didJwk,
|
|
131
|
+
careerWalletAdminAccessToken
|
|
132
|
+
)
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
const { payload: presentation } = jwtDecode(
|
|
136
|
+
presentationRequest.jwt.encodedJwt
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
let { authToken } = feed;
|
|
140
|
+
|
|
141
|
+
const authTokenValid =
|
|
142
|
+
feed.authToken.accessToken.jwtValue.payload.exp >
|
|
143
|
+
Math.floor(Date.now() / 1000);
|
|
144
|
+
|
|
145
|
+
if (!authTokenValid) {
|
|
146
|
+
authToken = await vclSdk.getAuthToken(
|
|
147
|
+
new VCLAuthTokenDescriptor(presentationRequest),
|
|
148
|
+
feed.refreshToken
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const submissionResult = await vclSdk.submitPresentation(
|
|
153
|
+
new VCLPresentationSubmission(presentationRequest, credentialsMatch),
|
|
154
|
+
authToken
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const disclosure = await repos.disclosures.insert({
|
|
158
|
+
auth0UserId: user.sub,
|
|
159
|
+
userDid,
|
|
160
|
+
presentation,
|
|
161
|
+
encodedJwt: presentationRequest.jwt.encodedJwt,
|
|
162
|
+
jti: submissionResult.jti,
|
|
163
|
+
submissionId: submissionResult.submissionId,
|
|
164
|
+
presentationDefinitionId: presentation.presentation_definition.id,
|
|
165
|
+
token: submissionResult.sessionToken.value,
|
|
166
|
+
sharedCredentials: credentialsMatch.map(({ id }) => id),
|
|
167
|
+
type: body.type,
|
|
168
|
+
feed: true,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
return disclosure;
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const disclosures = await Promise.all(disclosurePromises);
|
|
175
|
+
|
|
176
|
+
return { disclosures };
|
|
177
|
+
}
|
|
178
|
+
);
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
module.exports = feedsController;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const webWalletGetFeedsResponseSchema = {
|
|
2
|
+
$id: 'https://velocitycareerlabs.io/webwallet-get-feeds-response.schema.json',
|
|
3
|
+
title: 'webwallet-get-feeds-response',
|
|
4
|
+
description: 'an array of feed objects returned by webwallet get feeds',
|
|
5
|
+
type: 'array',
|
|
6
|
+
items: {
|
|
7
|
+
type: 'object',
|
|
8
|
+
properties: {
|
|
9
|
+
id: { type: 'string' },
|
|
10
|
+
auth0UserId: { type: 'string' },
|
|
11
|
+
authToken: { type: 'object', additionalProperties: true },
|
|
12
|
+
deeplink: { type: 'string' },
|
|
13
|
+
disclosureId: { type: 'string' },
|
|
14
|
+
inspectorDid: { type: 'string' },
|
|
15
|
+
credentialTypes: {
|
|
16
|
+
type: 'array',
|
|
17
|
+
items: { type: 'string' },
|
|
18
|
+
},
|
|
19
|
+
createdAt: { type: 'string' },
|
|
20
|
+
updatedAt: { type: 'string' },
|
|
21
|
+
revokedAt: { type: 'string' },
|
|
22
|
+
},
|
|
23
|
+
required: [
|
|
24
|
+
'auth0UserId',
|
|
25
|
+
'authToken',
|
|
26
|
+
'deeplink',
|
|
27
|
+
'disclosureId',
|
|
28
|
+
'inspectorDid',
|
|
29
|
+
'credentialTypes',
|
|
30
|
+
'createdAt',
|
|
31
|
+
'updatedAt',
|
|
32
|
+
],
|
|
33
|
+
additionalProperties: false,
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports = {
|
|
38
|
+
webWalletGetFeedsResponseSchema,
|
|
39
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const webWalletShareFeedRequestBodySchema = {
|
|
2
|
+
$id: 'https://velocitycareerlabs.io/webwalletshare-feed-request-body.schema.json',
|
|
3
|
+
title: 'webwallet-accept-presentation-request',
|
|
4
|
+
description: 'the request schema for webwallet accept presentation request',
|
|
5
|
+
type: 'object',
|
|
6
|
+
properties: {
|
|
7
|
+
credentials: {
|
|
8
|
+
type: 'array',
|
|
9
|
+
items: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
id: { type: 'string' },
|
|
13
|
+
inputDescriptor: { type: 'string' },
|
|
14
|
+
jwtVc: { type: 'string' },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
required: ['credentials'],
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
module.exports = {
|
|
23
|
+
webWalletShareFeedRequestBodySchema,
|
|
24
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const webWalletShareFeedResponseBodySchema = {
|
|
2
|
+
$id: 'https://velocitycareerlabs.io/webwallet-share-feed-response.schema.json',
|
|
3
|
+
title: 'webwallet-share-feed-response',
|
|
4
|
+
description: 'the response schema for webwallet accept presentation request',
|
|
5
|
+
type: 'object',
|
|
6
|
+
properties: {
|
|
7
|
+
disclosures: {
|
|
8
|
+
type: 'array',
|
|
9
|
+
items: {
|
|
10
|
+
$ref: 'https://velocitycareerlabs.io/webwallet-disclosure.schema.json',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
required: ['disclosures'],
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
module.exports = {
|
|
18
|
+
webWalletShareFeedResponseBodySchema,
|
|
19
|
+
};
|
|
@@ -9,7 +9,7 @@ const {
|
|
|
9
9
|
VCLVerifiedProfile,
|
|
10
10
|
VCLDidJwk,
|
|
11
11
|
} = require('@verii/vnf-nodejs-wallet-sdk');
|
|
12
|
-
const { omit, map } = require('lodash/fp');
|
|
12
|
+
const { omit, map, intersection, isEmpty } = require('lodash/fp');
|
|
13
13
|
const {
|
|
14
14
|
loadAdditionalRenderInfo,
|
|
15
15
|
getCredentialsFromOffers,
|
|
@@ -173,6 +173,11 @@ const issuingController = async (fastify) => {
|
|
|
173
173
|
// eslint-disable-next-line no-unused-vars
|
|
174
174
|
savedCredentials = await req.repos.credentials.insertMany(credentials);
|
|
175
175
|
}
|
|
176
|
+
const feeds = await req.repos.feeds.find({
|
|
177
|
+
filter: {
|
|
178
|
+
auth0UserId: req.user.sub,
|
|
179
|
+
},
|
|
180
|
+
});
|
|
176
181
|
|
|
177
182
|
return {
|
|
178
183
|
passedCredentials:
|
|
@@ -180,6 +185,7 @@ const issuingController = async (fastify) => {
|
|
|
180
185
|
(credential) => ({
|
|
181
186
|
...omit(['_id'], credential),
|
|
182
187
|
id: credential._id,
|
|
188
|
+
feed: shouldShareViaFeeds(feeds, credential.type),
|
|
183
189
|
}),
|
|
184
190
|
savedCredentials
|
|
185
191
|
) || [],
|
|
@@ -195,6 +201,12 @@ const issuingController = async (fastify) => {
|
|
|
195
201
|
? VCLDidJwk.fromJSON(account.didKeyMetadatum[0])
|
|
196
202
|
: null;
|
|
197
203
|
};
|
|
204
|
+
|
|
205
|
+
const shouldShareViaFeeds = (feeds, credentialType) =>
|
|
206
|
+
feeds.some(
|
|
207
|
+
({ credentialTypes }) =>
|
|
208
|
+
!isEmpty(intersection(credentialTypes, credentialType))
|
|
209
|
+
);
|
|
198
210
|
};
|
|
199
211
|
|
|
200
212
|
module.exports = issuingController;
|
|
@@ -64,6 +64,9 @@ const webWalletPresentationRequestSchema = {
|
|
|
64
64
|
},
|
|
65
65
|
progress_uri: { type: 'string', format: 'uri' },
|
|
66
66
|
submit_presentation_uri: { type: 'string', format: 'uri' },
|
|
67
|
+
feed: {
|
|
68
|
+
type: 'boolean',
|
|
69
|
+
},
|
|
67
70
|
},
|
|
68
71
|
required: ['client_name', 'logo_uri', 'tos_uri'],
|
|
69
72
|
},
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const {
|
|
2
|
+
autoboxIdsExtension,
|
|
3
|
+
repoFactory,
|
|
4
|
+
} = require('@spencejs/spence-mongo-repos');
|
|
5
|
+
|
|
6
|
+
module.exports = (app, _, next = () => {}) => {
|
|
7
|
+
next();
|
|
8
|
+
return repoFactory(
|
|
9
|
+
{
|
|
10
|
+
name: 'feeds',
|
|
11
|
+
entityName: 'feeds',
|
|
12
|
+
defaultProjection: {
|
|
13
|
+
_id: 1,
|
|
14
|
+
auth0UserId: 1,
|
|
15
|
+
authToken: 1,
|
|
16
|
+
deeplink: 1,
|
|
17
|
+
disclosureId: 1,
|
|
18
|
+
inspectorDid: 1,
|
|
19
|
+
credentialTypes: 1,
|
|
20
|
+
createdAt: 1,
|
|
21
|
+
updatedAt: 1,
|
|
22
|
+
revokedAt: 1,
|
|
23
|
+
},
|
|
24
|
+
extensions: [autoboxIdsExtension, filterRevokedFeedsExtension],
|
|
25
|
+
},
|
|
26
|
+
app
|
|
27
|
+
);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const filterRevokedFeedsExtension = (parent) => {
|
|
31
|
+
return {
|
|
32
|
+
prepFilter: (filter) => {
|
|
33
|
+
return parent.prepFilter({
|
|
34
|
+
...filter,
|
|
35
|
+
revokedAt: filter.revokedAt ?? { $exists: false },
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
extensions: parent.extensions.concat(['filterRevokedFeedsExtension']),
|
|
39
|
+
};
|
|
40
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const webWalletFeedSchema = {
|
|
2
|
+
$id: 'https://velocitycareerlabs.io/webwallet-feed.schema.json',
|
|
3
|
+
title: 'webwallet-feed',
|
|
4
|
+
description: 'The schema of the accepted feed',
|
|
5
|
+
type: 'object',
|
|
6
|
+
properties: {
|
|
7
|
+
id: { type: 'string' },
|
|
8
|
+
auth0UserId: {
|
|
9
|
+
type: 'string',
|
|
10
|
+
},
|
|
11
|
+
authToken: { type: 'object', additionalProperties: true },
|
|
12
|
+
deeplink: { type: 'string' },
|
|
13
|
+
disclosureId: { type: 'string' },
|
|
14
|
+
inspectorDid: { type: 'string' },
|
|
15
|
+
credentialTypes: {
|
|
16
|
+
type: 'array',
|
|
17
|
+
items: { type: 'string' },
|
|
18
|
+
},
|
|
19
|
+
createdAt: { type: 'string' },
|
|
20
|
+
updatedAt: { type: 'string' },
|
|
21
|
+
revokedAt: { type: 'string' },
|
|
22
|
+
},
|
|
23
|
+
required: [
|
|
24
|
+
'id',
|
|
25
|
+
'auth0UserId',
|
|
26
|
+
'authToken',
|
|
27
|
+
'deeplink',
|
|
28
|
+
'disclosureId',
|
|
29
|
+
'inspectorDid',
|
|
30
|
+
'credentialTypes',
|
|
31
|
+
'createdAt',
|
|
32
|
+
'updatedAt',
|
|
33
|
+
],
|
|
34
|
+
additionalProperties: true,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports = {
|
|
38
|
+
webWalletFeedSchema,
|
|
39
|
+
};
|
package/src/entities/index.js
CHANGED
|
@@ -32,7 +32,11 @@ jest.mock('@verii/vnf-nodejs-wallet-sdk', () => {
|
|
|
32
32
|
.fn()
|
|
33
33
|
.mockResolvedValue(getCredentialManifestMock),
|
|
34
34
|
submitPresentation: jest.fn().mockResolvedValue(submissionResultMock),
|
|
35
|
-
getAuthToken: jest.fn()
|
|
35
|
+
getAuthToken: jest.fn().mockResolvedValue({
|
|
36
|
+
value: 'mock_auth_token',
|
|
37
|
+
accessToken: { value: 'mock_access_token' },
|
|
38
|
+
refreshToken: { value: 'mock_refresh_token' },
|
|
39
|
+
}),
|
|
36
40
|
}),
|
|
37
41
|
},
|
|
38
42
|
};
|
|
@@ -77,6 +81,7 @@ describe('Test disclosure credentials controller', () => {
|
|
|
77
81
|
nock.cleanAll();
|
|
78
82
|
jest.clearAllMocks();
|
|
79
83
|
await mongoDb().collection('disclosures').deleteMany();
|
|
84
|
+
await mongoDb().collection('feeds').deleteMany();
|
|
80
85
|
});
|
|
81
86
|
|
|
82
87
|
afterAll(async () => {
|
|
@@ -99,8 +104,8 @@ describe('Test disclosure credentials controller', () => {
|
|
|
99
104
|
|
|
100
105
|
expect(response.statusCode).toBe(200);
|
|
101
106
|
|
|
102
|
-
expect(vclSdk.getPresentationRequest).
|
|
103
|
-
expect(vclSdk.getPresentationRequest).
|
|
107
|
+
expect(vclSdk.getPresentationRequest).toHaveBeenCalledTimes(1);
|
|
108
|
+
expect(vclSdk.getPresentationRequest).toHaveBeenCalledWith(
|
|
104
109
|
new VCLPresentationRequestDescriptor(
|
|
105
110
|
new VCLDeepLink(inspectionDeepLink)
|
|
106
111
|
)
|
|
@@ -188,8 +193,8 @@ describe('Test disclosure credentials controller', () => {
|
|
|
188
193
|
|
|
189
194
|
expect(response.statusCode).toBe(200);
|
|
190
195
|
|
|
191
|
-
expect(vclSdk.getPresentationRequest).
|
|
192
|
-
expect(vclSdk.getPresentationRequest).
|
|
196
|
+
expect(vclSdk.getPresentationRequest).toHaveBeenCalledTimes(1);
|
|
197
|
+
expect(vclSdk.getPresentationRequest).toHaveBeenCalledWith(
|
|
193
198
|
new VCLPresentationRequestDescriptor(
|
|
194
199
|
new VCLDeepLink(inspectionDeepLink),
|
|
195
200
|
null,
|
|
@@ -202,8 +207,8 @@ describe('Test disclosure credentials controller', () => {
|
|
|
202
207
|
presentationRequestMock.jwt.encodedJwt
|
|
203
208
|
);
|
|
204
209
|
|
|
205
|
-
expect(vclSdk.submitPresentation).
|
|
206
|
-
expect(vclSdk.submitPresentation).
|
|
210
|
+
expect(vclSdk.submitPresentation).toHaveBeenCalledTimes(1);
|
|
211
|
+
expect(vclSdk.submitPresentation).toHaveBeenCalledWith(
|
|
207
212
|
expect.objectContaining({
|
|
208
213
|
exchangeId: submissionResultMock.exchange.id,
|
|
209
214
|
submitUri: presentationSubmissionMock.submitUri,
|
|
@@ -247,6 +252,81 @@ describe('Test disclosure credentials controller', () => {
|
|
|
247
252
|
}).toEqual(response.json);
|
|
248
253
|
});
|
|
249
254
|
|
|
255
|
+
it('should accept presentation and create feed when disclosure has feed', async () => {
|
|
256
|
+
const presentationRequestFeedMock = {
|
|
257
|
+
...require('./mocks').presentationRequestMock,
|
|
258
|
+
feed: true,
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
vclSdk.getPresentationRequest.mockResolvedValueOnce(
|
|
262
|
+
presentationRequestFeedMock
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
const response = await fastify.injectJson({
|
|
266
|
+
method: 'POST',
|
|
267
|
+
url: '/disclosures/accept-presentation-request',
|
|
268
|
+
payload: {
|
|
269
|
+
link: inspectionDeepLink,
|
|
270
|
+
credentials: [
|
|
271
|
+
{
|
|
272
|
+
id: 'credential_id_feed',
|
|
273
|
+
inputDescriptor: 'EducationDegreeGraduationV1.1',
|
|
274
|
+
jwtVc: CredentialMocks.JwtCredentialEmail,
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
},
|
|
278
|
+
headers: {
|
|
279
|
+
authorization: `Bearer ${idToken}`,
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
expect(response.statusCode).toBe(200);
|
|
284
|
+
|
|
285
|
+
expect(vclSdk.getAuthToken).toHaveBeenCalledTimes(1);
|
|
286
|
+
|
|
287
|
+
const savedDisclosure = await mongoDb()
|
|
288
|
+
.collection('disclosures')
|
|
289
|
+
.findOne();
|
|
290
|
+
|
|
291
|
+
expect(savedDisclosure).toEqual({
|
|
292
|
+
_id: expect.any(ObjectId),
|
|
293
|
+
auth0UserId: userId,
|
|
294
|
+
userDid: did,
|
|
295
|
+
presentation: expect.any(Object),
|
|
296
|
+
encodedJwt: presentationRequestFeedMock.jwt.encodedJwt,
|
|
297
|
+
jti: submissionResultMock.jti,
|
|
298
|
+
submissionId: submissionResultMock.submissionId,
|
|
299
|
+
presentationDefinitionId: expect.any(String),
|
|
300
|
+
token: submissionResultMock.sessionToken.value,
|
|
301
|
+
sharedCredentials: ['credential_id_feed'],
|
|
302
|
+
createdAt: expect.any(Date),
|
|
303
|
+
updatedAt: expect.any(Date),
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
const savedFeed = await mongoDb().collection('feeds').findOne();
|
|
307
|
+
|
|
308
|
+
expect(savedFeed).toEqual({
|
|
309
|
+
_id: expect.any(ObjectId),
|
|
310
|
+
auth0UserId: userId,
|
|
311
|
+
authToken: expect.any(Object),
|
|
312
|
+
deeplink: inspectionDeepLink,
|
|
313
|
+
disclosureId: expect.any(String),
|
|
314
|
+
inspectorDid: expect.any(String),
|
|
315
|
+
credentialTypes: expect.any(Array),
|
|
316
|
+
createdAt: expect.any(Date),
|
|
317
|
+
updatedAt: expect.any(Date),
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
expect(response.json).toEqual({
|
|
321
|
+
disclosure: {
|
|
322
|
+
...omit(['_id', 'auth0UserId', 'userDid'], savedDisclosure),
|
|
323
|
+
id: savedDisclosure._id.toString(),
|
|
324
|
+
updatedAt: savedDisclosure.updatedAt.toISOString(),
|
|
325
|
+
createdAt: savedDisclosure.createdAt.toISOString(),
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
});
|
|
329
|
+
|
|
250
330
|
it('should return 401 if no access token is provided', async () => {
|
|
251
331
|
const response = await fastify.injectJson({
|
|
252
332
|
method: 'POST',
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* eslint-disable max-len */
|
|
2
|
+
const { register } = require('@spencejs/spence-factories');
|
|
3
|
+
const { feedsRepoPlugin } = require('../../src/entities/feeds');
|
|
4
|
+
|
|
5
|
+
module.exports = (app) => {
|
|
6
|
+
return register(
|
|
7
|
+
'feeds',
|
|
8
|
+
feedsRepoPlugin(app)({ config: app.config }),
|
|
9
|
+
async (overrides) => {
|
|
10
|
+
return {
|
|
11
|
+
auth0UserId: 'auth0|6798e0e98aea20c2a606d1ca',
|
|
12
|
+
authToken: {
|
|
13
|
+
payload: {
|
|
14
|
+
access_token:
|
|
15
|
+
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiIjZXhjaGFuZ2Uta2V5LTEifQ.eyJuYmYiOjE3NTI0OTAyMDksImp0aSI6IlJGYXR4Z1VCN2hqOEJrbmxYSXpjRyIsImlzcyI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImF1ZCI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImV4cCI6MTc1MzA5NTAwOSwic3ViIjoiNjM4NmY4MjRlNzc0Nzg5YzQwM2M5NmEwIiwiaWF0IjoxNzUyNDkwMjA5fQ.ajqMpwmuIWzgHN-RsMpp7MFSA9EHVPtYST68TTexUCfGthX2oX-ocT2j0SrKJO931OH4DyXzDzAE6oZGrAtCnw',
|
|
16
|
+
token_type: 'Bearer',
|
|
17
|
+
refresh_token:
|
|
18
|
+
'211c1835e9845272f85bff7b2d3700f10e6dcedf926688bcea9b356059aeb99078d8155aca156df6a059d5b88ae66fdd6a979dd04767b120e3f94eb28352703e',
|
|
19
|
+
},
|
|
20
|
+
authTokenUri:
|
|
21
|
+
'https://devagent.velocitycareerlabs.io/api/holder/v0.6/org/did:web:devregistrar.velocitynetwork.foundation:d:www.umass.edu/oauth/token',
|
|
22
|
+
walletDid:
|
|
23
|
+
'did:jwk:eyJjcnYiOiJzZWNwMjU2azEiLCJrdHkiOiJFQyIsIngiOiJCbnhJcVBBUFB5RTNOVTJEejhaUnhIQUhIQW9aWmFUem95Ry1ONW1va2pjIiwieSI6ImQ3aEhUNlNqbVdOYkdpYnhzVnI3UThEVU1sbVNSY245bGFyUG04R3haTXMifQ',
|
|
24
|
+
relyingPartyDid:
|
|
25
|
+
'did:web:devregistrar.velocitynetwork.foundation:d:www.umass.edu',
|
|
26
|
+
accessToken: {
|
|
27
|
+
value:
|
|
28
|
+
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiIjZXhjaGFuZ2Uta2V5LTEifQ.eyJuYmYiOjE3NTI0OTAyMDksImp0aSI6IlJGYXR4Z1VCN2hqOEJrbmxYSXpjRyIsImlzcyI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImF1ZCI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImV4cCI6MTc1MzA5NTAwOSwic3ViIjoiNjM4NmY4MjRlNzc0Nzg5YzQwM2M5NmEwIiwiaWF0IjoxNzUyNDkwMjA5fQ.ajqMpwmuIWzgHN-RsMpp7MFSA9EHVPtYST68TTexUCfGthX2oX-ocT2j0SrKJO931OH4DyXzDzAE6oZGrAtCnw',
|
|
29
|
+
jwtValue: {
|
|
30
|
+
signedJwt: {
|
|
31
|
+
header:
|
|
32
|
+
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiIjZXhjaGFuZ2Uta2V5LTEifQ',
|
|
33
|
+
payload:
|
|
34
|
+
'eyJuYmYiOjE3NTI0OTAyMDksImp0aSI6IlJGYXR4Z1VCN2hqOEJrbmxYSXpjRyIsImlzcyI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImF1ZCI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImV4cCI6MTc1MzA5NTAwOSwic3ViIjoiNjM4NmY4MjRlNzc0Nzg5YzQwM2M5NmEwIiwiaWF0IjoxNzUyNDkwMjA5fQ',
|
|
35
|
+
signature:
|
|
36
|
+
'ajqMpwmuIWzgHN-RsMpp7MFSA9EHVPtYST68TTexUCfGthX2oX-ocT2j0SrKJO931OH4DyXzDzAE6oZGrAtCnw',
|
|
37
|
+
},
|
|
38
|
+
encodedJwt:
|
|
39
|
+
'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NksiLCJraWQiOiIjZXhjaGFuZ2Uta2V5LTEifQ.eyJuYmYiOjE3NTI0OTAyMDksImp0aSI6IlJGYXR4Z1VCN2hqOEJrbmxYSXpjRyIsImlzcyI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImF1ZCI6ImRpZDp3ZWI6ZGV2cmVnaXN0cmFyLnZlbG9jaXR5bmV0d29yay5mb3VuZGF0aW9uOmQ6d3d3LnVtYXNzLmVkdSIsImV4cCI6MTc1MzA5NTAwOSwic3ViIjoiNjM4NmY4MjRlNzc0Nzg5YzQwM2M5NmEwIiwiaWF0IjoxNzUyNDkwMjA5fQ.ajqMpwmuIWzgHN-RsMpp7MFSA9EHVPtYST68TTexUCfGthX2oX-ocT2j0SrKJO931OH4DyXzDzAE6oZGrAtCnw',
|
|
40
|
+
header: {
|
|
41
|
+
typ: 'JWT',
|
|
42
|
+
alg: 'ES256K',
|
|
43
|
+
kid: '#exchange-key-1',
|
|
44
|
+
},
|
|
45
|
+
payload: {
|
|
46
|
+
nbf: 1752490209,
|
|
47
|
+
jti: 'RFatxgUB7hj8BknlXIzcG',
|
|
48
|
+
iss: 'did:web:devregistrar.velocitynetwork.foundation:d:www.umass.edu',
|
|
49
|
+
aud: 'did:web:devregistrar.velocitynetwork.foundation:d:www.umass.edu',
|
|
50
|
+
exp: 1753095009,
|
|
51
|
+
sub: '6386f824e774789c403c96a0',
|
|
52
|
+
iat: 1752490209,
|
|
53
|
+
},
|
|
54
|
+
signature:
|
|
55
|
+
'ajqMpwmuIWzgHN-RsMpp7MFSA9EHVPtYST68TTexUCfGthX2oX-ocT2j0SrKJO931OH4DyXzDzAE6oZGrAtCnw',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
refreshToken: {
|
|
59
|
+
value:
|
|
60
|
+
'211c1835e9845272f85bff7b2d3700f10e6dcedf926688bcea9b356059aeb99078d8155aca156df6a059d5b88ae66fdd6a979dd04767b120e3f94eb28352703e',
|
|
61
|
+
jwtValue: {
|
|
62
|
+
signedJwt: {
|
|
63
|
+
header: '',
|
|
64
|
+
payload: '',
|
|
65
|
+
signature: '',
|
|
66
|
+
},
|
|
67
|
+
encodedJwt: '',
|
|
68
|
+
header: {},
|
|
69
|
+
payload: {},
|
|
70
|
+
signature: '',
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
tokenType: 'Bearer',
|
|
74
|
+
},
|
|
75
|
+
deeplink:
|
|
76
|
+
'velocity-network-devnet://inspect?request_uri=https://devagent.velocitycareerlabs.io/api/holder/v0.6/org/did:web:devregistrar.velocitynetwork.foundation:d:www.umass.edu/inspect/get-presentation-request?id=68736ac609c41e44796d040e%26inspectorDid%3Ddid%3Aweb%3Adevregistrar.velocitynetwork.foundation%3Ad%3Awww.umass.edu%26vendorOriginContext%3DAdam',
|
|
77
|
+
disclosureId: '68736ac609c41e44796d040e',
|
|
78
|
+
inspectorDid:
|
|
79
|
+
'did:web:devregistrar.velocitynetwork.foundation:d:www.umass.edu',
|
|
80
|
+
credentialTypes: [
|
|
81
|
+
'CertificationV1.1',
|
|
82
|
+
'LicenseV1.1',
|
|
83
|
+
'AssessmentV1.1',
|
|
84
|
+
'OpenBadgeCredential',
|
|
85
|
+
],
|
|
86
|
+
createdAt: {
|
|
87
|
+
$date: '2025-07-14T10:52:35.522Z',
|
|
88
|
+
},
|
|
89
|
+
updatedAt: {
|
|
90
|
+
$date: '2025-07-14T10:52:35.522Z',
|
|
91
|
+
},
|
|
92
|
+
...overrides(),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
);
|
|
96
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
const { mongoDb } = require('@spencejs/spence-mongo-repos');
|
|
2
|
+
const nock = require('nock');
|
|
3
|
+
const buildFastify = require('./helpers/webwallet-build-fastify');
|
|
4
|
+
const initFeedsFactory = require('./factories/feeds');
|
|
5
|
+
|
|
6
|
+
const auth0Token =
|
|
7
|
+
// eslint-disable-next-line max-len
|
|
8
|
+
'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IktFWSJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0LyIsImF1ZCI6ImZvbyIsInNjb3BlIjoicmVhZDp1c2VycyJ9.VwIIUqx9T-AxqbfL_FyNRAeOxTwiC2JpcwtrqnEWN3DdF07ijUkF1WYy8Ahfr_p4R3KnoPbiefZnIbVANCt-lt0ej32rfil2yHhQEsvFxSOjcrx6ARmPp0YAfWlN-5Sotzkxy29jaOZMEDkmRFZg3jkdC7wosPW_S6M-olC4g3HHfylpZI8O3Jdd87Qr9wD_QtUzANwnPbl2Q-9NEyxVjAZIWg_HWK9JAAaf_2IY5VwHBvyp0oeQSEHKi4hogcM59EOc4FxdR5WH45B_PenVa6W4mHFBkH8sAXxt2Zs9s2efujkfWYfyXvgL_lN7vT-TEADlAPP2L6CpWpDISOMsQWUSgGHcN_KwRh_E7qJwahR6mv4QHY6ReEoyjkmSS3swrD1l74jNs7QLAdsMywvzCMDsHabs7DYcEMGQBdP14PJ_ucLFnkivZeBDAc6sS445ocbyrpyO40XMaMorD5khRd9ej89SxR7d_v0W6Ne2Nn4XgW3pAZzu5Rdc4JvqfzLFxkp95jxy1MTAddjWISPmNOYYyXHM9SSqSpqVECOFS0f4z2zycHRqXUcOytWrvED6VGo9x7-IVCgu8vFzj0zToIWQmsDs3UoH9RnV12z0PMwGXQzca1lT_zGwJxBF3e4zJjmcJ05OMF2JgZ2_G48O3M4Dtb0jlgWbKLd0kWlIFzQ;';
|
|
9
|
+
|
|
10
|
+
const auth0UserId = '1234567890';
|
|
11
|
+
|
|
12
|
+
jest.mock('@verii/vnf-nodejs-wallet-sdk', () => {
|
|
13
|
+
const originalModule = jest.requireActual('@verii/vnf-nodejs-wallet-sdk');
|
|
14
|
+
return {
|
|
15
|
+
...originalModule,
|
|
16
|
+
VCLProvider: {
|
|
17
|
+
getInstance: jest.fn().mockReturnValue({
|
|
18
|
+
initialize: jest.fn().mockResolvedValue(null),
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
describe('Feeds Controller', () => {
|
|
24
|
+
let fastify;
|
|
25
|
+
let persistFeeds;
|
|
26
|
+
|
|
27
|
+
beforeAll(async () => {
|
|
28
|
+
fastify = buildFastify();
|
|
29
|
+
nock('https://localhost/').get('/.well-known/jwks.json').reply(200, jwks);
|
|
30
|
+
await fastify.ready();
|
|
31
|
+
await mongoDb().collection('feeds').deleteMany({});
|
|
32
|
+
({ persistFeeds } = initFeedsFactory(fastify));
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(async () => {
|
|
36
|
+
nock.cleanAll();
|
|
37
|
+
await mongoDb().collection('feeds').deleteMany({});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
afterAll(async () => {
|
|
41
|
+
nock.restore();
|
|
42
|
+
await fastify.close();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('getFeeds', () => {
|
|
46
|
+
it('should return list of feeds on success', async () => {
|
|
47
|
+
await persistFeeds({
|
|
48
|
+
auth0UserId,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const response = await fastify.inject({
|
|
52
|
+
method: 'GET',
|
|
53
|
+
url: '/feeds',
|
|
54
|
+
headers: {
|
|
55
|
+
authorization: `Bearer ${auth0Token}`,
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
expect(response.statusCode).toBe(200);
|
|
60
|
+
expect(response.json()).toHaveLength(1);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe('deleteFeed', () => {
|
|
65
|
+
it('should delete feed when exists', async () => {
|
|
66
|
+
const feed = await persistFeeds({
|
|
67
|
+
auth0UserId,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const response = await fastify.inject({
|
|
71
|
+
method: 'DELETE',
|
|
72
|
+
url: `/feeds/${feed._id}`,
|
|
73
|
+
headers: {
|
|
74
|
+
authorization: `Bearer ${auth0Token}`,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(response.statusCode).toBe(204);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const jwks = {
|
|
84
|
+
keys: [
|
|
85
|
+
{
|
|
86
|
+
alg: 'RS512',
|
|
87
|
+
kid: 'KEY',
|
|
88
|
+
x5c: ['UNUSED'],
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
alg: 'RS256',
|
|
92
|
+
kid: 'KEY',
|
|
93
|
+
x5c: [
|
|
94
|
+
`
|
|
95
|
+
MIIEnjCCAoYCCQDmnGII6qzGlTANBgkqhkiG9w0BAQsFADARMQ8wDQYDVQQDDAZ1
|
|
96
|
+
bnVzZWQwHhcNMjEwOTE5MDcxODQ2WhcNMjExMDE5MDcxODQ2WjARMQ8wDQYDVQQD
|
|
97
|
+
DAZ1bnVzZWQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDY2acJ8JAH
|
|
98
|
+
XjK8j3sAXOokSWwvaEg65UJS0C7KdnfbLTeaeYFHBRY0v9Jkk/PJSXv9hMWw1aD3
|
|
99
|
+
n7NrhVwXeRXi/7VZuW/S4ek+hK+IMDvpKqzn+XeCpaMoRpAgloADeNY0qhYKxpr2
|
|
100
|
+
L0SmRQDwVy1r/g31ECewD2WpEiRSmXsQ2Q2uYT3V60BmbhUw31KGEr4SLXL9pzmb
|
|
101
|
+
arOH/5Rhqg+YFMywNY6i01S3UdOlUtAyWT/mVRAkVTsUEou9tBw61zputPdMrl7p
|
|
102
|
+
d4InmlfCmXNTPFh9EDczPQiAVPq8MDyEdRGP134+HM9+YgQUZjy+WsxmGEvplJIf
|
|
103
|
+
KrYtlWe11//oAXC3690LUYtvg49lNY4+H0/nngjnCDXkZo6f+PEvnBZfYl596VTV
|
|
104
|
+
Fx4FGNOqLwg4bAyE5j5jXtEGW1oKo1pxBg7Oe3MteQUDwMrONB3CbxdxDiN3YH94
|
|
105
|
+
2nWGW9Le+CeA1QUhfjQqSoZRJURGYGoztVuIXOElnkrgwcJreX4b8y+Uo5kpp2By
|
|
106
|
+
6UUaD/mMj9XQ+Ygp/J8DlJlqDXOIp6JUJ75aSK5ZIjRtWq/Go5RUjW9IW0ldEehh
|
|
107
|
+
/4j0ZWC0vR1/le2UmAE6tXhkH4sdx9JM84V+qRzjiGqQx3Wn00uwMiHHhte17t41
|
|
108
|
+
vk+b75wuHbfiq9R8irL6wqWeeuzvCC37NwIDAQABMA0GCSqGSIb3DQEBCwUAA4IC
|
|
109
|
+
AQCZOT6S5HLUp0gBtWK6Fxyzb9lWPE+AJipjJ80lS3OnaOIyVtyJexJ2BjTKWldJ
|
|
110
|
+
48zkzLNIRsTEGEipNS6NkrkElfmoaNBpdbDch2WBkME3UYlFIR9GgbXPMlACQlwJ
|
|
111
|
+
f4qT3iIZ9zjpVMP8F63TzRRr7KEYW2PGHEtVQktMPprGEfU4Sz0OIa9RRV+BLsfh
|
|
112
|
+
x8he2pimJEzoEaWPgyJXV1S+tLUif8A/CEkZVRZ2vADA7WMGl2ZTdbmsTjXh4bf2
|
|
113
|
+
A4l4Zec+jwOjUPiEk5lLJwv1KeYos9wuUczAk7ku8wRzyZbrjwgRam9VQA5qmRzJ
|
|
114
|
+
PegEQwJaKMRu8PPK0L4KFN4v3ma7Ux6D719nko8mZ0kA2oUs6phsFmoWQfsbRbsD
|
|
115
|
+
CdUGnM2fPp6V285r9w9Y6+1nVdtJpbAPFJR3SxIpfYVfx3tI6C3BR9bIMr8uCf81
|
|
116
|
+
G+Ebvo4qTuY6Cg/mTpPLZ4cKpwSvB6cE+xeSHvKIRYm6QUYEReRxQ3b4aUKBSNwl
|
|
117
|
+
FEQufVGhGzeblNC3fjP+mMtqbyC8c1zkHc6tjJYO5yesKf8bjO71by2jgSced7nN
|
|
118
|
+
5JvJawfEcabgHJ1aAFLj0tlPMrViFzu6y8/A5aZLc5UMISXAZXfB4wIEdyUUXJh4
|
|
119
|
+
rJKE/ZCb2+W8g29N5cv2P6nhahT3mYatMiQ0U/gfaIrA0A==
|
|
120
|
+
`.trim(),
|
|
121
|
+
],
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
@@ -310,6 +310,7 @@ describe('Test Deep Link issuing controller', () => {
|
|
|
310
310
|
expect({
|
|
311
311
|
...omit(['_id'], savedCredential),
|
|
312
312
|
id: savedCredential._id.toHexString(),
|
|
313
|
+
feed: false,
|
|
313
314
|
updatedAt: savedCredential.updatedAt.toISOString(),
|
|
314
315
|
createdAt: savedCredential.createdAt.toISOString(),
|
|
315
316
|
}).toEqual(mockParsedResponse.passedCredentials[0]);
|