@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.
Files changed (444) hide show
  1. package/bin/BinObjects.js +17 -0
  2. package/bin/cliOperations.js +157 -0
  3. package/bin/copyDb.ts +280 -0
  4. package/bin/harper.js +156 -0
  5. package/bin/install.js +15 -0
  6. package/bin/lite.js +5 -0
  7. package/bin/restart.js +201 -0
  8. package/bin/run.js +409 -0
  9. package/bin/status.js +65 -0
  10. package/bin/stop.js +22 -0
  11. package/bin/upgrade.js +134 -0
  12. package/components/Application.ts +646 -0
  13. package/components/ApplicationScope.ts +49 -0
  14. package/components/Component.ts +53 -0
  15. package/components/ComponentV1.ts +342 -0
  16. package/components/DEFAULT_CONFIG.ts +18 -0
  17. package/components/EntryHandler.ts +227 -0
  18. package/components/Logger.ts +14 -0
  19. package/components/OptionsWatcher.ts +354 -0
  20. package/components/PluginModule.ts +6 -0
  21. package/components/Scope.ts +329 -0
  22. package/components/componentLoader.ts +529 -0
  23. package/components/deriveCommonPatternBase.ts +31 -0
  24. package/components/deriveGlobOptions.ts +44 -0
  25. package/components/deriveURLPath.ts +57 -0
  26. package/components/operations.js +658 -0
  27. package/components/operationsValidation.js +246 -0
  28. package/components/packageComponent.ts +39 -0
  29. package/components/requestRestart.ts +26 -0
  30. package/components/resolveBaseURLPath.ts +38 -0
  31. package/components/status/ComponentStatus.ts +110 -0
  32. package/components/status/ComponentStatusRegistry.ts +251 -0
  33. package/components/status/api.ts +153 -0
  34. package/components/status/crossThread.ts +405 -0
  35. package/components/status/errors.ts +152 -0
  36. package/components/status/index.ts +44 -0
  37. package/components/status/internal.ts +65 -0
  38. package/components/status/registry.ts +12 -0
  39. package/components/status/types.ts +96 -0
  40. package/config/RootConfigWatcher.ts +59 -0
  41. package/config/configHelpers.ts +11 -0
  42. package/config/configUtils.js +967 -0
  43. package/config/harperConfigEnvVars.ts +641 -0
  44. package/dataLayer/CreateAttributeObject.js +25 -0
  45. package/dataLayer/CreateTableObject.js +11 -0
  46. package/dataLayer/DataLayerObjects.js +43 -0
  47. package/dataLayer/DeleteBeforeObject.js +22 -0
  48. package/dataLayer/DeleteObject.js +25 -0
  49. package/dataLayer/DropAttributeObject.js +11 -0
  50. package/dataLayer/GetBackupObject.js +22 -0
  51. package/dataLayer/InsertObject.js +24 -0
  52. package/dataLayer/ReadAuditLogObject.js +24 -0
  53. package/dataLayer/SQLSearch.js +1335 -0
  54. package/dataLayer/SearchByConditionsObject.js +61 -0
  55. package/dataLayer/SearchByHashObject.js +21 -0
  56. package/dataLayer/SearchObject.js +45 -0
  57. package/dataLayer/SqlSearchObject.js +14 -0
  58. package/dataLayer/UpdateObject.js +23 -0
  59. package/dataLayer/UpsertObject.js +23 -0
  60. package/dataLayer/bulkLoad.js +813 -0
  61. package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
  62. package/dataLayer/dataObjects/UpsertObject.js +23 -0
  63. package/dataLayer/delete.js +164 -0
  64. package/dataLayer/export.js +381 -0
  65. package/dataLayer/getBackup.js +40 -0
  66. package/dataLayer/harperBridge/BridgeMethods.js +81 -0
  67. package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
  68. package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
  69. package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
  70. package/dataLayer/harperBridge/harperBridge.js +21 -0
  71. package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
  72. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
  73. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
  74. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
  75. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
  76. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
  77. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
  78. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
  79. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
  80. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
  81. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
  82. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
  83. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
  84. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
  85. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
  86. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
  87. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
  88. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
  89. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
  90. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
  91. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
  92. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
  93. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
  94. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
  95. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
  96. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
  97. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
  98. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
  99. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
  100. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
  101. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
  102. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
  103. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
  104. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
  105. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
  106. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
  107. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
  108. package/dataLayer/hdbInfoController.js +254 -0
  109. package/dataLayer/insert.js +266 -0
  110. package/dataLayer/readAuditLog.js +59 -0
  111. package/dataLayer/schema.js +366 -0
  112. package/dataLayer/schemaDescribe.js +289 -0
  113. package/dataLayer/search.js +60 -0
  114. package/dataLayer/transaction.js +17 -0
  115. package/dataLayer/update.js +124 -0
  116. package/dist/components/Logger.d.ts +12 -0
  117. package/dist/components/Logger.js +3 -0
  118. package/dist/components/Logger.js.map +1 -0
  119. package/dist/components/Scope.d.ts +14 -4
  120. package/dist/components/Scope.js +18 -10
  121. package/dist/components/Scope.js.map +1 -1
  122. package/dist/components/componentLoader.js +16 -9
  123. package/dist/components/componentLoader.js.map +1 -1
  124. package/dist/components/operations.js +2 -2
  125. package/dist/components/operations.js.map +1 -1
  126. package/dist/config/configUtils.d.ts +1 -1
  127. package/dist/config/configUtils.js +1 -1
  128. package/dist/config/configUtils.js.map +1 -1
  129. package/dist/dataLayer/CreateTableObject.d.ts +2 -2
  130. package/dist/dataLayer/CreateTableObject.js +2 -2
  131. package/dist/dataLayer/CreateTableObject.js.map +1 -1
  132. package/dist/dataLayer/delete.d.ts +1 -1
  133. package/dist/dataLayer/schema.js +6 -5
  134. package/dist/dataLayer/schema.js.map +1 -1
  135. package/dist/dataLayer/schemaDescribe.js +1 -1
  136. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  137. package/dist/index.d.ts +1 -1
  138. package/dist/index.js +2 -0
  139. package/dist/index.js.map +1 -1
  140. package/dist/resources/DatabaseTransaction.d.ts +1 -1
  141. package/dist/resources/IterableEventQueue.d.ts +1 -1
  142. package/dist/resources/LMDBTransaction.d.ts +5 -1
  143. package/dist/resources/Resource.d.ts +1 -1
  144. package/dist/resources/RocksIndexStore.d.ts +3 -3
  145. package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
  146. package/dist/resources/Table.d.ts +15 -6
  147. package/dist/resources/Table.js +4 -1
  148. package/dist/resources/Table.js.map +1 -1
  149. package/dist/resources/analytics/read.js +32 -22
  150. package/dist/resources/analytics/read.js.map +1 -1
  151. package/dist/resources/analytics/write.js +3 -6
  152. package/dist/resources/analytics/write.js.map +1 -1
  153. package/dist/resources/auditStore.d.ts +3 -3
  154. package/dist/resources/blob.d.ts +25 -2
  155. package/dist/resources/databases.d.ts +12 -2
  156. package/dist/resources/databases.js +22 -19
  157. package/dist/resources/databases.js.map +1 -1
  158. package/dist/resources/search.js +11 -5
  159. package/dist/resources/search.js.map +1 -1
  160. package/dist/resources/transaction.d.ts +2 -1
  161. package/dist/security/auth.js +1 -1
  162. package/dist/security/auth.js.map +1 -1
  163. package/dist/security/cryptoHash.d.ts +2 -2
  164. package/dist/security/jsLoader.js +243 -66
  165. package/dist/security/jsLoader.js.map +1 -1
  166. package/dist/security/keys.js +4 -5
  167. package/dist/security/keys.js.map +1 -1
  168. package/dist/security/user.js +3 -3
  169. package/dist/security/user.js.map +1 -1
  170. package/dist/server/REST.js +16 -2
  171. package/dist/server/REST.js.map +1 -1
  172. package/dist/server/Server.d.ts +2 -1
  173. package/dist/server/Server.js.map +1 -1
  174. package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
  175. package/dist/server/fastifyRoutes.js +2 -0
  176. package/dist/server/fastifyRoutes.js.map +1 -1
  177. package/dist/server/http.js +12 -6
  178. package/dist/server/http.js.map +1 -1
  179. package/dist/server/jobs/JobObject.d.ts +3 -3
  180. package/dist/server/loadRootComponents.js +1 -0
  181. package/dist/server/loadRootComponents.js.map +1 -1
  182. package/dist/server/operationsServer.js +3 -1
  183. package/dist/server/operationsServer.js.map +1 -1
  184. package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
  185. package/dist/server/serverHelpers/Request.d.ts +5 -5
  186. package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
  187. package/dist/server/threads/manageThreads.d.ts +2 -2
  188. package/dist/server/threads/manageThreads.js +50 -35
  189. package/dist/server/threads/manageThreads.js.map +1 -1
  190. package/dist/server/threads/socketRouter.d.ts +1 -1
  191. package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
  192. package/dist/utility/AWS/AWSConnector.d.ts +3 -2
  193. package/dist/utility/common_utils.d.ts +3 -3
  194. package/dist/utility/environment/systemInformation.d.ts +1 -0
  195. package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
  196. package/dist/utility/globalSchema.d.ts +1 -1
  197. package/dist/utility/hdbTerms.d.ts +3 -0
  198. package/dist/utility/hdbTerms.js +3 -0
  199. package/dist/utility/hdbTerms.js.map +1 -1
  200. package/dist/utility/installation.d.ts +2 -4
  201. package/dist/utility/installation.js.map +1 -1
  202. package/dist/utility/lmdb/commonUtility.d.ts +1 -0
  203. package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
  204. package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
  205. package/dist/utility/lmdb/searchUtility.d.ts +2 -1
  206. package/dist/utility/lmdb/writeUtility.d.ts +1 -0
  207. package/dist/utility/logging/harper_logger.d.ts +6 -6
  208. package/dist/utility/processManagement/processManagement.d.ts +1 -1
  209. package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
  210. package/dist/validation/common_validators.d.ts +4 -3
  211. package/dist/validation/configValidator.d.ts +3 -2
  212. package/index.d.ts +56 -0
  213. package/index.js +41 -0
  214. package/json/systemSchema.json +373 -0
  215. package/launchServiceScripts/launchHarperDB.js +3 -0
  216. package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
  217. package/package.json +21 -3
  218. package/resources/DatabaseTransaction.ts +378 -0
  219. package/resources/ErrorResource.ts +57 -0
  220. package/resources/IterableEventQueue.ts +94 -0
  221. package/resources/LMDBTransaction.ts +349 -0
  222. package/resources/RecordEncoder.ts +702 -0
  223. package/resources/RequestTarget.ts +134 -0
  224. package/resources/Resource.ts +789 -0
  225. package/resources/ResourceInterface.ts +221 -0
  226. package/resources/ResourceInterfaceV2.ts +53 -0
  227. package/resources/ResourceV2.ts +67 -0
  228. package/resources/Resources.ts +162 -0
  229. package/resources/RocksIndexStore.ts +70 -0
  230. package/resources/RocksTransactionLogStore.ts +352 -0
  231. package/resources/Table.ts +4527 -0
  232. package/resources/analytics/hostnames.ts +72 -0
  233. package/resources/analytics/metadata.ts +10 -0
  234. package/resources/analytics/read.ts +252 -0
  235. package/resources/analytics/write.ts +803 -0
  236. package/resources/auditStore.ts +556 -0
  237. package/resources/blob.ts +1268 -0
  238. package/resources/crdt.ts +125 -0
  239. package/resources/dataLoader.ts +527 -0
  240. package/resources/databases.ts +1290 -0
  241. package/resources/graphql.ts +221 -0
  242. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
  243. package/resources/indexes/customIndexes.ts +7 -0
  244. package/resources/indexes/vector.ts +38 -0
  245. package/resources/jsResource.ts +86 -0
  246. package/resources/loadEnv.ts +22 -0
  247. package/resources/login.ts +18 -0
  248. package/resources/openApi.ts +409 -0
  249. package/resources/registrationDeprecated.ts +8 -0
  250. package/resources/replayLogs.ts +136 -0
  251. package/resources/roles.ts +98 -0
  252. package/resources/search.ts +1301 -0
  253. package/resources/tracked.ts +584 -0
  254. package/resources/transaction.ts +89 -0
  255. package/resources/transactionBroadcast.ts +258 -0
  256. package/security/auth.ts +376 -0
  257. package/security/certificateVerification/certificateVerificationSource.ts +84 -0
  258. package/security/certificateVerification/configValidation.ts +107 -0
  259. package/security/certificateVerification/crlVerification.ts +623 -0
  260. package/security/certificateVerification/index.ts +121 -0
  261. package/security/certificateVerification/ocspVerification.ts +148 -0
  262. package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
  263. package/security/certificateVerification/types.ts +128 -0
  264. package/security/certificateVerification/verificationConfig.ts +138 -0
  265. package/security/certificateVerification/verificationUtils.ts +447 -0
  266. package/security/cryptoHash.js +42 -0
  267. package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
  268. package/security/data_objects/PermissionResponseObject.js +115 -0
  269. package/security/data_objects/PermissionTableResponseObject.js +20 -0
  270. package/security/fastifyAuth.js +169 -0
  271. package/security/impersonation.ts +160 -0
  272. package/security/jsLoader.ts +716 -0
  273. package/security/keys.js +948 -0
  274. package/security/permissionsTranslator.js +300 -0
  275. package/security/role.js +218 -0
  276. package/security/tokenAuthentication.ts +228 -0
  277. package/security/user.ts +449 -0
  278. package/server/DurableSubscriptionsSession.ts +503 -0
  279. package/server/REST.ts +407 -0
  280. package/server/Server.ts +89 -0
  281. package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
  282. package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
  283. package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
  284. package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
  285. package/server/fastifyRoutes.ts +205 -0
  286. package/server/graphqlQuerying.ts +700 -0
  287. package/server/http.ts +640 -0
  288. package/server/itc/serverHandlers.js +161 -0
  289. package/server/itc/utility/ITCEventObject.js +10 -0
  290. package/server/jobs/JobObject.js +24 -0
  291. package/server/jobs/jobProcess.js +69 -0
  292. package/server/jobs/jobRunner.js +162 -0
  293. package/server/jobs/jobs.js +304 -0
  294. package/server/loadRootComponents.js +44 -0
  295. package/server/mqtt.ts +485 -0
  296. package/server/nodeName.ts +75 -0
  297. package/server/operationsServer.ts +313 -0
  298. package/server/serverHelpers/Headers.ts +108 -0
  299. package/server/serverHelpers/JSONStream.ts +269 -0
  300. package/server/serverHelpers/OperationFunctionObject.ts +13 -0
  301. package/server/serverHelpers/Request.ts +158 -0
  302. package/server/serverHelpers/contentTypes.ts +637 -0
  303. package/server/serverHelpers/requestTimePlugin.js +57 -0
  304. package/server/serverHelpers/serverHandlers.js +148 -0
  305. package/server/serverHelpers/serverUtilities.ts +473 -0
  306. package/server/serverRegistry.ts +8 -0
  307. package/server/static.ts +187 -0
  308. package/server/status/definitions.ts +37 -0
  309. package/server/status/index.ts +125 -0
  310. package/server/storageReclamation.ts +93 -0
  311. package/server/threads/itc.js +89 -0
  312. package/server/threads/manageThreads.js +594 -0
  313. package/server/threads/socketRouter.ts +360 -0
  314. package/server/threads/threadServer.js +279 -0
  315. package/server/throttle.ts +73 -0
  316. package/sqlTranslator/SelectValidator.js +330 -0
  317. package/sqlTranslator/alasqlFunctionImporter.js +62 -0
  318. package/sqlTranslator/deleteTranslator.js +67 -0
  319. package/sqlTranslator/index.js +242 -0
  320. package/sqlTranslator/sql_statement_bucket.js +472 -0
  321. package/static/defaultConfig.yaml +3 -0
  322. package/studio/web/HDBDogOnly.svg +78 -0
  323. package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
  324. package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
  325. package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
  326. package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
  327. package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
  328. package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
  329. package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
  330. package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
  331. package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
  332. package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
  333. package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
  334. package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
  335. package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
  336. package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
  337. package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
  338. package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
  339. package/studio/web/assets/index-BTgXJX9d.js +235 -0
  340. package/studio/web/assets/index-BTgXJX9d.js.map +1 -0
  341. package/studio/web/assets/index-C-GXfcup.js +37 -0
  342. package/studio/web/assets/index-C-GXfcup.js.map +1 -0
  343. package/studio/web/assets/index-PFlNdimM.js +2 -0
  344. package/studio/web/assets/index-PFlNdimM.js.map +1 -0
  345. package/studio/web/assets/index-Y2g_iFpU.css +1 -0
  346. package/studio/web/assets/index-jiPwkrsB.css +1 -0
  347. package/studio/web/assets/index.lazy-C3TJZJ4o.js +266 -0
  348. package/studio/web/assets/index.lazy-C3TJZJ4o.js.map +1 -0
  349. package/studio/web/assets/profiler-DotzgiCJ.js +2 -0
  350. package/studio/web/assets/profiler-DotzgiCJ.js.map +1 -0
  351. package/studio/web/assets/react-redux-VxUEx_mU.js +6 -0
  352. package/studio/web/assets/react-redux-VxUEx_mU.js.map +1 -0
  353. package/studio/web/assets/startRecording-B_9J9Csd.js +3 -0
  354. package/studio/web/assets/startRecording-B_9J9Csd.js.map +1 -0
  355. package/studio/web/fabric-signup-background.webp +0 -0
  356. package/studio/web/fabric-signup-text.png +0 -0
  357. package/studio/web/favicon_purple.png +0 -0
  358. package/studio/web/github-icon.svg +15 -0
  359. package/studio/web/harper-fabric_black.png +0 -0
  360. package/studio/web/harper-fabric_white.png +0 -0
  361. package/studio/web/harper-studio_white.png +0 -0
  362. package/studio/web/index.html +16 -0
  363. package/studio/web/running.css +148 -0
  364. package/studio/web/running.html +147 -0
  365. package/studio/web/running.js +111 -0
  366. package/upgrade/UpgradeObjects.js +13 -0
  367. package/upgrade/directives/directivesController.js +90 -0
  368. package/upgrade/directivesManager.js +139 -0
  369. package/upgrade/upgradePrompt.js +124 -0
  370. package/upgrade/upgradeUtilities.js +28 -0
  371. package/utility/AWS/AWSConnector.js +29 -0
  372. package/utility/OperationFunctionCaller.js +63 -0
  373. package/utility/assignCmdEnvVariables.js +62 -0
  374. package/utility/common_utils.js +867 -0
  375. package/utility/environment/environmentManager.js +208 -0
  376. package/utility/environment/systemInformation.js +355 -0
  377. package/utility/errors/commonErrors.js +267 -0
  378. package/utility/errors/hdbError.js +146 -0
  379. package/utility/functions/date/dateFunctions.js +65 -0
  380. package/utility/functions/geo.js +355 -0
  381. package/utility/functions/sql/alaSQLExtension.js +104 -0
  382. package/utility/globalSchema.js +35 -0
  383. package/utility/hdbTerms.ts +819 -0
  384. package/utility/install/checkJWTTokensExist.js +62 -0
  385. package/utility/install/harperdb.conf +15 -0
  386. package/utility/install/harperdb.service +14 -0
  387. package/utility/install/installer.js +635 -0
  388. package/utility/installation.ts +30 -0
  389. package/utility/lmdb/DBIDefinition.js +20 -0
  390. package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
  391. package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
  392. package/utility/lmdb/OpenDBIObject.js +31 -0
  393. package/utility/lmdb/OpenEnvironmentObject.js +41 -0
  394. package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
  395. package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
  396. package/utility/lmdb/cleanLMDBMap.js +65 -0
  397. package/utility/lmdb/commonUtility.js +119 -0
  398. package/utility/lmdb/deleteUtility.js +128 -0
  399. package/utility/lmdb/environmentUtility.js +477 -0
  400. package/utility/lmdb/searchCursorFunctions.js +187 -0
  401. package/utility/lmdb/searchUtility.js +918 -0
  402. package/utility/lmdb/terms.js +57 -0
  403. package/utility/lmdb/writeUtility.js +407 -0
  404. package/utility/logging/harper_logger.js +876 -0
  405. package/utility/logging/logRotator.js +157 -0
  406. package/utility/logging/logger.ts +24 -0
  407. package/utility/logging/readLog.js +355 -0
  408. package/utility/logging/transactionLog.js +57 -0
  409. package/utility/mount_hdb.js +59 -0
  410. package/utility/npmUtilities.js +102 -0
  411. package/utility/operationPermissions.ts +112 -0
  412. package/utility/operation_authorization.js +836 -0
  413. package/utility/packageUtils.js +55 -0
  414. package/utility/password.ts +99 -0
  415. package/utility/processManagement/processManagement.js +187 -0
  416. package/utility/processManagement/servicesConfig.js +56 -0
  417. package/utility/scripts/restartHdb.js +24 -0
  418. package/utility/scripts/user_data.sh +13 -0
  419. package/utility/signalling.js +36 -0
  420. package/utility/terms/certificates.js +81 -0
  421. package/utility/when.ts +20 -0
  422. package/v1.d.ts +39 -0
  423. package/v1.js +41 -0
  424. package/v2.d.ts +39 -0
  425. package/v2.js +41 -0
  426. package/validation/bulkDeleteValidator.js +24 -0
  427. package/validation/check_permissions.js +19 -0
  428. package/validation/common_validators.js +95 -0
  429. package/validation/configValidator.js +331 -0
  430. package/validation/deleteValidator.js +15 -0
  431. package/validation/fileLoadValidator.js +153 -0
  432. package/validation/insertValidator.js +40 -0
  433. package/validation/installValidator.js +37 -0
  434. package/validation/readLogValidator.js +64 -0
  435. package/validation/role_validation.js +320 -0
  436. package/validation/schemaMetadataValidator.js +42 -0
  437. package/validation/searchValidator.js +166 -0
  438. package/validation/statusValidator.ts +66 -0
  439. package/validation/transactionLogValidator.js +33 -0
  440. package/validation/user_validation.js +55 -0
  441. package/validation/validationWrapper.js +105 -0
  442. package/dist/resources/analytics/profile.d.ts +0 -2
  443. package/dist/resources/analytics/profile.js +0 -144
  444. package/dist/resources/analytics/profile.js.map +0 -1
@@ -0,0 +1,623 @@
1
+ /**
2
+ * CRL (Certificate Revocation List) verification
3
+ */
4
+
5
+ import * as pkijs from 'pkijs';
6
+ import { loggerWithTag } from '../../utility/logging/logger.ts';
7
+ import { table } from '../../resources/databases.ts';
8
+ import { Resource } from '../../resources/Resource.ts';
9
+ import type { SourceContext } from '../../resources/ResourceInterface.ts';
10
+ import {
11
+ extractCRLDistributionPoints,
12
+ extractSerialNumber,
13
+ extractIssuerKeyId,
14
+ createRevokedCertificateId,
15
+ bufferToPem,
16
+ createCacheKey,
17
+ getCertificateCacheTable as getSharedCertificateCacheTable,
18
+ pemToBuffer,
19
+ } from './verificationUtils.ts';
20
+ import { ERROR_CACHE_TTL, CRL_DEFAULT_VALIDITY_PERIOD, CRL_USER_AGENT } from './verificationConfig.ts';
21
+ import type {
22
+ CertificateVerificationResult,
23
+ CertificateVerificationContext,
24
+ CertificateCacheEntry,
25
+ CRLCheckResult,
26
+ CRLConfig,
27
+ CRLVerificationContext,
28
+ CRLCacheEntry,
29
+ RevokedCertificateEntry,
30
+ } from './types.ts';
31
+
32
+ /**
33
+ * Custom error for CRL signature verification failures
34
+ * This distinguishes security failures (invalid signatures) from operational failures (network, timeout)
35
+ */
36
+ export class CRLSignatureVerificationError extends Error {
37
+ constructor(message: string) {
38
+ super(message);
39
+ this.name = 'CRLSignatureVerificationError';
40
+ }
41
+ }
42
+ import { CertificateVerificationSource } from './certificateVerificationSource.ts';
43
+
44
+ const logger = loggerWithTag('crl-verification');
45
+
46
+ // Lazy-load the certificate verification cache table with CRL source configured
47
+ let certCacheTable: ReturnType<typeof getSharedCertificateCacheTable>;
48
+ function getCertificateCacheTable() {
49
+ if (!certCacheTable) {
50
+ certCacheTable = getSharedCertificateCacheTable();
51
+ // Configure the caching source using the shared CertificateVerificationSource class
52
+ (certCacheTable as any).sourcedFrom(CertificateVerificationSource);
53
+ }
54
+ return certCacheTable;
55
+ }
56
+
57
+ /**
58
+ * CRL fetching and validation source
59
+ */
60
+ class CertificateRevocationListSource extends Resource {
61
+ async get(id: string) {
62
+ const context = this.getContext() as SourceContext<CRLVerificationContext>;
63
+ const requestContext = context?.requestContext;
64
+
65
+ if (!requestContext?.distributionPoint || !requestContext?.issuerPem) {
66
+ throw new Error(`No CRL data provided for cache key: ${id}`);
67
+ }
68
+
69
+ const { distributionPoint, issuerPem: issuerPemStr, config } = requestContext;
70
+
71
+ try {
72
+ const result = await downloadAndParseCRL(distributionPoint, issuerPemStr, config.timeout);
73
+
74
+ // Set expiration - use the CRL's nextUpdate time or configured TTL, whichever is sooner
75
+ const crlExpiry = result.next_update;
76
+ const configExpiry = Date.now() + config.cacheTtl;
77
+ const expiresAt = Math.min(crlExpiry, configExpiry);
78
+
79
+ return {
80
+ ...result,
81
+ expiresAt,
82
+ };
83
+ } catch (error) {
84
+ logger.error?.(`CRL fetch error for: ${distributionPoint} - ${error}`);
85
+
86
+ // Check failure mode
87
+ if (config.failureMode === 'fail-closed') {
88
+ // Cache the error for faster recovery
89
+ const expiresAt = Date.now() + ERROR_CACHE_TTL;
90
+
91
+ return {
92
+ crl_id: id,
93
+ distribution_point: distributionPoint,
94
+ issuer_dn: 'unknown',
95
+ crl_blob: Buffer.alloc(0),
96
+ this_update: Date.now(),
97
+ next_update: expiresAt,
98
+ signature_valid: false,
99
+ expiresAt,
100
+ };
101
+ }
102
+
103
+ // Fail open - return null to not cache
104
+ logger.warn?.('CRL fetch failed, not caching (fail-open mode)');
105
+ return null;
106
+ }
107
+ }
108
+ }
109
+
110
+ // Lazy-load Harper tables
111
+ let crlCacheTable: ReturnType<typeof table>;
112
+ let revokedCertificateTable: ReturnType<typeof table>;
113
+
114
+ function getCRLCacheTable() {
115
+ if (!crlCacheTable) {
116
+ crlCacheTable = table({
117
+ table: 'hdb_crl_cache',
118
+ database: 'system',
119
+ attributes: [
120
+ {
121
+ name: 'distribution_point',
122
+ isPrimaryKey: true,
123
+ },
124
+ {
125
+ name: 'issuer_dn',
126
+ },
127
+ {
128
+ name: 'crl_blob',
129
+ },
130
+ {
131
+ name: 'this_update',
132
+ },
133
+ {
134
+ name: 'next_update',
135
+ },
136
+ {
137
+ name: 'signature_valid',
138
+ },
139
+ {
140
+ name: 'expiresAt',
141
+ expiresAt: true,
142
+ indexed: true,
143
+ },
144
+ ],
145
+ });
146
+
147
+ // Configure the caching source
148
+ (crlCacheTable as any).sourcedFrom(CertificateRevocationListSource);
149
+ }
150
+ return crlCacheTable;
151
+ }
152
+
153
+ function getRevokedCertificateTable() {
154
+ if (!revokedCertificateTable) {
155
+ revokedCertificateTable = table({
156
+ table: 'hdb_revoked_certificates',
157
+ database: 'system',
158
+ attributes: [
159
+ {
160
+ name: 'composite_id',
161
+ isPrimaryKey: true,
162
+ },
163
+ {
164
+ name: 'serial_number',
165
+ indexed: true,
166
+ },
167
+ {
168
+ name: 'issuer_key_id',
169
+ indexed: true,
170
+ },
171
+ {
172
+ name: 'revocation_date',
173
+ },
174
+ {
175
+ name: 'revocation_reason',
176
+ },
177
+ {
178
+ name: 'crl_source',
179
+ indexed: true, // Links to CRL cache
180
+ },
181
+ {
182
+ name: 'crl_next_update',
183
+ },
184
+ {
185
+ name: 'expiresAt',
186
+ expiresAt: true,
187
+ indexed: true,
188
+ },
189
+ ],
190
+ });
191
+ }
192
+ return revokedCertificateTable;
193
+ }
194
+
195
+ /**
196
+ * Verify CRL status of a client certificate
197
+ * @param certPem - Client certificate as Buffer (DER format)
198
+ * @param issuerPem - Issuer (CA) certificate as Buffer (DER format)
199
+ * @param config - CRL configuration
200
+ * @param crlUrls - Optional pre-extracted CRL distribution point URLs (avoids re-parsing)
201
+ * @returns Promise resolving to verification result
202
+ */
203
+ export async function verifyCRL(
204
+ certPem: Buffer,
205
+ issuerPem: Buffer,
206
+ config?: CRLConfig,
207
+ crlUrls?: string[]
208
+ ): Promise<CertificateVerificationResult> {
209
+ // Check if CRL verification is disabled
210
+ if (config?.enabled === false) {
211
+ return { valid: true, status: 'disabled', method: 'disabled' };
212
+ }
213
+
214
+ try {
215
+ // Convert DER buffers to PEM strings for certificate parsing libraries
216
+ // PKI.js and other certificate utilities expect PEM format for extension extraction
217
+ const certPemStr = bufferToPem(certPem, 'CERTIFICATE');
218
+ const issuerPemStr = bufferToPem(issuerPem, 'CERTIFICATE');
219
+
220
+ // Extract CRL distribution points from the certificate (if not already provided)
221
+ const distributionPoints = crlUrls ?? extractCRLDistributionPoints(certPemStr);
222
+
223
+ if (distributionPoints.length === 0) {
224
+ return { valid: true, status: 'no-crl-distribution-points', method: 'crl' };
225
+ }
226
+
227
+ // Create a cache key that includes all verification parameters
228
+ const cacheKey = createCacheKey(certPemStr, issuerPemStr, 'crl');
229
+
230
+ // Pass certificate data as context - Harper will make it available as requestContext in the source
231
+ const cacheEntry = await (getCertificateCacheTable() as any).get(cacheKey, {
232
+ certPem: certPemStr,
233
+ issuerPem: issuerPemStr,
234
+ distributionPoint: distributionPoints[0], // Use first distribution point for CRL fetch
235
+ config: { crl: config ?? {} },
236
+ } as CertificateVerificationContext);
237
+
238
+ if (!cacheEntry) {
239
+ // This should not happen if the source is configured correctly but handle it gracefully
240
+ logger.error?.('Cache fetch returned null - this indicates a source configuration issue');
241
+ if (config.failureMode === 'fail-closed') {
242
+ return { valid: false, status: 'error', error: 'Cache fetch failed', method: 'crl' };
243
+ }
244
+
245
+ logger.warn?.('CRL cache fetch failed, allowing connection (fail-open mode)');
246
+ return { valid: true, status: 'error-allowed', method: 'crl' };
247
+ }
248
+
249
+ const cached = cacheEntry as unknown as CertificateCacheEntry;
250
+ const wasLoadedFromSource = (cacheEntry as any).wasLoadedFromSource?.();
251
+ logger.trace?.(`CRL ${wasLoadedFromSource ? 'source fetch' : 'cache hit'} for certificate`);
252
+
253
+ return {
254
+ valid: cached.status === 'good',
255
+ status: cached.status,
256
+ cached: !wasLoadedFromSource,
257
+ method: cached.method || 'crl',
258
+ };
259
+ } catch (error) {
260
+ logger.error?.(`CRL verification error: ${error}`);
261
+
262
+ // Check failure mode
263
+ if (config.failureMode === 'fail-closed') {
264
+ return { valid: false, status: 'error', error: (error as Error).message, method: 'crl' };
265
+ }
266
+
267
+ // Fail open - allow connection on CRL errors
268
+ logger.warn?.('CRL check failed, allowing connection (fail-open mode)');
269
+ return { valid: true, status: 'error-allowed', method: 'crl' };
270
+ }
271
+ }
272
+
273
+ /**
274
+ * Perform the actual CRL check by looking up the certificate in the revoked certificates table
275
+ * @param certPem - Certificate in PEM format
276
+ * @param issuerPem - Issuer certificate in PEM format
277
+ * @param config - CRL configuration
278
+ * @param crlUrls - Optional pre-extracted CRL distribution point URLs (avoids re-parsing)
279
+ * @returns CRL check result
280
+ */
281
+ export async function performCRLCheck(
282
+ certPem: string,
283
+ issuerPem: string,
284
+ config: CRLConfig,
285
+ crlUrls?: string[]
286
+ ): Promise<CRLCheckResult> {
287
+ // Extract CRL distribution points from the certificate (if not already provided)
288
+ const distributionPoints = crlUrls ?? extractCRLDistributionPoints(certPem);
289
+
290
+ if (distributionPoints.length === 0) {
291
+ return { status: 'good' };
292
+ }
293
+
294
+ // Extract certificate identifiers for lookup
295
+ const serialNumber = extractSerialNumber(certPem);
296
+ const issuerKeyId = extractIssuerKeyId(issuerPem);
297
+ const compositeId = createRevokedCertificateId(issuerKeyId, serialNumber);
298
+
299
+ try {
300
+ // Get the revoked certificates table
301
+ const revokedTable = getRevokedCertificateTable();
302
+
303
+ // Look up the certificate in the revoked list
304
+ const revokedEntry = await (revokedTable as any).get(compositeId);
305
+
306
+ if (revokedEntry) {
307
+ // Check if CRL data is still valid (within grace period if expired)
308
+ const now = Date.now();
309
+
310
+ const entry = revokedEntry as any;
311
+ if (entry.crl_next_update > now) {
312
+ // CRL is still valid
313
+ return {
314
+ status: 'revoked',
315
+ reason: entry.revocation_reason || 'unspecified',
316
+ source: entry.crl_source,
317
+ };
318
+ } else if (entry.crl_next_update + config.gracePeriod > now) {
319
+ // CRL is expired but within grace period
320
+ logger.warn?.('Using expired CRL data within grace period');
321
+ return {
322
+ status: 'revoked',
323
+ reason: entry.revocation_reason || 'unspecified',
324
+ source: entry.crl_source,
325
+ };
326
+ } else {
327
+ // CRL is too old, treat as unknown
328
+ logger.warn?.('CRL data is too old, treating as unknown');
329
+ return {
330
+ status: 'unknown',
331
+ reason: 'crl-expired',
332
+ };
333
+ }
334
+ }
335
+
336
+ // Certificate not found in revocation list - check if we have current CRL data
337
+ // This requires checking if CRLs for the distribution points are up to date
338
+ const crlStatus = await checkCRLFreshness(distributionPoints, issuerPem, config);
339
+
340
+ if (crlStatus.upToDate) {
341
+ // We have current CRL data and certificate is not in it
342
+ return {
343
+ status: 'good',
344
+ source: crlStatus.source,
345
+ };
346
+ } else {
347
+ // CRL data is stale or missing
348
+ logger.warn?.('CRL data is stale or missing, treating as unknown');
349
+ return {
350
+ status: 'unknown',
351
+ reason: crlStatus.reason || 'crl-unavailable',
352
+ };
353
+ }
354
+ } catch (error) {
355
+ logger.error?.(`CRL lookup error: ${error}`);
356
+ return {
357
+ status: 'unknown',
358
+ reason: (error as Error).message,
359
+ };
360
+ }
361
+ }
362
+
363
+ /**
364
+ * Check if CRL data is fresh for the given distribution points, and fetch if needed
365
+ * @param distributionPoints - Array of CRL distribution point URLs
366
+ * @param issuerPem - Issuer certificate for CRL signature verification
367
+ * @param config - CRL configuration
368
+ * @returns Status of CRL freshness
369
+ */
370
+ async function checkCRLFreshness(
371
+ distributionPoints: string[],
372
+ issuerPem: string,
373
+ config: CRLConfig
374
+ ): Promise<{ upToDate: boolean; reason?: string; source?: string }> {
375
+ const now = Date.now();
376
+
377
+ // Check each distribution point
378
+ for (const distributionPoint of distributionPoints) {
379
+ try {
380
+ // First, check if we have a cached CRL that's still valid
381
+ const crlTable = getCRLCacheTable();
382
+ let crlData: CRLCacheEntry | null = null;
383
+ let cachedCRL: CRLCacheEntry | null = null;
384
+
385
+ try {
386
+ const cached = await (crlTable as any).get(distributionPoint);
387
+ cachedCRL = cached as unknown as CRLCacheEntry;
388
+ if (cachedCRL && cachedCRL.next_update > now) {
389
+ crlData = cachedCRL;
390
+ } else if (cachedCRL && cachedCRL.next_update + config.gracePeriod > now) {
391
+ crlData = cachedCRL;
392
+ }
393
+ } catch {
394
+ // Failed to check cache, continue
395
+ }
396
+
397
+ // If no valid cached CRL, download and parse fresh
398
+ if (!crlData) {
399
+ crlData = await downloadAndParseCRL(distributionPoint, issuerPem, config.timeout);
400
+ }
401
+
402
+ // Check if CRL is current
403
+ const crlExpiry = crlData.next_update;
404
+ if (crlExpiry > now) {
405
+ // Store in cache for future use (only if we downloaded it fresh)
406
+ if (!cachedCRL) {
407
+ try {
408
+ await (crlTable as any).put(distributionPoint, crlData);
409
+ } catch {
410
+ // Failed to cache, but continue anyway
411
+ }
412
+ }
413
+
414
+ return { upToDate: true, source: distributionPoint };
415
+ } else if (crlExpiry + config.gracePeriod > now) {
416
+ return { upToDate: true, source: distributionPoint };
417
+ } else {
418
+ return { upToDate: false, reason: 'crl-expired' };
419
+ }
420
+ } catch (error) {
421
+ // Signature verification failures are security failures, not operational failures
422
+ // Rethrow them so they don't get swallowed as "unknown" status
423
+ if (error instanceof CRLSignatureVerificationError) {
424
+ throw error;
425
+ }
426
+ // Operational failures (network, timeout, parse errors) - continue to next distribution point
427
+ }
428
+ }
429
+
430
+ return { upToDate: false, reason: 'no-current-crl-data' };
431
+ }
432
+
433
+ /**
434
+ * Download and parse a CRL from a distribution point
435
+ * @param distributionPoint - CRL URL
436
+ * @param issuerPemStr - Issuer certificate for signature verification
437
+ * @param timeout - Download timeout in milliseconds
438
+ * @returns Parsed CRL entry for caching
439
+ */
440
+ async function downloadAndParseCRL(
441
+ distributionPoint: string,
442
+ issuerPemStr: string,
443
+ timeout: number
444
+ ): Promise<CRLCacheEntry> {
445
+ // Download the CRL
446
+ // Note: Using fetch here since CRL downloads are cached and infrequent
447
+ // (typically one per CA), so this is not a hot path
448
+ const controller = new AbortController();
449
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
450
+
451
+ try {
452
+ const response = await fetch(distributionPoint, {
453
+ signal: controller.signal,
454
+ headers: {
455
+ 'User-Agent': CRL_USER_AGENT,
456
+ },
457
+ });
458
+
459
+ clearTimeout(timeoutId);
460
+
461
+ if (!response.ok) {
462
+ throw new Error(`CRL download failed: ${response.status}`);
463
+ }
464
+
465
+ const crlBuffer = Buffer.from(await response.arrayBuffer());
466
+
467
+ // Convert PEM to DER format if needed (PKI.js expects DER)
468
+ let crlDerBuffer: Buffer;
469
+ const crlText = crlBuffer.toString('utf8');
470
+ if (crlText.includes('-----BEGIN X509 CRL-----')) {
471
+ crlDerBuffer = Buffer.from(pemToBuffer(crlText));
472
+ } else {
473
+ crlDerBuffer = crlBuffer;
474
+ }
475
+
476
+ // Parse and validate the CRL
477
+ const crl = pkijs.CertificateRevocationList.fromBER(crlDerBuffer);
478
+
479
+ // Verify CRL signature
480
+ const issuerCert = pkijs.Certificate.fromBER(pemToBuffer(issuerPemStr));
481
+ const signatureValid = await crl.verify({ issuerCertificate: issuerCert });
482
+
483
+ if (!signatureValid) {
484
+ // Invalid signature is a security failure - always reject regardless of fail-open/fail-closed mode
485
+ // Fail-open mode is for operational failures (network issues, timeouts), not security validation failures
486
+ const msg = `CRL signature verification failed for: ${distributionPoint}`;
487
+ logger.error?.(msg);
488
+ throw new CRLSignatureVerificationError(msg);
489
+ }
490
+
491
+ // Extract timing information
492
+ const thisUpdate = crl.thisUpdate.value.getTime();
493
+ const nextUpdate = crl.nextUpdate?.value.getTime() ?? thisUpdate + CRL_DEFAULT_VALIDITY_PERIOD;
494
+
495
+ // Extract issuer DN
496
+ const issuerDN = issuerCert.issuer.typesAndValues.map((tv) => `${tv.type}=${tv.value.valueBlock.value}`).join(',');
497
+
498
+ const cacheEntry: CRLCacheEntry = {
499
+ distribution_point: distributionPoint,
500
+ issuer_dn: issuerDN,
501
+ crl_blob: crlBuffer,
502
+ this_update: thisUpdate,
503
+ next_update: nextUpdate,
504
+ signature_valid: signatureValid,
505
+ expiresAt: nextUpdate,
506
+ };
507
+
508
+ // Process revoked certificates in the background
509
+ processRevokedCertificates(crl, issuerPemStr, distributionPoint, nextUpdate).catch((error) => {
510
+ logger.error?.(`Error processing revoked certificates: ${error}`);
511
+ });
512
+
513
+ return cacheEntry;
514
+ } finally {
515
+ clearTimeout(timeoutId);
516
+ }
517
+ }
518
+
519
+ /**
520
+ * Process revoked certificates from CRL and store them in the revoked certificates table
521
+ * @param crl - Parsed CRL object
522
+ * @param issuerPemStr - Issuer certificate PEM
523
+ * @param distributionPoint - CRL distribution point URL
524
+ * @param nextUpdate - When this CRL expires
525
+ */
526
+ async function processRevokedCertificates(
527
+ crl: pkijs.CertificateRevocationList,
528
+ issuerPemStr: string,
529
+ distributionPoint: string,
530
+ nextUpdate: number
531
+ ): Promise<void> {
532
+ const revokedTable = getRevokedCertificateTable();
533
+ const issuerKeyId = extractIssuerKeyId(issuerPemStr);
534
+ const cacheKey = distributionPoint;
535
+
536
+ // Clear existing entries for this CRL to ensure data consistency
537
+ // This prevents stale revocation data when certificates are removed from updated CRLs
538
+ try {
539
+ await clearExistingCRLEntries(revokedTable, cacheKey);
540
+ } catch (error) {
541
+ logger.warn?.(`Failed to clear existing CRL entries: ${error}`);
542
+ // Continue with processing - partial cleanup is better than no update
543
+ }
544
+
545
+ // Add new revoked certificates
546
+ if (crl.revokedCertificates) {
547
+ for (const revokedCert of crl.revokedCertificates) {
548
+ try {
549
+ // Extract serial number using PKI.js - same method as extractSerialNumber() function
550
+ // This gives us the clean serial number without ASN.1 encoding
551
+ const serialHex = revokedCert.userCertificate.valueBlock.valueHexView;
552
+
553
+ if (!serialHex) {
554
+ logger.warn?.('Could not extract serial number from revoked certificate');
555
+ continue;
556
+ }
557
+
558
+ const serialNumber = Array.from(serialHex)
559
+ .map((b) => b.toString(16).padStart(2, '0'))
560
+ .join('');
561
+
562
+ const compositeId = createRevokedCertificateId(issuerKeyId, serialNumber);
563
+
564
+ // Extract revocation date
565
+ const revocationDate = revokedCert.revocationDate.value.getTime();
566
+
567
+ // For now, skip complex extension parsing and just use default reason
568
+ const revocationReason = 'unspecified';
569
+
570
+ const entry: RevokedCertificateEntry = {
571
+ composite_id: compositeId,
572
+ serial_number: serialNumber,
573
+ issuer_key_id: issuerKeyId,
574
+ revocation_date: revocationDate,
575
+ revocation_reason: revocationReason,
576
+ crl_source: cacheKey,
577
+ crl_next_update: nextUpdate,
578
+ expiresAt: nextUpdate,
579
+ };
580
+
581
+ await (revokedTable as any).create(entry.composite_id, entry);
582
+ } catch (error) {
583
+ logger.warn?.(`Failed to process revoked certificate: ${error}`);
584
+ // Continue with other certificates
585
+ }
586
+ }
587
+ }
588
+ }
589
+
590
+ /**
591
+ * Clear existing revoked certificate entries for a specific CRL source
592
+ * This ensures data consistency when CRLs are updated and certificates are removed
593
+ * @param revokedTable - Harper table for revoked certificates
594
+ * @param crlSource - CRL cache key to identify entries to remove
595
+ */
596
+ async function clearExistingCRLEntries(
597
+ revokedTable: ReturnType<typeof getRevokedCertificateTable>,
598
+ crlSource: string
599
+ ): Promise<void> {
600
+ // We need to find all entries with the matching crl_source and delete them individually
601
+ try {
602
+ // Use Harper's search capabilities to find entries by crl_source
603
+ // Note: This assumes the crl_source field is indexed (which it is)
604
+ const existingEntries = (revokedTable as any).search([
605
+ {
606
+ attribute: 'crl_source',
607
+ value: crlSource,
608
+ },
609
+ ]);
610
+
611
+ for await (const entry of existingEntries) {
612
+ try {
613
+ await (revokedTable as any).delete((entry as any).composite_id);
614
+ } catch (deleteError) {
615
+ logger.warn?.(`Failed to delete revoked certificate entry: ${deleteError}`);
616
+ // Continue with other entries
617
+ }
618
+ }
619
+ } catch (searchError) {
620
+ logger.error?.(`Failed to search for existing CRL entries: ${searchError}`);
621
+ throw searchError;
622
+ }
623
+ }