@friggframework/core 2.0.0-next.10 → 2.0.0-next.101
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 +702 -0
- package/README.md +959 -50
- package/admin-scripts/index.js +52 -0
- package/admin-scripts/repositories/admin-script-execution-repository-documentdb.js +21 -0
- package/admin-scripts/repositories/admin-script-execution-repository-factory.js +51 -0
- package/admin-scripts/repositories/admin-script-execution-repository-interface.js +166 -0
- package/admin-scripts/repositories/admin-script-execution-repository-mongo.js +228 -0
- package/admin-scripts/repositories/admin-script-execution-repository-postgres.js +268 -0
- package/admin-scripts/repositories/script-schedule-repository-documentdb.js +21 -0
- package/admin-scripts/repositories/script-schedule-repository-factory.js +51 -0
- package/admin-scripts/repositories/script-schedule-repository-interface.js +108 -0
- package/admin-scripts/repositories/script-schedule-repository-mongo.js +179 -0
- package/admin-scripts/repositories/script-schedule-repository-postgres.js +210 -0
- package/application/commands/README.md +451 -0
- package/application/commands/admin-script-commands.js +358 -0
- package/application/commands/credential-commands.js +245 -0
- package/application/commands/entity-commands.js +336 -0
- package/application/commands/integration-commands.js +343 -0
- package/application/commands/process-commands.js +135 -0
- package/application/commands/scheduler-commands.js +263 -0
- package/application/commands/user-commands.js +312 -0
- package/application/index.js +82 -0
- package/assertions/index.js +0 -3
- package/core/CLAUDE.md +690 -0
- package/core/Worker.js +60 -24
- package/core/create-handler.js +84 -6
- package/credential/repositories/credential-repository-documentdb.js +304 -0
- package/credential/repositories/credential-repository-factory.js +54 -0
- package/credential/repositories/credential-repository-interface.js +98 -0
- package/credential/repositories/credential-repository-mongo.js +269 -0
- package/credential/repositories/credential-repository-postgres.js +287 -0
- package/credential/repositories/credential-repository.js +300 -0
- package/credential/use-cases/get-credential-for-user.js +25 -0
- package/credential/use-cases/update-authentication-status.js +15 -0
- package/database/MONGODB_TRANSACTION_FIX.md +198 -0
- package/database/adapters/lambda-invoker.js +97 -0
- package/database/config.js +154 -0
- package/database/documentdb-encryption-service.js +330 -0
- package/database/documentdb-utils.js +136 -0
- package/database/encryption/README.md +839 -0
- package/database/encryption/documentdb-encryption-service.md +3575 -0
- package/database/encryption/encryption-schema-registry.js +401 -0
- package/database/encryption/field-encryption-service.js +254 -0
- package/database/encryption/logger.js +79 -0
- package/database/encryption/prisma-encryption-extension.js +230 -0
- package/database/index.js +21 -21
- package/database/prisma.js +182 -0
- package/database/repositories/health-check-repository-documentdb.js +138 -0
- package/database/repositories/health-check-repository-factory.js +48 -0
- package/database/repositories/health-check-repository-interface.js +82 -0
- package/database/repositories/health-check-repository-mongodb.js +89 -0
- package/database/repositories/health-check-repository-postgres.js +82 -0
- package/database/repositories/migration-status-repository-s3.js +137 -0
- package/database/use-cases/check-database-health-use-case.js +29 -0
- package/database/use-cases/check-database-state-use-case.js +81 -0
- package/database/use-cases/check-encryption-health-use-case.js +83 -0
- package/database/use-cases/get-database-state-via-worker-use-case.js +61 -0
- package/database/use-cases/get-migration-status-use-case.js +93 -0
- package/database/use-cases/run-database-migration-use-case.js +139 -0
- package/database/use-cases/test-encryption-use-case.js +253 -0
- package/database/use-cases/trigger-database-migration-use-case.js +157 -0
- package/database/utils/mongodb-collection-utils.js +94 -0
- package/database/utils/mongodb-schema-init.js +108 -0
- package/database/utils/prisma-runner.js +477 -0
- package/database/utils/prisma-schema-parser.js +182 -0
- package/docs/PROCESS_MANAGEMENT_QUEUE_SPEC.md +517 -0
- package/encrypt/Cryptor.js +34 -168
- package/encrypt/index.js +1 -2
- package/errors/client-safe-error.js +26 -0
- package/errors/fetch-error.js +15 -7
- package/errors/index.js +2 -0
- package/generated/prisma-mongodb/client.d.ts +1 -0
- package/generated/prisma-mongodb/client.js +5 -0
- package/generated/prisma-mongodb/default.d.ts +1 -0
- package/generated/prisma-mongodb/default.js +5 -0
- package/generated/prisma-mongodb/edge.d.ts +1 -0
- package/generated/prisma-mongodb/edge.js +374 -0
- package/generated/prisma-mongodb/index-browser.js +356 -0
- package/generated/prisma-mongodb/index.d.ts +25667 -0
- package/generated/prisma-mongodb/index.js +399 -0
- package/generated/prisma-mongodb/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-mongodb/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-mongodb/package.json +183 -0
- package/generated/prisma-mongodb/runtime/edge-esm.js +35 -0
- package/generated/prisma-mongodb/runtime/edge.js +35 -0
- package/generated/prisma-mongodb/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-mongodb/runtime/index-browser.js +17 -0
- package/generated/prisma-mongodb/runtime/library.d.ts +3982 -0
- package/generated/prisma-mongodb/runtime/library.js +147 -0
- package/generated/prisma-mongodb/runtime/react-native.js +84 -0
- package/generated/prisma-mongodb/runtime/wasm-compiler-edge.js +85 -0
- package/generated/prisma-mongodb/runtime/wasm-engine-edge.js +38 -0
- package/generated/prisma-mongodb/schema.prisma +432 -0
- package/generated/prisma-mongodb/wasm-edge-light-loader.mjs +5 -0
- package/generated/prisma-mongodb/wasm-worker-loader.mjs +5 -0
- package/generated/prisma-mongodb/wasm.d.ts +1 -0
- package/generated/prisma-mongodb/wasm.js +381 -0
- package/generated/prisma-postgresql/client.d.ts +1 -0
- package/generated/prisma-postgresql/client.js +5 -0
- package/generated/prisma-postgresql/default.d.ts +1 -0
- package/generated/prisma-postgresql/default.js +5 -0
- package/generated/prisma-postgresql/edge.d.ts +1 -0
- package/generated/prisma-postgresql/edge.js +395 -0
- package/generated/prisma-postgresql/index-browser.js +377 -0
- package/generated/prisma-postgresql/index.d.ts +28455 -0
- package/generated/prisma-postgresql/index.js +420 -0
- package/generated/prisma-postgresql/libquery_engine-debian-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-postgresql/libquery_engine-rhel-openssl-3.0.x.so.node +0 -0
- package/generated/prisma-postgresql/package.json +183 -0
- package/generated/prisma-postgresql/query_engine_bg.js +2 -0
- package/generated/prisma-postgresql/query_engine_bg.wasm +0 -0
- package/generated/prisma-postgresql/runtime/edge-esm.js +35 -0
- package/generated/prisma-postgresql/runtime/edge.js +35 -0
- package/generated/prisma-postgresql/runtime/index-browser.d.ts +370 -0
- package/generated/prisma-postgresql/runtime/index-browser.js +17 -0
- package/generated/prisma-postgresql/runtime/library.d.ts +3982 -0
- package/generated/prisma-postgresql/runtime/library.js +147 -0
- package/generated/prisma-postgresql/runtime/react-native.js +84 -0
- package/generated/prisma-postgresql/runtime/wasm-compiler-edge.js +85 -0
- package/generated/prisma-postgresql/runtime/wasm-engine-edge.js +38 -0
- package/generated/prisma-postgresql/schema.prisma +414 -0
- package/generated/prisma-postgresql/wasm-edge-light-loader.mjs +5 -0
- package/generated/prisma-postgresql/wasm-worker-loader.mjs +5 -0
- package/generated/prisma-postgresql/wasm.d.ts +1 -0
- package/generated/prisma-postgresql/wasm.js +402 -0
- package/handlers/WEBHOOKS.md +653 -0
- package/handlers/app-definition-loader.js +43 -0
- package/handlers/app-handler-helpers.js +3 -3
- package/handlers/backend-utils.js +271 -42
- package/handlers/database-migration-handler.js +227 -0
- package/handlers/integration-event-dispatcher.js +54 -0
- package/handlers/middleware/admin-auth.js +73 -0
- package/handlers/routers/HEALTHCHECK.md +342 -0
- package/handlers/routers/auth.js +4 -15
- package/handlers/routers/db-migration.handler.js +29 -0
- package/handlers/routers/db-migration.js +311 -0
- package/handlers/routers/health.js +518 -0
- package/handlers/routers/integration-defined-routers.js +85 -10
- package/handlers/routers/integration-webhook-routers.js +67 -0
- package/handlers/routers/reporting.js +9 -0
- package/handlers/routers/user.js +27 -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 +44 -0
- package/handlers/workers/db-migration.js +352 -0
- package/handlers/workers/dlq-processor.js +63 -0
- package/handlers/workers/integration-defined-workers.js +13 -7
- package/index.js +91 -46
- package/infrastructure/scheduler/eventbridge-scheduler-adapter.js +184 -0
- package/infrastructure/scheduler/index.js +33 -0
- package/infrastructure/scheduler/mock-scheduler-adapter.js +143 -0
- package/infrastructure/scheduler/scheduler-service-factory.js +73 -0
- package/infrastructure/scheduler/scheduler-service-interface.js +47 -0
- package/integrations/EXTENSIONS.md +240 -0
- package/integrations/WEBHOOK-QUICKSTART.md +151 -0
- package/integrations/extension.js +254 -0
- package/integrations/index.js +20 -10
- package/integrations/integration-base.js +633 -72
- package/integrations/integration-router.js +398 -180
- package/integrations/options.js +1 -1
- package/integrations/repositories/config-patch-shared.js +43 -0
- package/integrations/repositories/integration-mapping-repository-documentdb.js +280 -0
- package/integrations/repositories/integration-mapping-repository-factory.js +57 -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-documentdb.js +284 -0
- package/integrations/repositories/integration-repository-factory.js +51 -0
- package/integrations/repositories/integration-repository-interface.js +173 -0
- package/integrations/repositories/integration-repository-mongo.js +414 -0
- package/integrations/repositories/integration-repository-postgres.js +452 -0
- package/integrations/repositories/process-repository-documentdb.js +311 -0
- package/integrations/repositories/process-repository-factory.js +53 -0
- package/integrations/repositories/process-repository-interface.js +136 -0
- package/integrations/repositories/process-repository-mongo.js +262 -0
- package/integrations/repositories/process-repository-postgres.js +380 -0
- package/integrations/repositories/process-update-ops-shared.js +112 -0
- package/integrations/tests/doubles/config-capturing-integration.js +81 -0
- package/integrations/tests/doubles/dummy-integration-class.js +113 -0
- package/integrations/tests/doubles/test-integration-repository.js +146 -0
- package/integrations/use-cases/create-integration.js +215 -0
- package/integrations/use-cases/create-process.js +130 -0
- package/integrations/use-cases/delete-integration-for-user.js +119 -0
- package/integrations/use-cases/find-integration-by-entity-external-id.js +74 -0
- package/integrations/use-cases/find-integration-context-by-external-entity-id.js +76 -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 +88 -0
- package/integrations/use-cases/get-possible-integrations.js +27 -0
- package/integrations/use-cases/get-process.js +89 -0
- package/integrations/use-cases/index.js +19 -0
- package/integrations/use-cases/list-integrations-by-entity-external-id.js +46 -0
- package/integrations/use-cases/load-integration-context.js +71 -0
- package/integrations/use-cases/patch-integration-config.js +39 -0
- package/integrations/use-cases/process-errors.js +28 -0
- package/integrations/use-cases/update-integration-config.js +32 -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 +92 -0
- package/integrations/use-cases/update-process-metrics.js +216 -0
- package/integrations/use-cases/update-process-state.js +163 -0
- package/integrations/utils/map-integration-dto.js +37 -0
- package/jest-global-setup-noop.js +3 -0
- package/jest-global-teardown-noop.js +3 -0
- package/logs/logger.js +0 -4
- package/{module-plugin → modules}/index.js +0 -10
- package/modules/module-factory.js +56 -0
- package/modules/module.js +287 -0
- package/modules/repositories/module-repository-documentdb.js +350 -0
- package/modules/repositories/module-repository-factory.js +40 -0
- package/modules/repositories/module-repository-interface.js +145 -0
- package/modules/repositories/module-repository-mongo.js +436 -0
- package/modules/repositories/module-repository-postgres.js +481 -0
- package/modules/repositories/module-repository.js +369 -0
- package/modules/requester/api-key.js +52 -0
- package/modules/requester/oauth-2.js +396 -0
- package/modules/requester/requester.js +334 -0
- package/{module-plugin → modules}/test/mock-api/api.js +8 -3
- package/{module-plugin → modules}/test/mock-api/definition.js +14 -10
- 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 +71 -0
- package/modules/use-cases/get-entity-options-by-type.js +34 -0
- package/modules/use-cases/get-module-instance-from-type.js +34 -0
- package/modules/use-cases/get-module.js +74 -0
- package/modules/use-cases/process-authorization-callback.js +243 -0
- package/modules/use-cases/refresh-entity-options.js +72 -0
- package/modules/use-cases/test-module-auth.js +72 -0
- package/modules/utils/map-module-dto.js +18 -0
- package/package.json +82 -50
- package/prisma-mongodb/schema.prisma +432 -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/20251010000000_remove_unused_entity_reference_map/migration.sql +3 -0
- package/prisma-postgresql/migrations/20251112195422_update_user_unique_constraints/migration.sql +25 -0
- package/prisma-postgresql/migrations/20260422120000_add_entity_data_column/migration.sql +10 -0
- package/prisma-postgresql/migrations/20260422120001_create_process_table/migration.sql +48 -0
- package/prisma-postgresql/migrations/20260625000000_add_user_organization_id_index/migration.sql +2 -0
- package/prisma-postgresql/migrations/20260703000000_add_integration_status_in_creation_in_deletion/migration.sql +11 -0
- package/prisma-postgresql/migrations/20260703000001_integration_status_default_in_creation/migration.sql +8 -0
- package/prisma-postgresql/migrations/20260706000000_add_admin_script_execution_and_schedule/migration.sql +61 -0
- package/prisma-postgresql/migrations/migration_lock.toml +3 -0
- package/prisma-postgresql/schema.prisma +414 -0
- package/queues/queuer-util.js +103 -21
- package/reporting/README.md +86 -0
- package/reporting/index.js +17 -0
- package/reporting/reporting-router.js +77 -0
- package/reporting/repositories/reporting-repository-documentdb.js +127 -0
- package/reporting/repositories/reporting-repository-factory.js +35 -0
- package/reporting/repositories/reporting-repository-interface.js +16 -0
- package/reporting/repositories/reporting-repository-mongo.js +54 -0
- package/reporting/repositories/reporting-repository-postgres.js +70 -0
- package/reporting/use-cases/index.js +6 -0
- package/reporting/use-cases/list-integrations-report.js +142 -0
- package/syncs/manager.js +468 -443
- package/syncs/repositories/sync-repository-documentdb.js +240 -0
- package/syncs/repositories/sync-repository-factory.js +43 -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-documentdb.js +137 -0
- package/token/repositories/token-repository-factory.js +40 -0
- package/token/repositories/token-repository-interface.js +131 -0
- package/token/repositories/token-repository-mongo.js +219 -0
- package/token/repositories/token-repository-postgres.js +264 -0
- package/token/repositories/token-repository.js +219 -0
- package/types/associations/index.d.ts +0 -17
- package/types/core/index.d.ts +12 -4
- package/types/database/index.d.ts +10 -2
- package/types/encrypt/index.d.ts +5 -3
- package/types/integrations/index.d.ts +3 -8
- package/types/module-plugin/index.d.ts +17 -69
- package/types/syncs/index.d.ts +0 -17
- package/user/repositories/user-repository-documentdb.js +458 -0
- package/user/repositories/user-repository-factory.js +52 -0
- package/user/repositories/user-repository-interface.js +214 -0
- package/user/repositories/user-repository-mongo.js +323 -0
- package/user/repositories/user-repository-postgres.js +377 -0
- package/user/tests/doubles/test-user-repository.js +72 -0
- package/user/use-cases/authenticate-user.js +127 -0
- package/user/use-cases/authenticate-with-shared-secret.js +48 -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-adopter-jwt.js +149 -0
- package/user/use-cases/get-user-from-bearer-token.js +77 -0
- package/user/use-cases/get-user-from-x-frigg-headers.js +132 -0
- package/user/use-cases/login-user.js +122 -0
- package/user/user.js +125 -0
- package/utils/backend-path.js +38 -0
- package/utils/index.js +6 -0
- package/websocket/repositories/websocket-connection-repository-documentdb.js +119 -0
- package/websocket/repositories/websocket-connection-repository-factory.js +44 -0
- package/websocket/repositories/websocket-connection-repository-interface.js +106 -0
- package/websocket/repositories/websocket-connection-repository-mongo.js +156 -0
- package/websocket/repositories/websocket-connection-repository-postgres.js +196 -0
- package/websocket/repositories/websocket-connection-repository.js +161 -0
- package/assertions/is-equal.js +0 -17
- package/associations/model.js +0 -54
- package/database/models/IndividualUser.js +0 -76
- package/database/models/OrganizationUser.js +0 -29
- package/database/models/State.js +0 -9
- package/database/models/Token.js +0 -70
- package/database/models/UserModel.js +0 -7
- package/database/models/WebsocketConnection.js +0 -49
- package/database/mongo.js +0 -45
- package/database/mongoose.js +0 -5
- package/encrypt/Cryptor.test.js +0 -32
- package/encrypt/encrypt.js +0 -132
- package/encrypt/encrypt.test.js +0 -1069
- package/encrypt/test-encrypt.js +0 -107
- package/errors/base-error.test.js +0 -32
- package/errors/fetch-error.test.js +0 -79
- package/errors/halt-error.test.js +0 -11
- package/errors/validation-errors.test.js +0 -120
- 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/lambda/TimeoutCatcher.test.js +0 -68
- package/logs/logger.test.js +0 -76
- 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/entity.js +0 -46
- package/module-plugin/manager.js +0 -169
- package/module-plugin/module-factory.js +0 -61
- package/module-plugin/requester/api-key.js +0 -36
- package/module-plugin/requester/oauth-2.js +0 -219
- package/module-plugin/requester/requester.js +0 -165
- package/module-plugin/requester/requester.test.js +0 -28
- package/module-plugin/test/auther.test.js +0 -97
- package/syncs/model.js +0 -62
- /package/{module-plugin → modules}/ModuleConstants.js +0 -0
- /package/{module-plugin → modules}/requester/basic.js +0 -0
- /package/{module-plugin → modules}/test/mock-api/mocks/hubspot.js +0 -0
|
@@ -2,23 +2,220 @@ 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
|
+
GetUserFromXFriggHeaders,
|
|
61
|
+
} = require('../user/use-cases/get-user-from-x-frigg-headers');
|
|
62
|
+
const {
|
|
63
|
+
GetUserFromAdopterJwt,
|
|
64
|
+
} = require('../user/use-cases/get-user-from-adopter-jwt');
|
|
65
|
+
const {
|
|
66
|
+
AuthenticateWithSharedSecret,
|
|
67
|
+
} = require('../user/use-cases/authenticate-with-shared-secret');
|
|
68
|
+
const { AuthenticateUser } = require('../user/use-cases/authenticate-user');
|
|
69
|
+
const {
|
|
70
|
+
ProcessAuthorizationCallback,
|
|
71
|
+
} = require('../modules/use-cases/process-authorization-callback');
|
|
72
|
+
|
|
73
|
+
function createIntegrationRouter() {
|
|
74
|
+
const { integrations: integrationClasses, userConfig } =
|
|
75
|
+
loadAppDefinition();
|
|
76
|
+
const moduleRepository = createModuleRepository();
|
|
77
|
+
const integrationRepository = createIntegrationRepository();
|
|
78
|
+
const credentialRepository = createCredentialRepository();
|
|
79
|
+
const userRepository = createUserRepository();
|
|
80
|
+
|
|
81
|
+
const getUserFromBearerToken = new GetUserFromBearerToken({
|
|
82
|
+
userRepository,
|
|
83
|
+
userConfig,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const getUserFromXFriggHeaders = new GetUserFromXFriggHeaders({
|
|
87
|
+
userRepository,
|
|
88
|
+
userConfig,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const getUserFromAdopterJwt = new GetUserFromAdopterJwt({
|
|
92
|
+
userRepository,
|
|
93
|
+
userConfig,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const authenticateWithSharedSecret = new AuthenticateWithSharedSecret();
|
|
97
|
+
|
|
98
|
+
const authenticateUser = new AuthenticateUser({
|
|
99
|
+
getUserFromBearerToken,
|
|
100
|
+
getUserFromXFriggHeaders,
|
|
101
|
+
getUserFromAdopterJwt,
|
|
102
|
+
authenticateWithSharedSecret,
|
|
103
|
+
userConfig,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const moduleFactory = new ModuleFactory({
|
|
107
|
+
moduleRepository,
|
|
108
|
+
moduleDefinitions:
|
|
109
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
110
|
+
});
|
|
111
|
+
const deleteIntegrationForUser = new DeleteIntegrationForUser({
|
|
112
|
+
integrationRepository,
|
|
113
|
+
integrationClasses,
|
|
114
|
+
moduleFactory,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
const getIntegrationsForUser = new GetIntegrationsForUser({
|
|
118
|
+
integrationRepository,
|
|
119
|
+
integrationClasses,
|
|
120
|
+
moduleFactory,
|
|
121
|
+
moduleRepository,
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const getCredentialForUser = new GetCredentialForUser({
|
|
125
|
+
credentialRepository,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const createIntegration = new CreateIntegration({
|
|
129
|
+
integrationRepository,
|
|
130
|
+
integrationClasses,
|
|
131
|
+
moduleFactory,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const getEntitiesForUser = new GetEntitiesForUser({
|
|
135
|
+
moduleRepository,
|
|
136
|
+
moduleDefinitions:
|
|
137
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
const getIntegrationInstance = new GetIntegrationInstance({
|
|
141
|
+
integrationRepository,
|
|
142
|
+
integrationClasses,
|
|
143
|
+
moduleFactory,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const updateIntegration = new UpdateIntegration({
|
|
147
|
+
integrationRepository,
|
|
148
|
+
integrationClasses,
|
|
149
|
+
moduleFactory,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const getModuleInstanceFromType = new GetModuleInstanceFromType({
|
|
153
|
+
moduleDefinitions:
|
|
154
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
const getEntityOptionsByType = new GetEntityOptionsByType({
|
|
158
|
+
moduleDefinitions:
|
|
159
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const testModuleAuth = new TestModuleAuth({
|
|
163
|
+
moduleRepository,
|
|
164
|
+
moduleDefinitions:
|
|
165
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
const getModule = new GetModule({
|
|
169
|
+
moduleRepository,
|
|
170
|
+
moduleDefinitions:
|
|
171
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
const getEntityOptionsById = new GetEntityOptionsById({
|
|
175
|
+
moduleRepository,
|
|
176
|
+
moduleDefinitions:
|
|
177
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
const refreshEntityOptions = new RefreshEntityOptions({
|
|
181
|
+
moduleRepository,
|
|
182
|
+
moduleDefinitions:
|
|
183
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const getPossibleIntegrations = new GetPossibleIntegrations({
|
|
187
|
+
integrationClasses,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
const processAuthorizationCallback = new ProcessAuthorizationCallback({
|
|
191
|
+
moduleRepository,
|
|
192
|
+
credentialRepository,
|
|
193
|
+
integrationRepository,
|
|
194
|
+
moduleDefinitions:
|
|
195
|
+
getModulesDefinitionFromIntegrationClasses(integrationClasses),
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
const router = express();
|
|
199
|
+
|
|
200
|
+
setIntegrationRoutes(router, authenticateUser, {
|
|
201
|
+
createIntegration,
|
|
202
|
+
deleteIntegrationForUser,
|
|
203
|
+
getIntegrationsForUser,
|
|
204
|
+
getEntitiesForUser,
|
|
205
|
+
getIntegrationInstance,
|
|
206
|
+
updateIntegration,
|
|
207
|
+
getPossibleIntegrations,
|
|
208
|
+
});
|
|
209
|
+
setEntityRoutes(router, authenticateUser, {
|
|
210
|
+
getCredentialForUser,
|
|
211
|
+
getModuleInstanceFromType,
|
|
212
|
+
getEntityOptionsByType,
|
|
213
|
+
testModuleAuth,
|
|
214
|
+
getModule,
|
|
215
|
+
getEntityOptionsById,
|
|
216
|
+
refreshEntityOptions,
|
|
217
|
+
processAuthorizationCallback,
|
|
218
|
+
});
|
|
22
219
|
return router;
|
|
23
220
|
}
|
|
24
221
|
|
|
@@ -46,111 +243,95 @@ function checkRequiredParams(params, requiredKeys) {
|
|
|
46
243
|
return returnDict;
|
|
47
244
|
}
|
|
48
245
|
|
|
49
|
-
|
|
50
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Sets up integration-related routes on the provided Express router
|
|
248
|
+
* @param {express.Router} router - Express router instance to add routes to
|
|
249
|
+
* @param {import('../user/use-cases/authenticate-user').AuthenticateUser} authenticateUser - Use case for multi-mode user authentication
|
|
250
|
+
* @param {Object} useCases - use cases for integration management
|
|
251
|
+
*/
|
|
252
|
+
function setIntegrationRoutes(router, authenticateUser, useCases) {
|
|
253
|
+
const {
|
|
254
|
+
createIntegration,
|
|
255
|
+
deleteIntegrationForUser,
|
|
256
|
+
getIntegrationsForUser,
|
|
257
|
+
getEntitiesForUser,
|
|
258
|
+
getIntegrationInstance,
|
|
259
|
+
updateIntegration,
|
|
260
|
+
getPossibleIntegrations,
|
|
261
|
+
} = useCases;
|
|
51
262
|
router.route('/api/integrations').get(
|
|
52
263
|
catchAsyncError(async (req, res) => {
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
results
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
264
|
+
const user = await authenticateUser.execute(req);
|
|
265
|
+
const userId = user.getId();
|
|
266
|
+
const integrations = await getIntegrationsForUser.execute(userId);
|
|
267
|
+
const results = {
|
|
268
|
+
entities: {
|
|
269
|
+
options: await getPossibleIntegrations.execute(),
|
|
270
|
+
authorized: await getEntitiesForUser.execute(userId),
|
|
271
|
+
},
|
|
272
|
+
integrations: integrations,
|
|
273
|
+
};
|
|
60
274
|
|
|
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
275
|
res.json(results);
|
|
70
276
|
})
|
|
71
277
|
);
|
|
72
278
|
|
|
73
279
|
router.route('/api/integrations').post(
|
|
74
280
|
catchAsyncError(async (req, res) => {
|
|
281
|
+
const user = await authenticateUser.execute(req);
|
|
282
|
+
const userId = user.getId();
|
|
75
283
|
const params = checkRequiredParams(req.body, [
|
|
76
284
|
'entities',
|
|
77
285
|
'config',
|
|
78
286
|
]);
|
|
79
|
-
|
|
287
|
+
|
|
80
288
|
get(params.config, 'type');
|
|
81
289
|
|
|
82
|
-
|
|
83
|
-
const integration = await integrationFactory.createIntegration(
|
|
290
|
+
const integration = await createIntegration.execute(
|
|
84
291
|
params.entities,
|
|
85
|
-
|
|
292
|
+
userId,
|
|
86
293
|
params.config
|
|
87
294
|
);
|
|
88
295
|
|
|
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
|
-
);
|
|
296
|
+
res.status(201).json(integration);
|
|
100
297
|
})
|
|
101
298
|
);
|
|
102
299
|
|
|
103
300
|
router.route('/api/integrations/:integrationId').patch(
|
|
104
301
|
catchAsyncError(async (req, res) => {
|
|
302
|
+
const user = await authenticateUser.execute(req);
|
|
303
|
+
const userId = user.getId();
|
|
105
304
|
const params = checkRequiredParams(req.body, ['config']);
|
|
106
305
|
|
|
107
|
-
const integration =
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
)
|
|
306
|
+
const integration = await updateIntegration.execute(
|
|
307
|
+
req.params.integrationId,
|
|
308
|
+
userId,
|
|
309
|
+
params.config
|
|
123
310
|
);
|
|
311
|
+
res.json(integration);
|
|
124
312
|
})
|
|
125
313
|
);
|
|
126
314
|
|
|
127
315
|
router.route('/api/integrations/:integrationId').delete(
|
|
128
316
|
catchAsyncError(async (req, res) => {
|
|
317
|
+
const user = await authenticateUser.execute(req);
|
|
129
318
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
integrationId: params.integrationId,
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
debug(
|
|
137
|
-
`Calling onUpdate on the ${integration?.constructor?.Definition?.name} Integration with no arguments`
|
|
319
|
+
await deleteIntegrationForUser.execute(
|
|
320
|
+
params.integrationId,
|
|
321
|
+
user.getId()
|
|
138
322
|
);
|
|
139
|
-
|
|
140
|
-
await IntegrationHelper.deleteIntegrationForUserById(
|
|
141
|
-
getUserId(req),
|
|
142
|
-
params.integrationId
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
res.status(201).json({});
|
|
323
|
+
res.status(204).json({});
|
|
146
324
|
})
|
|
147
325
|
);
|
|
148
326
|
|
|
149
327
|
router.route('/api/integrations/:integrationId/config/options').get(
|
|
150
328
|
catchAsyncError(async (req, res) => {
|
|
329
|
+
const user = await authenticateUser.execute(req);
|
|
151
330
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
152
|
-
const integration =
|
|
153
|
-
|
|
331
|
+
const integration = await getIntegrationInstance.execute(
|
|
332
|
+
params.integrationId,
|
|
333
|
+
user.getId()
|
|
334
|
+
);
|
|
154
335
|
res.json(await integration.send('GET_CONFIG_OPTIONS'));
|
|
155
336
|
})
|
|
156
337
|
);
|
|
@@ -159,13 +340,14 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
159
340
|
.route('/api/integrations/:integrationId/config/options/refresh')
|
|
160
341
|
.post(
|
|
161
342
|
catchAsyncError(async (req, res) => {
|
|
343
|
+
const user = await authenticateUser.execute(req);
|
|
162
344
|
const params = checkRequiredParams(req.params, [
|
|
163
345
|
'integrationId',
|
|
164
346
|
]);
|
|
165
|
-
const integration =
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
347
|
+
const integration = await getIntegrationInstance.execute(
|
|
348
|
+
params.integrationId,
|
|
349
|
+
user.getId()
|
|
350
|
+
);
|
|
169
351
|
|
|
170
352
|
res.json(
|
|
171
353
|
await integration.send('REFRESH_CONFIG_OPTIONS', req.body)
|
|
@@ -174,9 +356,12 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
174
356
|
);
|
|
175
357
|
router.route('/api/integrations/:integrationId/actions').all(
|
|
176
358
|
catchAsyncError(async (req, res) => {
|
|
359
|
+
const user = await authenticateUser.execute(req);
|
|
177
360
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
178
|
-
const integration =
|
|
179
|
-
|
|
361
|
+
const integration = await getIntegrationInstance.execute(
|
|
362
|
+
params.integrationId,
|
|
363
|
+
user.getId()
|
|
364
|
+
);
|
|
180
365
|
res.json(await integration.send('GET_USER_ACTIONS', req.body));
|
|
181
366
|
})
|
|
182
367
|
);
|
|
@@ -185,14 +370,15 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
185
370
|
.route('/api/integrations/:integrationId/actions/:actionId/options')
|
|
186
371
|
.all(
|
|
187
372
|
catchAsyncError(async (req, res) => {
|
|
373
|
+
const user = await authenticateUser.execute(req);
|
|
188
374
|
const params = checkRequiredParams(req.params, [
|
|
189
375
|
'integrationId',
|
|
190
376
|
'actionId',
|
|
191
377
|
]);
|
|
192
|
-
const integration =
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
378
|
+
const integration = await getIntegrationInstance.execute(
|
|
379
|
+
params.integrationId,
|
|
380
|
+
user.getId()
|
|
381
|
+
);
|
|
196
382
|
|
|
197
383
|
res.json(
|
|
198
384
|
await integration.send('GET_USER_ACTION_OPTIONS', {
|
|
@@ -209,14 +395,15 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
209
395
|
)
|
|
210
396
|
.post(
|
|
211
397
|
catchAsyncError(async (req, res) => {
|
|
398
|
+
const user = await authenticateUser.execute(req);
|
|
212
399
|
const params = checkRequiredParams(req.params, [
|
|
213
400
|
'integrationId',
|
|
214
401
|
'actionId',
|
|
215
402
|
]);
|
|
216
|
-
const integration =
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
403
|
+
const integration = await getIntegrationInstance.execute(
|
|
404
|
+
params.integrationId,
|
|
405
|
+
user.getId()
|
|
406
|
+
);
|
|
220
407
|
|
|
221
408
|
res.json(
|
|
222
409
|
await integration.send('REFRESH_USER_ACTION_OPTIONS', {
|
|
@@ -229,23 +416,33 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
229
416
|
|
|
230
417
|
router.route('/api/integrations/:integrationId/actions/:actionId').post(
|
|
231
418
|
catchAsyncError(async (req, res) => {
|
|
419
|
+
const user = await authenticateUser.execute(req);
|
|
232
420
|
const params = checkRequiredParams(req.params, [
|
|
233
421
|
'integrationId',
|
|
234
422
|
'actionId',
|
|
235
423
|
]);
|
|
236
|
-
const integration =
|
|
237
|
-
|
|
238
|
-
|
|
424
|
+
const integration = await getIntegrationInstance.execute(
|
|
425
|
+
params.integrationId,
|
|
426
|
+
user.getId()
|
|
427
|
+
);
|
|
239
428
|
res.json(await integration.send(params.actionId, req.body));
|
|
240
429
|
})
|
|
241
430
|
);
|
|
242
431
|
|
|
243
432
|
router.route('/api/integrations/:integrationId').get(
|
|
244
433
|
catchAsyncError(async (req, res) => {
|
|
434
|
+
const user = await authenticateUser.execute(req);
|
|
435
|
+
|
|
436
|
+
if (!user) {
|
|
437
|
+
throw Boom.forbidden('User not found');
|
|
438
|
+
}
|
|
439
|
+
|
|
245
440
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
246
|
-
const integration = await
|
|
247
|
-
params.integrationId
|
|
441
|
+
const integration = await getIntegrationInstance.execute(
|
|
442
|
+
params.integrationId,
|
|
443
|
+
user.getId()
|
|
248
444
|
);
|
|
445
|
+
|
|
249
446
|
// We could perhaps augment router with dynamic options? Haven't decided yet, but here may be the place
|
|
250
447
|
|
|
251
448
|
res.json({
|
|
@@ -259,19 +456,20 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
259
456
|
|
|
260
457
|
router.route('/api/integrations/:integrationId/test-auth').get(
|
|
261
458
|
catchAsyncError(async (req, res) => {
|
|
459
|
+
const user = await authenticateUser.execute(req);
|
|
262
460
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
263
|
-
const instance =
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
});
|
|
461
|
+
const instance = await getIntegrationInstance.execute(
|
|
462
|
+
params.integrationId,
|
|
463
|
+
user.getId()
|
|
464
|
+
);
|
|
268
465
|
|
|
269
466
|
if (!instance) {
|
|
270
467
|
throw Boom.notFound();
|
|
271
468
|
}
|
|
272
469
|
|
|
273
470
|
const start = Date.now();
|
|
274
|
-
await instance.testAuth();
|
|
471
|
+
const authPassed = await instance.testAuth();
|
|
472
|
+
await instance.reconcileAuthStatus(authPassed);
|
|
275
473
|
const errors = instance.record.messages?.errors?.filter(
|
|
276
474
|
({ timestamp }) => timestamp >= start
|
|
277
475
|
);
|
|
@@ -286,57 +484,88 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
286
484
|
);
|
|
287
485
|
}
|
|
288
486
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
487
|
+
/**
|
|
488
|
+
* Sets up entity-related routes for the integration router
|
|
489
|
+
* @param {Object} router - Express router instance
|
|
490
|
+
* @param {import('../user/use-cases/authenticate-user').AuthenticateUser} authenticateUser - Use case for multi-mode user authentication
|
|
491
|
+
*/
|
|
492
|
+
function setEntityRoutes(router, authenticateUser, useCases) {
|
|
493
|
+
const {
|
|
494
|
+
getCredentialForUser,
|
|
495
|
+
getModuleInstanceFromType,
|
|
496
|
+
getEntityOptionsByType,
|
|
497
|
+
testModuleAuth,
|
|
498
|
+
getModule,
|
|
499
|
+
getEntityOptionsById,
|
|
500
|
+
refreshEntityOptions,
|
|
501
|
+
processAuthorizationCallback,
|
|
502
|
+
} = useCases;
|
|
304
503
|
|
|
305
504
|
router.route('/api/authorize').get(
|
|
306
505
|
catchAsyncError(async (req, res) => {
|
|
506
|
+
const user = await authenticateUser.execute(req);
|
|
507
|
+
const userId = user.getId();
|
|
307
508
|
const params = checkRequiredParams(req.query, ['entityType']);
|
|
308
|
-
const module = await
|
|
509
|
+
const module = await getModuleInstanceFromType.execute(
|
|
510
|
+
userId,
|
|
511
|
+
params.entityType,
|
|
512
|
+
{ state: req.query.state }
|
|
513
|
+
);
|
|
309
514
|
const areRequirementsValid =
|
|
310
515
|
module.validateAuthorizationRequirements();
|
|
311
516
|
if (!areRequirementsValid) {
|
|
312
517
|
throw new Error(
|
|
313
|
-
`Error:
|
|
518
|
+
`Error: Entity of type ${params.entityType} requires a valid url`
|
|
314
519
|
);
|
|
315
520
|
}
|
|
316
521
|
|
|
317
|
-
res.json(
|
|
522
|
+
res.json(module.getAuthorizationRequirements());
|
|
318
523
|
})
|
|
319
524
|
);
|
|
320
525
|
|
|
321
526
|
router.route('/api/authorize').post(
|
|
322
527
|
catchAsyncError(async (req, res) => {
|
|
528
|
+
const user = await authenticateUser.execute(req);
|
|
529
|
+
const userId = user.getId();
|
|
323
530
|
const params = checkRequiredParams(req.body, [
|
|
324
531
|
'entityType',
|
|
325
532
|
'data',
|
|
326
533
|
]);
|
|
327
|
-
const module = await getModuleInstance(req, params.entityType);
|
|
328
534
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
535
|
+
const dataKeys =
|
|
536
|
+
params.data && typeof params.data === 'object'
|
|
537
|
+
? Object.keys(params.data)
|
|
538
|
+
: [];
|
|
539
|
+
console.log(
|
|
540
|
+
`[Frigg] POST /api/authorize userId=${userId} entityType=${params.entityType} dataKeys=${JSON.stringify(dataKeys)}`
|
|
334
541
|
);
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
const entityDetails =
|
|
545
|
+
await processAuthorizationCallback.execute(
|
|
546
|
+
userId,
|
|
547
|
+
params.entityType,
|
|
548
|
+
params.data
|
|
549
|
+
);
|
|
550
|
+
|
|
551
|
+
console.log(
|
|
552
|
+
`[Frigg] POST /api/authorize success userId=${userId} entityType=${params.entityType} credentialId=${entityDetails?.credential_id} entityId=${entityDetails?.entity_id}`
|
|
553
|
+
);
|
|
554
|
+
|
|
555
|
+
res.json(entityDetails);
|
|
556
|
+
} catch (err) {
|
|
557
|
+
console.error(
|
|
558
|
+
`[Frigg] POST /api/authorize failed userId=${userId} entityType=${params.entityType} error=${err?.message || err}`
|
|
559
|
+
);
|
|
560
|
+
throw err;
|
|
561
|
+
}
|
|
335
562
|
})
|
|
336
563
|
);
|
|
337
564
|
|
|
338
565
|
router.route('/api/entity').post(
|
|
339
566
|
catchAsyncError(async (req, res) => {
|
|
567
|
+
const user = await authenticateUser.execute(req);
|
|
568
|
+
const userId = user.getId();
|
|
340
569
|
const params = checkRequiredParams(req.body, [
|
|
341
570
|
'entityType',
|
|
342
571
|
'data',
|
|
@@ -344,20 +573,24 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
344
573
|
checkRequiredParams(req.body.data, ['credential_id']);
|
|
345
574
|
|
|
346
575
|
// 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
|
|
576
|
+
const credential = await getCredentialForUser.execute(
|
|
577
|
+
params.data.credential_id,
|
|
578
|
+
userId
|
|
349
579
|
);
|
|
350
580
|
|
|
351
581
|
if (!credential) {
|
|
352
582
|
throw Boom.badRequest('Invalid credential ID');
|
|
353
583
|
}
|
|
354
584
|
|
|
355
|
-
const module = await
|
|
585
|
+
const module = await getModuleInstanceFromType.execute(
|
|
586
|
+
userId,
|
|
587
|
+
params.entityType
|
|
588
|
+
);
|
|
356
589
|
const entityDetails = await module.getEntityDetails(
|
|
357
590
|
module.api,
|
|
358
591
|
null,
|
|
359
592
|
null,
|
|
360
|
-
|
|
593
|
+
userId
|
|
361
594
|
);
|
|
362
595
|
|
|
363
596
|
res.json(await module.findOrCreateEntity(entityDetails));
|
|
@@ -366,43 +599,44 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
366
599
|
|
|
367
600
|
router.route('/api/entity/options/:credentialId').get(
|
|
368
601
|
catchAsyncError(async (req, res) => {
|
|
602
|
+
const user = await authenticateUser.execute(req);
|
|
603
|
+
const userId = user.getId();
|
|
369
604
|
// TODO May want to pass along the user ID as well so credential ID's can't be fished???
|
|
370
605
|
// TODO **flagging this for review** -MW
|
|
371
|
-
const credential = await
|
|
372
|
-
req.params.credentialId
|
|
606
|
+
const credential = await getCredentialForUser.execute(
|
|
607
|
+
req.params.credentialId,
|
|
608
|
+
userId
|
|
373
609
|
);
|
|
374
|
-
if (credential.
|
|
610
|
+
if (credential.userId.toString() !== userId) {
|
|
375
611
|
throw Boom.forbidden('Credential does not belong to user');
|
|
376
612
|
}
|
|
377
613
|
|
|
378
614
|
const params = checkRequiredParams(req.query, ['entityType']);
|
|
379
|
-
const
|
|
615
|
+
const entityOptions = await getEntityOptionsByType.execute(
|
|
616
|
+
userId,
|
|
617
|
+
params.entityType
|
|
618
|
+
);
|
|
380
619
|
|
|
381
|
-
res.json(
|
|
620
|
+
res.json(entityOptions);
|
|
382
621
|
})
|
|
383
622
|
);
|
|
384
623
|
|
|
385
624
|
router.route('/api/entities/:entityId/test-auth').get(
|
|
386
625
|
catchAsyncError(async (req, res) => {
|
|
626
|
+
const user = await authenticateUser.execute(req);
|
|
387
627
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
388
|
-
const
|
|
628
|
+
const testAuthResponse = await testModuleAuth.execute(
|
|
389
629
|
params.entityId,
|
|
390
|
-
|
|
630
|
+
user // Pass User object for proper validation
|
|
391
631
|
);
|
|
392
632
|
|
|
393
|
-
if (!module) {
|
|
394
|
-
throw Boom.notFound();
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
const testAuthResponse = await module.testAuth();
|
|
398
|
-
|
|
399
633
|
if (!testAuthResponse) {
|
|
400
634
|
res.status(400);
|
|
401
635
|
res.json({
|
|
402
636
|
errors: [
|
|
403
637
|
{
|
|
404
638
|
title: 'Authentication Error',
|
|
405
|
-
message: `There was an error with your
|
|
639
|
+
message: `There was an error with your Entity. Please reconnect/re-authenticate, or reach out to Support for assistance.`,
|
|
406
640
|
timestamp: Date.now(),
|
|
407
641
|
},
|
|
408
642
|
],
|
|
@@ -415,55 +649,39 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
415
649
|
|
|
416
650
|
router.route('/api/entities/:entityId').get(
|
|
417
651
|
catchAsyncError(async (req, res) => {
|
|
652
|
+
const user = await authenticateUser.execute(req);
|
|
418
653
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
419
|
-
const module = await
|
|
420
|
-
params.entityId,
|
|
421
|
-
getUserId(req)
|
|
422
|
-
);
|
|
654
|
+
const module = await getModule.execute(params.entityId, user); // Pass User object
|
|
423
655
|
|
|
424
|
-
|
|
425
|
-
throw Boom.notFound();
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
res.json(module.entity);
|
|
656
|
+
res.json(module);
|
|
429
657
|
})
|
|
430
658
|
);
|
|
431
659
|
|
|
432
660
|
router.route('/api/entities/:entityId/options').post(
|
|
433
661
|
catchAsyncError(async (req, res) => {
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
662
|
+
const user = await authenticateUser.execute(req);
|
|
663
|
+
const params = checkRequiredParams(req.params, ['entityId']);
|
|
664
|
+
|
|
665
|
+
const entityOptions = await getEntityOptionsById.execute(
|
|
439
666
|
params.entityId,
|
|
440
|
-
|
|
667
|
+
user // Pass User object
|
|
441
668
|
);
|
|
442
669
|
|
|
443
|
-
|
|
444
|
-
throw Boom.notFound();
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
res.json(await module.getEntityOptions());
|
|
670
|
+
res.json(entityOptions);
|
|
448
671
|
})
|
|
449
672
|
);
|
|
450
673
|
|
|
451
674
|
router.route('/api/entities/:entityId/options/refresh').post(
|
|
452
675
|
catchAsyncError(async (req, res) => {
|
|
453
|
-
const
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
]);
|
|
457
|
-
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
676
|
+
const user = await authenticateUser.execute(req);
|
|
677
|
+
const params = checkRequiredParams(req.params, ['entityId']);
|
|
678
|
+
const updatedOptions = await refreshEntityOptions.execute(
|
|
458
679
|
params.entityId,
|
|
459
|
-
|
|
680
|
+
user, // Pass User object
|
|
681
|
+
req.body
|
|
460
682
|
);
|
|
461
683
|
|
|
462
|
-
|
|
463
|
-
throw Boom.notFound();
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
res.json(await module.refreshEntityOptions(req.body));
|
|
684
|
+
res.json(updatedOptions);
|
|
467
685
|
})
|
|
468
686
|
);
|
|
469
687
|
}
|