@friggframework/core 2.0.0-next.1 → 2.0.0-next.100
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 +57 -0
- package/handlers/backend-utils.js +316 -0
- 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 +15 -0
- 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 +117 -0
- package/handlers/routers/integration-webhook-routers.js +67 -0
- package/handlers/routers/reporting.js +9 -0
- package/handlers/routers/user.js +63 -0
- package/handlers/routers/websocket.js +57 -0
- 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 +30 -0
- package/index.js +111 -50
- 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 +619 -72
- package/integrations/integration-router.js +460 -218
- package/integrations/options.js +3 -4
- 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 +274 -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 +285 -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/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 -350
- 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,19 +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
|
-
|
|
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
|
+
});
|
|
18
219
|
return router;
|
|
19
220
|
}
|
|
20
221
|
|
|
@@ -42,182 +243,206 @@ function checkRequiredParams(params, requiredKeys) {
|
|
|
42
243
|
return returnDict;
|
|
43
244
|
}
|
|
44
245
|
|
|
45
|
-
|
|
46
|
-
|
|
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;
|
|
47
262
|
router.route('/api/integrations').get(
|
|
48
263
|
catchAsyncError(async (req, res) => {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
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
|
+
};
|
|
56
274
|
|
|
57
|
-
for (const integrationRecord of results.integrations) {
|
|
58
|
-
const integration = await integrationFactory.getInstanceFromIntegrationId({
|
|
59
|
-
integrationId: integrationRecord.id,
|
|
60
|
-
userId: getUserId(req),
|
|
61
|
-
});
|
|
62
|
-
integrationRecord.userActions = integration.userActions;
|
|
63
|
-
}
|
|
64
275
|
res.json(results);
|
|
65
276
|
})
|
|
66
277
|
);
|
|
67
278
|
|
|
68
279
|
router.route('/api/integrations').post(
|
|
69
280
|
catchAsyncError(async (req, res) => {
|
|
281
|
+
const user = await authenticateUser.execute(req);
|
|
282
|
+
const userId = user.getId();
|
|
70
283
|
const params = checkRequiredParams(req.body, [
|
|
71
284
|
'entities',
|
|
72
285
|
'config',
|
|
73
286
|
]);
|
|
74
|
-
// throw if not value
|
|
75
|
-
get(params.config, 'type');
|
|
76
287
|
|
|
77
|
-
|
|
78
|
-
const integration =
|
|
79
|
-
await integrationFactory.createIntegration(
|
|
80
|
-
params.entities,
|
|
81
|
-
getUserId(req),
|
|
82
|
-
params.config,
|
|
83
|
-
);
|
|
288
|
+
get(params.config, 'type');
|
|
84
289
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
290
|
+
const integration = await createIntegration.execute(
|
|
291
|
+
params.entities,
|
|
292
|
+
userId,
|
|
293
|
+
params.config
|
|
88
294
|
);
|
|
89
|
-
await integration.onCreate();
|
|
90
295
|
|
|
91
|
-
res.status(201).json(
|
|
92
|
-
await IntegrationHelper.getFormattedIntegration(integration.record)
|
|
93
|
-
);
|
|
296
|
+
res.status(201).json(integration);
|
|
94
297
|
})
|
|
95
298
|
);
|
|
96
299
|
|
|
97
300
|
router.route('/api/integrations/:integrationId').patch(
|
|
98
301
|
catchAsyncError(async (req, res) => {
|
|
302
|
+
const user = await authenticateUser.execute(req);
|
|
303
|
+
const userId = user.getId();
|
|
99
304
|
const params = checkRequiredParams(req.body, ['config']);
|
|
100
305
|
|
|
101
|
-
const integration =
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
debug(
|
|
108
|
-
`Calling onUpdate on the ${integration?.constructor?.Config?.name} Integration arguments: `,
|
|
109
|
-
params
|
|
110
|
-
);
|
|
111
|
-
await integration.onUpdate(params);
|
|
112
|
-
|
|
113
|
-
res.json(
|
|
114
|
-
await IntegrationHelper.getFormattedIntegration(integration.record)
|
|
306
|
+
const integration = await updateIntegration.execute(
|
|
307
|
+
req.params.integrationId,
|
|
308
|
+
userId,
|
|
309
|
+
params.config
|
|
115
310
|
);
|
|
311
|
+
res.json(integration);
|
|
116
312
|
})
|
|
117
313
|
);
|
|
118
314
|
|
|
119
315
|
router.route('/api/integrations/:integrationId').delete(
|
|
120
316
|
catchAsyncError(async (req, res) => {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
userId: getUserId(req),
|
|
127
|
-
integrationId: params.integrationId,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
debug(
|
|
131
|
-
`Calling onUpdate on the ${integration?.constructor?.Config?.name} Integration with no arguments`
|
|
317
|
+
const user = await authenticateUser.execute(req);
|
|
318
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
319
|
+
await deleteIntegrationForUser.execute(
|
|
320
|
+
params.integrationId,
|
|
321
|
+
user.getId()
|
|
132
322
|
);
|
|
133
|
-
|
|
134
|
-
await IntegrationHelper.deleteIntegrationForUserById(
|
|
135
|
-
getUserId(req),
|
|
136
|
-
params.integrationId
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
res.status(201).json({});
|
|
323
|
+
res.status(204).json({});
|
|
140
324
|
})
|
|
141
325
|
);
|
|
142
326
|
|
|
143
327
|
router.route('/api/integrations/:integrationId/config/options').get(
|
|
144
328
|
catchAsyncError(async (req, res) => {
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
329
|
+
const user = await authenticateUser.execute(req);
|
|
330
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
331
|
+
const integration = await getIntegrationInstance.execute(
|
|
332
|
+
params.integrationId,
|
|
333
|
+
user.getId()
|
|
334
|
+
);
|
|
335
|
+
res.json(await integration.send('GET_CONFIG_OPTIONS'));
|
|
151
336
|
})
|
|
152
337
|
);
|
|
153
338
|
|
|
154
|
-
router
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
339
|
+
router
|
|
340
|
+
.route('/api/integrations/:integrationId/config/options/refresh')
|
|
341
|
+
.post(
|
|
342
|
+
catchAsyncError(async (req, res) => {
|
|
343
|
+
const user = await authenticateUser.execute(req);
|
|
344
|
+
const params = checkRequiredParams(req.params, [
|
|
345
|
+
'integrationId',
|
|
346
|
+
]);
|
|
347
|
+
const integration = await getIntegrationInstance.execute(
|
|
348
|
+
params.integrationId,
|
|
349
|
+
user.getId()
|
|
350
|
+
);
|
|
161
351
|
|
|
162
|
-
|
|
163
|
-
|
|
352
|
+
res.json(
|
|
353
|
+
await integration.send('REFRESH_CONFIG_OPTIONS', req.body)
|
|
354
|
+
);
|
|
355
|
+
})
|
|
356
|
+
);
|
|
357
|
+
router.route('/api/integrations/:integrationId/actions').all(
|
|
358
|
+
catchAsyncError(async (req, res) => {
|
|
359
|
+
const user = await authenticateUser.execute(req);
|
|
360
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
361
|
+
const integration = await getIntegrationInstance.execute(
|
|
362
|
+
params.integrationId,
|
|
363
|
+
user.getId()
|
|
164
364
|
);
|
|
365
|
+
res.json(await integration.send('GET_USER_ACTIONS', req.body));
|
|
165
366
|
})
|
|
166
367
|
);
|
|
167
368
|
|
|
168
|
-
router
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
369
|
+
router
|
|
370
|
+
.route('/api/integrations/:integrationId/actions/:actionId/options')
|
|
371
|
+
.all(
|
|
372
|
+
catchAsyncError(async (req, res) => {
|
|
373
|
+
const user = await authenticateUser.execute(req);
|
|
374
|
+
const params = checkRequiredParams(req.params, [
|
|
375
|
+
'integrationId',
|
|
376
|
+
'actionId',
|
|
377
|
+
]);
|
|
378
|
+
const integration = await getIntegrationInstance.execute(
|
|
379
|
+
params.integrationId,
|
|
380
|
+
user.getId()
|
|
381
|
+
);
|
|
176
382
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
383
|
+
res.json(
|
|
384
|
+
await integration.send('GET_USER_ACTION_OPTIONS', {
|
|
385
|
+
actionId: params.actionId,
|
|
386
|
+
data: req.body,
|
|
387
|
+
})
|
|
388
|
+
);
|
|
389
|
+
})
|
|
390
|
+
);
|
|
182
391
|
|
|
183
|
-
router
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
392
|
+
router
|
|
393
|
+
.route(
|
|
394
|
+
'/api/integrations/:integrationId/actions/:actionId/options/refresh'
|
|
395
|
+
)
|
|
396
|
+
.post(
|
|
397
|
+
catchAsyncError(async (req, res) => {
|
|
398
|
+
const user = await authenticateUser.execute(req);
|
|
399
|
+
const params = checkRequiredParams(req.params, [
|
|
400
|
+
'integrationId',
|
|
401
|
+
'actionId',
|
|
402
|
+
]);
|
|
403
|
+
const integration = await getIntegrationInstance.execute(
|
|
404
|
+
params.integrationId,
|
|
405
|
+
user.getId()
|
|
406
|
+
);
|
|
191
407
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
408
|
+
res.json(
|
|
409
|
+
await integration.send('REFRESH_USER_ACTION_OPTIONS', {
|
|
410
|
+
actionId: params.actionId,
|
|
411
|
+
data: req.body,
|
|
412
|
+
})
|
|
413
|
+
);
|
|
414
|
+
})
|
|
415
|
+
);
|
|
197
416
|
|
|
198
417
|
router.route('/api/integrations/:integrationId/actions/:actionId').post(
|
|
199
418
|
catchAsyncError(async (req, res) => {
|
|
419
|
+
const user = await authenticateUser.execute(req);
|
|
200
420
|
const params = checkRequiredParams(req.params, [
|
|
201
421
|
'integrationId',
|
|
202
|
-
'actionId'
|
|
422
|
+
'actionId',
|
|
203
423
|
]);
|
|
204
|
-
const integration =
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
res.json(
|
|
208
|
-
await integration.notify(params.actionId, req.body)
|
|
424
|
+
const integration = await getIntegrationInstance.execute(
|
|
425
|
+
params.integrationId,
|
|
426
|
+
user.getId()
|
|
209
427
|
);
|
|
428
|
+
res.json(await integration.send(params.actionId, req.body));
|
|
210
429
|
})
|
|
211
430
|
);
|
|
212
431
|
|
|
213
432
|
router.route('/api/integrations/:integrationId').get(
|
|
214
433
|
catchAsyncError(async (req, res) => {
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
434
|
+
const user = await authenticateUser.execute(req);
|
|
435
|
+
|
|
436
|
+
if (!user) {
|
|
437
|
+
throw Boom.forbidden('User not found');
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
441
|
+
const integration = await getIntegrationInstance.execute(
|
|
442
|
+
params.integrationId,
|
|
443
|
+
user.getId()
|
|
220
444
|
);
|
|
445
|
+
|
|
221
446
|
// We could perhaps augment router with dynamic options? Haven't decided yet, but here may be the place
|
|
222
447
|
|
|
223
448
|
res.json({
|
|
@@ -231,20 +456,20 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
231
456
|
|
|
232
457
|
router.route('/api/integrations/:integrationId/test-auth').get(
|
|
233
458
|
catchAsyncError(async (req, res) => {
|
|
234
|
-
const
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
});
|
|
459
|
+
const user = await authenticateUser.execute(req);
|
|
460
|
+
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
461
|
+
const instance = await getIntegrationInstance.execute(
|
|
462
|
+
params.integrationId,
|
|
463
|
+
user.getId()
|
|
464
|
+
);
|
|
241
465
|
|
|
242
466
|
if (!instance) {
|
|
243
467
|
throw Boom.notFound();
|
|
244
468
|
}
|
|
245
469
|
|
|
246
470
|
const start = Date.now();
|
|
247
|
-
await instance.testAuth();
|
|
471
|
+
const authPassed = await instance.testAuth();
|
|
472
|
+
await instance.reconcileAuthStatus(authPassed);
|
|
248
473
|
const errors = instance.record.messages?.errors?.filter(
|
|
249
474
|
({ timestamp }) => timestamp >= start
|
|
250
475
|
);
|
|
@@ -259,56 +484,88 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
259
484
|
);
|
|
260
485
|
}
|
|
261
486
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
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;
|
|
274
503
|
|
|
275
504
|
router.route('/api/authorize').get(
|
|
276
505
|
catchAsyncError(async (req, res) => {
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
]);
|
|
280
|
-
const module = await
|
|
506
|
+
const user = await authenticateUser.execute(req);
|
|
507
|
+
const userId = user.getId();
|
|
508
|
+
const params = checkRequiredParams(req.query, ['entityType']);
|
|
509
|
+
const module = await getModuleInstanceFromType.execute(
|
|
510
|
+
userId,
|
|
511
|
+
params.entityType,
|
|
512
|
+
{ state: req.query.state }
|
|
513
|
+
);
|
|
281
514
|
const areRequirementsValid =
|
|
282
515
|
module.validateAuthorizationRequirements();
|
|
283
516
|
if (!areRequirementsValid) {
|
|
284
517
|
throw new Error(
|
|
285
|
-
`Error:
|
|
518
|
+
`Error: Entity of type ${params.entityType} requires a valid url`
|
|
286
519
|
);
|
|
287
520
|
}
|
|
288
521
|
|
|
289
|
-
res.json(
|
|
522
|
+
res.json(module.getAuthorizationRequirements());
|
|
290
523
|
})
|
|
291
524
|
);
|
|
292
525
|
|
|
293
526
|
router.route('/api/authorize').post(
|
|
294
527
|
catchAsyncError(async (req, res) => {
|
|
528
|
+
const user = await authenticateUser.execute(req);
|
|
529
|
+
const userId = user.getId();
|
|
295
530
|
const params = checkRequiredParams(req.body, [
|
|
296
531
|
'entityType',
|
|
297
532
|
'data',
|
|
298
533
|
]);
|
|
299
|
-
const module = await getModuleInstance(req, params.entityType);
|
|
300
534
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
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)}`
|
|
306
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
|
+
}
|
|
307
562
|
})
|
|
308
563
|
);
|
|
309
564
|
|
|
310
565
|
router.route('/api/entity').post(
|
|
311
566
|
catchAsyncError(async (req, res) => {
|
|
567
|
+
const user = await authenticateUser.execute(req);
|
|
568
|
+
const userId = user.getId();
|
|
312
569
|
const params = checkRequiredParams(req.body, [
|
|
313
570
|
'entityType',
|
|
314
571
|
'data',
|
|
@@ -316,130 +573,115 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
316
573
|
checkRequiredParams(req.body.data, ['credential_id']);
|
|
317
574
|
|
|
318
575
|
// May want to pass along the user ID as well so credential ID's can't be fished???
|
|
319
|
-
const credential = await
|
|
320
|
-
params.data.credential_id
|
|
576
|
+
const credential = await getCredentialForUser.execute(
|
|
577
|
+
params.data.credential_id,
|
|
578
|
+
userId
|
|
321
579
|
);
|
|
322
580
|
|
|
323
581
|
if (!credential) {
|
|
324
582
|
throw Boom.badRequest('Invalid credential ID');
|
|
325
583
|
}
|
|
326
584
|
|
|
327
|
-
const module = await
|
|
585
|
+
const module = await getModuleInstanceFromType.execute(
|
|
586
|
+
userId,
|
|
587
|
+
params.entityType
|
|
588
|
+
);
|
|
328
589
|
const entityDetails = await module.getEntityDetails(
|
|
329
590
|
module.api,
|
|
330
591
|
null,
|
|
331
592
|
null,
|
|
332
|
-
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
res.json(
|
|
336
|
-
await module.findOrCreateEntity(entityDetails)
|
|
593
|
+
userId
|
|
337
594
|
);
|
|
595
|
+
|
|
596
|
+
res.json(await module.findOrCreateEntity(entityDetails));
|
|
338
597
|
})
|
|
339
598
|
);
|
|
340
599
|
|
|
341
600
|
router.route('/api/entity/options/:credentialId').get(
|
|
342
601
|
catchAsyncError(async (req, res) => {
|
|
602
|
+
const user = await authenticateUser.execute(req);
|
|
603
|
+
const userId = user.getId();
|
|
343
604
|
// TODO May want to pass along the user ID as well so credential ID's can't be fished???
|
|
344
605
|
// TODO **flagging this for review** -MW
|
|
345
|
-
const credential = await
|
|
346
|
-
req.params.credentialId
|
|
606
|
+
const credential = await getCredentialForUser.execute(
|
|
607
|
+
req.params.credentialId,
|
|
608
|
+
userId
|
|
347
609
|
);
|
|
348
|
-
if (credential.
|
|
610
|
+
if (credential.userId.toString() !== userId) {
|
|
349
611
|
throw Boom.forbidden('Credential does not belong to user');
|
|
350
612
|
}
|
|
351
613
|
|
|
352
|
-
const params = checkRequiredParams(req.query, [
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
614
|
+
const params = checkRequiredParams(req.query, ['entityType']);
|
|
615
|
+
const entityOptions = await getEntityOptionsByType.execute(
|
|
616
|
+
userId,
|
|
617
|
+
params.entityType
|
|
618
|
+
);
|
|
356
619
|
|
|
357
|
-
res.json(
|
|
620
|
+
res.json(entityOptions);
|
|
358
621
|
})
|
|
359
622
|
);
|
|
360
623
|
|
|
361
624
|
router.route('/api/entities/:entityId/test-auth').get(
|
|
362
625
|
catchAsyncError(async (req, res) => {
|
|
626
|
+
const user = await authenticateUser.execute(req);
|
|
363
627
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
364
|
-
const
|
|
628
|
+
const testAuthResponse = await testModuleAuth.execute(
|
|
365
629
|
params.entityId,
|
|
366
|
-
|
|
630
|
+
user // Pass User object for proper validation
|
|
367
631
|
);
|
|
368
632
|
|
|
369
|
-
if (!module) {
|
|
370
|
-
throw Boom.notFound();
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const testAuthResponse = await module.testAuth();
|
|
374
|
-
|
|
375
633
|
if (!testAuthResponse) {
|
|
376
634
|
res.status(400);
|
|
377
635
|
res.json({
|
|
378
636
|
errors: [
|
|
379
637
|
{
|
|
380
638
|
title: 'Authentication Error',
|
|
381
|
-
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.`,
|
|
382
640
|
timestamp: Date.now(),
|
|
383
641
|
},
|
|
384
642
|
],
|
|
385
643
|
});
|
|
386
644
|
} else {
|
|
387
|
-
res.json({status: 'ok'});
|
|
645
|
+
res.json({ status: 'ok' });
|
|
388
646
|
}
|
|
389
647
|
})
|
|
390
648
|
);
|
|
391
649
|
|
|
392
650
|
router.route('/api/entities/:entityId').get(
|
|
393
651
|
catchAsyncError(async (req, res) => {
|
|
652
|
+
const user = await authenticateUser.execute(req);
|
|
394
653
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
395
|
-
const module = await
|
|
396
|
-
params.entityId,
|
|
397
|
-
getUserId(req)
|
|
398
|
-
);
|
|
399
|
-
|
|
400
|
-
if (!module) {
|
|
401
|
-
throw Boom.notFound();
|
|
402
|
-
}
|
|
654
|
+
const module = await getModule.execute(params.entityId, user); // Pass User object
|
|
403
655
|
|
|
404
|
-
res.json(module
|
|
656
|
+
res.json(module);
|
|
405
657
|
})
|
|
406
658
|
);
|
|
407
659
|
|
|
408
660
|
router.route('/api/entities/:entityId/options').post(
|
|
409
661
|
catchAsyncError(async (req, res) => {
|
|
410
|
-
const
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
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(
|
|
415
666
|
params.entityId,
|
|
416
|
-
|
|
667
|
+
user // Pass User object
|
|
417
668
|
);
|
|
418
669
|
|
|
419
|
-
|
|
420
|
-
throw Boom.notFound();
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
res.json(await module.getEntityOptions());
|
|
670
|
+
res.json(entityOptions);
|
|
424
671
|
})
|
|
425
672
|
);
|
|
426
673
|
|
|
427
674
|
router.route('/api/entities/:entityId/options/refresh').post(
|
|
428
675
|
catchAsyncError(async (req, res) => {
|
|
429
|
-
const
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
]);
|
|
433
|
-
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(
|
|
434
679
|
params.entityId,
|
|
435
|
-
|
|
680
|
+
user, // Pass User object
|
|
681
|
+
req.body
|
|
436
682
|
);
|
|
437
683
|
|
|
438
|
-
|
|
439
|
-
throw Boom.notFound();
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
res.json(await module.refreshEntityOptions(req.body));
|
|
684
|
+
res.json(updatedOptions);
|
|
443
685
|
})
|
|
444
686
|
);
|
|
445
687
|
}
|