@friggframework/core 2.0.0--canary.681.2df9ef0.0 → 2.0.0--canary.683.f45da33.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/README.md +37 -1
- package/application/commands/integration-commands.js +20 -10
- package/application/index.js +6 -2
- package/credential/use-cases/credential-operations-for-user.js +9 -1
- package/credential/use-cases/reauthorize-credential-for-user.js +14 -4
- package/database/encryption/encryption-schema-registry.js +7 -0
- package/database/organization-where.js +18 -0
- package/generated/prisma-mongodb/edge.js +5 -3
- package/generated/prisma-mongodb/index-browser.js +2 -0
- package/generated/prisma-mongodb/index.d.ts +115 -2
- package/generated/prisma-mongodb/index.js +5 -3
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +15 -0
- package/generated/prisma-mongodb/wasm.js +5 -3
- package/generated/prisma-postgresql/edge.js +5 -3
- package/generated/prisma-postgresql/index-browser.js +2 -0
- package/generated/prisma-postgresql/index.d.ts +131 -2
- package/generated/prisma-postgresql/index.js +5 -3
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +15 -0
- package/generated/prisma-postgresql/wasm.js +5 -3
- package/handlers/app-definition-loader.js +25 -8
- package/handlers/backend-utils.js +31 -25
- package/handlers/routers/health.js +1 -4
- package/handlers/workers/integration-defined-workers.js +5 -2
- package/index.js +10 -2
- package/integrations/index.js +0 -4
- package/integrations/integration-router.js +101 -52
- package/integrations/repositories/integration-not-found.js +14 -0
- package/integrations/repositories/integration-repository-documentdb.js +34 -3
- package/integrations/repositories/integration-repository-interface.js +17 -1
- package/integrations/repositories/integration-repository-mongo.js +59 -76
- package/integrations/repositories/integration-repository-postgres.js +62 -76
- package/integrations/tests/doubles/test-integration-repository.js +12 -1
- package/integrations/use-cases/create-integration.js +55 -20
- package/integrations/use-cases/get-integrations-for-user.js +80 -40
- package/integrations/use-cases/index.js +5 -1
- package/integrations/use-cases/integration-operations-for-user.js +55 -24
- package/integrations/use-cases/resolve-integration-ownership.js +177 -0
- package/integrations/utils/map-integration-dto.js +1 -15
- package/management-api/management-api-config.js +3 -0
- package/management-api/openapi/components.js +46 -1
- package/management-api/openapi/v2-operations.js +14 -1
- package/management-api/v2/dependencies.js +58 -14
- package/management-api/v2/dto.js +17 -0
- package/management-api/v2/handlers/authorization.js +1 -0
- package/management-api/v2/handlers/entities.js +10 -7
- package/management-api/v2/handlers/integrations.js +6 -3
- package/management-api/v2/request.js +32 -1
- package/modules/entity-scope.js +15 -0
- package/modules/entity-type-registry.js +311 -0
- package/modules/index.js +14 -0
- package/modules/repositories/module-repository-documentdb.js +41 -1
- package/modules/repositories/module-repository-interface.js +19 -2
- package/modules/repositories/module-repository-mongo.js +64 -73
- package/modules/repositories/module-repository-postgres.js +63 -73
- package/modules/scope-config.js +177 -0
- package/modules/scope-policy.js +96 -0
- package/modules/scope-resolution.js +288 -0
- package/modules/scope-visibility.js +212 -0
- package/modules/tests/doubles/ownership-matching.js +18 -0
- package/modules/use-cases/authorize-entity-for-user.js +59 -0
- package/modules/use-cases/entity-operations-for-user.js +50 -13
- package/modules/use-cases/entity-types.js +62 -14
- package/modules/use-cases/execute-entity-proxy-request.js +15 -0
- package/modules/use-cases/get-entities-for-user.js +16 -5
- package/modules/use-cases/get-entity-module-for-user.js +23 -3
- package/modules/use-cases/get-entity-options-by-id.js +5 -2
- package/modules/use-cases/get-module.js +5 -2
- package/modules/use-cases/manage-access.js +21 -0
- package/modules/use-cases/multi-step-authorization.js +36 -12
- package/modules/use-cases/process-authorization-callback.js +52 -18
- package/modules/use-cases/refresh-entity-options.js +5 -2
- package/modules/use-cases/test-module-auth.js +5 -2
- package/package.json +5 -5
- package/prisma-mongodb/schema.prisma +15 -0
- package/prisma-postgresql/migrations/20261016000000_add_entity_integration_organization/migration.sql +25 -0
- package/prisma-postgresql/schema.prisma +15 -0
- package/types/index.d.ts +1 -0
- package/types/modules/index.d.ts +145 -0
- package/types/user/index.d.ts +7 -0
- package/user/use-cases/authenticate-user.js +7 -1
- package/user/user.js +24 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const Boom = require('@hapi/boom');
|
|
2
2
|
const { getLogger } = require('../../logs');
|
|
3
|
+
const { AUTH_SOURCES } = require('../user');
|
|
3
4
|
|
|
4
5
|
const log = getLogger('frigg.user.authentication');
|
|
5
6
|
|
|
@@ -68,10 +69,13 @@ class AuthenticateUser {
|
|
|
68
69
|
// Validate the API key (authentication)
|
|
69
70
|
await this.authenticateWithSharedSecret.execute(apiKey);
|
|
70
71
|
// Get user from x-frigg headers (authorization)
|
|
71
|
-
|
|
72
|
+
const user = await this.getUserFromXFriggHeaders.execute(
|
|
72
73
|
appUserId,
|
|
73
74
|
appOrgId
|
|
74
75
|
);
|
|
76
|
+
// The app's own backend: trusted to manage organization things.
|
|
77
|
+
user.setAuthSource(AUTH_SOURCES.SHARED_SECRET);
|
|
78
|
+
return user;
|
|
75
79
|
}
|
|
76
80
|
log.debug('No x-frigg-api-key header, skipping shared secret', {
|
|
77
81
|
eventName: `${log.name}.shared_secret_skipped`,
|
|
@@ -90,6 +94,7 @@ class AuthenticateUser {
|
|
|
90
94
|
// Detect JWT format (3 parts separated by dots)
|
|
91
95
|
if (token && token.split('.').length === 3) {
|
|
92
96
|
const user = await this.getUserFromAdopterJwt.execute(token);
|
|
97
|
+
user.setAuthSource(AUTH_SOURCES.ADOPTER_JWT);
|
|
93
98
|
// Validate x-frigg headers match JWT claims if present
|
|
94
99
|
if (appUserId || appOrgId) {
|
|
95
100
|
this.validateUserMatch(user, appUserId, appOrgId);
|
|
@@ -106,6 +111,7 @@ class AuthenticateUser {
|
|
|
106
111
|
const user = await this.getUserFromBearerToken.execute(
|
|
107
112
|
req.headers.authorization
|
|
108
113
|
);
|
|
114
|
+
user.setAuthSource(AUTH_SOURCES.BEARER_TOKEN);
|
|
109
115
|
// Validate x-frigg headers match token user if present
|
|
110
116
|
if (appUserId || appOrgId) {
|
|
111
117
|
this.validateUserMatch(user, appUserId, appOrgId);
|
package/user/user.js
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
const bcrypt = require('bcryptjs');
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* How the request that produced a `User` proved who it is. Set by
|
|
5
|
+
* AuthenticateUser, never inferred from a missing value. Organization roles
|
|
6
|
+
* (ADR-056 §3, §3.6) depend on it: a shared-secret caller is the app's own
|
|
7
|
+
* backend and is trusted to manage; a person with a token has the role the
|
|
8
|
+
* token carries, or `MEMBER`.
|
|
9
|
+
*/
|
|
10
|
+
const AUTH_SOURCES = Object.freeze({
|
|
11
|
+
SHARED_SECRET: 'shared-secret',
|
|
12
|
+
ADOPTER_JWT: 'adopter-jwt',
|
|
13
|
+
BEARER_TOKEN: 'bearer-token',
|
|
14
|
+
});
|
|
15
|
+
|
|
3
16
|
/**
|
|
4
17
|
* Represents a user in the system. The User class is a domain entity,
|
|
5
18
|
* @class User
|
|
@@ -21,6 +34,8 @@ class User {
|
|
|
21
34
|
// Organization role from an adopter token claim (ADR-056 §2). Per request:
|
|
22
35
|
// the role stored on a membership is only what the first token carried.
|
|
23
36
|
this.orgRole = null;
|
|
37
|
+
// How this request authenticated (one of AUTH_SOURCES); null until AuthenticateUser says.
|
|
38
|
+
this.authSource = null;
|
|
24
39
|
|
|
25
40
|
this.config = {
|
|
26
41
|
primary,
|
|
@@ -84,6 +99,14 @@ class User {
|
|
|
84
99
|
return this.config.individualUserRequired;
|
|
85
100
|
}
|
|
86
101
|
|
|
102
|
+
getAuthSource() {
|
|
103
|
+
return this.authSource;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
setAuthSource(authSource) {
|
|
107
|
+
this.authSource = authSource ?? null;
|
|
108
|
+
}
|
|
109
|
+
|
|
87
110
|
getOrgRole() {
|
|
88
111
|
return this.orgRole;
|
|
89
112
|
}
|
|
@@ -149,4 +172,4 @@ class User {
|
|
|
149
172
|
}
|
|
150
173
|
}
|
|
151
174
|
|
|
152
|
-
module.exports = { User };
|
|
175
|
+
module.exports = { User, AUTH_SOURCES };
|