@friggframework/core 2.0.0-next.3 → 2.0.0-next.30

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.
@@ -25,15 +25,14 @@
25
25
  // 1. Add definition of expected params to API Class (or could just be credential?)
26
26
  // 2.
27
27
 
28
-
29
28
  const { Delegate } = require('../core');
30
29
  const { get } = require('../assertions');
31
30
  const _ = require('lodash');
32
- const {flushDebugLog} = require('../logs');
31
+ const { flushDebugLog } = require('../logs');
33
32
  const { Credential } = require('./credential');
34
33
  const { Entity } = require('./entity');
35
34
  const { mongoose } = require('../database/mongoose');
36
- const {ModuleConstants} = require("./ModuleConstants");
35
+ const { ModuleConstants } = require('./ModuleConstants');
37
36
 
38
37
  class Auther extends Delegate {
39
38
  static validateDefinition(definition) {
@@ -55,21 +54,35 @@ class Auther extends Delegate {
55
54
  if (!definition.requiredAuthMethods) {
56
55
  throw new Error('Auther definition requires requiredAuthMethods');
57
56
  } else {
58
- if (definition.API.requesterType === ModuleConstants.authType.oauth2 &&
59
- !definition.requiredAuthMethods.getToken) {
60
- throw new Error('Auther definition requires requiredAuthMethods.getToken');
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
+ );
61
65
  }
62
66
  if (!definition.requiredAuthMethods.getEntityDetails) {
63
- throw new Error('Auther definition requires requiredAuthMethods.getEntityDetails');
67
+ throw new Error(
68
+ 'Auther definition requires requiredAuthMethods.getEntityDetails'
69
+ );
64
70
  }
65
71
  if (!definition.requiredAuthMethods.getCredentialDetails) {
66
- throw new Error('Auther definition requires requiredAuthMethods.getCredentialDetails');
72
+ throw new Error(
73
+ 'Auther definition requires requiredAuthMethods.getCredentialDetails'
74
+ );
67
75
  }
68
76
  if (!definition.requiredAuthMethods.apiPropertiesToPersist) {
69
- throw new Error('Auther definition requires requiredAuthMethods.apiPropertiesToPersist');
70
- } else if (definition.Credential){
71
- for (const prop of definition.requiredAuthMethods.apiPropertiesToPersist?.credential) {
72
- if (!definition.Credential.schema.paths.hasOwnProperty(prop)) {
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
+ ) {
73
86
  throw new Error(
74
87
  `Auther definition requires Credential schema to have property ${prop}`
75
88
  );
@@ -77,7 +90,9 @@ class Auther extends Delegate {
77
90
  }
78
91
  }
79
92
  if (!definition.requiredAuthMethods.testAuthRequest) {
80
- throw new Error('Auther definition requires requiredAuthMethods.testAuth');
93
+ throw new Error(
94
+ 'Auther definition requires requiredAuthMethods.testAuth'
95
+ );
81
96
  }
82
97
  }
83
98
  }
@@ -97,14 +112,17 @@ class Auther extends Delegate {
97
112
  this.name = definition.moduleName;
98
113
  this.modelName = definition.modelName;
99
114
  this.apiClass = definition.API;
100
- this.CredentialModel = definition.Credential || this.getCredentialModel();
115
+ this.CredentialModel =
116
+ definition.Credential || this.getCredentialModel();
101
117
  this.EntityModel = definition.Entity || this.getEntityModel();
102
118
  }
103
119
 
104
120
  static async getInstance(params) {
105
121
  const instance = new this(params);
106
122
  if (params.entityId) {
107
- instance.entity = await instance.EntityModel.findById(params.entityId);
123
+ instance.entity = await instance.EntityModel.findById(
124
+ params.entityId
125
+ );
108
126
  instance.credential = await instance.CredentialModel.findById(
109
127
  instance.entity.credential
110
128
  );
@@ -132,7 +150,7 @@ class Auther extends Delegate {
132
150
  }
133
151
 
134
152
  static getEntityModelFromDefinition(definition) {
135
- const partialModule = new this({definition});
153
+ const partialModule = new this({ definition });
136
154
  return partialModule.getEntityModel();
137
155
  }
138
156
 
@@ -151,30 +169,38 @@ class Auther extends Delegate {
151
169
  getEntityModel() {
152
170
  if (!this.EntityModel) {
153
171
  const prefix = this.modelName ?? _.upperFirst(this.getName());
154
- const arrayToDefaultObject = (array, defaultValue) => _.mapValues(_.keyBy(array), () => defaultValue);
155
- const schema = new mongoose.Schema(arrayToDefaultObject(this.apiPropertiesToPersist.entity, {
156
- type: mongoose.Schema.Types.Mixed,
157
- trim: true,
158
- }));
172
+ const arrayToDefaultObject = (array, defaultValue) =>
173
+ _.mapValues(_.keyBy(array), () => defaultValue);
174
+ const schema = new mongoose.Schema(
175
+ arrayToDefaultObject(this.apiPropertiesToPersist.entity, {
176
+ type: mongoose.Schema.Types.Mixed,
177
+ trim: true,
178
+ })
179
+ );
159
180
  const name = `${prefix}Entity`;
160
181
  this.EntityModel =
161
- Entity.discriminators?.[name] || Entity.discriminator(name, schema);
182
+ Entity.discriminators?.[name] ||
183
+ Entity.discriminator(name, schema);
162
184
  }
163
185
  return this.EntityModel;
164
186
  }
165
187
 
166
188
  getCredentialModel() {
167
189
  if (!this.CredentialModel) {
168
- const arrayToDefaultObject = (array, defaultValue) => _.mapValues(_.keyBy(array), () => defaultValue);
169
- const schema = new mongoose.Schema(arrayToDefaultObject(this.apiPropertiesToPersist.credential, {
170
- type: mongoose.Schema.Types.Mixed,
171
- trim: true,
172
- lhEncrypt: true
173
- }));
190
+ const arrayToDefaultObject = (array, defaultValue) =>
191
+ _.mapValues(_.keyBy(array), () => defaultValue);
192
+ const schema = new mongoose.Schema(
193
+ arrayToDefaultObject(this.apiPropertiesToPersist.credential, {
194
+ type: mongoose.Schema.Types.Mixed,
195
+ trim: true,
196
+ lhEncrypt: true,
197
+ })
198
+ );
174
199
  const prefix = this.modelName ?? _.upperFirst(this.getName());
175
200
  const name = `${prefix}Credential`;
176
201
  this.CredentialModel =
177
- Credential.discriminators?.[name] || Credential.discriminator(name, schema);
202
+ Credential.discriminators?.[name] ||
203
+ Credential.discriminator(name, schema);
178
204
  }
179
205
  return this.CredentialModel;
180
206
  }
@@ -197,7 +223,10 @@ class Auther extends Delegate {
197
223
  async validateAuthorizationRequirements() {
198
224
  const requirements = await this.getAuthorizationRequirements();
199
225
  let valid = true;
200
- if (['oauth1', 'oauth2'].includes(requirements.type) && !requirements.url) {
226
+ if (
227
+ ['oauth1', 'oauth2'].includes(requirements.type) &&
228
+ !requirements.url
229
+ ) {
201
230
  valid = false;
202
231
  }
203
232
  return valid;
@@ -238,20 +267,32 @@ class Auther extends Delegate {
238
267
  throw new Error('Authorization failed');
239
268
  }
240
269
  const entityDetails = await this.getEntityDetails(
241
- this.api, params, tokenResponse, this.userId
270
+ this.api,
271
+ params,
272
+ tokenResponse,
273
+ this.userId
274
+ );
275
+ Object.assign(
276
+ entityDetails.details,
277
+ this.apiParamsFromEntity(this.api)
242
278
  );
243
- Object.assign(entityDetails.details, this.apiParamsFromEntity(this.api));
244
279
  await this.findOrCreateEntity(entityDetails);
245
280
  return {
246
281
  credential_id: this.credential.id,
247
282
  entity_id: this.entity.id,
248
283
  type: this.getName(),
249
- }
284
+ };
250
285
  }
251
286
 
252
287
  async onTokenUpdate() {
253
- const credentialDetails = await this.getCredentialDetails(this.api, this.userId);
254
- Object.assign(credentialDetails.details, this.apiParamsFromCredential(this.api));
288
+ const credentialDetails = await this.getCredentialDetails(
289
+ this.api,
290
+ this.userId
291
+ );
292
+ Object.assign(
293
+ credentialDetails.details,
294
+ this.apiParamsFromCredential(this.api)
295
+ );
255
296
  credentialDetails.details.auth_is_valid = true;
256
297
  await this.updateOrCreateCredential(credentialDetails);
257
298
  }
@@ -259,11 +300,9 @@ class Auther extends Delegate {
259
300
  async receiveNotification(notifier, delegateString, object = null) {
260
301
  if (delegateString === this.api.DLGT_TOKEN_UPDATE) {
261
302
  await this.onTokenUpdate();
262
- }
263
- else if (delegateString === this.api.DLGT_TOKEN_DEAUTHORIZED) {
303
+ } else if (delegateString === this.api.DLGT_TOKEN_DEAUTHORIZED) {
264
304
  await this.deauthorize();
265
- }
266
- else if (delegateString === this.api.DLGT_INVALID_AUTH) {
305
+ } else if (delegateString === this.api.DLGT_INVALID_AUTH) {
267
306
  await this.markCredentialsInvalid();
268
307
  }
269
308
  }
@@ -286,10 +325,10 @@ class Auther extends Delegate {
286
325
  const search = await this.EntityModel.find(identifiers);
287
326
  if (search.length > 1) {
288
327
  throw new Error(
289
- 'Multiple entities found with the same identifiers: ' + JSON.stringify(identifiers)
328
+ 'Multiple entities found with the same identifiers: ' +
329
+ JSON.stringify(identifiers)
290
330
  );
291
- }
292
- else if (search.length === 0) {
331
+ } else if (search.length === 0) {
293
332
  this.entity = await this.EntityModel.create({
294
333
  credential: this.credential.id,
295
334
  ...details,
@@ -308,25 +347,27 @@ class Auther extends Delegate {
308
347
  const identifiers = get(credentialDetails, 'identifiers');
309
348
  const details = get(credentialDetails, 'details');
310
349
 
311
- if (!this.credential){
312
- const credentialSearch = await this.CredentialModel.find(identifiers);
350
+ if (!this.credential) {
351
+ const credentialSearch = await this.CredentialModel.find(
352
+ identifiers
353
+ );
313
354
  if (credentialSearch.length > 1) {
314
- throw new Error(`Multiple credentials found with same identifiers: ${identifiers}`);
315
- }
316
- else if (credentialSearch.length === 1) {
355
+ throw new Error(
356
+ `Multiple credentials found with same identifiers: ${identifiers}`
357
+ );
358
+ } else if (credentialSearch.length === 1) {
317
359
  // found exactly one credential with these identifiers
318
360
  this.credential = credentialSearch[0];
319
- }
320
- else {
361
+ } else {
321
362
  // found no credential with these identifiers (match none for insert)
322
- this.credential = {$exists: false};
363
+ this.credential = { $exists: false };
323
364
  }
324
365
  }
325
366
  // update credential or create if none was found
326
367
  this.credential = await this.CredentialModel.findOneAndUpdate(
327
- {_id: this.credential},
328
- {$set: {...identifiers, ...details}},
329
- {useFindAndModify: true, new: true, upsert: true}
368
+ { _id: this.credential },
369
+ { $set: { ...identifiers, ...details } },
370
+ { useFindAndModify: true, new: true, upsert: true }
330
371
  );
331
372
  }
332
373
 
@@ -340,7 +381,9 @@ class Auther extends Delegate {
340
381
  async deauthorize() {
341
382
  this.api = new this.apiClass();
342
383
  if (this.entity?.credential) {
343
- await this.CredentialModel.deleteOne({ _id: this.entity.credential });
384
+ await this.CredentialModel.deleteOne({
385
+ _id: this.entity.credential,
386
+ });
344
387
  this.entity.credential = undefined;
345
388
  await this.entity.save();
346
389
  }
@@ -108,6 +108,7 @@ class Requester extends Delegate {
108
108
  }
109
109
 
110
110
  async _post(options, stringify = true) {
111
+ console.log('options', options);
111
112
  const fetchOptions = {
112
113
  method: 'POST',
113
114
  credentials: 'include',
package/package.json CHANGED
@@ -1,24 +1,31 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0-next.3",
4
+ "version": "2.0.0-next.30",
5
5
  "dependencies": {
6
6
  "@hapi/boom": "^10.0.1",
7
7
  "aws-sdk": "^2.1200.0",
8
8
  "bcryptjs": "^2.4.3",
9
+ "body-parser": "^1.20.2",
9
10
  "common-tags": "^1.8.2",
10
- "express": "^4.18.2",
11
+ "cors": "^2.8.5",
12
+ "dotenv": "^16.4.7",
13
+ "express": "^4.19.2",
11
14
  "express-async-handler": "^1.2.0",
12
- "lodash": "^4.17.21",
15
+ "form-data": "^4.0.0",
16
+ "fs-extra": "^11.2.0",
17
+ "lodash": "4.17.21",
13
18
  "lodash.get": "^4.4.2",
14
19
  "mongoose": "6.11.6",
15
- "node-fetch": "^2.6.7"
20
+ "node-fetch": "^2.6.7",
21
+ "serverless-http": "^2.7.0",
22
+ "uuid": "^9.0.1"
16
23
  },
17
24
  "devDependencies": {
18
- "@friggframework/eslint-config": "2.0.0-next.3",
19
- "@friggframework/prettier-config": "2.0.0-next.3",
20
- "@friggframework/test": "2.0.0-next.3",
21
- "@types/lodash": "^4.14.191",
25
+ "@friggframework/eslint-config": "2.0.0-next.30",
26
+ "@friggframework/prettier-config": "2.0.0-next.30",
27
+ "@friggframework/test": "2.0.0-next.30",
28
+ "@types/lodash": "4.17.15",
22
29
  "@typescript-eslint/eslint-plugin": "^8.0.0",
23
30
  "chai": "^4.3.6",
24
31
  "eslint": "^8.22.0",
@@ -26,9 +33,7 @@
26
33
  "eslint-plugin-n": "^17.10.2",
27
34
  "eslint-plugin-promise": "^7.0.0",
28
35
  "jest": "^29.7.0",
29
- "jest-runner-groups": "^2.2.0",
30
- "mongodb-memory-server": "^8.9.0",
31
- "prettier": "^2.8.5",
36
+ "prettier": "^2.7.1",
32
37
  "sinon": "^16.1.1",
33
38
  "typescript": "^5.0.2"
34
39
  },
@@ -48,5 +53,5 @@
48
53
  },
49
54
  "homepage": "https://github.com/friggframework/frigg#readme",
50
55
  "description": "",
51
- "gitHead": "431427564322cdb02a43b686af70b0fb30a17a8b"
56
+ "gitHead": "5c1c0838a8e2d0d77e557ce11d9ad0899c3f464d"
52
57
  }
@@ -0,0 +1,38 @@
1
+ const fs = require('fs-extra');
2
+ const path = require('node:path');
3
+ const PACKAGE_JSON = 'package.json';
4
+
5
+ function findNearestBackendPackageJson() {
6
+ let currentDir = process.cwd();
7
+
8
+ // First check if we're in production by looking for package.json in the current directory
9
+ const rootPackageJson = path.join(currentDir, PACKAGE_JSON);
10
+ if (fs.existsSync(rootPackageJson)) {
11
+ // In production environment, check for index.js in the same directory
12
+ const indexJs = path.join(currentDir, 'index.js');
13
+ if (fs.existsSync(indexJs)) {
14
+ return rootPackageJson;
15
+ }
16
+ }
17
+
18
+ // If not found at root or not in production, look for it in the backend directory
19
+ while (currentDir !== path.parse(currentDir).root) {
20
+ const packageJsonPath = path.join(currentDir, 'backend', PACKAGE_JSON);
21
+ if (fs.existsSync(packageJsonPath)) {
22
+ return packageJsonPath;
23
+ }
24
+ currentDir = path.dirname(currentDir);
25
+ }
26
+ return null;
27
+ }
28
+
29
+ function validateBackendPath(backendPath) {
30
+ if (!backendPath) {
31
+ throw new Error('Could not find a backend package.json file.');
32
+ }
33
+ }
34
+
35
+ module.exports = {
36
+ findNearestBackendPackageJson,
37
+ validateBackendPath,
38
+ };
package/utils/index.js ADDED
@@ -0,0 +1,6 @@
1
+ const { findNearestBackendPackageJson, validateBackendPath } = require('./backend-path');
2
+
3
+ module.exports = {
4
+ findNearestBackendPackageJson,
5
+ validateBackendPath,
6
+ };