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