@friggframework/core 2.0.0--canary.690.08cd07e.0 → 2.0.0--canary.693.d8859c2.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/CLAUDE.md +0 -28
- package/README.md +0 -105
- package/application/commands/integration-commands.js +10 -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-utils.js +0 -2
- package/database/encryption/encryption-schema-registry.js +12 -93
- package/database/prisma.js +2 -4
- package/errors/index.js +4 -0
- package/errors/mapping-already-exists-error.js +14 -0
- package/generated/prisma-mongodb/edge.js +38 -33
- package/generated/prisma-mongodb/index-browser.js +35 -30
- package/generated/prisma-mongodb/index.d.ts +1880 -3191
- package/generated/prisma-mongodb/index.js +38 -33
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +50 -86
- package/generated/prisma-mongodb/wasm.js +38 -33
- package/generated/prisma-postgresql/edge.js +38 -33
- package/generated/prisma-postgresql/index-browser.js +35 -30
- package/generated/prisma-postgresql/index.d.ts +2050 -3390
- package/generated/prisma-postgresql/index.js +38 -33
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +48 -81
- package/generated/prisma-postgresql/wasm.js +38 -33
- package/handlers/WEBHOOKS.md +29 -0
- package/handlers/app-definition-loader.js +19 -128
- 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/index.js +6 -19
- package/infrastructure/scheduler/scheduler-service-factory.js +7 -55
- package/integrations/data-defined/README.md +169 -0
- package/integrations/data-defined/canonical.js +11 -0
- package/integrations/data-defined/capabilities/acmeerp.capabilities.json +608 -0
- package/integrations/data-defined/capabilities/asana.capabilities.json +265 -0
- package/integrations/data-defined/capabilities/calendly.capabilities.json +385 -0
- package/integrations/data-defined/capabilities/docusign.capabilities.json +314 -0
- package/integrations/data-defined/capabilities/fathom.capabilities.json +228 -0
- package/integrations/data-defined/capabilities/github.capabilities.json +563 -0
- package/integrations/data-defined/capabilities/hubspot.capabilities.json +715 -0
- package/integrations/data-defined/capabilities/jira.capabilities.json +376 -0
- package/integrations/data-defined/capabilities/klaviyo.capabilities.json +475 -0
- package/integrations/data-defined/capabilities/linear.capabilities.json +324 -0
- package/integrations/data-defined/capabilities/netsuite.capabilities.json +491 -0
- package/integrations/data-defined/capabilities/notion.capabilities.json +208 -0
- package/integrations/data-defined/capabilities/phone.capabilities.json +470 -0
- package/integrations/data-defined/capabilities/pipedrive.capabilities.json +388 -0
- package/integrations/data-defined/capabilities/quickbooks.capabilities.json +615 -0
- package/integrations/data-defined/capabilities/salesforce.capabilities.json +507 -0
- package/integrations/data-defined/capabilities/shopify.capabilities.json +1082 -0
- package/integrations/data-defined/capabilities/slack.capabilities.json +363 -0
- package/integrations/data-defined/capabilities/stripe.capabilities.json +580 -0
- package/integrations/data-defined/capabilities/webflow.capabilities.json +196 -0
- package/integrations/data-defined/capabilities/zendesk.capabilities.json +409 -0
- package/integrations/data-defined/compile.js +77 -0
- package/integrations/data-defined/config-form.js +110 -0
- package/integrations/data-defined/data-defined-integration.js +366 -0
- package/integrations/data-defined/examples/acme-erp-quickbooks.definition.json +467 -0
- package/integrations/data-defined/examples/asana-slack.definition.json +220 -0
- package/integrations/data-defined/examples/calendly-salesforce.definition.json +459 -0
- package/integrations/data-defined/examples/docusign-salesforce.definition.json +305 -0
- package/integrations/data-defined/examples/fathom-hubspot-notion.definition.json +575 -0
- package/integrations/data-defined/examples/github-linear.definition.json +316 -0
- package/integrations/data-defined/examples/hubspot-slack.definition.json +409 -0
- package/integrations/data-defined/examples/klaviyo-hubspot.definition.json +339 -0
- package/integrations/data-defined/examples/phone-hubspot.definition.json +637 -0
- package/integrations/data-defined/examples/pipedrive-hubspot.definition.json +136 -0
- package/integrations/data-defined/examples/pipedrive-phone.definition.json +340 -0
- package/integrations/data-defined/examples/records/phone-hubspot.definition-version.json +652 -0
- package/integrations/data-defined/examples/records/phone-hubspot.integration.json +86 -0
- package/integrations/data-defined/examples/records/phone-hubspot.mappings.json +39 -0
- package/integrations/data-defined/examples/records/phone-hubspot.workflow-run.json +62 -0
- package/integrations/data-defined/examples/shopify-klaviyo.definition.json +488 -0
- package/integrations/data-defined/examples/shopify-netsuite.definition.json +622 -0
- package/integrations/data-defined/examples/stripe-quickbooks.definition.json +476 -0
- package/integrations/data-defined/examples/webflow-hubspot-slack.definition.json +262 -0
- package/integrations/data-defined/examples/zendesk-jira.definition.json +604 -0
- package/integrations/data-defined/expressions.js +225 -0
- package/integrations/data-defined/index.js +39 -0
- package/integrations/data-defined/interpreter.js +89 -0
- package/integrations/data-defined/manifests.js +125 -0
- package/integrations/data-defined/repositories/definition-version-repository.js +67 -0
- package/integrations/data-defined/repositories/workflow-run-repository.js +59 -0
- package/integrations/data-defined/router.js +97 -0
- package/integrations/data-defined/runtime.js +208 -0
- package/integrations/data-defined/schema/capability-manifest.v0.1.schema.json +377 -0
- package/integrations/data-defined/schema/installation.v0.1.schema.json +83 -0
- package/integrations/data-defined/schema/integration-definition.v0.1.schema.json +848 -0
- package/integrations/data-defined/schema/records.md +98 -0
- package/integrations/data-defined/schema-check.js +58 -0
- package/integrations/data-defined/scripts/validate.js +66 -0
- package/integrations/data-defined/steps.js +89 -0
- package/integrations/data-defined/transforms.js +91 -0
- package/integrations/data-defined/use-cases/definition-use-cases.js +187 -0
- package/integrations/data-defined/validate.js +370 -0
- package/integrations/data-defined/versioning.js +161 -0
- package/integrations/data-defined/webhooks.js +119 -0
- package/integrations/index.js +0 -1
- package/integrations/integration-base.js +29 -0
- package/integrations/integration-router.js +101 -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 +3 -35
- package/integrations/repositories/integration-repository-interface.js +1 -17
- package/integrations/repositories/integration-repository-mongo.js +77 -60
- package/integrations/repositories/integration-repository-postgres.js +76 -62
- package/integrations/repositories/process-repository-mongo.js +1 -1
- package/integrations/tests/doubles/test-integration-repository.js +1 -12
- package/integrations/use-cases/create-integration.js +20 -55
- package/integrations/use-cases/get-integrations-for-user.js +40 -80
- package/integrations/use-cases/index.js +1 -7
- package/integrations/utils/map-integration-dto.js +14 -43
- 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 +5 -35
- 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/package.json +6 -6
- package/prisma-mongodb/schema.prisma +50 -86
- package/prisma-postgresql/migrations/20261018000000_add_data_defined_integrations/migration.sql +66 -0
- package/prisma-postgresql/schema.prisma +48 -81
- package/queues/index.js +0 -25
- 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/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-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/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 -216
- 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 -415
- 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-bases.js +0 -169
- package/modules/proxy/proxy-errors.js +0 -31
- package/modules/proxy/proxy-path.js +0 -183
- package/modules/proxy/proxy-policy.js +0 -277
- 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 -245
- 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 -331
- 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 -150
- 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 -214
- 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,6 +1,5 @@
|
|
|
1
1
|
const { prisma } = require('../../database/prisma');
|
|
2
2
|
const { ModuleRepositoryInterface } = require('./module-repository-interface');
|
|
3
|
-
const { entityNotFoundError } = require('./entity-not-found');
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* PostgreSQL Module Repository Adapter
|
|
@@ -109,26 +108,6 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
109
108
|
return credentialMap;
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
/**
|
|
113
|
-
* The one place a stored entity row becomes the entity the application sees.
|
|
114
|
-
* The provider's `data` is spread FIRST and every column is pinned after it:
|
|
115
|
-
* a stored `id`, `userId` or `organizationId` in `data` must not decide who
|
|
116
|
-
* owns the entity or who sees it.
|
|
117
|
-
* @private
|
|
118
|
-
*/
|
|
119
|
-
_mapEntity(row, credential) {
|
|
120
|
-
return {
|
|
121
|
-
...(row.data || {}),
|
|
122
|
-
id: row.id.toString(),
|
|
123
|
-
credential,
|
|
124
|
-
userId: row.userId?.toString(),
|
|
125
|
-
name: row.name,
|
|
126
|
-
externalId: row.externalId,
|
|
127
|
-
moduleName: row.moduleName,
|
|
128
|
-
organizationId: row.organizationId?.toString() ?? null,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
111
|
/**
|
|
133
112
|
* Find entity by ID with credential
|
|
134
113
|
* Replaces: Entity.findById(entityId).populate('credential')
|
|
@@ -145,12 +124,20 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
145
124
|
});
|
|
146
125
|
|
|
147
126
|
if (!entity) {
|
|
148
|
-
throw
|
|
127
|
+
throw new Error(`Entity ${entityId} not found`);
|
|
149
128
|
}
|
|
150
129
|
|
|
151
130
|
const credential = await this._fetchCredential(entity.credentialId);
|
|
152
131
|
|
|
153
|
-
return
|
|
132
|
+
return {
|
|
133
|
+
id: entity.id.toString(),
|
|
134
|
+
credential,
|
|
135
|
+
userId: entity.userId?.toString(),
|
|
136
|
+
name: entity.name,
|
|
137
|
+
externalId: entity.externalId,
|
|
138
|
+
moduleName: entity.moduleName,
|
|
139
|
+
...(entity.data || {}),
|
|
140
|
+
};
|
|
154
141
|
}
|
|
155
142
|
|
|
156
143
|
/**
|
|
@@ -170,7 +157,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
170
157
|
const credentialIds = entities.map(e => e.credentialId).filter(Boolean);
|
|
171
158
|
const credentialMap = await this._fetchCredentialsBulk(credentialIds);
|
|
172
159
|
|
|
173
|
-
return entities.map((e) => (
|
|
160
|
+
return entities.map((e) => ({
|
|
161
|
+
id: e.id.toString(),
|
|
162
|
+
credential: credentialMap.get(e.credentialId) || null,
|
|
163
|
+
userId: e.userId?.toString(),
|
|
164
|
+
name: e.name,
|
|
165
|
+
externalId: e.externalId,
|
|
166
|
+
moduleName: e.moduleName,
|
|
167
|
+
...(e.data || {}),
|
|
168
|
+
}));
|
|
174
169
|
}
|
|
175
170
|
|
|
176
171
|
/**
|
|
@@ -190,7 +185,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
190
185
|
const credentialIds = entities.map(e => e.credentialId).filter(Boolean);
|
|
191
186
|
const credentialMap = await this._fetchCredentialsBulk(credentialIds);
|
|
192
187
|
|
|
193
|
-
return entities.map((e) => (
|
|
188
|
+
return entities.map((e) => ({
|
|
189
|
+
id: e.id.toString(),
|
|
190
|
+
credential: credentialMap.get(e.credentialId) || null,
|
|
191
|
+
userId: e.userId?.toString(),
|
|
192
|
+
name: e.name,
|
|
193
|
+
externalId: e.externalId,
|
|
194
|
+
moduleName: e.moduleName,
|
|
195
|
+
...(e.data || {}),
|
|
196
|
+
}));
|
|
194
197
|
}
|
|
195
198
|
|
|
196
199
|
/**
|
|
@@ -214,32 +217,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
214
217
|
const credentialIds = entities.map(e => e.credentialId).filter(Boolean);
|
|
215
218
|
const credentialMap = await this._fetchCredentialsBulk(credentialIds);
|
|
216
219
|
|
|
217
|
-
return entities.map((e) => (
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
* @returns {Promise<Array>} Array of entity objects with string IDs
|
|
227
|
-
*/
|
|
228
|
-
async findEntitiesByOwnership(clauses) {
|
|
229
|
-
if (!Array.isArray(clauses) || clauses.length === 0) return [];
|
|
230
|
-
const entities = await this.prisma.entity.findMany({
|
|
231
|
-
where: {
|
|
232
|
-
OR: clauses.map(({ userId, organizationId }) => ({
|
|
233
|
-
userId: this._convertId(userId),
|
|
234
|
-
organizationId: this._convertId(organizationId),
|
|
235
|
-
})),
|
|
236
|
-
},
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
const credentialIds = entities.map(e => e.credentialId).filter(Boolean);
|
|
240
|
-
const credentialMap = await this._fetchCredentialsBulk(credentialIds);
|
|
241
|
-
|
|
242
|
-
return entities.map((e) => (this._mapEntity(e, credentialMap.get(e.credentialId) || null)));
|
|
220
|
+
return entities.map((e) => ({
|
|
221
|
+
id: e.id.toString(),
|
|
222
|
+
credential: credentialMap.get(e.credentialId) || null,
|
|
223
|
+
userId: e.userId?.toString(),
|
|
224
|
+
name: e.name,
|
|
225
|
+
externalId: e.externalId,
|
|
226
|
+
moduleName: e.moduleName,
|
|
227
|
+
...(e.data || {}),
|
|
228
|
+
}));
|
|
243
229
|
}
|
|
244
230
|
|
|
245
231
|
/**
|
|
@@ -278,7 +264,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
278
264
|
|
|
279
265
|
const credential = await this._fetchCredential(entity.credentialId);
|
|
280
266
|
|
|
281
|
-
return
|
|
267
|
+
return {
|
|
268
|
+
id: entity.id.toString(),
|
|
269
|
+
credential,
|
|
270
|
+
userId: entity.userId?.toString(),
|
|
271
|
+
name: entity.name,
|
|
272
|
+
externalId: entity.externalId,
|
|
273
|
+
moduleName: entity.moduleName,
|
|
274
|
+
...(entity.data || {}),
|
|
275
|
+
};
|
|
282
276
|
}
|
|
283
277
|
|
|
284
278
|
/**
|
|
@@ -298,7 +292,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
298
292
|
.filter(Boolean);
|
|
299
293
|
const credentialMap = await this._fetchCredentialsBulk(credentialIds);
|
|
300
294
|
|
|
301
|
-
return entities.map((e) => (
|
|
295
|
+
return entities.map((e) => ({
|
|
296
|
+
id: e.id.toString(),
|
|
297
|
+
credential: credentialMap.get(e.credentialId) || null,
|
|
298
|
+
userId: e.userId?.toString(),
|
|
299
|
+
name: e.name,
|
|
300
|
+
externalId: e.externalId,
|
|
301
|
+
moduleName: e.moduleName,
|
|
302
|
+
...(e.data || {}),
|
|
303
|
+
}));
|
|
302
304
|
}
|
|
303
305
|
|
|
304
306
|
/**
|
|
@@ -306,13 +308,9 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
306
308
|
* Replaces: Entity.create(entityData)
|
|
307
309
|
*
|
|
308
310
|
* @param {Object} entityData - Entity data (with string IDs from application layer)
|
|
309
|
-
* @param {{organizationId?: (string|null)}} [tenancy] - the organization the entity
|
|
310
|
-
* belongs to (ADR-056 §3.6). A separate argument, not a field of `entityData`,
|
|
311
|
-
* because `entityData` carries provider fields and one named `organizationId`
|
|
312
|
-
* must not be taken for ours.
|
|
313
311
|
* @returns {Promise<Object>} Created entity object with string IDs
|
|
314
312
|
*/
|
|
315
|
-
async createEntity(entityData
|
|
313
|
+
async createEntity(entityData) {
|
|
316
314
|
const {
|
|
317
315
|
user,
|
|
318
316
|
userId,
|
|
@@ -330,7 +328,6 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
330
328
|
name,
|
|
331
329
|
moduleName,
|
|
332
330
|
externalId,
|
|
333
|
-
organizationId: this._convertId(tenancy.organizationId ?? null),
|
|
334
331
|
data: dynamicData,
|
|
335
332
|
};
|
|
336
333
|
|
|
@@ -340,7 +337,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
340
337
|
|
|
341
338
|
const credentialObj = await this._fetchCredential(entity.credentialId);
|
|
342
339
|
|
|
343
|
-
return
|
|
340
|
+
return {
|
|
341
|
+
id: entity.id.toString(),
|
|
342
|
+
credential: credentialObj,
|
|
343
|
+
userId: entity.userId?.toString(),
|
|
344
|
+
name: entity.name,
|
|
345
|
+
externalId: entity.externalId,
|
|
346
|
+
moduleName: entity.moduleName,
|
|
347
|
+
...(entity.data || {}),
|
|
348
|
+
};
|
|
344
349
|
}
|
|
345
350
|
|
|
346
351
|
/**
|
|
@@ -396,7 +401,15 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
396
401
|
|
|
397
402
|
const credentialObj = await this._fetchCredential(entity.credentialId);
|
|
398
403
|
|
|
399
|
-
return
|
|
404
|
+
return {
|
|
405
|
+
id: entity.id.toString(),
|
|
406
|
+
credential: credentialObj,
|
|
407
|
+
userId: entity.userId?.toString(),
|
|
408
|
+
name: entity.name,
|
|
409
|
+
externalId: entity.externalId,
|
|
410
|
+
moduleName: entity.moduleName,
|
|
411
|
+
...(entity.data || {}),
|
|
412
|
+
};
|
|
400
413
|
} catch (error) {
|
|
401
414
|
if (error.code === 'P2025') {
|
|
402
415
|
return null;
|
|
@@ -461,11 +474,6 @@ class ModuleRepositoryPostgres extends ModuleRepositoryInterface {
|
|
|
461
474
|
if (filter.moduleName) where.moduleName = filter.moduleName;
|
|
462
475
|
if (filter.externalId) where.externalId = this._toString(filter.externalId);
|
|
463
476
|
|
|
464
|
-
// `null` means "no organization"; absent means "any".
|
|
465
|
-
if (filter.organizationId !== undefined) {
|
|
466
|
-
where.organizationId = this._convertId(filter.organizationId);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
477
|
return where;
|
|
470
478
|
}
|
|
471
479
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const { prisma } = require('../../database/prisma');
|
|
2
2
|
const { ModuleRepositoryInterface } = require('./module-repository-interface');
|
|
3
|
-
const { entityNotFoundError } = require('./entity-not-found');
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Prisma-based Module Repository
|
|
@@ -38,7 +37,7 @@ class ModuleRepository extends ModuleRepositoryInterface {
|
|
|
38
37
|
});
|
|
39
38
|
|
|
40
39
|
if (!entity) {
|
|
41
|
-
throw
|
|
40
|
+
throw new Error(`Entity ${entityId} not found`);
|
|
42
41
|
}
|
|
43
42
|
|
|
44
43
|
return {
|
|
@@ -8,7 +8,6 @@ const { getLogger } = require('../../logs');
|
|
|
8
8
|
const { redactUrl } = require('../../logs/redact');
|
|
9
9
|
const { toSanitizedSurrogate } = require('../../logs/serialize');
|
|
10
10
|
const { getLoggerScope } = require('../../logs/context');
|
|
11
|
-
const { proxyRequest } = require('./proxy-request');
|
|
12
11
|
|
|
13
12
|
const DEFAULT_REQUEST_TIMEOUT_MS = 60_000;
|
|
14
13
|
|
|
@@ -219,14 +218,9 @@ class Requester extends Delegate {
|
|
|
219
218
|
if (options.query) {
|
|
220
219
|
let queryBuild = '?';
|
|
221
220
|
for (const key in options.query) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
const values =
|
|
226
|
-
Array.isArray(value) && key.endsWith('[]') ? value : [value];
|
|
227
|
-
for (const v of values) {
|
|
228
|
-
queryBuild += `${encodeURIComponent(key)}=${encodeURIComponent(v)}&`;
|
|
229
|
-
}
|
|
221
|
+
queryBuild += `${encodeURIComponent(key)}=${encodeURIComponent(
|
|
222
|
+
options.query[key]
|
|
223
|
+
)}&`;
|
|
230
224
|
}
|
|
231
225
|
encodedUrl += queryBuild.slice(0, -1);
|
|
232
226
|
}
|
|
@@ -243,9 +237,7 @@ class Requester extends Delegate {
|
|
|
243
237
|
// recursion (with its own backoff sleeps) always gets a clean
|
|
244
238
|
// signal. Timer is cleared in the finally block regardless of
|
|
245
239
|
// outcome.
|
|
246
|
-
|
|
247
|
-
// Management API proxy passes what is left of its deadline).
|
|
248
|
-
const timeoutMs = options.timeoutMs ?? this.requestTimeoutMs;
|
|
240
|
+
const timeoutMs = this.requestTimeoutMs;
|
|
249
241
|
const controller = timeoutMs > 0 ? new AbortController() : null;
|
|
250
242
|
const timeoutHandle = controller
|
|
251
243
|
? setTimeout(() => controller.abort(), timeoutMs)
|
|
@@ -283,11 +275,7 @@ class Requester extends Delegate {
|
|
|
283
275
|
// stall at batch scale.
|
|
284
276
|
const isTimeout =
|
|
285
277
|
e?.name === 'AbortError' || e?.type === 'aborted';
|
|
286
|
-
if (
|
|
287
|
-
e?.code === 'ECONNRESET' &&
|
|
288
|
-
!options.noRetry &&
|
|
289
|
-
attempt < this.backOff.length
|
|
290
|
-
) {
|
|
278
|
+
if (e?.code === 'ECONNRESET' && attempt < this.backOff.length) {
|
|
291
279
|
clearRequestTimer();
|
|
292
280
|
const delay = this.backOff[attempt] * 1000;
|
|
293
281
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
@@ -313,7 +301,6 @@ class Requester extends Delegate {
|
|
|
313
301
|
// If the status is retriable and there are back off requests left, retry the request
|
|
314
302
|
if (
|
|
315
303
|
(status === 429 || status >= 500) &&
|
|
316
|
-
!options.noRetry &&
|
|
317
304
|
attempt < this.backOff.length
|
|
318
305
|
) {
|
|
319
306
|
clearRequestTimer();
|
|
@@ -399,12 +386,6 @@ class Requester extends Delegate {
|
|
|
399
386
|
// If the error wasn't retried, throw. FetchError.create reads
|
|
400
387
|
// the response body (response.text()) — timer must still be
|
|
401
388
|
// alive to catch a stalled body stream.
|
|
402
|
-
// The proxy relays upstream errors to its caller instead of
|
|
403
|
-
// throwing; 401 keeps the refresh / invalidate handling above.
|
|
404
|
-
if (status >= 400 && options.returnErrorResponses) {
|
|
405
|
-
return response;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
389
|
if (status >= 400) {
|
|
409
390
|
this._logRequestFailed(encodedUrl, options, status);
|
|
410
391
|
const fetchError = await FetchError.create({
|
|
@@ -547,17 +528,6 @@ class Requester extends Delegate {
|
|
|
547
528
|
return res;
|
|
548
529
|
}
|
|
549
530
|
|
|
550
|
-
/**
|
|
551
|
-
* Generic, path-checked request for the Management API entity proxy
|
|
552
|
-
* (ADR-052 §8). The URL is always the module base URL plus a validated
|
|
553
|
-
* path; see ./proxy-request.js. Module methods are not involved.
|
|
554
|
-
*
|
|
555
|
-
* @param {Object} params - see proxyRequest()
|
|
556
|
-
*/
|
|
557
|
-
async _proxyRequest(params) {
|
|
558
|
-
return proxyRequest(this, params);
|
|
559
|
-
}
|
|
560
|
-
|
|
561
531
|
async _delete(options) {
|
|
562
532
|
const fetchOptions = {
|
|
563
533
|
method: 'DELETE',
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
const { Module } = require('../module');
|
|
2
2
|
const { mapModuleClassToModuleDTO } = require('../utils/map-module-dto');
|
|
3
|
-
const { describeRecord, visibilityClauses } = require('../scope-visibility');
|
|
4
|
-
const { DEFAULT_SCOPE_POLICY } = require('../scope-policy');
|
|
5
3
|
|
|
6
4
|
class GetEntitiesForUser {
|
|
7
|
-
constructor({ moduleRepository, moduleDefinitions
|
|
8
|
-
this.scopePolicy = scopePolicy || DEFAULT_SCOPE_POLICY;
|
|
5
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
9
6
|
this.moduleRepository = moduleRepository;
|
|
10
7
|
|
|
11
8
|
this.definitionMap = new Map();
|
|
@@ -14,31 +11,21 @@ class GetEntitiesForUser {
|
|
|
14
11
|
}
|
|
15
12
|
}
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*/
|
|
21
|
-
async execute(user) {
|
|
22
|
-
const ctx = this.scopePolicy.accessContext(user);
|
|
23
|
-
const found = await this.moduleRepository.findEntitiesByOwnership(
|
|
24
|
-
visibilityClauses(ctx, 'entity')
|
|
25
|
-
);
|
|
26
|
-
const entities = (found || []).filter((entity) =>
|
|
27
|
-
describeRecord(entity, ctx, 'entity')
|
|
14
|
+
async execute(userId) {
|
|
15
|
+
const entities = await this.moduleRepository.findEntitiesByUserId(
|
|
16
|
+
userId
|
|
28
17
|
);
|
|
29
18
|
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
const definition = this.definitionMap.get(entity.moduleName);
|
|
19
|
+
return entities.map((entity) => {
|
|
20
|
+
const definition = this.definitionMap.get(entity.moduleName);
|
|
33
21
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
);
|
|
22
|
+
const moduleInstance = new Module({
|
|
23
|
+
userId,
|
|
24
|
+
definition: definition,
|
|
25
|
+
entity: entity,
|
|
26
|
+
});
|
|
27
|
+
return mapModuleClassToModuleDTO(moduleInstance);
|
|
28
|
+
});
|
|
42
29
|
}
|
|
43
30
|
}
|
|
44
31
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const { Module } = require('../module');
|
|
2
|
-
const { DEFAULT_SCOPE_POLICY } = require('../scope-policy');
|
|
3
2
|
|
|
4
3
|
class GetEntityOptionsById {
|
|
5
4
|
/**
|
|
@@ -7,11 +6,9 @@ class GetEntityOptionsById {
|
|
|
7
6
|
* @param {import('../repositories/module-repository-interface').ModuleRepositoryInterface} params.moduleRepository
|
|
8
7
|
* @param {} params.moduleDefinitions
|
|
9
8
|
*/
|
|
10
|
-
constructor({ moduleRepository, moduleDefinitions
|
|
9
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
11
10
|
this.moduleRepository = moduleRepository;
|
|
12
11
|
this.moduleDefinitions = moduleDefinitions;
|
|
13
|
-
// Who may load an entity follows its scope (ADR-056 §3.6).
|
|
14
|
-
this.scopePolicy = scopePolicy || DEFAULT_SCOPE_POLICY;
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
/**
|
|
@@ -38,7 +35,7 @@ class GetEntityOptionsById {
|
|
|
38
35
|
|
|
39
36
|
// Validate entity ownership
|
|
40
37
|
const isOwned = typeof userIdOrUser === 'object' && userIdOrUser?.ownsUserId
|
|
41
|
-
?
|
|
38
|
+
? userIdOrUser.ownsUserId(entity.userId)
|
|
42
39
|
: entity.userId?.toString() === userId?.toString();
|
|
43
40
|
|
|
44
41
|
if (!isOwned) {
|
|
@@ -60,11 +57,8 @@ class GetEntityOptionsById {
|
|
|
60
57
|
);
|
|
61
58
|
}
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
// update the owner's credential, not create one under the caller.
|
|
66
|
-
const module = await Module.create({
|
|
67
|
-
userId: entity.userId ?? userId,
|
|
60
|
+
const module = new Module({
|
|
61
|
+
userId,
|
|
68
62
|
entity,
|
|
69
63
|
definition: moduleDefinition,
|
|
70
64
|
});
|
|
@@ -21,7 +21,7 @@ class GetEntityOptionsByType {
|
|
|
21
21
|
if (!moduleDefinition) {
|
|
22
22
|
throw new Error(`Module definition not found for type: ${type}`);
|
|
23
23
|
}
|
|
24
|
-
const moduleInstance =
|
|
24
|
+
const moduleInstance = new Module({
|
|
25
25
|
userId,
|
|
26
26
|
definition: moduleDefinition,
|
|
27
27
|
});
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
const { Module } = require('../module');
|
|
2
|
-
const { DEFAULT_SCOPE_POLICY } = require('../scope-policy');
|
|
3
2
|
|
|
4
3
|
class GetModule {
|
|
5
|
-
constructor({ moduleRepository, moduleDefinitions
|
|
4
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
6
5
|
this.moduleRepository = moduleRepository;
|
|
7
6
|
this.moduleDefinitions = moduleDefinitions;
|
|
8
|
-
// Who may load an entity follows its scope (ADR-056 §3.6).
|
|
9
|
-
this.scopePolicy = scopePolicy || DEFAULT_SCOPE_POLICY;
|
|
10
7
|
}
|
|
11
8
|
|
|
12
9
|
/**
|
|
@@ -35,7 +32,7 @@ class GetModule {
|
|
|
35
32
|
// If User object provided, use ownsUserId to check linked users
|
|
36
33
|
// Otherwise fall back to simple equality check
|
|
37
34
|
const isOwned = typeof userIdOrUser === 'object' && userIdOrUser?.ownsUserId
|
|
38
|
-
?
|
|
35
|
+
? userIdOrUser.ownsUserId(entity.userId)
|
|
39
36
|
: entity.userId?.toString() === userId?.toString();
|
|
40
37
|
|
|
41
38
|
if (!isOwned) {
|
|
@@ -56,11 +53,8 @@ class GetModule {
|
|
|
56
53
|
);
|
|
57
54
|
}
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// update the owner's credential, not create one under the caller.
|
|
62
|
-
const module = await Module.create({
|
|
63
|
-
userId: entity.userId ?? userId,
|
|
56
|
+
const module = new Module({
|
|
57
|
+
userId,
|
|
64
58
|
entity,
|
|
65
59
|
definition: moduleDefinition,
|
|
66
60
|
});
|
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
const { Module } = require('../module');
|
|
2
2
|
const { ModuleConstants } = require('../ModuleConstants');
|
|
3
|
-
const { pickExistingEntity } = require('../scope-resolution');
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* What an entity belongs to when the caller says nothing: the person's own,
|
|
7
|
-
* outside any organization.
|
|
8
|
-
*/
|
|
9
|
-
const DEFAULT_TENANCY = Object.freeze({
|
|
10
|
-
scope: 'individual',
|
|
11
|
-
organizationId: null,
|
|
12
|
-
legacyOrgId: null,
|
|
13
|
-
});
|
|
14
3
|
const { getLogger } = require('../../logs');
|
|
15
4
|
|
|
16
5
|
const log = getLogger('frigg.modules.authorization_callback');
|
|
@@ -41,17 +30,7 @@ class ProcessAuthorizationCallback {
|
|
|
41
30
|
this.integrationRepository = integrationRepository;
|
|
42
31
|
}
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
* @param {string} userId - the OWNER of what this creates (ADR-056 §3.2): the
|
|
46
|
-
* person for `individual`, the organization's user for `organization`.
|
|
47
|
-
* Not necessarily the caller; callers resolve it from the scope.
|
|
48
|
-
* @param {string} entityType
|
|
49
|
-
* @param {Object} params - what the module's authorization needs
|
|
50
|
-
* @param {{scope: string, organizationId: (string|null), legacyOrgId: (string|null)}} [tenancy]
|
|
51
|
-
* the entity's scope and organization (§3.6); default: the person's own,
|
|
52
|
-
* with no organization
|
|
53
|
-
*/
|
|
54
|
-
async execute(userId, entityType, params, tenancy = DEFAULT_TENANCY) {
|
|
33
|
+
async execute(userId, entityType, params) {
|
|
55
34
|
log.debug('Authorization callback started', {
|
|
56
35
|
eventName: `${log.name}.started`,
|
|
57
36
|
userId,
|
|
@@ -78,7 +57,10 @@ class ProcessAuthorizationCallback {
|
|
|
78
57
|
userId,
|
|
79
58
|
entityType
|
|
80
59
|
);
|
|
81
|
-
const existingEntity =
|
|
60
|
+
const existingEntity =
|
|
61
|
+
existingEntities && existingEntities.length > 0
|
|
62
|
+
? existingEntities[0]
|
|
63
|
+
: null;
|
|
82
64
|
|
|
83
65
|
if (existingEntity) {
|
|
84
66
|
log.debug('Existing entity found', {
|
|
@@ -88,7 +70,7 @@ class ProcessAuthorizationCallback {
|
|
|
88
70
|
});
|
|
89
71
|
}
|
|
90
72
|
|
|
91
|
-
const module =
|
|
73
|
+
const module = new Module({
|
|
92
74
|
userId,
|
|
93
75
|
entity: existingEntity,
|
|
94
76
|
definition: moduleDefinition,
|
|
@@ -174,8 +156,7 @@ class ProcessAuthorizationCallback {
|
|
|
174
156
|
const persistedEntity = await this.findOrCreateEntity(
|
|
175
157
|
entityDetails,
|
|
176
158
|
entityType,
|
|
177
|
-
module.credential.id
|
|
178
|
-
tenancy
|
|
159
|
+
module.credential.id
|
|
179
160
|
);
|
|
180
161
|
log.debug('Authorization callback completed', {
|
|
181
162
|
eventName: `${log.name}.completed`,
|
|
@@ -252,12 +233,7 @@ class ProcessAuthorizationCallback {
|
|
|
252
233
|
module.credential = persisted;
|
|
253
234
|
}
|
|
254
235
|
|
|
255
|
-
async findOrCreateEntity(
|
|
256
|
-
entityDetails,
|
|
257
|
-
moduleName,
|
|
258
|
-
credentialId,
|
|
259
|
-
tenancy = DEFAULT_TENANCY
|
|
260
|
-
) {
|
|
236
|
+
async findOrCreateEntity(entityDetails, moduleName, credentialId) {
|
|
261
237
|
const { identifiers, details } = entityDetails;
|
|
262
238
|
|
|
263
239
|
// Support both 'user' and 'userId' field names from module definitions
|
|
@@ -271,16 +247,11 @@ class ProcessAuthorizationCallback {
|
|
|
271
247
|
);
|
|
272
248
|
}
|
|
273
249
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
user: userId,
|
|
280
|
-
moduleName: moduleName,
|
|
281
|
-
}),
|
|
282
|
-
tenancy
|
|
283
|
-
);
|
|
250
|
+
const existingEntity = await this.moduleRepository.findEntity({
|
|
251
|
+
externalId: identifiers.externalId,
|
|
252
|
+
user: userId,
|
|
253
|
+
moduleName: moduleName,
|
|
254
|
+
});
|
|
284
255
|
|
|
285
256
|
if (existingEntity) {
|
|
286
257
|
// Repoint the entity's credentialId when re-auth produced a
|
|
@@ -311,17 +282,12 @@ class ProcessAuthorizationCallback {
|
|
|
311
282
|
return existingEntity;
|
|
312
283
|
}
|
|
313
284
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
moduleName: moduleName,
|
|
321
|
-
credential: credentialId,
|
|
322
|
-
},
|
|
323
|
-
{ organizationId: tenancy.organizationId ?? null }
|
|
324
|
-
);
|
|
285
|
+
return await this.moduleRepository.createEntity({
|
|
286
|
+
...identifiers,
|
|
287
|
+
...details,
|
|
288
|
+
moduleName: moduleName,
|
|
289
|
+
credential: credentialId,
|
|
290
|
+
});
|
|
325
291
|
}
|
|
326
292
|
}
|
|
327
293
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const { Module } = require('../module');
|
|
2
|
-
const { DEFAULT_SCOPE_POLICY } = require('../scope-policy');
|
|
3
2
|
|
|
4
3
|
class RefreshEntityOptions {
|
|
5
4
|
/**
|
|
@@ -7,11 +6,9 @@ class RefreshEntityOptions {
|
|
|
7
6
|
* @param {import('../repositories/module-repository-interface').ModuleRepositoryInterface} params.moduleRepository
|
|
8
7
|
* @param {} params.moduleDefinitions
|
|
9
8
|
*/
|
|
10
|
-
constructor({ moduleRepository, moduleDefinitions
|
|
9
|
+
constructor({ moduleRepository, moduleDefinitions }) {
|
|
11
10
|
this.moduleRepository = moduleRepository;
|
|
12
11
|
this.moduleDefinitions = moduleDefinitions;
|
|
13
|
-
// Who may load an entity follows its scope (ADR-056 §3.6).
|
|
14
|
-
this.scopePolicy = scopePolicy || DEFAULT_SCOPE_POLICY;
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
/**
|
|
@@ -39,7 +36,7 @@ class RefreshEntityOptions {
|
|
|
39
36
|
|
|
40
37
|
// Validate entity ownership
|
|
41
38
|
const isOwned = typeof userIdOrUser === 'object' && userIdOrUser?.ownsUserId
|
|
42
|
-
?
|
|
39
|
+
? userIdOrUser.ownsUserId(entity.userId)
|
|
43
40
|
: entity.userId?.toString() === userId?.toString();
|
|
44
41
|
|
|
45
42
|
if (!isOwned) {
|
|
@@ -61,11 +58,8 @@ class RefreshEntityOptions {
|
|
|
61
58
|
);
|
|
62
59
|
}
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
// update the owner's credential, not create one under the caller.
|
|
67
|
-
const module = await Module.create({
|
|
68
|
-
userId: entity.userId ?? userId,
|
|
61
|
+
const module = new Module({
|
|
62
|
+
userId,
|
|
69
63
|
entity,
|
|
70
64
|
definition: moduleDefinition,
|
|
71
65
|
});
|