@oneuptime/common 12.0.33 → 12.0.34

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 (652) hide show
  1. package/Models/AnalyticsModels/RumSession.ts +117 -1
  2. package/Models/AnalyticsModels/RumSessionChunk.ts +13 -0
  3. package/Models/DatabaseModels/AlertCustomField.ts +77 -3
  4. package/Models/DatabaseModels/ApiKeyPermission.ts +3 -27
  5. package/Models/DatabaseModels/IncidentCustomField.ts +77 -3
  6. package/Models/DatabaseModels/InventoryItemCustomField.ts +77 -3
  7. package/Models/DatabaseModels/MonitorCustomField.ts +77 -3
  8. package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +77 -3
  9. package/Models/DatabaseModels/RumApplication.ts +6 -6
  10. package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +77 -3
  11. package/Models/DatabaseModels/StatusPageCustomField.ts +77 -3
  12. package/Models/DatabaseModels/TeamCustomField.ts +77 -3
  13. package/Models/DatabaseModels/TeamMember.ts +0 -9
  14. package/Models/DatabaseModels/TeamMemberCustomField.ts +77 -3
  15. package/Models/DatabaseModels/TeamPermission.ts +3 -24
  16. package/Models/DatabaseModels/TelemetryIngestionKey.ts +260 -0
  17. package/Models/DatabaseModels/UserTelegram.ts +0 -4
  18. package/Scripts/benchmark-fanin-capacity.js +181 -0
  19. package/Server/API/TelemetryAPI.ts +1284 -164
  20. package/Server/API/UserNotificationSettingAPI.ts +55 -0
  21. package/Server/API/UserTelegramAPI.ts +48 -4
  22. package/Server/EnvironmentConfig.ts +35 -2
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.ts +91 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.ts +67 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.ts +139 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.ts +121 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  28. package/Server/Infrastructure/QueueWorker.ts +20 -14
  29. package/Server/Infrastructure/Semaphore.ts +2 -0
  30. package/Server/Middleware/TelemetryIngest.ts +453 -7
  31. package/Server/Services/AccessTokenService.ts +1 -0
  32. package/Server/Services/AlertCustomFieldService.ts +98 -0
  33. package/Server/Services/AlertService.ts +37 -0
  34. package/Server/Services/ApiKeyPermissionService.ts +461 -29
  35. package/Server/Services/CustomFieldMappingService.ts +879 -0
  36. package/Server/Services/GlobalConfigService.ts +194 -0
  37. package/Server/Services/IncidentCustomFieldService.ts +98 -0
  38. package/Server/Services/IncidentService.ts +35 -0
  39. package/Server/Services/MetricService.ts +194 -0
  40. package/Server/Services/MonitorService.ts +32 -0
  41. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +78 -25
  42. package/Server/Services/ProjectService.ts +22 -0
  43. package/Server/Services/RoutineEmailSettingsService.ts +73 -0
  44. package/Server/Services/RumSessionReplayViewService.ts +104 -24
  45. package/Server/Services/ScheduledMaintenanceCustomFieldService.ts +98 -0
  46. package/Server/Services/ScheduledMaintenanceService.ts +32 -0
  47. package/Server/Services/TeamMemberService.ts +78 -0
  48. package/Server/Services/TeamPermissionService.ts +235 -3
  49. package/Server/Services/TelemetryIngestionKeyService.ts +722 -19
  50. package/Server/Services/UserNotificationSettingService.ts +34 -6
  51. package/Server/Services/UserTelegramService.ts +326 -5
  52. package/Server/Types/Database/QueryHelper.ts +2 -0
  53. package/Server/Utils/APIKey/AccessPermission.ts +5 -2
  54. package/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.ts +54 -0
  55. package/Server/Utils/CustomField/CustomFieldMappingRegistry.ts +415 -0
  56. package/Server/Utils/CustomField/CustomFieldMappingValidator.ts +335 -0
  57. package/Server/Utils/DataSource/EgressGuard.ts +177 -8
  58. package/Server/Utils/EmailRollup/EmailRollupConstants.ts +38 -5
  59. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +57 -4
  60. package/Server/Utils/FrontendEnvironment.ts +40 -0
  61. package/Server/Utils/LogRedaction.ts +20 -0
  62. package/Server/Utils/Logger.ts +11 -0
  63. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +338 -77
  64. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +30 -4
  65. package/Server/Utils/Monitor/MonitorAlert.ts +29 -6
  66. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +110 -15
  67. package/Server/Utils/Monitor/MonitorIncident.ts +22 -6
  68. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +29 -0
  69. package/Server/Utils/Monitor/SeriesContextEnricher.ts +304 -0
  70. package/Server/Utils/SSRFProtection.ts +217 -10
  71. package/Server/Utils/SessionReplay/SessionReplayGateCache.ts +239 -138
  72. package/Server/Utils/SessionReplay/SessionReplayHealthCounters.ts +305 -0
  73. package/Server/Utils/SessionReplay/SessionReplayReadService.ts +1430 -289
  74. package/Server/Utils/StartServer.ts +2 -17
  75. package/Server/Utils/TelegramVerificationToken.ts +185 -0
  76. package/Server/Utils/Telemetry/PinServiceName.ts +197 -0
  77. package/Server/Utils/Telemetry/TelemetryFanInWriter.ts +38 -16
  78. package/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.ts +92 -0
  79. package/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.ts +217 -0
  80. package/Server/Utils/VM/VMAPI.ts +1 -0
  81. package/Server/Utils/VM/VMRunner.ts +975 -95
  82. package/Tests/App/AdminDashboard/AdminHeaderSmallScreens.test.tsx +202 -0
  83. package/Tests/App/Dashboard/DashboardHeaderSmallScreens.test.tsx +404 -0
  84. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +468 -0
  85. package/Tests/App/Dashboard/NotificationEmailPreferences.test.tsx +399 -0
  86. package/Tests/App/StatusPage/StatusPageLastUpdated.test.tsx +263 -0
  87. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +753 -0
  88. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +224 -0
  89. package/Tests/Models/AnalyticsModels/RumSessionReplayColumns.test.ts +262 -0
  90. package/Tests/Models/CustomFieldMappingColumns.test.ts +166 -0
  91. package/Tests/Models/DatabaseModels/SessionReplayModels.test.ts +20 -6
  92. package/Tests/ResponsiveVisibility.test.ts +115 -0
  93. package/Tests/ResponsiveVisibility.ts +183 -0
  94. package/Tests/Server/API/SessionReplayAPI.test.ts +1940 -216
  95. package/Tests/Server/API/UserNotificationSettingAPI.test.ts +186 -0
  96. package/Tests/Server/API/UserTelegramAPISecurity.test.ts +231 -0
  97. package/Tests/Server/EnvironmentConfigFrontendSecurity.test.ts +234 -0
  98. package/Tests/Server/Infrastructure/Postgres/CustomFieldValueMappingMigration.test.ts +202 -0
  99. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +41 -0
  100. package/Tests/Server/Infrastructure/Postgres/SessionReplayRecordEverySessionByDefaultMigration.test.ts +169 -0
  101. package/Tests/Server/Infrastructure/QueueWorkerTimeout.test.ts +210 -0
  102. package/Tests/Server/Infrastructure/TelemetryExporterDeploymentConfig.test.ts +130 -0
  103. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +4 -1
  104. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +1163 -0
  105. package/Tests/Server/Middleware/TelemetryIngestTokenLog.test.ts +5 -3
  106. package/Tests/Server/Services/AddTelemetryIngestionKeyTypeMigration.test.ts +555 -0
  107. package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +678 -0
  108. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +276 -28
  109. package/Tests/Server/Services/CustomFieldDropdownOptionsColumnWidth.test.ts +431 -0
  110. package/Tests/Server/Services/CustomFieldMappingService.test.ts +850 -0
  111. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +32 -0
  112. package/Tests/Server/Services/GlobalConfigService.test.ts +414 -1
  113. package/Tests/Server/Services/MetricRawEntityKeyPrune.test.ts +592 -0
  114. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +226 -1
  115. package/Tests/Server/Services/RoutineEmailSettingsPostgres.test.ts +329 -0
  116. package/Tests/Server/Services/RumSessionReplayViewService.test.ts +267 -0
  117. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +9 -0
  118. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +9 -0
  119. package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +834 -0
  120. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +814 -0
  121. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +998 -0
  122. package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +141 -0
  123. package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +18 -10
  124. package/Tests/Server/Services/UserTelegramVerificationSecurity.test.ts +688 -0
  125. package/Tests/Server/Utils/AI/SRE/Insights/FixRouting.test.ts +497 -0
  126. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +383 -0
  127. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +7 -3
  128. package/Tests/Server/Utils/AnalyticsDatabase/ClusterConfig.test.ts +315 -0
  129. package/Tests/Server/Utils/CustomField/CustomFieldMappingValidator.test.ts +437 -0
  130. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +300 -11
  131. package/Tests/Server/Utils/EmailRollup/EmailRollupBurstWindow.test.ts +83 -0
  132. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1 -1
  133. package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerPreferences.test.ts +362 -0
  134. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +77 -1
  135. package/Tests/Server/Utils/FrontendEnvironment.test.ts +190 -0
  136. package/Tests/Server/Utils/LogRedaction.test.ts +26 -0
  137. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +23 -9
  138. package/Tests/Server/Utils/Monitor/Criteria/CompareCriteriaAggregation.test.ts +584 -0
  139. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestHeaderCriteria.test.ts +236 -0
  140. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +437 -0
  141. package/Tests/Server/Utils/Monitor/MonitorTemplateUtilSeriesContext.test.ts +176 -0
  142. package/Tests/Server/Utils/Monitor/SeriesContextEnricher.test.ts +356 -0
  143. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +595 -0
  144. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCachePolicy.test.ts +198 -1
  145. package/Tests/Server/Utils/SessionReplay/SessionReplayHealthCounters.test.ts +453 -0
  146. package/Tests/Server/Utils/SessionReplay/SessionReplayReadServiceQueries.test.ts +1378 -0
  147. package/Tests/Server/Utils/SessionReplayOriginAllowListRefactor.test.ts +420 -0
  148. package/Tests/Server/Utils/TelegramVerificationToken.test.ts +253 -0
  149. package/Tests/Server/Utils/Telemetry/PinServiceName.test.ts +666 -0
  150. package/Tests/Server/Utils/Telemetry/TelemetryFanInWriterCapacity.test.ts +458 -0
  151. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +424 -0
  152. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.test.ts +528 -0
  153. package/Tests/Server/Utils/TelemetryExporterEnvironment.test.ts +56 -0
  154. package/Tests/Server/Utils/VM/VMRunnerHostBridgeLatency.test.ts +74 -0
  155. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +100 -7
  156. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +1176 -6
  157. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +220 -0
  158. package/Tests/Types/CustomField/CustomFieldValueMapping.test.ts +348 -0
  159. package/Tests/Types/JSONFunctions.test.ts +260 -0
  160. package/Tests/Types/Monitor/CephAlertTemplates.test.ts +422 -53
  161. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +495 -15
  162. package/Tests/Types/Monitor/DockerSwarmAlertTemplates.test.ts +191 -45
  163. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +370 -42
  164. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +375 -20
  165. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +636 -42
  166. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +189 -0
  167. package/Tests/Types/Monitor/KubernetesTemplateGroupByKeys.test.ts +95 -14
  168. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +190 -21
  169. package/Tests/Types/Monitor/ProxmoxAlertTemplates.test.ts +352 -22
  170. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +363 -0
  171. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +93 -18
  172. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +259 -0
  173. package/Tests/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.test.ts +476 -0
  174. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +136 -0
  175. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +661 -0
  176. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +507 -0
  177. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +270 -0
  178. package/Tests/Types/Monitor/TemplateGroupByKeys.test.ts +38 -10
  179. package/Tests/Types/Monitor/Utils/RecommendationCriteriaAssertions.ts +102 -0
  180. package/Tests/Types/NotificationSetting/RoutineEmailEvents.test.ts +47 -0
  181. package/Tests/Types/Rum/SessionReplayApiContracts.test.ts +608 -0
  182. package/Tests/Types/Rum/SessionReplayCustomEvents.test.ts +434 -0
  183. package/Tests/Types/WebsiteRequest.test.ts +285 -3
  184. package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +16 -3
  185. package/Tests/UI/Components/Charts/ChartTrailingBucketGap.test.ts +691 -0
  186. package/Tests/UI/Components/ComponentsModal.test.tsx +12 -4
  187. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +518 -0
  188. package/Tests/UI/Components/CustomFields/CustomFieldsDetailMapping.test.tsx +324 -0
  189. package/Tests/UI/Components/CustomFields/MapFromCustomFieldInput.test.tsx +176 -0
  190. package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +484 -0
  191. package/Tests/UI/Components/HeaderRightRail.test.tsx +157 -0
  192. package/Tests/UI/Components/IconDropdownItem.test.tsx +102 -0
  193. package/Tests/UI/Components/JSONTablePrototypePollution.test.tsx +117 -0
  194. package/Tests/UI/Components/KeyboardShortcutsModal.test.tsx +214 -0
  195. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +561 -0
  196. package/Tests/UI/Components/MonitorGraphs/UptimeBarDayModal.test.tsx +302 -0
  197. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +28 -12
  198. package/Tests/UI/Components/ShortcutDialogGuard.test.tsx +74 -0
  199. package/Tests/UI/Components/StatusPage/ResourceGroupSectionAutoExpand.test.tsx +248 -0
  200. package/Tests/UI/Components/TableCellWrapping.test.tsx +625 -0
  201. package/Tests/UI/Components/TableLoadingStates.test.tsx +205 -0
  202. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +148 -0
  203. package/Tests/UI/Components/Workflow/Workflow.test.tsx +981 -0
  204. package/Tests/UI/ConfigBrowserTelemetry.test.ts +70 -0
  205. package/Tests/UI/Rum/ChunkLoader.test.ts +1036 -2
  206. package/Tests/UI/Rum/FidelityNotices.test.ts +187 -0
  207. package/Tests/UI/Rum/InactivityMap.test.ts +341 -0
  208. package/Tests/UI/Rum/PrivacySummaryCard.test.tsx +259 -0
  209. package/Tests/UI/Rum/RecordingHealthCard.test.tsx +855 -0
  210. package/Tests/UI/Rum/RecordingHealthStrip.test.tsx +594 -0
  211. package/Tests/UI/Rum/ReplayCard.test.tsx +451 -0
  212. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +536 -0
  213. package/Tests/UI/Rum/ReplayEngine.test.ts +2503 -0
  214. package/Tests/UI/Rum/ReplayEngineTypes.test.ts +171 -0
  215. package/Tests/UI/Rum/ReplayHeader.test.tsx +711 -0
  216. package/Tests/UI/Rum/ReplayLink.test.tsx +119 -0
  217. package/Tests/UI/Rum/ReplayPinControl.test.tsx +408 -0
  218. package/Tests/UI/Rum/ReplayPlaybackIntent.test.ts +152 -0
  219. package/Tests/UI/Rum/ReplayRail.test.tsx +1296 -0
  220. package/Tests/UI/Rum/ReplayRailDetail.test.tsx +900 -0
  221. package/Tests/UI/Rum/ReplayScrubber.test.tsx +763 -147
  222. package/Tests/UI/Rum/ReplaySignalTypes.test.ts +189 -0
  223. package/Tests/UI/Rum/ReplaySignals.test.ts +1579 -0
  224. package/Tests/UI/Rum/ReplayStage.test.tsx +396 -473
  225. package/Tests/UI/Rum/ReplayStageOverlays.test.tsx +918 -0
  226. package/Tests/UI/Rum/ReplayTimeline.test.tsx +696 -0
  227. package/Tests/UI/Rum/SessionReplayEmptyState.test.tsx +499 -0
  228. package/Tests/UI/Rum/SessionReplaySearchBar.test.tsx +346 -0
  229. package/Tests/UI/Rum/SessionReplaySetupGuide.test.tsx +545 -0
  230. package/Tests/UI/Rum/SessionReplayTable.test.tsx +991 -0
  231. package/Tests/UI/Rum/TargetedCapturePanel.test.tsx +254 -0
  232. package/Tests/UI/Telemetry/BrowserExporterIsolation.test.ts +71 -0
  233. package/Tests/UI/Utils/GlobalKeyboardShortcut.test.ts +344 -0
  234. package/Tests/Utils/API.test.ts +308 -0
  235. package/Tests/Utils/HTTPResponseBodyReader.test.ts +323 -0
  236. package/Tests/Utils/NetworkDiscovery/DiscoveryScanStatus.test.ts +117 -0
  237. package/Tests/Utils/Rum/ChunkMath.test.ts +83 -0
  238. package/Tests/Utils/Rum/SessionReplayHealthDiagnosis.test.ts +993 -0
  239. package/Tests/Utils/Rum/SessionReplayStringMap.test.ts +245 -0
  240. package/Tests/Utils/StatusPage/ResourceSearch.test.ts +631 -0
  241. package/Tests/Utils/Telemetry/OriginAllowList.test.ts +633 -0
  242. package/Tests/Utils/Uptime/DayUptimeGraphUtil.test.ts +461 -0
  243. package/Tests/Utils/ValueFormatter.test.ts +148 -0
  244. package/Types/CustomField/CustomFieldMappingCatalog.ts +161 -0
  245. package/Types/CustomField/CustomFieldMappingSourceResource.ts +19 -0
  246. package/Types/CustomField/CustomFieldValueMapping.ts +288 -0
  247. package/Types/Icon/IconProp.ts +1 -0
  248. package/Types/JSONFunctions.ts +189 -43
  249. package/Types/Monitor/CephAlertTemplates.ts +157 -195
  250. package/Types/Monitor/DockerAlertTemplates.ts +338 -128
  251. package/Types/Monitor/DockerSwarmAlertTemplates.ts +95 -112
  252. package/Types/Monitor/HostAlertTemplates.ts +302 -130
  253. package/Types/Monitor/IotAlertTemplates.ts +112 -104
  254. package/Types/Monitor/KubernetesAlertTemplates.ts +415 -224
  255. package/Types/Monitor/KubernetesMetricCatalog.ts +23 -19
  256. package/Types/Monitor/PodmanAlertTemplates.ts +116 -163
  257. package/Types/Monitor/ProxmoxAlertTemplates.ts +217 -99
  258. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +98 -6
  259. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +44 -7
  260. package/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.ts +383 -0
  261. package/Types/Monitor/RumAlertTemplates.ts +46 -7
  262. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +596 -0
  263. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +554 -0
  264. package/Types/Monitor/ServiceAlertTemplates.ts +98 -11
  265. package/Types/Monitor/UptimeHistoryLabels.ts +56 -0
  266. package/Types/NotificationSetting/RoutineEmailEvents.ts +30 -0
  267. package/Types/Rum/SessionReplay.ts +209 -0
  268. package/Types/Rum/SessionReplayApi.ts +722 -0
  269. package/Types/Rum/SessionReplayCaptureTrigger.ts +21 -12
  270. package/Types/Rum/SessionReplayConsentMode.ts +11 -7
  271. package/Types/Rum/SessionReplayCustomEvents.ts +549 -0
  272. package/Types/Rum/SessionReplayHealth.ts +238 -0
  273. package/Types/Telemetry/TelemetryIngestSurface.ts +95 -0
  274. package/Types/Telemetry/TelemetryIngestionKeyPolicy.ts +75 -0
  275. package/Types/Telemetry/TelemetryIngestionKeyType.ts +29 -0
  276. package/Types/WebsiteRequest.ts +85 -3
  277. package/UI/Components/Charts/Area/AreaChart.tsx +13 -2
  278. package/UI/Components/Charts/Bar/BarChart.tsx +6 -2
  279. package/UI/Components/Charts/Line/LineChart.tsx +13 -2
  280. package/UI/Components/Charts/Types/XAxis/XAxis.ts +29 -0
  281. package/UI/Components/Charts/Utils/DataPoint.ts +22 -3
  282. package/UI/Components/Charts/Utils/TimeAnnotation.ts +76 -9
  283. package/UI/Components/Charts/Utils/XAxis.ts +217 -0
  284. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +143 -25
  285. package/UI/Components/CustomFields/MapFromCustomFieldInput.tsx +216 -0
  286. package/UI/Components/Graphs/DayUptimeGraph.tsx +173 -8
  287. package/UI/Components/Graphs/UptimeBarTooltip.tsx +22 -278
  288. package/UI/Components/Graphs/UptimeDaySummary.tsx +327 -0
  289. package/UI/Components/Header/Header.tsx +25 -9
  290. package/UI/Components/Header/IconDropdown/IconDropdownItem.tsx +10 -1
  291. package/UI/Components/Header/IconDropdown/IconDropdownMenu.tsx +6 -1
  292. package/UI/Components/Header/ProjectPicker/ProjectPicker.tsx +6 -1
  293. package/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.tsx +6 -1
  294. package/UI/Components/Icon/Icon.tsx +11 -0
  295. package/UI/Components/JSONTable/JSONTable.tsx +2 -2
  296. package/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.tsx +125 -0
  297. package/UI/Components/KeyboardShortcut/Screenshots/README.md +19 -0
  298. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-command-palette.png +0 -0
  299. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog-dark.png +0 -0
  300. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-dialog.png +0 -0
  301. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-help-menu.png +0 -0
  302. package/UI/Components/KeyboardShortcut/Screenshots/keyboard-shortcuts-narrow.png +0 -0
  303. package/UI/Components/ModelTable/Column.ts +15 -0
  304. package/UI/Components/Monitor/SeriesDebugCommandsViewer.tsx +64 -0
  305. package/UI/Components/Monitor/SeriesLabelsViewer.tsx +93 -0
  306. package/UI/Components/MonitorGraphs/Uptime.tsx +14 -2
  307. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +63 -10
  308. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
  309. package/UI/Components/StatusPage/ResourceGroupSection.tsx +40 -0
  310. package/UI/Components/Table/CellClassName.ts +81 -0
  311. package/UI/Components/Table/TableRow.tsx +20 -14
  312. package/UI/Components/Table/TableSkeletonRows.tsx +9 -9
  313. package/UI/Components/Table/Types/Column.ts +36 -0
  314. package/UI/Components/Tooltip/Tooltip.tsx +11 -1
  315. package/UI/Components/Workflow/ComponentsModal.tsx +60 -39
  316. package/UI/Components/Workflow/NodePlacement.ts +57 -0
  317. package/UI/Components/Workflow/Workflow.tsx +47 -18
  318. package/UI/Config.ts +15 -33
  319. package/UI/Utils/GlobalKeyboardShortcut.ts +208 -0
  320. package/UI/Utils/Telemetry/BrowserTelemetryConfig.ts +28 -0
  321. package/UI/Utils/Telemetry/Telemetry.ts +10 -8
  322. package/Utils/API.ts +129 -3
  323. package/Utils/HTTPResponseBodyReader.ts +221 -0
  324. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +77 -0
  325. package/Utils/Rum/ChunkMath.ts +106 -0
  326. package/Utils/Rum/SessionReplayHealth.ts +732 -0
  327. package/Utils/Rum/SessionReplayStringMap.ts +226 -0
  328. package/Utils/Schema/ModelSchema.ts +1 -0
  329. package/Utils/StatusPage/ResourceSearch.ts +290 -0
  330. package/Utils/Telemetry/OriginAllowList.ts +355 -0
  331. package/Utils/Uptime/DayUptimeGraphUtil.ts +205 -0
  332. package/Utils/ValueFormatter.ts +35 -1
  333. package/build/dist/Models/AnalyticsModels/RumSession.js +102 -19
  334. package/build/dist/Models/AnalyticsModels/RumSession.js.map +1 -1
  335. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js +11 -9
  336. package/build/dist/Models/AnalyticsModels/RumSessionChunk.js.map +1 -1
  337. package/build/dist/Models/DatabaseModels/AlertCustomField.js +79 -3
  338. package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
  339. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js +3 -27
  340. package/build/dist/Models/DatabaseModels/ApiKeyPermission.js.map +1 -1
  341. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +79 -3
  342. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  343. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +79 -3
  344. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -1
  345. package/build/dist/Models/DatabaseModels/MonitorCustomField.js +79 -3
  346. package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
  347. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +79 -3
  348. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
  349. package/build/dist/Models/DatabaseModels/RumApplication.js +6 -6
  350. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  351. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +79 -3
  352. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
  353. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +79 -3
  354. package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
  355. package/build/dist/Models/DatabaseModels/TeamCustomField.js +79 -3
  356. package/build/dist/Models/DatabaseModels/TeamCustomField.js.map +1 -1
  357. package/build/dist/Models/DatabaseModels/TeamMember.js +0 -9
  358. package/build/dist/Models/DatabaseModels/TeamMember.js.map +1 -1
  359. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js +79 -3
  360. package/build/dist/Models/DatabaseModels/TeamMemberCustomField.js.map +1 -1
  361. package/build/dist/Models/DatabaseModels/TeamPermission.js +3 -24
  362. package/build/dist/Models/DatabaseModels/TeamPermission.js.map +1 -1
  363. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js +267 -0
  364. package/build/dist/Models/DatabaseModels/TelemetryIngestionKey.js.map +1 -1
  365. package/build/dist/Models/DatabaseModels/UserTelegram.js +0 -4
  366. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  367. package/build/dist/Server/API/TelemetryAPI.js +769 -109
  368. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  369. package/build/dist/Server/API/UserNotificationSettingAPI.js +35 -0
  370. package/build/dist/Server/API/UserNotificationSettingAPI.js.map +1 -0
  371. package/build/dist/Server/API/UserTelegramAPI.js +28 -6
  372. package/build/dist/Server/API/UserTelegramAPI.js.map +1 -1
  373. package/build/dist/Server/EnvironmentConfig.js +29 -2
  374. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  375. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js +60 -0
  376. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791300000000-AddTelemetryIngestionKeyType.js.map +1 -0
  377. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js +53 -0
  378. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791400000000-SessionReplayRecordEverySessionByDefault.js.map +1 -0
  379. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js +82 -0
  380. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791500000000-WidenCustomFieldDropdownOptions.js.map +1 -0
  381. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js +46 -0
  382. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791600000000-AddCustomFieldValueMapping.js.map +1 -0
  383. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  384. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  385. package/build/dist/Server/Infrastructure/QueueWorker.js +19 -7
  386. package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
  387. package/build/dist/Server/Infrastructure/Semaphore.js +1 -0
  388. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  389. package/build/dist/Server/Middleware/TelemetryIngest.js +315 -8
  390. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  391. package/build/dist/Server/Services/AccessTokenService.js +1 -0
  392. package/build/dist/Server/Services/AccessTokenService.js.map +1 -1
  393. package/build/dist/Server/Services/AlertCustomFieldService.js +93 -0
  394. package/build/dist/Server/Services/AlertCustomFieldService.js.map +1 -1
  395. package/build/dist/Server/Services/AlertService.js +34 -0
  396. package/build/dist/Server/Services/AlertService.js.map +1 -1
  397. package/build/dist/Server/Services/ApiKeyPermissionService.js +331 -28
  398. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  399. package/build/dist/Server/Services/CustomFieldMappingService.js +614 -0
  400. package/build/dist/Server/Services/CustomFieldMappingService.js.map +1 -0
  401. package/build/dist/Server/Services/GlobalConfigService.js +133 -0
  402. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  403. package/build/dist/Server/Services/IncidentCustomFieldService.js +93 -0
  404. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  405. package/build/dist/Server/Services/IncidentService.js +32 -0
  406. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  407. package/build/dist/Server/Services/MetricService.js +163 -0
  408. package/build/dist/Server/Services/MetricService.js.map +1 -1
  409. package/build/dist/Server/Services/MonitorService.js +29 -0
  410. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  411. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +79 -27
  412. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  413. package/build/dist/Server/Services/ProjectService.js +22 -0
  414. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  415. package/build/dist/Server/Services/RoutineEmailSettingsService.js +69 -0
  416. package/build/dist/Server/Services/RoutineEmailSettingsService.js.map +1 -0
  417. package/build/dist/Server/Services/RumSessionReplayViewService.js +86 -24
  418. package/build/dist/Server/Services/RumSessionReplayViewService.js.map +1 -1
  419. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js +93 -0
  420. package/build/dist/Server/Services/ScheduledMaintenanceCustomFieldService.js.map +1 -1
  421. package/build/dist/Server/Services/ScheduledMaintenanceService.js +29 -0
  422. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  423. package/build/dist/Server/Services/TeamMemberService.js +62 -2
  424. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  425. package/build/dist/Server/Services/TeamPermissionService.js +166 -3
  426. package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
  427. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +562 -18
  428. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  429. package/build/dist/Server/Services/UserNotificationSettingService.js +26 -6
  430. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  431. package/build/dist/Server/Services/UserTelegramService.js +257 -4
  432. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  433. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  434. package/build/dist/Server/Utils/APIKey/AccessPermission.js +2 -2
  435. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  436. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js +27 -0
  437. package/build/dist/Server/Utils/CustomField/CustomFieldDefinitionMappingHooks.js.map +1 -0
  438. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js +226 -0
  439. package/build/dist/Server/Utils/CustomField/CustomFieldMappingRegistry.js.map +1 -0
  440. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js +189 -0
  441. package/build/dist/Server/Utils/CustomField/CustomFieldMappingValidator.js.map +1 -0
  442. package/build/dist/Server/Utils/DataSource/EgressGuard.js +121 -7
  443. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  444. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +38 -5
  445. package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -1
  446. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +44 -2
  447. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  448. package/build/dist/Server/Utils/FrontendEnvironment.js +33 -0
  449. package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -0
  450. package/build/dist/Server/Utils/LogRedaction.js +20 -0
  451. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  452. package/build/dist/Server/Utils/Logger.js +10 -0
  453. package/build/dist/Server/Utils/Logger.js.map +1 -1
  454. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +287 -68
  455. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  456. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +20 -4
  457. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  458. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +29 -6
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  460. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +88 -13
  461. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  462. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +22 -6
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  464. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +22 -0
  465. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  466. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js +237 -0
  467. package/build/dist/Server/Utils/Monitor/SeriesContextEnricher.js.map +1 -0
  468. package/build/dist/Server/Utils/SSRFProtection.js +136 -9
  469. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  470. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js +174 -89
  471. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCache.js.map +1 -1
  472. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js +223 -0
  473. package/build/dist/Server/Utils/SessionReplay/SessionReplayHealthCounters.js.map +1 -0
  474. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js +945 -164
  475. package/build/dist/Server/Utils/SessionReplay/SessionReplayReadService.js.map +1 -1
  476. package/build/dist/Server/Utils/StartServer.js +3 -14
  477. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  478. package/build/dist/Server/Utils/TelegramVerificationToken.js +129 -0
  479. package/build/dist/Server/Utils/TelegramVerificationToken.js.map +1 -0
  480. package/build/dist/Server/Utils/Telemetry/PinServiceName.js +163 -0
  481. package/build/dist/Server/Utils/Telemetry/PinServiceName.js.map +1 -0
  482. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js +28 -15
  483. package/build/dist/Server/Utils/Telemetry/TelemetryFanInWriter.js.map +1 -1
  484. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js +64 -0
  485. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.js.map +1 -0
  486. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js +171 -0
  487. package/build/dist/Server/Utils/Telemetry/TelemetryIngestionKeyRateLimiter.js.map +1 -0
  488. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  489. package/build/dist/Server/Utils/VM/VMRunner.js +780 -69
  490. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  491. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +60 -0
  492. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -0
  493. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js +20 -0
  494. package/build/dist/Types/CustomField/CustomFieldMappingSourceResource.js.map +1 -0
  495. package/build/dist/Types/CustomField/CustomFieldValueMapping.js +141 -0
  496. package/build/dist/Types/CustomField/CustomFieldValueMapping.js.map +1 -0
  497. package/build/dist/Types/Icon/IconProp.js +1 -0
  498. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  499. package/build/dist/Types/JSONFunctions.js +118 -37
  500. package/build/dist/Types/JSONFunctions.js.map +1 -1
  501. package/build/dist/Types/Monitor/CephAlertTemplates.js +130 -171
  502. package/build/dist/Types/Monitor/CephAlertTemplates.js.map +1 -1
  503. package/build/dist/Types/Monitor/DockerAlertTemplates.js +286 -121
  504. package/build/dist/Types/Monitor/DockerAlertTemplates.js.map +1 -1
  505. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js +84 -105
  506. package/build/dist/Types/Monitor/DockerSwarmAlertTemplates.js.map +1 -1
  507. package/build/dist/Types/Monitor/HostAlertTemplates.js +250 -122
  508. package/build/dist/Types/Monitor/HostAlertTemplates.js.map +1 -1
  509. package/build/dist/Types/Monitor/IotAlertTemplates.js +81 -81
  510. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  511. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +375 -215
  512. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  513. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js +19 -19
  514. package/build/dist/Types/Monitor/KubernetesMetricCatalog.js.map +1 -1
  515. package/build/dist/Types/Monitor/PodmanAlertTemplates.js +104 -153
  516. package/build/dist/Types/Monitor/PodmanAlertTemplates.js.map +1 -1
  517. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +156 -91
  518. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  519. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +67 -6
  520. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  521. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +38 -7
  522. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  523. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js +261 -0
  524. package/build/dist/Types/Monitor/Recommendation/RecommendationCriteriaBuilder.js.map +1 -0
  525. package/build/dist/Types/Monitor/RumAlertTemplates.js +46 -7
  526. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  527. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +422 -0
  528. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -0
  529. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +441 -0
  530. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -0
  531. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +79 -15
  532. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -1
  533. package/build/dist/Types/Monitor/UptimeHistoryLabels.js +17 -0
  534. package/build/dist/Types/Monitor/UptimeHistoryLabels.js.map +1 -0
  535. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js +29 -0
  536. package/build/dist/Types/NotificationSetting/RoutineEmailEvents.js.map +1 -0
  537. package/build/dist/Types/Rum/SessionReplay.js +117 -0
  538. package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
  539. package/build/dist/Types/Rum/SessionReplayApi.js +181 -0
  540. package/build/dist/Types/Rum/SessionReplayApi.js.map +1 -0
  541. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js +21 -12
  542. package/build/dist/Types/Rum/SessionReplayCaptureTrigger.js.map +1 -1
  543. package/build/dist/Types/Rum/SessionReplayConsentMode.js +11 -7
  544. package/build/dist/Types/Rum/SessionReplayConsentMode.js.map +1 -1
  545. package/build/dist/Types/Rum/SessionReplayCustomEvents.js +172 -0
  546. package/build/dist/Types/Rum/SessionReplayCustomEvents.js.map +1 -0
  547. package/build/dist/Types/Rum/SessionReplayHealth.js +37 -0
  548. package/build/dist/Types/Rum/SessionReplayHealth.js.map +1 -0
  549. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +85 -0
  550. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -0
  551. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js +15 -0
  552. package/build/dist/Types/Telemetry/TelemetryIngestionKeyPolicy.js.map +1 -0
  553. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js +30 -0
  554. package/build/dist/Types/Telemetry/TelemetryIngestionKeyType.js.map +1 -0
  555. package/build/dist/Types/WebsiteRequest.js +55 -3
  556. package/build/dist/Types/WebsiteRequest.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/Area/AreaChart.js +13 -2
  558. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/Bar/BarChart.js +6 -2
  560. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/Line/LineChart.js +13 -2
  562. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/Types/XAxis/XAxis.js.map +1 -1
  564. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -3
  565. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  566. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +40 -9
  567. package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
  568. package/build/dist/UI/Components/Charts/Utils/XAxis.js +186 -0
  569. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  570. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +80 -6
  571. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  572. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js +118 -0
  573. package/build/dist/UI/Components/CustomFields/MapFromCustomFieldInput.js.map +1 -0
  574. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +112 -7
  575. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  576. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +5 -162
  577. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  578. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js +181 -0
  579. package/build/dist/UI/Components/Graphs/UptimeDaySummary.js.map +1 -0
  580. package/build/dist/UI/Components/Header/Header.js +2 -3
  581. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  582. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js +2 -1
  583. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownItem.js.map +1 -1
  584. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js +7 -1
  585. package/build/dist/UI/Components/Header/IconDropdown/IconDropdownMenu.js.map +1 -1
  586. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js +7 -1
  587. package/build/dist/UI/Components/Header/ProjectPicker/ProjectPicker.js.map +1 -1
  588. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js +7 -1
  589. package/build/dist/UI/Components/HeaderAlert/NotificationBell/NotificationBellDropdown.js.map +1 -1
  590. package/build/dist/UI/Components/Icon/Icon.js +5 -0
  591. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  592. package/build/dist/UI/Components/JSONTable/JSONTable.js +2 -2
  593. package/build/dist/UI/Components/JSONTable/JSONTable.js.map +1 -1
  594. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js +35 -0
  595. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcutsModal.js.map +1 -0
  596. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js +34 -0
  597. package/build/dist/UI/Components/Monitor/SeriesDebugCommandsViewer.js.map +1 -0
  598. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js +49 -0
  599. package/build/dist/UI/Components/Monitor/SeriesLabelsViewer.js.map +1 -0
  600. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +1 -1
  601. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  602. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +32 -6
  603. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  604. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +38 -0
  605. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  606. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +22 -1
  607. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -1
  608. package/build/dist/UI/Components/Table/CellClassName.js +55 -0
  609. package/build/dist/UI/Components/Table/CellClassName.js.map +1 -0
  610. package/build/dist/UI/Components/Table/TableRow.js +16 -13
  611. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  612. package/build/dist/UI/Components/Table/TableSkeletonRows.js +9 -8
  613. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -1
  614. package/build/dist/UI/Components/Tooltip/Tooltip.js +25 -1
  615. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  616. package/build/dist/UI/Components/Workflow/ComponentsModal.js +47 -30
  617. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  618. package/build/dist/UI/Components/Workflow/NodePlacement.js +37 -0
  619. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -0
  620. package/build/dist/UI/Components/Workflow/Workflow.js +35 -18
  621. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  622. package/build/dist/UI/Config.js +10 -20
  623. package/build/dist/UI/Config.js.map +1 -1
  624. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js +138 -0
  625. package/build/dist/UI/Utils/GlobalKeyboardShortcut.js.map +1 -0
  626. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js +14 -0
  627. package/build/dist/UI/Utils/Telemetry/BrowserTelemetryConfig.js.map +1 -0
  628. package/build/dist/UI/Utils/Telemetry/Telemetry.js +7 -5
  629. package/build/dist/UI/Utils/Telemetry/Telemetry.js.map +1 -1
  630. package/build/dist/Utils/API.js +67 -5
  631. package/build/dist/Utils/API.js.map +1 -1
  632. package/build/dist/Utils/HTTPResponseBodyReader.js +157 -0
  633. package/build/dist/Utils/HTTPResponseBodyReader.js.map +1 -0
  634. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +69 -0
  635. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -0
  636. package/build/dist/Utils/Rum/ChunkMath.js +76 -0
  637. package/build/dist/Utils/Rum/ChunkMath.js.map +1 -1
  638. package/build/dist/Utils/Rum/SessionReplayHealth.js +534 -0
  639. package/build/dist/Utils/Rum/SessionReplayHealth.js.map +1 -0
  640. package/build/dist/Utils/Rum/SessionReplayStringMap.js +165 -0
  641. package/build/dist/Utils/Rum/SessionReplayStringMap.js.map +1 -0
  642. package/build/dist/Utils/Schema/ModelSchema.js +1 -0
  643. package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
  644. package/build/dist/Utils/StatusPage/ResourceSearch.js +200 -0
  645. package/build/dist/Utils/StatusPage/ResourceSearch.js.map +1 -0
  646. package/build/dist/Utils/Telemetry/OriginAllowList.js +299 -0
  647. package/build/dist/Utils/Telemetry/OriginAllowList.js.map +1 -0
  648. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js +147 -0
  649. package/build/dist/Utils/Uptime/DayUptimeGraphUtil.js.map +1 -0
  650. package/build/dist/Utils/ValueFormatter.js +32 -1
  651. package/build/dist/Utils/ValueFormatter.js.map +1 -1
  652. package/package.json +1 -1
@@ -0,0 +1,666 @@
1
+ import PinServiceName from "../../../../Server/Utils/Telemetry/PinServiceName";
2
+ import { JSONObject, JSONValue } from "../../../../Types/JSON";
3
+ import { describe, expect, test } from "@jest/globals";
4
+
5
+ /*
6
+ * PinServiceName is the control that stops telemetry written with a scraped
7
+ * Browser ingestion key from masquerading as a backend service.
8
+ *
9
+ * A Browser key is published in page source by design, so it must be assumed
10
+ * scraped. The origin allowlist and the rate limit bound HOW MUCH forged data
11
+ * an attacker can write and FROM WHERE; neither stops them writing it under
12
+ * `service.name: "payments-api"` and poisoning the dashboards, SLOs, telemetry
13
+ * monitors and alert rules of a service that never emitted a byte of it.
14
+ * Pinning is what makes forged data self-identifying, so it has to hold on
15
+ * every payload an attacker can compose - not just the well-formed ones.
16
+ *
17
+ * Three properties are pinned here, and each maps to a concrete bypass:
18
+ *
19
+ * 1. TOTALITY. Every resource block under resourceSpans / resourceLogs /
20
+ * resourceMetrics / resourceProfiles is rewritten. One unwalked
21
+ * container, or one skipped block in a batch of a thousand, is a forged
22
+ * span filed under someone else's service.
23
+ * 2. EXACTLY ONE service.name survives, and it is ours. Replacement - not
24
+ * appending - is the whole game: a forger who sends several service.name
25
+ * attributes hoping a downstream consumer takes the first (or the one
26
+ * with a non-string OTLP value, or the oddly-cased one) must end up with
27
+ * a payload where there is nothing left to take but the pin.
28
+ * 3. IT NEVER THROWS, AND IT NEVER SKIPS ON MALFORMED INPUT. This runs in a
29
+ * queue worker on JSON that has not been schema-validated yet. A
30
+ * TypeError would fail the whole batch and would be reachable by anyone
31
+ * holding a scraped key; a `"resource": "not-an-object"` that merely got
32
+ * skipped would be a one-character bypass of the entire control. So a
33
+ * hostile shape is repaired where there is somewhere to write, and only
34
+ * ever skipped where there is not.
35
+ *
36
+ * The suite therefore leans hard on attacker-shaped input: nulls, primitives
37
+ * and arrays in every position a spec-shaped payload has an object.
38
+ */
39
+
40
+ const PINNED: string = "browser-frontend";
41
+
42
+ /*
43
+ * pinInPlace's signature is typed for well-formed OTLP; every hostile case
44
+ * below has to go in through `unknown` to be expressible at all, so funnel
45
+ * every call through one helper rather than scattering casts.
46
+ */
47
+ const pinRaw: (body: unknown, serviceName: unknown) => number = (
48
+ body: unknown,
49
+ serviceName: unknown,
50
+ ): number => {
51
+ return PinServiceName.pinInPlace(body as JSONObject, serviceName as string);
52
+ };
53
+
54
+ /*
55
+ * Note the two entry points: `pin` defaults the name, so it cannot be used to
56
+ * test an explicitly-undefined name (the default would swallow it) - those
57
+ * cases go through pinRaw and reach pinInPlace with the argument as written.
58
+ */
59
+ const pin: (body: unknown, serviceName?: unknown) => number = (
60
+ body: unknown,
61
+ serviceName: unknown = PINNED,
62
+ ): number => {
63
+ return pinRaw(body, serviceName);
64
+ };
65
+
66
+ const attributesOf: (block: unknown) => Array<JSONObject> = (
67
+ block: unknown,
68
+ ): Array<JSONObject> => {
69
+ const resource: JSONObject = (block as JSONObject)["resource"] as JSONObject;
70
+ return resource["attributes"] as unknown as Array<JSONObject>;
71
+ };
72
+
73
+ const serviceNameAttributesOf: (block: unknown) => Array<JSONObject> = (
74
+ block: unknown,
75
+ ): Array<JSONObject> => {
76
+ return attributesOf(block).filter((attribute: JSONObject): boolean => {
77
+ return (
78
+ typeof attribute === "object" &&
79
+ attribute !== null &&
80
+ !Array.isArray(attribute) &&
81
+ String(attribute["key"] ?? "")
82
+ .trim()
83
+ .toLowerCase() === "service.name"
84
+ );
85
+ });
86
+ };
87
+
88
+ const pinnedAttribute: (serviceName?: string) => JSONObject = (
89
+ serviceName: string = PINNED,
90
+ ): JSONObject => {
91
+ return {
92
+ key: "service.name",
93
+ value: {
94
+ stringValue: serviceName,
95
+ },
96
+ };
97
+ };
98
+
99
+ const blockWithAttributes: (attributes: unknown) => JSONObject = (
100
+ attributes: unknown,
101
+ ): JSONObject => {
102
+ return {
103
+ resource: {
104
+ attributes: attributes as JSONValue,
105
+ },
106
+ };
107
+ };
108
+
109
+ const clone: (value: unknown) => unknown = (value: unknown): unknown => {
110
+ return JSON.parse(JSON.stringify(value)) as unknown;
111
+ };
112
+
113
+ /*
114
+ * All four OTLP resource containers. Profiles are in the list even though a
115
+ * Browser key cannot reach the profiles surface: a SERVER key may carry a pin
116
+ * too, and the pin has to mean the same thing for every signal.
117
+ */
118
+ const CONTAINER_KEYS: Array<string> = [
119
+ "resourceSpans",
120
+ "resourceLogs",
121
+ "resourceMetrics",
122
+ "resourceProfiles",
123
+ ];
124
+
125
+ describe("PinServiceName.pinInPlace: coverage of every OTLP resource container", () => {
126
+ test.each(CONTAINER_KEYS)(
127
+ "pins every resource block under %s and returns the number rewritten",
128
+ (containerKey: string) => {
129
+ const body: JSONObject = {
130
+ [containerKey]: [
131
+ blockWithAttributes([]),
132
+ blockWithAttributes([pinnedAttribute("forged-backend")]),
133
+ ],
134
+ };
135
+
136
+ const rewritten: number = pin(body);
137
+
138
+ expect(rewritten).toBe(2);
139
+
140
+ const blocks: Array<JSONObject> = body[
141
+ containerKey
142
+ ] as unknown as Array<JSONObject>;
143
+
144
+ for (const block of blocks) {
145
+ expect(serviceNameAttributesOf(block)).toEqual([pinnedAttribute()]);
146
+ }
147
+ },
148
+ );
149
+
150
+ test("a payload carrying all four signals has all four pinned and counts every block", () => {
151
+ const body: JSONObject = {
152
+ resourceSpans: [blockWithAttributes([]), blockWithAttributes([])],
153
+ resourceLogs: [blockWithAttributes([])],
154
+ resourceMetrics: [
155
+ blockWithAttributes([pinnedAttribute("payments-api")]),
156
+ blockWithAttributes([]),
157
+ blockWithAttributes([]),
158
+ ],
159
+ resourceProfiles: [blockWithAttributes([pinnedAttribute("profiler")])],
160
+ };
161
+
162
+ expect(pin(body)).toBe(7);
163
+
164
+ for (const containerKey of CONTAINER_KEYS) {
165
+ const blocks: Array<JSONObject> = body[
166
+ containerKey
167
+ ] as unknown as Array<JSONObject>;
168
+
169
+ for (const block of blocks) {
170
+ expect(serviceNameAttributesOf(block)).toEqual([pinnedAttribute()]);
171
+ }
172
+ }
173
+ });
174
+
175
+ test("an empty container contributes nothing to the count but is not an error", () => {
176
+ const body: JSONObject = {
177
+ resourceSpans: [],
178
+ resourceLogs: [blockWithAttributes([])],
179
+ };
180
+
181
+ expect(pin(body)).toBe(1);
182
+ });
183
+
184
+ test("rewrites the caller's body in place rather than returning a copy", () => {
185
+ const resource: JSONObject = { attributes: [] };
186
+ const container: Array<JSONObject> = [{ resource: resource }];
187
+ const body: JSONObject = {
188
+ resourceSpans: container as unknown as JSONValue,
189
+ };
190
+
191
+ pin(body);
192
+
193
+ // The caller keeps its own references; nothing is deep-cloned on the hot path.
194
+ expect(body["resourceSpans"]).toBe(container);
195
+ expect((container[0] as JSONObject)["resource"]).toBe(resource);
196
+ expect(resource["attributes"]).toEqual([pinnedAttribute()]);
197
+ });
198
+ });
199
+
200
+ describe("PinServiceName.pinInPlace: exactly one service.name survives", () => {
201
+ test("an existing service.name is replaced, not duplicated", () => {
202
+ const block: JSONObject = blockWithAttributes([
203
+ pinnedAttribute("payments-api"),
204
+ ]);
205
+
206
+ expect(pin({ resourceSpans: [block] })).toBe(1);
207
+
208
+ expect(attributesOf(block)).toEqual([pinnedAttribute()]);
209
+ });
210
+
211
+ test("several forged service.name entries all collapse to exactly one pinned entry", () => {
212
+ const block: JSONObject = blockWithAttributes([
213
+ pinnedAttribute("payments-api"),
214
+ { key: "http.method", value: { stringValue: "GET" } },
215
+ pinnedAttribute("auth-service"),
216
+ pinnedAttribute("billing-worker"),
217
+ ]);
218
+
219
+ pin({ resourceLogs: [block] });
220
+
221
+ expect(serviceNameAttributesOf(block)).toHaveLength(1);
222
+ expect(attributesOf(block)).toEqual([
223
+ { key: "http.method", value: { stringValue: "GET" } },
224
+ pinnedAttribute(),
225
+ ]);
226
+ });
227
+
228
+ test("a service.name that differs only by case or padding is still removed", () => {
229
+ /*
230
+ * Deliberately looser than the OTLP spec, which is case-sensitive: the
231
+ * cost of over-matching is that an exotic key is dropped, and the cost of
232
+ * under-matching is a bypass through any consumer that folds case.
233
+ */
234
+ const block: JSONObject = blockWithAttributes([
235
+ { key: "Service.Name", value: { stringValue: "payments-api" } },
236
+ { key: " service.name ", value: { stringValue: "auth-service" } },
237
+ { key: "SERVICE.NAME", value: { stringValue: "billing-worker" } },
238
+ ]);
239
+
240
+ pin({ resourceMetrics: [block] });
241
+
242
+ expect(attributesOf(block)).toEqual([pinnedAttribute()]);
243
+ });
244
+
245
+ test("a service.name attribute carrying a non-string OTLP value is still replaced by a stringValue", () => {
246
+ const forgedValues: Array<JSONObject> = [
247
+ { key: "service.name", value: { intValue: "42" } },
248
+ { key: "service.name", value: { boolValue: true } },
249
+ {
250
+ key: "service.name",
251
+ value: {
252
+ arrayValue: { values: [{ stringValue: "payments-api" }] },
253
+ },
254
+ },
255
+ { key: "service.name", value: null },
256
+ { key: "service.name" },
257
+ { key: "service.name", value: { kvlistValue: { values: [] } } },
258
+ { key: "service.name", value: "payments-api" },
259
+ { key: "service.name", value: ["payments-api"] },
260
+ ];
261
+
262
+ for (const forged of forgedValues) {
263
+ const block: JSONObject = blockWithAttributes([forged]);
264
+
265
+ expect(pin({ resourceSpans: [block] })).toBe(1);
266
+
267
+ expect(attributesOf(block)).toEqual([pinnedAttribute()]);
268
+ }
269
+ });
270
+
271
+ test("service.name is appended when the resource never carried one", () => {
272
+ const block: JSONObject = blockWithAttributes([
273
+ { key: "host.name", value: { stringValue: "laptop" } },
274
+ ]);
275
+
276
+ pin({ resourceSpans: [block] });
277
+
278
+ expect(attributesOf(block)).toEqual([
279
+ { key: "host.name", value: { stringValue: "laptop" } },
280
+ pinnedAttribute(),
281
+ ]);
282
+ });
283
+
284
+ test("unrelated attributes keep their identity and relative order, and the pin lands last", () => {
285
+ const first: JSONObject = {
286
+ key: "telemetry.sdk.name",
287
+ value: { stringValue: "opentelemetry" },
288
+ };
289
+ const second: JSONObject = {
290
+ key: "deployment.environment",
291
+ value: { stringValue: "production" },
292
+ };
293
+ const third: JSONObject = {
294
+ key: "host.arch",
295
+ value: { stringValue: "arm64" },
296
+ };
297
+
298
+ const block: JSONObject = blockWithAttributes([
299
+ first,
300
+ pinnedAttribute("payments-api"),
301
+ second,
302
+ third,
303
+ ]);
304
+
305
+ pin({ resourceLogs: [block] });
306
+
307
+ const attributes: Array<JSONObject> = attributesOf(block);
308
+
309
+ expect(attributes).toHaveLength(4);
310
+ // Same objects, same order - nothing is rebuilt or reordered.
311
+ expect(attributes[0]).toBe(first);
312
+ expect(attributes[1]).toBe(second);
313
+ expect(attributes[2]).toBe(third);
314
+ expect(attributes[3]).toEqual(pinnedAttribute());
315
+ });
316
+ });
317
+
318
+ describe("PinServiceName.pinInPlace: missing or malformed structure is repaired, never skipped", () => {
319
+ test("a resource block with no resource at all gets one created and pinned", () => {
320
+ const block: JSONObject = { scopeSpans: [] };
321
+
322
+ expect(pin({ resourceSpans: [block] })).toBe(1);
323
+
324
+ expect(block["resource"]).toEqual({ attributes: [pinnedAttribute()] });
325
+ // The rest of the envelope is untouched.
326
+ expect(block["scopeSpans"]).toEqual([]);
327
+ });
328
+
329
+ test("a resource with no attributes array gets one created and pinned", () => {
330
+ const resource: JSONObject = { droppedAttributesCount: 0 };
331
+ const block: JSONObject = { resource: resource };
332
+
333
+ expect(pin({ resourceLogs: [block] })).toBe(1);
334
+
335
+ expect(resource["attributes"]).toEqual([pinnedAttribute()]);
336
+ expect(resource["droppedAttributesCount"]).toBe(0);
337
+ });
338
+
339
+ test.each([
340
+ ["an object", { "service.name": "payments-api" } as unknown],
341
+ ["a string", "service.name=payments-api" as unknown],
342
+ ["a number", 7 as unknown],
343
+ ["null", null as unknown],
344
+ ["a boolean", true as unknown],
345
+ ])(
346
+ "attributes that are %s are replaced with a valid array holding only the pin",
347
+ (_label: string, attributes: unknown) => {
348
+ const block: JSONObject = blockWithAttributes(attributes);
349
+
350
+ expect(pin({ resourceMetrics: [block] })).toBe(1);
351
+
352
+ /*
353
+ * The malformed value is discarded rather than preserved. That is the
354
+ * safe direction: leaving it in place would let a forged payload keep an
355
+ * unpinned service.name under a shape the walker cannot read.
356
+ */
357
+ expect(attributesOf(block)).toEqual([pinnedAttribute()]);
358
+ },
359
+ );
360
+
361
+ test.each([
362
+ ["a string", "not-a-resource" as unknown],
363
+ ["a number", 1 as unknown],
364
+ ["an array", [{ attributes: [] }] as unknown],
365
+ ["a boolean", false as unknown],
366
+ ["null", null as unknown],
367
+ ])(
368
+ "a resource that is %s is replaced with a real resource carrying the pin",
369
+ (_label: string, resource: unknown) => {
370
+ const block: JSONObject = { resource: resource as JSONValue };
371
+
372
+ expect(pin({ resourceSpans: [block] })).toBe(1);
373
+
374
+ expect(block["resource"]).toEqual({ attributes: [pinnedAttribute()] });
375
+ },
376
+ );
377
+
378
+ test("attribute entries that are null, primitives or arrays are preserved untouched alongside the pin", () => {
379
+ const block: JSONObject = blockWithAttributes([
380
+ null,
381
+ "not-an-attribute",
382
+ 42,
383
+ true,
384
+ ["service.name", "payments-api"],
385
+ { value: { stringValue: "no key at all" } },
386
+ { key: 7, value: { stringValue: "non-string key" } },
387
+ { key: null },
388
+ pinnedAttribute("payments-api"),
389
+ ]);
390
+
391
+ expect(pin({ resourceLogs: [block] })).toBe(1);
392
+
393
+ expect(attributesOf(block)).toEqual([
394
+ null,
395
+ "not-an-attribute",
396
+ 42,
397
+ true,
398
+ ["service.name", "payments-api"],
399
+ { value: { stringValue: "no key at all" } },
400
+ { key: 7, value: { stringValue: "non-string key" } },
401
+ { key: null },
402
+ pinnedAttribute(),
403
+ ]);
404
+ });
405
+
406
+ test("blocks that are not objects are skipped, and their well-formed siblings are still pinned", () => {
407
+ const good: JSONObject = blockWithAttributes([]);
408
+ const alsoGood: JSONObject = blockWithAttributes([
409
+ pinnedAttribute("payments-api"),
410
+ ]);
411
+
412
+ const body: JSONObject = {
413
+ resourceSpans: [
414
+ null,
415
+ undefined,
416
+ "resource",
417
+ 0,
418
+ false,
419
+ [],
420
+ [{ resource: {} }],
421
+ good,
422
+ alsoGood,
423
+ ] as unknown as JSONValue,
424
+ };
425
+
426
+ // Only the two real envelopes are rewritable; there is nowhere to write on the rest.
427
+ expect(pin(body)).toBe(2);
428
+ expect(attributesOf(good)).toEqual([pinnedAttribute()]);
429
+ expect(attributesOf(alsoGood)).toEqual([pinnedAttribute()]);
430
+ });
431
+ });
432
+
433
+ describe("PinServiceName.pinInPlace: hostile input never throws", () => {
434
+ const hostileBodies: Array<[string, unknown]> = [
435
+ ["null body", null],
436
+ ["undefined body", undefined],
437
+ ["array body", [{ resourceSpans: [] }]],
438
+ ["string body", "resourceSpans"],
439
+ ["number body", 42],
440
+ ["boolean body", true],
441
+ ["empty body", {}],
442
+ ["resourceSpans is a string", { resourceSpans: "resourceSpans" }],
443
+ ["resourceSpans is a number", { resourceSpans: 1 }],
444
+ ["resourceSpans is null", { resourceSpans: null }],
445
+ ["resourceSpans is undefined", { resourceSpans: undefined }],
446
+ ["resourceSpans is a boolean", { resourceSpans: false }],
447
+ [
448
+ "resourceSpans is an object, not an array",
449
+ { resourceSpans: { "0": { resource: {} } } },
450
+ ],
451
+ ["resourceLogs is a string", { resourceLogs: "x" }],
452
+ ["resourceMetrics is an object", { resourceMetrics: { resource: {} } }],
453
+ ["array of nulls", { resourceSpans: [null, null] }],
454
+ ["array of primitives", { resourceSpans: ["a", 1, true] }],
455
+ ["array of arrays", { resourceSpans: [[], [[]]] }],
456
+ ["resource is a primitive", { resourceSpans: [{ resource: 5 }] }],
457
+ [
458
+ "attributes is a primitive",
459
+ { resourceSpans: [{ resource: { attributes: 5 } }] },
460
+ ],
461
+ [
462
+ "attributes holds hostile entries",
463
+ {
464
+ resourceSpans: [
465
+ { resource: { attributes: [null, 1, [], { key: {} }] } },
466
+ ],
467
+ },
468
+ ],
469
+ [
470
+ "deeply nested but malformed",
471
+ {
472
+ resourceSpans: [
473
+ {
474
+ resource: {
475
+ attributes: [
476
+ {
477
+ key: "service.name",
478
+ value: { arrayValue: { values: [{ stringValue: "x" }] } },
479
+ },
480
+ ],
481
+ },
482
+ scopeSpans: [
483
+ { scope: null, spans: "not-an-array" },
484
+ { spans: [{ attributes: { key: "service.name" } }] },
485
+ ],
486
+ },
487
+ ],
488
+ resourceLogs: [{ resource: [], scopeLogs: 3 }],
489
+ resourceMetrics: "none",
490
+ },
491
+ ],
492
+ ];
493
+
494
+ test.each(hostileBodies)(
495
+ "returns a number and does not throw on: %s",
496
+ (_label: string, body: unknown) => {
497
+ let result: number = -1;
498
+
499
+ expect((): void => {
500
+ result = pin(body);
501
+ }).not.toThrow();
502
+
503
+ expect(typeof result).toBe("number");
504
+ expect(Number.isInteger(result)).toBe(true);
505
+ expect(result).toBeGreaterThanOrEqual(0);
506
+ },
507
+ );
508
+
509
+ test("a body whose container is not an array is left completely alone", () => {
510
+ const body: JSONObject = {
511
+ resourceSpans: { "0": { resource: { attributes: [] } } },
512
+ };
513
+ const before: unknown = clone(body);
514
+
515
+ expect(pin(body)).toBe(0);
516
+ expect(body).toEqual(before);
517
+ });
518
+
519
+ test("a large hostile batch is walked to the end without throwing", () => {
520
+ const blocks: Array<unknown> = [];
521
+
522
+ for (let index: number = 0; index < 500; index++) {
523
+ blocks.push(index % 2 === 0 ? blockWithAttributes([]) : null);
524
+ }
525
+
526
+ expect(pin({ resourceSpans: blocks as unknown as JSONValue })).toBe(250);
527
+ });
528
+ });
529
+
530
+ describe("PinServiceName.pinInPlace: the pinned name itself", () => {
531
+ test.each([
532
+ ["an empty string", ""],
533
+ ["whitespace only", " "],
534
+ ])(
535
+ "refuses to pin when the name is %s, leaving the payload untouched",
536
+ (_label: string, serviceName: string) => {
537
+ const body: JSONObject = {
538
+ resourceSpans: [blockWithAttributes([pinnedAttribute("payments-api")])],
539
+ };
540
+ const before: unknown = clone(body);
541
+
542
+ /*
543
+ * Stamping `service.name: ""` on everything would be strictly worse than
544
+ * not pinning - it destroys the customer's own attribution AND makes the
545
+ * forged data indistinguishable from it.
546
+ */
547
+ expect(pin(body, serviceName)).toBe(0);
548
+ expect(body).toEqual(before);
549
+ },
550
+ );
551
+
552
+ test.each([
553
+ ["undefined", undefined as unknown],
554
+ ["null", null as unknown],
555
+ ["a number", 42 as unknown],
556
+ ["an object", { name: "payments-api" } as unknown],
557
+ ])(
558
+ "refuses to pin when the name is %s rather than a string",
559
+ (_label: string, serviceName: unknown) => {
560
+ const body: JSONObject = {
561
+ resourceSpans: [blockWithAttributes([])],
562
+ };
563
+ const before: unknown = clone(body);
564
+
565
+ expect(pinRaw(body, serviceName)).toBe(0);
566
+ expect(body).toEqual(before);
567
+ },
568
+ );
569
+
570
+ test("surrounding whitespace on the pinned name is trimmed before it is written", () => {
571
+ const block: JSONObject = blockWithAttributes([]);
572
+
573
+ expect(pin({ resourceSpans: [block] }, " browser-frontend ")).toBe(1);
574
+
575
+ expect(attributesOf(block)).toEqual([pinnedAttribute()]);
576
+ });
577
+
578
+ test("a very long pinned name is written verbatim rather than truncated or rejected", () => {
579
+ const longName: string = "a".repeat(10000);
580
+ const block: JSONObject = blockWithAttributes([
581
+ pinnedAttribute("payments-api"),
582
+ ]);
583
+
584
+ expect(pin({ resourceSpans: [block] }, longName)).toBe(1);
585
+
586
+ expect(attributesOf(block)).toEqual([pinnedAttribute(longName)]);
587
+ });
588
+
589
+ test("a name full of odd characters is written verbatim, not escaped or dropped", () => {
590
+ const oddName: string = 'svc"\\/<>& name';
591
+ const block: JSONObject = blockWithAttributes([]);
592
+
593
+ expect(pin({ resourceSpans: [block] }, oddName)).toBe(1);
594
+
595
+ expect(attributesOf(block)).toEqual([pinnedAttribute(oddName)]);
596
+ });
597
+ });
598
+
599
+ describe("PinServiceName.pinInPlace: every OTLP container, and nothing else", () => {
600
+ test("resourceProfiles is walked like the other three", () => {
601
+ /*
602
+ * A Browser key cannot reach the profiles surface at all
603
+ * (BROWSER_ALLOWED_INGEST_SURFACES), so this is not part of containing a
604
+ * scraped credential. It is here because a SERVER key may carry a pin too,
605
+ * and the dashboard field promises the pin applies to "everything the key
606
+ * writes" - a promise that would be quietly false for one signal if
607
+ * profiles were skipped.
608
+ */
609
+ const body: JSONObject = {
610
+ resourceProfiles: [
611
+ blockWithAttributes([pinnedAttribute("payments-api")]),
612
+ ],
613
+ };
614
+
615
+ expect(pin(body)).toBe(1);
616
+
617
+ expect(
618
+ attributesOf((body["resourceProfiles"] as Array<JSONObject>)[0]!),
619
+ ).toEqual([pinnedAttribute(PINNED)]);
620
+ });
621
+
622
+ test("unrelated top-level keys survive a payload that does get pinned", () => {
623
+ const body: JSONObject = {
624
+ resourceSpans: [blockWithAttributes([])],
625
+ partialSuccess: { rejectedSpans: "0" },
626
+ someVendorExtension: { nested: { deep: [1, 2, 3] } },
627
+ };
628
+
629
+ expect(pin(body)).toBe(1);
630
+
631
+ expect(body["partialSuccess"]).toEqual({ rejectedSpans: "0" });
632
+ expect(body["someVendorExtension"]).toEqual({
633
+ nested: { deep: [1, 2, 3] },
634
+ });
635
+ });
636
+ });
637
+
638
+ describe("PinServiceName.pinInPlace: idempotence", () => {
639
+ test("pinning an already-pinned payload changes nothing and reports the same count", () => {
640
+ const body: JSONObject = {
641
+ resourceSpans: [
642
+ blockWithAttributes([
643
+ { key: "host.name", value: { stringValue: "laptop" } },
644
+ pinnedAttribute("payments-api"),
645
+ ]),
646
+ { scopeSpans: [] },
647
+ ],
648
+ resourceLogs: [blockWithAttributes("not-an-array")],
649
+ resourceMetrics: [blockWithAttributes([null, pinnedAttribute("x")])],
650
+ };
651
+
652
+ const firstCount: number = pin(body);
653
+ const afterFirst: unknown = clone(body);
654
+
655
+ const secondCount: number = pin(body);
656
+ const afterSecond: unknown = clone(body);
657
+
658
+ expect(firstCount).toBe(4);
659
+ expect(secondCount).toBe(firstCount);
660
+ expect(afterSecond).toEqual(afterFirst);
661
+
662
+ // And a third pass is still a fixed point.
663
+ expect(pin(body)).toBe(firstCount);
664
+ expect(clone(body)).toEqual(afterFirst);
665
+ });
666
+ });