@friggframework/core 2.0.0--canary.686.df38e8e.0 → 2.0.0--canary.710.9045bbc.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/CHANGELOG.md +0 -16
- package/CLAUDE.md +41 -29
- package/README.md +0 -105
- package/application/commands/README.md +17 -11
- package/application/commands/entity-commands.js +18 -60
- package/application/commands/integration-commands.js +73 -20
- package/application/commands/scheduler-commands.js +7 -11
- package/application/commands/user-commands.js +5 -17
- package/application/index.js +2 -6
- package/core/Worker.js +7 -31
- package/core/create-handler.js +0 -9
- package/credential/repositories/credential-repository-documentdb.js +0 -34
- package/credential/repositories/credential-repository-interface.js +0 -15
- package/credential/repositories/credential-repository-mongo.js +0 -23
- package/credential/repositories/credential-repository-postgres.js +0 -28
- package/database/config.js +24 -48
- package/database/documentdb-encryption-service.js +22 -9
- package/database/documentdb-utils.js +0 -2
- package/database/encryption/README.md +17 -81
- package/database/encryption/documentdb-encryption-service.md +1 -78
- package/database/encryption/encryption-schema-registry.js +46 -123
- package/database/encryption/field-encryption-service.js +5 -69
- package/database/encryption/integration-mapping-encryption.js +1 -1
- package/database/prisma.js +38 -15
- package/database/use-cases/check-encryption-health-use-case.js +52 -43
- package/errors/index.js +4 -0
- package/errors/mapping-already-exists-error.js +14 -0
- package/generated/prisma-mongodb/edge.js +4 -43
- package/generated/prisma-mongodb/index-browser.js +1 -40
- package/generated/prisma-mongodb/index.d.ts +111 -4739
- package/generated/prisma-mongodb/index.js +4 -43
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +0 -92
- package/generated/prisma-mongodb/wasm.js +4 -43
- package/generated/prisma-postgresql/edge.js +4 -43
- package/generated/prisma-postgresql/index-browser.js +1 -40
- package/generated/prisma-postgresql/index.d.ts +33 -4966
- package/generated/prisma-postgresql/index.js +4 -43
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +0 -87
- package/generated/prisma-postgresql/wasm.js +4 -43
- package/handlers/WEBHOOKS.md +29 -0
- package/handlers/app-definition-loader.js +19 -121
- package/handlers/app-handler-helpers.js +3 -25
- package/handlers/backend-utils.js +25 -31
- package/handlers/middleware/admin-auth.js +1 -14
- package/handlers/routers/auth.js +10 -46
- package/handlers/routers/health.js +4 -13
- package/handlers/routers/integration-defined-routers.js +92 -144
- package/handlers/routers/integration-webhook-routers.js +64 -102
- package/handlers/workers/integration-defined-workers.js +2 -5
- package/index.js +3 -65
- package/infrastructure/scheduler/eventbridge-scheduler-adapter.js +67 -13
- package/infrastructure/scheduler/index.js +6 -19
- package/infrastructure/scheduler/scheduler-service-factory.js +7 -55
- package/integrations/index.js +0 -1
- package/integrations/integration-base.js +29 -0
- package/integrations/integration-router.js +96 -131
- package/integrations/repositories/integration-mapping-repository-documentdb.js +50 -0
- package/integrations/repositories/integration-mapping-repository-interface.js +15 -0
- package/integrations/repositories/integration-mapping-repository-mongo.js +29 -0
- package/integrations/repositories/integration-mapping-repository-postgres.js +30 -0
- package/integrations/repositories/integration-mapping-repository.js +29 -0
- package/integrations/repositories/integration-repository-documentdb.js +35 -35
- package/integrations/repositories/integration-repository-interface.js +31 -17
- package/integrations/repositories/integration-repository-mongo.js +129 -60
- package/integrations/repositories/integration-repository-postgres.js +134 -62
- package/integrations/repositories/process-repository-mongo.js +1 -1
- package/integrations/tests/doubles/test-integration-repository.js +1 -12
- package/integrations/use-cases/add-entities-to-integration.js +92 -0
- package/integrations/use-cases/create-integration.js +75 -72
- package/integrations/use-cases/get-integrations-for-user.js +40 -80
- package/integrations/use-cases/index.js +1 -7
- package/integrations/use-cases/remove-entities-from-integration.js +70 -0
- package/integrations/utils/assert-entity-ids-input.js +42 -0
- package/integrations/utils/map-integration-dto.js +14 -43
- package/jest-setup.js +13 -2
- package/jest-teardown.js +5 -2
- package/jest.config.js +4 -0
- package/jest.db.config.js +23 -0
- package/modules/index.js +0 -14
- package/modules/module-factory.js +0 -12
- package/modules/module.js +2 -53
- package/modules/repositories/module-repository-documentdb.js +6 -51
- package/modules/repositories/module-repository-interface.js +2 -19
- package/modules/repositories/module-repository-mongo.js +74 -67
- package/modules/repositories/module-repository-postgres.js +74 -66
- package/modules/repositories/module-repository.js +1 -2
- package/modules/requester/requester.js +2 -27
- package/modules/use-cases/get-entities-for-user.js +13 -26
- package/modules/use-cases/get-entity-options-by-id.js +4 -10
- package/modules/use-cases/get-entity-options-by-type.js +1 -1
- package/modules/use-cases/get-module-instance-from-type.js +1 -1
- package/modules/use-cases/get-module.js +4 -10
- package/modules/use-cases/process-authorization-callback.js +19 -53
- package/modules/use-cases/refresh-entity-options.js +4 -10
- package/modules/use-cases/test-module-auth.js +4 -10
- package/modules/utils/map-module-dto.js +5 -3
- package/modules/utils/to-credential-id.js +14 -0
- package/package.json +7 -6
- package/prisma-mongodb/schema.prisma +0 -92
- package/prisma-postgresql/schema.prisma +0 -87
- package/queues/index.js +0 -25
- package/queues/queuer-util.js +6 -5
- package/types/index.d.ts +0 -2
- package/user/repositories/user-repository-documentdb.js +2 -27
- package/user/repositories/user-repository-interface.js +0 -18
- package/user/repositories/user-repository-mongo.js +0 -24
- package/user/repositories/user-repository-postgres.js +0 -18
- package/user/tests/doubles/test-user-repository.js +1 -1
- package/user/use-cases/authenticate-user.js +1 -7
- package/user/use-cases/get-user-from-adopter-jwt.js +124 -95
- package/user/use-cases/get-user-from-bearer-token.js +7 -2
- package/user/use-cases/get-user-from-x-frigg-headers.js +80 -83
- package/user/user.js +1 -64
- package/credential/use-cases/credential-operations-for-user.js +0 -202
- package/credential/use-cases/reauthorize-credential-for-user.js +0 -73
- package/database/encryption/encryption-config.js +0 -219
- package/database/encryption/test-support/fake-ciphertext.js +0 -15
- package/database/organization-where.js +0 -18
- package/database/unique-violation.js +0 -25
- package/extensions/bootstrap-runner.js +0 -43
- package/extensions/extension-loader.js +0 -187
- package/extensions/index.js +0 -41
- package/extensions/initialize-app.js +0 -123
- package/extensions/route-mounter.js +0 -103
- package/extensions/schema-composer.js +0 -188
- package/infrastructure/scheduler/netlify-scheduler-adapter.js +0 -220
- package/infrastructure/scheduler/scheduled-job-repository.js +0 -118
- package/integrations/repositories/integration-not-found.js +0 -14
- package/integrations/schedule-config.js +0 -80
- package/integrations/use-cases/dispatch-ongoing-syncs.js +0 -100
- package/integrations/use-cases/integration-operations-for-user.js +0 -256
- package/integrations/use-cases/resolve-integration-ownership.js +0 -177
- package/management-api/create-management-api-router.js +0 -49
- package/management-api/error-response.js +0 -116
- package/management-api/management-api-config.js +0 -151
- package/management-api/meta-router.js +0 -76
- package/management-api/openapi/build-openapi.js +0 -144
- package/management-api/openapi/components.js +0 -408
- package/management-api/openapi/v1-operations.js +0 -83
- package/management-api/openapi/v2-operations.js +0 -264
- package/management-api/route-registry.js +0 -411
- package/management-api/test-support/http-client.js +0 -39
- package/management-api/use-cases/get-management-api-meta.js +0 -57
- package/management-api/v1-deprecation.js +0 -120
- package/management-api/v2/create-v2-router.js +0 -85
- package/management-api/v2/dependencies.js +0 -281
- package/management-api/v2/dto.js +0 -143
- package/management-api/v2/handlers/authorization.js +0 -94
- package/management-api/v2/handlers/credentials.js +0 -33
- package/management-api/v2/handlers/entities.js +0 -77
- package/management-api/v2/handlers/integrations.js +0 -128
- package/management-api/v2/handlers/proxy.js +0 -34
- package/management-api/v2/request.js +0 -85
- package/management-api/v2/test-support/fake-dependencies.js +0 -103
- package/modules/domain/authorization-session.js +0 -144
- package/modules/entity-scope.js +0 -15
- package/modules/entity-type-registry.js +0 -311
- package/modules/proxy/proxy-errors.js +0 -20
- package/modules/proxy/proxy-path.js +0 -179
- package/modules/proxy/proxy-policy.js +0 -248
- package/modules/repositories/authorization-session-repository-documentdb.js +0 -112
- package/modules/repositories/authorization-session-repository-factory.js +0 -31
- package/modules/repositories/authorization-session-repository-interface.js +0 -47
- package/modules/repositories/authorization-session-repository-prisma.js +0 -87
- package/modules/repositories/entity-not-found.js +0 -18
- package/modules/requester/proxy-request.js +0 -244
- package/modules/scope-config.js +0 -192
- package/modules/scope-policy.js +0 -112
- package/modules/scope-resolution.js +0 -288
- package/modules/scope-visibility.js +0 -247
- package/modules/tests/doubles/in-memory-authorization-session-repository.js +0 -45
- package/modules/tests/doubles/ownership-matching.js +0 -18
- package/modules/use-cases/authorize-entity-for-user.js +0 -61
- package/modules/use-cases/create-entity-from-credential.js +0 -113
- package/modules/use-cases/entity-operations-for-user.js +0 -162
- package/modules/use-cases/entity-types.js +0 -139
- package/modules/use-cases/execute-entity-proxy-request.js +0 -286
- package/modules/use-cases/get-authorization-requirements.js +0 -100
- package/modules/use-cases/get-entity-module-for-user.js +0 -113
- package/modules/use-cases/manage-access.js +0 -21
- package/modules/use-cases/multi-step-authorization.js +0 -329
- package/prisma-postgresql/migrations/20261003000000_add_authorization_session/migration.sql +0 -28
- package/prisma-postgresql/migrations/20261015000000_add_organization_membership/migration.sql +0 -26
- package/prisma-postgresql/migrations/20261016000000_add_entity_integration_organization/migration.sql +0 -25
- package/prisma-postgresql/migrations/20261017000000_add_scheduled_job/migration.sql +0 -28
- package/providers/index.js +0 -23
- package/providers/resolve-provider.js +0 -93
- package/providers/runtime-detection.js +0 -124
- package/queues/providers/index.js +0 -11
- package/queues/providers/netlify-background-provider.js +0 -187
- package/queues/providers/qstash-queue-provider.js +0 -219
- package/queues/providers/sqs-queue-provider.js +0 -70
- package/queues/queue-client-interface.js +0 -55
- package/queues/queue-message-auth.js +0 -193
- package/queues/queue-provider-factory.js +0 -101
- package/queues/queue-provider.js +0 -65
- package/queues/sqs-queue-client.js +0 -81
- package/types/modules/index.d.ts +0 -197
- package/types/user/index.d.ts +0 -134
- package/user/adopter-jwt-config.js +0 -177
- package/user/adopter-jwt-errors.js +0 -59
- package/user/adopter-token-verifier.js +0 -122
- package/user/app-user-helpers.js +0 -97
- package/user/create-user-authentication.js +0 -64
- package/user/membership.js +0 -51
- package/user/repositories/organization-membership-record.js +0 -19
- package/user/repositories/organization-membership-repository-documentdb.js +0 -106
- package/user/repositories/organization-membership-repository-factory.js +0 -42
- package/user/repositories/organization-membership-repository-interface.js +0 -57
- package/user/repositories/organization-membership-repository-mongo.js +0 -13
- package/user/repositories/organization-membership-repository-postgres.js +0 -29
- package/user/repositories/organization-membership-repository-prisma.js +0 -81
- package/user/tests/doubles/adopter-jwt-fixtures.js +0 -220
- package/user/use-cases/ensure-organization-membership.js +0 -92
- package/user/use-cases/find-individual-users-by-organization.js +0 -54
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
const { getLogger } = require('../../logs');
|
|
2
|
-
const { isPresent, implicitMembership } = require('../membership');
|
|
3
|
-
|
|
4
|
-
const log = getLogger('frigg.user.membership');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Makes sure a person is a member of the organization a request is acting in
|
|
8
|
-
* (ADR-056 §3.6). Shared by the adopter-token and x-frigg header paths.
|
|
9
|
-
*
|
|
10
|
-
* - Already a member (a stored row, or the legacy `organizationId` pointer
|
|
11
|
-
* read as an implicit membership): nothing is written.
|
|
12
|
-
* - Not a member: a membership is added, unless the caller asks for existing
|
|
13
|
-
* memberships only (`requireExisting`), in which case nothing is written and
|
|
14
|
-
* `membership` is null so the caller can refuse.
|
|
15
|
-
* - The legacy `organizationId` is set when the person has none (their first
|
|
16
|
-
* link) and never changed afterwards. It is a pointer for old readers, not
|
|
17
|
-
* the active organization: that is whichever organization the request names.
|
|
18
|
-
*
|
|
19
|
-
* Adding is an idempotent upsert, so two first logins racing for different
|
|
20
|
-
* organizations both succeed.
|
|
21
|
-
*
|
|
22
|
-
* @class EnsureOrganizationMembership
|
|
23
|
-
*/
|
|
24
|
-
class EnsureOrganizationMembership {
|
|
25
|
-
/**
|
|
26
|
-
* @param {Object} params
|
|
27
|
-
* @param {import('../repositories/user-repository-interface').UserRepositoryInterface} params.userRepository
|
|
28
|
-
* @param {import('../repositories/organization-membership-repository-interface').OrganizationMembershipRepositoryInterface} params.organizationMembershipRepository
|
|
29
|
-
*/
|
|
30
|
-
constructor({ userRepository, organizationMembershipRepository }) {
|
|
31
|
-
this.userRepository = userRepository;
|
|
32
|
-
this.organizationMembershipRepository = organizationMembershipRepository;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @param {Object} params
|
|
37
|
-
* @param {Object|null} params.individual Individual user as the repository returns it.
|
|
38
|
-
* @param {Object|null} params.organization The active organization user.
|
|
39
|
-
* @param {string|null} [params.orgRole] Role to store with a new membership.
|
|
40
|
-
* @param {boolean} [params.requireExisting=false] Refuse to add.
|
|
41
|
-
* @returns {Promise<{individual: Object|null, membership: Object|null}>}
|
|
42
|
-
* `individual` may be the updated record (legacy pointer set).
|
|
43
|
-
*/
|
|
44
|
-
async execute({
|
|
45
|
-
individual,
|
|
46
|
-
organization,
|
|
47
|
-
orgRole = null,
|
|
48
|
-
requireExisting = false,
|
|
49
|
-
}) {
|
|
50
|
-
// A request that names no organization, or no person (organization-only
|
|
51
|
-
// auth), has no membership to check or add.
|
|
52
|
-
if (!individual || !organization) {
|
|
53
|
-
return { individual, membership: null };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const existing =
|
|
57
|
-
(await this.organizationMembershipRepository.findMembership(
|
|
58
|
-
individual.id,
|
|
59
|
-
organization.id
|
|
60
|
-
)) ?? implicitMembership(individual, organization.id);
|
|
61
|
-
if (existing) {
|
|
62
|
-
return { individual, membership: existing };
|
|
63
|
-
}
|
|
64
|
-
if (requireExisting) {
|
|
65
|
-
return { individual, membership: null };
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const membership =
|
|
69
|
-
await this.organizationMembershipRepository.addMembership(
|
|
70
|
-
individual.id,
|
|
71
|
-
organization.id,
|
|
72
|
-
{ orgRole }
|
|
73
|
-
);
|
|
74
|
-
log.debug('Organization membership added', {
|
|
75
|
-
eventName: `${log.name}.added`,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// The database repeats this condition in the update itself, so a
|
|
79
|
-
// concurrent first link by another request cannot be overwritten.
|
|
80
|
-
let updated = individual;
|
|
81
|
-
if (!isPresent(individual.organizationId)) {
|
|
82
|
-
updated =
|
|
83
|
-
(await this.userRepository.linkIndividualToOrganizationIfUnset(
|
|
84
|
-
individual.id,
|
|
85
|
-
organization.id
|
|
86
|
-
)) ?? individual;
|
|
87
|
-
}
|
|
88
|
-
return { individual: updated, membership };
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
module.exports = { EnsureOrganizationMembership };
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
const { sameId } = require('../membership');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* The individual users who belong to an organization (ADR-056 §3.6): the
|
|
5
|
-
* people with a stored membership, plus those the legacy
|
|
6
|
-
* `IndividualUser.organizationId` pointer places there, each once.
|
|
7
|
-
*
|
|
8
|
-
* Both repositories stay atomic; the union is composed here. Reading only the
|
|
9
|
-
* legacy pointer would list a person in the first organization they ever
|
|
10
|
-
* joined and in no other.
|
|
11
|
-
*
|
|
12
|
-
* @class FindIndividualUsersByOrganization
|
|
13
|
-
*/
|
|
14
|
-
class FindIndividualUsersByOrganization {
|
|
15
|
-
/**
|
|
16
|
-
* @param {Object} params
|
|
17
|
-
* @param {import('../repositories/user-repository-interface').UserRepositoryInterface} params.userRepository
|
|
18
|
-
* @param {import('../repositories/organization-membership-repository-interface').OrganizationMembershipRepositoryInterface} params.organizationMembershipRepository
|
|
19
|
-
*/
|
|
20
|
-
constructor({ userRepository, organizationMembershipRepository }) {
|
|
21
|
-
this.userRepository = userRepository;
|
|
22
|
-
this.organizationMembershipRepository = organizationMembershipRepository;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @param {string|number} organizationUserId
|
|
27
|
-
* @returns {Promise<Object[]>} Individual users, legacy-pointer people first.
|
|
28
|
-
*/
|
|
29
|
-
async execute(organizationUserId) {
|
|
30
|
-
const [legacy, memberships] = await Promise.all([
|
|
31
|
-
this.userRepository.findIndividualUsersByOrganizationId(
|
|
32
|
-
organizationUserId
|
|
33
|
-
),
|
|
34
|
-
this.organizationMembershipRepository.listMembershipsForOrganization(
|
|
35
|
-
organizationUserId
|
|
36
|
-
),
|
|
37
|
-
]);
|
|
38
|
-
|
|
39
|
-
const users = [...(legacy || [])];
|
|
40
|
-
for (const { individualUserId } of memberships) {
|
|
41
|
-
if (users.some((u) => sameId(u.id ?? u._id, individualUserId))) {
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
const individual = await this.userRepository.findIndividualUserById(
|
|
45
|
-
individualUserId
|
|
46
|
-
);
|
|
47
|
-
// A membership whose person was deleted is skipped, not an error.
|
|
48
|
-
if (individual) users.push(individual);
|
|
49
|
-
}
|
|
50
|
-
return users;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
module.exports = { FindIndividualUsersByOrganization };
|