@harperfast/harper 5.2.13 → 5.3.0-beta.1
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/agent/mcpTools.ts +1 -1
- package/agent/session.ts +25 -14
- package/bin/cliOperations.ts +58 -9
- package/bin/copyDb.ts +282 -59
- package/bin/deploySetup.ts +16 -5
- package/bin/harper.ts +1 -1
- package/bin/help.ts +4 -1
- package/bin/lite.ts +4 -1
- package/bin/restart.ts +120 -4
- package/bin/run.ts +6 -11
- package/bin/upgrade.js +7 -3
- package/bin/workloadIdentity.ts +119 -0
- package/components/Application.ts +3436 -242
- package/components/ApplicationScope.ts +8 -0
- package/components/EntryHandler.ts +59 -39
- package/components/OptionsWatcher.ts +440 -98
- package/components/RuntimeModuleTracker.ts +38 -7
- package/components/Scope.ts +56 -15
- package/components/awaitRestart.ts +84 -0
- package/components/componentLoader.ts +381 -32
- package/components/componentPreparationLock.ts +16 -5
- package/components/deploymentOperations.ts +4 -1
- package/components/deploymentRecorder.ts +9 -2
- package/components/mcp/adapters/harperHttp.ts +4 -0
- package/components/mcp/listChanged.ts +4 -0
- package/components/mcp/toolRegistry.ts +2 -0
- package/components/mcp/tools/operations.ts +9 -0
- package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
- package/components/operations.js +537 -113
- package/components/operationsValidation.js +98 -3
- package/components/packageComponent.ts +25 -1
- package/components/requestRestart.ts +11 -0
- package/components/status/ComponentStatusRegistry.ts +59 -0
- package/config/RootConfigWatcher.ts +240 -40
- package/config/configReadRetry.ts +62 -0
- package/config/configUtils.ts +357 -48
- package/config/harperConfigEnvVars.ts +170 -27
- package/config/parseConfigFile.ts +34 -0
- package/config/readConfigFileSync.ts +44 -0
- package/config/watcherArming.ts +59 -0
- package/config-root.schema.json +33 -0
- package/dataLayer/blobBackup.ts +160 -50
- package/dataLayer/delete.ts +6 -1
- package/dataLayer/harperBridge/ResourceBridge.ts +80 -10
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dataLayer/hdbInfoController.ts +34 -1
- package/dataLayer/insert.ts +44 -1
- package/dataLayer/rocksdbBackup.ts +53 -10
- package/dataLayer/schema.ts +11 -1
- package/dataLayer/schemaDescribe.ts +8 -1
- package/dist/agent/mcpTools.js +1 -1
- package/dist/agent/mcpTools.js.map +1 -1
- package/dist/agent/session.d.ts +22 -0
- package/dist/agent/session.js +26 -15
- package/dist/agent/session.js.map +1 -1
- package/dist/bin/cliOperations.js +61 -9
- package/dist/bin/cliOperations.js.map +1 -1
- package/dist/bin/copyDb.d.ts +12 -1
- package/dist/bin/copyDb.js +248 -60
- package/dist/bin/copyDb.js.map +1 -1
- package/dist/bin/deploySetup.d.ts +2 -0
- package/dist/bin/deploySetup.js +11 -3
- package/dist/bin/deploySetup.js.map +1 -1
- package/dist/bin/harper.js +1 -1
- package/dist/bin/harper.js.map +1 -1
- package/dist/bin/help.js +4 -1
- package/dist/bin/help.js.map +1 -1
- package/dist/bin/lite.js +4 -1
- package/dist/bin/lite.js.map +1 -1
- package/dist/bin/restart.js +91 -6
- package/dist/bin/restart.js.map +1 -1
- package/dist/bin/run.js +4 -10
- package/dist/bin/run.js.map +1 -1
- package/dist/bin/upgrade.js +4 -3
- package/dist/bin/upgrade.js.map +1 -1
- package/dist/bin/workloadIdentity.d.ts +18 -0
- package/dist/bin/workloadIdentity.js +100 -0
- package/dist/bin/workloadIdentity.js.map +1 -0
- package/dist/components/Application.d.ts +235 -17
- package/dist/components/Application.js +3038 -238
- package/dist/components/Application.js.map +1 -1
- package/dist/components/ApplicationScope.d.ts +8 -0
- package/dist/components/ApplicationScope.js +7 -0
- package/dist/components/ApplicationScope.js.map +1 -1
- package/dist/components/EntryHandler.js +26 -10
- package/dist/components/EntryHandler.js.map +1 -1
- package/dist/components/OptionsWatcher.d.ts +4 -0
- package/dist/components/OptionsWatcher.js +440 -99
- package/dist/components/OptionsWatcher.js.map +1 -1
- package/dist/components/RuntimeModuleTracker.js +40 -6
- package/dist/components/RuntimeModuleTracker.js.map +1 -1
- package/dist/components/Scope.js +52 -13
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/awaitRestart.d.ts +33 -0
- package/dist/components/awaitRestart.js +61 -0
- package/dist/components/awaitRestart.js.map +1 -0
- package/dist/components/componentLoader.d.ts +38 -1
- package/dist/components/componentLoader.js +313 -24
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/componentPreparationLock.d.ts +5 -0
- package/dist/components/componentPreparationLock.js +14 -6
- package/dist/components/componentPreparationLock.js.map +1 -1
- package/dist/components/deploymentOperations.js +4 -1
- package/dist/components/deploymentOperations.js.map +1 -1
- package/dist/components/deploymentRecorder.d.ts +4 -2
- package/dist/components/deploymentRecorder.js +1 -0
- package/dist/components/deploymentRecorder.js.map +1 -1
- package/dist/components/mcp/adapters/harperHttp.js +4 -0
- package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
- package/dist/components/mcp/listChanged.js +5 -0
- package/dist/components/mcp/listChanged.js.map +1 -1
- package/dist/components/mcp/toolRegistry.d.ts +1 -0
- package/dist/components/mcp/toolRegistry.js.map +1 -1
- package/dist/components/mcp/tools/operations.d.ts +5 -0
- package/dist/components/mcp/tools/operations.js +9 -0
- package/dist/components/mcp/tools/operations.js.map +1 -1
- package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
- package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
- package/dist/components/operations.d.ts +28 -0
- package/dist/components/operations.js +476 -113
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.js +97 -3
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/components/packageComponent.js +24 -0
- package/dist/components/packageComponent.js.map +1 -1
- package/dist/components/requestRestart.d.ts +1 -0
- package/dist/components/requestRestart.js +7 -0
- package/dist/components/requestRestart.js.map +1 -1
- package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
- package/dist/components/status/ComponentStatusRegistry.js +63 -0
- package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
- package/dist/config/RootConfigWatcher.d.ts +9 -1
- package/dist/config/RootConfigWatcher.js +228 -37
- package/dist/config/RootConfigWatcher.js.map +1 -1
- package/dist/config/configReadRetry.d.ts +8 -0
- package/dist/config/configReadRetry.js +62 -0
- package/dist/config/configReadRetry.js.map +1 -0
- package/dist/config/configUtils.d.ts +11 -2
- package/dist/config/configUtils.js +304 -47
- package/dist/config/configUtils.js.map +1 -1
- package/dist/config/harperConfigEnvVars.d.ts +16 -0
- package/dist/config/harperConfigEnvVars.js +162 -25
- package/dist/config/harperConfigEnvVars.js.map +1 -1
- package/dist/config/parseConfigFile.d.ts +4 -0
- package/dist/config/parseConfigFile.js +35 -0
- package/dist/config/parseConfigFile.js.map +1 -0
- package/dist/config/readConfigFileSync.d.ts +1 -0
- package/dist/config/readConfigFileSync.js +47 -0
- package/dist/config/readConfigFileSync.js.map +1 -0
- package/dist/config/watcherArming.d.ts +15 -0
- package/dist/config/watcherArming.js +59 -0
- package/dist/config/watcherArming.js.map +1 -0
- package/dist/dataLayer/blobBackup.d.ts +49 -20
- package/dist/dataLayer/blobBackup.js +139 -50
- package/dist/dataLayer/blobBackup.js.map +1 -1
- package/dist/dataLayer/delete.js +1 -1
- package/dist/dataLayer/delete.js.map +1 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.js +72 -12
- package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
- package/dist/dataLayer/hdbInfoController.d.ts +10 -0
- package/dist/dataLayer/hdbInfoController.js +30 -1
- package/dist/dataLayer/hdbInfoController.js.map +1 -1
- package/dist/dataLayer/insert.d.ts +9 -1
- package/dist/dataLayer/insert.js +30 -0
- package/dist/dataLayer/insert.js.map +1 -1
- package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
- package/dist/dataLayer/rocksdbBackup.js +45 -8
- package/dist/dataLayer/rocksdbBackup.js.map +1 -1
- package/dist/dataLayer/schema.js +8 -0
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +8 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/json/systemSchema.json +55 -0
- package/dist/resources/DatabaseTransaction.d.ts +77 -0
- package/dist/resources/DatabaseTransaction.js +586 -54
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/LMDBTransaction.d.ts +2 -1
- package/dist/resources/LMDBTransaction.js +43 -6
- package/dist/resources/LMDBTransaction.js.map +1 -1
- package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
- package/dist/resources/PrimaryRocksDatabase.js +49 -5
- package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
- package/dist/resources/RecordEncoder.d.ts +20 -0
- package/dist/resources/RecordEncoder.js +110 -9
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/RequestTarget.d.ts +2 -0
- package/dist/resources/RequestTarget.js.map +1 -1
- package/dist/resources/Resource.js +117 -24
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +28 -1
- package/dist/resources/ResourceInterface.js.map +1 -1
- package/dist/resources/RocksIndexStore.d.ts +6 -1
- package/dist/resources/RocksIndexStore.js +24 -9
- package/dist/resources/RocksIndexStore.js.map +1 -1
- package/dist/resources/RocksTransactionLogStore.d.ts +24 -1
- package/dist/resources/RocksTransactionLogStore.js +160 -49
- package/dist/resources/RocksTransactionLogStore.js.map +1 -1
- package/dist/resources/Table.d.ts +165 -10
- package/dist/resources/Table.js +1805 -303
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/write.js +10 -3
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/auditStore.d.ts +181 -2
- package/dist/resources/auditStore.js +640 -29
- package/dist/resources/auditStore.js.map +1 -1
- package/dist/resources/blob.d.ts +129 -9
- package/dist/resources/blob.js +992 -114
- package/dist/resources/blob.js.map +1 -1
- package/dist/resources/branchDatabase.d.ts +48 -0
- package/dist/resources/branchDatabase.js +892 -0
- package/dist/resources/branchDatabase.js.map +1 -0
- package/dist/resources/crdt.js +50 -12
- package/dist/resources/crdt.js.map +1 -1
- package/dist/resources/dataLoader.js +3 -4
- package/dist/resources/dataLoader.js.map +1 -1
- package/dist/resources/databases.d.ts +157 -14
- package/dist/resources/databases.js +1462 -325
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/defineTable.d.ts +10 -2
- package/dist/resources/defineTable.js +9 -1
- package/dist/resources/defineTable.js.map +1 -1
- package/dist/resources/derivedIndexRegistry.d.ts +5 -0
- package/dist/resources/derivedIndexRegistry.js +68 -0
- package/dist/resources/derivedIndexRegistry.js.map +1 -0
- package/dist/resources/derivedIndexRuntime.d.ts +215 -0
- package/dist/resources/derivedIndexRuntime.js +2027 -0
- package/dist/resources/derivedIndexRuntime.js.map +1 -0
- package/dist/resources/graphql.d.ts +1 -1
- package/dist/resources/graphql.js +52 -16
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +103 -9
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +854 -41
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/resources/indexes/hnswDerivedIndex.d.ts +67 -0
- package/dist/resources/indexes/hnswDerivedIndex.js +464 -0
- package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -0
- package/dist/resources/indexes/hnswPlaneBinding.d.ts +65 -0
- package/dist/resources/indexes/hnswPlaneBinding.js +91 -0
- package/dist/resources/indexes/hnswPlaneBinding.js.map +1 -0
- package/dist/resources/longLivedTransactions.d.ts +71 -0
- package/dist/resources/longLivedTransactions.js +358 -0
- package/dist/resources/longLivedTransactions.js.map +1 -0
- package/dist/resources/models/backendRegistry.d.ts +26 -0
- package/dist/resources/models/backendRegistry.js +60 -2
- package/dist/resources/models/backendRegistry.js.map +1 -1
- package/dist/resources/models/bootstrap.d.ts +33 -1
- package/dist/resources/models/bootstrap.js +416 -31
- package/dist/resources/models/bootstrap.js.map +1 -1
- package/dist/resources/nodeIdMapping.d.ts +5 -0
- package/dist/resources/nodeIdMapping.js +49 -0
- package/dist/resources/nodeIdMapping.js.map +1 -1
- package/dist/resources/recordLock.d.ts +123 -0
- package/dist/resources/recordLock.js +315 -0
- package/dist/resources/recordLock.js.map +1 -0
- package/dist/resources/recordLockCoordinator.d.ts +557 -0
- package/dist/resources/recordLockCoordinator.js +2565 -0
- package/dist/resources/recordLockCoordinator.js.map +1 -0
- package/dist/resources/replayLogs.d.ts +14 -1
- package/dist/resources/replayLogs.js +157 -24
- package/dist/resources/replayLogs.js.map +1 -1
- package/dist/resources/replayLogsGuards.d.ts +94 -7
- package/dist/resources/replayLogsGuards.js +111 -7
- package/dist/resources/replayLogsGuards.js.map +1 -1
- package/dist/resources/replicatedApplyFailure.d.ts +16 -0
- package/dist/resources/replicatedApplyFailure.js +63 -0
- package/dist/resources/replicatedApplyFailure.js.map +1 -0
- package/dist/resources/scheduler/scheduler.js +3 -3
- package/dist/resources/scheduler/scheduler.js.map +1 -1
- package/dist/resources/search.d.ts +10 -4
- package/dist/resources/search.js +283 -37
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/tracked.d.ts +5 -1
- package/dist/resources/tracked.js +74 -23
- package/dist/resources/tracked.js.map +1 -1
- package/dist/resources/transactionBroadcast.d.ts +1 -1
- package/dist/resources/transactionBroadcast.js +2 -2
- package/dist/resources/transactionBroadcast.js.map +1 -1
- package/dist/security/auth.js +61 -30
- package/dist/security/auth.js.map +1 -1
- package/dist/security/authn/oidc/claims.d.ts +22 -0
- package/dist/security/authn/oidc/claims.js +71 -0
- package/dist/security/authn/oidc/claims.js.map +1 -0
- package/dist/security/authn/oidc/identityToken.d.ts +27 -0
- package/dist/security/authn/oidc/identityToken.js +111 -0
- package/dist/security/authn/oidc/identityToken.js.map +1 -0
- package/dist/security/authn/oidc/jwks.d.ts +25 -0
- package/dist/security/authn/oidc/jwks.js +261 -0
- package/dist/security/authn/oidc/jwks.js.map +1 -0
- package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
- package/dist/security/authn/oidc/providers/generic.js +34 -0
- package/dist/security/authn/oidc/providers/generic.js.map +1 -0
- package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
- package/dist/security/authn/oidc/providers/githubActions.js +129 -0
- package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
- package/dist/security/authn/oidc/providers/index.d.ts +37 -0
- package/dist/security/authn/oidc/providers/index.js +24 -0
- package/dist/security/authn/oidc/providers/index.js.map +1 -0
- package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
- package/dist/security/authn/oidc/tokenExchange.js +306 -0
- package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
- package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
- package/dist/security/authn/oidc/types.d.ts +38 -0
- package/dist/security/authn/oidc/types.js +6 -0
- package/dist/security/authn/oidc/types.js.map +1 -0
- package/dist/security/certificateVerification/index.js +40 -11
- package/dist/security/certificateVerification/index.js.map +1 -1
- package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
- package/dist/security/certificateVerification/trustedIssuers.js +79 -0
- package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
- package/dist/security/certificateVerification/types.d.ts +1 -0
- package/dist/security/credentialProvenance.d.ts +35 -0
- package/dist/security/credentialProvenance.js +51 -0
- package/dist/security/credentialProvenance.js.map +1 -0
- package/dist/security/credentialRejection.d.ts +4 -0
- package/dist/security/credentialRejection.js +24 -0
- package/dist/security/credentialRejection.js.map +1 -0
- package/dist/security/deferredAuthentication.d.ts +36 -0
- package/dist/security/deferredAuthentication.js +70 -0
- package/dist/security/deferredAuthentication.js.map +1 -0
- package/dist/security/impersonation.d.ts +21 -0
- package/dist/security/impersonation.js +108 -9
- package/dist/security/impersonation.js.map +1 -1
- package/dist/security/jsLoader.d.ts +6 -0
- package/dist/security/jsLoader.js +77 -15
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +301 -71
- package/dist/security/keys.js.map +1 -1
- package/dist/security/operationScope.d.ts +21 -0
- package/dist/security/operationScope.js +36 -0
- package/dist/security/operationScope.js.map +1 -0
- package/dist/security/permissionsTranslator.js +21 -0
- package/dist/security/permissionsTranslator.js.map +1 -1
- package/dist/security/tokenAuthentication.d.ts +19 -1
- package/dist/security/tokenAuthentication.js +191 -10
- package/dist/security/tokenAuthentication.js.map +1 -1
- package/dist/security/user.js +4 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
- package/dist/server/DurableSubscriptionsSession.js +67 -10
- package/dist/server/DurableSubscriptionsSession.js.map +1 -1
- package/dist/server/REST.js +106 -2
- package/dist/server/REST.js.map +1 -1
- package/dist/server/graphqlQuerying.js +4 -0
- package/dist/server/graphqlQuerying.js.map +1 -1
- package/dist/server/http.d.ts +16 -1
- package/dist/server/http.js +122 -17
- package/dist/server/http.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +8 -1
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/server/jobs/jobProcess.js +6 -2
- package/dist/server/jobs/jobProcess.js.map +1 -1
- package/dist/server/jobs/jobs.js +4 -1
- package/dist/server/jobs/jobs.js.map +1 -1
- package/dist/server/liveSubscriptionAuth.d.ts +26 -4
- package/dist/server/liveSubscriptionAuth.js +105 -39
- package/dist/server/liveSubscriptionAuth.js.map +1 -1
- package/dist/server/loadRootComponents.js +49 -10
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/mqtt.d.ts +2 -0
- package/dist/server/mqtt.js +165 -30
- package/dist/server/mqtt.js.map +1 -1
- package/dist/server/nodeName.d.ts +2 -0
- package/dist/server/nodeName.js +107 -23
- package/dist/server/nodeName.js.map +1 -1
- package/dist/server/serverHelpers/Headers.d.ts +27 -0
- package/dist/server/serverHelpers/Headers.js +145 -1
- package/dist/server/serverHelpers/Headers.js.map +1 -1
- package/dist/server/serverHelpers/NodeAdapterResponse.d.ts +48 -0
- package/dist/server/serverHelpers/NodeAdapterResponse.js +220 -0
- package/dist/server/serverHelpers/NodeAdapterResponse.js.map +1 -0
- package/dist/server/serverHelpers/Request.d.ts +5 -10
- package/dist/server/serverHelpers/Request.js +38 -136
- package/dist/server/serverHelpers/Request.js.map +1 -1
- package/dist/server/serverHelpers/contentTypes.d.ts +11 -0
- package/dist/server/serverHelpers/contentTypes.js +221 -40
- package/dist/server/serverHelpers/contentTypes.js.map +1 -1
- package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
- package/dist/server/serverHelpers/deployValidationState.js +9 -19
- package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
- package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
- package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
- package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
- package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
- package/dist/server/serverHelpers/registeredOperations.js +74 -21
- package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
- package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
- package/dist/server/serverHelpers/requestSanitization.js +20 -0
- package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
- package/dist/server/serverHelpers/serverHandlers.js +6 -3
- package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
- package/dist/server/serverHelpers/serverUtilities.js +178 -29
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
- package/dist/server/serverHelpers/uwsServer.js +19 -1
- package/dist/server/serverHelpers/uwsServer.js.map +1 -1
- package/dist/server/static.js +24 -28
- package/dist/server/static.js.map +1 -1
- package/dist/server/storageReclamation.d.ts +5 -0
- package/dist/server/storageReclamation.js +17 -1
- package/dist/server/storageReclamation.js.map +1 -1
- package/dist/server/threads/isolatedApplications.d.ts +47 -0
- package/dist/server/threads/isolatedApplications.js +171 -0
- package/dist/server/threads/isolatedApplications.js.map +1 -0
- package/dist/server/threads/itc.d.ts +7 -2
- package/dist/server/threads/itc.js +5 -1
- package/dist/server/threads/itc.js.map +1 -1
- package/dist/server/threads/logRotationTransport.d.ts +1 -0
- package/dist/server/threads/logRotationTransport.js +33 -0
- package/dist/server/threads/logRotationTransport.js.map +1 -0
- package/dist/server/threads/manageThreads.d.ts +83 -3
- package/dist/server/threads/manageThreads.js +769 -75
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.d.ts +1 -0
- package/dist/server/threads/socketRouter.js +277 -31
- package/dist/server/threads/socketRouter.js.map +1 -1
- package/dist/server/threads/threadHeapMemory.d.ts +2 -0
- package/dist/server/threads/threadHeapMemory.js +31 -0
- package/dist/server/threads/threadHeapMemory.js.map +1 -0
- package/dist/server/threads/threadServer.js +76 -22
- package/dist/server/threads/threadServer.js.map +1 -1
- package/dist/sqlEngine/config.d.ts +1 -3
- package/dist/sqlEngine/config.js +19 -16
- package/dist/sqlEngine/config.js.map +1 -1
- package/dist/sqlTranslator/index.d.ts +1 -1
- package/dist/sqlTranslator/index.js +30 -7
- package/dist/sqlTranslator/index.js.map +1 -1
- package/dist/upgrade/directives/5-3-0.d.ts +7 -0
- package/dist/upgrade/directives/5-3-0.js +148 -0
- package/dist/upgrade/directives/5-3-0.js.map +1 -0
- package/dist/upgrade/directives/directivesController.js +2 -1
- package/dist/upgrade/directives/directivesController.js.map +1 -1
- package/dist/utility/OperationFunctionCaller.js +2 -1
- package/dist/utility/OperationFunctionCaller.js.map +1 -1
- package/dist/utility/common_utils.d.ts +16 -0
- package/dist/utility/common_utils.js +32 -6
- package/dist/utility/common_utils.js.map +1 -1
- package/dist/utility/componentNames.d.ts +8 -0
- package/dist/utility/componentNames.js +12 -1
- package/dist/utility/componentNames.js.map +1 -1
- package/dist/utility/environment/environmentManager.js +3 -6
- package/dist/utility/environment/environmentManager.js.map +1 -1
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/environment/systemInformation.js +1 -0
- package/dist/utility/environment/systemInformation.js.map +1 -1
- package/dist/utility/errors/commonErrors.d.ts +2 -0
- package/dist/utility/errors/commonErrors.js +2 -0
- package/dist/utility/errors/commonErrors.js.map +1 -1
- package/dist/utility/errors/hdbError.d.ts +33 -0
- package/dist/utility/errors/hdbError.js +58 -1
- package/dist/utility/errors/hdbError.js.map +1 -1
- package/dist/utility/globalSchema.d.ts +18 -0
- package/dist/utility/hdbTerms.d.ts +18 -0
- package/dist/utility/hdbTerms.js +20 -2
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/logging/harper_logger.d.ts +2 -0
- package/dist/utility/logging/harper_logger.js +286 -30
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/dist/utility/logging/logGenerationCoordinator.d.ts +35 -0
- package/dist/utility/logging/logGenerationCoordinator.js +184 -0
- package/dist/utility/logging/logGenerationCoordinator.js.map +1 -0
- package/dist/utility/logging/logRotation.d.ts +46 -0
- package/dist/utility/logging/logRotation.js +365 -0
- package/dist/utility/logging/logRotation.js.map +1 -0
- package/dist/utility/logging/logRotator.d.ts +1 -1
- package/dist/utility/logging/logRotator.js +192 -85
- package/dist/utility/logging/logRotator.js.map +1 -1
- package/dist/utility/nodeIdentity.d.ts +9 -0
- package/dist/utility/nodeIdentity.js +58 -0
- package/dist/utility/nodeIdentity.js.map +1 -0
- package/dist/utility/npmUtilities.js +11 -7
- package/dist/utility/npmUtilities.js.map +1 -1
- package/dist/utility/operationPermissions.d.ts +3 -1
- package/dist/utility/operationPermissions.js +16 -1
- package/dist/utility/operationPermissions.js.map +1 -1
- package/dist/utility/operation_authorization.d.ts +10 -7
- package/dist/utility/operation_authorization.js +212 -41
- package/dist/utility/operation_authorization.js.map +1 -1
- package/dist/utility/watchPath.d.ts +29 -0
- package/dist/utility/watchPath.js +68 -0
- package/dist/utility/watchPath.js.map +1 -0
- package/dist/utility/watcherFallback.d.ts +41 -0
- package/dist/utility/watcherFallback.js +153 -0
- package/dist/utility/watcherFallback.js.map +1 -1
- package/dist/validation/configValidator.d.ts +12 -0
- package/dist/validation/configValidator.js +205 -75
- package/dist/validation/configValidator.js.map +1 -1
- package/dist/validation/installValidator.js +12 -0
- package/dist/validation/installValidator.js.map +1 -1
- package/dist/validation/validationWrapper.d.ts +11 -0
- package/dist/validation/validationWrapper.js +16 -3
- package/dist/validation/validationWrapper.js.map +1 -1
- package/index.ts +8 -0
- package/json/systemSchema.json +55 -0
- package/npm-shrinkwrap.json +286 -194
- package/package.json +15 -7
- package/resources/DESIGN.md +219 -52
- package/resources/DatabaseTransaction.ts +657 -52
- package/resources/LMDBTransaction.ts +46 -6
- package/resources/PrimaryRocksDatabase.ts +46 -7
- package/resources/RecordEncoder.ts +124 -9
- package/resources/RequestTarget.ts +2 -0
- package/resources/Resource.ts +114 -22
- package/resources/ResourceInterface.ts +31 -0
- package/resources/RocksIndexStore.ts +30 -9
- package/resources/RocksTransactionLogStore.ts +188 -51
- package/resources/Table.ts +1960 -301
- package/resources/analytics/write.ts +10 -3
- package/resources/auditStore.ts +647 -32
- package/resources/blob.ts +1029 -110
- package/resources/branchDatabase.ts +941 -0
- package/resources/crdt.ts +76 -12
- package/resources/dataLoader.ts +3 -4
- package/resources/databases.ts +1584 -320
- package/resources/defineTable.ts +18 -2
- package/resources/derivedIndexRegistry.ts +56 -0
- package/resources/derivedIndexRuntime.ts +2292 -0
- package/resources/graphql.ts +72 -17
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +911 -48
- package/resources/indexes/hnswDerivedIndex.ts +531 -0
- package/resources/indexes/hnswPlaneBinding.ts +174 -0
- package/resources/longLivedTransactions.ts +360 -0
- package/resources/models/backendRegistry.ts +84 -2
- package/resources/models/bootstrap.ts +473 -28
- package/resources/nodeIdMapping.ts +50 -0
- package/resources/recordLock.ts +419 -0
- package/resources/recordLockCoordinator.ts +3043 -0
- package/resources/replayLogs.ts +152 -26
- package/resources/replayLogsGuards.ts +171 -8
- package/resources/replicatedApplyFailure.ts +77 -0
- package/resources/scheduler/scheduler.ts +4 -4
- package/resources/search.ts +288 -46
- package/resources/tracked.ts +73 -22
- package/resources/transactionBroadcast.ts +3 -3
- package/security/auth.ts +68 -29
- package/security/authn/oidc/claims.ts +72 -0
- package/security/authn/oidc/identityToken.ts +129 -0
- package/security/authn/oidc/jwks.ts +260 -0
- package/security/authn/oidc/providers/generic.ts +40 -0
- package/security/authn/oidc/providers/githubActions.ts +137 -0
- package/security/authn/oidc/providers/index.ts +52 -0
- package/security/authn/oidc/tokenExchange.ts +300 -0
- package/security/authn/oidc/trustPolicyOperations.ts +343 -0
- package/security/authn/oidc/types.ts +41 -0
- package/security/certificateVerification/index.ts +54 -13
- package/security/certificateVerification/trustedIssuers.ts +76 -0
- package/security/certificateVerification/types.ts +1 -0
- package/security/credentialProvenance.ts +47 -0
- package/security/credentialRejection.ts +22 -0
- package/security/deferredAuthentication.ts +71 -0
- package/security/impersonation.ts +117 -12
- package/security/jsLoader.ts +83 -18
- package/security/keys.ts +298 -72
- package/security/operationScope.ts +33 -0
- package/security/permissionsTranslator.js +23 -0
- package/security/tokenAuthentication.ts +233 -12
- package/security/user.ts +4 -3
- package/server/DESIGN.md +194 -16
- package/server/DurableSubscriptionsSession.ts +71 -11
- package/server/REST.ts +115 -4
- package/server/graphqlQuerying.ts +4 -0
- package/server/http.ts +133 -20
- package/server/itc/serverHandlers.js +8 -1
- package/server/jobs/jobProcess.ts +8 -2
- package/server/jobs/jobs.ts +4 -1
- package/server/liveSubscriptionAuth.ts +129 -46
- package/server/loadRootComponents.js +50 -8
- package/server/mqtt.ts +179 -38
- package/server/nodeName.ts +103 -21
- package/server/serverHelpers/Headers.ts +135 -0
- package/server/serverHelpers/NodeAdapterResponse.ts +221 -0
- package/server/serverHelpers/Request.ts +33 -131
- package/server/serverHelpers/contentTypes.ts +217 -36
- package/server/serverHelpers/deployValidationState.ts +24 -13
- package/server/serverHelpers/operationAuthorizationState.ts +34 -3
- package/server/serverHelpers/registeredOperations.ts +79 -22
- package/server/serverHelpers/requestSanitization.ts +15 -0
- package/server/serverHelpers/serverHandlers.js +6 -3
- package/server/serverHelpers/serverUtilities.ts +232 -40
- package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
- package/server/serverHelpers/uwsServer.ts +17 -2
- package/server/static.ts +23 -29
- package/server/storageReclamation.ts +15 -2
- package/server/threads/isolatedApplications.ts +157 -0
- package/server/threads/itc.js +11 -1
- package/server/threads/logRotationTransport.ts +40 -0
- package/server/threads/manageThreads.js +771 -66
- package/server/threads/socketRouter.ts +291 -30
- package/server/threads/threadHeapMemory.ts +26 -0
- package/server/threads/threadServer.js +73 -22
- package/sqlTranslator/index.ts +31 -8
- package/studio/web/assets/{Chat-4RrB5134.js → Chat-D3j-1yY1.js} +1 -1
- package/studio/web/assets/{FloatingChat-omlNMDcJ.js → FloatingChat-BxJGYcfB.js} +3 -3
- package/studio/web/assets/{apiToken-Bke3wvfZ.js → apiToken-CT55oWOe.js} +1 -1
- package/studio/web/assets/{applications-DvFDYJgK.js → applications-D9Ct9_vm.js} +1 -1
- package/studio/web/assets/{cssMode-C1vRa7zh.js → cssMode-DV8H7VwA.js} +1 -1
- package/studio/web/assets/{editor-3XRWEDWX.js → editor-uatc0unt.js} +1 -1
- package/studio/web/assets/{html-CTY5tdMr.js → html-Bm6D6paN.js} +1 -1
- package/studio/web/assets/{htmlMode-CG1vSD9t.js → htmlMode-CEn7tpLG.js} +1 -1
- package/studio/web/assets/{index-Dfpeofdu.js → index-BIXW6Pu4.js} +5 -5
- package/studio/web/assets/{index.lazy-B1VOIv-t.js → index.lazy-UI7L-Vrk.js} +1 -1
- package/studio/web/assets/{javascript-CJeJzGnI.js → javascript-CJ0G3AFZ.js} +1 -1
- package/studio/web/assets/{jsonMode-CYPBwM82.js → jsonMode-DQADAYEa.js} +1 -1
- package/studio/web/assets/{languageServices-IKH4GUHl.js → languageServices-CAQJXWcI.js} +1 -1
- package/studio/web/assets/{lspLanguageFeatures-BC8_gxKG.js → lspLanguageFeatures-CCQ8P5sY.js} +1 -1
- package/studio/web/assets/{notifications-BfKBpYcq.js → notifications-BbxTU6Aw.js} +1 -1
- package/studio/web/assets/{notifications-DFbArTfC.js → notifications-Cvb3P1lB.js} +1 -1
- package/studio/web/assets/{profile-Q4-T6c-S.js → profile-Yyb7gsvL.js} +1 -1
- package/studio/web/assets/{regions-CtkV0xje.js → regions-OgjGHlU5.js} +1 -1
- package/studio/web/assets/{register-1ZZuMsiA.js → register-6qwNEOY3.js} +2 -2
- package/studio/web/assets/{setComponentFile-ZWLcWv5X.js → setComponentFile-BilDMtgB.js} +1 -1
- package/studio/web/assets/{setup-DWprJyJy.js → setup-J6qJ7OIU.js} +2 -2
- package/studio/web/assets/{status--aNm8isn.js → status-0RWGcfyD.js} +1 -1
- package/studio/web/assets/{toggleHighContrast-Cq_lt3XD.js → toggleHighContrast-BIn-vErT.js} +1 -1
- package/studio/web/assets/{tsMode-pjgytARx.js → tsMode-DgUXku4d.js} +1 -1
- package/studio/web/assets/{typescript-Cdg0mqUh.js → typescript-C9orXcsM.js} +1 -1
- package/studio/web/assets/{useEntityRestURL-RZhaY8Rn.js → useEntityRestURL-BEoXXbUB.js} +1 -1
- package/studio/web/assets/{workers-BgoXIqQe.js → workers-JVzSDmgx.js} +1 -1
- package/studio/web/assets/{xml-BwSeDMiP.js → xml-Cq-S8S4X.js} +1 -1
- package/studio/web/assets/{yaml-DotCUG5l.js → yaml-sfoRdh1M.js} +1 -1
- package/studio/web/index.html +1 -1
- package/upgrade/directives/5-3-0.ts +132 -0
- package/upgrade/directives/directivesController.ts +2 -1
- package/utility/OperationFunctionCaller.ts +2 -1
- package/utility/common_utils.ts +30 -5
- package/utility/componentNames.ts +12 -0
- package/utility/environment/environmentManager.ts +3 -7
- package/utility/environment/systemInformation.ts +7 -0
- package/utility/errors/commonErrors.ts +4 -0
- package/utility/errors/hdbError.ts +57 -0
- package/utility/hdbTerms.ts +19 -0
- package/utility/logging/harper_logger.ts +278 -26
- package/utility/logging/logGenerationCoordinator.ts +196 -0
- package/utility/logging/logRotation.ts +367 -0
- package/utility/logging/logRotator.ts +213 -81
- package/utility/nodeIdentity.ts +45 -0
- package/utility/npmUtilities.ts +12 -8
- package/utility/operationPermissions.ts +18 -1
- package/utility/operation_authorization.ts +231 -42
- package/utility/watchPath.ts +63 -0
- package/utility/watcherFallback.ts +148 -0
- package/validation/configValidator.ts +215 -75
- package/validation/installValidator.ts +15 -0
- package/validation/validationWrapper.ts +18 -4
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ClientError } from '../utility/errors/hdbError.ts';
|
|
2
|
+
import { serializeMessage, findBestSerializer } from '../server/serverHelpers/contentTypes.ts';
|
|
3
|
+
import { Headers } from '../server/serverHelpers/Headers.ts';
|
|
4
|
+
|
|
5
|
+
export { isCredentialRejection, markCredentialRejection, credentialRejectionError } from './credentialRejection.ts';
|
|
6
|
+
|
|
7
|
+
const DEFERRED_CREDENTIAL_REJECTION = Symbol('harper.deferredCredentialRejection');
|
|
8
|
+
|
|
9
|
+
export type DeferredCredentialRejection = {
|
|
10
|
+
readonly status: number;
|
|
11
|
+
readonly message: string;
|
|
12
|
+
readonly strategy: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const CREDENTIAL_REJECTION_STATUS = 401;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Records that this request presented a credential Harper rejected, without deciding the request.
|
|
19
|
+
* The caller leaves `request.user` unset and the inbound `Authorization` header untouched.
|
|
20
|
+
*
|
|
21
|
+
* The immutable, non-enumerable descriptor prevents downstream middleware from clearing it and
|
|
22
|
+
* keeps it out of request copies and serialization.
|
|
23
|
+
*/
|
|
24
|
+
export function deferCredentialRejection(request: any, error: { message?: string }, strategy: string): void {
|
|
25
|
+
if (getDeferredCredentialRejection(request)) return;
|
|
26
|
+
const deferred: DeferredCredentialRejection = Object.freeze({
|
|
27
|
+
status: CREDENTIAL_REJECTION_STATUS,
|
|
28
|
+
message: error?.message ?? 'Unauthorized',
|
|
29
|
+
strategy,
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(request, DEFERRED_CREDENTIAL_REJECTION, {
|
|
32
|
+
value: deferred,
|
|
33
|
+
enumerable: false,
|
|
34
|
+
configurable: false,
|
|
35
|
+
writable: false,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function getDeferredCredentialRejection(request: any): DeferredCredentialRejection | undefined {
|
|
40
|
+
return request?.[DEFERRED_CREDENTIAL_REJECTION];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The response an owning layer returns once it has established Harper owns the route: exactly the
|
|
45
|
+
* descriptor `security/auth.ts` returns in-line, so immediate and deferred rejection share a wire
|
|
46
|
+
* contract.
|
|
47
|
+
*
|
|
48
|
+
* Owner-specific error mapping must not run first. REST renders a thrown error as an RFC 9457
|
|
49
|
+
* Problem Details document and GraphQL as `{errors:[…]}` rather than authentication's negotiated
|
|
50
|
+
* `{error: message}` response. `security/auth.ts` likewise leaves a settled rejection's status and
|
|
51
|
+
* challenge headers alone, so it stays byte-identical to the in-line 401 it replaced.
|
|
52
|
+
*
|
|
53
|
+
* Returns `undefined` when nothing was deferred, so a caller can `return settled ?? …` inline.
|
|
54
|
+
*/
|
|
55
|
+
export function settleDeferredCredentialRejection(
|
|
56
|
+
request: any
|
|
57
|
+
): { status: number; headers: Headers; body: string | Buffer } | undefined {
|
|
58
|
+
const deferred = getDeferredCredentialRejection(request);
|
|
59
|
+
if (!deferred) return undefined;
|
|
60
|
+
const contentType = (request?.headers ? findBestSerializer(request).type : undefined) ?? 'application/json';
|
|
61
|
+
return {
|
|
62
|
+
status: deferred.status,
|
|
63
|
+
headers: new Headers({ 'Content-Type': contentType }),
|
|
64
|
+
body: serializeMessage({ error: deferred.message }, request) as string | Buffer,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function assertNoDeferredCredentialRejection(request: any): void {
|
|
69
|
+
const deferred = getDeferredCredentialRejection(request);
|
|
70
|
+
if (deferred) throw new ClientError(deferred.message, deferred.status);
|
|
71
|
+
}
|
|
@@ -1,10 +1,46 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import type { User, UserRole } from './user.ts';
|
|
2
3
|
import type { ImpersonatePayload } from '../server/operationsServer.ts';
|
|
3
4
|
import { getUsersWithRolesCache } from './user.ts';
|
|
4
5
|
import { validateOperations } from '../utility/operationPermissions.ts';
|
|
6
|
+
import { addRoleValidation } from '../validation/role_validation.ts';
|
|
5
7
|
import { ClientError } from '../utility/errors/hdbError.ts';
|
|
6
8
|
import harperLogger from '../utility/logging/harper_logger.ts';
|
|
7
9
|
import { getRoleByName } from './role.ts';
|
|
10
|
+
import { attachScopeToUser } from './operationScope.ts';
|
|
11
|
+
import { attachWorkloadIdentityToUser } from './credentialProvenance.ts';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Content-derived identity for synthetic (inline) roles. getRolePermissions memoizes translated
|
|
15
|
+
* permissions by role name, so synthetic roles must never share a constant name: two inline roles
|
|
16
|
+
* with different permissions would alias in that cache and leak permissions across principals.
|
|
17
|
+
* Hashing the (already downgraded) permission content isolates distinct permission sets while
|
|
18
|
+
* letting identical ones share a cache entry. The paired __updatedtime__ of 0 keeps the memo key
|
|
19
|
+
* stable across requests; the content hash in the name is what invalidates on permission change.
|
|
20
|
+
*
|
|
21
|
+
* Object keys are canonicalized before hashing so two structurally-identical permission sets that
|
|
22
|
+
* differ only in key order (e.g. from different client request shapes) map to the same name and
|
|
23
|
+
* share one cache slot — otherwise they would each consume a distinct slot (never an aliasing bug,
|
|
24
|
+
* but it worsens the bounded synthetic-role cache pressure).
|
|
25
|
+
*/
|
|
26
|
+
export function syntheticRoleName(prefix: string, permission: object): string {
|
|
27
|
+
return `${prefix}_${createHash('sha256').update(canonicalJSON(permission)).digest('hex').slice(0, 24)}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Array order is intentionally preserved: operations is order-insensitive semantically, but
|
|
31
|
+
// canonicalizing it too would be a broader behavior change than this cache-sharing fix needs.
|
|
32
|
+
function canonicalJSON(value: any): string {
|
|
33
|
+
return JSON.stringify(value, (_key, v) =>
|
|
34
|
+
v && typeof v === 'object' && !Array.isArray(v)
|
|
35
|
+
? Object.keys(v)
|
|
36
|
+
.sort()
|
|
37
|
+
.reduce((acc: any, k) => {
|
|
38
|
+
acc[k] = v[k];
|
|
39
|
+
return acc;
|
|
40
|
+
}, {})
|
|
41
|
+
: v
|
|
42
|
+
);
|
|
43
|
+
}
|
|
8
44
|
|
|
9
45
|
/**
|
|
10
46
|
* Applies impersonation to a request. The authenticated user must be a super_user.
|
|
@@ -38,6 +74,26 @@ export async function applyImpersonation(authenticatedUser: User, payload: Imper
|
|
|
38
74
|
// Enforce downgrade: never allow escalation
|
|
39
75
|
enforceDowngrade(impersonatedUser);
|
|
40
76
|
|
|
77
|
+
// A token's operation scope (#2174) constrains the credential regardless of which principal it
|
|
78
|
+
// acts as, so it survives impersonation. enforceDowngrade only bounds the impersonated role's
|
|
79
|
+
// permissions; without carrying the scope, a scoped super_user token would shed it by impersonating.
|
|
80
|
+
attachScopeToUser(impersonatedUser, (authenticatedUser as any).tokenOperations);
|
|
81
|
+
// Same reasoning for provenance (#2171), and the omission would be worse: impersonation returns a
|
|
82
|
+
// NEW principal, so dropping the marker here would let a workload token impersonate — even down to
|
|
83
|
+
// a lesser role — and then mint a 30-day credential that createTokens would no longer refuse.
|
|
84
|
+
attachWorkloadIdentityToUser(impersonatedUser, (authenticatedUser as any).fromWorkloadIdentity);
|
|
85
|
+
|
|
86
|
+
// Re-key the synthetic role by its effective (post-downgrade) content so it can never alias
|
|
87
|
+
// another impersonation's permissions or poison a persisted role's memoized translation —
|
|
88
|
+
// getRolePermissions caches by role name (see syntheticRoleName).
|
|
89
|
+
if (impersonatedUser.role) {
|
|
90
|
+
impersonatedUser.role = {
|
|
91
|
+
...impersonatedUser.role,
|
|
92
|
+
role: syntheticRoleName('_impersonated', impersonatedUser.role.permission),
|
|
93
|
+
__updatedtime__: 0,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
41
97
|
// Tag for audit trail
|
|
42
98
|
impersonatedUser._impersonated = true;
|
|
43
99
|
impersonatedUser._impersonatedBy = authenticatedUser.username;
|
|
@@ -49,9 +105,60 @@ export async function applyImpersonation(authenticatedUser: User, payload: Imper
|
|
|
49
105
|
return impersonatedUser;
|
|
50
106
|
}
|
|
51
107
|
|
|
52
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Builds the synthetic user embedded in a scoped authentication token
|
|
110
|
+
* (create_authentication_tokens with an inline `role` object). Same gate and downgrade rules as
|
|
111
|
+
* impersonation Mode A. `trusted` marks internal dispatch (operation authorization bypassed),
|
|
112
|
+
* where no authenticated minter exists.
|
|
113
|
+
*/
|
|
114
|
+
export async function buildScopedTokenUser(
|
|
115
|
+
minter: User | undefined,
|
|
116
|
+
payload: ImpersonatePayload,
|
|
117
|
+
trusted = false
|
|
118
|
+
): Promise<User> {
|
|
119
|
+
if (!trusted && !minter?.role?.permission?.super_user) {
|
|
120
|
+
throw new ClientError('Only super_user can create a token with an inline role', 403);
|
|
121
|
+
}
|
|
122
|
+
validatePayload(payload, 'scoped token role');
|
|
123
|
+
if (!payload.role) {
|
|
124
|
+
throw new ClientError("A scoped token requires 'role' with 'permission'");
|
|
125
|
+
}
|
|
126
|
+
const username = payload.username || (minter?.username && `scoped:${minter.username}`);
|
|
127
|
+
if (!username || typeof username !== 'string') {
|
|
128
|
+
throw new ClientError("A scoped token requires a 'username'");
|
|
129
|
+
}
|
|
130
|
+
// The attribution name must never collide with a real principal: paths that rehydrate a user
|
|
131
|
+
// by name (e.g. MQTT last-will replay) would resolve the token's bearer to that user's full
|
|
132
|
+
// permissions. This also keeps scoped-token activity distinguishable in audit logs.
|
|
133
|
+
if ((await getUsersWithRolesCache())?.has(username)) {
|
|
134
|
+
throw new ClientError(`'username' must not name an existing user; scoped-token attribution is a label`);
|
|
135
|
+
}
|
|
136
|
+
// Downgrade first so validation and the content hash see the effective permission set.
|
|
137
|
+
const permission = {
|
|
138
|
+
...payload.role.permission,
|
|
139
|
+
super_user: false,
|
|
140
|
+
cluster_user: false,
|
|
141
|
+
} as UserRole['permission'];
|
|
142
|
+
// Full persisted-role validation: a malformed shape must fail at mint (400), not at every use.
|
|
143
|
+
const deepValidation = addRoleValidation({ role: 'scoped_token', permission });
|
|
144
|
+
if (deepValidation) throw deepValidation;
|
|
145
|
+
const roleName = syntheticRoleName('_scoped_token', permission);
|
|
146
|
+
return {
|
|
147
|
+
username,
|
|
148
|
+
active: true,
|
|
149
|
+
role: {
|
|
150
|
+
permission,
|
|
151
|
+
role: roleName,
|
|
152
|
+
id: roleName,
|
|
153
|
+
__updatedtime__: 0,
|
|
154
|
+
__createdtime__: 0,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function validatePayload(payload: ImpersonatePayload, context = 'impersonate payload'): void {
|
|
53
160
|
if (typeof payload !== 'object' || payload === null || Array.isArray(payload)) {
|
|
54
|
-
throw new ClientError(
|
|
161
|
+
throw new ClientError(`Invalid ${context}: must be an object`);
|
|
55
162
|
}
|
|
56
163
|
|
|
57
164
|
const hasRole = payload.role !== undefined;
|
|
@@ -59,33 +166,31 @@ function validatePayload(payload: ImpersonatePayload): void {
|
|
|
59
166
|
const hasRoleName = typeof payload.role_name === 'string' && payload.role_name.length > 0;
|
|
60
167
|
|
|
61
168
|
if (!hasRole && !hasUsername && !hasRoleName) {
|
|
62
|
-
throw new ClientError(
|
|
63
|
-
"Invalid impersonate payload: must include 'username', 'role_name', or 'role' with 'permission'"
|
|
64
|
-
);
|
|
169
|
+
throw new ClientError(`Invalid ${context}: must include 'username', 'role_name', or 'role' with 'permission'`);
|
|
65
170
|
}
|
|
66
171
|
|
|
67
172
|
if (hasRole) {
|
|
68
173
|
if (typeof payload.role !== 'object' || payload.role === null) {
|
|
69
|
-
throw new ClientError(
|
|
174
|
+
throw new ClientError(`Invalid ${context}: 'role' must be an object`);
|
|
70
175
|
}
|
|
71
176
|
if (typeof payload.role.permission !== 'object' || payload.role.permission === null) {
|
|
72
|
-
throw new ClientError(
|
|
177
|
+
throw new ClientError(`Invalid ${context}: 'role.permission' must be an object`);
|
|
73
178
|
}
|
|
74
|
-
validateOperationsField(payload.role.permission);
|
|
179
|
+
validateOperationsField(payload.role.permission, context);
|
|
75
180
|
}
|
|
76
181
|
}
|
|
77
182
|
|
|
78
|
-
function validateOperationsField(permission: Record<string, unknown
|
|
183
|
+
function validateOperationsField(permission: Record<string, unknown>, context = 'impersonate payload'): void {
|
|
79
184
|
const operations = permission.operations;
|
|
80
185
|
if (operations === undefined) return;
|
|
81
186
|
|
|
82
187
|
if (!Array.isArray(operations)) {
|
|
83
|
-
throw new ClientError(
|
|
188
|
+
throw new ClientError(`Invalid ${context}: 'operations' must be an array`);
|
|
84
189
|
}
|
|
85
190
|
|
|
86
191
|
const invalidOp = validateOperations(operations);
|
|
87
192
|
if (invalidOp !== null) {
|
|
88
|
-
throw new ClientError(`Invalid
|
|
193
|
+
throw new ClientError(`Invalid ${context}: unknown operation '${invalidOp}'`);
|
|
89
194
|
}
|
|
90
195
|
}
|
|
91
196
|
|
package/security/jsLoader.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Resource } from '../resources/Resource.ts';
|
|
2
2
|
import { contextStorage, transaction } from '../resources/transaction.ts';
|
|
3
3
|
import { RequestTarget } from '../resources/RequestTarget.ts';
|
|
4
|
-
import { tables, databases } from '../resources/databases.ts';
|
|
4
|
+
import { tables, databases, scopedTableFactory } from '../resources/databases.ts';
|
|
5
5
|
import { models as harperModelsSingleton } from '../resources/models/Models.ts';
|
|
6
|
-
import { defineTable, types } from '../resources/defineTable.ts';
|
|
6
|
+
import { defineTable, defineTableUsing, types } from '../resources/defineTable.ts';
|
|
7
7
|
import { defineResource, t, schemaOf, projectTableFragment } from '../resources/defineResource.ts';
|
|
8
8
|
import { readFile } from 'node:fs/promises';
|
|
9
9
|
import { dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
@@ -15,10 +15,12 @@ import logger from '../utility/logging/harper_logger.ts';
|
|
|
15
15
|
import { createRequire } from 'node:module';
|
|
16
16
|
import * as env from '../utility/environment/environmentManager';
|
|
17
17
|
import * as child_process from 'node:child_process';
|
|
18
|
-
import { CONFIG_PARAMS } from '../utility/hdbTerms.ts';
|
|
18
|
+
import { CONFIG_PARAMS, DEFAULT_DATABASE_NAME } from '../utility/hdbTerms.ts';
|
|
19
|
+
|
|
19
20
|
import { contentTypes } from '../server/serverHelpers/contentTypes.ts';
|
|
20
21
|
import type {} from 'ses';
|
|
21
22
|
import {
|
|
23
|
+
existsSync,
|
|
22
24
|
mkdirSync,
|
|
23
25
|
readFileSync,
|
|
24
26
|
writeFileSync,
|
|
@@ -30,6 +32,7 @@ import {
|
|
|
30
32
|
} from 'node:fs';
|
|
31
33
|
import { EventEmitter } from 'node:events';
|
|
32
34
|
import { whenComponentsLoaded } from '../server/threads/threadServer.js';
|
|
35
|
+
import { thisThreadOwnsApplication } from '../server/threads/isolatedApplications.ts';
|
|
33
36
|
|
|
34
37
|
type Lockdown = 'none' | 'freeze' | 'ses' | 'freeze-after-load';
|
|
35
38
|
const APPLICATIONS_LOCKDOWN: Lockdown = env.get(CONFIG_PARAMS.APPLICATIONS_LOCKDOWN);
|
|
@@ -174,13 +177,13 @@ function walkExportsConditions(entry: unknown, conditions: readonly string[]): s
|
|
|
174
177
|
|
|
175
178
|
/**
|
|
176
179
|
* Resolve a bare package specifier to a file:// URL using the package's exports map
|
|
177
|
-
* with ESM import conditions. Used as a fallback when
|
|
178
|
-
*
|
|
179
|
-
* conditions and no "require").
|
|
180
|
+
* with ESM import conditions. Used as a fallback when the runtime's CommonJS resolver
|
|
181
|
+
* cannot match a pure-ESM package (exports map with only "import" conditions).
|
|
180
182
|
*/
|
|
181
183
|
function resolveESMPackageExports(
|
|
182
184
|
specifier: string,
|
|
183
|
-
fromDir: string
|
|
185
|
+
fromDir: string,
|
|
186
|
+
preferRequireConditions = false
|
|
184
187
|
): { resolvedUrl: string; packageJsonUrl: string; packageJsonSource: Buffer } | null {
|
|
185
188
|
const isScoped = specifier.startsWith('@');
|
|
186
189
|
const parts = specifier.split('/');
|
|
@@ -223,11 +226,23 @@ function resolveESMPackageExports(
|
|
|
223
226
|
|
|
224
227
|
if (!entry) return null;
|
|
225
228
|
|
|
226
|
-
const relative =
|
|
229
|
+
const relative = preferRequireConditions
|
|
230
|
+
? (walkExportsConditions(entry, ['bun', 'require', 'node', 'default']) ??
|
|
231
|
+
walkExportsConditions(entry, ['bun', 'import', 'node', 'default']))
|
|
232
|
+
: walkExportsConditions(entry, ['import', 'node', 'default']);
|
|
227
233
|
if (!relative) return null;
|
|
228
234
|
|
|
235
|
+
let resolvedPath = join(pkgRoot, relative);
|
|
236
|
+
if (preferRequireConditions && !existsSync(resolvedPath)) {
|
|
237
|
+
// The runtime's preferred condition (Bun's `require`) named a target that isn't
|
|
238
|
+
// actually on disk -- fall back to the plain ESM `import` condition instead of
|
|
239
|
+
// failing resolution outright.
|
|
240
|
+
const importRelative = walkExportsConditions(entry, ['import', 'node', 'default']);
|
|
241
|
+
if (importRelative) resolvedPath = join(pkgRoot, importRelative);
|
|
242
|
+
}
|
|
243
|
+
|
|
229
244
|
return {
|
|
230
|
-
resolvedUrl: pathToFileURL(realpathSync(
|
|
245
|
+
resolvedUrl: pathToFileURL(realpathSync(resolvedPath)).toString(),
|
|
231
246
|
packageJsonUrl: pathToFileURL(realpathSync(packageJsonPath)).toString(),
|
|
232
247
|
packageJsonSource,
|
|
233
248
|
};
|
|
@@ -325,9 +340,10 @@ async function loadModuleWithVM(moduleUrl: string, scope: ApplicationScope, useC
|
|
|
325
340
|
const referrerDir = resolveReferrer.startsWith('file:')
|
|
326
341
|
? dirname(fileURLToPath(resolveReferrer))
|
|
327
342
|
: dirname(resolveReferrer);
|
|
328
|
-
const esmResolved = resolveESMPackageExports(specifier, referrerDir);
|
|
343
|
+
const esmResolved = resolveESMPackageExports(specifier, referrerDir, (err as any)?.code === 'MODULE_NOT_FOUND');
|
|
329
344
|
if (esmResolved) {
|
|
330
345
|
scope.recordLoadedModule?.(esmResolved.packageJsonUrl, esmResolved.packageJsonSource);
|
|
346
|
+
scope.recordLoadedModule?.(esmResolved.resolvedUrl, readFileSync(new URL(esmResolved.resolvedUrl)));
|
|
331
347
|
return esmResolved.resolvedUrl;
|
|
332
348
|
}
|
|
333
349
|
}
|
|
@@ -849,6 +865,53 @@ function getGlobalObject(scope: ApplicationScope, copyIntrinsics = false) {
|
|
|
849
865
|
// `Resource`/`tables`/`databases`/`createBlob`/… below are the live, process-wide singletons (the
|
|
850
866
|
// same values surfaced as the top-level package exports and bare globals), not per-compartment
|
|
851
867
|
// copies — only `server`/`logger`/`resources`/`config` are scope-overridable.
|
|
868
|
+
/**
|
|
869
|
+
* The `databases`/`tables` a scope sees. An application that declared `branchedDatabases` gets a view
|
|
870
|
+
* in which those names resolve to its private graph and everything else falls through to the real
|
|
871
|
+
* map, live: `databases` gains entries at runtime (`ensureDB`), so a copy taken at load would
|
|
872
|
+
* silently stop showing databases created afterwards.
|
|
873
|
+
*
|
|
874
|
+
* An unbranched scope gets the process-wide singletons **by identity**, not a view: that is the
|
|
875
|
+
* overwhelmingly common case and it must stay indistinguishable from before, and it means only
|
|
876
|
+
* branched applications pay for the indirection. Proxying rather than copying also keeps
|
|
877
|
+
* `databases.system` — deliberately non-enumerable (`resources/databases.ts`) — reachable for free.
|
|
878
|
+
*/
|
|
879
|
+
function scopedDatabaseBindings(scope: ApplicationScope): { databases: any; tables: any } {
|
|
880
|
+
const branches = scope.branches;
|
|
881
|
+
if (!branches?.size) return { databases, tables };
|
|
882
|
+
// Every branched name already exists on the target as a writable, configurable property (a branch
|
|
883
|
+
// is only ever taken of a database that exists), so overriding it here breaks no Proxy invariant.
|
|
884
|
+
const scoped = new Proxy(databases, {
|
|
885
|
+
get: (target, key, receiver) =>
|
|
886
|
+
typeof key === 'string' && branches.has(key) ? branches.get(key)!.tables : Reflect.get(target, key, receiver),
|
|
887
|
+
getOwnPropertyDescriptor(target, key) {
|
|
888
|
+
if (typeof key !== 'string' || !branches.has(key)) return Reflect.getOwnPropertyDescriptor(target, key);
|
|
889
|
+
return { value: branches.get(key)!.tables, writable: true, enumerable: true, configurable: true };
|
|
890
|
+
},
|
|
891
|
+
});
|
|
892
|
+
// `tables` is the flat alias for the default database, so it follows that database's branch.
|
|
893
|
+
return { databases: scoped, tables: branches.get(DEFAULT_DATABASE_NAME)?.tables ?? tables };
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
/**
|
|
897
|
+
* `defineTable` for a branched or isolated application registers through that application's table
|
|
898
|
+
* factory, so a branched name lands in its branch and an isolated schema is tagged with its owner.
|
|
899
|
+
*/
|
|
900
|
+
function scopedDefineTable(scope: ApplicationScope): typeof defineTable {
|
|
901
|
+
const branches = scope.branches;
|
|
902
|
+
const isolatedApplicationOwner = thisThreadOwnsApplication(scope.name);
|
|
903
|
+
if (!branches?.size && !isolatedApplicationOwner) return defineTable;
|
|
904
|
+
const declareTable = scopedTableFactory(branches, isolatedApplicationOwner);
|
|
905
|
+
return function (name: string, shape: any, options?: any) {
|
|
906
|
+
return defineTableUsing(declareTable, name, shape, options);
|
|
907
|
+
} as typeof defineTable;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
/** Everything an application sees differently because of what it declared. Built once, at load. */
|
|
911
|
+
export function scopedBindings(scope: ApplicationScope): { databases: any; tables: any; defineTable: any } {
|
|
912
|
+
return { ...scopedDatabaseBindings(scope), defineTable: scopedDefineTable(scope) };
|
|
913
|
+
}
|
|
914
|
+
|
|
852
915
|
function getHarperExports(scope: ApplicationScope) {
|
|
853
916
|
return {
|
|
854
917
|
server: scope.server ?? server,
|
|
@@ -859,9 +922,7 @@ function getHarperExports(scope: ApplicationScope) {
|
|
|
859
922
|
// the process-wide singletons below.
|
|
860
923
|
secrets: getSecretsForComponent(scope.name),
|
|
861
924
|
Resource,
|
|
862
|
-
|
|
863
|
-
databases,
|
|
864
|
-
defineTable,
|
|
925
|
+
...scopedBindings(scope),
|
|
865
926
|
types,
|
|
866
927
|
defineResource,
|
|
867
928
|
t,
|
|
@@ -914,7 +975,6 @@ const ALLOWED_NODE_BUILTIN_MODULES = env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDB
|
|
|
914
975
|
return true;
|
|
915
976
|
},
|
|
916
977
|
};
|
|
917
|
-
const ALLOWED_COMMANDS = new Set(env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDSPAWNCOMMANDS) ?? []);
|
|
918
978
|
const child_processConstrained: any = {
|
|
919
979
|
exec: createSpawn(child_process.exec),
|
|
920
980
|
execFile: createSpawn(child_process.execFile),
|
|
@@ -1070,10 +1130,15 @@ function acquirePidFileLock(
|
|
|
1070
1130
|
}
|
|
1071
1131
|
|
|
1072
1132
|
function createSpawn(spawnFunction: (...args: any) => child_process.ChildProcess, alwaysAllow?: boolean) {
|
|
1073
|
-
const basePath = env.getHdbBasePath();
|
|
1074
1133
|
return function (command: string, args?: any, options?: any, callback?: (...args: any[]) => void) {
|
|
1075
|
-
|
|
1076
|
-
|
|
1134
|
+
// componentLoader imports this module, so it can load before the config is resolved; a value
|
|
1135
|
+
// captured out here would pin an empty allowlist, and an undefined base path, for the life of
|
|
1136
|
+
// the process. Anything but a configured list denies.
|
|
1137
|
+
if (!alwaysAllow) {
|
|
1138
|
+
const allowedCommands = env.get(CONFIG_PARAMS.APPLICATIONS_ALLOWEDSPAWNCOMMANDS);
|
|
1139
|
+
if (!Array.isArray(allowedCommands) || !allowedCommands.includes(command.split(' ')[0])) {
|
|
1140
|
+
throw new Error(`Command ${command} is not allowed`);
|
|
1141
|
+
}
|
|
1077
1142
|
}
|
|
1078
1143
|
const processName = options?.name;
|
|
1079
1144
|
if (!processName)
|
|
@@ -1083,7 +1148,7 @@ function createSpawn(spawnFunction: (...args: any) => child_process.ChildProcess
|
|
|
1083
1148
|
const requestedVersion = options?.version;
|
|
1084
1149
|
|
|
1085
1150
|
// Ensure PID directory exists
|
|
1086
|
-
const pidDir = join(
|
|
1151
|
+
const pidDir = join(env.getHdbBasePath(), 'pids');
|
|
1087
1152
|
mkdirSync(pidDir, { recursive: true });
|
|
1088
1153
|
|
|
1089
1154
|
const pidFilePath = join(pidDir, `${processName}.pid`);
|