@harperfast/harper 5.0.0-alpha.10 → 5.0.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/bin/BinObjects.js +17 -0
- package/bin/cliOperations.js +157 -0
- package/bin/copyDb.ts +280 -0
- package/bin/harper.js +156 -0
- package/bin/install.js +15 -0
- package/bin/lite.js +5 -0
- package/bin/restart.js +201 -0
- package/bin/run.js +409 -0
- package/bin/status.js +65 -0
- package/bin/stop.js +22 -0
- package/bin/upgrade.js +134 -0
- package/components/Application.ts +646 -0
- package/components/ApplicationScope.ts +49 -0
- package/components/Component.ts +53 -0
- package/components/ComponentV1.ts +342 -0
- package/components/DEFAULT_CONFIG.ts +18 -0
- package/components/EntryHandler.ts +227 -0
- package/components/Logger.ts +14 -0
- package/components/OptionsWatcher.ts +354 -0
- package/components/PluginModule.ts +6 -0
- package/components/Scope.ts +329 -0
- package/components/componentLoader.ts +529 -0
- package/components/deriveCommonPatternBase.ts +31 -0
- package/components/deriveGlobOptions.ts +44 -0
- package/components/deriveURLPath.ts +57 -0
- package/components/operations.js +658 -0
- package/components/operationsValidation.js +246 -0
- package/components/packageComponent.ts +39 -0
- package/components/requestRestart.ts +26 -0
- package/components/resolveBaseURLPath.ts +38 -0
- package/components/status/ComponentStatus.ts +110 -0
- package/components/status/ComponentStatusRegistry.ts +251 -0
- package/components/status/api.ts +153 -0
- package/components/status/crossThread.ts +405 -0
- package/components/status/errors.ts +152 -0
- package/components/status/index.ts +44 -0
- package/components/status/internal.ts +65 -0
- package/components/status/registry.ts +12 -0
- package/components/status/types.ts +96 -0
- package/config/RootConfigWatcher.ts +59 -0
- package/config/configHelpers.ts +11 -0
- package/config/configUtils.js +967 -0
- package/config/harperConfigEnvVars.ts +641 -0
- package/dataLayer/CreateAttributeObject.js +25 -0
- package/dataLayer/CreateTableObject.js +11 -0
- package/dataLayer/DataLayerObjects.js +43 -0
- package/dataLayer/DeleteBeforeObject.js +22 -0
- package/dataLayer/DeleteObject.js +25 -0
- package/dataLayer/DropAttributeObject.js +11 -0
- package/dataLayer/GetBackupObject.js +22 -0
- package/dataLayer/InsertObject.js +24 -0
- package/dataLayer/ReadAuditLogObject.js +24 -0
- package/dataLayer/SQLSearch.js +1335 -0
- package/dataLayer/SearchByConditionsObject.js +61 -0
- package/dataLayer/SearchByHashObject.js +21 -0
- package/dataLayer/SearchObject.js +45 -0
- package/dataLayer/SqlSearchObject.js +14 -0
- package/dataLayer/UpdateObject.js +23 -0
- package/dataLayer/UpsertObject.js +23 -0
- package/dataLayer/bulkLoad.js +813 -0
- package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
- package/dataLayer/dataObjects/UpsertObject.js +23 -0
- package/dataLayer/delete.js +164 -0
- package/dataLayer/export.js +381 -0
- package/dataLayer/getBackup.js +40 -0
- package/dataLayer/harperBridge/BridgeMethods.js +81 -0
- package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
- package/dataLayer/harperBridge/harperBridge.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
- package/dataLayer/hdbInfoController.js +254 -0
- package/dataLayer/insert.js +266 -0
- package/dataLayer/readAuditLog.js +59 -0
- package/dataLayer/schema.js +366 -0
- package/dataLayer/schemaDescribe.js +289 -0
- package/dataLayer/search.js +60 -0
- package/dataLayer/transaction.js +17 -0
- package/dataLayer/update.js +124 -0
- package/dist/components/Logger.d.ts +12 -0
- package/dist/components/Logger.js +3 -0
- package/dist/components/Logger.js.map +1 -0
- package/dist/components/Scope.d.ts +14 -4
- package/dist/components/Scope.js +18 -10
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/componentLoader.js +16 -9
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/operations.js +2 -2
- package/dist/components/operations.js.map +1 -1
- package/dist/config/configUtils.d.ts +1 -1
- package/dist/config/configUtils.js +1 -1
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/CreateTableObject.d.ts +2 -2
- package/dist/dataLayer/CreateTableObject.js +2 -2
- package/dist/dataLayer/CreateTableObject.js.map +1 -1
- package/dist/dataLayer/delete.d.ts +1 -1
- package/dist/dataLayer/schema.js +6 -5
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +1 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resources/DatabaseTransaction.d.ts +1 -1
- package/dist/resources/IterableEventQueue.d.ts +1 -1
- package/dist/resources/LMDBTransaction.d.ts +5 -1
- package/dist/resources/Resource.d.ts +1 -1
- package/dist/resources/RocksIndexStore.d.ts +3 -3
- package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
- package/dist/resources/Table.d.ts +15 -6
- package/dist/resources/Table.js +4 -1
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/read.js +32 -22
- package/dist/resources/analytics/read.js.map +1 -1
- package/dist/resources/analytics/write.js +3 -6
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/auditStore.d.ts +3 -3
- package/dist/resources/blob.d.ts +25 -2
- package/dist/resources/databases.d.ts +12 -2
- package/dist/resources/databases.js +22 -19
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/search.js +11 -5
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/transaction.d.ts +2 -1
- package/dist/security/auth.js +1 -1
- package/dist/security/auth.js.map +1 -1
- package/dist/security/cryptoHash.d.ts +2 -2
- package/dist/security/jsLoader.js +243 -66
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +4 -5
- package/dist/security/keys.js.map +1 -1
- package/dist/security/user.js +3 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/REST.js +16 -2
- package/dist/server/REST.js.map +1 -1
- package/dist/server/Server.d.ts +2 -1
- package/dist/server/Server.js.map +1 -1
- package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
- package/dist/server/fastifyRoutes.js +2 -0
- package/dist/server/fastifyRoutes.js.map +1 -1
- package/dist/server/http.js +12 -6
- package/dist/server/http.js.map +1 -1
- package/dist/server/jobs/JobObject.d.ts +3 -3
- package/dist/server/loadRootComponents.js +1 -0
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/operationsServer.js +3 -1
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
- package/dist/server/serverHelpers/Request.d.ts +5 -5
- package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
- package/dist/server/threads/manageThreads.d.ts +2 -2
- package/dist/server/threads/manageThreads.js +50 -35
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.d.ts +1 -1
- package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
- package/dist/utility/AWS/AWSConnector.d.ts +3 -2
- package/dist/utility/common_utils.d.ts +3 -3
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
- package/dist/utility/globalSchema.d.ts +1 -1
- package/dist/utility/hdbTerms.d.ts +3 -0
- package/dist/utility/hdbTerms.js +3 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/installation.d.ts +2 -4
- package/dist/utility/installation.js.map +1 -1
- package/dist/utility/lmdb/commonUtility.d.ts +1 -0
- package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
- package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
- package/dist/utility/lmdb/searchUtility.d.ts +2 -1
- package/dist/utility/lmdb/writeUtility.d.ts +1 -0
- package/dist/utility/logging/harper_logger.d.ts +6 -6
- package/dist/utility/processManagement/processManagement.d.ts +1 -1
- package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
- package/dist/validation/common_validators.d.ts +4 -3
- package/dist/validation/configValidator.d.ts +3 -2
- package/index.d.ts +56 -0
- package/index.js +41 -0
- package/json/systemSchema.json +373 -0
- package/launchServiceScripts/launchHarperDB.js +3 -0
- package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
- package/package.json +21 -3
- package/resources/DatabaseTransaction.ts +378 -0
- package/resources/ErrorResource.ts +57 -0
- package/resources/IterableEventQueue.ts +94 -0
- package/resources/LMDBTransaction.ts +349 -0
- package/resources/RecordEncoder.ts +702 -0
- package/resources/RequestTarget.ts +134 -0
- package/resources/Resource.ts +789 -0
- package/resources/ResourceInterface.ts +221 -0
- package/resources/ResourceInterfaceV2.ts +53 -0
- package/resources/ResourceV2.ts +67 -0
- package/resources/Resources.ts +162 -0
- package/resources/RocksIndexStore.ts +70 -0
- package/resources/RocksTransactionLogStore.ts +352 -0
- package/resources/Table.ts +4527 -0
- package/resources/analytics/hostnames.ts +72 -0
- package/resources/analytics/metadata.ts +10 -0
- package/resources/analytics/read.ts +252 -0
- package/resources/analytics/write.ts +803 -0
- package/resources/auditStore.ts +556 -0
- package/resources/blob.ts +1268 -0
- package/resources/crdt.ts +125 -0
- package/resources/dataLoader.ts +527 -0
- package/resources/databases.ts +1290 -0
- package/resources/graphql.ts +221 -0
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
- package/resources/indexes/customIndexes.ts +7 -0
- package/resources/indexes/vector.ts +38 -0
- package/resources/jsResource.ts +86 -0
- package/resources/loadEnv.ts +22 -0
- package/resources/login.ts +18 -0
- package/resources/openApi.ts +409 -0
- package/resources/registrationDeprecated.ts +8 -0
- package/resources/replayLogs.ts +136 -0
- package/resources/roles.ts +98 -0
- package/resources/search.ts +1301 -0
- package/resources/tracked.ts +584 -0
- package/resources/transaction.ts +89 -0
- package/resources/transactionBroadcast.ts +258 -0
- package/security/auth.ts +376 -0
- package/security/certificateVerification/certificateVerificationSource.ts +84 -0
- package/security/certificateVerification/configValidation.ts +107 -0
- package/security/certificateVerification/crlVerification.ts +623 -0
- package/security/certificateVerification/index.ts +121 -0
- package/security/certificateVerification/ocspVerification.ts +148 -0
- package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
- package/security/certificateVerification/types.ts +128 -0
- package/security/certificateVerification/verificationConfig.ts +138 -0
- package/security/certificateVerification/verificationUtils.ts +447 -0
- package/security/cryptoHash.js +42 -0
- package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
- package/security/data_objects/PermissionResponseObject.js +115 -0
- package/security/data_objects/PermissionTableResponseObject.js +20 -0
- package/security/fastifyAuth.js +169 -0
- package/security/impersonation.ts +160 -0
- package/security/jsLoader.ts +716 -0
- package/security/keys.js +948 -0
- package/security/permissionsTranslator.js +300 -0
- package/security/role.js +218 -0
- package/security/tokenAuthentication.ts +228 -0
- package/security/user.ts +449 -0
- package/server/DurableSubscriptionsSession.ts +503 -0
- package/server/REST.ts +407 -0
- package/server/Server.ts +89 -0
- package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
- package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
- package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
- package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
- package/server/fastifyRoutes.ts +205 -0
- package/server/graphqlQuerying.ts +700 -0
- package/server/http.ts +640 -0
- package/server/itc/serverHandlers.js +161 -0
- package/server/itc/utility/ITCEventObject.js +10 -0
- package/server/jobs/JobObject.js +24 -0
- package/server/jobs/jobProcess.js +69 -0
- package/server/jobs/jobRunner.js +162 -0
- package/server/jobs/jobs.js +304 -0
- package/server/loadRootComponents.js +44 -0
- package/server/mqtt.ts +485 -0
- package/server/nodeName.ts +75 -0
- package/server/operationsServer.ts +313 -0
- package/server/serverHelpers/Headers.ts +108 -0
- package/server/serverHelpers/JSONStream.ts +269 -0
- package/server/serverHelpers/OperationFunctionObject.ts +13 -0
- package/server/serverHelpers/Request.ts +158 -0
- package/server/serverHelpers/contentTypes.ts +637 -0
- package/server/serverHelpers/requestTimePlugin.js +57 -0
- package/server/serverHelpers/serverHandlers.js +148 -0
- package/server/serverHelpers/serverUtilities.ts +473 -0
- package/server/serverRegistry.ts +8 -0
- package/server/static.ts +187 -0
- package/server/status/definitions.ts +37 -0
- package/server/status/index.ts +125 -0
- package/server/storageReclamation.ts +93 -0
- package/server/threads/itc.js +89 -0
- package/server/threads/manageThreads.js +594 -0
- package/server/threads/socketRouter.ts +360 -0
- package/server/threads/threadServer.js +279 -0
- package/server/throttle.ts +73 -0
- package/sqlTranslator/SelectValidator.js +330 -0
- package/sqlTranslator/alasqlFunctionImporter.js +62 -0
- package/sqlTranslator/deleteTranslator.js +67 -0
- package/sqlTranslator/index.js +242 -0
- package/sqlTranslator/sql_statement_bucket.js +472 -0
- package/static/defaultConfig.yaml +3 -0
- package/studio/web/HDBDogOnly.svg +78 -0
- package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
- package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
- package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
- package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
- package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
- package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
- package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
- package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
- package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
- package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
- package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
- package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
- package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
- package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
- package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
- package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
- package/studio/web/assets/index-BTgXJX9d.js +235 -0
- package/studio/web/assets/index-BTgXJX9d.js.map +1 -0
- package/studio/web/assets/index-C-GXfcup.js +37 -0
- package/studio/web/assets/index-C-GXfcup.js.map +1 -0
- package/studio/web/assets/index-PFlNdimM.js +2 -0
- package/studio/web/assets/index-PFlNdimM.js.map +1 -0
- package/studio/web/assets/index-Y2g_iFpU.css +1 -0
- package/studio/web/assets/index-jiPwkrsB.css +1 -0
- package/studio/web/assets/index.lazy-C3TJZJ4o.js +266 -0
- package/studio/web/assets/index.lazy-C3TJZJ4o.js.map +1 -0
- package/studio/web/assets/profiler-DotzgiCJ.js +2 -0
- package/studio/web/assets/profiler-DotzgiCJ.js.map +1 -0
- package/studio/web/assets/react-redux-VxUEx_mU.js +6 -0
- package/studio/web/assets/react-redux-VxUEx_mU.js.map +1 -0
- package/studio/web/assets/startRecording-B_9J9Csd.js +3 -0
- package/studio/web/assets/startRecording-B_9J9Csd.js.map +1 -0
- package/studio/web/fabric-signup-background.webp +0 -0
- package/studio/web/fabric-signup-text.png +0 -0
- package/studio/web/favicon_purple.png +0 -0
- package/studio/web/github-icon.svg +15 -0
- package/studio/web/harper-fabric_black.png +0 -0
- package/studio/web/harper-fabric_white.png +0 -0
- package/studio/web/harper-studio_white.png +0 -0
- package/studio/web/index.html +16 -0
- package/studio/web/running.css +148 -0
- package/studio/web/running.html +147 -0
- package/studio/web/running.js +111 -0
- package/upgrade/UpgradeObjects.js +13 -0
- package/upgrade/directives/directivesController.js +90 -0
- package/upgrade/directivesManager.js +139 -0
- package/upgrade/upgradePrompt.js +124 -0
- package/upgrade/upgradeUtilities.js +28 -0
- package/utility/AWS/AWSConnector.js +29 -0
- package/utility/OperationFunctionCaller.js +63 -0
- package/utility/assignCmdEnvVariables.js +62 -0
- package/utility/common_utils.js +867 -0
- package/utility/environment/environmentManager.js +208 -0
- package/utility/environment/systemInformation.js +355 -0
- package/utility/errors/commonErrors.js +267 -0
- package/utility/errors/hdbError.js +146 -0
- package/utility/functions/date/dateFunctions.js +65 -0
- package/utility/functions/geo.js +355 -0
- package/utility/functions/sql/alaSQLExtension.js +104 -0
- package/utility/globalSchema.js +35 -0
- package/utility/hdbTerms.ts +819 -0
- package/utility/install/checkJWTTokensExist.js +62 -0
- package/utility/install/harperdb.conf +15 -0
- package/utility/install/harperdb.service +14 -0
- package/utility/install/installer.js +635 -0
- package/utility/installation.ts +30 -0
- package/utility/lmdb/DBIDefinition.js +20 -0
- package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
- package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/OpenDBIObject.js +31 -0
- package/utility/lmdb/OpenEnvironmentObject.js +41 -0
- package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
- package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/cleanLMDBMap.js +65 -0
- package/utility/lmdb/commonUtility.js +119 -0
- package/utility/lmdb/deleteUtility.js +128 -0
- package/utility/lmdb/environmentUtility.js +477 -0
- package/utility/lmdb/searchCursorFunctions.js +187 -0
- package/utility/lmdb/searchUtility.js +918 -0
- package/utility/lmdb/terms.js +57 -0
- package/utility/lmdb/writeUtility.js +407 -0
- package/utility/logging/harper_logger.js +876 -0
- package/utility/logging/logRotator.js +157 -0
- package/utility/logging/logger.ts +24 -0
- package/utility/logging/readLog.js +355 -0
- package/utility/logging/transactionLog.js +57 -0
- package/utility/mount_hdb.js +59 -0
- package/utility/npmUtilities.js +102 -0
- package/utility/operationPermissions.ts +112 -0
- package/utility/operation_authorization.js +836 -0
- package/utility/packageUtils.js +55 -0
- package/utility/password.ts +99 -0
- package/utility/processManagement/processManagement.js +187 -0
- package/utility/processManagement/servicesConfig.js +56 -0
- package/utility/scripts/restartHdb.js +24 -0
- package/utility/scripts/user_data.sh +13 -0
- package/utility/signalling.js +36 -0
- package/utility/terms/certificates.js +81 -0
- package/utility/when.ts +20 -0
- package/v1.d.ts +39 -0
- package/v1.js +41 -0
- package/v2.d.ts +39 -0
- package/v2.js +41 -0
- package/validation/bulkDeleteValidator.js +24 -0
- package/validation/check_permissions.js +19 -0
- package/validation/common_validators.js +95 -0
- package/validation/configValidator.js +331 -0
- package/validation/deleteValidator.js +15 -0
- package/validation/fileLoadValidator.js +153 -0
- package/validation/insertValidator.js +40 -0
- package/validation/installValidator.js +37 -0
- package/validation/readLogValidator.js +64 -0
- package/validation/role_validation.js +320 -0
- package/validation/schemaMetadataValidator.js +42 -0
- package/validation/searchValidator.js +166 -0
- package/validation/statusValidator.ts +66 -0
- package/validation/transactionLogValidator.js +33 -0
- package/validation/user_validation.js +55 -0
- package/validation/validationWrapper.js +105 -0
- package/dist/resources/analytics/profile.d.ts +0 -2
- package/dist/resources/analytics/profile.js +0 -144
- package/dist/resources/analytics/profile.js.map +0 -1
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
import { readKey, writeKey } from 'ordered-binary';
|
|
2
|
+
import { initSync, get as envGet } from '../utility/environment/environmentManager.js';
|
|
3
|
+
import { AUDIT_STORE_NAME } from '../utility/lmdb/terms.js';
|
|
4
|
+
import { CONFIG_PARAMS } from '../utility/hdbTerms.ts';
|
|
5
|
+
import { getWorkerIndex, getWorkerCount } from '../server/threads/manageThreads.js';
|
|
6
|
+
import { convertToMS } from '../utility/common_utils.js';
|
|
7
|
+
import { PREVIOUS_TIMESTAMP_PLACEHOLDER, LAST_TIMESTAMP_PLACEHOLDER } from './RecordEncoder.ts';
|
|
8
|
+
import * as harperLogger from '../utility/logging/harper_logger.js';
|
|
9
|
+
import { getRecordAtTime } from './crdt.ts';
|
|
10
|
+
import { decodeFromDatabase } from './blob.ts';
|
|
11
|
+
import { onStorageReclamation } from '../server/storageReclamation.ts';
|
|
12
|
+
import { RocksDatabase } from '@harperfast/rocksdb-js';
|
|
13
|
+
import { RocksTransactionLogStore } from './RocksTransactionLogStore.ts';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* This module is responsible for the binary representation of audit records in an efficient form.
|
|
17
|
+
* This includes a custom key encoder that specifically encodes arrays with the first element (timestamp) as a
|
|
18
|
+
* 64-bit float, second (table id) as a 32-unsigned int, and third using standard ordered-binary encoding
|
|
19
|
+
*
|
|
20
|
+
* This also defines a binary representation for the audit records themselves which is:
|
|
21
|
+
* 1 or 2 bytes: action, describes the action of this record and any flags for which other parts are included
|
|
22
|
+
* tableId
|
|
23
|
+
* recordId
|
|
24
|
+
* origin version
|
|
25
|
+
* previous local version
|
|
26
|
+
* 1 or 2 bytes: position of end of the username section. 0 if there is no username
|
|
27
|
+
* 2 or 4 bytes: node-id
|
|
28
|
+
* 8 bytes (optional): last version timestamp (allows for backwards traversal through history of a record)
|
|
29
|
+
* username
|
|
30
|
+
* remaining bytes (optional, not included for deletes/invalidation): the record itself, using the same encoding as its primary store
|
|
31
|
+
*/
|
|
32
|
+
initSync();
|
|
33
|
+
|
|
34
|
+
export type AuditRecord = {
|
|
35
|
+
version?: number;
|
|
36
|
+
localTime?: number; // only to be used by LMDB (from the key)
|
|
37
|
+
type: string;
|
|
38
|
+
encodedRecord: Buffer;
|
|
39
|
+
extendedType: number;
|
|
40
|
+
residencyId: number;
|
|
41
|
+
previousResidencyId: number;
|
|
42
|
+
expiresAt: Date | null;
|
|
43
|
+
originatingOperation: string;
|
|
44
|
+
tableId: number;
|
|
45
|
+
recordId: number;
|
|
46
|
+
previousVersion: number;
|
|
47
|
+
user?: string;
|
|
48
|
+
nodeId?: number;
|
|
49
|
+
previousNodeId?: number;
|
|
50
|
+
previousAdditionalAuditRefs?: Array<{ version: number; nodeId: number }>;
|
|
51
|
+
endTxn?: boolean;
|
|
52
|
+
structureVersion?: number;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const ENTRY_HEADER = Buffer.alloc(2816); // this is sized to be large enough for the maximum key size (1976) plus large usernames. We may want to consider some limits on usernames to ensure this all fits
|
|
56
|
+
export const ENTRY_DATAVIEW = new DataView(ENTRY_HEADER.buffer, ENTRY_HEADER.byteOffset, 2816);
|
|
57
|
+
export const transactionKeyEncoder = {
|
|
58
|
+
writeKey(key, buffer, position) {
|
|
59
|
+
if (key === LAST_TIMESTAMP_PLACEHOLDER) {
|
|
60
|
+
buffer.set(LAST_TIMESTAMP_PLACEHOLDER, position);
|
|
61
|
+
return position + 8;
|
|
62
|
+
}
|
|
63
|
+
if (typeof key === 'number') {
|
|
64
|
+
const dataView =
|
|
65
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
66
|
+
dataView.setFloat64(position, key);
|
|
67
|
+
return position + 8;
|
|
68
|
+
} else {
|
|
69
|
+
return writeKey(key, buffer, position);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
readKey(buffer, start, end) {
|
|
73
|
+
if (buffer[start] === 66) {
|
|
74
|
+
const dataView =
|
|
75
|
+
buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
76
|
+
return dataView.getFloat64(start);
|
|
77
|
+
} else {
|
|
78
|
+
return readKey(buffer, start, end);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
export const AUDIT_STORE_OPTIONS = {
|
|
83
|
+
encoder: {
|
|
84
|
+
needsStableBuffer: true,
|
|
85
|
+
encode: (auditRecord: AuditRecord) =>
|
|
86
|
+
auditRecord && (auditRecord instanceof Uint8Array ? auditRecord : createAuditEntry(auditRecord)),
|
|
87
|
+
decode: (encoding: Buffer) => readAuditEntry(encoding),
|
|
88
|
+
},
|
|
89
|
+
keyEncoder: transactionKeyEncoder,
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export let auditRetention = convertToMS(envGet(CONFIG_PARAMS.LOGGING_AUDITRETENTION)) || 86400 * 1000;
|
|
93
|
+
const MAX_DELETES_PER_CLEANUP = 1000;
|
|
94
|
+
const FLOAT_TARGET = new Float64Array(1);
|
|
95
|
+
const FLOAT_BUFFER = new Uint8Array(FLOAT_TARGET.buffer);
|
|
96
|
+
let DEFAULT_AUDIT_CLEANUP_DELAY = 10000; // default delay of 10 seconds
|
|
97
|
+
let timestampErrored = false;
|
|
98
|
+
export function openAuditStore(rootStore) {
|
|
99
|
+
let auditStore;
|
|
100
|
+
if (rootStore instanceof RocksDatabase) {
|
|
101
|
+
auditStore = new RocksTransactionLogStore(rootStore);
|
|
102
|
+
auditStore.env = {};
|
|
103
|
+
} else {
|
|
104
|
+
auditStore = rootStore.openDB(AUDIT_STORE_NAME, {
|
|
105
|
+
create: false,
|
|
106
|
+
...AUDIT_STORE_OPTIONS,
|
|
107
|
+
});
|
|
108
|
+
if (!auditStore) {
|
|
109
|
+
// this means we are creating a new audit store. Initialize with the last removed timestamp (we don't want to put this in legacy audit logs since we don't know if they have had deletions or not).
|
|
110
|
+
auditStore = rootStore.openDB(AUDIT_STORE_NAME, AUDIT_STORE_OPTIONS);
|
|
111
|
+
updateLastRemoved(auditStore, 1);
|
|
112
|
+
}
|
|
113
|
+
const superGetRange = auditStore.getRange.bind(auditStore);
|
|
114
|
+
auditStore.getRange = function (options) {
|
|
115
|
+
if (options.values === false) return superGetRange(options); // getKeys shouldn't be modified
|
|
116
|
+
return superGetRange(options).map(({ key, value }) => {
|
|
117
|
+
value.key = value.localTime = key;
|
|
118
|
+
return value;
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
rootStore.auditStore = auditStore;
|
|
123
|
+
auditStore.rootStore = rootStore;
|
|
124
|
+
auditStore.tableStores = [];
|
|
125
|
+
const deleteCallbacks = [];
|
|
126
|
+
auditStore.addDeleteRemovalCallback = function (tableId, table, callback) {
|
|
127
|
+
deleteCallbacks[tableId] = callback;
|
|
128
|
+
auditStore.tableStores[tableId] = table;
|
|
129
|
+
auditStore.deleteCallbacks = deleteCallbacks;
|
|
130
|
+
return {
|
|
131
|
+
remove() {
|
|
132
|
+
delete deleteCallbacks[tableId];
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
let pendingCleanup = null;
|
|
137
|
+
let lastCleanupResolution: Promise<void>;
|
|
138
|
+
let cleanupPriority = 0;
|
|
139
|
+
let auditCleanupDelay = DEFAULT_AUDIT_CLEANUP_DELAY;
|
|
140
|
+
onStorageReclamation(rootStore.path, (priority) => {
|
|
141
|
+
cleanupPriority = priority; // update the priority
|
|
142
|
+
if (priority) {
|
|
143
|
+
// and if we have a priority, schedule cleanup soon
|
|
144
|
+
return scheduleAuditCleanup(100);
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
function scheduleAuditCleanup(newCleanupDelay?: number): Promise<void> {
|
|
148
|
+
if (auditStore instanceof RocksTransactionLogStore) return; // transaction logs are simply deleted with rocksdb
|
|
149
|
+
if (newCleanupDelay) auditCleanupDelay = newCleanupDelay;
|
|
150
|
+
clearTimeout(pendingCleanup);
|
|
151
|
+
const resolution = new Promise<void>((resolve) => {
|
|
152
|
+
pendingCleanup = setTimeout(async () => {
|
|
153
|
+
await lastCleanupResolution;
|
|
154
|
+
lastCleanupResolution = resolution;
|
|
155
|
+
// query for audit entries that are old
|
|
156
|
+
if (auditStore.rootStore.status === 'closed' || auditStore.rootStore.status === 'closing') return;
|
|
157
|
+
let deleted = 0;
|
|
158
|
+
let committed: Promise<void>;
|
|
159
|
+
let lastKey: any;
|
|
160
|
+
try {
|
|
161
|
+
for (const auditRecord of auditStore.getRange({
|
|
162
|
+
start: 1, // must not be zero or it will be interpreted as null and overlap with symbols in search
|
|
163
|
+
snapshot: false,
|
|
164
|
+
end: Date.now() - auditRetention / (1 + cleanupPriority * cleanupPriority), // remove up until the audit retention time, reducing audit retention time if cleanup is higher priority
|
|
165
|
+
})) {
|
|
166
|
+
try {
|
|
167
|
+
committed = removeAuditEntry(auditStore, auditRecord);
|
|
168
|
+
} catch (error) {
|
|
169
|
+
harperLogger.warn('Error removing audit entry', error);
|
|
170
|
+
}
|
|
171
|
+
lastKey = auditRecord.key;
|
|
172
|
+
await new Promise(setImmediate);
|
|
173
|
+
if (++deleted >= MAX_DELETES_PER_CLEANUP) {
|
|
174
|
+
// limit the amount we cleanup per event turn so we don't use too much memory/CPU
|
|
175
|
+
auditCleanupDelay = 10; // and keep trying very soon
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
await committed;
|
|
180
|
+
} finally {
|
|
181
|
+
if (deleted === 0) {
|
|
182
|
+
// if we didn't delete anything, we can increase the delay (double until we get to one tenth of the retention time)
|
|
183
|
+
auditCleanupDelay = Math.min(auditCleanupDelay << 1, auditRetention / 10);
|
|
184
|
+
} else {
|
|
185
|
+
// if we did delete something, update our updates since timestamp
|
|
186
|
+
updateLastRemoved(auditStore, lastKey);
|
|
187
|
+
// and do updates faster
|
|
188
|
+
if (auditCleanupDelay > 100) auditCleanupDelay = auditCleanupDelay >> 1;
|
|
189
|
+
}
|
|
190
|
+
resolve(undefined);
|
|
191
|
+
scheduleAuditCleanup();
|
|
192
|
+
}
|
|
193
|
+
// we can run this pretty frequently since there is very little overhead to these queries
|
|
194
|
+
}, auditCleanupDelay).unref();
|
|
195
|
+
});
|
|
196
|
+
return resolution;
|
|
197
|
+
}
|
|
198
|
+
auditStore.scheduleAuditCleanup = scheduleAuditCleanup;
|
|
199
|
+
if (getWorkerIndex() === getWorkerCount() - 1) {
|
|
200
|
+
scheduleAuditCleanup();
|
|
201
|
+
}
|
|
202
|
+
if (getWorkerIndex() === 0 && !timestampErrored) {
|
|
203
|
+
// make sure the timestamp is valid
|
|
204
|
+
for (const time of auditStore.getKeys({ reverse: true, limit: 1 })) {
|
|
205
|
+
if (time > Date.now()) {
|
|
206
|
+
timestampErrored = true;
|
|
207
|
+
harperLogger.error(
|
|
208
|
+
'The current time is before the last recorded entry in the audit log. Time reversal can undermine the integrity of data tracking and certificate validation and the time must be corrected.'
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
return auditStore;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function removeAuditEntry(auditStore: any, auditRecord: AuditRecord): Promise<void> {
|
|
217
|
+
if (auditRecord.type === 'delete') {
|
|
218
|
+
// if this is a delete, we remove the delete entry from the primary table
|
|
219
|
+
// at the same time so the audit table the primary table are in sync, assuming the entry matches this audit record version
|
|
220
|
+
const tableId = auditRecord.tableId;
|
|
221
|
+
const primaryStore = auditStore.tableStores[auditRecord.tableId];
|
|
222
|
+
if (primaryStore?.getEntry(auditRecord.recordId)?.version === auditRecord.version)
|
|
223
|
+
auditStore.deleteCallbacks?.[tableId]?.(auditRecord.recordId, auditRecord.version);
|
|
224
|
+
}
|
|
225
|
+
return auditStore.remove(auditRecord.key);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function updateLastRemoved(auditStore, lastKey) {
|
|
229
|
+
FLOAT_TARGET[0] = lastKey;
|
|
230
|
+
auditStore.put(Symbol.for('last-removed'), FLOAT_BUFFER);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function getLastRemoved(auditStore) {
|
|
234
|
+
const lastRemoved = auditStore.get(Symbol.for('last-removed'));
|
|
235
|
+
if (lastRemoved) {
|
|
236
|
+
FLOAT_BUFFER.set(lastRemoved);
|
|
237
|
+
return FLOAT_TARGET[0];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
export function setAuditRetention(retentionTime, defaultDelay = DEFAULT_AUDIT_CLEANUP_DELAY) {
|
|
241
|
+
auditRetention = retentionTime;
|
|
242
|
+
DEFAULT_AUDIT_CLEANUP_DELAY = defaultDelay;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const HAS_RECORD = 16;
|
|
246
|
+
const HAS_PARTIAL_RECORD = 32; // will be used for CRDTs
|
|
247
|
+
const PUT = 1;
|
|
248
|
+
const DELETE = 2;
|
|
249
|
+
const MESSAGE = 3;
|
|
250
|
+
const INVALIDATE = 4;
|
|
251
|
+
const PATCH = 5;
|
|
252
|
+
const RELOCATE = 6;
|
|
253
|
+
const STRUCTURES = 7;
|
|
254
|
+
export const ACTION_32_BIT = 14;
|
|
255
|
+
export const ACTION_64_BIT = 15;
|
|
256
|
+
/** Used to indicate we have received a remote local time update */
|
|
257
|
+
export const REMOTE_SEQUENCE_UPDATE = 11;
|
|
258
|
+
export const HAS_CURRENT_RESIDENCY_ID = 512;
|
|
259
|
+
export const HAS_PREVIOUS_RESIDENCY_ID = 1024;
|
|
260
|
+
export const HAS_ORIGINATING_OPERATION = 2048;
|
|
261
|
+
export const HAS_EXPIRATION_EXTENDED_TYPE = 0x1000;
|
|
262
|
+
export const HAS_BLOBS = 0x2000;
|
|
263
|
+
export const HAS_ADDITIONAL_AUDIT_REFS = 0x4000;
|
|
264
|
+
const EVENT_TYPES = {
|
|
265
|
+
put: PUT | HAS_RECORD,
|
|
266
|
+
[PUT]: 'put',
|
|
267
|
+
delete: DELETE,
|
|
268
|
+
[DELETE]: 'delete',
|
|
269
|
+
message: MESSAGE | HAS_RECORD,
|
|
270
|
+
[MESSAGE]: 'message',
|
|
271
|
+
invalidate: INVALIDATE | HAS_PARTIAL_RECORD,
|
|
272
|
+
[INVALIDATE]: 'invalidate',
|
|
273
|
+
patch: PATCH | HAS_PARTIAL_RECORD,
|
|
274
|
+
[PATCH]: 'patch',
|
|
275
|
+
relocate: RELOCATE,
|
|
276
|
+
[RELOCATE]: 'relocate',
|
|
277
|
+
structures: STRUCTURES,
|
|
278
|
+
[STRUCTURES]: 'structures',
|
|
279
|
+
remoteSequenceUpdate: REMOTE_SEQUENCE_UPDATE,
|
|
280
|
+
[REMOTE_SEQUENCE_UPDATE]: 'remoteSequenceUpdate',
|
|
281
|
+
};
|
|
282
|
+
const ORIGINATING_OPERATIONS = {
|
|
283
|
+
insert: 1,
|
|
284
|
+
update: 2,
|
|
285
|
+
upsert: 3,
|
|
286
|
+
1: 'insert',
|
|
287
|
+
2: 'update',
|
|
288
|
+
3: 'upsert',
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Creates a binary audit entry
|
|
293
|
+
* @param txnTime
|
|
294
|
+
* @param tableId
|
|
295
|
+
* @param recordId
|
|
296
|
+
* @param previousVersion
|
|
297
|
+
* @param nodeId
|
|
298
|
+
* @param user
|
|
299
|
+
* @param type
|
|
300
|
+
* @param encodedRecord
|
|
301
|
+
* @param extendedType
|
|
302
|
+
* @param residencyId
|
|
303
|
+
* @param previousResidencyId
|
|
304
|
+
*/
|
|
305
|
+
export function createAuditEntry(auditRecord: AuditRecord, start = 0) {
|
|
306
|
+
const {
|
|
307
|
+
version,
|
|
308
|
+
tableId,
|
|
309
|
+
recordId,
|
|
310
|
+
previousVersion,
|
|
311
|
+
nodeId,
|
|
312
|
+
user,
|
|
313
|
+
type,
|
|
314
|
+
encodedRecord,
|
|
315
|
+
extendedType,
|
|
316
|
+
residencyId,
|
|
317
|
+
previousResidencyId,
|
|
318
|
+
expiresAt,
|
|
319
|
+
originatingOperation,
|
|
320
|
+
previousAdditionalAuditRefs,
|
|
321
|
+
} = auditRecord;
|
|
322
|
+
const action = EVENT_TYPES[type];
|
|
323
|
+
if (!action) {
|
|
324
|
+
throw new Error(`Invalid audit entry type ${type}`);
|
|
325
|
+
}
|
|
326
|
+
let position = start + 1;
|
|
327
|
+
if (previousVersion) {
|
|
328
|
+
if (previousVersion > 1) ENTRY_DATAVIEW.setFloat64(start, previousVersion);
|
|
329
|
+
else ENTRY_HEADER.set(PREVIOUS_TIMESTAMP_PLACEHOLDER, start);
|
|
330
|
+
position = start + 9;
|
|
331
|
+
}
|
|
332
|
+
if (extendedType) {
|
|
333
|
+
if (extendedType & 0xff) {
|
|
334
|
+
throw new Error('Illegal extended type');
|
|
335
|
+
}
|
|
336
|
+
position += 3;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
writeInt(nodeId);
|
|
340
|
+
writeInt(tableId);
|
|
341
|
+
writeValue(recordId);
|
|
342
|
+
// TODO: Once we support multiple format versions, we can conditionally write the version (and the previousResidencyId)
|
|
343
|
+
// if (formatVersion === 1) {
|
|
344
|
+
ENTRY_DATAVIEW.setFloat64(position, version);
|
|
345
|
+
position += 8;
|
|
346
|
+
if (extendedType & HAS_CURRENT_RESIDENCY_ID) writeInt(residencyId);
|
|
347
|
+
if (extendedType & HAS_PREVIOUS_RESIDENCY_ID) writeInt(previousResidencyId);
|
|
348
|
+
if (extendedType & HAS_EXPIRATION_EXTENDED_TYPE) {
|
|
349
|
+
ENTRY_DATAVIEW.setFloat64(position, expiresAt);
|
|
350
|
+
position += 8;
|
|
351
|
+
}
|
|
352
|
+
if (extendedType & HAS_ORIGINATING_OPERATION) {
|
|
353
|
+
writeInt(ORIGINATING_OPERATIONS[originatingOperation]);
|
|
354
|
+
}
|
|
355
|
+
if (extendedType & HAS_ADDITIONAL_AUDIT_REFS) {
|
|
356
|
+
if (previousAdditionalAuditRefs && previousAdditionalAuditRefs.length > 0) {
|
|
357
|
+
ENTRY_HEADER[position++] = previousAdditionalAuditRefs.length;
|
|
358
|
+
for (const ref of previousAdditionalAuditRefs) {
|
|
359
|
+
ENTRY_DATAVIEW.setFloat64(position, ref.version);
|
|
360
|
+
position += 8;
|
|
361
|
+
writeInt(ref.nodeId);
|
|
362
|
+
}
|
|
363
|
+
} else {
|
|
364
|
+
ENTRY_HEADER[position++] = 0;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (user) writeValue(user);
|
|
369
|
+
else ENTRY_HEADER[position++] = 0;
|
|
370
|
+
if (extendedType) ENTRY_DATAVIEW.setUint32(start + (previousVersion ? 8 : 0), action | extendedType | 0xc0000000);
|
|
371
|
+
else ENTRY_HEADER[start + (previousVersion ? 8 : 0)] = action;
|
|
372
|
+
const header = ENTRY_HEADER.subarray(0, position);
|
|
373
|
+
if (encodedRecord) {
|
|
374
|
+
return Buffer.concat([header, encodedRecord]);
|
|
375
|
+
} else return header;
|
|
376
|
+
function writeValue(value) {
|
|
377
|
+
const valueLengthPosition = position;
|
|
378
|
+
position += 1;
|
|
379
|
+
position = writeKey(value, ENTRY_HEADER, position);
|
|
380
|
+
const keyLength = position - valueLengthPosition - 1;
|
|
381
|
+
if (keyLength > 0x7f) {
|
|
382
|
+
if (keyLength > 0x3fff) {
|
|
383
|
+
harperLogger.error('Key or username was too large for audit entry', value);
|
|
384
|
+
position = valueLengthPosition + 1;
|
|
385
|
+
ENTRY_HEADER[valueLengthPosition] = 0;
|
|
386
|
+
} else {
|
|
387
|
+
// requires two byte length header, need to move the value/key to make room for it
|
|
388
|
+
ENTRY_HEADER.copyWithin(valueLengthPosition + 2, valueLengthPosition + 1, position);
|
|
389
|
+
// now write a two-byte length header
|
|
390
|
+
ENTRY_DATAVIEW.setUint16(valueLengthPosition, keyLength | 0x8000);
|
|
391
|
+
// must adjust the position by one since we moved everything one position
|
|
392
|
+
position++;
|
|
393
|
+
}
|
|
394
|
+
} else {
|
|
395
|
+
// one byte length header, as expected
|
|
396
|
+
ENTRY_HEADER[valueLengthPosition] = keyLength;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
function writeInt(number) {
|
|
400
|
+
if (number < 128) {
|
|
401
|
+
ENTRY_HEADER[position++] = number;
|
|
402
|
+
} else if (number < 0x4000) {
|
|
403
|
+
ENTRY_DATAVIEW.setUint16(position, number | 0x8000);
|
|
404
|
+
position += 2;
|
|
405
|
+
} else if (number < 0x3f000000) {
|
|
406
|
+
ENTRY_DATAVIEW.setUint32(position, number | 0xc0000000);
|
|
407
|
+
position += 4;
|
|
408
|
+
} else {
|
|
409
|
+
ENTRY_HEADER[position] = 0xff;
|
|
410
|
+
ENTRY_DATAVIEW.setUint32(position + 1, number);
|
|
411
|
+
position += 5;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Reads a audit entry from binary data
|
|
418
|
+
* @param buffer
|
|
419
|
+
* @param start
|
|
420
|
+
* @param end
|
|
421
|
+
*/
|
|
422
|
+
export function readAuditEntry(buffer: Uint8Array, start = 0, end = undefined): AuditRecord {
|
|
423
|
+
try {
|
|
424
|
+
const decoder =
|
|
425
|
+
buffer.decoder || (buffer.decoder = new Decoder(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
426
|
+
decoder.position = start;
|
|
427
|
+
let previousVersion;
|
|
428
|
+
if (buffer[decoder.position] == 66) {
|
|
429
|
+
// 66 is the first byte in a date double.
|
|
430
|
+
previousVersion = decoder.readFloat64();
|
|
431
|
+
}
|
|
432
|
+
const action = decoder.readInt();
|
|
433
|
+
const nodeId = decoder.readInt();
|
|
434
|
+
const tableId = decoder.readInt();
|
|
435
|
+
let length = decoder.readInt();
|
|
436
|
+
const recordIdStart = decoder.position;
|
|
437
|
+
const recordIdEnd = (decoder.position += length);
|
|
438
|
+
// TODO: Once we support multiple format versions, we can conditionally read the version (and the previousResidencyId)
|
|
439
|
+
const version = decoder.readFloat64();
|
|
440
|
+
let residencyId, previousResidencyId, expiresAt, originatingOperation, previousAdditionalAuditRefs;
|
|
441
|
+
if (action & HAS_CURRENT_RESIDENCY_ID) {
|
|
442
|
+
residencyId = decoder.readInt();
|
|
443
|
+
}
|
|
444
|
+
if (action & HAS_PREVIOUS_RESIDENCY_ID) {
|
|
445
|
+
previousResidencyId = decoder.readInt();
|
|
446
|
+
}
|
|
447
|
+
if (action & HAS_EXPIRATION_EXTENDED_TYPE) {
|
|
448
|
+
expiresAt = decoder.readFloat64();
|
|
449
|
+
}
|
|
450
|
+
if (action & HAS_ORIGINATING_OPERATION) {
|
|
451
|
+
const operationId = decoder.readInt();
|
|
452
|
+
originatingOperation = ORIGINATING_OPERATIONS[operationId];
|
|
453
|
+
}
|
|
454
|
+
if (action & HAS_ADDITIONAL_AUDIT_REFS) {
|
|
455
|
+
const count = buffer[decoder.position++];
|
|
456
|
+
if (count > 0) {
|
|
457
|
+
previousAdditionalAuditRefs = [];
|
|
458
|
+
for (let i = 0; i < count; i++) {
|
|
459
|
+
const refVersion = decoder.readFloat64();
|
|
460
|
+
const refNodeId = decoder.readInt();
|
|
461
|
+
previousAdditionalAuditRefs.push({ version: refVersion, nodeId: refNodeId });
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
length = decoder.readInt();
|
|
466
|
+
const usernameStart = decoder.position;
|
|
467
|
+
const usernameEnd = (decoder.position += length);
|
|
468
|
+
let value: any;
|
|
469
|
+
return {
|
|
470
|
+
type: EVENT_TYPES[action & 7],
|
|
471
|
+
tableId,
|
|
472
|
+
nodeId,
|
|
473
|
+
get recordId() {
|
|
474
|
+
// use a subarray to protect against the underlying buffer being modified
|
|
475
|
+
return readKey(buffer.subarray(0, recordIdEnd), recordIdStart, recordIdEnd);
|
|
476
|
+
},
|
|
477
|
+
getBinaryRecordId() {
|
|
478
|
+
return buffer.subarray(recordIdStart, recordIdEnd);
|
|
479
|
+
},
|
|
480
|
+
version,
|
|
481
|
+
previousVersion,
|
|
482
|
+
get user() {
|
|
483
|
+
return usernameEnd > usernameStart
|
|
484
|
+
? readKey(buffer.subarray(0, usernameEnd), usernameStart, usernameEnd)
|
|
485
|
+
: undefined;
|
|
486
|
+
},
|
|
487
|
+
get encoded() {
|
|
488
|
+
return start ? buffer.subarray(start, end) : buffer;
|
|
489
|
+
},
|
|
490
|
+
get size() {
|
|
491
|
+
return start !== undefined && end !== undefined ? end - start : buffer.byteLength;
|
|
492
|
+
},
|
|
493
|
+
getValue(store, fullRecord?, auditTime?) {
|
|
494
|
+
if (action & HAS_RECORD || (action & HAS_PARTIAL_RECORD && !fullRecord)) {
|
|
495
|
+
if (!value) {
|
|
496
|
+
value = decodeFromDatabase(
|
|
497
|
+
() => store.decoder.decode(buffer.subarray(decoder.position, end)),
|
|
498
|
+
store.rootStore
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
return value;
|
|
502
|
+
}
|
|
503
|
+
if (action & HAS_PARTIAL_RECORD && auditTime) {
|
|
504
|
+
const recordId = this.recordId;
|
|
505
|
+
return getRecordAtTime(store.getEntry(recordId), auditTime, store, tableId, recordId);
|
|
506
|
+
} // TODO: If we store a partial and full record, may need to read both sequentially
|
|
507
|
+
},
|
|
508
|
+
getBinaryValue() {
|
|
509
|
+
return buffer.subarray(decoder.position, end);
|
|
510
|
+
},
|
|
511
|
+
extendedType: action,
|
|
512
|
+
residencyId,
|
|
513
|
+
previousResidencyId,
|
|
514
|
+
expiresAt,
|
|
515
|
+
originatingOperation,
|
|
516
|
+
previousAdditionalAuditRefs,
|
|
517
|
+
};
|
|
518
|
+
} catch (error) {
|
|
519
|
+
harperLogger.error('Reading audit entry error', error, buffer);
|
|
520
|
+
return {};
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export class Decoder extends DataView<ArrayBufferLike> {
|
|
525
|
+
position = 0;
|
|
526
|
+
readInt() {
|
|
527
|
+
let number;
|
|
528
|
+
number = this.getUint8(this.position++);
|
|
529
|
+
if (number >= 0x80) {
|
|
530
|
+
if (number >= 0xc0) {
|
|
531
|
+
if (number === 0xff) {
|
|
532
|
+
number = this.getUint32(this.position);
|
|
533
|
+
this.position += 4;
|
|
534
|
+
return number;
|
|
535
|
+
}
|
|
536
|
+
number = this.getUint32(this.position - 1) & 0x3fffffff;
|
|
537
|
+
this.position += 3;
|
|
538
|
+
return number;
|
|
539
|
+
}
|
|
540
|
+
number = this.getUint16(this.position - 1) & 0x7fff;
|
|
541
|
+
this.position++;
|
|
542
|
+
return number;
|
|
543
|
+
}
|
|
544
|
+
return number;
|
|
545
|
+
}
|
|
546
|
+
readFloat64() {
|
|
547
|
+
try {
|
|
548
|
+
const value = this.getFloat64(this.position);
|
|
549
|
+
this.position += 8;
|
|
550
|
+
return value;
|
|
551
|
+
} catch (error) {
|
|
552
|
+
error.message = `Error reading float64: ${error.message} at position ${this.position}`;
|
|
553
|
+
throw error;
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|