@friggframework/core 2.0.0--canary.707.df80bfd.0 → 2.0.0--canary.680.d670696.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 +3 -0
- package/CLAUDE.md +0 -28
- package/README.md +0 -105
- package/application/commands/integration-commands.js +2 -2
- package/application/commands/scheduler-commands.js +7 -11
- package/application/commands/user-commands.js +5 -17
- package/core/Worker.js +7 -31
- package/core/create-handler.js +0 -9
- package/credential/use-cases/credential-operations-for-user.js +25 -110
- package/credential/use-cases/reauthorize-credential-for-user.js +8 -15
- package/database/config.js +24 -48
- package/database/documentdb-encryption-service.js +0 -1
- package/database/documentdb-utils.js +1 -6
- package/database/encryption/encryption-config.js +44 -13
- package/database/encryption/encryption-schema-registry.js +31 -88
- package/database/prisma.js +2 -4
- package/generated/prisma-mongodb/edge.js +4 -27
- package/generated/prisma-mongodb/index-browser.js +1 -24
- package/generated/prisma-mongodb/index.d.ts +48 -3228
- package/generated/prisma-mongodb/index.js +4 -27
- package/generated/prisma-mongodb/package.json +1 -1
- package/generated/prisma-mongodb/schema.prisma +0 -65
- package/generated/prisma-mongodb/wasm.js +4 -27
- package/generated/prisma-postgresql/edge.js +4 -27
- package/generated/prisma-postgresql/index-browser.js +1 -24
- package/generated/prisma-postgresql/index.d.ts +51 -3503
- package/generated/prisma-postgresql/index.js +4 -27
- package/generated/prisma-postgresql/package.json +1 -1
- package/generated/prisma-postgresql/schema.prisma +0 -61
- package/generated/prisma-postgresql/wasm.js +4 -27
- package/handlers/app-definition-loader.js +12 -110
- package/handlers/routers/auth.js +12 -40
- package/handlers/routers/health.js +2 -4
- package/handlers/routers/integration-defined-routers.js +92 -144
- package/handlers/routers/integration-webhook-routers.js +64 -102
- package/index.js +1 -64
- package/infrastructure/scheduler/index.js +6 -19
- package/infrastructure/scheduler/scheduler-service-factory.js +7 -55
- package/integrations/index.js +0 -5
- package/integrations/integration-router.js +73 -115
- 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 +76 -59
- package/integrations/repositories/integration-repository-postgres.js +76 -62
- 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/use-cases/integration-operations-for-user.js +24 -55
- package/integrations/utils/map-integration-dto.js +1 -44
- package/management-api/management-api-config.js +2 -71
- package/management-api/meta-router.js +2 -21
- package/management-api/openapi/components.js +3 -50
- package/management-api/openapi/v2-operations.js +5 -17
- package/management-api/route-registry.js +6 -123
- package/management-api/v2/dependencies.js +15 -40
- package/management-api/v2/dto.js +0 -20
- package/management-api/v2/handlers/authorization.js +0 -1
- package/management-api/v2/handlers/credentials.js +2 -6
- package/management-api/v2/handlers/entities.js +7 -10
- package/management-api/v2/handlers/integrations.js +3 -6
- package/management-api/v2/request.js +1 -32
- package/modules/index.js +0 -8
- package/modules/module-factory.js +0 -12
- package/modules/module.js +2 -53
- package/modules/proxy/proxy-errors.js +1 -12
- package/modules/proxy/proxy-path.js +3 -7
- package/modules/proxy/proxy-policy.js +5 -34
- 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/proxy-request.js +1 -2
- package/modules/requester/requester.js +3 -8
- package/modules/use-cases/entity-operations-for-user.js +13 -50
- package/modules/use-cases/entity-types.js +7 -31
- package/modules/use-cases/execute-entity-proxy-request.js +15 -107
- package/modules/use-cases/get-authorization-requirements.js +2 -2
- package/modules/use-cases/get-entities-for-user.js +13 -26
- package/modules/use-cases/get-entity-module-for-user.js +7 -34
- 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/multi-step-authorization.js +13 -40
- 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 +5 -6
- package/prisma-mongodb/schema.prisma +0 -65
- package/prisma-postgresql/schema.prisma +0 -61
- package/queues/index.js +0 -25
- package/types/index.d.ts +0 -1
- package/types/modules/index.d.ts +1 -157
- 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/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 -230
- package/extensions/index.js +0 -44
- package/extensions/initialize-app.js +0 -123
- package/extensions/prisma-composer.js +0 -270
- 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/resolve-integration-ownership.js +0 -177
- package/modules/entity-scope.js +0 -15
- package/modules/proxy/proxy-bases.js +0 -169
- package/modules/repositories/entity-not-found.js +0 -18
- 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/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/manage-access.js +0 -21
- 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/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
package/database/config.js
CHANGED
|
@@ -3,39 +3,6 @@
|
|
|
3
3
|
* Manages configuration for Prisma ORM operations
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
/**
|
|
7
|
-
* Maps an app definition's `database` block to a Prisma database type.
|
|
8
|
-
*
|
|
9
|
-
* @param {Object|undefined} database - `Definition.database`
|
|
10
|
-
* @param {string} where - where the definition lives, for the error message
|
|
11
|
-
* @returns {'mongodb'|'postgresql'|'documentdb'}
|
|
12
|
-
*/
|
|
13
|
-
function databaseTypeFromConfig(database, where) {
|
|
14
|
-
if (!database) {
|
|
15
|
-
throw new Error(
|
|
16
|
-
'[Frigg] App definition missing database configuration. ' +
|
|
17
|
-
`Add database: { postgres: { enable: true } } (or mongoDB/documentDB) to ${where}`
|
|
18
|
-
);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// Determine database type from enabled database
|
|
22
|
-
// Priority order: postgres > mongoDB > documentDB
|
|
23
|
-
if (database.postgres?.enable === true) {
|
|
24
|
-
return 'postgresql';
|
|
25
|
-
}
|
|
26
|
-
if (database.mongoDB?.enable === true) {
|
|
27
|
-
return 'mongodb';
|
|
28
|
-
}
|
|
29
|
-
if (database.documentDB?.enable === true) {
|
|
30
|
-
return 'documentdb';
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
throw new Error(
|
|
34
|
-
'[Frigg] No database enabled in app definition. ' +
|
|
35
|
-
'Set one of: database.postgres.enable, database.mongoDB.enable, or database.documentDB.enable to true'
|
|
36
|
-
);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
6
|
/**
|
|
40
7
|
* Determines database type from environment or app definition
|
|
41
8
|
*
|
|
@@ -54,20 +21,6 @@ function getDatabaseType() {
|
|
|
54
21
|
|
|
55
22
|
// Fallback: Load app definition
|
|
56
23
|
try {
|
|
57
|
-
// A definition preset with setAppDefinition() (provider-netlify's
|
|
58
|
-
// function preamble) wins: on Netlify process.cwd() is the function
|
|
59
|
-
// root at runtime, so discovery cannot find the backend.
|
|
60
|
-
const {
|
|
61
|
-
getPresetAppDefinition,
|
|
62
|
-
} = require('../handlers/app-definition-loader');
|
|
63
|
-
const preset = getPresetAppDefinition();
|
|
64
|
-
if (preset) {
|
|
65
|
-
return databaseTypeFromConfig(
|
|
66
|
-
preset.database,
|
|
67
|
-
'your backend/index.js'
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
24
|
const path = require('node:path');
|
|
72
25
|
const fs = require('node:fs');
|
|
73
26
|
const { findNearestBackendPackageJson } = require('../utils');
|
|
@@ -123,7 +76,30 @@ function getDatabaseType() {
|
|
|
123
76
|
}
|
|
124
77
|
|
|
125
78
|
database = backendModule?.Definition?.database;
|
|
126
|
-
|
|
79
|
+
|
|
80
|
+
if (!database) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
'[Frigg] App definition missing database configuration. ' +
|
|
83
|
+
`Add database: { postgres: { enable: true } } (or mongoDB/documentDB) to ${backendIndexPath}`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Determine database type from enabled database
|
|
88
|
+
// Priority order: postgres > mongoDB > documentDB
|
|
89
|
+
if (database.postgres?.enable === true) {
|
|
90
|
+
return 'postgresql';
|
|
91
|
+
}
|
|
92
|
+
if (database.mongoDB?.enable === true) {
|
|
93
|
+
return 'mongodb';
|
|
94
|
+
}
|
|
95
|
+
if (database.documentDB?.enable === true) {
|
|
96
|
+
return 'documentdb';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
throw new Error(
|
|
100
|
+
'[Frigg] No database enabled in app definition. ' +
|
|
101
|
+
'Set one of: database.postgres.enable, database.mongoDB.enable, or database.documentDB.enable to true'
|
|
102
|
+
);
|
|
127
103
|
} catch (error) {
|
|
128
104
|
// Re-throw with context if it's our error
|
|
129
105
|
if (error.message.includes('[Frigg]')) {
|
|
@@ -58,12 +58,7 @@ async function insertOne(client, collection, document) {
|
|
|
58
58
|
|
|
59
59
|
// Provide helpful context for common errors
|
|
60
60
|
if (error.code === 11000) {
|
|
61
|
-
|
|
62
|
-
// (see database/unique-violation.js).
|
|
63
|
-
throw Object.assign(
|
|
64
|
-
new Error(`${errorMsg} - Duplicate key violation`),
|
|
65
|
-
{ code: 11000 }
|
|
66
|
-
);
|
|
61
|
+
throw new Error(`${errorMsg} - Duplicate key violation`);
|
|
67
62
|
}
|
|
68
63
|
throw new Error(errorMsg);
|
|
69
64
|
}
|
|
@@ -18,9 +18,6 @@
|
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
const { logger } = require('./logger');
|
|
21
|
-
const {
|
|
22
|
-
isDeployedRuntime: isDeployedProviderRuntime,
|
|
23
|
-
} = require('../../providers/runtime-detection');
|
|
24
21
|
|
|
25
22
|
const LOCAL_BYPASS_STAGES = ['dev', 'test', 'local'];
|
|
26
23
|
const OPT_OUT_VAR = 'FRIGG_ENCRYPTION_DISABLED';
|
|
@@ -43,18 +40,42 @@ function isTrue(value) {
|
|
|
43
40
|
}
|
|
44
41
|
|
|
45
42
|
/**
|
|
46
|
-
* True when the process runs as a deployed function, on AWS Lambda or on
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* runtime
|
|
51
|
-
*
|
|
43
|
+
* True when the process runs as a deployed function, on AWS Lambda or on
|
|
44
|
+
* another provider's platform.
|
|
45
|
+
*
|
|
46
|
+
* - AWS Lambda sets AWS_LAMBDA_FUNCTION_NAME, LAMBDA_TASK_ROOT and
|
|
47
|
+
* AWS_EXECUTION_ENV (AWS_Lambda_<runtime>). Other AWS hosts (CloudShell,
|
|
48
|
+
* CodeBuild, ECS) set AWS_EXECUTION_ENV to other values and count as local:
|
|
49
|
+
* CLI commands run from CI must not trip the deployed-stage check.
|
|
50
|
+
* - Other providers: FRIGG_PROVIDER names a non-AWS provider. Frigg's
|
|
51
|
+
* generated function entry points for that provider set it (provider-netlify
|
|
52
|
+
* sets 'netlify'), so it is present in every deployed function. Netlify
|
|
53
|
+
* exposes SITE_ID, CONTEXT and NETLIFY at build time only, so they cannot
|
|
54
|
+
* tell a running function from a laptop.
|
|
55
|
+
*
|
|
56
|
+
* A local run is never deployed: serverless-offline and `serverless invoke
|
|
57
|
+
* local` (which set the Lambda variables themselves) mark IS_OFFLINE /
|
|
58
|
+
* IS_LOCAL, `netlify dev` marks NETLIFY_DEV, and Jest marks JEST_WORKER_ID.
|
|
52
59
|
*
|
|
53
60
|
* @param {Object} [env=process.env]
|
|
54
61
|
* @returns {boolean}
|
|
55
62
|
*/
|
|
56
63
|
function isDeployedRuntime(env = process.env) {
|
|
57
|
-
|
|
64
|
+
const localRun =
|
|
65
|
+
isTrue(env.IS_OFFLINE) ||
|
|
66
|
+
isTrue(env.IS_LOCAL) ||
|
|
67
|
+
isTrue(env.NETLIFY_DEV) ||
|
|
68
|
+
isSet(env.JEST_WORKER_ID);
|
|
69
|
+
if (localRun) return false;
|
|
70
|
+
|
|
71
|
+
const onAwsRuntime =
|
|
72
|
+
isSet(env.AWS_LAMBDA_FUNCTION_NAME) ||
|
|
73
|
+
isSet(env.LAMBDA_TASK_ROOT) ||
|
|
74
|
+
String(env.AWS_EXECUTION_ENV ?? '').startsWith('AWS_Lambda_');
|
|
75
|
+
if (onAwsRuntime) return true;
|
|
76
|
+
|
|
77
|
+
const provider = String(env.FRIGG_PROVIDER ?? '').trim().toLowerCase();
|
|
78
|
+
return provider !== '' && provider !== 'aws';
|
|
58
79
|
}
|
|
59
80
|
|
|
60
81
|
function missingKeyMessage(stage) {
|
|
@@ -100,6 +121,10 @@ function resolveEncryptionConfig(env = process.env) {
|
|
|
100
121
|
const runtime = isDeployedRuntime(env) ? 'deployed' : 'local';
|
|
101
122
|
const hasKMS = isSet(env.KMS_KEY_ARN);
|
|
102
123
|
const hasAES = isSet(env.AES_KEY_ID);
|
|
124
|
+
// AES needs the key as well as its id, locally too: a cryptor built from
|
|
125
|
+
// the id alone cannot encrypt, and a local run reads failed decrypts as
|
|
126
|
+
// stored values, so an incomplete pair would hand back blobs as tokens.
|
|
127
|
+
const hasCompleteAES = hasAES && isSet(env.AES_KEY);
|
|
103
128
|
const optOutRequested = isTrue(env[OPT_OUT_VAR]);
|
|
104
129
|
|
|
105
130
|
const base = {
|
|
@@ -120,14 +145,13 @@ function resolveEncryptionConfig(env = process.env) {
|
|
|
120
145
|
if (LOCAL_BYPASS_STAGES.includes(String(stage).toLowerCase())) {
|
|
121
146
|
return { ...base, bypassed: true };
|
|
122
147
|
}
|
|
123
|
-
if (hasKMS ||
|
|
148
|
+
if (hasKMS || hasCompleteAES) {
|
|
124
149
|
const method = hasKMS ? 'kms' : 'aes';
|
|
125
150
|
return { ...base, enabled: true, method, mode: method };
|
|
126
151
|
}
|
|
127
152
|
return base;
|
|
128
153
|
}
|
|
129
154
|
|
|
130
|
-
const hasCompleteAES = hasAES && isSet(env.AES_KEY);
|
|
131
155
|
if (hasKMS || hasCompleteAES) {
|
|
132
156
|
const method = hasKMS ? 'kms' : 'aes';
|
|
133
157
|
return {
|
|
@@ -191,7 +215,14 @@ function getEncryptionConfig(env = process.env) {
|
|
|
191
215
|
);
|
|
192
216
|
}
|
|
193
217
|
|
|
194
|
-
if (config.runtime === 'local' && !config.enabled && !config.bypassed) {
|
|
218
|
+
if (config.runtime === 'local' && !config.enabled && !config.bypassed && config.hasAES) {
|
|
219
|
+
warnOnce(
|
|
220
|
+
'local-incomplete-aes',
|
|
221
|
+
`AES_KEY_ID is set but AES_KEY is not for local stage "${config.stage}". ` +
|
|
222
|
+
'Field-level encryption disabled for this local run; set both to encrypt. ' +
|
|
223
|
+
'A deployed stage refuses to start without both.'
|
|
224
|
+
);
|
|
225
|
+
} else if (config.runtime === 'local' && !config.enabled && !config.bypassed) {
|
|
195
226
|
warnOnce(
|
|
196
227
|
'local-no-keys',
|
|
197
228
|
`No encryption keys configured (KMS_KEY_ARN or AES_KEY_ID) for local stage "${config.stage}". ` +
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
const { logger } = require('./logger');
|
|
12
|
+
const { isDeployedRuntime } = require('./encryption-config');
|
|
12
13
|
const { registerDeniedKeys } = require('../../logs/denied-keys');
|
|
13
14
|
const {
|
|
14
15
|
getEntityTypeRegistry,
|
|
@@ -229,85 +230,35 @@ function loadModuleEncryptionSchemas(integrations, entities) {
|
|
|
229
230
|
*
|
|
230
231
|
* Used by both Prisma (MongoDB/PostgreSQL) and DocumentDB encryption services.
|
|
231
232
|
*/
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
*/
|
|
239
|
-
function loadExtensionEncryptionSchemas(extensions) {
|
|
240
|
-
if (!extensions || !Array.isArray(extensions) || extensions.length === 0) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
for (const ext of extensions) {
|
|
245
|
-
if (!ext.encryption || typeof ext.encryption !== 'object') {
|
|
246
|
-
continue;
|
|
247
|
-
}
|
|
233
|
+
function loadCustomEncryptionSchema() {
|
|
234
|
+
let appDefinition;
|
|
235
|
+
try {
|
|
236
|
+
// Lazy require to avoid circular dependency issues
|
|
237
|
+
const path = require('node:path');
|
|
238
|
+
const { findNearestBackendPackageJson } = require('../../utils');
|
|
248
239
|
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
schema[modelName] = { fields: config.fields };
|
|
253
|
-
}
|
|
240
|
+
const backendPackagePath = findNearestBackendPackageJson();
|
|
241
|
+
if (!backendPackagePath) {
|
|
242
|
+
return; // No backend found, skip custom schema
|
|
254
243
|
}
|
|
255
244
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
`Registering encryption schema from extension "${ext.name}" for models: ${Object.keys(schema).join(', ')}`
|
|
259
|
-
);
|
|
260
|
-
// registerCustomSchema replaces the registered schema, so merge:
|
|
261
|
-
// an extension adds its models to the app's encryption.schema
|
|
262
|
-
// rather than dropping it.
|
|
263
|
-
const merged = { ...customSchema };
|
|
264
|
-
for (const [modelName, config] of Object.entries(schema)) {
|
|
265
|
-
const existing = merged[modelName]?.fields || [];
|
|
266
|
-
merged[modelName] = {
|
|
267
|
-
...merged[modelName],
|
|
268
|
-
fields: [...new Set([...existing, ...config.fields])],
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
registerCustomSchema(merged);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
245
|
+
const backendDir = path.dirname(backendPackagePath);
|
|
246
|
+
const backendIndexPath = path.join(backendDir, 'index.js');
|
|
275
247
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
const preset = getPresetAppDefinition();
|
|
284
|
-
if (preset) {
|
|
285
|
-
return preset;
|
|
248
|
+
const backendModule = require(backendIndexPath);
|
|
249
|
+
appDefinition = backendModule?.Definition;
|
|
250
|
+
} catch (error) {
|
|
251
|
+
// No app definition to read (tests, standalone usage): there is
|
|
252
|
+
// nothing to register, so nothing is lost by carrying on.
|
|
253
|
+
logger.debug('Could not load custom encryption schema:', error.message);
|
|
254
|
+
return;
|
|
286
255
|
}
|
|
287
256
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
const backendPackagePath = findNearestBackendPackageJson();
|
|
292
|
-
if (!backendPackagePath) {
|
|
293
|
-
return null; // No backend found, skip custom schema
|
|
257
|
+
if (!appDefinition) {
|
|
258
|
+
return; // No app definition found
|
|
294
259
|
}
|
|
295
260
|
|
|
296
|
-
const backendDir = path.dirname(backendPackagePath);
|
|
297
|
-
const backendIndexPath = path.join(backendDir, 'index.js');
|
|
298
|
-
|
|
299
|
-
const backendModule = require(backendIndexPath);
|
|
300
|
-
return backendModule?.Definition || null;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function loadCustomEncryptionSchema() {
|
|
304
261
|
try {
|
|
305
|
-
const appDefinition = readAppDefinitionForEncryption();
|
|
306
|
-
|
|
307
|
-
if (!appDefinition) {
|
|
308
|
-
return; // No app definition found
|
|
309
|
-
}
|
|
310
|
-
|
|
311
262
|
// Load app-level custom schema
|
|
312
263
|
const customSchema = appDefinition.encryption?.schema;
|
|
313
264
|
if (customSchema && Object.keys(customSchema).length > 0) {
|
|
@@ -322,15 +273,6 @@ function loadCustomEncryptionSchema() {
|
|
|
322
273
|
registerEncryptionOptOut(disable);
|
|
323
274
|
}
|
|
324
275
|
|
|
325
|
-
// Load app-level extension encryption schemas. Before the module
|
|
326
|
-
// schemas: loadModuleEncryptionSchemas currently throws (see the
|
|
327
|
-
// NOTE inside it) and the throw would skip anything after it.
|
|
328
|
-
const { loadExtensions } = require('../../extensions/extension-loader');
|
|
329
|
-
const extensions = loadExtensions(appDefinition);
|
|
330
|
-
if (extensions.length > 0) {
|
|
331
|
-
loadExtensionEncryptionSchemas(extensions);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
276
|
// Load module-level encryption schemas from integrations
|
|
335
277
|
const integrations = appDefinition.integrations;
|
|
336
278
|
if (Array.isArray(integrations) || appDefinition.entities) {
|
|
@@ -340,14 +282,16 @@ function loadCustomEncryptionSchema() {
|
|
|
340
282
|
);
|
|
341
283
|
}
|
|
342
284
|
} catch (error) {
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
//
|
|
346
|
-
//
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
logger.
|
|
285
|
+
// The app declared fields to encrypt and they could not be registered:
|
|
286
|
+
// carrying on would store them in plaintext. A bad entity registry is a
|
|
287
|
+
// configuration error anywhere; a deployed function refuses to start
|
|
288
|
+
// for any registration failure, and a local run says so loudly.
|
|
289
|
+
if (error instanceof EntityRegistryError || isDeployedRuntime()) {
|
|
290
|
+
throw error;
|
|
291
|
+
}
|
|
292
|
+
logger.warn(
|
|
293
|
+
`Encryption schema from the app definition could not be registered; those fields stay plaintext in this local run: ${error.message}`
|
|
294
|
+
);
|
|
351
295
|
}
|
|
352
296
|
}
|
|
353
297
|
|
|
@@ -492,7 +436,6 @@ module.exports = {
|
|
|
492
436
|
registerEncryptionOptOut,
|
|
493
437
|
loadCustomEncryptionSchema,
|
|
494
438
|
loadModuleEncryptionSchemas,
|
|
495
|
-
loadExtensionEncryptionSchemas,
|
|
496
439
|
extractCredentialFieldsFromModules,
|
|
497
440
|
validateCustomSchema,
|
|
498
441
|
validateOptOut,
|
package/database/prisma.js
CHANGED
|
@@ -41,15 +41,13 @@ const prismaClientSingleton = () => {
|
|
|
41
41
|
const paths = [
|
|
42
42
|
// Lambda layer location (when using Prisma Lambda layer)
|
|
43
43
|
`/opt/nodejs/node_modules/generated/prisma-${dbType}`,
|
|
44
|
-
// __dirname-based absolute path (Netlify functions and bundlers)
|
|
45
|
-
require('node:path').resolve(__dirname, `../generated/prisma-${dbType}`),
|
|
46
44
|
// Local development location (relative to core package)
|
|
47
45
|
`../generated/prisma-${dbType}`,
|
|
48
46
|
];
|
|
49
47
|
|
|
50
|
-
for (const
|
|
48
|
+
for (const path of paths) {
|
|
51
49
|
try {
|
|
52
|
-
return require(
|
|
50
|
+
return require(path).PrismaClient;
|
|
53
51
|
} catch (err) {
|
|
54
52
|
// Continue to next path
|
|
55
53
|
}
|