@oneuptime/common 12.0.5 → 12.0.6

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 (528) hide show
  1. package/Models/DatabaseModels/AIRun.ts +33 -0
  2. package/Models/DatabaseModels/DataSource.ts +744 -0
  3. package/Models/DatabaseModels/Index.ts +3 -0
  4. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +10 -2
  5. package/Models/DatabaseModels/User.ts +2 -0
  6. package/Models/DatabaseModels/UserOnCallLog.ts +2 -0
  7. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +2 -0
  8. package/Models/DatabaseModels/UserSession.ts +2 -0
  9. package/Models/DatabaseModels/UserTotpAuth.ts +6 -4
  10. package/Models/DatabaseModels/UserWebAuthn.ts +5 -3
  11. package/Server/API/AIInsightAPI.ts +47 -4
  12. package/Server/API/AIInvestigationAPI.ts +25 -0
  13. package/Server/API/DashboardAPI.ts +176 -492
  14. package/Server/API/DataSourceAPI.ts +268 -0
  15. package/Server/API/StatusPageAPI.ts +11 -1
  16. package/Server/API/UserAPI.ts +119 -0
  17. package/Server/Infrastructure/ClickhouseConfig.ts +59 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.ts +24 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.ts +76 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  22. package/Server/Infrastructure/Queue.ts +26 -0
  23. package/Server/Infrastructure/QueueWorker.ts +17 -0
  24. package/Server/Middleware/TelemetryIngest.ts +8 -3
  25. package/Server/Services/AIInsightService.ts +132 -12
  26. package/Server/Services/AIRunService.ts +34 -0
  27. package/Server/Services/AIService.ts +17 -2
  28. package/Server/Services/AlertService.ts +38 -32
  29. package/Server/Services/AnalyticsDatabaseService.ts +8 -4
  30. package/Server/Services/DataSourceService.ts +200 -0
  31. package/Server/Services/HostService.ts +92 -0
  32. package/Server/Services/IncidentService.ts +45 -0
  33. package/Server/Services/Index.ts +2 -0
  34. package/Server/Services/MonitorService.ts +49 -0
  35. package/Server/Services/MonitorStatusService.ts +166 -0
  36. package/Server/Services/OpenTelemetryIngestService.ts +255 -184
  37. package/Server/Services/RumSessionPinService.ts +7 -21
  38. package/Server/Services/StatusPageSubscriberService.ts +13 -0
  39. package/Server/Services/UserService.ts +280 -9
  40. package/Server/Static/Vendor/README.md +62 -0
  41. package/Server/Static/Vendor/fonts/InterVariable.woff2 +0 -0
  42. package/Server/Static/Vendor/highlight/highlight.min.js +1244 -0
  43. package/Server/Static/Vendor/highlight/languages/apache.min.js +15 -0
  44. package/Server/Static/Vendor/highlight/languages/bash.min.js +21 -0
  45. package/Server/Static/Vendor/highlight/languages/c.min.js +41 -0
  46. package/Server/Static/Vendor/highlight/languages/cpp.min.js +47 -0
  47. package/Server/Static/Vendor/highlight/languages/csharp.min.js +49 -0
  48. package/Server/Static/Vendor/highlight/languages/css.min.js +31 -0
  49. package/Server/Static/Vendor/highlight/languages/diff.min.js +9 -0
  50. package/Server/Static/Vendor/highlight/languages/dns.min.js +11 -0
  51. package/Server/Static/Vendor/highlight/languages/dockerfile.min.js +8 -0
  52. package/Server/Static/Vendor/highlight/languages/go.min.js +20 -0
  53. package/Server/Static/Vendor/highlight/languages/graphql.min.js +12 -0
  54. package/Server/Static/Vendor/highlight/languages/http.min.js +14 -0
  55. package/Server/Static/Vendor/highlight/languages/ini.min.js +15 -0
  56. package/Server/Static/Vendor/highlight/languages/java.min.js +38 -0
  57. package/Server/Static/Vendor/highlight/languages/javascript.min.js +81 -0
  58. package/Server/Static/Vendor/highlight/languages/json.min.js +8 -0
  59. package/Server/Static/Vendor/highlight/languages/kotlin.min.js +46 -0
  60. package/Server/Static/Vendor/highlight/languages/lua.min.js +15 -0
  61. package/Server/Static/Vendor/highlight/languages/makefile.min.js +14 -0
  62. package/Server/Static/Vendor/highlight/languages/nginx.min.js +21 -0
  63. package/Server/Static/Vendor/highlight/languages/perl.min.js +41 -0
  64. package/Server/Static/Vendor/highlight/languages/php.min.js +59 -0
  65. package/Server/Static/Vendor/highlight/languages/powershell.min.js +39 -0
  66. package/Server/Static/Vendor/highlight/languages/python.min.js +42 -0
  67. package/Server/Static/Vendor/highlight/languages/r.min.js +26 -0
  68. package/Server/Static/Vendor/highlight/languages/ruby.min.js +54 -0
  69. package/Server/Static/Vendor/highlight/languages/rust.min.js +27 -0
  70. package/Server/Static/Vendor/highlight/languages/scala.min.js +28 -0
  71. package/Server/Static/Vendor/highlight/languages/sql.min.js +21 -0
  72. package/Server/Static/Vendor/highlight/languages/swift.min.js +68 -0
  73. package/Server/Static/Vendor/highlight/languages/typescript.min.js +99 -0
  74. package/Server/Static/Vendor/highlight/languages/xml.min.js +29 -0
  75. package/Server/Static/Vendor/highlight/languages/yaml.min.js +28 -0
  76. package/Server/Static/Vendor/highlight/styles/github-dark.min.css +10 -0
  77. package/Server/Static/Vendor/highlight/styles/vs2015.min.css +1 -0
  78. package/Server/Static/Vendor/tailwind/tailwind-3.4.5.js +21028 -0
  79. package/Server/Types/Database/Permissions/BasePermission.ts +7 -0
  80. package/Server/Types/Database/Permissions/DeletePermission.ts +2 -0
  81. package/Server/Types/Database/Permissions/ReadPermission.ts +3 -0
  82. package/Server/Types/Database/Permissions/TenantPermission.ts +101 -16
  83. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +2 -2
  84. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +90 -11
  85. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +1 -0
  86. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +1 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.ts +125 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +25 -15
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +256 -57
  90. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +76 -18
  91. package/Server/Utils/AI/SRE/InvestigationTldr.ts +352 -0
  92. package/Server/Utils/AnalyticsDatabase/InsertDedupContext.ts +7 -2
  93. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +1793 -0
  94. package/Server/Utils/Dashboard/PublicDashboardViewConfig.ts +65 -0
  95. package/Server/Utils/DataSource/ConnectorRegistry.ts +53 -0
  96. package/Server/Utils/DataSource/Connectors/ClickHouseConnector.ts +338 -0
  97. package/Server/Utils/DataSource/Connectors/ElasticsearchConnector.ts +717 -0
  98. package/Server/Utils/DataSource/Connectors/LokiConnector.ts +606 -0
  99. package/Server/Utils/DataSource/Connectors/MySqlConnector.ts +307 -0
  100. package/Server/Utils/DataSource/Connectors/PostgresConnector.ts +260 -0
  101. package/Server/Utils/DataSource/Connectors/PrometheusConnector.ts +555 -0
  102. package/Server/Utils/DataSource/Connectors/RestApiConnector.ts +597 -0
  103. package/Server/Utils/DataSource/Connectors/SqlServerConnector.ts +318 -0
  104. package/Server/Utils/DataSource/EgressGuard.ts +446 -0
  105. package/Server/Utils/DataSource/HttpFetch.ts +221 -0
  106. package/Server/Utils/DataSource/SqlQueryGuard.ts +383 -0
  107. package/Server/Utils/DataSource/SqlResultShaper.ts +372 -0
  108. package/Server/Utils/DataSource/Types.ts +93 -0
  109. package/Server/Utils/Database/PostgresErrorTranslator.ts +172 -17
  110. package/Server/Utils/InProcessMemo.ts +141 -0
  111. package/Server/Utils/InstanceHealth/TelemetryIngestion.ts +628 -0
  112. package/Server/Utils/Monitor/MonitorMetricUtil.ts +58 -0
  113. package/Server/Utils/Monitor/MonitorResource.ts +14 -0
  114. package/Server/Utils/Response.ts +12 -1
  115. package/Server/Utils/SSRFProtection.ts +237 -0
  116. package/Server/Utils/StartServer.ts +8 -0
  117. package/Server/Utils/StatusPageSubscriberWebhook.ts +30 -0
  118. package/Server/Utils/Telemetry/CaptureSpan.ts +30 -18
  119. package/Server/Utils/Telemetry/IngestionTimestamp.ts +75 -0
  120. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +99 -7
  121. package/Server/Utils/Telemetry/Telemetry.ts +112 -1
  122. package/Server/Utils/Telemetry.ts +104 -3
  123. package/Server/Utils/VendorAssets.ts +165 -0
  124. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +28 -5
  125. package/Server/Utils/Workspace/Slack/Slack.ts +5 -0
  126. package/Server/Views/Partials/Head.ejs +21 -7
  127. package/Tests/App/AdminDashboard/AdminProjectsIdFilter.test.tsx +207 -0
  128. package/Tests/App/AdminDashboard/AdminUsersIdFilter.test.tsx +216 -0
  129. package/Tests/App/Dashboard/AIInsightViewActions.test.tsx +422 -0
  130. package/Tests/App/Dashboard/AddWidgetModal.test.tsx +10 -3
  131. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +387 -0
  132. package/Tests/App/Dashboard/ChatActivityFeed.test.tsx +199 -0
  133. package/Tests/App/Dashboard/DataSourceChartSyntheticConfig.test.tsx +736 -0
  134. package/Tests/App/Dashboard/DataSourceQueryEditor.test.tsx +868 -0
  135. package/Tests/App/Dashboard/DataSourceWidgetCatalog.test.ts +440 -0
  136. package/Tests/App/Dashboard/DataSourceWidgetFetching.test.tsx +2109 -0
  137. package/Tests/App/Dashboard/DataSourceWidgetViews.test.tsx +726 -0
  138. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +447 -0
  139. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +514 -3
  140. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +391 -0
  141. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +326 -0
  142. package/Tests/App/Dashboard/SideMenuHarness.tsx +187 -0
  143. package/Tests/App/Dashboard/WidgetCatalog.test.ts +6 -1
  144. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +1858 -0
  145. package/Tests/Models/DatabaseModels/DataSourceModelSecrets.test.ts +70 -0
  146. package/Tests/Server/API/AIInvestigationAPI.test.ts +187 -0
  147. package/Tests/Server/API/DashboardPublicDataSourceStrip.test.ts +686 -0
  148. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +585 -823
  149. package/Tests/Server/API/DataSourceAPIRoutes.test.ts +486 -0
  150. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +291 -0
  151. package/Tests/Server/API/UserAuthenticationAPI.test.ts +641 -0
  152. package/Tests/Server/Infrastructure/ClickhouseKeepAliveOptions.test.ts +441 -0
  153. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +140 -0
  154. package/Tests/Server/Services/AIInsightService.test.ts +266 -11
  155. package/Tests/Server/Services/AIRunAnalysisTldrPersistence.test.ts +160 -0
  156. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +4 -0
  157. package/Tests/Server/Services/AlertMetricResourceAttributes.test.ts +352 -0
  158. package/Tests/Server/Services/DataSourceServiceSettings.test.ts +244 -0
  159. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +397 -0
  160. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +41 -2
  161. package/Tests/Server/Services/IncidentMetricResourceAttributes.test.ts +408 -0
  162. package/Tests/Server/Services/MonitorStatusServiceDeleteReferenceCleanup.test.ts +351 -0
  163. package/Tests/Server/Services/MonitorStatusServiceValidation.test.ts +171 -0
  164. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +398 -0
  165. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +19 -0
  166. package/Tests/Server/Services/ProjectCallSMSConfigCredentialUniqueness.test.ts +305 -0
  167. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +36 -1
  168. package/Tests/Server/Services/RumSessionPinUniqueViolationRecovery.test.ts +163 -0
  169. package/Tests/Server/Services/UserAuthenticationService.test.ts +973 -0
  170. package/Tests/Server/Types/Database/ObjectIdColumnQuery.test.ts +262 -0
  171. package/Tests/Server/Types/Database/Permissions/TenantPermission.test.ts +358 -0
  172. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +2 -2
  173. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +6 -1
  174. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +121 -4
  175. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +361 -10
  176. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +292 -0
  177. package/Tests/Server/Utils/AI/InvestigationTldr.test.ts +623 -0
  178. package/Tests/Server/Utils/AI/InvestigationTldrWiring.test.ts +98 -0
  179. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +857 -0
  180. package/Tests/Server/Utils/Dashboard/PublicDashboardViewConfig.test.ts +480 -0
  181. package/Tests/Server/Utils/DataSource/ClickHouseConnector.test.ts +759 -0
  182. package/Tests/Server/Utils/DataSource/ConnectorRegistry.test.ts +37 -0
  183. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +645 -0
  184. package/Tests/Server/Utils/DataSource/ElasticsearchConnector.test.ts +1206 -0
  185. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +616 -0
  186. package/Tests/Server/Utils/DataSource/LokiConnector.test.ts +970 -0
  187. package/Tests/Server/Utils/DataSource/MySqlConnector.test.ts +935 -0
  188. package/Tests/Server/Utils/DataSource/PostgresConnector.test.ts +854 -0
  189. package/Tests/Server/Utils/DataSource/PrometheusConnector.test.ts +881 -0
  190. package/Tests/Server/Utils/DataSource/RestApiConnector.test.ts +1020 -0
  191. package/Tests/Server/Utils/DataSource/SqlQueryGuard.test.ts +425 -0
  192. package/Tests/Server/Utils/DataSource/SqlResultShaper.test.ts +555 -0
  193. package/Tests/Server/Utils/DataSource/SqlServerConnector.test.ts +934 -0
  194. package/Tests/Server/Utils/Database/PostgresErrorTranslator.test.ts +228 -7
  195. package/Tests/Server/Utils/InProcessMemo.test.ts +292 -0
  196. package/Tests/Server/Utils/InstanceHealth/TelemetryIngestion.test.ts +960 -0
  197. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +103 -0
  198. package/Tests/Server/Utils/Monitor/MonitorMetricResourceAttributes.test.ts +336 -0
  199. package/Tests/Server/Utils/OfflineAssetHygiene.test.ts +521 -0
  200. package/Tests/Server/Utils/ResponseRenderAnalytics.test.ts +143 -0
  201. package/Tests/Server/Utils/SSRFProtection.test.ts +193 -0
  202. package/Tests/Server/Utils/StatusPageSubscriberWebhook.test.ts +101 -0
  203. package/Tests/Server/Utils/TailwindBuildCopy.test.ts +225 -0
  204. package/Tests/Server/Utils/Telemetry/ResourceHeartbeatL1Memo.test.ts +355 -0
  205. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriter.test.ts +128 -0
  206. package/Tests/Server/Utils/Telemetry/TelemetryUtilAttributeKeys.test.ts +381 -0
  207. package/Tests/Server/Utils/Telemetry.test.ts +87 -0
  208. package/Tests/Server/Utils/VendorAssetIntegrity.test.ts +343 -0
  209. package/Tests/Server/Utils/VendorAssets.test.ts +671 -0
  210. package/Tests/Server/Views/OfflineRender.test.ts +297 -0
  211. package/Tests/Types/Dashboard/DataSourceComponentTypes.test.ts +618 -0
  212. package/Tests/Types/DateClickhouseFormat.test.ts +192 -0
  213. package/Tests/Types/Password.test.ts +363 -0
  214. package/Tests/UI/Components/ConfirmModal.test.tsx +7 -0
  215. package/Tests/UI/Components/ErrorBoundary.test.tsx +53 -0
  216. package/Tests/UI/Components/Modal.test.tsx +281 -1
  217. package/Tests/UI/Components/ObjectIdFilterPipeline.test.tsx +396 -0
  218. package/Tests/UI/Components/StatusPage/ResourceGroupNavigator.test.tsx +1147 -0
  219. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +116 -1
  220. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
  221. package/Tests/Utils/Analytics.test.ts +23 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardDataSourceComponents.test.ts +640 -0
  223. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +138 -0
  224. package/Tests/Utils/DataSource/DataSourceValueReducer.test.ts +526 -0
  225. package/Tests/Utils/Metrics/MetricResourceAttributeUtil.test.ts +691 -0
  226. package/Tests/Utils/StatusPage/GroupHierarchyView.test.ts +1452 -0
  227. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +931 -0
  228. package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +288 -0
  229. package/Tests/Utils/Telemetry/IngestionTimestamp.test.ts +170 -0
  230. package/Types/AI/AIInsightEvidence.ts +6 -0
  231. package/Types/Analytics/RevenueEvent.ts +31 -0
  232. package/Types/Dashboard/DashboardComponentType.ts +31 -0
  233. package/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.ts +27 -0
  234. package/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.ts +32 -0
  235. package/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.ts +30 -0
  236. package/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.ts +55 -0
  237. package/Types/DataSource/DataSourceLimits.ts +62 -0
  238. package/Types/DataSource/DataSourceQueryConfig.ts +41 -0
  239. package/Types/DataSource/DataSourceTableResult.ts +38 -0
  240. package/Types/DataSource/DataSourceType.ts +213 -0
  241. package/Types/Date.ts +43 -3
  242. package/Types/Password.ts +64 -0
  243. package/Types/Permission.ts +46 -0
  244. package/Types/UserAuthenticationStatus.ts +34 -0
  245. package/UI/Components/Button/Button.tsx +1 -1
  246. package/UI/Components/ErrorBoundary.tsx +459 -108
  247. package/UI/Components/Icon/Icon.tsx +10 -9
  248. package/UI/Components/Modal/ConfirmModal.tsx +6 -1
  249. package/UI/Components/Modal/Modal.tsx +267 -35
  250. package/UI/Components/Modal/ModalFooter.tsx +6 -1
  251. package/UI/Components/MoreMenu/MoreMenu.tsx +19 -4
  252. package/UI/Components/MoreMenu/MoreMenuItem.tsx +6 -1
  253. package/UI/Components/StatusPage/ResourceGrid.tsx +314 -0
  254. package/UI/Components/StatusPage/ResourceGroupNavigator.tsx +808 -0
  255. package/UI/Components/StatusPage/ResourceList.tsx +570 -0
  256. package/UI/Styles/Theme.css +18 -0
  257. package/UI/Utils/API/RequestOptions.ts +7 -0
  258. package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +1 -0
  259. package/UI/Utils/ModelAPI/ModelAPI.ts +1 -0
  260. package/UI/Utils/TestDataSource.ts +61 -0
  261. package/UI/esbuild-config.js +45 -0
  262. package/Utils/Analytics.ts +15 -0
  263. package/Utils/Dashboard/Components/DashboardDataSourceChartComponent.ts +88 -0
  264. package/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.ts +123 -0
  265. package/Utils/Dashboard/Components/DashboardDataSourceShared.ts +16 -0
  266. package/Utils/Dashboard/Components/DashboardDataSourceTableComponent.ts +72 -0
  267. package/Utils/Dashboard/Components/DashboardDataSourceValueComponent.ts +126 -0
  268. package/Utils/Dashboard/Components/Index.ts +28 -0
  269. package/Utils/DataSource/DataSourceQueryText.ts +94 -0
  270. package/Utils/DataSource/DataSourceValueReducer.ts +156 -0
  271. package/Utils/Metrics/MetricResourceAttributeUtil.ts +380 -0
  272. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +8 -6
  273. package/Utils/StatusPage/GroupHierarchyView.ts +931 -0
  274. package/Utils/StatusPage/ResourceExplorer.ts +853 -0
  275. package/build/dist/Models/DatabaseModels/AIRun.js +34 -0
  276. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/DataSource.js +774 -0
  278. package/build/dist/Models/DatabaseModels/DataSource.js.map +1 -0
  279. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  280. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +14 -4
  282. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/User.js +2 -0
  284. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -0
  286. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +2 -0
  288. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/UserSession.js +2 -0
  290. package/build/dist/Models/DatabaseModels/UserSession.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/UserTotpAuth.js +6 -4
  292. package/build/dist/Models/DatabaseModels/UserTotpAuth.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/UserWebAuthn.js +5 -3
  294. package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
  295. package/build/dist/Server/API/AIInsightAPI.js +34 -4
  296. package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
  297. package/build/dist/Server/API/AIInvestigationAPI.js +23 -0
  298. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  299. package/build/dist/Server/API/DashboardAPI.js +119 -433
  300. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  301. package/build/dist/Server/API/DataSourceAPI.js +173 -0
  302. package/build/dist/Server/API/DataSourceAPI.js.map +1 -0
  303. package/build/dist/Server/API/StatusPageAPI.js +11 -1
  304. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  305. package/build/dist/Server/API/UserAPI.js +94 -2
  306. package/build/dist/Server/API/UserAPI.js.map +1 -1
  307. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +49 -0
  308. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  309. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js +20 -0
  310. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786303472848-AddDataSourceTable.js.map +1 -0
  311. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js +19 -0
  312. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786600000000-AddInvestigationAnalysisTldr.js.map +1 -0
  313. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js +64 -0
  314. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786700000000-DropProjectCallSMSConfigCredentialUniques.js.map +1 -0
  315. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  316. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  317. package/build/dist/Server/Infrastructure/Queue.js +27 -0
  318. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  319. package/build/dist/Server/Infrastructure/QueueWorker.js +13 -0
  320. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  321. package/build/dist/Server/Middleware/TelemetryIngest.js +8 -3
  322. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  323. package/build/dist/Server/Services/AIInsightService.js +110 -10
  324. package/build/dist/Server/Services/AIInsightService.js.map +1 -1
  325. package/build/dist/Server/Services/AIRunService.js +34 -0
  326. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  327. package/build/dist/Server/Services/AIService.js +16 -2
  328. package/build/dist/Server/Services/AIService.js.map +1 -1
  329. package/build/dist/Server/Services/AlertService.js +28 -35
  330. package/build/dist/Server/Services/AlertService.js.map +1 -1
  331. package/build/dist/Server/Services/AnalyticsDatabaseService.js +8 -4
  332. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  333. package/build/dist/Server/Services/DataSourceService.js +159 -0
  334. package/build/dist/Server/Services/DataSourceService.js.map +1 -0
  335. package/build/dist/Server/Services/HostService.js +74 -0
  336. package/build/dist/Server/Services/HostService.js.map +1 -1
  337. package/build/dist/Server/Services/IncidentService.js +35 -24
  338. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  339. package/build/dist/Server/Services/Index.js +2 -0
  340. package/build/dist/Server/Services/Index.js.map +1 -1
  341. package/build/dist/Server/Services/MonitorService.js +45 -0
  342. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  343. package/build/dist/Server/Services/MonitorStatusService.js +129 -0
  344. package/build/dist/Server/Services/MonitorStatusService.js.map +1 -1
  345. package/build/dist/Server/Services/OpenTelemetryIngestService.js +222 -159
  346. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  347. package/build/dist/Server/Services/RumSessionPinService.js +7 -15
  348. package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
  349. package/build/dist/Server/Services/StatusPageSubscriberService.js +10 -0
  350. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  351. package/build/dist/Server/Services/UserService.js +241 -10
  352. package/build/dist/Server/Services/UserService.js.map +1 -1
  353. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +6 -0
  354. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  355. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js +1 -0
  356. package/build/dist/Server/Types/Database/Permissions/DeletePermission.js.map +1 -1
  357. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js +2 -0
  358. package/build/dist/Server/Types/Database/Permissions/ReadPermission.js.map +1 -1
  359. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +68 -12
  360. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  361. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +2 -2
  362. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  363. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +68 -8
  364. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  365. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +1 -0
  366. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  367. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +1 -0
  368. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  369. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js +97 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionIdentity.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +17 -15
  372. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
  373. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +178 -54
  374. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
  375. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +65 -16
  376. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -1
  377. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js +303 -0
  378. package/build/dist/Server/Utils/AI/SRE/InvestigationTldr.js.map +1 -0
  379. package/build/dist/Server/Utils/AnalyticsDatabase/InsertDedupContext.js.map +1 -1
  380. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +1261 -0
  381. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -0
  382. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js +47 -0
  383. package/build/dist/Server/Utils/Dashboard/PublicDashboardViewConfig.js.map +1 -0
  384. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js +42 -0
  385. package/build/dist/Server/Utils/DataSource/ConnectorRegistry.js.map +1 -0
  386. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js +187 -0
  387. package/build/dist/Server/Utils/DataSource/Connectors/ClickHouseConnector.js.map +1 -0
  388. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js +493 -0
  389. package/build/dist/Server/Utils/DataSource/Connectors/ElasticsearchConnector.js.map +1 -0
  390. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js +399 -0
  391. package/build/dist/Server/Utils/DataSource/Connectors/LokiConnector.js.map +1 -0
  392. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js +195 -0
  393. package/build/dist/Server/Utils/DataSource/Connectors/MySqlConnector.js.map +1 -0
  394. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js +149 -0
  395. package/build/dist/Server/Utils/DataSource/Connectors/PostgresConnector.js.map +1 -0
  396. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js +362 -0
  397. package/build/dist/Server/Utils/DataSource/Connectors/PrometheusConnector.js.map +1 -0
  398. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js +342 -0
  399. package/build/dist/Server/Utils/DataSource/Connectors/RestApiConnector.js.map +1 -0
  400. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js +186 -0
  401. package/build/dist/Server/Utils/DataSource/Connectors/SqlServerConnector.js.map +1 -0
  402. package/build/dist/Server/Utils/DataSource/EgressGuard.js +305 -0
  403. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -0
  404. package/build/dist/Server/Utils/DataSource/HttpFetch.js +134 -0
  405. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -0
  406. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js +331 -0
  407. package/build/dist/Server/Utils/DataSource/SqlQueryGuard.js.map +1 -0
  408. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js +280 -0
  409. package/build/dist/Server/Utils/DataSource/SqlResultShaper.js.map +1 -0
  410. package/build/dist/Server/Utils/DataSource/Types.js +2 -0
  411. package/build/dist/Server/Utils/DataSource/Types.js.map +1 -0
  412. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js +103 -9
  413. package/build/dist/Server/Utils/Database/PostgresErrorTranslator.js.map +1 -1
  414. package/build/dist/Server/Utils/InProcessMemo.js +113 -0
  415. package/build/dist/Server/Utils/InProcessMemo.js.map +1 -0
  416. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js +406 -0
  417. package/build/dist/Server/Utils/InstanceHealth/TelemetryIngestion.js.map +1 -0
  418. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +34 -0
  419. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  420. package/build/dist/Server/Utils/Monitor/MonitorResource.js +14 -0
  421. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  422. package/build/dist/Server/Utils/Response.js +9 -1
  423. package/build/dist/Server/Utils/Response.js.map +1 -1
  424. package/build/dist/Server/Utils/SSRFProtection.js +192 -0
  425. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -0
  426. package/build/dist/Server/Utils/StartServer.js +7 -0
  427. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  428. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +24 -0
  429. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -1
  430. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +25 -11
  431. package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
  432. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js +32 -0
  433. package/build/dist/Server/Utils/Telemetry/IngestionTimestamp.js.map +1 -0
  434. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +92 -5
  435. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
  436. package/build/dist/Server/Utils/Telemetry/Telemetry.js +92 -6
  437. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  438. package/build/dist/Server/Utils/Telemetry.js +93 -6
  439. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  440. package/build/dist/Server/Utils/VendorAssets.js +121 -0
  441. package/build/dist/Server/Utils/VendorAssets.js.map +1 -0
  442. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +25 -4
  443. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  444. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +5 -0
  445. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  446. package/build/dist/Types/Analytics/RevenueEvent.js +26 -0
  447. package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -0
  448. package/build/dist/Types/Dashboard/DashboardComponentType.js +27 -0
  449. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  450. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js +2 -0
  451. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceChartComponent.js.map +1 -0
  452. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js +2 -0
  453. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceGaugeComponent.js.map +1 -0
  454. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js +2 -0
  455. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceTableComponent.js.map +1 -0
  456. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js +16 -0
  457. package/build/dist/Types/Dashboard/DashboardComponents/DashboardDataSourceValueComponent.js.map +1 -0
  458. package/build/dist/Types/DataSource/DataSourceLimits.js +47 -0
  459. package/build/dist/Types/DataSource/DataSourceLimits.js.map +1 -0
  460. package/build/dist/Types/DataSource/DataSourceQueryConfig.js +10 -0
  461. package/build/dist/Types/DataSource/DataSourceQueryConfig.js.map +1 -0
  462. package/build/dist/Types/DataSource/DataSourceTableResult.js +14 -0
  463. package/build/dist/Types/DataSource/DataSourceTableResult.js.map +1 -0
  464. package/build/dist/Types/DataSource/DataSourceType.js +183 -0
  465. package/build/dist/Types/DataSource/DataSourceType.js.map +1 -0
  466. package/build/dist/Types/Date.js +38 -3
  467. package/build/dist/Types/Date.js.map +1 -1
  468. package/build/dist/Types/Password.js +56 -0
  469. package/build/dist/Types/Password.js.map +1 -0
  470. package/build/dist/Types/Permission.js +42 -0
  471. package/build/dist/Types/Permission.js.map +1 -1
  472. package/build/dist/Types/UserAuthenticationStatus.js +2 -0
  473. package/build/dist/Types/UserAuthenticationStatus.js.map +1 -0
  474. package/build/dist/UI/Components/ErrorBoundary.js +388 -72
  475. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  476. package/build/dist/UI/Components/Icon/Icon.js +10 -4
  477. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  478. package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
  479. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  480. package/build/dist/UI/Components/Modal/Modal.js +178 -19
  481. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  482. package/build/dist/UI/Components/Modal/ModalFooter.js +3 -1
  483. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  484. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +9 -6
  485. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  486. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +7 -1
  487. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  488. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +119 -0
  489. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -0
  490. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js +354 -0
  491. package/build/dist/UI/Components/StatusPage/ResourceGroupNavigator.js.map +1 -0
  492. package/build/dist/UI/Components/StatusPage/ResourceList.js +203 -0
  493. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -0
  494. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +1 -6
  495. package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
  496. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +3 -8
  497. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  498. package/build/dist/UI/Utils/TestDataSource.js +39 -0
  499. package/build/dist/UI/Utils/TestDataSource.js.map +1 -0
  500. package/build/dist/Utils/Analytics.js +4 -0
  501. package/build/dist/Utils/Analytics.js.map +1 -1
  502. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js +79 -0
  503. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceChartComponent.js.map +1 -0
  504. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js +111 -0
  505. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceGaugeComponent.js.map +1 -0
  506. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js +15 -0
  507. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceShared.js.map +1 -0
  508. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js +62 -0
  509. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceTableComponent.js.map +1 -0
  510. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js +112 -0
  511. package/build/dist/Utils/Dashboard/Components/DashboardDataSourceValueComponent.js.map +1 -0
  512. package/build/dist/Utils/Dashboard/Components/Index.js +16 -0
  513. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  514. package/build/dist/Utils/DataSource/DataSourceQueryText.js +64 -0
  515. package/build/dist/Utils/DataSource/DataSourceQueryText.js.map +1 -0
  516. package/build/dist/Utils/DataSource/DataSourceValueReducer.js +124 -0
  517. package/build/dist/Utils/DataSource/DataSourceValueReducer.js.map +1 -0
  518. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js +281 -0
  519. package/build/dist/Utils/Metrics/MetricResourceAttributeUtil.js.map +1 -0
  520. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +8 -6
  521. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
  522. package/build/dist/Utils/StatusPage/GroupHierarchyView.js +560 -0
  523. package/build/dist/Utils/StatusPage/GroupHierarchyView.js.map +1 -0
  524. package/build/dist/Utils/StatusPage/ResourceExplorer.js +519 -0
  525. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -0
  526. package/jest.config.json +1 -0
  527. package/package.json +5 -1
  528. package/tsconfig.json +12 -10
@@ -1,6 +1,7 @@
1
1
  import logger from "../Logger";
2
2
  import CaptureSpan from "../Telemetry/CaptureSpan";
3
3
  import TelemetryUtil from "../Telemetry/Telemetry";
4
+ import MetricResourceAttributeUtil from "../../../Utils/Metrics/MetricResourceAttributeUtil";
4
5
  import MetricService from "../../Services/MetricService";
5
6
  import GlobalConfigService from "../../Services/GlobalConfigService";
6
7
  import GlobalConfig from "../../../Models/DatabaseModels/GlobalConfig";
@@ -8,6 +9,7 @@ import DataToProcess from "./DataToProcess";
8
9
  import { MetricPointType } from "../../../Models/AnalyticsModels/Metric";
9
10
  import ServiceType from "../../../Types/Telemetry/ServiceType";
10
11
  import MetricType from "../../../Models/DatabaseModels/MetricType";
12
+ import Label from "../../../Models/DatabaseModels/Label";
11
13
  import BasicInfrastructureMetrics, {
12
14
  NetworkInterfaceMetrics,
13
15
  } from "../../../Types/Infrastructure/BasicMetrics";
@@ -234,6 +236,47 @@ export default class MonitorMetricUtil {
234
236
  data.metricNameServiceNameMap[data.metricName] = metricType;
235
237
  }
236
238
 
239
+ /**
240
+ * Stamp every metric row produced by one monitor check with the monitor's
241
+ * label and custom field attributes.
242
+ *
243
+ * Done as a single pass over the finished rows rather than threaded through
244
+ * the ~30 emission sites below: every metric from one check describes the
245
+ * same monitor, so there is nothing per-metric to decide, and one pass is
246
+ * far easier to keep correct than thirty call sites.
247
+ *
248
+ * Resource attributes are merged LAST. Custom code monitors let a user
249
+ * supply their own attribute names, and those must not be able to shadow the
250
+ * oneuptime.* namespace.
251
+ */
252
+ public static applyResourceAttributesToMetricRows(data: {
253
+ metricRows: Array<JSONObject>;
254
+ labels?: Array<Label> | undefined;
255
+ customFields?: JSONObject | undefined;
256
+ }): void {
257
+ const resourceAttributes: JSONObject =
258
+ MetricResourceAttributeUtil.getResourceAttributes({
259
+ labels: data.labels,
260
+ customFields: data.customFields,
261
+ });
262
+
263
+ if (Object.keys(resourceAttributes).length === 0) {
264
+ // Nothing to stamp; leave the rows (and their attributeKeys) untouched.
265
+ return;
266
+ }
267
+
268
+ for (const metricRow of data.metricRows) {
269
+ const attributes: JSONObject =
270
+ MetricResourceAttributeUtil.mergeResourceAttributes(
271
+ (metricRow["attributes"] as JSONObject) || {},
272
+ resourceAttributes,
273
+ );
274
+
275
+ metricRow["attributes"] = attributes;
276
+ metricRow["attributeKeys"] = TelemetryUtil.getAttributeKeys(attributes);
277
+ }
278
+ }
279
+
237
280
  @CaptureSpan()
238
281
  public static async saveMonitorMetrics(data: {
239
282
  monitorId: ObjectID;
@@ -241,6 +284,15 @@ export default class MonitorMetricUtil {
241
284
  dataToProcess: DataToProcess;
242
285
  probeName: string | undefined;
243
286
  monitorName: string | undefined;
287
+ /*
288
+ * The monitor's own taxonomy, passed in by the caller which has already
289
+ * loaded the monitor — this is the hottest Postgres path in the product,
290
+ * so nothing here re-reads it. Both are optional: callers that do not
291
+ * select them simply record no oneuptime.label.* / oneuptime.customField.*
292
+ * attributes.
293
+ */
294
+ monitorLabels?: Array<Label> | undefined;
295
+ monitorCustomFields?: JSONObject | undefined;
244
296
  }): Promise<void> {
245
297
  if (!data.monitorId) {
246
298
  return;
@@ -1340,6 +1392,12 @@ export default class MonitorMetricUtil {
1340
1392
  metricNameServiceNameMap[prefixedName] = metricType;
1341
1393
  }
1342
1394
 
1395
+ this.applyResourceAttributesToMetricRows({
1396
+ metricRows: metricRows,
1397
+ labels: data.monitorLabels,
1398
+ customFields: data.monitorCustomFields,
1399
+ });
1400
+
1343
1401
  if (metricRows.length > 0) {
1344
1402
  await MetricService.insertJsonRows(metricRows);
1345
1403
  }
@@ -138,6 +138,18 @@ export default class MonitorResourceUtil {
138
138
  _id: true,
139
139
  name: true,
140
140
  minimumProbeAgreement: true,
141
+ /*
142
+ * Recorded as oneuptime.label.* / oneuptime.customField.* attributes on
143
+ * every monitor metric this result produces, so response time and
144
+ * uptime are groupable by a project's own taxonomy. Selected here
145
+ * rather than re-read inside MonitorMetricUtil: this is the hottest
146
+ * Postgres path in the product and it already loads the monitor.
147
+ */
148
+ labels: {
149
+ _id: true,
150
+ name: true,
151
+ },
152
+ customFields: true,
141
153
  },
142
154
  props: {
143
155
  isRoot: true,
@@ -480,6 +492,8 @@ export default class MonitorResourceUtil {
480
492
  dataToProcess: dataToProcess,
481
493
  probeName: probeName || undefined,
482
494
  monitorName: monitorName || undefined,
495
+ monitorLabels: monitor.labels || undefined,
496
+ monitorCustomFields: monitor.customFields || undefined,
483
497
  });
484
498
  } catch (err) {
485
499
  logger.error("Unable to save metrics");
@@ -24,6 +24,7 @@ import ListData from "../../Types/ListData";
24
24
  import PositiveNumber from "../../Types/PositiveNumber";
25
25
  import Route from "../../Types/API/Route";
26
26
  import CaptureSpan from "./Telemetry/CaptureSpan";
27
+ import { IsBillingEnabled } from "../EnvironmentConfig";
27
28
 
28
29
  export default class Response {
29
30
  @CaptureSpan()
@@ -94,7 +95,17 @@ export default class Response {
94
95
  ): void {
95
96
  const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse;
96
97
 
97
- oneUptimeResponse.render(path, vars);
98
+ /*
99
+ * Analytics is opt-in per render, and off unless this is the hosted
100
+ * product. A self-hosted install has no reason to load Google Tag Manager
101
+ * from googletagmanager.com, and an air-gapped one cannot - it would just
102
+ * be another request left hanging. Same default the frontend index pages
103
+ * already use; passing the flag explicitly still wins.
104
+ */
105
+ oneUptimeResponse.render(path, {
106
+ enableGoogleTagManager: IsBillingEnabled,
107
+ ...vars,
108
+ });
98
109
  }
99
110
 
100
111
  @CaptureSpan()
@@ -0,0 +1,237 @@
1
+ import URL from "../../Types/API/URL";
2
+ import BadDataException from "../../Types/Exception/BadDataException";
3
+ import dns from "dns";
4
+
5
+ const IPV4_LITERAL_REGEX: RegExp = /^(\d{1,3}\.){3}\d{1,3}$/;
6
+ const IPV6_UNIQUE_LOCAL_REGEX: RegExp = /^f[cd][0-9a-f]{2}:/;
7
+
8
+ /*
9
+ * Guards outbound HTTP(S) requests whose target is (fully or partly)
10
+ * attacker-controlled — status page subscriber webhooks, project webhook
11
+ * notifications, etc. — against Server-Side Request Forgery. It rejects URLs
12
+ * that point at loopback, RFC-1918 private ranges, link-local (including the
13
+ * 169.254.169.254 cloud metadata endpoint), CGNAT, and IPv6 loopback /
14
+ * link-local / unique-local addresses, resolving DNS hostnames first so a
15
+ * public-looking name that maps to an internal address is still blocked.
16
+ *
17
+ * This is a best-effort, TOCTOU-susceptible check: a hostname can resolve to a
18
+ * different address between validation and the actual request (DNS rebinding).
19
+ * Callers should therefore ALSO disable redirect-following on the request so a
20
+ * validated public host cannot 3xx-redirect the server to an internal target.
21
+ */
22
+ export default class SSRFProtection {
23
+ /*
24
+ * Returns the bare, lowercased host of a URL — no port, no brackets — or an
25
+ * empty string if it cannot be parsed. Host-pinning allowlists (Slack, Teams)
26
+ * must compare against THIS, never against the whole URL string: a substring
27
+ * check on the full URL is satisfied by an attacker-controlled path or query
28
+ * (`http://169.254.169.254/?x=office.com`) and pins nothing.
29
+ */
30
+ public static getBareHostname(rawUrl: string | URL): string {
31
+ let parsed: URL;
32
+ try {
33
+ parsed = URL.fromString(rawUrl.toString());
34
+ } catch {
35
+ return "";
36
+ }
37
+
38
+ return SSRFProtection.extractHost(parsed.hostname.hostname.toLowerCase());
39
+ }
40
+
41
+ /*
42
+ * True when the URL's host is exactly one of `allowedDomains` or a subdomain
43
+ * of one, and the scheme is https. Suffix matching is anchored on a leading
44
+ * dot so `office.com.attacker.tld` and `evil-office.com` are both rejected.
45
+ */
46
+ public static isUrlOnAllowedDomain(
47
+ rawUrl: string | URL,
48
+ allowedDomains: Array<string>,
49
+ ): boolean {
50
+ let parsed: URL;
51
+ try {
52
+ parsed = URL.fromString(rawUrl.toString());
53
+ } catch {
54
+ return false;
55
+ }
56
+
57
+ if (parsed.protocol.toString().toLowerCase() !== "https://") {
58
+ return false;
59
+ }
60
+
61
+ const hostname: string = SSRFProtection.getBareHostname(rawUrl);
62
+
63
+ if (!hostname) {
64
+ return false;
65
+ }
66
+
67
+ return allowedDomains.some((domain: string) => {
68
+ const allowed: string = domain.toLowerCase();
69
+ return hostname === allowed || hostname.endsWith(`.${allowed}`);
70
+ });
71
+ }
72
+
73
+ public static async validateWebhookTargetIsSafe(
74
+ rawUrl: string | URL,
75
+ ): Promise<void> {
76
+ let parsed: URL;
77
+ try {
78
+ parsed = URL.fromString(rawUrl.toString());
79
+ } catch {
80
+ throw new BadDataException("Webhook URL is not a valid URL");
81
+ }
82
+
83
+ const protocolValue: string = parsed.protocol.toString().toLowerCase();
84
+ if (protocolValue !== "http://" && protocolValue !== "https://") {
85
+ throw new BadDataException(
86
+ "Webhook URL must use http or https protocol.",
87
+ );
88
+ }
89
+
90
+ const rawHost: string = parsed.hostname.hostname.toLowerCase();
91
+
92
+ if (!rawHost) {
93
+ throw new BadDataException("Webhook URL must include a host.");
94
+ }
95
+
96
+ /*
97
+ * OneUptime's URL parser keeps the port glued to the host (e.g.
98
+ * "169.254.169.254:80"). Strip it before the checks below, otherwise a
99
+ * literal-with-port slips past the IPv4 blocklist and, because it contains
100
+ * a ":", is mistaken for an IP literal and skips DNS resolution entirely.
101
+ */
102
+ const hostname: string = SSRFProtection.extractHost(rawHost);
103
+
104
+ if (!hostname) {
105
+ throw new BadDataException("Webhook URL must include a host.");
106
+ }
107
+
108
+ if (SSRFProtection.isBlockedHostnameLiteral(hostname)) {
109
+ throw new BadDataException(
110
+ "Webhook URL points to a private, loopback, or link-local address and is not allowed.",
111
+ );
112
+ }
113
+
114
+ if (!SSRFProtection.isIpLiteral(hostname)) {
115
+ let resolved: Array<{ address: string }> = [];
116
+ try {
117
+ resolved = await dns.promises.lookup(hostname, { all: true });
118
+ } catch {
119
+ throw new BadDataException(
120
+ "Webhook URL hostname could not be resolved via DNS.",
121
+ );
122
+ }
123
+
124
+ for (const entry of resolved) {
125
+ if (
126
+ SSRFProtection.isBlockedHostnameLiteral(entry.address.toLowerCase())
127
+ ) {
128
+ throw new BadDataException(
129
+ "Webhook URL resolves to a private, loopback, or link-local address and is not allowed.",
130
+ );
131
+ }
132
+ }
133
+ }
134
+ }
135
+
136
+ /*
137
+ * Extracts the bare host (IPv4, IPv6, or hostname) from a "host[:port]"
138
+ * string, handling bracketed IPv6 (`[::1]`, `[::1]:8080`) and unbracketed
139
+ * IPv6 literals (which contain multiple colons and carry no port).
140
+ */
141
+ private static extractHost(hostWithPort: string): string {
142
+ const host: string = hostWithPort.trim();
143
+
144
+ if (host.startsWith("[")) {
145
+ const closingBracketIndex: number = host.indexOf("]");
146
+ if (closingBracketIndex !== -1) {
147
+ return host.slice(1, closingBracketIndex);
148
+ }
149
+ return host.replace(/^\[|\]$/g, "");
150
+ }
151
+
152
+ const colonCount: number = (host.match(/:/g) || []).length;
153
+
154
+ if (colonCount > 1) {
155
+ // Unbracketed IPv6 literal — colons are part of the address, not a port.
156
+ return host;
157
+ }
158
+
159
+ if (colonCount === 1) {
160
+ // host:port — keep only the host part.
161
+ return host.split(":")[0] || "";
162
+ }
163
+
164
+ return host;
165
+ }
166
+
167
+ private static isIpLiteral(hostname: string): boolean {
168
+ return IPV4_LITERAL_REGEX.test(hostname) || hostname.includes(":");
169
+ }
170
+
171
+ private static isBlockedHostnameLiteral(hostname: string): boolean {
172
+ if (
173
+ hostname === "localhost" ||
174
+ hostname.endsWith(".localhost") ||
175
+ hostname === "metadata.google.internal"
176
+ ) {
177
+ return true;
178
+ }
179
+
180
+ const ipv4Match: RegExpMatchArray | null = hostname.match(
181
+ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/,
182
+ );
183
+ if (ipv4Match) {
184
+ const octets: Array<number> = [
185
+ Number(ipv4Match[1]),
186
+ Number(ipv4Match[2]),
187
+ Number(ipv4Match[3]),
188
+ Number(ipv4Match[4]),
189
+ ];
190
+
191
+ if (
192
+ octets.some((o: number) => {
193
+ return o < 0 || o > 255;
194
+ })
195
+ ) {
196
+ return true;
197
+ }
198
+ if (octets[0] === 0) {
199
+ return true;
200
+ }
201
+ if (octets[0] === 127) {
202
+ return true;
203
+ }
204
+ if (octets[0] === 10) {
205
+ return true;
206
+ }
207
+ if (octets[0] === 172 && (octets[1]! & 0xf0) === 16) {
208
+ return true;
209
+ }
210
+ if (octets[0] === 192 && octets[1] === 168) {
211
+ return true;
212
+ }
213
+ if (octets[0] === 169 && octets[1] === 254) {
214
+ return true;
215
+ }
216
+ if (octets[0] === 100 && (octets[1]! & 0xc0) === 64) {
217
+ return true;
218
+ }
219
+ return false;
220
+ }
221
+
222
+ if (hostname.includes(":")) {
223
+ const stripped: string = hostname.replace(/^\[|\]$/g, "");
224
+ if (stripped === "::1" || stripped === "::") {
225
+ return true;
226
+ }
227
+ if (stripped.startsWith("fe80:") || stripped.startsWith("fe80::")) {
228
+ return true;
229
+ }
230
+ if (IPV6_UNIQUE_LOCAL_REGEX.test(stripped)) {
231
+ return true;
232
+ }
233
+ }
234
+
235
+ return false;
236
+ }
237
+ }
@@ -34,6 +34,7 @@ import "./Process";
34
34
  import Response from "./Response";
35
35
  import SpanUtil from "./Telemetry/SpanUtil";
36
36
  import TelemetryContext from "./Telemetry/TelemetryContext";
37
+ import mountVendorAssets from "./VendorAssets";
37
38
  import { api } from "@opentelemetry/sdk-node";
38
39
  import StatusCode from "../../Types/API/StatusCode";
39
40
  import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
@@ -303,6 +304,13 @@ const init: InitFunction = async (
303
304
  statusOptions: data.statusOptions,
304
305
  });
305
306
 
307
+ /*
308
+ * Ahead of the frontend static mounts and every catch-all below them, so a
309
+ * service that answers "/*" with its index page cannot swallow a request for
310
+ * a stylesheet.
311
+ */
312
+ mountVendorAssets(app);
313
+
306
314
  if (isFrontendApp) {
307
315
  app.use(ExpressStatic("/usr/src/app/public"));
308
316
 
@@ -4,6 +4,7 @@ import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
4
4
  import HTTPResponse from "../../Types/API/HTTPResponse";
5
5
  import { JSONObject } from "../../Types/JSON";
6
6
  import logger from "./Logger";
7
+ import SSRFProtection from "./SSRFProtection";
7
8
 
8
9
  export interface StatusPageWebhookPayload extends JSONObject {
9
10
  eventType: string;
@@ -21,6 +22,30 @@ export default class StatusPageSubscriberWebhookUtil {
21
22
  }): Promise<HTTPResponse<JSONObject> | HTTPErrorResponse> {
22
23
  logger.debug("Sending status page subscriber webhook notification.");
23
24
 
25
+ /*
26
+ * The subscriber webhook target is attacker-controllable: any unauthenticated
27
+ * visitor can register a subscriber with an arbitrary webhook URL on a public
28
+ * status page. Validate it against the SSRF blocklist before every send (not
29
+ * just at create time) so previously-stored URLs and DNS-rebinding cannot make
30
+ * the server reach internal services or the cloud metadata endpoint.
31
+ */
32
+ try {
33
+ await SSRFProtection.validateWebhookTargetIsSafe(data.webhookUrl);
34
+ } catch (err) {
35
+ logger.warn(
36
+ "Refusing to send status page subscriber webhook: unsafe URL.",
37
+ );
38
+ logger.warn(err);
39
+ return new HTTPErrorResponse(
40
+ 400,
41
+ {
42
+ message:
43
+ err instanceof Error ? err.message : "Webhook URL is not allowed.",
44
+ },
45
+ {},
46
+ );
47
+ }
48
+
24
49
  const apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse =
25
50
  await API.post({
26
51
  url: data.webhookUrl,
@@ -28,6 +53,11 @@ export default class StatusPageSubscriberWebhookUtil {
28
53
  options: {
29
54
  retries: 3,
30
55
  exponentialBackoff: true,
56
+ /*
57
+ * Do not follow redirects: a validated public host could otherwise
58
+ * 3xx-redirect the server to an internal address, bypassing the check.
59
+ */
60
+ doNotFollowRedirects: true,
31
61
  },
32
62
  });
33
63
 
@@ -38,35 +38,47 @@ function CaptureSpan(data?: {
38
38
  data?.name || `${className}.${propertyKey}`;
39
39
 
40
40
  descriptor.value = function (...args: any[]) {
41
- if (DisableTelemetry) {
41
+ /*
42
+ * Skip the span machinery entirely when telemetry is disabled OR no
43
+ * span exporter is installed. Without an exporter the span is never
44
+ * shipped anywhere, but creating it still costs attribute flattening,
45
+ * a span allocation, and an AsyncLocalStorage context transition —
46
+ * decorated methods sit on ingest hot paths that run millions of
47
+ * times per minute, so this must be a plain method call there.
48
+ */
49
+ if (DisableTelemetry || !Telemetry.isSpanExportEnabled()) {
42
50
  return originalMethod.apply(this, args);
43
51
  }
44
52
 
45
- let functionArguments: JSONObject = {};
53
+ /*
54
+ * Only pay for attribute flattening when there is something to
55
+ * flatten — the overwhelmingly common bare @CaptureSpan() form has
56
+ * neither captured arguments nor static attributes.
57
+ */
58
+ let spanAttributes: { [key: string]: any } | undefined = undefined;
46
59
 
47
- if (data?.captureArguments) {
48
- functionArguments = args.reduce(
49
- (acc: { [key: string]: any }, arg: any, index: number) => {
50
- acc[`arg${index}`] = arg;
51
- return acc;
52
- },
53
- {},
54
- );
55
- }
60
+ if (data?.captureArguments || data?.attributes) {
61
+ let functionArguments: JSONObject = {};
62
+
63
+ if (data?.captureArguments) {
64
+ functionArguments = args.reduce(
65
+ (acc: { [key: string]: any }, arg: any, index: number) => {
66
+ acc[`arg${index}`] = arg;
67
+ return acc;
68
+ },
69
+ {},
70
+ );
71
+ }
56
72
 
57
- const spanAttributes: { [key: string]: any } =
58
- JSONFunctions.flattenObject({
73
+ spanAttributes = JSONFunctions.flattenObject({
59
74
  ...functionArguments,
60
75
  ...data?.attributes,
61
76
  }) as { [key: string]: any };
77
+ }
62
78
 
63
79
  return Telemetry.startActiveSpan({
64
80
  name: name,
65
- options: {
66
- attributes: {
67
- ...spanAttributes,
68
- },
69
- },
81
+ options: spanAttributes ? { attributes: spanAttributes } : {},
70
82
  fn: (span: Span) => {
71
83
  let result: any = null;
72
84
  try {
@@ -0,0 +1,75 @@
1
+ import OneUptimeDate from "../../../Types/Date";
2
+
3
+ /*
4
+ * Per-second memo for the wall-clock stamps every ingested telemetry row
5
+ * carries (createdAt and retentionDate, both stored with second
6
+ * granularity).
7
+ *
8
+ * The Otel logs / traces / metrics row builders used to derive these per
9
+ * row: a current-Date allocation, a ClickHouse DateTime format, a
10
+ * moment-based add-days, and a second format — for every log record, span,
11
+ * and metric datapoint. All of that output only changes once per second
12
+ * (createdAt has no sub-second component) and once per distinct retention
13
+ * window, so a burst of rows in the same second re-derived identical
14
+ * strings millions of times. This memo pays the derivation once per second
15
+ * (and once per retention window within that second) instead.
16
+ *
17
+ * Not thread-shared state to worry about: workers are single-threaded, and
18
+ * the memo is replaced wholesale when the second rolls over, so the map of
19
+ * retention strings can never grow past the number of distinct retention
20
+ * windows seen within one second.
21
+ */
22
+
23
+ export interface IngestionStamp {
24
+ /** Current time truncated to the second the stamp was minted. */
25
+ date: Date;
26
+ /** ClickHouse DateTime string ("YYYY-MM-DD HH:mm:ss", UTC) of `date`. */
27
+ db: string;
28
+ }
29
+
30
+ type CachedStamp = IngestionStamp & {
31
+ epochSecond: number;
32
+ retentionDbByDays: Map<number, string>;
33
+ };
34
+
35
+ let cachedStamp: CachedStamp | null = null;
36
+
37
+ export function getIngestionStamp(): IngestionStamp {
38
+ const epochSecond: number = Math.floor(Date.now() / 1000);
39
+
40
+ if (!cachedStamp || cachedStamp.epochSecond !== epochSecond) {
41
+ const date: Date = new Date(epochSecond * 1000);
42
+ cachedStamp = {
43
+ epochSecond: epochSecond,
44
+ date: date,
45
+ db: OneUptimeDate.toClickhouseDateTime(date),
46
+ retentionDbByDays: new Map<number, string>(),
47
+ };
48
+ }
49
+
50
+ return cachedStamp;
51
+ }
52
+
53
+ /*
54
+ * ClickHouse DateTime string for `stamp.date + retentionDays`, memoized per
55
+ * (stamp second, retention window). Must be called with a stamp obtained
56
+ * from getIngestionStamp() in the same row-building pass, so the retention
57
+ * date stays consistent with the row's createdAt.
58
+ */
59
+ export function getRetentionDateDb(
60
+ stamp: IngestionStamp,
61
+ retentionDays: number,
62
+ ): string {
63
+ const cached: CachedStamp = stamp as CachedStamp;
64
+
65
+ let db: string | undefined = cached.retentionDbByDays?.get(retentionDays);
66
+
67
+ if (db === undefined) {
68
+ db = OneUptimeDate.toClickhouseDateTime(
69
+ OneUptimeDate.addRemoveDays(stamp.date, retentionDays),
70
+ );
71
+ cached.retentionDbByDays?.set(retentionDays, db);
72
+ }
73
+
74
+ return db;
75
+ }