@friggframework/core 1.1.4 → 1.1.5
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/CHANGELOG.md +21 -0
- package/integrations/integration-base.js +24 -0
- package/integrations/integration-router.js +133 -52
- package/module-plugin/auther.js +13 -5
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
# v1.1.5 (Tue Apr 09 2024)
|
|
2
|
+
|
|
3
|
+
#### 🐛 Bug Fix
|
|
4
|
+
|
|
5
|
+
- update router to include options and refresh [#301](https://github.com/friggframework/frigg/pull/301) ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
6
|
+
- consistent spacing ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
7
|
+
- add back the /api/entity POST of a credential with a tentative adjustment to implementation ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
8
|
+
- be consistent about not using redundant variables for the response json ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
9
|
+
- remove accidental newline ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
10
|
+
- fixes to router and stubs ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
11
|
+
- update router to include options and refresh for entities, integration config, and integration user actions ([@MichaelRyanWebber](https://github.com/MichaelRyanWebber))
|
|
12
|
+
- Bump version to: v1.1.4 \[skip ci\] ([@seanspeaks](https://github.com/seanspeaks))
|
|
13
|
+
- Bump version to: v1.1.3 \[skip ci\] ([@seanspeaks](https://github.com/seanspeaks))
|
|
14
|
+
|
|
15
|
+
#### Authors: 2
|
|
16
|
+
|
|
17
|
+
- [@MichaelRyanWebber](https://github.com/MichaelRyanWebber)
|
|
18
|
+
- Sean Matthews ([@seanspeaks](https://github.com/seanspeaks))
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
1
22
|
# v1.1.4 (Fri Apr 05 2024)
|
|
2
23
|
|
|
3
24
|
#### 🐛 Bug Fix
|
|
@@ -154,9 +154,33 @@ class IntegrationBase {
|
|
|
154
154
|
return options;
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
async refreshConfigOptions(params) {
|
|
158
|
+
const options = {
|
|
159
|
+
jsonSchema: {},
|
|
160
|
+
uiSchema: {},
|
|
161
|
+
}
|
|
162
|
+
return options
|
|
163
|
+
}
|
|
164
|
+
|
|
157
165
|
async getUserActions() {
|
|
158
166
|
return [];
|
|
159
167
|
}
|
|
168
|
+
|
|
169
|
+
async getActionOptions() {
|
|
170
|
+
const options = {
|
|
171
|
+
jsonSchema: {},
|
|
172
|
+
uiSchema: {},
|
|
173
|
+
}
|
|
174
|
+
return options
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async refreshActionOptions(params) {
|
|
178
|
+
const options = {
|
|
179
|
+
jsonSchema: {},
|
|
180
|
+
uiSchema: {},
|
|
181
|
+
}
|
|
182
|
+
return options
|
|
183
|
+
}
|
|
160
184
|
}
|
|
161
185
|
|
|
162
186
|
module.exports = { IntegrationBase };
|
|
@@ -89,12 +89,9 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
89
89
|
);
|
|
90
90
|
await integration.onCreate();
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
integration.record
|
|
92
|
+
res.status(201).json(
|
|
93
|
+
await IntegrationHelper.getFormattedIntegration(integration.record)
|
|
95
94
|
);
|
|
96
|
-
res.status(201);
|
|
97
|
-
res.json(response);
|
|
98
95
|
})
|
|
99
96
|
);
|
|
100
97
|
|
|
@@ -114,11 +111,9 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
114
111
|
);
|
|
115
112
|
await integration.onUpdate(params);
|
|
116
113
|
|
|
117
|
-
|
|
118
|
-
integration.record
|
|
114
|
+
res.json(
|
|
115
|
+
await IntegrationHelper.getFormattedIntegration(integration.record)
|
|
119
116
|
);
|
|
120
|
-
|
|
121
|
-
res.json(response);
|
|
122
117
|
})
|
|
123
118
|
);
|
|
124
119
|
|
|
@@ -142,8 +137,7 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
142
137
|
params.integrationId
|
|
143
138
|
);
|
|
144
139
|
|
|
145
|
-
res.status(201);
|
|
146
|
-
res.json({});
|
|
140
|
+
res.status(201).json({});
|
|
147
141
|
})
|
|
148
142
|
);
|
|
149
143
|
|
|
@@ -154,9 +148,21 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
154
148
|
]);
|
|
155
149
|
const integration =
|
|
156
150
|
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
151
|
+
res.json(await integration.getConfigOptions());
|
|
152
|
+
})
|
|
153
|
+
);
|
|
154
|
+
|
|
155
|
+
router.route('/api/integrations/:integrationId/config/options/refresh').post(
|
|
156
|
+
catchAsyncError(async (req, res) => {
|
|
157
|
+
const params = checkRequiredParams(req.params, [
|
|
158
|
+
'integrationId',
|
|
159
|
+
]);
|
|
160
|
+
const integration =
|
|
161
|
+
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
162
|
+
|
|
163
|
+
res.json(
|
|
164
|
+
await integration.refreshConfigOptions(req.body)
|
|
165
|
+
);
|
|
160
166
|
})
|
|
161
167
|
);
|
|
162
168
|
|
|
@@ -168,11 +174,25 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
168
174
|
]);
|
|
169
175
|
const integration =
|
|
170
176
|
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
171
|
-
|
|
172
|
-
|
|
177
|
+
|
|
178
|
+
res.json(
|
|
179
|
+
await integration.getActionOptions(params.actionId)
|
|
180
|
+
);
|
|
181
|
+
})
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
router.route('/api/integrations/:integrationId/actions/:actionId/options/refresh').post(
|
|
185
|
+
catchAsyncError(async (req, res) => {
|
|
186
|
+
const params = checkRequiredParams(req.params, [
|
|
187
|
+
'integrationId',
|
|
188
|
+
'actionId'
|
|
189
|
+
]);
|
|
190
|
+
const integration =
|
|
191
|
+
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
192
|
+
|
|
193
|
+
res.json(
|
|
194
|
+
await integration.refreshActionOptions(params.actionId, req.body)
|
|
173
195
|
);
|
|
174
|
-
// We could perhaps augment router with dynamic options? Haven't decided yet, but here may be the place
|
|
175
|
-
res.json(results);
|
|
176
196
|
})
|
|
177
197
|
);
|
|
178
198
|
|
|
@@ -184,14 +204,12 @@ function setIntegrationRoutes(router, factory, getUserId) {
|
|
|
184
204
|
]);
|
|
185
205
|
const integration =
|
|
186
206
|
await integrationFactory.getInstanceFromIntegrationId(params);
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
req.body
|
|
207
|
+
|
|
208
|
+
res.json(
|
|
209
|
+
await integration.notify(params.actionId, req.body)
|
|
190
210
|
);
|
|
191
|
-
// We could perhaps augment router with dynamic options? Haven't decided yet, but here may be the place
|
|
192
|
-
res.json(results);
|
|
193
211
|
})
|
|
194
|
-
)
|
|
212
|
+
);
|
|
195
213
|
|
|
196
214
|
router.route('/api/integrations/:integrationId').get(
|
|
197
215
|
catchAsyncError(async (req, res) => {
|
|
@@ -268,6 +286,7 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
268
286
|
`Error: EntityManager of type ${params.entityType} requires a valid url`
|
|
269
287
|
);
|
|
270
288
|
}
|
|
289
|
+
|
|
271
290
|
res.json(await module.getAuthorizationRequirements());
|
|
272
291
|
})
|
|
273
292
|
);
|
|
@@ -278,35 +297,14 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
278
297
|
'entityType',
|
|
279
298
|
'data',
|
|
280
299
|
]);
|
|
281
|
-
console.log('post authorize', params);
|
|
282
300
|
const module = await getModuleInstance(req, params.entityType);
|
|
283
|
-
console.log('post authorize module', module);
|
|
284
|
-
const results = await module.processAuthorizationCallback({
|
|
285
|
-
userId: getUserId(req),
|
|
286
|
-
data: params.data,
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
res.json(results);
|
|
290
|
-
})
|
|
291
|
-
);
|
|
292
301
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
req.params.credentialId
|
|
302
|
+
res.json(
|
|
303
|
+
await module.processAuthorizationCallback({
|
|
304
|
+
userId: getUserId(req),
|
|
305
|
+
data: params.data,
|
|
306
|
+
})
|
|
299
307
|
);
|
|
300
|
-
if (credential.user._id.toString() !== getUserId(req)) {
|
|
301
|
-
throw Boom.forbidden('Credential does not belong to user');
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
const params = checkRequiredParams(req.query, [
|
|
305
|
-
'entityType',
|
|
306
|
-
]);
|
|
307
|
-
const module = await getModuleInstance(req, params.entityType);
|
|
308
|
-
|
|
309
|
-
res.json(await module.getEntityOptions());
|
|
310
308
|
})
|
|
311
309
|
);
|
|
312
310
|
|
|
@@ -328,7 +326,36 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
328
326
|
}
|
|
329
327
|
|
|
330
328
|
const module = await getModuleInstance(req, params.entityType);
|
|
331
|
-
|
|
329
|
+
const entityDetails = await module.getEntityDetails(
|
|
330
|
+
module.api,
|
|
331
|
+
null,
|
|
332
|
+
null,
|
|
333
|
+
getUserId(req)
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
res.json(
|
|
337
|
+
await module.findOrCreateEntity(entityDetails)
|
|
338
|
+
);
|
|
339
|
+
})
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
router.route('/api/entity/options/:credentialId').get(
|
|
343
|
+
catchAsyncError(async (req, res) => {
|
|
344
|
+
// TODO May want to pass along the user ID as well so credential ID's can't be fished???
|
|
345
|
+
// TODO **flagging this for review** -MW
|
|
346
|
+
const credential = await IntegrationHelper.getCredentialById(
|
|
347
|
+
req.params.credentialId
|
|
348
|
+
);
|
|
349
|
+
if (credential.user._id.toString() !== getUserId(req)) {
|
|
350
|
+
throw Boom.forbidden('Credential does not belong to user');
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const params = checkRequiredParams(req.query, [
|
|
354
|
+
'entityType',
|
|
355
|
+
]);
|
|
356
|
+
const module = await getModuleInstance(req, params.entityType);
|
|
357
|
+
|
|
358
|
+
res.json(await module.getEntityOptions());
|
|
332
359
|
})
|
|
333
360
|
);
|
|
334
361
|
|
|
@@ -352,7 +379,7 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
352
379
|
errors: [
|
|
353
380
|
{
|
|
354
381
|
title: 'Authentication Error',
|
|
355
|
-
message: `There was an error with your ${module.
|
|
382
|
+
message: `There was an error with your ${module.getName()} Entity. Please reconnect/re-authenticate, or reach out to Support for assistance.`,
|
|
356
383
|
timestamp: Date.now(),
|
|
357
384
|
},
|
|
358
385
|
],
|
|
@@ -362,6 +389,60 @@ function setEntityRoutes(router, factory, getUserId) {
|
|
|
362
389
|
}
|
|
363
390
|
})
|
|
364
391
|
);
|
|
392
|
+
|
|
393
|
+
router.route('/api/entities/:entityId').get(
|
|
394
|
+
catchAsyncError(async (req, res) => {
|
|
395
|
+
const params = checkRequiredParams(req.params, ['entityId']);
|
|
396
|
+
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
397
|
+
params.entityId,
|
|
398
|
+
getUserId(req)
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
if (!module) {
|
|
402
|
+
throw Boom.notFound();
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
res.json(module.entity);
|
|
406
|
+
})
|
|
407
|
+
);
|
|
408
|
+
|
|
409
|
+
router.route('/api/entities/:entityId/options').post(
|
|
410
|
+
catchAsyncError(async (req, res) => {
|
|
411
|
+
const params = checkRequiredParams(req.params, [
|
|
412
|
+
'entityId',
|
|
413
|
+
getUserId(req)
|
|
414
|
+
]);
|
|
415
|
+
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
416
|
+
params.entityId,
|
|
417
|
+
getUserId(req)
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
if (!module) {
|
|
421
|
+
throw Boom.notFound();
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
res.json(await module.getEntityOptions());
|
|
425
|
+
})
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
router.route('/api/entities/:entityId/options/refresh').post(
|
|
429
|
+
catchAsyncError(async (req, res) => {
|
|
430
|
+
const params = checkRequiredParams(req.params, [
|
|
431
|
+
'entityId',
|
|
432
|
+
getUserId(req)
|
|
433
|
+
]);
|
|
434
|
+
const module = await moduleFactory.getModuleInstanceFromEntityId(
|
|
435
|
+
params.entityId,
|
|
436
|
+
getUserId(req)
|
|
437
|
+
);
|
|
438
|
+
|
|
439
|
+
if (!module) {
|
|
440
|
+
throw Boom.notFound();
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
res.json(await module.refreshEntityOptions(req.body));
|
|
444
|
+
})
|
|
445
|
+
);
|
|
365
446
|
}
|
|
366
447
|
|
|
367
448
|
module.exports = { createIntegrationRouter, checkRequiredParams };
|
package/module-plugin/auther.js
CHANGED
|
@@ -88,6 +88,12 @@ class Auther extends Delegate {
|
|
|
88
88
|
const definition = get(params, 'definition');
|
|
89
89
|
Auther.validateDefinition(definition);
|
|
90
90
|
Object.assign(this, definition.requiredAuthMethods);
|
|
91
|
+
if (definition.getEntityOptions) {
|
|
92
|
+
this.getEntityOptions = definition.getEntityOptions;
|
|
93
|
+
}
|
|
94
|
+
if (definition.refreshEntityOptions) {
|
|
95
|
+
this.refreshEntityOptions = definition.refreshEntityOptions;
|
|
96
|
+
}
|
|
91
97
|
this.name = definition.moduleName;
|
|
92
98
|
this.modelName = definition.modelName;
|
|
93
99
|
this.apiClass = definition.API;
|
|
@@ -263,12 +269,14 @@ class Auther extends Delegate {
|
|
|
263
269
|
}
|
|
264
270
|
|
|
265
271
|
async getEntityOptions() {
|
|
266
|
-
// May not be needed if the callback already creates the entity, such as in situations
|
|
267
|
-
// like HubSpot where the account is determined in the authorization flow.
|
|
268
|
-
// This should only be used in situations such as FreshBooks where the user needs to make
|
|
269
|
-
// an account decision on the front end.
|
|
270
272
|
throw new Error(
|
|
271
|
-
'
|
|
273
|
+
'Method getEntityOptions() is not defined in the class'
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async refreshEntityOptions() {
|
|
278
|
+
throw new Error(
|
|
279
|
+
'Method refreshEntityOptions() is not defined in the class'
|
|
272
280
|
);
|
|
273
281
|
}
|
|
274
282
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@friggframework/core",
|
|
3
3
|
"prettier": "@friggframework/prettier-config",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.5",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@hapi/boom": "^10.0.1",
|
|
7
7
|
"aws-sdk": "^2.1200.0",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"node-fetch": "^2.6.7"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@friggframework/eslint-config": "^1.1.
|
|
19
|
-
"@friggframework/prettier-config": "^1.1.
|
|
20
|
-
"@friggframework/test": "^1.1.
|
|
18
|
+
"@friggframework/eslint-config": "^1.1.5",
|
|
19
|
+
"@friggframework/prettier-config": "^1.1.5",
|
|
20
|
+
"@friggframework/test": "^1.1.5",
|
|
21
21
|
"@types/lodash": "^4.14.191",
|
|
22
22
|
"@typescript-eslint/eslint-plugin": "^5.55.0",
|
|
23
23
|
"chai": "^4.3.6",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
},
|
|
50
50
|
"homepage": "https://github.com/friggframework/frigg#readme",
|
|
51
51
|
"description": "",
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "1a53bc7153b3735729e4d881ca9d7677964293c9"
|
|
53
53
|
}
|