@oneuptime/common 12.0.2 → 12.0.4

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 (384) hide show
  1. package/Models/DatabaseModels/CephCluster.ts +14 -0
  2. package/Models/DatabaseModels/CodeRepository.ts +14 -6
  3. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
  4. package/Models/DatabaseModels/DockerHost.ts +14 -0
  5. package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
  6. package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
  7. package/Models/DatabaseModels/Index.ts +2 -0
  8. package/Models/DatabaseModels/IoTFleet.ts +14 -0
  9. package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
  10. package/Models/DatabaseModels/LogDropFilter.ts +9 -20
  11. package/Models/DatabaseModels/NetworkDevice.ts +14 -0
  12. package/Models/DatabaseModels/NetworkInterface.ts +18 -0
  13. package/Models/DatabaseModels/Project.ts +16 -2
  14. package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
  15. package/Models/DatabaseModels/Service.ts +30 -0
  16. package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
  17. package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
  18. package/Models/DatabaseModels/StatusPageResource.ts +73 -0
  19. package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
  20. package/Models/DatabaseModels/User.ts +30 -0
  21. package/Server/API/AIAgentDataAPI.ts +31 -0
  22. package/Server/API/BaseAPI.ts +13 -2
  23. package/Server/API/DashboardAPI.ts +458 -12
  24. package/Server/API/GitHubAPI.ts +119 -283
  25. package/Server/API/UserAPI.ts +263 -1
  26. package/Server/EnvironmentConfig.ts +38 -4
  27. package/Server/Infrastructure/GlobalCache.ts +152 -0
  28. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  36. package/Server/Services/AlertStateTimelineService.ts +20 -0
  37. package/Server/Services/AnalyticsDatabaseService.ts +72 -1
  38. package/Server/Services/CephClusterService.ts +26 -86
  39. package/Server/Services/CloudResourceService.ts +23 -83
  40. package/Server/Services/CodeRepositoryService.ts +105 -2
  41. package/Server/Services/DatabaseService.ts +296 -2
  42. package/Server/Services/DockerHostService.ts +19 -79
  43. package/Server/Services/DockerSwarmClusterService.ts +27 -88
  44. package/Server/Services/HostService.ts +46 -99
  45. package/Server/Services/IncidentStateTimelineService.ts +20 -0
  46. package/Server/Services/Index.ts +2 -0
  47. package/Server/Services/IoTFleetService.ts +19 -79
  48. package/Server/Services/KubernetesClusterService.ts +17 -78
  49. package/Server/Services/LabelService.ts +57 -10
  50. package/Server/Services/MetricTypeService.ts +84 -0
  51. package/Server/Services/MonitorService.ts +89 -14
  52. package/Server/Services/MonitorStatusTimelineService.ts +29 -0
  53. package/Server/Services/MonitorTemplateService.ts +65 -0
  54. package/Server/Services/OpenTelemetryIngestService.ts +230 -26
  55. package/Server/Services/PodmanHostService.ts +19 -79
  56. package/Server/Services/ProxmoxClusterService.ts +23 -83
  57. package/Server/Services/RumApplicationService.ts +19 -80
  58. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
  59. package/Server/Services/ServerlessFunctionService.ts +24 -85
  60. package/Server/Services/ServiceService.ts +299 -73
  61. package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
  62. package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
  63. package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
  64. package/Server/Services/TelemetryEntityService.ts +1 -0
  65. package/Server/Services/UserService.ts +184 -0
  66. package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
  67. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
  68. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
  69. package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
  70. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
  71. package/Server/Utils/Monitor/MonitorResource.ts +63 -36
  72. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
  73. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
  74. package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
  75. package/Server/Utils/PasswordHash.ts +306 -0
  76. package/Server/Utils/SingleFlight.ts +83 -0
  77. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
  78. package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
  79. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
  80. package/Server/Utils/Telemetry/Telemetry.ts +351 -122
  81. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
  82. package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
  83. package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
  84. package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
  85. package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
  86. package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
  87. package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
  88. package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
  89. package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
  90. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
  91. package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
  92. package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
  93. package/Tests/Server/API/Helpers.ts +6 -1
  94. package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
  95. package/Tests/Server/Infrastructure/GlobalCache.test.ts +354 -0
  96. package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
  97. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
  98. package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
  99. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
  100. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +5 -0
  101. package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
  102. package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
  103. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +870 -0
  104. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
  105. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
  106. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +163 -15
  107. package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
  108. package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
  109. package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
  110. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
  111. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +305 -56
  112. package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
  113. package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
  114. package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
  115. package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
  116. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
  117. package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
  118. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
  119. package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
  120. package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
  121. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
  122. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
  123. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
  124. package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
  125. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
  126. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
  127. package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
  128. package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
  129. package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
  130. package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
  131. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
  132. package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
  133. package/Tests/Server/Utils/PasswordHash.test.ts +555 -0
  134. package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
  135. package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
  136. package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
  137. package/Tests/Types/Database/ColumnLength.test.ts +7 -1
  138. package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
  139. package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
  140. package/Tests/Types/Decimal.test.ts +37 -0
  141. package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
  142. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
  143. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
  144. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
  145. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
  146. package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
  147. package/Tests/Types/Port.test.ts +38 -0
  148. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
  149. package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
  150. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
  151. package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
  152. package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
  153. package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
  154. package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
  155. package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
  156. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  157. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  158. package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
  159. package/Types/Dashboard/DashboardTemplates.ts +397 -0
  160. package/Types/Database/BigIntColumnTransformer.ts +74 -0
  161. package/Types/Database/ColumnLength.ts +9 -1
  162. package/Types/Database/DatabaseProperty.ts +26 -0
  163. package/Types/Database/NumericColumnValue.ts +128 -0
  164. package/Types/Database/TableColumn.ts +11 -0
  165. package/Types/Database/UnsynchronizedIndex.ts +48 -0
  166. package/Types/Decimal.ts +16 -4
  167. package/Types/HashedString.ts +139 -4
  168. package/Types/Permission.ts +48 -0
  169. package/Types/Port.ts +16 -4
  170. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
  171. package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
  172. package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
  173. package/UI/Components/Navbar/NavBar.tsx +12 -2
  174. package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
  175. package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
  176. package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
  177. package/Utils/Dashboard/Components/Index.ts +7 -0
  178. package/Utils/TeamMembersByProject.ts +237 -0
  179. package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
  180. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
  182. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
  184. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
  186. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  187. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
  188. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  189. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
  190. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  191. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  192. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  193. package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
  194. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  195. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
  196. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  197. package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
  198. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  199. package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
  200. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  201. package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
  202. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  203. package/build/dist/Models/DatabaseModels/Project.js +16 -2
  204. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  205. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
  206. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/Service.js +28 -1
  208. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  209. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
  210. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
  211. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
  212. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
  214. package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
  216. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/User.js +32 -0
  218. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  219. package/build/dist/Server/API/AIAgentDataAPI.js +21 -2
  220. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  221. package/build/dist/Server/API/BaseAPI.js +11 -1
  222. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  223. package/build/dist/Server/API/DashboardAPI.js +343 -10
  224. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  225. package/build/dist/Server/API/GitHubAPI.js +94 -167
  226. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  227. package/build/dist/Server/API/UserAPI.js +187 -2
  228. package/build/dist/Server/API/UserAPI.js.map +1 -1
  229. package/build/dist/Server/EnvironmentConfig.js +34 -4
  230. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  231. package/build/dist/Server/Infrastructure/GlobalCache.js +120 -0
  232. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
  234. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  249. package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
  250. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  251. package/build/dist/Server/Services/AnalyticsDatabaseService.js +57 -1
  252. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  253. package/build/dist/Server/Services/CephClusterService.js +26 -76
  254. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  255. package/build/dist/Server/Services/CloudResourceService.js +23 -73
  256. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  257. package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
  258. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  259. package/build/dist/Server/Services/DatabaseService.js +246 -2
  260. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  261. package/build/dist/Server/Services/DockerHostService.js +19 -69
  262. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  263. package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -78
  264. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  265. package/build/dist/Server/Services/HostService.js +58 -102
  266. package/build/dist/Server/Services/HostService.js.map +1 -1
  267. package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
  268. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  269. package/build/dist/Server/Services/Index.js +2 -0
  270. package/build/dist/Server/Services/Index.js.map +1 -1
  271. package/build/dist/Server/Services/IoTFleetService.js +19 -69
  272. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  273. package/build/dist/Server/Services/KubernetesClusterService.js +17 -68
  274. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  275. package/build/dist/Server/Services/LabelService.js +42 -7
  276. package/build/dist/Server/Services/LabelService.js.map +1 -1
  277. package/build/dist/Server/Services/MetricTypeService.js +74 -0
  278. package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
  279. package/build/dist/Server/Services/MonitorService.js +81 -9
  280. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  281. package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
  282. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  283. package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
  284. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  285. package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
  286. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  287. package/build/dist/Server/Services/PodmanHostService.js +19 -69
  288. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  289. package/build/dist/Server/Services/ProxmoxClusterService.js +23 -73
  290. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  291. package/build/dist/Server/Services/RumApplicationService.js +19 -70
  292. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  293. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
  294. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  295. package/build/dist/Server/Services/ServerlessFunctionService.js +24 -75
  296. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  297. package/build/dist/Server/Services/ServiceService.js +236 -61
  298. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  299. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
  300. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
  301. package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
  302. package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
  303. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
  304. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  305. package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
  306. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  307. package/build/dist/Server/Services/UserService.js +165 -0
  308. package/build/dist/Server/Services/UserService.js.map +1 -1
  309. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
  310. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
  311. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
  312. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  313. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
  314. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  315. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
  316. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
  317. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
  318. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  319. package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
  320. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  321. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
  322. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
  323. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
  324. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  325. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
  326. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
  327. package/build/dist/Server/Utils/PasswordHash.js +237 -0
  328. package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
  329. package/build/dist/Server/Utils/SingleFlight.js +76 -0
  330. package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
  331. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
  332. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
  333. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
  334. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  335. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
  336. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
  337. package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
  338. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  339. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  340. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  341. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  342. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  343. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js +2 -0
  344. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
  345. package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
  346. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  347. package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
  348. package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
  349. package/build/dist/Types/Database/ColumnLength.js +9 -1
  350. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  351. package/build/dist/Types/Database/DatabaseProperty.js +25 -0
  352. package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
  353. package/build/dist/Types/Database/NumericColumnValue.js +97 -0
  354. package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
  355. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  356. package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
  357. package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
  358. package/build/dist/Types/Decimal.js +14 -3
  359. package/build/dist/Types/Decimal.js.map +1 -1
  360. package/build/dist/Types/HashedString.js +95 -5
  361. package/build/dist/Types/HashedString.js.map +1 -1
  362. package/build/dist/Types/Permission.js +42 -0
  363. package/build/dist/Types/Permission.js.map +1 -1
  364. package/build/dist/Types/Port.js +15 -5
  365. package/build/dist/Types/Port.js.map +1 -1
  366. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
  367. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  368. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
  369. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
  370. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
  371. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
  372. package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
  373. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  374. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
  375. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  376. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
  377. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
  378. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
  379. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
  380. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  381. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  382. package/build/dist/Utils/TeamMembersByProject.js +145 -0
  383. package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
  384. package/package.json +1 -1
@@ -0,0 +1,312 @@
1
+ import MonitorSteps from "../../../Types/Monitor/MonitorSteps";
2
+ import ObjectID from "../../../Types/ObjectID";
3
+ import Typeof from "../../../Types/Typeof";
4
+ /*
5
+ * `monitorSteps` is a free-form JSON column, so none of the ids it embeds have
6
+ * a foreign key behind them. They are still real references: the monitor status
7
+ * a criteria switches to, the severity it opens incidents and alerts with, the
8
+ * on-call policies it pages, the labels/owners it stamps on what it creates.
9
+ *
10
+ * Until issue #3039 the only guard over this blob scraped every uuid out of the
11
+ * serialized JSON with a regex and asked whether it happened to be another
12
+ * project's record. That can never reject an id that exists nowhere, because
13
+ * monitorSteps is FULL of uuids that are not references at all — step ids,
14
+ * criteria ids, incident/alert template ids — and they match nothing either.
15
+ *
16
+ * This walker exists to tell those apart. It reads the structure rather than the
17
+ * text, so every id it yields is known to be a reference to a specific model and
18
+ * can be checked for existence without any risk of a false rejection.
19
+ */
20
+ export var MonitorStepsReferenceModel;
21
+ (function (MonitorStepsReferenceModel) {
22
+ MonitorStepsReferenceModel["MonitorStatus"] = "Monitor Status";
23
+ MonitorStepsReferenceModel["IncidentSeverity"] = "Incident Severity";
24
+ MonitorStepsReferenceModel["AlertSeverity"] = "Alert Severity";
25
+ MonitorStepsReferenceModel["OnCallDutyPolicy"] = "On-Call Duty Policy";
26
+ MonitorStepsReferenceModel["Label"] = "Label";
27
+ MonitorStepsReferenceModel["Team"] = "Team";
28
+ MonitorStepsReferenceModel["User"] = "User";
29
+ MonitorStepsReferenceModel["IncidentRole"] = "Incident Role";
30
+ MonitorStepsReferenceModel["TelemetryService"] = "Telemetry Service";
31
+ MonitorStepsReferenceModel["NetworkDevice"] = "Network Device";
32
+ })(MonitorStepsReferenceModel || (MonitorStepsReferenceModel = {}));
33
+ /*
34
+ * Step-level sub-configs that scope a monitor to specific telemetry services.
35
+ * All five carry the field under the same name.
36
+ */
37
+ const TELEMETRY_SERVICE_STEP_FIELDS = [
38
+ "logMonitor",
39
+ "traceMonitor",
40
+ "exceptionMonitor",
41
+ "profileMonitor",
42
+ "metricMonitor",
43
+ ];
44
+ /*
45
+ * Every level of monitorSteps is persisted inside a `{ _type, value }` envelope
46
+ * (MonitorSteps.toJSON -> MonitorStep.toJSON -> MonitorCriteria.toJSON ->
47
+ * MonitorCriteriaInstance.toJSON). API callers - Terraform among them - post
48
+ * the same envelope. Unwrap it when it is there and accept the bare object when
49
+ * it is not, so a hand-written payload is walked just as thoroughly.
50
+ */
51
+ function unwrap(value) {
52
+ if (!value || typeof value !== Typeof.Object || Array.isArray(value)) {
53
+ return null;
54
+ }
55
+ const object = value;
56
+ if (object["value"] && typeof object["value"] === Typeof.Object) {
57
+ return object["value"];
58
+ }
59
+ return object;
60
+ }
61
+ function asArray(value) {
62
+ return Array.isArray(value) ? value : [];
63
+ }
64
+ /*
65
+ * An id reaches here in every shape the codebase produces: a plain uuid string
66
+ * (MonitorSteps.toJSON stringifies defaultMonitorStatusId and monitorStatusId),
67
+ * a serialized `{ _type: "ObjectID", value }` envelope (what JSONFunctions.serialize
68
+ * does to the ObjectIDs nested inside the incidents/alerts arrays), a live
69
+ * ObjectID instance (validating a MonitorSteps object that was never
70
+ * serialized), or `{ value }` without the marker.
71
+ *
72
+ * Blank is treated as absent on purpose: a stored `{"_type":"ObjectID","value":""}`
73
+ * rehydrates to `new ObjectID("")`, which is truthy. Reporting that as a missing
74
+ * *reference* would be misleading - it is an unset field, and the required-field
75
+ * checks own that case.
76
+ */
77
+ export function toReferenceId(value) {
78
+ if (!value) {
79
+ return null;
80
+ }
81
+ if (value instanceof ObjectID) {
82
+ return value.toString().trim() || null;
83
+ }
84
+ if (typeof value === Typeof.String) {
85
+ return value.trim() || null;
86
+ }
87
+ if (typeof value === Typeof.Object && !Array.isArray(value)) {
88
+ const inner = value["value"];
89
+ if (typeof inner === Typeof.String) {
90
+ return inner.trim() || null;
91
+ }
92
+ }
93
+ return null;
94
+ }
95
+ export default class MonitorStepsReferenceExtractor {
96
+ /*
97
+ * Walks monitorSteps and returns every id it holds that points at another
98
+ * record. Ids that are NOT references (step ids, criteria ids, the id on each
99
+ * incident/alert template) are deliberately not returned - they are local
100
+ * identity, not a pointer to a row.
101
+ */
102
+ static extract(monitorSteps) {
103
+ const root = this.toJSONObject(monitorSteps);
104
+ if (!root) {
105
+ return [];
106
+ }
107
+ const references = [];
108
+ this.push(references, {
109
+ model: MonitorStepsReferenceModel.MonitorStatus,
110
+ value: root["defaultMonitorStatusId"],
111
+ path: "default monitor status",
112
+ /*
113
+ * Always operative: MonitorResource stamps it onto the monitor's first
114
+ * MonitorStatusTimeline row, which is the very insert issue #3039 reports
115
+ * failing.
116
+ */
117
+ isOperative: true,
118
+ });
119
+ const steps = asArray(root["monitorStepsInstanceArray"]);
120
+ for (const step of steps) {
121
+ const stepValue = unwrap(step);
122
+ if (!stepValue) {
123
+ continue;
124
+ }
125
+ this.extractFromStepConfig(references, stepValue);
126
+ const criteria = unwrap(stepValue["monitorCriteria"]);
127
+ if (!criteria) {
128
+ continue;
129
+ }
130
+ const instances = asArray(criteria["monitorCriteriaInstanceArray"]);
131
+ for (let index = 0; index < instances.length; index++) {
132
+ this.extractFromCriteriaInstance({
133
+ references: references,
134
+ criteriaInstance: unwrap(instances[index]),
135
+ index: index,
136
+ });
137
+ }
138
+ }
139
+ return references;
140
+ }
141
+ /*
142
+ * The step's own targets: the telemetry services a log/trace/exception/
143
+ * profile/metric monitor is scoped to, and the device a network monitor
144
+ * walks.
145
+ *
146
+ * These are reported as references — so a *cross-project* id in them is
147
+ * refused like any other — but never as `isOperative`, so they are not
148
+ * required to exist. Both already degrade on their own when the target is
149
+ * gone (the query simply matches nothing; NetworkDeviceHydrationUtil logs a
150
+ * warning and carries on), neither can produce the foreign key violation this
151
+ * guard exists for, and deleting a telemetry service is ordinary enough that
152
+ * refusing every later edit of a monitor that once watched it would be a
153
+ * worse failure than the one being fixed.
154
+ */
155
+ static extractFromStepConfig(references, step) {
156
+ for (const field of TELEMETRY_SERVICE_STEP_FIELDS) {
157
+ const config = unwrap(step[field]);
158
+ if (!config) {
159
+ continue;
160
+ }
161
+ for (const id of asArray(config["telemetryServiceIds"])) {
162
+ this.push(references, {
163
+ model: MonitorStepsReferenceModel.TelemetryService,
164
+ value: id,
165
+ path: "monitored telemetry service",
166
+ isOperative: false,
167
+ });
168
+ }
169
+ }
170
+ const networkDeviceMonitor = unwrap(step["networkDeviceMonitor"]);
171
+ if (networkDeviceMonitor) {
172
+ this.push(references, {
173
+ model: MonitorStepsReferenceModel.NetworkDevice,
174
+ value: networkDeviceMonitor["networkDeviceId"],
175
+ path: "monitored network device",
176
+ isOperative: false,
177
+ });
178
+ }
179
+ }
180
+ static extractFromCriteriaInstance(data) {
181
+ const criteriaInstance = data.criteriaInstance;
182
+ if (!criteriaInstance) {
183
+ return;
184
+ }
185
+ const name = criteriaInstance["name"] || `#${data.index + 1}`;
186
+ const label = `criteria "${name}"`;
187
+ this.push(data.references, {
188
+ model: MonitorStepsReferenceModel.MonitorStatus,
189
+ value: criteriaInstance["monitorStatusId"],
190
+ path: `${label} monitor status`,
191
+ isOperative: criteriaInstance["changeMonitorStatus"] === true,
192
+ });
193
+ const createsIncidents = criteriaInstance["createIncidents"] === true;
194
+ for (const incident of asArray(criteriaInstance["incidents"])) {
195
+ const incidentValue = unwrap(incident);
196
+ if (!incidentValue) {
197
+ continue;
198
+ }
199
+ this.push(data.references, {
200
+ model: MonitorStepsReferenceModel.IncidentSeverity,
201
+ value: incidentValue["incidentSeverityId"],
202
+ path: `${label} incident severity`,
203
+ isOperative: createsIncidents,
204
+ });
205
+ this.pushSharedNotificationReferences({
206
+ references: data.references,
207
+ source: incidentValue,
208
+ label: `${label} incident`,
209
+ isOperative: createsIncidents,
210
+ });
211
+ for (const roleAssignment of asArray(incidentValue["incidentMemberRoles"])) {
212
+ const assignment = unwrap(roleAssignment);
213
+ if (!assignment) {
214
+ continue;
215
+ }
216
+ this.push(data.references, {
217
+ model: MonitorStepsReferenceModel.IncidentRole,
218
+ value: assignment["roleId"],
219
+ path: `${label} incident member role`,
220
+ isOperative: createsIncidents,
221
+ });
222
+ this.push(data.references, {
223
+ model: MonitorStepsReferenceModel.User,
224
+ value: assignment["userId"],
225
+ path: `${label} incident member`,
226
+ isOperative: createsIncidents,
227
+ });
228
+ }
229
+ }
230
+ const createsAlerts = criteriaInstance["createAlerts"] === true;
231
+ for (const alert of asArray(criteriaInstance["alerts"])) {
232
+ const alertValue = unwrap(alert);
233
+ if (!alertValue) {
234
+ continue;
235
+ }
236
+ this.push(data.references, {
237
+ model: MonitorStepsReferenceModel.AlertSeverity,
238
+ value: alertValue["alertSeverityId"],
239
+ path: `${label} alert severity`,
240
+ isOperative: createsAlerts,
241
+ });
242
+ this.pushSharedNotificationReferences({
243
+ references: data.references,
244
+ source: alertValue,
245
+ label: `${label} alert`,
246
+ isOperative: createsAlerts,
247
+ });
248
+ }
249
+ }
250
+ // The four id arrays CriteriaIncident and CriteriaAlert have in common.
251
+ static pushSharedNotificationReferences(data) {
252
+ const arrays = [
253
+ {
254
+ field: "onCallPolicyIds",
255
+ model: MonitorStepsReferenceModel.OnCallDutyPolicy,
256
+ path: "on-call policy",
257
+ },
258
+ {
259
+ field: "labelIds",
260
+ model: MonitorStepsReferenceModel.Label,
261
+ path: "label",
262
+ },
263
+ {
264
+ field: "ownerTeamIds",
265
+ model: MonitorStepsReferenceModel.Team,
266
+ path: "owner team",
267
+ },
268
+ {
269
+ field: "ownerUserIds",
270
+ model: MonitorStepsReferenceModel.User,
271
+ path: "owner user",
272
+ },
273
+ ];
274
+ for (const array of arrays) {
275
+ for (const id of asArray(data.source[array.field])) {
276
+ this.push(data.references, {
277
+ model: array.model,
278
+ value: id,
279
+ path: `${data.label} ${array.path}`,
280
+ isOperative: data.isOperative,
281
+ });
282
+ }
283
+ }
284
+ }
285
+ static push(references, data) {
286
+ const id = toReferenceId(data.value);
287
+ if (!id) {
288
+ return;
289
+ }
290
+ references.push({
291
+ model: data.model,
292
+ id: id,
293
+ path: data.path,
294
+ isOperative: data.isOperative,
295
+ });
296
+ }
297
+ static toJSONObject(monitorSteps) {
298
+ if (!monitorSteps) {
299
+ return null;
300
+ }
301
+ if (monitorSteps instanceof MonitorSteps) {
302
+ /*
303
+ * toJSON() on a MonitorSteps whose `data` is undefined returns the
304
+ * "new monitor steps" skeleton, which holds no references. Walking it is
305
+ * harmless.
306
+ */
307
+ return unwrap(monitorSteps.toJSON());
308
+ }
309
+ return unwrap(monitorSteps);
310
+ }
311
+ }
312
+ //# sourceMappingURL=MonitorStepsReferenceExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MonitorStepsReferenceExtractor.js","sourceRoot":"","sources":["../../../../../Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,237 @@
1
+ import { EncryptionSecret } from "../EnvironmentConfig";
2
+ import BadDataException from "../../Types/Exception/BadDataException";
3
+ import HashedString from "../../Types/HashedString";
4
+ import crypto from "crypto";
5
+ /*
6
+ * Password hashing for user credentials.
7
+ *
8
+ * WHY THIS IS NOT A PLAIN HASH
9
+ *
10
+ * SHA-256 is designed to be fast, and that is exactly wrong for a password.
11
+ * A commodity GPU computes billions of SHA-256 digests per second, so a
12
+ * leaked User table is a dictionary attack that finishes over lunch — a
13
+ * per-user salt stops the attacker amortising that work across accounts, but
14
+ * it does nothing to slow down any single guess.
15
+ *
16
+ * scrypt is deliberately expensive in BOTH time and memory. The memory cost
17
+ * is the important half: it is what stops an attacker buying a thousandfold
18
+ * speedup with GPUs or custom silicon, because memory bandwidth is the one
19
+ * thing that hardware cannot cheaply parallelise.
20
+ *
21
+ * THE CONSTRUCTION
22
+ *
23
+ * input = HMAC-SHA256(key = EncryptionSecret, message = password)
24
+ * derived = scrypt(input, salt, 32 bytes, { N, r, p })
25
+ *
26
+ * The HMAC step carries the instance-wide EncryptionSecret as a "pepper".
27
+ * The pepper lives in configuration, not in the database, so a dump of
28
+ * Postgres alone is not enough to start guessing — the attacker also needs
29
+ * the deployment's secret. It also normalises the password to a fixed 32
30
+ * bytes before scrypt sees it, which sidesteps every question about very
31
+ * long or oddly-encoded inputs.
32
+ *
33
+ * THE STORED FORMAT
34
+ *
35
+ * scrypt$N=16384,r=8,p=1$<64 hex characters>
36
+ *
37
+ * The hash carries the algorithm and the cost parameters it was produced
38
+ * with. That is what makes raising the cost later a non-event: old hashes
39
+ * keep verifying against the parameters recorded in them, and each user's
40
+ * hash is re-derived at their next successful login. Nothing about a cost
41
+ * bump requires a migration or a forced password reset.
42
+ *
43
+ * The salt is NOT in this string — it lives in the row's own salt column
44
+ * (see TableColumn.hashSaltColumn), which is where the previous scheme put
45
+ * it and where the write path keeps it in step with the hash.
46
+ */
47
+ /*
48
+ * N is the CPU/memory cost. Memory used is 128 * N * r bytes, so the values
49
+ * below cost 16 MiB and roughly 50ms per hash on current server hardware.
50
+ *
51
+ * That is a deliberate middle: enough to make offline guessing expensive,
52
+ * cheap enough that a burst of logins does not exhaust the libuv thread pool
53
+ * or the box's memory. Raising N is a one-line change — bump it here, and
54
+ * every user is migrated to the new cost as they log in.
55
+ */
56
+ const CURRENT_PARAMS = {
57
+ N: 16384,
58
+ r: 8,
59
+ p: 1,
60
+ };
61
+ /** Bytes of derived key. 32 bytes = the 64 hex characters stored. */
62
+ const KEY_LENGTH_IN_BYTES = 32;
63
+ const SCHEME_NAME = "scrypt";
64
+ /*
65
+ * Refuse absurd parameters read back out of the database. Stored values are
66
+ * ours, not an attacker's, but a corrupted row must fail the login rather
67
+ * than ask Node to allocate gigabytes.
68
+ */
69
+ const MAX_N = 1048576; // 2^20
70
+ const MAX_R = 32;
71
+ const MAX_P = 16;
72
+ export default class PasswordHash {
73
+ /**
74
+ * A fresh, cryptographically random salt: 32 bytes as 64 hex characters.
75
+ *
76
+ * A salt is not a secret — its one job is to be UNIQUE per user, so that no
77
+ * precomputed table and no cracked password is ever worth anything against
78
+ * a second account.
79
+ */
80
+ static generateSalt() {
81
+ return crypto.randomBytes(32).toString("hex");
82
+ }
83
+ /** The `algorithm$params$` prefix that hashes written today carry. */
84
+ static getCurrentPrefix() {
85
+ return `${SCHEME_NAME}$${PasswordHash.encodeParams(CURRENT_PARAMS)}$`;
86
+ }
87
+ static getCurrentParams() {
88
+ return Object.assign({}, CURRENT_PARAMS);
89
+ }
90
+ static encodeParams(params) {
91
+ return `N=${params.N},r=${params.r},p=${params.p}`;
92
+ }
93
+ /**
94
+ * Pull the parameters and derived key back out of a stored value.
95
+ *
96
+ * Returns null for anything that is not one of our scrypt hashes — which
97
+ * includes every password written before this scheme existed. Callers use
98
+ * null to mean "fall back to the legacy comparison", so this must never
99
+ * throw on unrecognised input.
100
+ */
101
+ static parse(storedValue) {
102
+ const parts = storedValue.split("$");
103
+ if (parts.length !== 3 || parts[0] !== SCHEME_NAME) {
104
+ return null;
105
+ }
106
+ const match = parts[1].match(/^N=(\d+),r=(\d+),p=(\d+)$/);
107
+ if (!match) {
108
+ return null;
109
+ }
110
+ const params = {
111
+ N: Number(match[1]),
112
+ r: Number(match[2]),
113
+ p: Number(match[3]),
114
+ };
115
+ const isSane = params.N > 1 &&
116
+ params.N <= MAX_N &&
117
+ (params.N & (params.N - 1)) === 0 && // scrypt requires a power of two
118
+ params.r > 0 &&
119
+ params.r <= MAX_R &&
120
+ params.p > 0 &&
121
+ params.p <= MAX_P;
122
+ if (!isSane || !parts[2]) {
123
+ return null;
124
+ }
125
+ return { params: params, derivedKey: parts[2] };
126
+ }
127
+ /**
128
+ * The pepper step. Keyed with the instance's EncryptionSecret, so the
129
+ * database alone cannot be attacked offline.
130
+ */
131
+ static applyPepper(plainValue) {
132
+ return crypto
133
+ .createHmac("sha256", EncryptionSecret.toString())
134
+ .update(plainValue, "utf8")
135
+ .digest();
136
+ }
137
+ static derive(data) {
138
+ const { N, r, p } = data.params;
139
+ return new Promise((resolve, reject) => {
140
+ crypto.scrypt(PasswordHash.applyPepper(data.plainValue), data.salt, KEY_LENGTH_IN_BYTES, {
141
+ N: N,
142
+ r: r,
143
+ p: p,
144
+ /*
145
+ * Node rejects the call outright when 128 * N * r exceeds
146
+ * maxmem, and its default is a flat 32 MiB. Scale the ceiling
147
+ * with the parameters instead, so raising N does not silently
148
+ * become "Invalid scrypt params" at runtime.
149
+ */
150
+ maxmem: 128 * N * r * 2,
151
+ }, (error, derivedKey) => {
152
+ if (error) {
153
+ return reject(error);
154
+ }
155
+ return resolve(derivedKey.toString("hex"));
156
+ });
157
+ });
158
+ }
159
+ /**
160
+ * Hash a password for storage, at today's cost parameters.
161
+ *
162
+ * The returned string records the algorithm and the parameters used, so it
163
+ * stays verifiable after those parameters change.
164
+ */
165
+ static async hash(data) {
166
+ if (!data.plainValue) {
167
+ return "";
168
+ }
169
+ if (!data.salt) {
170
+ throw new BadDataException("A salt is required to hash a password.");
171
+ }
172
+ const derivedKey = await PasswordHash.derive({
173
+ plainValue: data.plainValue,
174
+ salt: data.salt,
175
+ params: CURRENT_PARAMS,
176
+ });
177
+ return `${PasswordHash.getCurrentPrefix()}${derivedKey}`;
178
+ }
179
+ /**
180
+ * Check a password against a stored value, whichever scheme wrote it.
181
+ *
182
+ * Three schemes are in circulation and all three have to keep working, or
183
+ * the change that introduced the next one locks people out:
184
+ *
185
+ * scrypt$... this one. Verified at the parameters recorded in the hash.
186
+ * salted SHA `SHA256("v2:" + salt + ":" + secret + ":" + password)`.
187
+ * bare SHA `SHA256(secret + password)`, from before salts existed.
188
+ *
189
+ * The last two are told apart by whether the row has a salt, which is the
190
+ * same rule they were written under. Anything not carrying a recognised
191
+ * scheme prefix is one of them.
192
+ */
193
+ static async verify(data) {
194
+ if (!data.plainValue || !data.storedValue) {
195
+ return false;
196
+ }
197
+ const parsed = PasswordHash.parse(data.storedValue);
198
+ if (!parsed) {
199
+ return await HashedString.verifyValue({
200
+ plainValue: data.plainValue,
201
+ hashedValue: data.storedValue,
202
+ encryptionSecret: EncryptionSecret,
203
+ salt: data.salt || null,
204
+ });
205
+ }
206
+ /*
207
+ * A scrypt hash is meaningless without the salt it was derived with.
208
+ * Reaching here without one means the caller did not select the salt
209
+ * column, which would otherwise look exactly like a wrong password.
210
+ */
211
+ if (!data.salt) {
212
+ throw new BadDataException("Cannot verify a salted password hash without its salt. Select the salt column alongside the hash.");
213
+ }
214
+ const derivedKey = await PasswordHash.derive({
215
+ plainValue: data.plainValue,
216
+ salt: data.salt,
217
+ params: parsed.params,
218
+ });
219
+ return HashedString.isEqual(derivedKey, parsed.derivedKey);
220
+ }
221
+ /**
222
+ * Should this stored value be re-hashed the next time the password is
223
+ * known to be correct?
224
+ *
225
+ * True for every hash that is not exactly what `hash()` writes today: the
226
+ * two SHA-256 schemes that came before, and any scrypt hash carrying
227
+ * parameters that are no longer current. This is the whole upgrade
228
+ * mechanism — raising the cost above is enough to start migrating users.
229
+ */
230
+ static needsUpgrade(storedValue) {
231
+ if (!storedValue) {
232
+ return false;
233
+ }
234
+ return !storedValue.startsWith(PasswordHash.getCurrentPrefix());
235
+ }
236
+ }
237
+ //# sourceMappingURL=PasswordHash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PasswordHash.js","sourceRoot":"","sources":["../../../../Server/Utils/PasswordHash.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /*
2
+ * In-process de-duplication of concurrent identical work.
3
+ *
4
+ * A Redis fence admits one writer per window across the FLEET, but every
5
+ * caller still pays a Redis round trip to discover it lost. That is the wrong
6
+ * unit of work when the duplicate callers are in the same process: an ingest
7
+ * pod running hundreds of concurrent jobs re-resolves the same handful of
8
+ * services on every batch, so hundreds of coroutines independently ask Redis
9
+ * the same question and then throw the answer away.
10
+ *
11
+ * SingleFlight collapses them first. The first caller for a key runs the work;
12
+ * everyone who arrives while it is still in flight awaits the SAME promise and
13
+ * gets the same result. Per pod, N concurrent duplicates cost one Redis round
14
+ * trip and at most one database write instead of N of each — which is what
15
+ * turns fleet-wide write amplification from (pods x jobs) into (pods).
16
+ *
17
+ * Deliberately unbounded in time but not in size: entries live only for the
18
+ * duration of the work itself and are removed in a `finally`, so the map holds
19
+ * exactly the set of operations currently running. There is no eviction policy
20
+ * to get wrong and nothing to leak if work hangs beyond a caller's patience —
21
+ * the entry is released when the underlying promise settles either way.
22
+ *
23
+ * This is a per-process optimisation and NOT a correctness mechanism: nothing
24
+ * here coordinates across pods. It composes with a distributed fence, it does
25
+ * not replace one.
26
+ */
27
+ class SingleFlight {
28
+ /**
29
+ * Run `work` for `key`, or join the run already in flight for it.
30
+ *
31
+ * Followers observe whatever the leader observes, including a rejection.
32
+ * That is intentional: these callers asked for identical work, so they are
33
+ * entitled to identical outcomes, and a follower silently retrying a failure
34
+ * the leader just hit would re-create the stampede this exists to prevent.
35
+ */
36
+ static async run(key, work) {
37
+ const existing = this.inflight.get(key);
38
+ if (existing) {
39
+ return (await existing);
40
+ }
41
+ /*
42
+ * Invoke through a wrapper so a `work` that throws SYNCHRONOUSLY still
43
+ * produces a promise to register and await. Calling it bare would throw
44
+ * past the bookkeeping below and leave the key registered forever.
45
+ */
46
+ const promise = (async () => {
47
+ return await work();
48
+ })();
49
+ this.inflight.set(key, promise);
50
+ try {
51
+ return await promise;
52
+ }
53
+ finally {
54
+ /*
55
+ * Only clear the entry if it is still ours. A follower cannot install a
56
+ * new one (it awaited instead), but a later leader can, and blindly
57
+ * deleting here would evict that live run and let the next caller start
58
+ * a duplicate of work already underway.
59
+ */
60
+ if (this.inflight.get(key) === promise) {
61
+ this.inflight.delete(key);
62
+ }
63
+ }
64
+ }
65
+ /** Number of operations currently in flight. For tests and diagnostics. */
66
+ static inflightCount() {
67
+ return this.inflight.size;
68
+ }
69
+ /** Drop all bookkeeping. For tests only. */
70
+ static clear() {
71
+ this.inflight.clear();
72
+ }
73
+ }
74
+ SingleFlight.inflight = new Map();
75
+ export default SingleFlight;
76
+ //# sourceMappingURL=SingleFlight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SingleFlight.js","sourceRoot":"","sources":["../../../../Server/Utils/SingleFlight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAqB,YAAY;IAM/B;;;;;;;OAOG;IACI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,IAAsB;QAC5D,MAAM,QAAQ,GAAiC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,CAAC,MAAM,QAAQ,CAAM,CAAC;QAC/B,CAAC;QAED;;;;WAIG;QACH,MAAM,OAAO,GAAe,CAAC,KAAK,IAAI,EAAE;YACtC,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC,CAAC,EAAE,CAAC;QAEL,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAEhC,IAAI,CAAC;YACH,OAAO,MAAM,OAAO,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT;;;;;eAKG;YACH,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC;gBACvC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IAED,2EAA2E;IACpE,MAAM,CAAC,aAAa;QACzB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;IAC5B,CAAC;IAED,4CAA4C;IACrC,MAAM,CAAC,KAAK;QACjB,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;;AAtDc,qBAAQ,GAAkC,IAAI,GAAG,EAG7D,CAAC;eAJe,YAAY"}