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