@friggframework/core 2.0.0--canary.397.e634da9.0 → 2.0.0--canary.398.ad248a6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +50 -931
  2. package/core/create-handler.js +0 -1
  3. package/database/models/WebsocketConnection.js +5 -0
  4. package/handlers/app-handler-helpers.js +3 -0
  5. package/handlers/backend-utils.js +44 -42
  6. package/handlers/routers/auth.js +14 -3
  7. package/handlers/routers/integration-defined-routers.js +5 -8
  8. package/handlers/routers/middleware/loadUser.js +15 -0
  9. package/handlers/routers/middleware/requireLoggedInUser.js +12 -0
  10. package/handlers/routers/user.js +5 -25
  11. package/handlers/workers/integration-defined-workers.js +3 -6
  12. package/index.js +16 -1
  13. package/integrations/create-frigg-backend.js +31 -0
  14. package/integrations/index.js +5 -0
  15. package/integrations/integration-base.js +46 -142
  16. package/integrations/integration-factory.js +251 -0
  17. package/integrations/integration-router.js +178 -301
  18. package/integrations/integration-user.js +144 -0
  19. package/integrations/options.js +1 -1
  20. package/integrations/test/integration-base.test.js +144 -0
  21. package/module-plugin/auther.js +393 -0
  22. package/module-plugin/entity-manager.js +70 -0
  23. package/{modules → module-plugin}/index.js +8 -0
  24. package/module-plugin/manager.js +169 -0
  25. package/module-plugin/module-factory.js +61 -0
  26. package/{modules → module-plugin}/test/mock-api/api.js +3 -8
  27. package/{modules → module-plugin}/test/mock-api/definition.js +8 -12
  28. package/package.json +5 -5
  29. package/syncs/sync.js +1 -0
  30. package/types/integrations/index.d.ts +6 -2
  31. package/types/module-plugin/index.d.ts +56 -4
  32. package/types/syncs/index.d.ts +2 -0
  33. package/credential/credential-repository.js +0 -42
  34. package/credential/use-cases/get-credential-for-user.js +0 -21
  35. package/credential/use-cases/update-authentication-status.js +0 -15
  36. package/handlers/app-definition-loader.js +0 -38
  37. package/integrations/integration-repository.js +0 -80
  38. package/integrations/integration.js +0 -246
  39. package/integrations/tests/doubles/dummy-integration-class.js +0 -90
  40. package/integrations/tests/doubles/test-integration-repository.js +0 -89
  41. package/integrations/tests/use-cases/create-integration.test.js +0 -124
  42. package/integrations/tests/use-cases/delete-integration-for-user.test.js +0 -143
  43. package/integrations/tests/use-cases/get-integration-for-user.test.js +0 -143
  44. package/integrations/tests/use-cases/get-integration-instance.test.js +0 -169
  45. package/integrations/tests/use-cases/get-integrations-for-user.test.js +0 -169
  46. package/integrations/tests/use-cases/get-possible-integrations.test.js +0 -188
  47. package/integrations/tests/use-cases/update-integration-messages.test.js +0 -142
  48. package/integrations/tests/use-cases/update-integration-status.test.js +0 -103
  49. package/integrations/tests/use-cases/update-integration.test.js +0 -134
  50. package/integrations/use-cases/create-integration.js +0 -71
  51. package/integrations/use-cases/delete-integration-for-user.js +0 -72
  52. package/integrations/use-cases/get-integration-for-user.js +0 -78
  53. package/integrations/use-cases/get-integration-instance-by-definition.js +0 -67
  54. package/integrations/use-cases/get-integration-instance.js +0 -82
  55. package/integrations/use-cases/get-integrations-for-user.js +0 -76
  56. package/integrations/use-cases/get-possible-integrations.js +0 -27
  57. package/integrations/use-cases/index.js +0 -11
  58. package/integrations/use-cases/update-integration-messages.js +0 -31
  59. package/integrations/use-cases/update-integration-status.js +0 -28
  60. package/integrations/use-cases/update-integration.js +0 -91
  61. package/integrations/utils/map-integration-dto.js +0 -36
  62. package/modules/module-factory.js +0 -54
  63. package/modules/module-repository.js +0 -107
  64. package/modules/module.js +0 -221
  65. package/modules/tests/doubles/test-module-factory.js +0 -16
  66. package/modules/tests/doubles/test-module-repository.js +0 -19
  67. package/modules/use-cases/get-entities-for-user.js +0 -32
  68. package/modules/use-cases/get-entity-options-by-id.js +0 -58
  69. package/modules/use-cases/get-entity-options-by-type.js +0 -34
  70. package/modules/use-cases/get-module-instance-from-type.js +0 -31
  71. package/modules/use-cases/get-module.js +0 -56
  72. package/modules/use-cases/process-authorization-callback.js +0 -114
  73. package/modules/use-cases/refresh-entity-options.js +0 -58
  74. package/modules/use-cases/test-module-auth.js +0 -54
  75. package/modules/utils/map-module-dto.js +0 -18
  76. package/user/tests/doubles/test-user-repository.js +0 -72
  77. package/user/tests/use-cases/create-individual-user.test.js +0 -24
  78. package/user/tests/use-cases/create-organization-user.test.js +0 -28
  79. package/user/tests/use-cases/create-token-for-user-id.test.js +0 -19
  80. package/user/tests/use-cases/get-user-from-bearer-token.test.js +0 -64
  81. package/user/tests/use-cases/login-user.test.js +0 -140
  82. package/user/use-cases/create-individual-user.js +0 -61
  83. package/user/use-cases/create-organization-user.js +0 -47
  84. package/user/use-cases/create-token-for-user-id.js +0 -30
  85. package/user/use-cases/get-user-from-bearer-token.js +0 -77
  86. package/user/use-cases/login-user.js +0 -122
  87. package/user/user-repository.js +0 -62
  88. package/user/user.js +0 -77
  89. /package/{modules → module-plugin}/ModuleConstants.js +0 -0
  90. /package/{modules → module-plugin}/credential.js +0 -0
  91. /package/{modules → module-plugin}/entity.js +0 -0
  92. /package/{modules → module-plugin}/requester/api-key.js +0 -0
  93. /package/{modules → module-plugin}/requester/basic.js +0 -0
  94. /package/{modules → module-plugin}/requester/oauth-2.js +0 -0
  95. /package/{modules → module-plugin}/requester/requester.js +0 -0
  96. /package/{modules → module-plugin}/requester/requester.test.js +0 -0
  97. /package/{modules → module-plugin}/test/auther.test.js +0 -0
  98. /package/{modules → module-plugin}/test/mock-api/mocks/hubspot.js +0 -0
@@ -34,7 +34,6 @@ const createHandler = (optionByName = {}) => {
34
34
  // Helps mongoose reuse the connection. Lowers response times.
35
35
  context.callbackWaitsForEmptyEventLoop = false;
36
36
 
37
- // todo: this should not be necessary anymore
38
37
  if (shouldUseDatabase) {
39
38
  await connectToDatabase();
40
39
  }
@@ -8,6 +8,11 @@ const schema = new mongoose.Schema({
8
8
  // Add a static method to get active connections
9
9
  schema.statics.getActiveConnections = async function () {
10
10
  try {
11
+ // Return empty array if websockets are not configured
12
+ if (!process.env.WEBSOCKET_API_ENDPOINT) {
13
+ return [];
14
+ }
15
+
11
16
  const connections = await this.find({}, 'connectionId');
12
17
  return connections.map((conn) => ({
13
18
  connectionId: conn.connectionId,
@@ -3,6 +3,7 @@ const express = require('express');
3
3
  const bodyParser = require('body-parser');
4
4
  const cors = require('cors');
5
5
  const Boom = require('@hapi/boom');
6
+ const loadUserManager = require('./routers/middleware/loadUser');
6
7
  const serverlessHttp = require('serverless-http');
7
8
 
8
9
  const createApp = (applyMiddleware) => {
@@ -19,6 +20,8 @@ const createApp = (applyMiddleware) => {
19
20
  })
20
21
  );
21
22
 
23
+ app.use(loadUserManager);
24
+
22
25
  if (applyMiddleware) applyMiddleware(app);
23
26
 
24
27
  // Handle sending error response and logging server errors to console
@@ -1,35 +1,36 @@
1
+ const { createFriggBackend, Worker } = require('@friggframework/core');
2
+ const { findNearestBackendPackageJson } = require('@friggframework/core/utils');
3
+ const path = require('node:path');
4
+ const fs = require('fs-extra');
5
+
6
+ const backendPath = findNearestBackendPackageJson();
7
+ if (!backendPath) {
8
+ throw new Error('Could not find backend package.json');
9
+ }
10
+
11
+ const backendDir = path.dirname(backendPath);
12
+ const backendFilePath = path.join(backendDir, 'index.js');
13
+ if (!fs.existsSync(backendFilePath)) {
14
+ throw new Error('Could not find index.js');
15
+ }
16
+
17
+ const backendJsFile = require(backendFilePath);
1
18
  const { Router } = require('express');
2
- const { Worker } = require('@friggframework/core');
3
- const { IntegrationRepository } = require('../integrations/integration-repository');
4
- const { ModuleFactory } = require('../modules/module-factory');
5
- const { getModulesDefinitionFromIntegrationClasses } = require('../integrations/utils/map-integration-dto');
6
- const { ModuleRepository } = require('../modules/module-repository');
7
- const { GetIntegrationInstanceByDefinition } = require('../integrations/use-cases/get-integration-instance-by-definition');
19
+ const appDefinition = backendJsFile.Definition;
8
20
 
21
+ const backend = createFriggBackend(appDefinition);
9
22
  const loadRouterFromObject = (IntegrationClass, routerObject) => {
10
-
11
- const integrationRepository = new IntegrationRepository();
12
- const moduleRepository = new ModuleRepository();
13
- const moduleFactory = new ModuleFactory({
14
- moduleRepository,
15
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses([IntegrationClass]),
16
- });
17
23
  const router = Router();
18
24
  const { path, method, event } = routerObject;
19
-
20
25
  console.log(
21
26
  `Registering ${method} ${path} for ${IntegrationClass.Definition.name}`
22
27
  );
23
-
24
28
  router[method.toLowerCase()](path, async (req, res, next) => {
25
29
  try {
26
- const getIntegrationInstanceByDefinition = new GetIntegrationInstanceByDefinition({
27
- integrationRepository,
28
- moduleFactory,
29
- moduleRepository,
30
- });
31
- const integration = await getIntegrationInstanceByDefinition.execute(IntegrationClass);
32
- const result = await integration.send(event, { req, res, next });
30
+ const integration = new IntegrationClass({});
31
+ await integration.loadModules();
32
+ await integration.registerEventHandlers();
33
+ const result = await integration.send(event, {req, res, next});
33
34
  res.json(result);
34
35
  } catch (error) {
35
36
  next(error);
@@ -38,29 +39,29 @@ const loadRouterFromObject = (IntegrationClass, routerObject) => {
38
39
 
39
40
  return router;
40
41
  };
41
-
42
- //todo: this should be in a use case class
43
- const createQueueWorker = (integrationClass) => {
42
+ const createQueueWorker = (integrationClass, integrationFactory) => {
44
43
  class QueueWorker extends Worker {
45
-
46
- integrationRepository = new IntegrationRepository();
47
- moduleRepository = new ModuleRepository();
48
- moduleFactory = new ModuleFactory({
49
- moduleRepository: this.moduleRepository,
50
- moduleDefinitions: getModulesDefinitionFromIntegrationClasses([integrationClass]),
51
- });
52
-
53
44
  async _run(params, context) {
54
45
  try {
55
- const getIntegrationInstanceByDefinition = new GetIntegrationInstanceByDefinition({
56
- integrationRepository: this.integrationRepository,
57
- moduleFactory: this.moduleFactory,
58
- moduleRepository: this.moduleRepository,
59
- });
60
-
61
- const integration = await getIntegrationInstanceByDefinition.execute(integrationClass);
62
-
63
- const res = await integration.send(params.event, {
46
+ let instance;
47
+ if (!params.integrationId) {
48
+ instance = new integrationClass({});
49
+ await instance.loadModules();
50
+ // await instance.loadUserActions();
51
+ await instance.registerEventHandlers();
52
+ console.log(
53
+ `${params.event} for ${integrationClass.Definition.name} integration with no integrationId`
54
+ );
55
+ } else {
56
+ instance =
57
+ await integrationFactory.getInstanceFromIntegrationId({
58
+ integrationId: params.integrationId,
59
+ });
60
+ console.log(
61
+ `${params.event} for ${instance.record.config.type} of integrationId: ${params.integrationId}`
62
+ );
63
+ }
64
+ const res = await instance.send(params.event, {
64
65
  data: params.data,
65
66
  context,
66
67
  });
@@ -78,6 +79,7 @@ const createQueueWorker = (integrationClass) => {
78
79
  };
79
80
 
80
81
  module.exports = {
82
+ ...backend,
81
83
  loadRouterFromObject,
82
84
  createQueueWorker,
83
85
  };
@@ -1,15 +1,26 @@
1
1
  const { createIntegrationRouter } = require('@friggframework/core');
2
2
  const { createAppHandler } = require('./../app-handler-helpers');
3
+ const { requireLoggedInUser } = require('./middleware/requireLoggedInUser');
4
+ const {
5
+ moduleFactory,
6
+ integrationFactory,
7
+ IntegrationHelper,
8
+ } = require('./../backend-utils');
3
9
 
4
- const router = createIntegrationRouter();
10
+ const router = createIntegrationRouter({
11
+ factory: { moduleFactory, integrationFactory, IntegrationHelper },
12
+ requireLoggedInUser,
13
+ getUserId: (req) => req.user.getUserId(),
14
+ });
5
15
 
6
16
  router.route('/redirect/:appId').get((req, res) => {
7
17
  res.redirect(
8
- `${process.env.FRONTEND_URI}/redirect/${req.params.appId
18
+ `${process.env.FRONTEND_URI}/redirect/${
19
+ req.params.appId
9
20
  }?${new URLSearchParams(req.query)}`
10
21
  );
11
22
  });
12
23
 
13
24
  const handler = createAppHandler('HTTP Event: Auth', router);
14
25
 
15
- module.exports = { handler };
26
+ module.exports = { handler, router };
@@ -1,18 +1,15 @@
1
1
  const { createAppHandler } = require('./../app-handler-helpers');
2
2
  const {
3
- loadAppDefinition,
4
- } = require('../app-definition-loader');
3
+ integrationFactory,
4
+ loadRouterFromObject,
5
+ } = require('./../backend-utils');
5
6
  const { Router } = require('express');
6
- const { loadRouterFromObject } = require('../backend-utils');
7
7
 
8
8
  const handlers = {};
9
- const { integrations: integrationClasses } = loadAppDefinition();
10
-
11
- //todo: this should be in a use case class
12
- for (const IntegrationClass of integrationClasses) {
9
+ for (const IntegrationClass of integrationFactory.integrationClasses) {
13
10
  const router = Router();
14
11
  const basePath = `/api/${IntegrationClass.Definition.name}-integration`;
15
-
12
+
16
13
  console.log(`\n│ Configuring routes for ${IntegrationClass.Definition.name} Integration:`);
17
14
 
18
15
  for (const routeDef of IntegrationClass.Definition.routes) {
@@ -0,0 +1,15 @@
1
+ const catchAsyncError = require('express-async-handler');
2
+ const { User } = require('../../backend-utils');
3
+
4
+ module.exports = catchAsyncError(async (req, res, next) => {
5
+ const authorizationHeader = req.headers.authorization;
6
+
7
+ if (authorizationHeader) {
8
+ // Removes "Bearer " and trims
9
+ const token = authorizationHeader.split(' ')[1].trim();
10
+ // Load user for later middleware/routes to use
11
+ req.user = await User.newUser({ token });
12
+ }
13
+
14
+ return next();
15
+ });
@@ -0,0 +1,12 @@
1
+ const Boom = require('@hapi/boom');
2
+
3
+ // CheckLoggedIn Middleware
4
+ const requireLoggedInUser = (req, res, next) => {
5
+ if (!req.user || !req.user.isLoggedIn()) {
6
+ throw Boom.unauthorized('Invalid Token');
7
+ }
8
+
9
+ next();
10
+ };
11
+
12
+ module.exports = { requireLoggedInUser };
@@ -1,29 +1,10 @@
1
1
  const express = require('express');
2
2
  const { createAppHandler } = require('../app-handler-helpers');
3
3
  const { checkRequiredParams } = require('@friggframework/core');
4
- const { UserRepository } = require('../../user/user-repository');
5
- const {
6
- CreateIndividualUser,
7
- } = require('../../user/use-cases/create-individual-user');
8
- const { LoginUser } = require('../../user/use-cases/login-user');
9
- const {
10
- CreateTokenForUserId,
11
- } = require('../../user/use-cases/create-token-for-user-id');
4
+ const { User } = require('../backend-utils');
12
5
  const catchAsyncError = require('express-async-handler');
13
- const { loadAppDefinition } = require('../app-definition-loader');
14
6
 
15
7
  const router = express();
16
- const { userConfig } = loadAppDefinition();
17
- const userRepository = new UserRepository({ userConfig });
18
- const createIndividualUser = new CreateIndividualUser({
19
- userRepository,
20
- userConfig,
21
- });
22
- const loginUser = new LoginUser({
23
- userRepository,
24
- userConfig,
25
- });
26
- const createTokenForUserId = new CreateTokenForUserId({ userRepository });
27
8
 
28
9
  // define the login endpoint
29
10
  router.route('/user/login').post(
@@ -32,8 +13,8 @@ router.route('/user/login').post(
32
13
  'username',
33
14
  'password',
34
15
  ]);
35
- const user = await loginUser.execute({ username, password });
36
- const token = await createTokenForUserId.execute(user.getId(), 120);
16
+ const user = await User.loginUser({ username, password });
17
+ const token = await user.createUserToken(120);
37
18
  res.status(201);
38
19
  res.json({ token });
39
20
  })
@@ -45,12 +26,11 @@ router.route('/user/create').post(
45
26
  'username',
46
27
  'password',
47
28
  ]);
48
-
49
- const user = await createIndividualUser.execute({
29
+ const user = await User.createIndividualUser({
50
30
  username,
51
31
  password,
52
32
  });
53
- const token = await createTokenForUserId.execute(user.getId(), 120);
33
+ const token = await user.createUserToken(120);
54
34
  res.status(201);
55
35
  res.json({ token });
56
36
  })
@@ -1,12 +1,9 @@
1
1
  const { createHandler } = require('@friggframework/core');
2
- const { loadAppDefinition } = require('../app-definition-loader');
3
- const { createQueueWorker } = require('../backend-utils');
2
+ const { integrationFactory, createQueueWorker } = require('../backend-utils');
4
3
 
5
4
  const handlers = {};
6
- const { integrations: integrationClasses } = loadAppDefinition();
7
-
8
- integrationClasses.forEach((IntegrationClass) => {
9
- const defaultQueueWorker = createQueueWorker(IntegrationClass);
5
+ integrationFactory.integrationClasses.forEach((IntegrationClass) => {
6
+ const defaultQueueWorker = createQueueWorker(IntegrationClass, integrationFactory);
10
7
 
11
8
  handlers[`${IntegrationClass.Definition.name}`] = {
12
9
  queueWorker: createHandler({
package/index.js CHANGED
@@ -38,20 +38,27 @@ const {
38
38
  IntegrationModel,
39
39
  Options,
40
40
  IntegrationMapping,
41
+ IntegrationFactory,
42
+ IntegrationHelper,
41
43
  createIntegrationRouter,
42
44
  checkRequiredParams,
45
+ createFriggBackend,
43
46
  } = require('./integrations/index');
44
47
  const { TimeoutCatcher } = require('./lambda/index');
45
48
  const { debug, initDebugLog, flushDebugLog } = require('./logs/index');
46
49
  const {
47
50
  Credential,
51
+ EntityManager,
48
52
  Entity,
53
+ ModuleManager,
49
54
  ApiKeyRequester,
50
55
  BasicAuthRequester,
51
56
  OAuth2Requester,
52
57
  Requester,
53
58
  ModuleConstants,
54
- } = require('./modules/index');
59
+ ModuleFactory,
60
+ Auther,
61
+ } = require('./module-plugin/index');
55
62
  const utils = require('./utils');
56
63
 
57
64
  // const {Sync } = require('./syncs/model');
@@ -102,8 +109,11 @@ module.exports = {
102
109
  IntegrationModel,
103
110
  Options,
104
111
  IntegrationMapping,
112
+ IntegrationFactory,
113
+ IntegrationHelper,
105
114
  checkRequiredParams,
106
115
  createIntegrationRouter,
116
+ createFriggBackend,
107
117
 
108
118
  // lambda
109
119
  TimeoutCatcher,
@@ -115,12 +125,17 @@ module.exports = {
115
125
 
116
126
  // module plugin
117
127
  Credential,
128
+ EntityManager,
118
129
  Entity,
130
+ ModuleManager,
119
131
  ApiKeyRequester,
120
132
  BasicAuthRequester,
121
133
  OAuth2Requester,
122
134
  Requester,
123
135
  ModuleConstants,
136
+ ModuleFactory,
137
+ Auther,
138
+
124
139
  // queues
125
140
  QueuerUtil,
126
141
 
@@ -0,0 +1,31 @@
1
+ const {IntegrationFactory, IntegrationHelper} = require('./integration-factory');
2
+ const User = require('./integration-user');
3
+
4
+ function createFriggBackend(appDefinition) {
5
+ const {integrations = [], user=null} = appDefinition
6
+ const integrationFactory = new IntegrationFactory(integrations);
7
+ if (user) {
8
+ if (user.usePassword) {
9
+ User.usePassword = true;
10
+ }
11
+ if (user.primary === 'organization') {
12
+ User.primary = User.OrganizationUser
13
+ }
14
+ if (user.individualUserRequired !== undefined) {
15
+ User.individualUserRequired = user.individualUserRequired
16
+ }
17
+ if (user.organizationUserRequired !== undefined) {
18
+ User.organizationUserRequired = user.organizationUserRequired
19
+ }
20
+
21
+ }
22
+ const backend = {
23
+ integrationFactory,
24
+ moduleFactory: integrationFactory.moduleFactory,
25
+ IntegrationHelper,
26
+ User: User
27
+ }
28
+ return backend
29
+ }
30
+
31
+ module.exports = { createFriggBackend }
@@ -2,13 +2,18 @@ const { IntegrationBase } = require('./integration-base');
2
2
  const { IntegrationModel } = require('./integration-model');
3
3
  const { Options } = require('./options');
4
4
  const { IntegrationMapping } = require('./integration-mapping');
5
+ const { IntegrationFactory, IntegrationHelper } = require('./integration-factory');
5
6
  const { createIntegrationRouter, checkRequiredParams } = require('./integration-router');
7
+ const { createFriggBackend } = require('./create-frigg-backend');
6
8
 
7
9
  module.exports = {
8
10
  IntegrationBase,
9
11
  IntegrationModel,
10
12
  Options,
11
13
  IntegrationMapping,
14
+ IntegrationFactory,
15
+ IntegrationHelper,
12
16
  createIntegrationRouter,
13
17
  checkRequiredParams,
18
+ createFriggBackend
14
19
  };