@friggframework/core 2.0.0--canary.405.1f6792c.0 → 2.0.0--canary.396.6862738.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 (59) hide show
  1. package/credential/credential-repository.js +9 -0
  2. package/credential/use-cases/get-credential-for-user.js +21 -0
  3. package/encrypt/encrypt.js +27 -4
  4. package/handlers/app-definition-loader.js +38 -0
  5. package/handlers/app-handler-helpers.js +0 -3
  6. package/handlers/backend-utils.js +29 -34
  7. package/handlers/routers/auth.js +14 -11
  8. package/handlers/routers/integration-defined-routers.js +8 -5
  9. package/handlers/routers/user.js +25 -5
  10. package/handlers/workers/integration-defined-workers.js +6 -3
  11. package/index.js +0 -11
  12. package/integrations/index.js +0 -5
  13. package/integrations/integration-base.js +10 -7
  14. package/integrations/integration-repository.js +44 -0
  15. package/integrations/integration-router.js +230 -132
  16. package/integrations/integration.js +233 -0
  17. package/integrations/options.js +1 -1
  18. package/integrations/use-cases/create-integration.js +58 -0
  19. package/integrations/use-cases/delete-integration-for-user.js +53 -0
  20. package/integrations/use-cases/get-integration-for-user.js +63 -0
  21. package/integrations/use-cases/get-integration-instance.js +73 -0
  22. package/integrations/use-cases/get-integrations-for-user.js +64 -0
  23. package/integrations/use-cases/index.js +11 -0
  24. package/integrations/use-cases/update-integration.js +81 -0
  25. package/integrations/utils/map-integration-dto.js +37 -0
  26. package/module-plugin/index.js +0 -4
  27. package/module-plugin/module-factory.js +13 -32
  28. package/module-plugin/module-repository.js +70 -0
  29. package/module-plugin/module-service.js +50 -0
  30. package/module-plugin/{auther.js → module.js} +109 -173
  31. package/module-plugin/test/mock-api/api.js +8 -3
  32. package/module-plugin/test/mock-api/definition.js +12 -8
  33. package/module-plugin/use-cases/get-entities-for-user.js +32 -0
  34. package/module-plugin/utils/map-module-dto.js +18 -0
  35. package/package.json +5 -5
  36. package/types/integrations/index.d.ts +2 -6
  37. package/types/module-plugin/index.d.ts +4 -21
  38. package/user/tests/doubles/test-user-repository.js +72 -0
  39. package/user/tests/use-cases/create-individual-user.test.js +24 -0
  40. package/user/tests/use-cases/create-organization-user.test.js +28 -0
  41. package/user/tests/use-cases/create-token-for-user-id.test.js +19 -0
  42. package/user/tests/use-cases/get-user-from-bearer-token.test.js +64 -0
  43. package/user/tests/use-cases/login-user.test.js +140 -0
  44. package/user/use-cases/create-individual-user.js +61 -0
  45. package/user/use-cases/create-organization-user.js +47 -0
  46. package/user/use-cases/create-token-for-user-id.js +30 -0
  47. package/user/use-cases/get-user-from-bearer-token.js +77 -0
  48. package/user/use-cases/login-user.js +122 -0
  49. package/user/user-repository.js +62 -0
  50. package/user/user.js +77 -0
  51. package/handlers/routers/HEALTHCHECK.md +0 -240
  52. package/handlers/routers/health.js +0 -459
  53. package/handlers/routers/health.test.js +0 -203
  54. package/handlers/routers/middleware/loadUser.js +0 -15
  55. package/handlers/routers/middleware/requireLoggedInUser.js +0 -12
  56. package/integrations/create-frigg-backend.js +0 -31
  57. package/integrations/integration-factory.js +0 -251
  58. package/integrations/integration-user.js +0 -144
  59. package/module-plugin/entity-manager.js +0 -70
@@ -1,5 +1,4 @@
1
1
  const { Credential } = require('./credential');
2
- const { EntityManager } = require('./entity-manager');
3
2
  const { Entity } = require('./entity');
4
3
  const { ModuleManager } = require('./manager');
5
4
  const { ApiKeyRequester } = require('./requester/api-key');
@@ -8,11 +7,9 @@ const { OAuth2Requester } = require('./requester/oauth-2');
8
7
  const { Requester } = require('./requester/requester');
9
8
  const { ModuleConstants } = require('./ModuleConstants');
10
9
  const { ModuleFactory } = require('./module-factory');
11
- const { Auther } = require('./auther');
12
10
 
13
11
  module.exports = {
14
12
  Credential,
15
- EntityManager,
16
13
  Entity,
17
14
  ModuleManager,
18
15
  ApiKeyRequester,
@@ -21,5 +18,4 @@ module.exports = {
21
18
  Requester,
22
19
  ModuleConstants,
23
20
  ModuleFactory,
24
- Auther
25
21
  };
@@ -1,23 +1,16 @@
1
- const { Entity } = require('./entity');
2
- const { Auther } = require('./auther');
1
+ const { ModuleRepository } = require('./module-repository');
2
+ const { ModuleService } = require('./module-service');
3
+ const { Module } = require('./module');
3
4
 
4
5
  class ModuleFactory {
5
6
  constructor(...params) {
6
7
  this.moduleDefinitions = params;
7
8
  this.moduleTypes = this.moduleDefinitions.map((def) => def.moduleName);
8
- }
9
-
10
- async getEntitiesForUser(userId) {
11
- let results = [];
12
- for (const moduleDefinition of this.moduleDefinitions) {
13
- const moduleInstance = await Auther.getInstance({
14
- userId,
15
- definition: moduleDefinition,
16
- });
17
- const list = await moduleInstance.getEntitiesForUserId(userId);
18
- results.push(...list);
19
- }
20
- return results;
9
+ this.moduleRepository = new ModuleRepository();
10
+ this.moduleService = new ModuleService({
11
+ moduleRepository: this.moduleRepository,
12
+ moduleDefinitions: this.moduleDefinitions,
13
+ });
21
14
  }
22
15
 
23
16
  checkIsValidType(entityType) {
@@ -29,29 +22,17 @@ class ModuleFactory {
29
22
  }
30
23
 
31
24
  async getModuleInstanceFromEntityId(entityId, userId) {
32
- const entity = await Entity.findById(entityId);
33
- const moduleDefinition = this.moduleDefinitions.find(
34
- (def) =>
35
- entity.toJSON()['__t'] ===
36
- Auther.getEntityModelFromDefinition(def).modelName
37
- );
38
- if (!moduleDefinition) {
39
- throw new Error(
40
- 'Module definition not found for entity type: ' + entity['__t']
41
- );
42
- }
43
- return await Auther.getInstance({
44
- userId,
45
- entityId,
46
- definition: moduleDefinition,
47
- });
25
+ return this.moduleService.getModuleInstance(entityId, userId);
48
26
  }
49
27
 
50
28
  async getInstanceFromTypeName(typeName, userId) {
51
29
  const moduleDefinition = this.moduleDefinitions.find(
52
30
  (def) => def.getName() === typeName
53
31
  );
54
- return await Auther.getInstance({
32
+ if (!moduleDefinition) {
33
+ throw new Error(`Module definition not found for type: ${typeName}`);
34
+ }
35
+ return new Module({
55
36
  userId,
56
37
  definition: moduleDefinition,
57
38
  });
@@ -0,0 +1,70 @@
1
+ const { Entity } = require('./entity');
2
+
3
+ class ModuleRepository {
4
+ async findEntityById(entityId) {
5
+ const entity = await Entity.findById(entityId, undefined, { lean: true }).populate('credential');
6
+ if (!entity) {
7
+ throw new Error(`Entity ${entityId} not found`);
8
+ }
9
+
10
+ return {
11
+ id: entity._id,
12
+ accountId: entity.accountId,
13
+ credential: entity.credential,
14
+ userId: entity.user.toString(),
15
+ name: entity.name,
16
+ externalId: entity.externalId,
17
+ type: entity.__t,
18
+ moduleName: entity.moduleName,
19
+ };
20
+ }
21
+
22
+ async findEntitiesByIds(entitiesIds) {
23
+ const entitiesRecords = await Entity.find({ _id: { $in: entitiesIds } }, '', { lean: true }).populate('credential');
24
+
25
+ // todo: this is a workaround needed while we create an integration with the same entity twice
26
+ if (entitiesRecords.length !== entitiesIds.length && entitiesIds[0] !== entitiesIds[1]) {
27
+ throw new Error(`Some entities not found`);
28
+ }
29
+
30
+ return entitiesRecords.map(e => ({
31
+ id: e._id,
32
+ accountId: e.accountId,
33
+ credential: e.credential,
34
+ userId: e.user.toString(),
35
+ name: e.name,
36
+ externalId: e.externalId,
37
+ type: e.__t,
38
+ moduleName: e.moduleName,
39
+ }));
40
+ }
41
+
42
+ async findEntitiesByUserId(userId) {
43
+ return Entity.find(
44
+ { user: userId },
45
+ '-dateCreated -dateUpdated -user -credentials -credential -__t -__v',
46
+ { lean: true }
47
+ );
48
+ }
49
+
50
+ async findEntitiesByIds(entityIds) {
51
+ const entities = await Entity.find(
52
+ { _id: { $in: entityIds } },
53
+ '',
54
+ { lean: true }
55
+ );
56
+
57
+ return entities.map(e => ({
58
+ id: e._id.toString(),
59
+ accountId: e.accountId,
60
+ credentialId: e.credential.toString(),
61
+ userId: e.user.toString(),
62
+ name: e.name,
63
+ externalId: e.externalId,
64
+ type: e.__t,
65
+ moduleName: e.moduleName,
66
+ }));
67
+ }
68
+ }
69
+
70
+ module.exports = { ModuleRepository };
@@ -0,0 +1,50 @@
1
+ const { Module } = require('./module');
2
+
3
+ class ModuleService {
4
+ /**
5
+ * @param {Object} params - Configuration parameters.
6
+ * @param {import('./module-repository').ModuleRepository} params.moduleRepository - Repository for module data operations.
7
+ * @param {Array<Object>} params.moduleDefinitions - Array of module definitions.
8
+ */
9
+ constructor({ moduleRepository, moduleDefinitions }) {
10
+ this.moduleRepository = moduleRepository;
11
+ this.moduleDefinitions = moduleDefinitions;
12
+ }
13
+
14
+ async getModuleInstance(entityId, userId) {
15
+ const entity = await this.moduleRepository.findEntityById(
16
+ entityId,
17
+ userId
18
+ );
19
+
20
+ if (!entity) {
21
+ throw new Error(`Entity ${entityId} not found`);
22
+ }
23
+
24
+ if (entity.userId !== userId) {
25
+ throw new Error(
26
+ `Entity ${entityId} does not belong to user ${userId}`
27
+ );
28
+ }
29
+
30
+ const entityType = entity.type;
31
+ const moduleDefinition = this.moduleDefinitions.find((def) => {
32
+ const modelName = Module.getEntityModelFromDefinition(def).modelName;
33
+ return entityType === modelName;
34
+ });
35
+
36
+ if (!moduleDefinition) {
37
+ throw new Error(
38
+ `Module definition not found for entity type: ${entityType}`
39
+ );
40
+ }
41
+
42
+ return new Module({
43
+ userId,
44
+ entity,
45
+ definition: moduleDefinition,
46
+ });
47
+ }
48
+ }
49
+
50
+ module.exports = { ModuleService };
@@ -1,30 +1,3 @@
1
- // Manages authorization and credential persistence
2
- // Instantiation of an API Class
3
- // Expects input object like this:
4
- // const authDef = {
5
- // API: class anAPI{},
6
- // moduleName: 'anAPI', //maybe not required
7
- // requiredAuthMethods: {
8
- // // oauth methods, how to handle these being required/not?
9
- // getToken: async function(params, callbackParams, tokenResponse) {},
10
- // // required for all Auth methods
11
- // getEntityDetails: async function(params) {}, //probably calls api method
12
- // getCredentialDetails: async function(params) {}, // might be same as above
13
- // apiParamsFromCredential: function(params) {},
14
- // testAuth: async function() {}, // basic request to testAuth
15
- // },
16
- // env: {
17
- // client_id: process.env.HUBSPOT_CLIENT_ID,
18
- // client_secret: process.env.HUBSPOT_CLIENT_SECRET,
19
- // scope: process.env.HUBSPOT_SCOPE,
20
- // redirect_uri: `${process.env.REDIRECT_URI}/an-api`,
21
- // }
22
- // };
23
-
24
- //TODO:
25
- // 1. Add definition of expected params to API Class (or could just be credential?)
26
- // 2.
27
-
28
1
  const { Delegate } = require('../core');
29
2
  const { get } = require('../assertions');
30
3
  const _ = require('lodash');
@@ -34,119 +7,44 @@ const { Entity } = require('./entity');
34
7
  const { mongoose } = require('../database/mongoose');
35
8
  const { ModuleConstants } = require('./ModuleConstants');
36
9
 
37
- class Auther extends Delegate {
38
- static validateDefinition(definition) {
39
- if (!definition) {
40
- throw new Error('Auther definition is required');
41
- }
42
- if (!definition.moduleName) {
43
- throw new Error('Auther definition requires moduleName');
44
- }
45
- if (!definition.API) {
46
- throw new Error('Auther definition requires API class');
47
- }
48
- // if (!definition.Credential) {
49
- // throw new Error('Auther definition requires Credential class');
50
- // }
51
- // if (!definition.Entity) {
52
- // throw new Error('Auther definition requires Entity class');
53
- // }
54
- if (!definition.requiredAuthMethods) {
55
- throw new Error('Auther definition requires requiredAuthMethods');
56
- } else {
57
- if (
58
- definition.API.requesterType ===
59
- ModuleConstants.authType.oauth2 &&
60
- !definition.requiredAuthMethods.getToken
61
- ) {
62
- throw new Error(
63
- 'Auther definition requires requiredAuthMethods.getToken'
64
- );
65
- }
66
- if (!definition.requiredAuthMethods.getEntityDetails) {
67
- throw new Error(
68
- 'Auther definition requires requiredAuthMethods.getEntityDetails'
69
- );
70
- }
71
- if (!definition.requiredAuthMethods.getCredentialDetails) {
72
- throw new Error(
73
- 'Auther definition requires requiredAuthMethods.getCredentialDetails'
74
- );
75
- }
76
- if (!definition.requiredAuthMethods.apiPropertiesToPersist) {
77
- throw new Error(
78
- 'Auther definition requires requiredAuthMethods.apiPropertiesToPersist'
79
- );
80
- } else if (definition.Credential) {
81
- for (const prop of definition.requiredAuthMethods
82
- .apiPropertiesToPersist?.credential) {
83
- if (
84
- !definition.Credential.schema.paths.hasOwnProperty(prop)
85
- ) {
86
- throw new Error(
87
- `Auther definition requires Credential schema to have property ${prop}`
88
- );
89
- }
90
- }
91
- }
92
- if (!definition.requiredAuthMethods.testAuthRequest) {
93
- throw new Error(
94
- 'Auther definition requires requiredAuthMethods.testAuth'
95
- );
96
- }
97
- }
98
- }
10
+ class Module extends Delegate {
11
+
12
+ /**
13
+ *
14
+ * @param {Object} params
15
+ * @param {Object} params.definition The definition of the Api Module
16
+ * @param {string} params.userId The user id
17
+ * @param {Object} params.entity The entity record from the database
18
+ */
19
+ constructor({ definition, userId = null, entity: entityObj = null }) {
20
+ super({ definition, userId, entity: entityObj });
21
+
22
+ this.validateDefinition(definition);
23
+
24
+ this.userId = userId;
25
+ this.entity = entityObj;
26
+ this.credential = entityObj?.credential;
27
+ this.definition = definition;
28
+ this.getEntityOptions = this.definition.getEntityOptions;
29
+ this.refreshEntityOptions = this.definition.refreshEntityOptions;
30
+ this.name = this.definition.moduleName;
31
+ this.modelName = this.definition.modelName;
32
+ this.apiClass = this.definition.API;
33
+
34
+
35
+ Object.assign(this, this.definition.requiredAuthMethods);
36
+
37
+ this.CredentialModel = this.getCredentialModel();
38
+ this.EntityModel = this.getEntityModel();
99
39
 
100
- constructor(params) {
101
- super(params);
102
- this.userId = get(params, 'userId', null); // Making this non-required
103
- const definition = get(params, 'definition');
104
- Auther.validateDefinition(definition);
105
- Object.assign(this, definition.requiredAuthMethods);
106
- if (definition.getEntityOptions) {
107
- this.getEntityOptions = definition.getEntityOptions;
108
- }
109
- if (definition.refreshEntityOptions) {
110
- this.refreshEntityOptions = definition.refreshEntityOptions;
111
- }
112
- this.name = definition.moduleName;
113
- this.modelName = definition.modelName;
114
- this.apiClass = definition.API;
115
- this.CredentialModel =
116
- definition.Credential || this.getCredentialModel();
117
- this.EntityModel = definition.Entity || this.getEntityModel();
118
- }
119
40
 
120
- static async getInstance(params) {
121
- const instance = new this(params);
122
- if (params.entityId) {
123
- instance.entity = await instance.EntityModel.findById(
124
- params.entityId
125
- );
126
- instance.credential = await instance.CredentialModel.findById(
127
- instance.entity.credential
128
- );
129
- } else if (params.credentialId) {
130
- instance.credential = await instance.CredentialModel.findById(
131
- params.credentialId
132
- );
133
- }
134
- let credential = {};
135
- let entity = {};
136
- if (instance.credential) {
137
- credential = instance.credential.toObject();
138
- }
139
- if (instance.entity) {
140
- entity = instance.entity.toObject();
141
- }
142
41
  const apiParams = {
143
- ...params.definition.env,
144
- delegate: instance,
145
- ...instance.apiParamsFromCredential(credential),
146
- ...instance.apiParamsFromEntity(entity),
42
+ ...this.definition.env,
43
+ delegate: this,
44
+ ...this.apiParamsFromCredential(this.credential),
45
+ ...this.apiParamsFromEntity(this.entity),
147
46
  };
148
- instance.api = new instance.apiClass(apiParams);
149
- return instance;
47
+ this.api = new this.apiClass(apiParams);
150
48
  }
151
49
 
152
50
  static getEntityModelFromDefinition(definition) {
@@ -205,20 +103,21 @@ class Auther extends Delegate {
205
103
  return this.CredentialModel;
206
104
  }
207
105
 
208
- async getEntitiesForUserId(userId) {
209
- // Only return non-internal fields. Leverages "select" and "options" to non-excepted fields and a pure object.
210
- const list = await this.EntityModel.find(
211
- { user: userId },
212
- '-dateCreated -dateUpdated -user -credentials -credential -__t -__v',
213
- { lean: true }
214
- );
215
- console.log('getEntitiesForUserId list', list, userId);
216
- return list.map((entity) => ({
217
- id: entity._id,
218
- type: this.getName(),
219
- ...entity,
220
- }));
221
- }
106
+ // todo: remove this method from all places
107
+ // async getEntitiesForUserId(userId) {
108
+ // // Only return non-internal fields. Leverages "select" and "options" to non-excepted fields and a pure object.
109
+ // const list = await this.EntityModel.find(
110
+ // { user: userId },
111
+ // '-dateCreated -dateUpdated -user -credentials -credential -__t -__v',
112
+ // { lean: true }
113
+ // );
114
+ // console.log('getEntitiesForUserId list', list, userId);
115
+ // return list.map((entity) => ({
116
+ // id: entity._id,
117
+ // type: this.getName(),
118
+ // ...entity,
119
+ // }));
120
+ // }
222
121
 
223
122
  async validateAuthorizationRequirements() {
224
123
  const requirements = await this.getAuthorizationRequirements();
@@ -233,18 +132,10 @@ class Auther extends Delegate {
233
132
  }
234
133
 
235
134
  async getAuthorizationRequirements(params) {
236
- // TODO: How can this be more helpful both to implement and consume
237
- // this function must return a dictionary with the following format
238
- // node only url key is required. Data would be used for Base Authentication
239
- // let returnData = {
240
- // url: "callback url for the data or teh redirect url for login",
241
- // type: one of the types defined in modules/Constants.js
242
- // data: ["required", "fields", "we", "may", "need"]
243
- // }
244
135
  return this.api.getAuthorizationRequirements();
245
136
  }
246
137
 
247
- async testAuth(params) {
138
+ async testAuth() {
248
139
  let validAuth = false;
249
140
  try {
250
141
  if (await this.testAuthRequest(this.api)) validAuth = true;
@@ -307,18 +198,6 @@ class Auther extends Delegate {
307
198
  }
308
199
  }
309
200
 
310
- async getEntityOptions() {
311
- throw new Error(
312
- 'Method getEntityOptions() is not defined in the class'
313
- );
314
- }
315
-
316
- async refreshEntityOptions() {
317
- throw new Error(
318
- 'Method refreshEntityOptions() is not defined in the class'
319
- );
320
- }
321
-
322
201
  async findOrCreateEntity(entityDetails) {
323
202
  const identifiers = get(entityDetails, 'identifiers');
324
203
  const details = get(entityDetails, 'details');
@@ -326,7 +205,7 @@ class Auther extends Delegate {
326
205
  if (search.length > 1) {
327
206
  throw new Error(
328
207
  'Multiple entities found with the same identifiers: ' +
329
- JSON.stringify(identifiers)
208
+ JSON.stringify(identifiers)
330
209
  );
331
210
  } else if (search.length === 0) {
332
211
  this.entity = await this.EntityModel.create({
@@ -388,6 +267,63 @@ class Auther extends Delegate {
388
267
  await this.entity.save();
389
268
  }
390
269
  }
270
+
271
+ // todo: check if all these props are still up to date
272
+ validateDefinition(definition) {
273
+ if (!definition) {
274
+ throw new Error('Module definition is required');
275
+ }
276
+ if (!definition.moduleName) {
277
+ throw new Error('Module definition requires moduleName');
278
+ }
279
+ if (!definition.API) {
280
+ throw new Error('Module definition requires API class');
281
+ }
282
+ if (!definition.requiredAuthMethods) {
283
+ throw new Error('Module definition requires requiredAuthMethods');
284
+ } else {
285
+ if (
286
+ definition.API.requesterType ===
287
+ ModuleConstants.authType.oauth2 &&
288
+ !definition.requiredAuthMethods.getToken
289
+ ) {
290
+ throw new Error(
291
+ 'Module definition requires requiredAuthMethods.getToken'
292
+ );
293
+ }
294
+ if (!definition.requiredAuthMethods.getEntityDetails) {
295
+ throw new Error(
296
+ 'Module definition requires requiredAuthMethods.getEntityDetails'
297
+ );
298
+ }
299
+ if (!definition.requiredAuthMethods.getCredentialDetails) {
300
+ throw new Error(
301
+ 'Module definition requires requiredAuthMethods.getCredentialDetails'
302
+ );
303
+ }
304
+ if (!definition.requiredAuthMethods.apiPropertiesToPersist) {
305
+ throw new Error(
306
+ 'Module definition requires requiredAuthMethods.apiPropertiesToPersist'
307
+ );
308
+ } else if (definition.Credential) {
309
+ for (const prop of definition.requiredAuthMethods
310
+ .apiPropertiesToPersist?.credential) {
311
+ if (
312
+ !definition.Credential.schema.paths.hasOwnProperty(prop)
313
+ ) {
314
+ throw new Error(
315
+ `Module definition requires Credential schema to have property ${prop}`
316
+ );
317
+ }
318
+ }
319
+ }
320
+ if (!definition.requiredAuthMethods.testAuthRequest) {
321
+ throw new Error(
322
+ 'Module definition requires requiredAuthMethods.testAuth'
323
+ );
324
+ }
325
+ }
326
+ }
391
327
  }
392
328
 
393
- module.exports = { Auther };
329
+ module.exports = { Module };
@@ -1,5 +1,5 @@
1
- const { get } = require('../../assertions');
2
- const { OAuth2Requester } = require('../../module-plugin');
1
+ const { get } = require('../../../assertions');
2
+ const { OAuth2Requester } = require('../..');
3
3
 
4
4
  class Api extends OAuth2Requester {
5
5
  constructor(params) {
@@ -23,7 +23,12 @@ class Api extends OAuth2Requester {
23
23
  return this.authorizationUri;
24
24
  }
25
25
 
26
-
26
+ getAuthorizationRequirements() {
27
+ return {
28
+ url: this.getAuthUri(),
29
+ type: 'oauth2',
30
+ };
31
+ }
27
32
  }
28
33
 
29
34
  module.exports = { Api };
@@ -1,19 +1,23 @@
1
1
  require('dotenv').config();
2
- const {Api} = require('./api');
3
- const {get} = require('../../assertions');
4
- const config = {name: 'anapi'}
2
+ const { Api } = require('./api');
3
+ const { get } = require('../../../assertions');
4
+ const config = { name: 'anapi' }
5
5
 
6
6
  const Definition = {
7
7
  API: Api,
8
- getName: function() {return config.name},
8
+ getAuthorizationRequirements: () => ({
9
+ url: 'http://localhost:3000/redirect/anapi',
10
+ type: 'oauth2',
11
+ }),
12
+ getName: function () { return config.name },
9
13
  moduleName: config.name,
10
14
  modelName: 'AnApi',
11
15
  requiredAuthMethods: {
12
- getToken: async function(api, params){
16
+ getToken: async function (api, params) {
13
17
  const code = get(params.data, 'code');
14
18
  return api.getTokenFromCode(code);
15
19
  },
16
- getEntityDetails: async function(api, callbackParams, tokenResponse, userId) {
20
+ getEntityDetails: async function (api, callbackParams, tokenResponse, userId) {
17
21
  const userDetails = await api.getUserDetails();
18
22
  return {
19
23
  identifiers: { externalId: userDetails.portalId, user: userId },
@@ -26,14 +30,14 @@ const Definition = {
26
30
  ],
27
31
  entity: [],
28
32
  },
29
- getCredentialDetails: async function(api, userId) {
33
+ getCredentialDetails: async function (api, userId) {
30
34
  const userDetails = await api.getUserDetails();
31
35
  return {
32
36
  identifiers: { externalId: userDetails.portalId, user: userId },
33
37
  details: {}
34
38
  };
35
39
  },
36
- testAuthRequest: async function(api){
40
+ testAuthRequest: async function (api) {
37
41
  return api.getUserDetails()
38
42
  },
39
43
  },
@@ -0,0 +1,32 @@
1
+ const { Module } = require('../module');
2
+ const { mapModuleClassToModuleDTO } = require('../utils/map-module-dto');
3
+
4
+ class GetEntitiesForUser {
5
+ constructor({ moduleRepository, moduleDefinitions }) {
6
+ this.moduleRepository = moduleRepository;
7
+
8
+ this.definitionMap = new Map();
9
+ for (const definition of moduleDefinitions) {
10
+ this.definitionMap.set(definition.modelName, definition);
11
+ }
12
+ }
13
+
14
+ async execute(userId) {
15
+ const entities = await this.moduleRepository.findEntitiesByUserId(
16
+ userId
17
+ );
18
+
19
+ return entities.map((entity) => {
20
+ const definition = this.definitionMap.get(entity.moduleName);
21
+
22
+ const moduleInstance = new Module({
23
+ userId,
24
+ definition: definition,
25
+ entity: entity,
26
+ });
27
+ return mapModuleClassToModuleDTO(moduleInstance);
28
+ });
29
+ }
30
+ }
31
+
32
+ module.exports = { GetEntitiesForUser };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @param {import('../module').Module} moduleInstance
3
+ * Convert a Module domain instance to a plain DTO suitable for JSON responses.
4
+ */
5
+ function mapModuleClassToModuleDTO(moduleInstance) {
6
+ if (!moduleInstance) return null;
7
+
8
+ return {
9
+ id: moduleInstance.entity._id.toString(),
10
+ name: moduleInstance.name,
11
+ userId: moduleInstance.userId,
12
+ entity: moduleInstance.entity,
13
+ credentialId: moduleInstance.credential?._id?.toString(),
14
+ type: moduleInstance.getName()
15
+ };
16
+ }
17
+
18
+ module.exports = { mapModuleClassToModuleDTO };