@friggframework/core 2.0.0--canary.405.1f6792c.0 → 2.0.0--canary.396.6862738.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/credential/credential-repository.js +9 -0
- package/credential/use-cases/get-credential-for-user.js +21 -0
- package/encrypt/encrypt.js +27 -4
- package/handlers/app-definition-loader.js +38 -0
- package/handlers/app-handler-helpers.js +0 -3
- package/handlers/backend-utils.js +29 -34
- package/handlers/routers/auth.js +14 -11
- package/handlers/routers/integration-defined-routers.js +8 -5
- package/handlers/routers/user.js +25 -5
- package/handlers/workers/integration-defined-workers.js +6 -3
- package/index.js +0 -11
- package/integrations/index.js +0 -5
- package/integrations/integration-base.js +10 -7
- package/integrations/integration-repository.js +44 -0
- package/integrations/integration-router.js +230 -132
- package/integrations/integration.js +233 -0
- package/integrations/options.js +1 -1
- package/integrations/use-cases/create-integration.js +58 -0
- package/integrations/use-cases/delete-integration-for-user.js +53 -0
- package/integrations/use-cases/get-integration-for-user.js +63 -0
- package/integrations/use-cases/get-integration-instance.js +73 -0
- package/integrations/use-cases/get-integrations-for-user.js +64 -0
- package/integrations/use-cases/index.js +11 -0
- package/integrations/use-cases/update-integration.js +81 -0
- package/integrations/utils/map-integration-dto.js +37 -0
- package/module-plugin/index.js +0 -4
- package/module-plugin/module-factory.js +13 -32
- package/module-plugin/module-repository.js +70 -0
- package/module-plugin/module-service.js +50 -0
- package/module-plugin/{auther.js → module.js} +109 -173
- package/module-plugin/test/mock-api/api.js +8 -3
- package/module-plugin/test/mock-api/definition.js +12 -8
- package/module-plugin/use-cases/get-entities-for-user.js +32 -0
- package/module-plugin/utils/map-module-dto.js +18 -0
- package/package.json +5 -5
- package/types/integrations/index.d.ts +2 -6
- package/types/module-plugin/index.d.ts +4 -21
- package/user/tests/doubles/test-user-repository.js +72 -0
- package/user/tests/use-cases/create-individual-user.test.js +24 -0
- package/user/tests/use-cases/create-organization-user.test.js +28 -0
- package/user/tests/use-cases/create-token-for-user-id.test.js +19 -0
- package/user/tests/use-cases/get-user-from-bearer-token.test.js +64 -0
- package/user/tests/use-cases/login-user.test.js +140 -0
- package/user/use-cases/create-individual-user.js +61 -0
- package/user/use-cases/create-organization-user.js +47 -0
- package/user/use-cases/create-token-for-user-id.js +30 -0
- package/user/use-cases/get-user-from-bearer-token.js +77 -0
- package/user/use-cases/login-user.js +122 -0
- package/user/user-repository.js +62 -0
- package/user/user.js +77 -0
- package/handlers/routers/HEALTHCHECK.md +0 -240
- package/handlers/routers/health.js +0 -459
- package/handlers/routers/health.test.js +0 -203
- package/handlers/routers/middleware/loadUser.js +0 -15
- package/handlers/routers/middleware/requireLoggedInUser.js +0 -12
- package/integrations/create-frigg-backend.js +0 -31
- package/integrations/integration-factory.js +0 -251
- package/integrations/integration-user.js +0 -144
- package/module-plugin/entity-manager.js +0 -70
|
@@ -2,23 +2,89 @@ const express = require('express');
|
|
|
2
2
|
const { get } = require('../assertions');
|
|
3
3
|
const Boom = require('@hapi/boom');
|
|
4
4
|
const catchAsyncError = require('express-async-handler');
|
|
5
|
-
const {
|
|
5
|
+
const { IntegrationRepository } = require('./integration-repository');
|
|
6
|
+
const { DeleteIntegrationForUser } = require('./use-cases/delete-integration-for-user');
|
|
7
|
+
const { GetIntegrationsForUser } = require('./use-cases/get-integrations-for-user');
|
|
8
|
+
const { CredentialRepository } = require('../credential/credential-repository');
|
|
9
|
+
const { GetCredentialForUser } = require('../credential/use-cases/get-credential-for-user');
|
|
10
|
+
const { CreateIntegration } = require('./use-cases/create-integration');
|
|
11
|
+
const { ModuleService } = require('../module-plugin/module-service');
|
|
12
|
+
const { ModuleRepository } = require('../module-plugin/module-repository');
|
|
13
|
+
const { GetEntitiesForUser } = require('../module-plugin/use-cases/get-entities-for-user');
|
|
14
|
+
const { loadAppDefinition } = require('../handlers/app-definition-loader');
|
|
15
|
+
const { GetIntegrationInstance } = require('./use-cases/get-integration-instance');
|
|
16
|
+
const { UpdateIntegration } = require('./use-cases/update-integration');
|
|
17
|
+
const { getModulesDefinitionFromIntegrationClasses } = require('./utils/map-integration-dto');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates an Express router with integration and entity routes configured
|
|
21
|
+
* @param {Object} params - Configuration parameters for the router
|
|
22
|
+
* @param {express.Router} [params.router] - Optional Express router instance, creates new one if not provided
|
|
23
|
+
* @param {import('../user/use-cases/get-user-from-bearer-token').GetUserFromBearerToken} params.getUserFromBearerToken - Use case for retrieving a user from a bearer token
|
|
24
|
+
* @returns {express.Router} Configured Express router with integration and entity routes
|
|
25
|
+
*/
|
|
6
26
|
function createIntegrationRouter(params) {
|
|
27
|
+
const { integrations: integrationClasses } = loadAppDefinition();
|
|
28
|
+
const moduleRepository = new ModuleRepository();
|
|
29
|
+
const integrationRepository = new IntegrationRepository();
|
|
30
|
+
const credentialRepository = new CredentialRepository();
|
|
31
|
+
|
|
32
|
+
const moduleService = new ModuleService({
|
|
33
|
+
moduleRepository,
|
|
34
|
+
moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
35
|
+
});
|
|
36
|
+
const deleteIntegrationForUser = new DeleteIntegrationForUser({
|
|
37
|
+
integrationRepository,
|
|
38
|
+
integrationClasses,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const getIntegrationsForUser = new GetIntegrationsForUser({
|
|
42
|
+
integrationRepository,
|
|
43
|
+
integrationClasses,
|
|
44
|
+
moduleService,
|
|
45
|
+
moduleRepository,
|
|
46
|
+
});
|
|
47
|
+
const getCredentialForUser = new GetCredentialForUser({
|
|
48
|
+
credentialRepository,
|
|
49
|
+
});
|
|
50
|
+
const createIntegration = new CreateIntegration({
|
|
51
|
+
integrationRepository,
|
|
52
|
+
integrationClasses,
|
|
53
|
+
moduleService,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const getEntitiesForUser = new GetEntitiesForUser({
|
|
57
|
+
moduleRepository,
|
|
58
|
+
moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const getIntegrationInstance = new GetIntegrationInstance({
|
|
62
|
+
integrationRepository,
|
|
63
|
+
integrationClasses,
|
|
64
|
+
moduleService,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const updateIntegration = new UpdateIntegration({
|
|
68
|
+
integrationRepository,
|
|
69
|
+
integrationClasses,
|
|
70
|
+
moduleService,
|
|
71
|
+
});
|
|
72
|
+
|
|
7
73
|
const router = get(params, 'router', express());
|
|
8
74
|
const factory = get(params, 'factory');
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
75
|
+
const getUserFromBearerToken = get(params, 'getUserFromBearerToken');
|
|
76
|
+
|
|
77
|
+
setIntegrationRoutes(router, getUserFromBearerToken, {
|
|
78
|
+
createIntegration,
|
|
79
|
+
deleteIntegrationForUser,
|
|
80
|
+
getIntegrationsForUser,
|
|
81
|
+
getEntitiesForUser,
|
|
82
|
+
getIntegrationInstance,
|
|
83
|
+
updateIntegration,
|
|
84
|
+
});
|
|
85
|
+
setEntityRoutes(router, factory, getUserFromBearerToken, {
|
|
86
|
+
getCredentialForUser,
|
|
87
|
+
});
|
|
22
88
|
return router;
|
|
23
89
|
}
|
|
24
90
|
|
|
@@ -36,121 +102,104 @@ function checkRequiredParams(params, requiredKeys) {
|
|
|
36
102
|
|
|
37
103
|
if (missingKeys.length > 0) {
|
|
38
104
|
throw Boom.badRequest(
|
|
39
|
-
`Missing Parameter${
|
|
40
|
-
|
|
41
|
-
}: ${missingKeys.join(', ')} ${
|
|
42
|
-
missingKeys.length === 1 ? 'is' : 'are'
|
|
105
|
+
`Missing Parameter${missingKeys.length === 1 ? '' : 's'
|
|
106
|
+
}: ${missingKeys.join(', ')} ${missingKeys.length === 1 ? 'is' : 'are'
|
|
43
107
|
} required.`
|
|
44
108
|
);
|
|
45
109
|
}
|
|
46
110
|
return returnDict;
|
|
47
111
|
}
|
|
48
112
|
|
|
49
|
-
|
|
50
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Sets up integration-related routes on the provided Express router
|
|
115
|
+
* @param {express.Router} router - Express router instance to add routes to
|
|
116
|
+
* @param {import('../user/use-cases/get-user-from-bearer-token').GetUserFromBearerToken} getUserFromBearerToken - Use case for retrieving a user from a bearer token
|
|
117
|
+
* @param {Object} useCases - use cases for integration management
|
|
118
|
+
*/
|
|
119
|
+
function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
120
|
+
const {
|
|
121
|
+
createIntegration,
|
|
122
|
+
deleteIntegrationForUser,
|
|
123
|
+
getIntegrationsForUser,
|
|
124
|
+
getEntitiesForUser,
|
|
125
|
+
getIntegrationInstance,
|
|
126
|
+
updateIntegration,
|
|
127
|
+
} = useCases;
|
|
51
128
|
router.route('/api/integrations').get(
|
|
52
129
|
catchAsyncError(async (req, res) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
await
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
});
|
|
67
|
-
integrationRecord.userActions = integration.userActions;
|
|
130
|
+
const user = await getUserFromBearerToken.execute(
|
|
131
|
+
req.headers.authorization
|
|
132
|
+
);
|
|
133
|
+
const userId = user.getId();
|
|
134
|
+
const integrations = await getIntegrationsForUser.execute(userId);
|
|
135
|
+
const results = {
|
|
136
|
+
entities: {
|
|
137
|
+
options: integrations.map((integration) =>
|
|
138
|
+
integration.options
|
|
139
|
+
),
|
|
140
|
+
authorized: await getEntitiesForUser.execute(userId),
|
|
141
|
+
},
|
|
142
|
+
integrations: integrations,
|
|
68
143
|
}
|
|
144
|
+
|
|
69
145
|
res.json(results);
|
|
70
146
|
})
|
|
71
147
|
);
|
|
72
148
|
|
|
73
149
|
router.route('/api/integrations').post(
|
|
74
150
|
catchAsyncError(async (req, res) => {
|
|
151
|
+
const user = await getUserFromBearerToken.execute(
|
|
152
|
+
req.headers.authorization
|
|
153
|
+
);
|
|
154
|
+
const userId = user.getId();
|
|
75
155
|
const params = checkRequiredParams(req.body, [
|
|
76
156
|
'entities',
|
|
77
157
|
'config',
|
|
78
158
|
]);
|
|
79
|
-
|
|
159
|
+
|
|
80
160
|
get(params.config, 'type');
|
|
81
161
|
|
|
82
|
-
|
|
83
|
-
const integration = await integrationFactory.createIntegration(
|
|
162
|
+
const integration = await createIntegration.execute(
|
|
84
163
|
params.entities,
|
|
85
|
-
|
|
164
|
+
userId,
|
|
86
165
|
params.config
|
|
87
166
|
);
|
|
88
167
|
|
|
89
|
-
|
|
90
|
-
debug(
|
|
91
|
-
`Calling onCreate on the ${integration?.constructor?.Config?.name} Integration with no arguments`
|
|
92
|
-
);
|
|
93
|
-
await integration.send('ON_CREATE', {});
|
|
94
|
-
|
|
95
|
-
res.status(201).json(
|
|
96
|
-
await IntegrationHelper.getFormattedIntegration(
|
|
97
|
-
integration.record
|
|
98
|
-
)
|
|
99
|
-
);
|
|
168
|
+
res.status(201).json(integration);
|
|
100
169
|
})
|
|
101
170
|
);
|
|
102
171
|
|
|
103
172
|
router.route('/api/integrations/:integrationId').patch(
|
|
104
173
|
catchAsyncError(async (req, res) => {
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
const integration =
|
|
108
|
-
await integrationFactory.getInstanceFromIntegrationId({
|
|
109
|
-
integrationId: req.params.integrationId,
|
|
110
|
-
userId: getUserId(req),
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
debug(
|
|
114
|
-
`Calling onUpdate on the ${integration?.constructor?.Config?.name} Integration arguments: `,
|
|
115
|
-
params
|
|
174
|
+
const user = await getUserFromBearerToken.execute(
|
|
175
|
+
req.headers.authorization
|
|
116
176
|
);
|
|
117
|
-
|
|
177
|
+
const userId = user.getId();
|
|
178
|
+
const params = checkRequiredParams(req.body, ['config']);
|
|
118
179
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
integration.record
|
|
122
|
-
)
|
|
123
|
-
);
|
|
180
|
+
const integration = await updateIntegration.execute(req.params.integrationId, userId, params.config);
|
|
181
|
+
res.json(integration);
|
|
124
182
|
})
|
|
125
183
|
);
|
|
126
184
|
|
|
127
185
|
router.route('/api/integrations/:integrationId').delete(
|
|
128
186
|
catchAsyncError(async (req, res) => {
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
await integrationFactory.getInstanceFromIntegrationId({
|
|
132
|
-
userId: getUserId(req),
|
|
133
|
-
integrationId: params.integrationId,
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
debug(
|
|
137
|
-
`Calling onUpdate on the ${integration?.constructor?.Definition?.name} Integration with no arguments`
|
|
138
|
-
);
|
|
139
|
-
await integration.send('ON_DELETE');
|
|
140
|
-
await IntegrationHelper.deleteIntegrationForUserById(
|
|
141
|
-
getUserId(req),
|
|
142
|
-
params.integrationId
|
|
187
|
+
const user = await getUserFromBearerToken.execute(
|
|
188
|
+
req.headers.authorization
|
|
143
189
|
);
|
|
144
|
-
|
|
145
|
-
|
|
190
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
191
|
+
await deleteIntegrationForUser.execute(params.integrationId, user.getId());
|
|
192
|
+
res.status(204).json({});
|
|
146
193
|
})
|
|
147
194
|
);
|
|
148
195
|
|
|
149
196
|
router.route('/api/integrations/:integrationId/config/options').get(
|
|
150
197
|
catchAsyncError(async (req, res) => {
|
|
198
|
+
const user = await getUserFromBearerToken.execute(
|
|
199
|
+
req.headers.authorization
|
|
200
|
+
);
|
|
151
201
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
152
|
-
const integration =
|
|
153
|
-
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
202
|
+
const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
154
203
|
res.json(await integration.send('GET_CONFIG_OPTIONS'));
|
|
155
204
|
})
|
|
156
205
|
);
|
|
@@ -159,13 +208,13 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
159
208
|
.route('/api/integrations/:integrationId/config/options/refresh')
|
|
160
209
|
.post(
|
|
161
210
|
catchAsyncError(async (req, res) => {
|
|
211
|
+
const user = await getUserFromBearerToken.execute(
|
|
212
|
+
req.headers.authorization
|
|
213
|
+
);
|
|
162
214
|
const params = checkRequiredParams(req.params, [
|
|
163
215
|
'integrationId',
|
|
164
216
|
]);
|
|
165
|
-
const integration =
|
|
166
|
-
await integrationFactory.getInstanceFromIntegrationId(
|
|
167
|
-
params
|
|
168
|
-
);
|
|
217
|
+
const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
169
218
|
|
|
170
219
|
res.json(
|
|
171
220
|
await integration.send('REFRESH_CONFIG_OPTIONS', req.body)
|
|
@@ -174,9 +223,11 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
174
223
|
);
|
|
175
224
|
router.route('/api/integrations/:integrationId/actions').all(
|
|
176
225
|
catchAsyncError(async (req, res) => {
|
|
226
|
+
const user = await getUserFromBearerToken.execute(
|
|
227
|
+
req.headers.authorization
|
|
228
|
+
);
|
|
177
229
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
178
|
-
const integration =
|
|
179
|
-
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
230
|
+
const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
180
231
|
res.json(await integration.send('GET_USER_ACTIONS', req.body));
|
|
181
232
|
})
|
|
182
233
|
);
|
|
@@ -185,14 +236,14 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
185
236
|
.route('/api/integrations/:integrationId/actions/:actionId/options')
|
|
186
237
|
.all(
|
|
187
238
|
catchAsyncError(async (req, res) => {
|
|
239
|
+
const user = await getUserFromBearerToken.execute(
|
|
240
|
+
req.headers.authorization
|
|
241
|
+
);
|
|
188
242
|
const params = checkRequiredParams(req.params, [
|
|
189
243
|
'integrationId',
|
|
190
244
|
'actionId',
|
|
191
245
|
]);
|
|
192
|
-
const integration =
|
|
193
|
-
await integrationFactory.getInstanceFromIntegrationId(
|
|
194
|
-
params
|
|
195
|
-
);
|
|
246
|
+
const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
196
247
|
|
|
197
248
|
res.json(
|
|
198
249
|
await integration.send('GET_USER_ACTION_OPTIONS', {
|
|
@@ -209,14 +260,14 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
209
260
|
)
|
|
210
261
|
.post(
|
|
211
262
|
catchAsyncError(async (req, res) => {
|
|
263
|
+
const user = await getUserFromBearerToken.execute(
|
|
264
|
+
req.headers.authorization
|
|
265
|
+
);
|
|
212
266
|
const params = checkRequiredParams(req.params, [
|
|
213
267
|
'integrationId',
|
|
214
268
|
'actionId',
|
|
215
269
|
]);
|
|
216
|
-
const integration =
|
|
217
|
-
await integrationFactory.getInstanceFromIntegrationId(
|
|
218
|
-
params
|
|
219
|
-
);
|
|
270
|
+
const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
220
271
|
|
|
221
272
|
res.json(
|
|
222
273
|
await integration.send('REFRESH_USER_ACTION_OPTIONS', {
|
|
@@ -229,23 +280,31 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
229
280
|
|
|
230
281
|
router.route('/api/integrations/:integrationId/actions/:actionId').post(
|
|
231
282
|
catchAsyncError(async (req, res) => {
|
|
283
|
+
const user = await getUserFromBearerToken.execute(
|
|
284
|
+
req.headers.authorization
|
|
285
|
+
);
|
|
232
286
|
const params = checkRequiredParams(req.params, [
|
|
233
287
|
'integrationId',
|
|
234
288
|
'actionId',
|
|
235
289
|
]);
|
|
236
|
-
const integration =
|
|
237
|
-
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
238
|
-
|
|
290
|
+
const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
239
291
|
res.json(await integration.send(params.actionId, req.body));
|
|
240
292
|
})
|
|
241
293
|
);
|
|
242
294
|
|
|
243
295
|
router.route('/api/integrations/:integrationId').get(
|
|
244
296
|
catchAsyncError(async (req, res) => {
|
|
245
|
-
const
|
|
246
|
-
|
|
247
|
-
params.integrationId
|
|
297
|
+
const user = await getUserFromBearerToken.execute(
|
|
298
|
+
req.headers.authorization
|
|
248
299
|
);
|
|
300
|
+
|
|
301
|
+
if (!user) {
|
|
302
|
+
throw Boom.forbidden('User not found');
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
306
|
+
const integration = await getIntegrationForUser.execute(params.integrationId, user.getId());
|
|
307
|
+
|
|
249
308
|
// We could perhaps augment router with dynamic options? Haven't decided yet, but here may be the place
|
|
250
309
|
|
|
251
310
|
res.json({
|
|
@@ -259,12 +318,11 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
259
318
|
|
|
260
319
|
router.route('/api/integrations/:integrationId/test-auth').get(
|
|
261
320
|
catchAsyncError(async (req, res) => {
|
|
321
|
+
const user = await getUserFromBearerToken.execute(
|
|
322
|
+
req.headers.authorization
|
|
323
|
+
);
|
|
262
324
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
263
|
-
const instance =
|
|
264
|
-
await integrationFactory.getInstanceFromIntegrationId({
|
|
265
|
-
userId: getUserId(req),
|
|
266
|
-
integrationId: params.integrationId,
|
|
267
|
-
});
|
|
325
|
+
const instance = await getIntegrationInstance.execute(params.integrationId, user.getId());
|
|
268
326
|
|
|
269
327
|
if (!instance) {
|
|
270
328
|
throw Boom.notFound();
|
|
@@ -286,9 +344,17 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
286
344
|
);
|
|
287
345
|
}
|
|
288
346
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Sets up entity-related routes for the integration router
|
|
350
|
+
* @param {Object} router - Express router instance
|
|
351
|
+
* @param {Object} factory - Factory object containing moduleFactory
|
|
352
|
+
* @param {import('../user/use-cases/get-user-from-bearer-token').GetUserFromBearerToken} getUserFromBearerToken - Use case for retrieving a user from a bearer token
|
|
353
|
+
*/
|
|
354
|
+
function setEntityRoutes(router, factory, getUserFromBearerToken, useCases) {
|
|
355
|
+
const { moduleFactory } = factory;
|
|
356
|
+
const { getCredentialForUser } = useCases;
|
|
357
|
+
const getModuleInstance = async (userId, entityType) => {
|
|
292
358
|
if (!moduleFactory.checkIsValidType(entityType)) {
|
|
293
359
|
throw Boom.badRequest(
|
|
294
360
|
`Error: Invalid entity type of ${entityType}, options are ${moduleFactory.moduleTypes.join(
|
|
@@ -298,19 +364,23 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
298
364
|
}
|
|
299
365
|
return await moduleFactory.getInstanceFromTypeName(
|
|
300
366
|
entityType,
|
|
301
|
-
|
|
367
|
+
userId
|
|
302
368
|
);
|
|
303
369
|
};
|
|
304
370
|
|
|
305
371
|
router.route('/api/authorize').get(
|
|
306
372
|
catchAsyncError(async (req, res) => {
|
|
373
|
+
const user = await getUserFromBearerToken.execute(
|
|
374
|
+
req.headers.authorization
|
|
375
|
+
);
|
|
376
|
+
const userId = user.getId();
|
|
307
377
|
const params = checkRequiredParams(req.query, ['entityType']);
|
|
308
|
-
const module = await getModuleInstance(
|
|
378
|
+
const module = await getModuleInstance(userId, params.entityType);
|
|
309
379
|
const areRequirementsValid =
|
|
310
380
|
module.validateAuthorizationRequirements();
|
|
311
381
|
if (!areRequirementsValid) {
|
|
312
382
|
throw new Error(
|
|
313
|
-
`Error:
|
|
383
|
+
`Error: Entity of type ${params.entityType} requires a valid url`
|
|
314
384
|
);
|
|
315
385
|
}
|
|
316
386
|
|
|
@@ -320,15 +390,19 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
320
390
|
|
|
321
391
|
router.route('/api/authorize').post(
|
|
322
392
|
catchAsyncError(async (req, res) => {
|
|
393
|
+
const user = await getUserFromBearerToken.execute(
|
|
394
|
+
req.headers.authorization
|
|
395
|
+
);
|
|
396
|
+
const userId = user.getId();
|
|
323
397
|
const params = checkRequiredParams(req.body, [
|
|
324
398
|
'entityType',
|
|
325
399
|
'data',
|
|
326
400
|
]);
|
|
327
|
-
const module = await getModuleInstance(
|
|
401
|
+
const module = await getModuleInstance(userId, params.entityType);
|
|
328
402
|
|
|
329
403
|
res.json(
|
|
330
404
|
await module.processAuthorizationCallback({
|
|
331
|
-
userId
|
|
405
|
+
userId,
|
|
332
406
|
data: params.data,
|
|
333
407
|
})
|
|
334
408
|
);
|
|
@@ -337,6 +411,10 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
337
411
|
|
|
338
412
|
router.route('/api/entity').post(
|
|
339
413
|
catchAsyncError(async (req, res) => {
|
|
414
|
+
const user = await getUserFromBearerToken.execute(
|
|
415
|
+
req.headers.authorization
|
|
416
|
+
);
|
|
417
|
+
const userId = user.getId();
|
|
340
418
|
const params = checkRequiredParams(req.body, [
|
|
341
419
|
'entityType',
|
|
342
420
|
'data',
|
|
@@ -344,20 +422,21 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
344
422
|
checkRequiredParams(req.body.data, ['credential_id']);
|
|
345
423
|
|
|
346
424
|
// May want to pass along the user ID as well so credential ID's can't be fished???
|
|
347
|
-
const credential = await
|
|
348
|
-
params.data.credential_id
|
|
425
|
+
const credential = await getCredentialForUser.execute(
|
|
426
|
+
params.data.credential_id,
|
|
427
|
+
userId
|
|
349
428
|
);
|
|
350
429
|
|
|
351
430
|
if (!credential) {
|
|
352
431
|
throw Boom.badRequest('Invalid credential ID');
|
|
353
432
|
}
|
|
354
433
|
|
|
355
|
-
const module = await getModuleInstance(
|
|
434
|
+
const module = await getModuleInstance(userId, params.entityType);
|
|
356
435
|
const entityDetails = await module.getEntityDetails(
|
|
357
436
|
module.api,
|
|
358
437
|
null,
|
|
359
438
|
null,
|
|
360
|
-
|
|
439
|
+
userId
|
|
361
440
|
);
|
|
362
441
|
|
|
363
442
|
res.json(await module.findOrCreateEntity(entityDetails));
|
|
@@ -366,17 +445,22 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
366
445
|
|
|
367
446
|
router.route('/api/entity/options/:credentialId').get(
|
|
368
447
|
catchAsyncError(async (req, res) => {
|
|
448
|
+
const user = await getUserFromBearerToken.execute(
|
|
449
|
+
req.headers.authorization
|
|
450
|
+
);
|
|
451
|
+
const userId = user.getId();
|
|
369
452
|
// TODO May want to pass along the user ID as well so credential ID's can't be fished???
|
|
370
453
|
// TODO **flagging this for review** -MW
|
|
371
|
-
const credential = await
|
|
372
|
-
req.params.credentialId
|
|
454
|
+
const credential = await getCredentialForUser.execute(
|
|
455
|
+
req.params.credentialId,
|
|
456
|
+
userId
|
|
373
457
|
);
|
|
374
|
-
if (credential.user._id.toString() !==
|
|
458
|
+
if (credential.user._id.toString() !== userId) {
|
|
375
459
|
throw Boom.forbidden('Credential does not belong to user');
|
|
376
460
|
}
|
|
377
461
|
|
|
378
462
|
const params = checkRequiredParams(req.query, ['entityType']);
|
|
379
|
-
const module = await getModuleInstance(
|
|
463
|
+
const module = await getModuleInstance(userId, params.entityType);
|
|
380
464
|
|
|
381
465
|
res.json(await module.getEntityOptions());
|
|
382
466
|
})
|
|
@@ -384,10 +468,14 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
384
468
|
|
|
385
469
|
router.route('/api/entities/:entityId/test-auth').get(
|
|
386
470
|
catchAsyncError(async (req, res) => {
|
|
471
|
+
const user = await getUserFromBearerToken.execute(
|
|
472
|
+
req.headers.authorization
|
|
473
|
+
);
|
|
474
|
+
const userId = user.getId();
|
|
387
475
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
388
476
|
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
389
477
|
params.entityId,
|
|
390
|
-
|
|
478
|
+
userId
|
|
391
479
|
);
|
|
392
480
|
|
|
393
481
|
if (!module) {
|
|
@@ -415,10 +503,14 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
415
503
|
|
|
416
504
|
router.route('/api/entities/:entityId').get(
|
|
417
505
|
catchAsyncError(async (req, res) => {
|
|
506
|
+
const user = await getUserFromBearerToken.execute(
|
|
507
|
+
req.headers.authorization
|
|
508
|
+
);
|
|
509
|
+
const userId = user.getId();
|
|
418
510
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
419
511
|
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
420
512
|
params.entityId,
|
|
421
|
-
|
|
513
|
+
userId
|
|
422
514
|
);
|
|
423
515
|
|
|
424
516
|
if (!module) {
|
|
@@ -431,13 +523,16 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
431
523
|
|
|
432
524
|
router.route('/api/entities/:entityId/options').post(
|
|
433
525
|
catchAsyncError(async (req, res) => {
|
|
526
|
+
const user = await getUserFromBearerToken.execute(
|
|
527
|
+
req.headers.authorization
|
|
528
|
+
);
|
|
529
|
+
const userId = user.getId();
|
|
434
530
|
const params = checkRequiredParams(req.params, [
|
|
435
531
|
'entityId',
|
|
436
|
-
getUserId(req),
|
|
437
532
|
]);
|
|
438
533
|
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
439
534
|
params.entityId,
|
|
440
|
-
|
|
535
|
+
userId
|
|
441
536
|
);
|
|
442
537
|
|
|
443
538
|
if (!module) {
|
|
@@ -450,13 +545,16 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
450
545
|
|
|
451
546
|
router.route('/api/entities/:entityId/options/refresh').post(
|
|
452
547
|
catchAsyncError(async (req, res) => {
|
|
548
|
+
const user = await getUserFromBearerToken.execute(
|
|
549
|
+
req.headers.authorization
|
|
550
|
+
);
|
|
551
|
+
const userId = user.getId();
|
|
453
552
|
const params = checkRequiredParams(req.params, [
|
|
454
553
|
'entityId',
|
|
455
|
-
getUserId(req),
|
|
456
554
|
]);
|
|
457
555
|
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
458
556
|
params.entityId,
|
|
459
|
-
|
|
557
|
+
userId
|
|
460
558
|
);
|
|
461
559
|
|
|
462
560
|
if (!module) {
|