harper 5.1.20 → 5.2.0-alpha.5
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/operations.ts +13 -16
- package/components/Application.ts +188 -7
- package/components/ApplicationScope.ts +3 -0
- package/components/Scope.ts +12 -0
- package/components/anthropic/index.ts +9 -2
- package/components/bedrock/index.ts +25 -2
- package/components/componentLoader.ts +56 -7
- package/components/componentSecrets.ts +451 -0
- package/components/deploymentRecorder.ts +7 -1
- package/components/mcp/adapters/fastify.ts +3 -0
- package/components/mcp/adapters/harperHttp.ts +3 -0
- package/components/mcp/audit.ts +21 -6
- package/components/mcp/customResourceRegistry.ts +17 -38
- package/components/mcp/listChanged.ts +37 -20
- package/components/mcp/quota.ts +145 -0
- package/components/mcp/rateLimit.ts +152 -14
- package/components/mcp/resources.ts +2 -4
- package/components/mcp/toolRegistry.ts +73 -4
- package/components/mcp/tools/application.ts +77 -8
- package/components/mcp/tools/operations.ts +106 -36
- package/components/mcp/tools/schemas/operationDescriptions.ts +4 -4
- package/components/mcp/tools/schemas/operations.ts +5 -0
- package/components/mcp/transport.ts +55 -4
- package/components/ollama/index.ts +6 -2
- package/components/openai/index.ts +9 -2
- package/components/operations.js +204 -10
- package/components/operationsValidation.js +173 -0
- package/components/secretOperations.ts +498 -0
- package/config/configUtils.ts +25 -1
- package/config-app.schema.json +81 -0
- package/config-root.schema.json +8 -1
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +4 -3
- package/dataLayer/readAuditLog.ts +14 -0
- package/dataLayer/schemaDescribe.ts +1 -0
- package/dist/agent/operations.d.ts +7 -4
- package/dist/agent/operations.js +13 -15
- package/dist/agent/operations.js.map +1 -1
- package/dist/components/Application.d.ts +25 -2
- package/dist/components/Application.js +166 -7
- package/dist/components/Application.js.map +1 -1
- package/dist/components/ApplicationScope.d.ts +2 -0
- package/dist/components/ApplicationScope.js +3 -0
- package/dist/components/ApplicationScope.js.map +1 -1
- package/dist/components/Scope.d.ts +8 -0
- package/dist/components/Scope.js +11 -0
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/anthropic/index.d.ts +4 -1
- package/dist/components/anthropic/index.js +4 -2
- package/dist/components/anthropic/index.js.map +1 -1
- package/dist/components/bedrock/index.d.ts +4 -1
- package/dist/components/bedrock/index.js +22 -2
- package/dist/components/bedrock/index.js.map +1 -1
- package/dist/components/componentLoader.d.ts +2 -0
- package/dist/components/componentLoader.js +52 -10
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/componentSecrets.d.ts +63 -0
- package/dist/components/componentSecrets.js +405 -0
- package/dist/components/componentSecrets.js.map +1 -0
- package/dist/components/deploymentRecorder.d.ts +3 -0
- package/dist/components/deploymentRecorder.js +4 -3
- package/dist/components/deploymentRecorder.js.map +1 -1
- package/dist/components/mcp/adapters/fastify.d.ts +2 -0
- package/dist/components/mcp/adapters/fastify.js +1 -0
- package/dist/components/mcp/adapters/fastify.js.map +1 -1
- package/dist/components/mcp/adapters/harperHttp.d.ts +2 -0
- package/dist/components/mcp/adapters/harperHttp.js +1 -0
- package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
- package/dist/components/mcp/audit.d.ts +2 -2
- package/dist/components/mcp/audit.js +20 -5
- package/dist/components/mcp/audit.js.map +1 -1
- package/dist/components/mcp/customResourceRegistry.d.ts +5 -12
- package/dist/components/mcp/customResourceRegistry.js +15 -30
- package/dist/components/mcp/customResourceRegistry.js.map +1 -1
- package/dist/components/mcp/listChanged.d.ts +7 -2
- package/dist/components/mcp/listChanged.js +28 -0
- package/dist/components/mcp/listChanged.js.map +1 -1
- package/dist/components/mcp/quota.d.ts +31 -0
- package/dist/components/mcp/quota.js +155 -0
- package/dist/components/mcp/quota.js.map +1 -0
- package/dist/components/mcp/rateLimit.d.ts +19 -3
- package/dist/components/mcp/rateLimit.js +129 -13
- package/dist/components/mcp/rateLimit.js.map +1 -1
- package/dist/components/mcp/resources.js.map +1 -1
- package/dist/components/mcp/toolRegistry.d.ts +39 -1
- package/dist/components/mcp/toolRegistry.js +60 -5
- package/dist/components/mcp/toolRegistry.js.map +1 -1
- package/dist/components/mcp/tools/application.d.ts +8 -1
- package/dist/components/mcp/tools/application.js +65 -5
- package/dist/components/mcp/tools/application.js.map +1 -1
- package/dist/components/mcp/tools/operations.d.ts +15 -3
- package/dist/components/mcp/tools/operations.js +99 -38
- package/dist/components/mcp/tools/operations.js.map +1 -1
- package/dist/components/mcp/tools/schemas/operationDescriptions.js +4 -4
- package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
- package/dist/components/mcp/tools/schemas/operations.js +4 -0
- package/dist/components/mcp/tools/schemas/operations.js.map +1 -1
- package/dist/components/mcp/transport.d.ts +6 -0
- package/dist/components/mcp/transport.js +47 -3
- package/dist/components/mcp/transport.js.map +1 -1
- package/dist/components/ollama/index.d.ts +4 -1
- package/dist/components/ollama/index.js +4 -2
- package/dist/components/ollama/index.js.map +1 -1
- package/dist/components/openai/index.d.ts +4 -1
- package/dist/components/openai/index.js +4 -2
- package/dist/components/openai/index.js.map +1 -1
- package/dist/components/operations.d.ts +39 -0
- package/dist/components/operations.js +194 -2
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.d.ts +38 -0
- package/dist/components/operationsValidation.js +155 -0
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/components/secretOperations.d.ts +113 -0
- package/dist/components/secretOperations.js +475 -0
- package/dist/components/secretOperations.js.map +1 -0
- package/dist/config/configUtils.d.ts +4 -1
- package/dist/config/configUtils.js +18 -1
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +4 -3
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
- package/dist/dataLayer/readAuditLog.js +11 -0
- package/dist/dataLayer/readAuditLog.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +2 -0
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/globals.d.ts +1 -1
- package/dist/globals.js +1 -0
- package/dist/globals.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/json/systemSchema.json +38 -0
- package/dist/resources/DatabaseTransaction.d.ts +31 -3
- package/dist/resources/DatabaseTransaction.js +190 -29
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/LMDBTransaction.d.ts +1 -1
- package/dist/resources/LMDBTransaction.js +43 -5
- package/dist/resources/LMDBTransaction.js.map +1 -1
- package/dist/resources/PrimaryRocksDatabase.d.ts +51 -0
- package/dist/resources/PrimaryRocksDatabase.js +194 -0
- package/dist/resources/PrimaryRocksDatabase.js.map +1 -0
- package/dist/resources/RecordEncoder.d.ts +1 -0
- package/dist/resources/RecordEncoder.js +81 -75
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/RequestTarget.d.ts +19 -0
- package/dist/resources/RequestTarget.js.map +1 -1
- package/dist/resources/Resource.d.ts +0 -1
- package/dist/resources/Resource.js +103 -16
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +6 -2
- package/dist/resources/ResourceInterface.js.map +1 -1
- package/dist/resources/Resources.js.map +1 -1
- package/dist/resources/Table.d.ts +6 -4
- package/dist/resources/Table.js +247 -24
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/read.js +25 -28
- package/dist/resources/analytics/read.js.map +1 -1
- package/dist/resources/blob.js +165 -22
- package/dist/resources/blob.js.map +1 -1
- package/dist/resources/crdt.d.ts +2 -0
- package/dist/resources/crdt.js +45 -36
- package/dist/resources/crdt.js.map +1 -1
- package/dist/resources/databases.d.ts +1 -0
- package/dist/resources/databases.js +134 -7
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/graphql.js +8 -0
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +35 -5
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +239 -14
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/resources/jsResource.js +6 -0
- package/dist/resources/jsResource.js.map +1 -1
- package/dist/resources/loadEnv.js +30 -3
- package/dist/resources/loadEnv.js.map +1 -1
- package/dist/resources/login.js +2 -2
- package/dist/resources/login.js.map +1 -1
- package/dist/resources/models/Models.js +14 -3
- package/dist/resources/models/Models.js.map +1 -1
- package/dist/resources/models/embedHook.js +10 -2
- package/dist/resources/models/embedHook.js.map +1 -1
- package/dist/resources/models/openaiStream.d.ts +56 -0
- package/dist/resources/models/openaiStream.js +94 -0
- package/dist/resources/models/openaiStream.js.map +1 -0
- package/dist/resources/replayLogs.js +4 -3
- package/dist/resources/replayLogs.js.map +1 -1
- package/dist/resources/search.d.ts +1 -1
- package/dist/resources/search.js +104 -11
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/secretDecryptor.d.ts +54 -0
- package/dist/resources/secretDecryptor.js +131 -0
- package/dist/resources/secretDecryptor.js.map +1 -0
- package/dist/resources/tracked.js +15 -5
- package/dist/resources/tracked.js.map +1 -1
- package/dist/security/auth.js +71 -8
- package/dist/security/auth.js.map +1 -1
- package/dist/security/jsLoader.js +11 -0
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/tokenAuthentication.d.ts +9 -1
- package/dist/security/tokenAuthentication.js +31 -1
- package/dist/security/tokenAuthentication.js.map +1 -1
- package/dist/server/DurableSubscriptionsSession.d.ts +1 -1
- package/dist/server/DurableSubscriptionsSession.js +8 -4
- package/dist/server/DurableSubscriptionsSession.js.map +1 -1
- package/dist/server/REST.js +28 -9
- package/dist/server/REST.js.map +1 -1
- package/dist/server/fastifyRoutes.js +11 -1
- package/dist/server/fastifyRoutes.js.map +1 -1
- package/dist/server/graphqlQuerying.js +4 -3
- package/dist/server/graphqlQuerying.js.map +1 -1
- package/dist/server/http.d.ts +40 -2
- package/dist/server/http.js +560 -77
- package/dist/server/http.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +64 -0
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/server/liveSubscriptionAuth.d.ts +12 -0
- package/dist/server/liveSubscriptionAuth.js +140 -0
- package/dist/server/liveSubscriptionAuth.js.map +1 -0
- package/dist/server/loadRootComponents.js +2 -1
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/middlewareChain.d.ts +44 -1
- package/dist/server/middlewareChain.js +86 -10
- package/dist/server/middlewareChain.js.map +1 -1
- package/dist/server/mqtt.js +2 -1
- package/dist/server/mqtt.js.map +1 -1
- package/dist/server/operationsServer.js +1 -1
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/server/serverHelpers/Headers.d.ts +9 -0
- package/dist/server/serverHelpers/Headers.js +22 -0
- package/dist/server/serverHelpers/Headers.js.map +1 -1
- package/dist/server/serverHelpers/JSONStream.js +3 -3
- package/dist/server/serverHelpers/JSONStream.js.map +1 -1
- package/dist/server/serverHelpers/Request.d.ts +52 -1
- package/dist/server/serverHelpers/Request.js +122 -1
- package/dist/server/serverHelpers/Request.js.map +1 -1
- package/dist/server/serverHelpers/contentTypes.js +3 -8
- package/dist/server/serverHelpers/contentTypes.js.map +1 -1
- package/dist/server/serverHelpers/progressEmitter.d.ts +19 -0
- package/dist/server/serverHelpers/progressEmitter.js +52 -4
- package/dist/server/serverHelpers/progressEmitter.js.map +1 -1
- package/dist/server/serverHelpers/registeredOperations.d.ts +40 -0
- package/dist/server/serverHelpers/registeredOperations.js +286 -0
- package/dist/server/serverHelpers/registeredOperations.js.map +1 -0
- package/dist/server/serverHelpers/serverHandlers.js +11 -5
- package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.d.ts +1 -0
- package/dist/server/serverHelpers/serverUtilities.js +67 -5
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/uwsServer.d.ts +80 -0
- package/dist/server/serverHelpers/uwsServer.js +433 -0
- package/dist/server/serverHelpers/uwsServer.js.map +1 -0
- package/dist/server/static.d.ts +0 -15
- package/dist/server/static.js +161 -2
- package/dist/server/static.js.map +1 -1
- package/dist/server/status/index.d.ts +4 -1
- package/dist/server/status/index.js +64 -4
- package/dist/server/status/index.js.map +1 -1
- package/dist/server/threads/manageThreads.d.ts +10 -0
- package/dist/server/threads/manageThreads.js +107 -4
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.js +5 -1
- package/dist/server/threads/socketRouter.js.map +1 -1
- package/dist/server/threads/threadServer.js +92 -14
- package/dist/server/threads/threadServer.js.map +1 -1
- package/dist/upgrade/directives/5-2-0.d.ts +7 -0
- package/dist/upgrade/directives/5-2-0.js +108 -0
- package/dist/upgrade/directives/5-2-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/common_utils.js +5 -0
- package/dist/utility/common_utils.js.map +1 -1
- package/dist/utility/envFile.d.ts +41 -0
- package/dist/utility/envFile.js +221 -0
- package/dist/utility/envFile.js.map +1 -0
- package/dist/utility/globalSchema.d.ts +9 -0
- package/dist/utility/hdbTerms.d.ts +25 -0
- package/dist/utility/hdbTerms.js +31 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/logging/harper_logger.d.ts +21 -0
- package/dist/utility/logging/harper_logger.js +160 -8
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/dist/utility/logging/logRotator.js +29 -17
- package/dist/utility/logging/logRotator.js.map +1 -1
- package/dist/utility/logging/readLog.d.ts +1 -1
- package/dist/utility/logging/readLog.js +305 -2
- package/dist/utility/logging/readLog.js.map +1 -1
- package/dist/utility/operationPermissions.d.ts +18 -0
- package/dist/utility/operationPermissions.js +35 -1
- package/dist/utility/operationPermissions.js.map +1 -1
- package/dist/utility/operation_authorization.d.ts +17 -0
- package/dist/utility/operation_authorization.js +38 -0
- package/dist/utility/operation_authorization.js.map +1 -1
- package/dist/utility/secretEnvelope.d.ts +30 -0
- package/dist/utility/secretEnvelope.js +94 -0
- package/dist/utility/secretEnvelope.js.map +1 -0
- package/dist/utility/signalling.d.ts +7 -0
- package/dist/utility/signalling.js +16 -0
- package/dist/utility/signalling.js.map +1 -1
- package/dist/validation/configValidator.js +70 -24
- package/dist/validation/configValidator.js.map +1 -1
- package/index.ts +4 -0
- package/json/systemSchema.json +38 -0
- package/npm-shrinkwrap.json +15066 -9347
- package/package.json +13 -8
- package/resources/DESIGN.md +15 -12
- package/resources/DatabaseTransaction.ts +206 -37
- package/resources/LMDBTransaction.ts +43 -9
- package/resources/PrimaryRocksDatabase.ts +201 -0
- package/resources/RecordEncoder.ts +81 -69
- package/resources/RequestTarget.ts +21 -0
- package/resources/Resource.ts +109 -25
- package/resources/ResourceInterface.ts +6 -2
- package/resources/Resources.ts +1 -3
- package/resources/Table.ts +238 -29
- package/resources/analytics/read.ts +25 -30
- package/resources/blob.ts +159 -23
- package/resources/crdt.ts +37 -31
- package/resources/databases.ts +143 -6
- package/resources/graphql.ts +8 -0
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +251 -17
- package/resources/jsResource.ts +6 -0
- package/resources/loadEnv.ts +34 -3
- package/resources/login.ts +2 -2
- package/resources/models/Models.ts +19 -3
- package/resources/models/embedHook.ts +13 -2
- package/resources/models/openaiStream.ts +133 -0
- package/resources/replayLogs.ts +4 -3
- package/resources/search.ts +113 -11
- package/resources/secretDecryptor.ts +159 -0
- package/resources/tracked.ts +24 -17
- package/security/auth.ts +70 -10
- package/security/jsLoader.ts +12 -0
- package/security/tokenAuthentication.ts +42 -1
- package/server/DESIGN.md +10 -0
- package/server/DurableSubscriptionsSession.ts +8 -4
- package/server/REST.ts +26 -9
- package/server/fastifyRoutes.ts +10 -1
- package/server/graphqlQuerying.ts +4 -3
- package/server/http.ts +563 -77
- package/server/itc/serverHandlers.js +70 -0
- package/server/liveSubscriptionAuth.ts +152 -0
- package/server/loadRootComponents.js +2 -1
- package/server/middlewareChain.ts +107 -17
- package/server/mqtt.ts +2 -1
- package/server/operationsServer.ts +2 -2
- package/server/serverHelpers/Headers.ts +24 -0
- package/server/serverHelpers/JSONStream.ts +3 -3
- package/server/serverHelpers/Request.ts +127 -0
- package/server/serverHelpers/contentTypes.ts +3 -8
- package/server/serverHelpers/progressEmitter.ts +55 -5
- package/server/serverHelpers/registeredOperations.ts +259 -0
- package/server/serverHelpers/serverHandlers.js +11 -5
- package/server/serverHelpers/serverUtilities.ts +88 -5
- package/server/serverHelpers/uwsServer.ts +488 -0
- package/server/static.ts +180 -2
- package/server/status/index.ts +72 -4
- package/server/threads/manageThreads.js +102 -4
- package/server/threads/socketRouter.ts +5 -1
- package/server/threads/threadServer.js +93 -10
- package/studio/web/assets/{Chat-SdD1EZca.js → Chat-Cv_2paZE.js} +2 -2
- package/studio/web/assets/{Chat-SdD1EZca.js.map → Chat-Cv_2paZE.js.map} +1 -1
- package/studio/web/assets/{FloatingChat-GMq6tHK9.js → FloatingChat-CPyPIcVR.js} +4 -4
- package/studio/web/assets/{FloatingChat-GMq6tHK9.js.map → FloatingChat-CPyPIcVR.js.map} +1 -1
- package/studio/web/assets/{applications-B5hhv7uA.js → applications-C0jT2vdZ.js} +2 -2
- package/studio/web/assets/{applications-B5hhv7uA.js.map → applications-C0jT2vdZ.js.map} +1 -1
- package/studio/web/assets/{index-VFcpNWgq.js → index-D_GKOkhn.js} +6 -6
- package/studio/web/assets/index-D_GKOkhn.js.map +1 -0
- package/studio/web/assets/{index.lazy-DgcJojIA.js → index.lazy-CAmCIA65.js} +4 -4
- package/studio/web/assets/{index.lazy-DgcJojIA.js.map → index.lazy-CAmCIA65.js.map} +1 -1
- package/studio/web/assets/{profile-BqN-8vzm.js → profile-CaF-4aZe.js} +2 -2
- package/studio/web/assets/{profile-BqN-8vzm.js.map → profile-CaF-4aZe.js.map} +1 -1
- package/studio/web/assets/{setComponentFile-CHFvFq9u.js → setComponentFile-DLW1DHCt.js} +2 -2
- package/studio/web/assets/{setComponentFile-CHFvFq9u.js.map → setComponentFile-DLW1DHCt.js.map} +1 -1
- package/studio/web/assets/{setup-CQ3vWJSr.js → setup-TGCErIhq.js} +2 -2
- package/studio/web/assets/{setup-CQ3vWJSr.js.map → setup-TGCErIhq.js.map} +1 -1
- package/studio/web/assets/{status-BsW5fjuh.js → status-DG0Maoao.js} +2 -2
- package/studio/web/assets/{status-BsW5fjuh.js.map → status-DG0Maoao.js.map} +1 -1
- package/studio/web/assets/{swagger-ui-react-DITdeB9-.js → swagger-ui-react-8T4SgQ1m.js} +2 -2
- package/studio/web/assets/{swagger-ui-react-DITdeB9-.js.map → swagger-ui-react-8T4SgQ1m.js.map} +1 -1
- package/studio/web/assets/{tsMode-Dyph-OUs.js → tsMode-DJ6Sl24Q.js} +2 -2
- package/studio/web/assets/{tsMode-Dyph-OUs.js.map → tsMode-DJ6Sl24Q.js.map} +1 -1
- package/studio/web/assets/{useEntityRestURL-D0QTUqex.js → useEntityRestURL-JO2mfWTQ.js} +2 -2
- package/studio/web/assets/{useEntityRestURL-D0QTUqex.js.map → useEntityRestURL-JO2mfWTQ.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/upgrade/directives/5-2-0.ts +82 -0
- package/upgrade/directives/directivesController.ts +2 -1
- package/utility/common_utils.ts +5 -0
- package/utility/envFile.ts +218 -0
- package/utility/hdbTerms.ts +31 -0
- package/utility/logging/harper_logger.ts +156 -8
- package/utility/logging/logRotator.ts +24 -14
- package/utility/logging/readLog.ts +323 -2
- package/utility/operationPermissions.ts +35 -1
- package/utility/operation_authorization.ts +74 -1
- package/utility/secretEnvelope.ts +113 -0
- package/utility/signalling.ts +15 -0
- package/validation/configValidator.ts +78 -25
- package/studio/web/assets/index-VFcpNWgq.js.map +0 -1
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure secret-envelope cryptography — intentionally free of Harper imports so it is unit-testable
|
|
3
|
+
* on its own and safe to publish. Hybrid scheme (see docs/env-secret-encryption.md): AES-256-GCM
|
|
4
|
+
* encrypts the value, RSA-OAEP(SHA-256) wraps the AES key. Functions operate on the base64url
|
|
5
|
+
* envelope BODY (the bytes after the `enc:v1:` marker); marker handling lives with the callers
|
|
6
|
+
* (utility/envFile.ts exports the `ENV_ENCRYPTED_PREFIX` marker).
|
|
7
|
+
*
|
|
8
|
+
* Ported from harper-pro security/envSecretCrypto.ts (Dawson Toth) so core and pro share one wire
|
|
9
|
+
* format for `.env` secrets and the hdb_secret store.
|
|
10
|
+
*/
|
|
11
|
+
import {
|
|
12
|
+
publicEncrypt,
|
|
13
|
+
privateDecrypt,
|
|
14
|
+
createCipheriv,
|
|
15
|
+
createDecipheriv,
|
|
16
|
+
createPublicKey,
|
|
17
|
+
createHash,
|
|
18
|
+
randomBytes,
|
|
19
|
+
constants,
|
|
20
|
+
} from 'node:crypto';
|
|
21
|
+
|
|
22
|
+
export interface EnvelopeFields {
|
|
23
|
+
kid?: string;
|
|
24
|
+
k: string;
|
|
25
|
+
iv: string;
|
|
26
|
+
ct: string;
|
|
27
|
+
tag: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** SHA-256 (hex) of the DER SPKI public key — a stable key id used as the envelope `kid`. */
|
|
31
|
+
export function fingerprintOf(publicKeyPem: string): string {
|
|
32
|
+
const der = createPublicKey(publicKeyPem).export({ type: 'spki', format: 'der' });
|
|
33
|
+
return createHash('sha256').update(der).digest('hex');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Base64 with OPTIONAL padding (the field encoding inside the envelope JSON). Buffer.from(s,
|
|
37
|
+
// 'base64') silently ignores invalid characters, so decodability has to be checked by pattern —
|
|
38
|
+
// but it decodes unpadded input fine, and browser/WebCrypto clients commonly emit unpadded
|
|
39
|
+
// base64, so padding is accepted rather than required. Charset stays strict; a trailing group of
|
|
40
|
+
// one character (never valid base64) is still rejected.
|
|
41
|
+
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}(?:==)?|[A-Za-z0-9+/]{3}=?)?$/;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Parse and shape-validate a base64url envelope body without decrypting it. Throws on a
|
|
45
|
+
* malformed/incomplete envelope: non-JSON, wrong type, missing/non-base64 `k`/`iv`/`ct`/`tag`
|
|
46
|
+
* (`ct` may be empty — the empty plaintext), or a non-string `kid`. This is how the server derives
|
|
47
|
+
* `kid` from a submitted envelope (the `kid` inside the sealed body is the only one trusted —
|
|
48
|
+
* never a separate client field) and structurally vets envelopes on ingest without ever
|
|
49
|
+
* decrypting them server-side.
|
|
50
|
+
*/
|
|
51
|
+
export function parseEnvelopeFields(body: string): EnvelopeFields {
|
|
52
|
+
let env: EnvelopeFields;
|
|
53
|
+
try {
|
|
54
|
+
env = JSON.parse(Buffer.from(body, 'base64url').toString('utf8'));
|
|
55
|
+
} catch {
|
|
56
|
+
throw new Error('malformed secret envelope');
|
|
57
|
+
}
|
|
58
|
+
if (!env || typeof env !== 'object' || Array.isArray(env) || (env.kid !== undefined && typeof env.kid !== 'string')) {
|
|
59
|
+
throw new Error('malformed secret envelope');
|
|
60
|
+
}
|
|
61
|
+
for (const field of ['k', 'iv', 'ct', 'tag'] as const) {
|
|
62
|
+
const fieldValue = env[field];
|
|
63
|
+
if (
|
|
64
|
+
typeof fieldValue !== 'string' ||
|
|
65
|
+
(fieldValue.length === 0 && field !== 'ct') ||
|
|
66
|
+
!BASE64_REGEX.test(fieldValue)
|
|
67
|
+
) {
|
|
68
|
+
throw new Error('malformed secret envelope');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return env;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Reference client-side encryption: returns the base64url envelope body for `enc:v1:<body>`. The
|
|
76
|
+
* server only encrypts on ingest (set_secret with a plaintext `value`); this is the single source
|
|
77
|
+
* of truth for the wire format and what the tests and the documented client example exercise.
|
|
78
|
+
*/
|
|
79
|
+
export function encryptEnvelope(plaintext: string, publicKeyPem: string, kid: string): string {
|
|
80
|
+
const aesKey = randomBytes(32);
|
|
81
|
+
const iv = randomBytes(12);
|
|
82
|
+
const cipher = createCipheriv('aes-256-gcm', aesKey, iv);
|
|
83
|
+
const ct = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
84
|
+
const tag = cipher.getAuthTag();
|
|
85
|
+
const k = publicEncrypt({ key: publicKeyPem, padding: constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' }, aesKey);
|
|
86
|
+
const envelope: EnvelopeFields = {
|
|
87
|
+
kid,
|
|
88
|
+
k: k.toString('base64'),
|
|
89
|
+
iv: iv.toString('base64'),
|
|
90
|
+
ct: ct.toString('base64'),
|
|
91
|
+
tag: tag.toString('base64'),
|
|
92
|
+
};
|
|
93
|
+
return Buffer.from(JSON.stringify(envelope)).toString('base64url');
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Decrypt a base64url envelope body. These are the security guarantees of the feature and throw on:
|
|
98
|
+
* a malformed/incomplete envelope, a `kid` that doesn't match this node's key, or a failed GCM
|
|
99
|
+
* authentication tag (any tampering with `ct`/`tag` makes `decipher.final()` throw).
|
|
100
|
+
*/
|
|
101
|
+
export function decryptEnvelope(body: string, privateKeyPem: string, keyFingerprint: string): string {
|
|
102
|
+
const env = parseEnvelopeFields(body);
|
|
103
|
+
if (env.kid && env.kid !== keyFingerprint) {
|
|
104
|
+
throw new Error(`no secrets key for kid ${env.kid}`);
|
|
105
|
+
}
|
|
106
|
+
const aesKey = privateDecrypt(
|
|
107
|
+
{ key: privateKeyPem, padding: constants.RSA_PKCS1_OAEP_PADDING, oaepHash: 'sha256' },
|
|
108
|
+
Buffer.from(env.k, 'base64')
|
|
109
|
+
);
|
|
110
|
+
const decipher = createDecipheriv('aes-256-gcm', aesKey, Buffer.from(env.iv, 'base64'));
|
|
111
|
+
decipher.setAuthTag(Buffer.from(env.tag, 'base64'));
|
|
112
|
+
return Buffer.concat([decipher.update(Buffer.from(env.ct, 'base64')), decipher.final()]).toString('utf8');
|
|
113
|
+
}
|
package/utility/signalling.ts
CHANGED
|
@@ -23,6 +23,21 @@ export async function signalSchemaChange(message: any) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Notify local listeners that JS resources have just been registered (resources.js loaded). This is
|
|
28
|
+
* deliberately local-only — no ITC broadcast — because every worker registers its own JS resources,
|
|
29
|
+
* so the dependent rebuild (MCP application tools) belongs in the worker where the registration
|
|
30
|
+
* happened. See `resourceHandler` in server/itc/serverHandlers.js and issue #1448.
|
|
31
|
+
*/
|
|
32
|
+
export function signalResourcesRegistered() {
|
|
33
|
+
try {
|
|
34
|
+
serverItcHandlers = serverItcHandlers || require('../server/itc/serverHandlers.js');
|
|
35
|
+
serverItcHandlers.resourceHandler();
|
|
36
|
+
} catch (err) {
|
|
37
|
+
hdbLogger.error(err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
26
41
|
export async function signalUserChange(message: any) {
|
|
27
42
|
try {
|
|
28
43
|
hdbLogger.trace('signalUserChange called with message:', message);
|
|
@@ -14,36 +14,54 @@ import * as validator from './validationWrapper.ts';
|
|
|
14
14
|
const DEFAULT_LOG_FOLDER = 'log';
|
|
15
15
|
const DEFAULT_COMPONENTS_FOLDER = 'components';
|
|
16
16
|
const INVALID_SIZE_UNIT_MSG = 'Invalid logging.rotation.maxSize unit. Available units are G, M or K';
|
|
17
|
-
const INVALID_INTERVAL_UNIT_MSG =
|
|
17
|
+
const INVALID_INTERVAL_UNIT_MSG =
|
|
18
|
+
'Invalid logging.rotation.interval unit. Available units are D (days), H (hours), M (months) or m (minutes)';
|
|
18
19
|
const INVALID_MAX_SIZE_VALUE_MSG =
|
|
19
20
|
"Invalid logging.rotation.maxSize value. Value should be a number followed by unit e.g. '10M'";
|
|
20
21
|
const INVALID_INTERVAL_VALUE_MSG =
|
|
21
22
|
"Invalid logging.rotation.interval value. Value should be a number followed by unit e.g. '10D'";
|
|
23
|
+
const INVALID_RETENTION_UNIT_MSG =
|
|
24
|
+
'Invalid logging.rotation.retention unit. Available units are D (days), H (hours), M (months) or m (minutes)';
|
|
25
|
+
const INVALID_RETENTION_VALUE_MSG =
|
|
26
|
+
"Invalid logging.rotation.retention value. Value should be a number followed by unit e.g. '30D'";
|
|
27
|
+
// Units accepted for rotation durations, matching convertToMS: note capital M (months) vs lowercase m (minutes).
|
|
28
|
+
const VALID_ROTATION_DURATION_UNITS = ['D', 'd', 'H', 'h', 'M', 'm'];
|
|
22
29
|
const UNDEFINED_OPS_API = 'rootPath config parameter is undefined';
|
|
23
30
|
|
|
24
|
-
// Directory-path validation. The previous `([...]+)+$` nested quantifier
|
|
25
|
-
// backtracked catastrophically (ReDoS), hanging the CLI at 100% CPU on any
|
|
26
|
-
// value with a character outside its allow-list after a run of valid ones — a
|
|
27
|
-
// dotted rootPath such as `/Users/john.doe/hdb` is enough (#1779). An allow-list
|
|
28
|
-
// is also the wrong model for file paths: they legitimately contain spaces, `~`,
|
|
29
|
-
// parens (`C:\\Program Files (x86)`), apostrophes, and any Unicode
|
|
30
|
-
// (`/Users/café/hdb`), so any fixed class rejects real, previously-valid
|
|
31
|
-
// configs. These paths only ever reach `fs`/`path` (never a shell), so the
|
|
32
|
-
// character check is just a friendly "reject obvious garbage" gate — the real
|
|
33
|
-
// validation is the existence check in `validatePath`. So this is a denylist:
|
|
34
|
-
// reject only control characters — C0 (`\x00-\x1f`), DEL, and C1 (`\x80-\x9f`,
|
|
35
|
-
// which includes NEL U+0085) — plus the Unicode line/paragraph separators
|
|
36
|
-
// U+2028/U+2029, since paths get logged and any of these could forge log lines,
|
|
37
|
-
// via a single anchored quantifier — linear time, no backtracking. The
|
|
38
|
-
// `(?!\s*$)` guard rejects empty/whitespace-only values, which on Windows
|
|
39
|
-
// silently strip to a valid-but-wrong directory and would pass the existence
|
|
40
|
-
// check; `.`/`..` are allowed since they resolve honestly to real directories.
|
|
41
|
-
// eslint-disable-next-line no-control-regex -- deliberate: reject control characters
|
|
42
|
-
const DIRECTORY_PATH_PATTERN = /^(?!\s*$)[^\x00-\x1f\x7f\x80-\x9f\u2028\u2029]+$/;
|
|
43
|
-
|
|
44
31
|
const portConstraints = Joi.alternatives([number.min(0), string])
|
|
45
32
|
.optional()
|
|
46
33
|
.empty(null);
|
|
34
|
+
// Controlled-flow ("directional") replication fields. A route's `replicates` is either a boolean
|
|
35
|
+
// (full replication on/off) or an object describing per-direction flow; `sends`/`receives` and
|
|
36
|
+
// `sendsTo`/`receivesFrom` are also accepted as top-level route keys (iterateRoutes normalizes both
|
|
37
|
+
// forms). Entries in sendsTo/receivesFrom are a peer name (string) or an object scoping the edge by
|
|
38
|
+
// target/source + database, with an optional per-table excludeTables list. harper-pro#498 — these
|
|
39
|
+
// were previously unvalidated (allowUnknown), so typos/wrong types passed silently.
|
|
40
|
+
const routeEntryConstraints = Joi.alternatives([
|
|
41
|
+
string,
|
|
42
|
+
{
|
|
43
|
+
target: string,
|
|
44
|
+
source: string,
|
|
45
|
+
database: string,
|
|
46
|
+
excludeTables: array.items(string),
|
|
47
|
+
},
|
|
48
|
+
]);
|
|
49
|
+
const replicatesConstraints = Joi.alternatives([
|
|
50
|
+
boolean,
|
|
51
|
+
{
|
|
52
|
+
sends: boolean,
|
|
53
|
+
sendsTo: array.items(routeEntryConstraints),
|
|
54
|
+
receives: boolean,
|
|
55
|
+
receivesFrom: array.items(routeEntryConstraints),
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
const directionalRouteFields = {
|
|
59
|
+
replicates: replicatesConstraints,
|
|
60
|
+
sends: boolean,
|
|
61
|
+
receives: boolean,
|
|
62
|
+
sendsTo: array.items(routeEntryConstraints),
|
|
63
|
+
receivesFrom: array.items(routeEntryConstraints),
|
|
64
|
+
};
|
|
47
65
|
export const routeConstraints = Joi.alternatives([
|
|
48
66
|
array
|
|
49
67
|
.items(
|
|
@@ -51,10 +69,12 @@ export const routeConstraints = Joi.alternatives([
|
|
|
51
69
|
{
|
|
52
70
|
host: string.required(),
|
|
53
71
|
port: portConstraints,
|
|
72
|
+
...directionalRouteFields,
|
|
54
73
|
},
|
|
55
74
|
{
|
|
56
75
|
hostname: string.required(),
|
|
57
76
|
port: portConstraints,
|
|
77
|
+
...directionalRouteFields,
|
|
58
78
|
}
|
|
59
79
|
)
|
|
60
80
|
.empty(null),
|
|
@@ -73,7 +93,10 @@ export function configValidator(configJson, skipFsValidation = false) {
|
|
|
73
93
|
|
|
74
94
|
const enabledConstraints = boolean.optional();
|
|
75
95
|
const threadsConstraints = number.min(0).max(1000).empty(null).default(setDefaultThreads);
|
|
76
|
-
const rootConstraints = string
|
|
96
|
+
const rootConstraints = string
|
|
97
|
+
.pattern(/^[\\/]$|([\\/a-zA-Z_0-9:-]+)+$/, 'directory path')
|
|
98
|
+
.empty(null)
|
|
99
|
+
.default(setDefaultRoot);
|
|
77
100
|
const pemFileConstraints = string.optional().empty(null);
|
|
78
101
|
|
|
79
102
|
const storagePathConstraints = Joi.custom(validatePath).empty(null).default(setDefaultRoot);
|
|
@@ -235,6 +258,7 @@ export function configValidator(configJson, skipFsValidation = false) {
|
|
|
235
258
|
compress: boolean.optional(),
|
|
236
259
|
interval: string.custom(validateRotationInterval).optional().empty(null),
|
|
237
260
|
maxSize: string.custom(validateRotationMaxSize).optional().empty(null),
|
|
261
|
+
retention: string.custom(validateRotationRetention).optional().empty(null),
|
|
238
262
|
path: string.optional().empty(null).default(setDefaultRoot),
|
|
239
263
|
}).required(),
|
|
240
264
|
root: rootConstraints,
|
|
@@ -254,7 +278,7 @@ export function configValidator(configJson, skipFsValidation = false) {
|
|
|
254
278
|
}).optional(),
|
|
255
279
|
tls: Joi.alternatives([Joi.array().items(tlsConstraints), tlsConstraints]),
|
|
256
280
|
}).required(),
|
|
257
|
-
rootPath: string.pattern(
|
|
281
|
+
rootPath: string.pattern(/^[\\/]$|([\\/a-zA-Z_0-9:-]+)+$/, 'directory path').required(),
|
|
258
282
|
mqtt: Joi.object({
|
|
259
283
|
network: Joi.object({
|
|
260
284
|
port: portConstraints,
|
|
@@ -353,7 +377,7 @@ function doesPathExist(pathToCheck) {
|
|
|
353
377
|
}
|
|
354
378
|
|
|
355
379
|
function validatePath(value, helpers) {
|
|
356
|
-
Joi.assert(value, string.pattern(
|
|
380
|
+
Joi.assert(value, string.pattern(/^[\\/~]$|([\\/~a-zA-Z_0-9:-]+)+$/, 'directory path'));
|
|
357
381
|
|
|
358
382
|
let resolvedValue;
|
|
359
383
|
if (value.startsWith('~/')) {
|
|
@@ -385,7 +409,7 @@ function validateRotationMaxSize(value, helpers) {
|
|
|
385
409
|
|
|
386
410
|
function validateRotationInterval(value, helpers) {
|
|
387
411
|
const unit = value.slice(-1);
|
|
388
|
-
if (unit
|
|
412
|
+
if (!VALID_ROTATION_DURATION_UNITS.includes(unit)) {
|
|
389
413
|
return helpers.message(INVALID_INTERVAL_UNIT_MSG);
|
|
390
414
|
}
|
|
391
415
|
|
|
@@ -396,9 +420,38 @@ function validateRotationInterval(value, helpers) {
|
|
|
396
420
|
|
|
397
421
|
return value;
|
|
398
422
|
}
|
|
423
|
+
function validateRotationRetention(value, helpers) {
|
|
424
|
+
if (typeof value !== 'string' || !value.trim()) {
|
|
425
|
+
return helpers.message(INVALID_RETENTION_VALUE_MSG);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const unit = value.slice(-1);
|
|
429
|
+
if (!VALID_ROTATION_DURATION_UNITS.includes(unit)) {
|
|
430
|
+
return helpers.message(INVALID_RETENTION_UNIT_MSG);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
// parseFloat + strictly-positive check: convertToMS accepts fractional intervals, and a zero or
|
|
434
|
+
// negative retention makes every rotated log older than the (<=0) window, deleting them immediately.
|
|
435
|
+
const age = parseFloat(value.slice(0, -1));
|
|
436
|
+
if (isNaN(age) || age <= 0) {
|
|
437
|
+
return helpers.message(INVALID_RETENTION_VALUE_MSG);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return value;
|
|
441
|
+
}
|
|
399
442
|
|
|
400
443
|
function setDefaultThreads(parent, helpers) {
|
|
401
444
|
const configParam = helpers.state.path.join('.');
|
|
445
|
+
// Without SO_REUSEPORT (macOS is unreliable, Windows lacks it) worker threads cannot share the
|
|
446
|
+
// HTTP/socket ports — the main thread binds them all first and serves alone, so extra HTTP
|
|
447
|
+
// workers never receive direct TCP traffic. Default to a single worker there; an explicit
|
|
448
|
+
// threads.count still overrides.
|
|
449
|
+
if (process.platform === 'darwin' || process.platform === 'win32') {
|
|
450
|
+
hdbLogger.info(
|
|
451
|
+
`Defaulting ${configParam} to 1 on ${process.platform}: without SO_REUSEPORT, additional HTTP workers cannot share the server ports`
|
|
452
|
+
);
|
|
453
|
+
return 1;
|
|
454
|
+
}
|
|
402
455
|
let processors = os.cpus().length;
|
|
403
456
|
|
|
404
457
|
// default to one less than the number of logical CPU/processors so we can have good concurrency with the
|