@friggframework/core 2.0.0--canary.461.d1a7bbb.0 → 2.0.0--canary.461.4066059.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.
@@ -118,9 +118,16 @@ async function checkDatabaseState(dbType) {
118
118
  }
119
119
 
120
120
  const schemaPath = getPrismaSchemaPath(dbType);
121
+ const prismaBin = getPrismaBinaryPath();
122
+
123
+ // Use direct path instead of npx to avoid WASM file resolution issues
124
+ const isDirectBinary = prismaBin !== 'npx prisma';
125
+ const command = isDirectBinary
126
+ ? `${prismaBin} migrate status --schema=${schemaPath}`
127
+ : `npx prisma migrate status --schema=${schemaPath}`;
121
128
 
122
129
  const output = execSync(
123
- `npx prisma migrate status --schema=${schemaPath}`,
130
+ command,
124
131
  {
125
132
  encoding: 'utf8',
126
133
  stdio: 'pipe',
@@ -63,8 +63,8 @@ const {
63
63
  GetUserFromAdopterJwt,
64
64
  } = require('../user/use-cases/get-user-from-adopter-jwt');
65
65
  const {
66
- GetUserFromSharedSecret,
67
- } = require('../user/use-cases/get-user-from-shared-secret');
66
+ AuthenticateWithSharedSecret,
67
+ } = require('../user/use-cases/authenticate-with-shared-secret');
68
68
  const {
69
69
  AuthenticateUser,
70
70
  } = require('../user/use-cases/authenticate-user');
@@ -95,16 +95,13 @@ function createIntegrationRouter() {
95
95
  userConfig,
96
96
  });
97
97
 
98
- const getUserFromSharedSecret = new GetUserFromSharedSecret({
99
- userRepository,
100
- userConfig,
101
- });
98
+ const authenticateWithSharedSecret = new AuthenticateWithSharedSecret();
102
99
 
103
100
  const authenticateUser = new AuthenticateUser({
104
101
  getUserFromBearerToken,
105
102
  getUserFromXFriggHeaders,
106
103
  getUserFromAdopterJwt,
107
- getUserFromSharedSecret,
104
+ authenticateWithSharedSecret,
108
105
  userConfig,
109
106
  });
110
107
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.461.d1a7bbb.0",
4
+ "version": "2.0.0--canary.461.4066059.0",
5
5
  "dependencies": {
6
6
  "@aws-sdk/client-apigatewaymanagementapi": "^3.588.0",
7
7
  "@aws-sdk/client-kms": "^3.588.0",
@@ -38,9 +38,9 @@
38
38
  }
39
39
  },
40
40
  "devDependencies": {
41
- "@friggframework/eslint-config": "2.0.0--canary.461.d1a7bbb.0",
42
- "@friggframework/prettier-config": "2.0.0--canary.461.d1a7bbb.0",
43
- "@friggframework/test": "2.0.0--canary.461.d1a7bbb.0",
41
+ "@friggframework/eslint-config": "2.0.0--canary.461.4066059.0",
42
+ "@friggframework/prettier-config": "2.0.0--canary.461.4066059.0",
43
+ "@friggframework/test": "2.0.0--canary.461.4066059.0",
44
44
  "@prisma/client": "^6.17.0",
45
45
  "@types/lodash": "4.17.15",
46
46
  "@typescript-eslint/eslint-plugin": "^8.0.0",
@@ -80,5 +80,5 @@
80
80
  "publishConfig": {
81
81
  "access": "public"
82
82
  },
83
- "gitHead": "d1a7bbb21e49abe96c803b1f3433e8d3bbeaa478"
83
+ "gitHead": "4066059afecf11231ca7ff94cc4483b47f5b6e74"
84
84
  }
@@ -21,20 +21,20 @@ class AuthenticateUser {
21
21
  * @param {import('./get-user-from-bearer-token').GetUserFromBearerToken} params.getUserFromBearerToken - Use case for bearer token auth.
22
22
  * @param {import('./get-user-from-x-frigg-headers').GetUserFromXFriggHeaders} params.getUserFromXFriggHeaders - Use case for x-frigg header auth.
23
23
  * @param {import('./get-user-from-adopter-jwt').GetUserFromAdopterJwt} params.getUserFromAdopterJwt - Use case for adopter JWT auth.
24
- * @param {import('./get-user-from-shared-secret').GetUserFromSharedSecret} params.getUserFromSharedSecret - Use case for shared secret auth.
24
+ * @param {import('./authenticate-with-shared-secret').AuthenticateWithSharedSecret} params.authenticateWithSharedSecret - Use case for validating shared secret.
25
25
  * @param {Object} params.userConfig - The user config in the app definition.
26
26
  */
27
27
  constructor({
28
28
  getUserFromBearerToken,
29
29
  getUserFromXFriggHeaders,
30
30
  getUserFromAdopterJwt,
31
- getUserFromSharedSecret,
31
+ authenticateWithSharedSecret,
32
32
  userConfig,
33
33
  }) {
34
34
  this.getUserFromBearerToken = getUserFromBearerToken;
35
35
  this.getUserFromXFriggHeaders = getUserFromXFriggHeaders;
36
36
  this.getUserFromAdopterJwt = getUserFromAdopterJwt;
37
- this.getUserFromSharedSecret = getUserFromSharedSecret;
37
+ this.authenticateWithSharedSecret = authenticateWithSharedSecret;
38
38
  this.userConfig = userConfig;
39
39
  }
40
40
 
@@ -56,8 +56,10 @@ class AuthenticateUser {
56
56
  if (authModes.sharedSecret !== false) {
57
57
  const apiKey = req.headers['x-frigg-api-key'];
58
58
  if (apiKey) {
59
- return await this.getUserFromSharedSecret.execute(
60
- apiKey,
59
+ // Validate the API key (authentication)
60
+ await this.authenticateWithSharedSecret.execute(apiKey);
61
+ // Get user from x-frigg headers (authorization)
62
+ return await this.getUserFromXFriggHeaders.execute(
61
63
  appUserId,
62
64
  appOrgId
63
65
  );
@@ -0,0 +1,48 @@
1
+ const Boom = require('@hapi/boom');
2
+
3
+ /**
4
+ * Use case for authenticating requests with shared secret API key.
5
+ * This use case ONLY validates the authenticity of the request via API key.
6
+ * It does NOT retrieve user data - that's handled by GetUserFromXFriggHeaders.
7
+ *
8
+ * Used for backend-to-backend communication where the secret proves
9
+ * the request is legitimate, but user identification comes from x-frigg headers.
10
+ *
11
+ * @class AuthenticateWithSharedSecret
12
+ */
13
+ class AuthenticateWithSharedSecret {
14
+ /**
15
+ * Creates a new AuthenticateWithSharedSecret instance.
16
+ * @param {Object} params - Configuration parameters (none needed currently, but kept for consistency).
17
+ */
18
+ constructor() {
19
+ // No dependencies needed - just validates against env var
20
+ }
21
+
22
+ /**
23
+ * Validates the provided shared secret against FRIGG_API_KEY.
24
+ * @async
25
+ * @param {string} providedSecret - Secret from x-frigg-api-key header
26
+ * @returns {Promise<boolean>} True if valid (or throws error if invalid)
27
+ * @throws {Boom} 500 if FRIGG_API_KEY not configured
28
+ * @throws {Boom} 401 if provided secret doesn't match
29
+ */
30
+ async execute(providedSecret) {
31
+ // Validate secret
32
+ const expectedSecret = process.env.FRIGG_API_KEY;
33
+ if (!expectedSecret) {
34
+ throw Boom.badImplementation(
35
+ 'FRIGG_API_KEY environment variable is not configured. ' +
36
+ 'Set FRIGG_API_KEY to enable shared secret authentication.'
37
+ );
38
+ }
39
+
40
+ if (!providedSecret || providedSecret !== expectedSecret) {
41
+ throw Boom.unauthorized('Invalid API key');
42
+ }
43
+
44
+ return true;
45
+ }
46
+ }
47
+
48
+ module.exports = { AuthenticateWithSharedSecret };
@@ -1,124 +0,0 @@
1
- const Boom = require('@hapi/boom');
2
- const { User } = require('../user');
3
-
4
- /**
5
- * Use case for authenticating requests with shared secret API key.
6
- * Used for backend-to-backend communication where the secret proves
7
- * authenticity, and x-frigg headers identify the user/org.
8
- *
9
- * This separates authentication (proving legitimacy via API key) from
10
- * authorization (identifying user/org via x-frigg headers).
11
- *
12
- * @class GetUserFromSharedSecret
13
- */
14
- class GetUserFromSharedSecret {
15
- /**
16
- * Creates a new GetUserFromSharedSecret instance.
17
- * @param {Object} params - Configuration parameters.
18
- * @param {import('../repositories/user-repository-interface').UserRepositoryInterface} params.userRepository - Repository for user data operations.
19
- * @param {Object} params.userConfig - The user config in the app definition.
20
- */
21
- constructor({ userRepository, userConfig }) {
22
- this.userRepository = userRepository;
23
- this.userConfig = userConfig;
24
- }
25
-
26
- /**
27
- * Validates shared secret and extracts user from x-frigg headers.
28
- * @async
29
- * @param {string} providedSecret - Secret from x-frigg-api-key header
30
- * @param {string} [appUserId] - From x-frigg-appuserid header
31
- * @param {string} [appOrgId] - From x-frigg-apporgid header
32
- * @returns {Promise<import('../user').User>} The authenticated user object.
33
- * @throws {Boom} 500 if FRIGG_API_KEY not configured
34
- * @throws {Boom} 401 if provided secret doesn't match
35
- * @throws {Boom} 400 if no user identifiers provided or if they refer to different users
36
- */
37
- async execute(providedSecret, appUserId, appOrgId) {
38
- // Validate secret
39
- const expectedSecret = process.env.FRIGG_API_KEY;
40
- if (!expectedSecret) {
41
- throw Boom.badImplementation(
42
- 'FRIGG_API_KEY environment variable is not configured. ' +
43
- 'Set FRIGG_API_KEY to enable shared secret authentication.'
44
- );
45
- }
46
-
47
- if (!providedSecret || providedSecret !== expectedSecret) {
48
- throw Boom.unauthorized('Invalid API key');
49
- }
50
-
51
- // Require at least one user identifier
52
- if (!appUserId && !appOrgId) {
53
- throw Boom.badRequest(
54
- 'At least one of x-frigg-appuserid or x-frigg-apporgid headers is required with shared secret authentication'
55
- );
56
- }
57
-
58
- // Find or create users (reuse logic from GetUserFromXFriggHeaders)
59
- let individualUserData = null;
60
- let organizationUserData = null;
61
-
62
- if (appUserId && this.userConfig.individualUserRequired !== false) {
63
- individualUserData =
64
- await this.userRepository.findIndividualUserByAppUserId(
65
- appUserId
66
- );
67
- }
68
-
69
- if (appOrgId && this.userConfig.organizationUserRequired) {
70
- organizationUserData =
71
- await this.userRepository.findOrganizationUserByAppOrgId(
72
- appOrgId
73
- );
74
- }
75
-
76
- // VALIDATION: If both IDs provided and both users exist, verify they match
77
- if (
78
- appUserId &&
79
- appOrgId &&
80
- individualUserData &&
81
- organizationUserData
82
- ) {
83
- const individualOrgId =
84
- individualUserData.organizationUser?.toString();
85
- const expectedOrgId = organizationUserData.id?.toString();
86
-
87
- if (individualOrgId !== expectedOrgId) {
88
- throw Boom.badRequest(
89
- 'User ID mismatch: x-frigg-appuserid and x-frigg-apporgid refer to different users. ' +
90
- 'Provide only one identifier or ensure they belong to the same user.'
91
- );
92
- }
93
- }
94
-
95
- // Auto-create user if not found
96
- if (!individualUserData && !organizationUserData) {
97
- if (appUserId) {
98
- individualUserData =
99
- await this.userRepository.createIndividualUser({
100
- appUserId,
101
- username: `api-user-${appUserId}`,
102
- email: `${appUserId}@api.local`,
103
- });
104
- } else {
105
- organizationUserData =
106
- await this.userRepository.createOrganizationUser({
107
- appOrgId,
108
- });
109
- }
110
- }
111
-
112
- return new User(
113
- individualUserData,
114
- organizationUserData,
115
- this.userConfig.usePassword,
116
- this.userConfig.primary,
117
- this.userConfig.individualUserRequired,
118
- this.userConfig.organizationUserRequired
119
- );
120
- }
121
- }
122
-
123
- module.exports = { GetUserFromSharedSecret };
124
-