@friggframework/core 2.0.0--canary.397.155fecd.0 → 2.0.0--canary.398.c9e5d61.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.
Files changed (94) hide show
  1. package/README.md +50 -933
  2. package/core/create-handler.js +0 -1
  3. package/database/models/WebsocketConnection.js +5 -0
  4. package/handlers/app-handler-helpers.js +3 -0
  5. package/handlers/backend-utils.js +34 -35
  6. package/handlers/routers/auth.js +14 -3
  7. package/handlers/routers/integration-defined-routers.js +5 -8
  8. package/handlers/routers/middleware/loadUser.js +15 -0
  9. package/handlers/routers/middleware/requireLoggedInUser.js +12 -0
  10. package/handlers/routers/user.js +5 -25
  11. package/handlers/workers/integration-defined-workers.js +3 -6
  12. package/index.js +14 -1
  13. package/integrations/create-frigg-backend.js +31 -0
  14. package/integrations/index.js +5 -0
  15. package/integrations/integration-base.js +44 -42
  16. package/integrations/integration-factory.js +251 -0
  17. package/integrations/integration-router.js +173 -291
  18. package/integrations/integration-user.js +144 -0
  19. package/integrations/options.js +1 -1
  20. package/integrations/test/integration-base.test.js +144 -0
  21. package/module-plugin/auther.js +393 -0
  22. package/module-plugin/entity-manager.js +70 -0
  23. package/{modules → module-plugin}/index.js +6 -0
  24. package/module-plugin/module-factory.js +61 -0
  25. package/{modules → module-plugin}/test/mock-api/api.js +3 -8
  26. package/{modules → module-plugin}/test/mock-api/definition.js +8 -12
  27. package/package.json +5 -5
  28. package/types/integrations/index.d.ts +6 -2
  29. package/types/module-plugin/index.d.ts +21 -4
  30. package/credential/credential-repository.js +0 -42
  31. package/credential/use-cases/get-credential-for-user.js +0 -21
  32. package/credential/use-cases/update-authentication-status.js +0 -15
  33. package/handlers/app-definition-loader.js +0 -38
  34. package/integrations/integration-repository.js +0 -67
  35. package/integrations/integration.js +0 -233
  36. package/integrations/tests/doubles/dummy-integration-class.js +0 -90
  37. package/integrations/tests/doubles/test-integration-repository.js +0 -89
  38. package/integrations/tests/use-cases/create-integration.test.js +0 -124
  39. package/integrations/tests/use-cases/delete-integration-for-user.test.js +0 -143
  40. package/integrations/tests/use-cases/get-integration-for-user.test.js +0 -143
  41. package/integrations/tests/use-cases/get-integration-instance.test.js +0 -169
  42. package/integrations/tests/use-cases/get-integrations-for-user.test.js +0 -169
  43. package/integrations/tests/use-cases/get-possible-integrations.test.js +0 -188
  44. package/integrations/tests/use-cases/update-integration-messages.test.js +0 -142
  45. package/integrations/tests/use-cases/update-integration-status.test.js +0 -103
  46. package/integrations/tests/use-cases/update-integration.test.js +0 -134
  47. package/integrations/use-cases/create-integration.js +0 -72
  48. package/integrations/use-cases/delete-integration-for-user.js +0 -73
  49. package/integrations/use-cases/get-integration-for-user.js +0 -79
  50. package/integrations/use-cases/get-integration-instance.js +0 -84
  51. package/integrations/use-cases/get-integrations-for-user.js +0 -77
  52. package/integrations/use-cases/get-possible-integrations.js +0 -27
  53. package/integrations/use-cases/index.js +0 -11
  54. package/integrations/use-cases/update-integration-messages.js +0 -31
  55. package/integrations/use-cases/update-integration-status.js +0 -28
  56. package/integrations/use-cases/update-integration.js +0 -92
  57. package/integrations/utils/map-integration-dto.js +0 -36
  58. package/modules/module-factory.js +0 -54
  59. package/modules/module-repository.js +0 -72
  60. package/modules/module.js +0 -251
  61. package/modules/tests/doubles/test-module-factory.js +0 -16
  62. package/modules/tests/doubles/test-module-repository.js +0 -19
  63. package/modules/use-cases/get-entities-for-user.js +0 -32
  64. package/modules/use-cases/get-entity-options-by-id.js +0 -58
  65. package/modules/use-cases/get-entity-options-by-type.js +0 -34
  66. package/modules/use-cases/get-module-instance-from-type.js +0 -31
  67. package/modules/use-cases/get-module.js +0 -56
  68. package/modules/use-cases/refresh-entity-options.js +0 -58
  69. package/modules/use-cases/test-module-auth.js +0 -54
  70. package/modules/utils/map-module-dto.js +0 -18
  71. package/user/tests/doubles/test-user-repository.js +0 -72
  72. package/user/tests/use-cases/create-individual-user.test.js +0 -24
  73. package/user/tests/use-cases/create-organization-user.test.js +0 -28
  74. package/user/tests/use-cases/create-token-for-user-id.test.js +0 -19
  75. package/user/tests/use-cases/get-user-from-bearer-token.test.js +0 -64
  76. package/user/tests/use-cases/login-user.test.js +0 -140
  77. package/user/use-cases/create-individual-user.js +0 -61
  78. package/user/use-cases/create-organization-user.js +0 -47
  79. package/user/use-cases/create-token-for-user-id.js +0 -30
  80. package/user/use-cases/get-user-from-bearer-token.js +0 -77
  81. package/user/use-cases/login-user.js +0 -122
  82. package/user/user-repository.js +0 -62
  83. package/user/user.js +0 -77
  84. /package/{modules → module-plugin}/ModuleConstants.js +0 -0
  85. /package/{modules → module-plugin}/credential.js +0 -0
  86. /package/{modules → module-plugin}/entity.js +0 -0
  87. /package/{modules → module-plugin}/manager.js +0 -0
  88. /package/{modules → module-plugin}/requester/api-key.js +0 -0
  89. /package/{modules → module-plugin}/requester/basic.js +0 -0
  90. /package/{modules → module-plugin}/requester/oauth-2.js +0 -0
  91. /package/{modules → module-plugin}/requester/requester.js +0 -0
  92. /package/{modules → module-plugin}/requester/requester.test.js +0 -0
  93. /package/{modules → module-plugin}/test/auther.test.js +0 -0
  94. /package/{modules → module-plugin}/test/mock-api/mocks/hubspot.js +0 -0
@@ -2,136 +2,23 @@ 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 { 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 { ModuleFactory } = require('../modules/module-factory');
12
- const { ModuleRepository } = require('../modules/module-repository');
13
- const { GetEntitiesForUser } = require('../modules/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
- const { GetModuleInstanceFromType } = require('../modules/use-cases/get-module-instance-from-type');
19
- const { GetEntityOptionsByType } = require('../modules/use-cases/get-entity-options-by-type');
20
- const { TestModuleAuth } = require('../modules/use-cases/test-module-auth');
21
- const { GetModule } = require('../modules/use-cases/get-module');
22
- const { GetEntityOptionsById } = require('../modules/use-cases/get-entity-options-by-id');
23
- const { RefreshEntityOptions } = require('../modules/use-cases/refresh-entity-options');
24
- const { GetPossibleIntegrations } = require('./use-cases/get-possible-integrations');
25
- const { UserRepository } = require('../user/user-repository');
26
- const { GetUserFromBearerToken } = require('../user/use-cases/get-user-from-bearer-token');
27
-
28
- function createIntegrationRouter() {
29
- const { integrations: integrationClasses, userConfig } = loadAppDefinition();
30
- const moduleRepository = new ModuleRepository();
31
- const integrationRepository = new IntegrationRepository();
32
- const credentialRepository = new CredentialRepository();
33
- const userRepository = new UserRepository({ userConfig });
34
-
35
- const getUserFromBearerToken = new GetUserFromBearerToken({
36
- userRepository,
37
- userConfig,
38
- });
39
-
40
- const moduleFactory = new ModuleFactory({
41
- moduleRepository,
42
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
43
- });
44
- const deleteIntegrationForUser = new DeleteIntegrationForUser({
45
- integrationRepository,
46
- integrationClasses,
47
- });
48
-
49
- const getIntegrationsForUser = new GetIntegrationsForUser({
50
- integrationRepository,
51
- integrationClasses,
52
- moduleFactory,
53
- moduleRepository,
54
- });
55
-
56
- const getCredentialForUser = new GetCredentialForUser({
57
- credentialRepository,
58
- });
59
-
60
- const createIntegration = new CreateIntegration({
61
- integrationRepository,
62
- integrationClasses,
63
- moduleFactory,
64
- });
65
-
66
- const getEntitiesForUser = new GetEntitiesForUser({
67
- moduleRepository,
68
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
69
- });
70
-
71
- const getIntegrationInstance = new GetIntegrationInstance({
72
- integrationRepository,
73
- integrationClasses,
74
- moduleFactory,
75
- });
76
-
77
- const updateIntegration = new UpdateIntegration({
78
- integrationRepository,
79
- integrationClasses,
80
- moduleFactory,
81
- });
82
-
83
- const getModuleInstanceFromType = new GetModuleInstanceFromType({
84
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
85
- });
86
-
87
- const getEntityOptionsByType = new GetEntityOptionsByType({
88
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
89
- });
90
-
91
- const testModuleAuth = new TestModuleAuth({
92
- moduleRepository,
93
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
94
- });
95
-
96
- const getModule = new GetModule({
97
- moduleRepository,
98
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
99
- });
100
-
101
- const getEntityOptionsById = new GetEntityOptionsById({
102
- moduleRepository,
103
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
104
- });
105
-
106
- const refreshEntityOptions = new RefreshEntityOptions({
107
- moduleRepository,
108
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses(integrationClasses),
109
- });
110
-
111
- const getPossibleIntegrations = new GetPossibleIntegrations({
112
- integrationClasses,
113
- });
114
-
115
- const router = express();
116
-
117
- setIntegrationRoutes(router, getUserFromBearerToken, {
118
- createIntegration,
119
- deleteIntegrationForUser,
120
- getIntegrationsForUser,
121
- getEntitiesForUser,
122
- getIntegrationInstance,
123
- updateIntegration,
124
- getPossibleIntegrations,
125
- });
126
- setEntityRoutes(router, getUserFromBearerToken, {
127
- getCredentialForUser,
128
- getModuleInstanceFromType,
129
- getEntityOptionsByType,
130
- testModuleAuth,
131
- getModule,
132
- getEntityOptionsById,
133
- refreshEntityOptions,
134
- });
5
+ const { debug } = require('../logs');
6
+ function createIntegrationRouter(params) {
7
+ const router = get(params, 'router', express());
8
+ const factory = get(params, 'factory');
9
+ const getUserId = get(params, 'getUserId', (req) => null);
10
+ const requireLoggedInUser = get(
11
+ params,
12
+ 'requireLoggedInUser',
13
+ (req, res, next) => next()
14
+ );
15
+
16
+ router.all('/api/entities*', requireLoggedInUser);
17
+ router.all('/api/authorize', requireLoggedInUser);
18
+ router.all('/api/integrations*', requireLoggedInUser);
19
+
20
+ setIntegrationRoutes(router, factory, getUserId);
21
+ setEntityRoutes(router, factory, getUserId);
135
22
  return router;
136
23
  }
137
24
 
@@ -149,103 +36,121 @@ function checkRequiredParams(params, requiredKeys) {
149
36
 
150
37
  if (missingKeys.length > 0) {
151
38
  throw Boom.badRequest(
152
- `Missing Parameter${missingKeys.length === 1 ? '' : 's'
153
- }: ${missingKeys.join(', ')} ${missingKeys.length === 1 ? 'is' : 'are'
39
+ `Missing Parameter${
40
+ missingKeys.length === 1 ? '' : 's'
41
+ }: ${missingKeys.join(', ')} ${
42
+ missingKeys.length === 1 ? 'is' : 'are'
154
43
  } required.`
155
44
  );
156
45
  }
157
46
  return returnDict;
158
47
  }
159
48
 
160
- /**
161
- * Sets up integration-related routes on the provided Express router
162
- * @param {express.Router} router - Express router instance to add routes to
163
- * @param {import('../user/use-cases/get-user-from-bearer-token').GetUserFromBearerToken} getUserFromBearerToken - Use case for retrieving a user from a bearer token
164
- * @param {Object} useCases - use cases for integration management
165
- */
166
- function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
167
- const {
168
- createIntegration,
169
- deleteIntegrationForUser,
170
- getIntegrationsForUser,
171
- getEntitiesForUser,
172
- getIntegrationInstance,
173
- updateIntegration,
174
- getPossibleIntegrations,
175
- } = useCases;
49
+ function setIntegrationRoutes(router, factory, getUserId) {
50
+ const { moduleFactory, integrationFactory, IntegrationHelper } = factory;
176
51
  router.route('/api/integrations').get(
177
52
  catchAsyncError(async (req, res) => {
178
- const user = await getUserFromBearerToken.execute(
179
- req.headers.authorization
180
- );
181
- const userId = user.getId();
182
- const integrations = await getIntegrationsForUser.execute(userId);
183
- const results = {
184
- entities: {
185
- options: await getPossibleIntegrations.execute(),
186
- authorized: await getEntitiesForUser.execute(userId),
187
- },
188
- integrations: integrations,
189
- }
53
+ const results = await integrationFactory.getIntegrationOptions();
54
+ results.entities.authorized =
55
+ await moduleFactory.getEntitiesForUser(getUserId(req));
56
+ results.integrations =
57
+ await IntegrationHelper.getIntegrationsForUserId(
58
+ getUserId(req)
59
+ );
190
60
 
61
+ for (const integrationRecord of results.integrations) {
62
+ const integration =
63
+ await integrationFactory.getInstanceFromIntegrationId({
64
+ integrationId: integrationRecord.id,
65
+ userId: getUserId(req),
66
+ });
67
+ integrationRecord.userActions = integration.userActions;
68
+ }
191
69
  res.json(results);
192
70
  })
193
71
  );
194
72
 
195
73
  router.route('/api/integrations').post(
196
74
  catchAsyncError(async (req, res) => {
197
- const user = await getUserFromBearerToken.execute(
198
- req.headers.authorization
199
- );
200
- const userId = user.getId();
201
75
  const params = checkRequiredParams(req.body, [
202
76
  'entities',
203
77
  'config',
204
78
  ]);
205
-
79
+ // throw if not value
206
80
  get(params.config, 'type');
207
81
 
208
- const integration = await createIntegration.execute(
82
+ // create integration
83
+ const integration = await integrationFactory.createIntegration(
209
84
  params.entities,
210
- userId,
85
+ getUserId(req),
211
86
  params.config
212
87
  );
213
88
 
214
- res.status(201).json(integration);
89
+ // post integration initialization
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
+ );
215
100
  })
216
101
  );
217
102
 
218
103
  router.route('/api/integrations/:integrationId').patch(
219
104
  catchAsyncError(async (req, res) => {
220
- const user = await getUserFromBearerToken.execute(
221
- req.headers.authorization
222
- );
223
- const userId = user.getId();
224
105
  const params = checkRequiredParams(req.body, ['config']);
225
106
 
226
- const integration = await updateIntegration.execute(req.params.integrationId, userId, params.config);
227
- res.json(integration);
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
116
+ );
117
+ await integration.send('ON_UPDATE', params);
118
+
119
+ res.json(
120
+ await IntegrationHelper.getFormattedIntegration(
121
+ integration.record
122
+ )
123
+ );
228
124
  })
229
125
  );
230
126
 
231
127
  router.route('/api/integrations/:integrationId').delete(
232
128
  catchAsyncError(async (req, res) => {
233
- const user = await getUserFromBearerToken.execute(
234
- req.headers.authorization
235
- );
236
129
  const params = checkRequiredParams(req.params, ['integrationId']);
237
- await deleteIntegrationForUser.execute(params.integrationId, user.getId());
238
- res.status(204).json({});
130
+ const integration =
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
143
+ );
144
+
145
+ res.status(201).json({});
239
146
  })
240
147
  );
241
148
 
242
149
  router.route('/api/integrations/:integrationId/config/options').get(
243
150
  catchAsyncError(async (req, res) => {
244
- const user = await getUserFromBearerToken.execute(
245
- req.headers.authorization
246
- );
247
151
  const params = checkRequiredParams(req.params, ['integrationId']);
248
- const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
152
+ const integration =
153
+ await integrationFactory.getInstanceFromIntegrationId(params);
249
154
  res.json(await integration.send('GET_CONFIG_OPTIONS'));
250
155
  })
251
156
  );
@@ -254,13 +159,13 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
254
159
  .route('/api/integrations/:integrationId/config/options/refresh')
255
160
  .post(
256
161
  catchAsyncError(async (req, res) => {
257
- const user = await getUserFromBearerToken.execute(
258
- req.headers.authorization
259
- );
260
162
  const params = checkRequiredParams(req.params, [
261
163
  'integrationId',
262
164
  ]);
263
- const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
165
+ const integration =
166
+ await integrationFactory.getInstanceFromIntegrationId(
167
+ params
168
+ );
264
169
 
265
170
  res.json(
266
171
  await integration.send('REFRESH_CONFIG_OPTIONS', req.body)
@@ -269,11 +174,9 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
269
174
  );
270
175
  router.route('/api/integrations/:integrationId/actions').all(
271
176
  catchAsyncError(async (req, res) => {
272
- const user = await getUserFromBearerToken.execute(
273
- req.headers.authorization
274
- );
275
177
  const params = checkRequiredParams(req.params, ['integrationId']);
276
- const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
178
+ const integration =
179
+ await integrationFactory.getInstanceFromIntegrationId(params);
277
180
  res.json(await integration.send('GET_USER_ACTIONS', req.body));
278
181
  })
279
182
  );
@@ -282,14 +185,14 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
282
185
  .route('/api/integrations/:integrationId/actions/:actionId/options')
283
186
  .all(
284
187
  catchAsyncError(async (req, res) => {
285
- const user = await getUserFromBearerToken.execute(
286
- req.headers.authorization
287
- );
288
188
  const params = checkRequiredParams(req.params, [
289
189
  'integrationId',
290
190
  'actionId',
291
191
  ]);
292
- const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
192
+ const integration =
193
+ await integrationFactory.getInstanceFromIntegrationId(
194
+ params
195
+ );
293
196
 
294
197
  res.json(
295
198
  await integration.send('GET_USER_ACTION_OPTIONS', {
@@ -306,14 +209,14 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
306
209
  )
307
210
  .post(
308
211
  catchAsyncError(async (req, res) => {
309
- const user = await getUserFromBearerToken.execute(
310
- req.headers.authorization
311
- );
312
212
  const params = checkRequiredParams(req.params, [
313
213
  'integrationId',
314
214
  'actionId',
315
215
  ]);
316
- const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
216
+ const integration =
217
+ await integrationFactory.getInstanceFromIntegrationId(
218
+ params
219
+ );
317
220
 
318
221
  res.json(
319
222
  await integration.send('REFRESH_USER_ACTION_OPTIONS', {
@@ -326,31 +229,23 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
326
229
 
327
230
  router.route('/api/integrations/:integrationId/actions/:actionId').post(
328
231
  catchAsyncError(async (req, res) => {
329
- const user = await getUserFromBearerToken.execute(
330
- req.headers.authorization
331
- );
332
232
  const params = checkRequiredParams(req.params, [
333
233
  'integrationId',
334
234
  'actionId',
335
235
  ]);
336
- const integration = await getIntegrationInstance.execute(params.integrationId, user.getId());
236
+ const integration =
237
+ await integrationFactory.getInstanceFromIntegrationId(params);
238
+
337
239
  res.json(await integration.send(params.actionId, req.body));
338
240
  })
339
241
  );
340
242
 
341
243
  router.route('/api/integrations/:integrationId').get(
342
244
  catchAsyncError(async (req, res) => {
343
- const user = await getUserFromBearerToken.execute(
344
- req.headers.authorization
345
- );
346
-
347
- if (!user) {
348
- throw Boom.forbidden('User not found');
349
- }
350
-
351
245
  const params = checkRequiredParams(req.params, ['integrationId']);
352
- const integration = await getIntegrationForUser.execute(params.integrationId, user.getId());
353
-
246
+ const integration = await IntegrationHelper.getIntegrationById(
247
+ params.integrationId
248
+ );
354
249
  // We could perhaps augment router with dynamic options? Haven't decided yet, but here may be the place
355
250
 
356
251
  res.json({
@@ -364,11 +259,12 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
364
259
 
365
260
  router.route('/api/integrations/:integrationId/test-auth').get(
366
261
  catchAsyncError(async (req, res) => {
367
- const user = await getUserFromBearerToken.execute(
368
- req.headers.authorization
369
- );
370
262
  const params = checkRequiredParams(req.params, ['integrationId']);
371
- const instance = await getIntegrationInstance.execute(params.integrationId, user.getId());
263
+ const instance =
264
+ await integrationFactory.getInstanceFromIntegrationId({
265
+ userId: getUserId(req),
266
+ integrationId: params.integrationId,
267
+ });
372
268
 
373
269
  if (!instance) {
374
270
  throw Boom.notFound();
@@ -390,36 +286,31 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
390
286
  );
391
287
  }
392
288
 
393
-
394
- /**
395
- * Sets up entity-related routes for the integration router
396
- * @param {Object} router - Express router instance
397
- * @param {import('../user/use-cases/get-user-from-bearer-token').GetUserFromBearerToken} getUserFromBearerToken - Use case for retrieving a user from a bearer token
398
- */
399
- function setEntityRoutes(router, getUserFromBearerToken, useCases) {
400
- const {
401
- getCredentialForUser,
402
- getModuleInstanceFromType,
403
- getEntityOptionsByType,
404
- testModuleAuth,
405
- getModule,
406
- getEntityOptionsById,
407
- refreshEntityOptions,
408
- } = useCases;
289
+ function setEntityRoutes(router, factory, getUserId) {
290
+ const { moduleFactory, IntegrationHelper } = factory;
291
+ const getModuleInstance = async (req, entityType) => {
292
+ if (!moduleFactory.checkIsValidType(entityType)) {
293
+ throw Boom.badRequest(
294
+ `Error: Invalid entity type of ${entityType}, options are ${moduleFactory.moduleTypes.join(
295
+ ', '
296
+ )}`
297
+ );
298
+ }
299
+ return await moduleFactory.getInstanceFromTypeName(
300
+ entityType,
301
+ getUserId(req)
302
+ );
303
+ };
409
304
 
410
305
  router.route('/api/authorize').get(
411
306
  catchAsyncError(async (req, res) => {
412
- const user = await getUserFromBearerToken.execute(
413
- req.headers.authorization
414
- );
415
- const userId = user.getId();
416
307
  const params = checkRequiredParams(req.query, ['entityType']);
417
- const module = await getModuleInstanceFromType.execute(userId, params.entityType);
308
+ const module = await getModuleInstance(req, params.entityType);
418
309
  const areRequirementsValid =
419
310
  module.validateAuthorizationRequirements();
420
311
  if (!areRequirementsValid) {
421
312
  throw new Error(
422
- `Error: Entity of type ${params.entityType} requires a valid url`
313
+ `Error: EntityManager of type ${params.entityType} requires a valid url`
423
314
  );
424
315
  }
425
316
 
@@ -429,19 +320,15 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
429
320
 
430
321
  router.route('/api/authorize').post(
431
322
  catchAsyncError(async (req, res) => {
432
- const user = await getUserFromBearerToken.execute(
433
- req.headers.authorization
434
- );
435
- const userId = user.getId();
436
323
  const params = checkRequiredParams(req.body, [
437
324
  'entityType',
438
325
  'data',
439
326
  ]);
440
- const module = await getModuleInstanceFromType.execute(userId, params.entityType);
327
+ const module = await getModuleInstance(req, params.entityType);
441
328
 
442
329
  res.json(
443
330
  await module.processAuthorizationCallback({
444
- userId,
331
+ userId: getUserId(req),
445
332
  data: params.data,
446
333
  })
447
334
  );
@@ -450,10 +337,6 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
450
337
 
451
338
  router.route('/api/entity').post(
452
339
  catchAsyncError(async (req, res) => {
453
- const user = await getUserFromBearerToken.execute(
454
- req.headers.authorization
455
- );
456
- const userId = user.getId();
457
340
  const params = checkRequiredParams(req.body, [
458
341
  'entityType',
459
342
  'data',
@@ -461,21 +344,20 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
461
344
  checkRequiredParams(req.body.data, ['credential_id']);
462
345
 
463
346
  // May want to pass along the user ID as well so credential ID's can't be fished???
464
- const credential = await getCredentialForUser.execute(
465
- params.data.credential_id,
466
- userId
347
+ const credential = await IntegrationHelper.getCredentialById(
348
+ params.data.credential_id
467
349
  );
468
350
 
469
351
  if (!credential) {
470
352
  throw Boom.badRequest('Invalid credential ID');
471
353
  }
472
354
 
473
- const module = await getModuleInstanceFromType.execute(userId, params.entityType);
355
+ const module = await getModuleInstance(req, params.entityType);
474
356
  const entityDetails = await module.getEntityDetails(
475
357
  module.api,
476
358
  null,
477
359
  null,
478
- userId
360
+ getUserId(req)
479
361
  );
480
362
 
481
363
  res.json(await module.findOrCreateEntity(entityDetails));
@@ -484,39 +366,36 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
484
366
 
485
367
  router.route('/api/entity/options/:credentialId').get(
486
368
  catchAsyncError(async (req, res) => {
487
- const user = await getUserFromBearerToken.execute(
488
- req.headers.authorization
489
- );
490
- const userId = user.getId();
491
369
  // TODO May want to pass along the user ID as well so credential ID's can't be fished???
492
370
  // TODO **flagging this for review** -MW
493
- const credential = await getCredentialForUser.execute(
494
- req.params.credentialId,
495
- userId
371
+ const credential = await IntegrationHelper.getCredentialById(
372
+ req.params.credentialId
496
373
  );
497
- if (credential.user._id.toString() !== userId) {
374
+ if (credential.user._id.toString() !== getUserId(req)) {
498
375
  throw Boom.forbidden('Credential does not belong to user');
499
376
  }
500
377
 
501
378
  const params = checkRequiredParams(req.query, ['entityType']);
502
- const entityOptions = await getEntityOptionsByType.execute(userId, params.entityType);
379
+ const module = await getModuleInstance(req, params.entityType);
503
380
 
504
- res.json(entityOptions);
381
+ res.json(await module.getEntityOptions());
505
382
  })
506
383
  );
507
384
 
508
385
  router.route('/api/entities/:entityId/test-auth').get(
509
386
  catchAsyncError(async (req, res) => {
510
- const user = await getUserFromBearerToken.execute(
511
- req.headers.authorization
512
- );
513
- const userId = user.getId();
514
387
  const params = checkRequiredParams(req.params, ['entityId']);
515
- const testAuthResponse = await testModuleAuth.execute(
388
+ const module = await moduleFactory.getModuleInstanceFromEntityId(
516
389
  params.entityId,
517
- userId
390
+ getUserId(req)
518
391
  );
519
392
 
393
+ if (!module) {
394
+ throw Boom.notFound();
395
+ }
396
+
397
+ const testAuthResponse = await module.testAuth();
398
+
520
399
  if (!testAuthResponse) {
521
400
  res.status(400);
522
401
  res.json({
@@ -536,52 +415,55 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
536
415
 
537
416
  router.route('/api/entities/:entityId').get(
538
417
  catchAsyncError(async (req, res) => {
539
- const user = await getUserFromBearerToken.execute(
540
- req.headers.authorization
541
- );
542
- const userId = user.getId();
543
418
  const params = checkRequiredParams(req.params, ['entityId']);
544
- const module = await getModule.execute(
419
+ const module = await moduleFactory.getModuleInstanceFromEntityId(
545
420
  params.entityId,
546
- userId
421
+ getUserId(req)
547
422
  );
548
423
 
549
- res.json(module);
424
+ if (!module) {
425
+ throw Boom.notFound();
426
+ }
427
+
428
+ res.json(module.entity);
550
429
  })
551
430
  );
552
431
 
553
432
  router.route('/api/entities/:entityId/options').post(
554
433
  catchAsyncError(async (req, res) => {
555
- const user = await getUserFromBearerToken.execute(
556
- req.headers.authorization
557
- );
558
- const userId = user.getId();
559
434
  const params = checkRequiredParams(req.params, [
560
435
  'entityId',
436
+ getUserId(req),
561
437
  ]);
438
+ const module = await moduleFactory.getModuleInstanceFromEntityId(
439
+ params.entityId,
440
+ getUserId(req)
441
+ );
562
442
 
563
- const entityOptions = await getEntityOptionsById.execute(params.entityId, userId);
443
+ if (!module) {
444
+ throw Boom.notFound();
445
+ }
564
446
 
565
- res.json(entityOptions);
447
+ res.json(await module.getEntityOptions());
566
448
  })
567
449
  );
568
450
 
569
451
  router.route('/api/entities/:entityId/options/refresh').post(
570
452
  catchAsyncError(async (req, res) => {
571
- const user = await getUserFromBearerToken.execute(
572
- req.headers.authorization
573
- );
574
- const userId = user.getId();
575
453
  const params = checkRequiredParams(req.params, [
576
454
  'entityId',
455
+ getUserId(req),
577
456
  ]);
578
- const updatedOptions = await refreshEntityOptions.execute(
457
+ const module = await moduleFactory.getModuleInstanceFromEntityId(
579
458
  params.entityId,
580
- userId,
581
- req.body
459
+ getUserId(req)
582
460
  );
583
461
 
584
- res.json(updatedOptions);
462
+ if (!module) {
463
+ throw Boom.notFound();
464
+ }
465
+
466
+ res.json(await module.refreshEntityOptions(req.body));
585
467
  })
586
468
  );
587
469
  }