@friggframework/core 2.0.0--canary.461.651659d.0 → 2.0.0--canary.461.d74bc46.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.
- package/database/prisma.js +4 -4
- package/handlers/routers/health.js +2 -2
- package/index.js +12 -0
- package/integrations/integration-router.js +54 -70
- package/integrations/tests/integration-router-multi-auth.test.js +368 -0
- package/package.json +5 -5
- package/user/tests/use-cases/get-user-from-adopter-jwt.test.js +113 -0
- package/user/tests/use-cases/get-user-from-x-frigg-headers.test.js +345 -0
- package/user/use-cases/authenticate-user.js +78 -0
- package/user/use-cases/get-user-from-adopter-jwt.js +148 -0
- package/user/use-cases/get-user-from-x-frigg-headers.js +105 -0
package/database/prisma.js
CHANGED
|
@@ -22,7 +22,7 @@ function getEncryptionConfig() {
|
|
|
22
22
|
if (!hasKMS && !hasAES) {
|
|
23
23
|
logger.warn(
|
|
24
24
|
'No encryption keys configured (KMS_KEY_ARN or AES_KEY_ID). ' +
|
|
25
|
-
|
|
25
|
+
'Field-level encryption disabled. Set STAGE=production and configure keys to enable.'
|
|
26
26
|
);
|
|
27
27
|
return { enabled: false };
|
|
28
28
|
}
|
|
@@ -75,7 +75,7 @@ function loadCustomEncryptionSchema() {
|
|
|
75
75
|
|
|
76
76
|
const prismaClientSingleton = () => {
|
|
77
77
|
let PrismaClient;
|
|
78
|
-
|
|
78
|
+
|
|
79
79
|
// Helper to try loading Prisma client from multiple locations
|
|
80
80
|
const loadPrismaClient = (dbType) => {
|
|
81
81
|
const paths = [
|
|
@@ -84,7 +84,7 @@ const prismaClientSingleton = () => {
|
|
|
84
84
|
// Local development location (relative to core package)
|
|
85
85
|
`../generated/prisma-${dbType}`,
|
|
86
86
|
];
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
for (const path of paths) {
|
|
89
89
|
try {
|
|
90
90
|
return require(path).PrismaClient;
|
|
@@ -92,7 +92,7 @@ const prismaClientSingleton = () => {
|
|
|
92
92
|
// Continue to next path
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
|
|
95
|
+
|
|
96
96
|
throw new Error(
|
|
97
97
|
`Cannot find Prisma client for ${dbType}. Tried paths: ${paths.join(', ')}`
|
|
98
98
|
);
|
|
@@ -39,10 +39,10 @@ let moduleFactory, integrationClasses;
|
|
|
39
39
|
try {
|
|
40
40
|
const appDef = loadAppDefinition();
|
|
41
41
|
integrationClasses = appDef.integrations || [];
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
const moduleRepository = createModuleRepository();
|
|
44
44
|
const moduleDefinitions = getModulesDefinitionFromIntegrationClasses(integrationClasses);
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
moduleFactory = new ModuleFactory({
|
|
47
47
|
moduleRepository,
|
|
48
48
|
moduleDefinitions,
|
package/index.js
CHANGED
|
@@ -33,6 +33,15 @@ const {
|
|
|
33
33
|
UserRepositoryMongo,
|
|
34
34
|
UserRepositoryPostgres,
|
|
35
35
|
} = require('./user/repositories/user-repository-factory');
|
|
36
|
+
const {
|
|
37
|
+
GetUserFromXFriggHeaders,
|
|
38
|
+
} = require('./user/use-cases/get-user-from-x-frigg-headers');
|
|
39
|
+
const {
|
|
40
|
+
GetUserFromAdopterJwt,
|
|
41
|
+
} = require('./user/use-cases/get-user-from-adopter-jwt');
|
|
42
|
+
const {
|
|
43
|
+
AuthenticateUser,
|
|
44
|
+
} = require('./user/use-cases/authenticate-user');
|
|
36
45
|
|
|
37
46
|
const {
|
|
38
47
|
CredentialRepository,
|
|
@@ -123,6 +132,9 @@ module.exports = {
|
|
|
123
132
|
createUserRepository,
|
|
124
133
|
UserRepositoryMongo,
|
|
125
134
|
UserRepositoryPostgres,
|
|
135
|
+
GetUserFromXFriggHeaders,
|
|
136
|
+
GetUserFromAdopterJwt,
|
|
137
|
+
AuthenticateUser,
|
|
126
138
|
CredentialRepository,
|
|
127
139
|
ModuleRepository,
|
|
128
140
|
IntegrationMappingRepository,
|
|
@@ -56,6 +56,15 @@ const {
|
|
|
56
56
|
const {
|
|
57
57
|
GetUserFromBearerToken,
|
|
58
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
|
+
AuthenticateUser,
|
|
67
|
+
} = require('../user/use-cases/authenticate-user');
|
|
59
68
|
const {
|
|
60
69
|
ProcessAuthorizationCallback,
|
|
61
70
|
} = require('../modules/use-cases/process-authorization-callback');
|
|
@@ -73,6 +82,23 @@ function createIntegrationRouter() {
|
|
|
73
82
|
userConfig,
|
|
74
83
|
});
|
|
75
84
|
|
|
85
|
+
const getUserFromXFriggHeaders = new GetUserFromXFriggHeaders({
|
|
86
|
+
userRepository,
|
|
87
|
+
userConfig,
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
const getUserFromAdopterJwt = new GetUserFromAdopterJwt({
|
|
91
|
+
userRepository,
|
|
92
|
+
userConfig,
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const authenticateUser = new AuthenticateUser({
|
|
96
|
+
getUserFromBearerToken,
|
|
97
|
+
getUserFromXFriggHeaders,
|
|
98
|
+
getUserFromAdopterJwt,
|
|
99
|
+
userConfig,
|
|
100
|
+
});
|
|
101
|
+
|
|
76
102
|
const moduleFactory = new ModuleFactory({
|
|
77
103
|
moduleRepository,
|
|
78
104
|
moduleDefinitions:
|
|
@@ -165,7 +191,7 @@ function createIntegrationRouter() {
|
|
|
165
191
|
|
|
166
192
|
const router = express();
|
|
167
193
|
|
|
168
|
-
setIntegrationRoutes(router,
|
|
194
|
+
setIntegrationRoutes(router, authenticateUser, {
|
|
169
195
|
createIntegration,
|
|
170
196
|
deleteIntegrationForUser,
|
|
171
197
|
getIntegrationsForUser,
|
|
@@ -174,7 +200,7 @@ function createIntegrationRouter() {
|
|
|
174
200
|
updateIntegration,
|
|
175
201
|
getPossibleIntegrations,
|
|
176
202
|
});
|
|
177
|
-
setEntityRoutes(router,
|
|
203
|
+
setEntityRoutes(router, authenticateUser, {
|
|
178
204
|
getCredentialForUser,
|
|
179
205
|
getModuleInstanceFromType,
|
|
180
206
|
getEntityOptionsByType,
|
|
@@ -201,10 +227,8 @@ function checkRequiredParams(params, requiredKeys) {
|
|
|
201
227
|
|
|
202
228
|
if (missingKeys.length > 0) {
|
|
203
229
|
throw Boom.badRequest(
|
|
204
|
-
`Missing Parameter${
|
|
205
|
-
|
|
206
|
-
}: ${missingKeys.join(', ')} ${
|
|
207
|
-
missingKeys.length === 1 ? 'is' : 'are'
|
|
230
|
+
`Missing Parameter${missingKeys.length === 1 ? '' : 's'
|
|
231
|
+
}: ${missingKeys.join(', ')} ${missingKeys.length === 1 ? 'is' : 'are'
|
|
208
232
|
} required.`
|
|
209
233
|
);
|
|
210
234
|
}
|
|
@@ -214,10 +238,10 @@ function checkRequiredParams(params, requiredKeys) {
|
|
|
214
238
|
/**
|
|
215
239
|
* Sets up integration-related routes on the provided Express router
|
|
216
240
|
* @param {express.Router} router - Express router instance to add routes to
|
|
217
|
-
* @param {import('../user/use-cases/
|
|
241
|
+
* @param {import('../user/use-cases/authenticate-user').AuthenticateUser} authenticateUser - Use case for multi-mode user authentication
|
|
218
242
|
* @param {Object} useCases - use cases for integration management
|
|
219
243
|
*/
|
|
220
|
-
function setIntegrationRoutes(router,
|
|
244
|
+
function setIntegrationRoutes(router, authenticateUser, useCases) {
|
|
221
245
|
const {
|
|
222
246
|
createIntegration,
|
|
223
247
|
deleteIntegrationForUser,
|
|
@@ -229,9 +253,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
229
253
|
} = useCases;
|
|
230
254
|
router.route('/api/integrations').get(
|
|
231
255
|
catchAsyncError(async (req, res) => {
|
|
232
|
-
const user = await
|
|
233
|
-
req.headers.authorization
|
|
234
|
-
);
|
|
256
|
+
const user = await authenticateUser.execute(req);
|
|
235
257
|
const userId = user.getId();
|
|
236
258
|
const integrations = await getIntegrationsForUser.execute(userId);
|
|
237
259
|
const results = {
|
|
@@ -248,9 +270,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
248
270
|
|
|
249
271
|
router.route('/api/integrations').post(
|
|
250
272
|
catchAsyncError(async (req, res) => {
|
|
251
|
-
const user = await
|
|
252
|
-
req.headers.authorization
|
|
253
|
-
);
|
|
273
|
+
const user = await authenticateUser.execute(req);
|
|
254
274
|
const userId = user.getId();
|
|
255
275
|
const params = checkRequiredParams(req.body, [
|
|
256
276
|
'entities',
|
|
@@ -271,9 +291,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
271
291
|
|
|
272
292
|
router.route('/api/integrations/:integrationId').patch(
|
|
273
293
|
catchAsyncError(async (req, res) => {
|
|
274
|
-
const user = await
|
|
275
|
-
req.headers.authorization
|
|
276
|
-
);
|
|
294
|
+
const user = await authenticateUser.execute(req);
|
|
277
295
|
const userId = user.getId();
|
|
278
296
|
const params = checkRequiredParams(req.body, ['config']);
|
|
279
297
|
|
|
@@ -288,9 +306,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
288
306
|
|
|
289
307
|
router.route('/api/integrations/:integrationId').delete(
|
|
290
308
|
catchAsyncError(async (req, res) => {
|
|
291
|
-
const user = await
|
|
292
|
-
req.headers.authorization
|
|
293
|
-
);
|
|
309
|
+
const user = await authenticateUser.execute(req);
|
|
294
310
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
295
311
|
await deleteIntegrationForUser.execute(
|
|
296
312
|
params.integrationId,
|
|
@@ -302,9 +318,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
302
318
|
|
|
303
319
|
router.route('/api/integrations/:integrationId/config/options').get(
|
|
304
320
|
catchAsyncError(async (req, res) => {
|
|
305
|
-
const user = await
|
|
306
|
-
req.headers.authorization
|
|
307
|
-
);
|
|
321
|
+
const user = await authenticateUser.execute(req);
|
|
308
322
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
309
323
|
const integration = await getIntegrationInstance.execute(
|
|
310
324
|
params.integrationId,
|
|
@@ -318,9 +332,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
318
332
|
.route('/api/integrations/:integrationId/config/options/refresh')
|
|
319
333
|
.post(
|
|
320
334
|
catchAsyncError(async (req, res) => {
|
|
321
|
-
const user = await
|
|
322
|
-
req.headers.authorization
|
|
323
|
-
);
|
|
335
|
+
const user = await authenticateUser.execute(req);
|
|
324
336
|
const params = checkRequiredParams(req.params, [
|
|
325
337
|
'integrationId',
|
|
326
338
|
]);
|
|
@@ -336,9 +348,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
336
348
|
);
|
|
337
349
|
router.route('/api/integrations/:integrationId/actions').all(
|
|
338
350
|
catchAsyncError(async (req, res) => {
|
|
339
|
-
const user = await
|
|
340
|
-
req.headers.authorization
|
|
341
|
-
);
|
|
351
|
+
const user = await authenticateUser.execute(req);
|
|
342
352
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
343
353
|
const integration = await getIntegrationInstance.execute(
|
|
344
354
|
params.integrationId,
|
|
@@ -352,9 +362,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
352
362
|
.route('/api/integrations/:integrationId/actions/:actionId/options')
|
|
353
363
|
.all(
|
|
354
364
|
catchAsyncError(async (req, res) => {
|
|
355
|
-
const user = await
|
|
356
|
-
req.headers.authorization
|
|
357
|
-
);
|
|
365
|
+
const user = await authenticateUser.execute(req);
|
|
358
366
|
const params = checkRequiredParams(req.params, [
|
|
359
367
|
'integrationId',
|
|
360
368
|
'actionId',
|
|
@@ -379,9 +387,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
379
387
|
)
|
|
380
388
|
.post(
|
|
381
389
|
catchAsyncError(async (req, res) => {
|
|
382
|
-
const user = await
|
|
383
|
-
req.headers.authorization
|
|
384
|
-
);
|
|
390
|
+
const user = await authenticateUser.execute(req);
|
|
385
391
|
const params = checkRequiredParams(req.params, [
|
|
386
392
|
'integrationId',
|
|
387
393
|
'actionId',
|
|
@@ -402,9 +408,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
402
408
|
|
|
403
409
|
router.route('/api/integrations/:integrationId/actions/:actionId').post(
|
|
404
410
|
catchAsyncError(async (req, res) => {
|
|
405
|
-
const user = await
|
|
406
|
-
req.headers.authorization
|
|
407
|
-
);
|
|
411
|
+
const user = await authenticateUser.execute(req);
|
|
408
412
|
const params = checkRequiredParams(req.params, [
|
|
409
413
|
'integrationId',
|
|
410
414
|
'actionId',
|
|
@@ -419,9 +423,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
419
423
|
|
|
420
424
|
router.route('/api/integrations/:integrationId').get(
|
|
421
425
|
catchAsyncError(async (req, res) => {
|
|
422
|
-
const user = await
|
|
423
|
-
req.headers.authorization
|
|
424
|
-
);
|
|
426
|
+
const user = await authenticateUser.execute(req);
|
|
425
427
|
|
|
426
428
|
if (!user) {
|
|
427
429
|
throw Boom.forbidden('User not found');
|
|
@@ -446,9 +448,7 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
446
448
|
|
|
447
449
|
router.route('/api/integrations/:integrationId/test-auth').get(
|
|
448
450
|
catchAsyncError(async (req, res) => {
|
|
449
|
-
const user = await
|
|
450
|
-
req.headers.authorization
|
|
451
|
-
);
|
|
451
|
+
const user = await authenticateUser.execute(req);
|
|
452
452
|
const params = checkRequiredParams(req.params, ['integrationId']);
|
|
453
453
|
const instance = await getIntegrationInstance.execute(
|
|
454
454
|
params.integrationId,
|
|
@@ -478,9 +478,9 @@ function setIntegrationRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
478
478
|
/**
|
|
479
479
|
* Sets up entity-related routes for the integration router
|
|
480
480
|
* @param {Object} router - Express router instance
|
|
481
|
-
* @param {import('../user/use-cases/
|
|
481
|
+
* @param {import('../user/use-cases/authenticate-user').AuthenticateUser} authenticateUser - Use case for multi-mode user authentication
|
|
482
482
|
*/
|
|
483
|
-
function setEntityRoutes(router,
|
|
483
|
+
function setEntityRoutes(router, authenticateUser, useCases) {
|
|
484
484
|
const {
|
|
485
485
|
getCredentialForUser,
|
|
486
486
|
getModuleInstanceFromType,
|
|
@@ -494,9 +494,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
494
494
|
|
|
495
495
|
router.route('/api/authorize').get(
|
|
496
496
|
catchAsyncError(async (req, res) => {
|
|
497
|
-
const user = await
|
|
498
|
-
req.headers.authorization
|
|
499
|
-
);
|
|
497
|
+
const user = await authenticateUser.execute(req);
|
|
500
498
|
const userId = user.getId();
|
|
501
499
|
const params = checkRequiredParams(req.query, ['entityType']);
|
|
502
500
|
const module = await getModuleInstanceFromType.execute(
|
|
@@ -517,9 +515,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
517
515
|
|
|
518
516
|
router.route('/api/authorize').post(
|
|
519
517
|
catchAsyncError(async (req, res) => {
|
|
520
|
-
const user = await
|
|
521
|
-
req.headers.authorization
|
|
522
|
-
);
|
|
518
|
+
const user = await authenticateUser.execute(req);
|
|
523
519
|
const userId = user.getId();
|
|
524
520
|
const params = checkRequiredParams(req.body, [
|
|
525
521
|
'entityType',
|
|
@@ -538,9 +534,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
538
534
|
|
|
539
535
|
router.route('/api/entity').post(
|
|
540
536
|
catchAsyncError(async (req, res) => {
|
|
541
|
-
const user = await
|
|
542
|
-
req.headers.authorization
|
|
543
|
-
);
|
|
537
|
+
const user = await authenticateUser.execute(req);
|
|
544
538
|
const userId = user.getId();
|
|
545
539
|
const params = checkRequiredParams(req.body, [
|
|
546
540
|
'entityType',
|
|
@@ -575,9 +569,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
575
569
|
|
|
576
570
|
router.route('/api/entity/options/:credentialId').get(
|
|
577
571
|
catchAsyncError(async (req, res) => {
|
|
578
|
-
const user = await
|
|
579
|
-
req.headers.authorization
|
|
580
|
-
);
|
|
572
|
+
const user = await authenticateUser.execute(req);
|
|
581
573
|
const userId = user.getId();
|
|
582
574
|
// TODO May want to pass along the user ID as well so credential ID's can't be fished???
|
|
583
575
|
// TODO **flagging this for review** -MW
|
|
@@ -601,9 +593,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
601
593
|
|
|
602
594
|
router.route('/api/entities/:entityId/test-auth').get(
|
|
603
595
|
catchAsyncError(async (req, res) => {
|
|
604
|
-
const user = await
|
|
605
|
-
req.headers.authorization
|
|
606
|
-
);
|
|
596
|
+
const user = await authenticateUser.execute(req);
|
|
607
597
|
const userId = user.getId();
|
|
608
598
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
609
599
|
const testAuthResponse = await testModuleAuth.execute(
|
|
@@ -630,9 +620,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
630
620
|
|
|
631
621
|
router.route('/api/entities/:entityId').get(
|
|
632
622
|
catchAsyncError(async (req, res) => {
|
|
633
|
-
const user = await
|
|
634
|
-
req.headers.authorization
|
|
635
|
-
);
|
|
623
|
+
const user = await authenticateUser.execute(req);
|
|
636
624
|
const userId = user.getId();
|
|
637
625
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
638
626
|
const module = await getModule.execute(params.entityId, userId);
|
|
@@ -643,9 +631,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
643
631
|
|
|
644
632
|
router.route('/api/entities/:entityId/options').post(
|
|
645
633
|
catchAsyncError(async (req, res) => {
|
|
646
|
-
const user = await
|
|
647
|
-
req.headers.authorization
|
|
648
|
-
);
|
|
634
|
+
const user = await authenticateUser.execute(req);
|
|
649
635
|
const userId = user.getId();
|
|
650
636
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
651
637
|
|
|
@@ -660,9 +646,7 @@ function setEntityRoutes(router, getUserFromBearerToken, useCases) {
|
|
|
660
646
|
|
|
661
647
|
router.route('/api/entities/:entityId/options/refresh').post(
|
|
662
648
|
catchAsyncError(async (req, res) => {
|
|
663
|
-
const user = await
|
|
664
|
-
req.headers.authorization
|
|
665
|
-
);
|
|
649
|
+
const user = await authenticateUser.execute(req);
|
|
666
650
|
const userId = user.getId();
|
|
667
651
|
const params = checkRequiredParams(req.params, ['entityId']);
|
|
668
652
|
const updatedOptions = await refreshEntityOptions.execute(
|