@oneuptime/common 13.0.0 → 13.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (734) hide show
  1. package/Models/DatabaseModels/Alert.ts +55 -0
  2. package/Models/DatabaseModels/CloudResource.ts +45 -7
  3. package/Models/DatabaseModels/CodeRepository.ts +85 -0
  4. package/Models/DatabaseModels/GoogleSecOpsConnection.ts +57 -7
  5. package/Models/DatabaseModels/GoogleSecOpsConnectionRun.ts +263 -0
  6. package/Models/DatabaseModels/Incident.ts +55 -0
  7. package/Models/DatabaseModels/Index.ts +16 -0
  8. package/Models/DatabaseModels/ScheduledMaintenance.ts +55 -0
  9. package/Models/DatabaseModels/User.ts +51 -2
  10. package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +43 -2
  11. package/Models/DatabaseModels/UserWebAuthn.ts +17 -0
  12. package/Models/DatabaseModels/VMwareResource.ts +1149 -0
  13. package/Models/DatabaseModels/VMwareVCenter.ts +1122 -0
  14. package/Models/DatabaseModels/VMwareVCenterFeed.ts +625 -0
  15. package/Models/DatabaseModels/VMwareVCenterLabelRule.ts +514 -0
  16. package/Models/DatabaseModels/VMwareVCenterOwnerRule.ts +596 -0
  17. package/Models/DatabaseModels/VMwareVCenterOwnerTeam.ts +485 -0
  18. package/Models/DatabaseModels/VMwareVCenterOwnerUser.ts +484 -0
  19. package/Models/DatabaseModels/WorkflowVariable.ts +22 -1
  20. package/Server/API/AIAgentDataAPI.ts +79 -4
  21. package/Server/API/AIAgentGitHubAPI.ts +523 -0
  22. package/Server/API/AIChatAPI.ts +20 -1
  23. package/Server/API/BillingAPI.ts +33 -0
  24. package/Server/API/DashboardAPI.ts +10 -0
  25. package/Server/API/GitHubAPI.ts +47 -5
  26. package/Server/API/GoogleSecOpsConnectionAPI.ts +79 -0
  27. package/Server/API/UserWebAuthnAPI.ts +21 -1
  28. package/Server/API/VMwareResourceAPI.ts +143 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.ts +68 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.ts +26 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.ts +636 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.ts +47 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.ts +17 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.ts +83 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  36. package/Server/Middleware/IdentityRateLimit.ts +101 -0
  37. package/Server/Services/AIRunService.ts +13 -0
  38. package/Server/Services/BillingPaymentMethodService.ts +99 -28
  39. package/Server/Services/BillingService.ts +287 -20
  40. package/Server/Services/CloudResourceInstanceService.ts +70 -0
  41. package/Server/Services/ExceptionAggregationService.ts +1 -0
  42. package/Server/Services/GoogleSecOpsConnectionRunService.ts +10 -0
  43. package/Server/Services/GoogleSecOpsConnectionService.ts +12 -0
  44. package/Server/Services/Index.ts +16 -0
  45. package/Server/Services/LogAggregationService.ts +1 -0
  46. package/Server/Services/MetricAggregationService.ts +1 -0
  47. package/Server/Services/MobilePasskeyLoginService.ts +216 -0
  48. package/Server/Services/MonitorService.ts +51 -1
  49. package/Server/Services/MonitorTemplateService.ts +91 -29
  50. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +132 -1
  51. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +176 -2
  52. package/Server/Services/OpenTelemetryIngestService.ts +17 -0
  53. package/Server/Services/PayAsYouGoBillingService.ts +446 -0
  54. package/Server/Services/ProjectService.ts +46 -2
  55. package/Server/Services/ServerlessFunctionInstanceService.ts +71 -0
  56. package/Server/Services/TeamMemberService.ts +96 -36
  57. package/Server/Services/TelemetryIngestionKeyService.ts +80 -10
  58. package/Server/Services/TelemetryUsageBillingService.ts +95 -5
  59. package/Server/Services/TraceAggregationService.ts +5 -4
  60. package/Server/Services/UserWebAuthnService.ts +592 -133
  61. package/Server/Services/VMwareResourceService.ts +648 -0
  62. package/Server/Services/VMwareVCenterFeedService.ts +99 -0
  63. package/Server/Services/VMwareVCenterLabelRuleEngineService.ts +240 -0
  64. package/Server/Services/VMwareVCenterLabelRuleService.ts +14 -0
  65. package/Server/Services/VMwareVCenterOwnerRuleEngineService.ts +252 -0
  66. package/Server/Services/VMwareVCenterOwnerRuleService.ts +14 -0
  67. package/Server/Services/VMwareVCenterOwnerTeamService.ts +139 -0
  68. package/Server/Services/VMwareVCenterOwnerUserService.ts +133 -0
  69. package/Server/Services/VMwareVCenterService.ts +629 -0
  70. package/Server/Services/WorkflowVariableService.ts +203 -0
  71. package/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.ts +17 -0
  72. package/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.ts +31 -1
  73. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +7 -0
  74. package/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.ts +341 -0
  75. package/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.ts +274 -0
  76. package/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.ts +375 -0
  77. package/Server/Utils/CodeRepository/GitHub/GitHubConversation.ts +846 -0
  78. package/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.ts +360 -0
  79. package/Server/Utils/CodeRepository/GitHub/GitHubRunReply.ts +421 -0
  80. package/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.ts +140 -0
  81. package/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.ts +906 -0
  82. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +143 -0
  83. package/Server/Utils/DataSource/EgressGuard.ts +160 -15
  84. package/Server/Utils/Database/TruncateColumnValue.ts +1 -1
  85. package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +2 -0
  86. package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +33 -0
  87. package/Server/Utils/EmailRollup/EmailRollupWriter.ts +44 -0
  88. package/Server/Utils/LogRedaction.ts +2 -1
  89. package/Server/Utils/Monitor/MonitorAlert.ts +1 -1
  90. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +302 -3
  91. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +26 -4
  92. package/Server/Utils/Monitor/MonitorResourceContext.ts +5 -3
  93. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +14 -0
  94. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  95. package/Server/Utils/Monitor/SeriesResourceLabels.ts +26 -0
  96. package/Server/Utils/Monitor/SeriesResourceLinker.ts +28 -5
  97. package/Server/Utils/ResourceFeed/ResourceFeedUtil.ts +3 -3
  98. package/Server/Utils/SecurityEvent/ConnectorErrorMessage.ts +14 -9
  99. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.ts +116 -84
  100. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.ts +594 -195
  101. package/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.ts +466 -0
  102. package/Server/Utils/Telemetry/EntityRegistry.ts +5 -0
  103. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +2 -1
  104. package/Server/Utils/Telemetry/TelemetryEntity.ts +181 -1
  105. package/Server/Utils/Telemetry/VMwareSnapshotScan.ts +1352 -0
  106. package/Tests/App/Accounts/LoginPasskey.test.tsx +529 -0
  107. package/Tests/App/Accounts/MobilePasskey.test.tsx +620 -0
  108. package/Tests/App/Accounts/PasswordRequirements.test.tsx +254 -0
  109. package/Tests/App/Accounts/RegisterPassword.test.tsx +553 -0
  110. package/Tests/App/Dashboard/AskAiAvailability.test.ts +224 -0
  111. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +432 -0
  112. package/Tests/App/Dashboard/BackupCodes.test.tsx +414 -0
  113. package/Tests/App/Dashboard/BillingPaidUsageFlow.test.tsx +530 -0
  114. package/Tests/App/Dashboard/BillingPaymentMethodForm.test.tsx +195 -0
  115. package/Tests/App/Dashboard/BreadcrumbCoverage.test.tsx +199 -0
  116. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +198 -0
  117. package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +215 -0
  118. package/Tests/App/Dashboard/CloudFleetSummary.test.ts +183 -0
  119. package/Tests/App/Dashboard/CloudFleetSummaryComponent.test.tsx +248 -0
  120. package/Tests/App/Dashboard/CloudResourceTelemetryScope.test.ts +215 -0
  121. package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +3 -0
  122. package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +441 -0
  123. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +458 -0
  124. package/Tests/App/Dashboard/DashboardToolbarPopupLayering.test.tsx +566 -0
  125. package/Tests/App/Dashboard/DiscoveryScanLivePage.test.tsx +376 -0
  126. package/Tests/App/Dashboard/DiscoveryScanLiveUpdates.test.tsx +642 -0
  127. package/Tests/App/Dashboard/DiscoveryScanProgress.test.tsx +267 -0
  128. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +69 -231
  129. package/Tests/App/Dashboard/GoogleSecOpsConnectionsErrors.test.tsx +244 -0
  130. package/Tests/App/Dashboard/GoogleSecOpsDiagnostics.test.tsx +724 -0
  131. package/Tests/App/Dashboard/MonitorTemplateSyncFields.test.tsx +539 -0
  132. package/Tests/App/Dashboard/OnCallLayerCardOverrides.test.tsx +24 -7
  133. package/Tests/App/Dashboard/OnCallOverridePresentation.test.ts +496 -0
  134. package/Tests/App/Dashboard/OnCallScheduleOverrideClarity.test.tsx +677 -0
  135. package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +31 -3
  136. package/Tests/App/Dashboard/PaidUsageConsent.test.tsx +180 -0
  137. package/Tests/App/Dashboard/PasskeySettings.test.tsx +1220 -0
  138. package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +176 -275
  139. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +380 -233
  140. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +3 -23
  141. package/Tests/App/Dashboard/ResourceFeed.test.tsx +1 -0
  142. package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +8 -1
  143. package/Tests/App/Dashboard/TwoFactorStatus.test.tsx +260 -0
  144. package/Tests/App/Dashboard/VMwareDashboardWidgets.test.ts +573 -0
  145. package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
  146. package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +768 -0
  147. package/Tests/App/StatusPage/StatusPageOverviewLiveAndSearch.test.tsx +532 -40
  148. package/Tests/App/StatusPage/StatusPageResourceSearchBox.test.tsx +19 -2
  149. package/Tests/Fixtures/MobilePasskeyUser.json +8 -0
  150. package/Tests/Models/DatabaseModels/ResourceFeedModels.test.ts +25 -6
  151. package/Tests/Models/DatabaseModels/VMwareModels.test.ts +1134 -0
  152. package/Tests/Models/RunnerVersionLabel.test.ts +4 -2
  153. package/Tests/Server/API/AIChatProvidersAIEnabled.test.ts +259 -0
  154. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +31 -2
  155. package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +116 -0
  156. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +29 -1
  157. package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +13 -2
  158. package/Tests/Server/API/GitHubWebhookSignature.test.ts +368 -0
  159. package/Tests/Server/API/GoogleSecOpsConnectionAPI.test.ts +248 -0
  160. package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +330 -0
  161. package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +172 -0
  162. package/Tests/Server/API/VMwareResourceAPI.test.ts +546 -0
  163. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupMetadataMigration.test.ts +85 -0
  164. package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +34 -3
  165. package/Tests/Server/Middleware/PasskeyRateLimit.test.ts +141 -0
  166. package/Tests/Server/Services/AutoImportRuleRearmRecentScans.test.ts +343 -0
  167. package/Tests/Server/Services/AutoImportRuleWriteRearmsScans.test.ts +381 -0
  168. package/Tests/Server/Services/BillingPaymentMethodServiceSync.test.ts +175 -0
  169. package/Tests/Server/Services/BillingService.test.ts +26 -11
  170. package/Tests/Server/Services/BillingServiceMeteredPaymentAuthorization.test.ts +245 -0
  171. package/Tests/Server/Services/BillingServicePaymentMethodReads.test.ts +362 -0
  172. package/Tests/Server/Services/CloudResourceInstanceStalePrune.test.ts +188 -0
  173. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +16 -2
  174. package/Tests/Server/Services/GoogleSecOpsDiagnosticsModel.test.ts +153 -0
  175. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +13 -0
  176. package/Tests/Server/Services/InventoryItemPromotionGate.test.ts +5 -0
  177. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +36 -0
  178. package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +151 -0
  179. package/Tests/Server/Services/MobilePasskeyLoginIntegration.test.ts +231 -0
  180. package/Tests/Server/Services/MobilePasskeyLoginService.test.ts +315 -0
  181. package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +302 -0
  182. package/Tests/Server/Services/MonitorTemplateServiceFieldSync.test.ts +994 -0
  183. package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +22 -0
  184. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +7 -1
  185. package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +857 -0
  186. package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +379 -0
  187. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +99 -1
  188. package/Tests/Server/Services/ProjectServiceSubscriptionSeats.test.ts +134 -0
  189. package/Tests/Server/Services/ResourceFeedServices.test.ts +3 -2
  190. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +32 -6
  191. package/Tests/Server/Services/SecurityEventLastErrorColumnWidth.test.ts +363 -175
  192. package/Tests/Server/Services/ServerlessFunctionInstanceStalePrune.test.ts +200 -0
  193. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +3 -0
  194. package/Tests/Server/Services/TeamMemberBillingSeatSync.test.ts +762 -0
  195. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +3 -0
  196. package/Tests/Server/Services/TelemetryIngestionKeyPolicyResolution.test.ts +72 -0
  197. package/Tests/Server/Services/TelemetryIngestionKeyValidation.test.ts +17 -4
  198. package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +355 -0
  199. package/Tests/Server/Services/TraceAnalyticsResourceDisplayNames.test.ts +41 -4
  200. package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +37 -0
  201. package/Tests/Server/Services/UserWebAuthnPasskeyIntegration.test.ts +401 -0
  202. package/Tests/Server/Services/UserWebAuthnPasskeyService.test.ts +769 -0
  203. package/Tests/Server/Services/UserWebAuthnUserVerification.test.ts +649 -0
  204. package/Tests/Server/Services/VMwareResourceService.test.ts +945 -0
  205. package/Tests/Server/Services/VMwareVCenterService.test.ts +722 -0
  206. package/Tests/Server/Services/WorkflowVariableRenameUniqueness.test.ts +842 -0
  207. package/Tests/Server/TestingUtils/PasskeyHttpIntegration.ts +102 -0
  208. package/Tests/Server/TestingUtils/SecurityKey.ts +464 -0
  209. package/Tests/Server/TestingUtils/WebAuthnServiceMocks.ts +60 -0
  210. package/Tests/Server/Types/Billing/PayAsYouGoMeteredAuthorization.test.ts +573 -0
  211. package/Tests/Server/Types/Database/Permissions/ProjectCustomerSupportAccessColumn.test.ts +261 -0
  212. package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +95 -0
  213. package/Tests/Server/Utils/CodeRepository/GitHubAgentTaskTrigger.test.ts +2101 -0
  214. package/Tests/Server/Utils/CodeRepository/GitHubCommandAuthorizer.test.ts +883 -0
  215. package/Tests/Server/Utils/CodeRepository/GitHubCommandParser.test.ts +1474 -0
  216. package/Tests/Server/Utils/CodeRepository/GitHubConversation.test.ts +1526 -0
  217. package/Tests/Server/Utils/CodeRepository/GitHubReplyComposer.test.ts +1389 -0
  218. package/Tests/Server/Utils/CodeRepository/GitHubRunReply.test.ts +1707 -0
  219. package/Tests/Server/Utils/CodeRepository/GitHubWebhookHandler.test.ts +2202 -0
  220. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +345 -0
  221. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +896 -0
  222. package/Tests/Server/Utils/EmailRollup/EmailRollupMetadataIntegration.test.ts +246 -0
  223. package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +299 -1
  224. package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +6 -0
  225. package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +185 -0
  226. package/Tests/Server/Utils/LogRedaction.test.ts +33 -0
  227. package/Tests/Server/Utils/Monitor/CapturedMetricAttributeUtil.test.ts +2 -1
  228. package/Tests/Server/Utils/Monitor/Criteria/TelemetryStepMetricAlias.test.ts +10 -0
  229. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +66 -1
  230. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +362 -0
  231. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +1 -0
  232. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +60 -1
  233. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +60 -0
  234. package/Tests/Server/Utils/Monitor/MonitorRootCauseTargetResolution.test.ts +423 -0
  235. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +6 -0
  236. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +1 -0
  237. package/Tests/Server/Utils/Monitor/PerSeriesSecondEntityAlerting.test.ts +1 -0
  238. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +46 -2
  239. package/Tests/Server/Utils/SecurityEvent/ConnectorErrorMessage.test.ts +81 -45
  240. package/Tests/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.test.ts +711 -0
  241. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClickhouseIntegration.test.ts +223 -0
  242. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsClient.test.ts +69 -1
  243. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsDiagnostics.test.ts +838 -0
  244. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsErrorHandling.test.ts +241 -28
  245. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsHttpIntegration.test.ts +651 -0
  246. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPoller.test.ts +11 -0
  247. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerFailureTaxonomy.test.ts +13 -12
  248. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsPollerHardening.test.ts +112 -127
  249. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsRequestContract.test.ts +12 -18
  250. package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsResponseParsing.test.ts +43 -0
  251. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +580 -0
  252. package/Tests/Server/Utils/Telemetry/VMwareSnapshotScan.test.ts +1748 -0
  253. package/Tests/Types/Cloud/CloudPlatform.test.ts +574 -0
  254. package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +2 -0
  255. package/Tests/Types/Monitor/MonitorCriteriaMetricVariables.test.ts +9 -0
  256. package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
  257. package/Tests/Types/Monitor/MonitorStepInfraMonitorUtils.test.ts +53 -8
  258. package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +97 -0
  259. package/Tests/Types/Monitor/MonitorStepMetricViewConfigUtil.test.ts +1 -0
  260. package/Tests/Types/Monitor/MonitorStepTemplateSyncFields.test.ts +107 -0
  261. package/Tests/Types/Monitor/MonitorTemplateSyncField.test.ts +172 -0
  262. package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
  263. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +2 -0
  264. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationAlertDebuggability.test.ts +1 -0
  265. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +9 -0
  266. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  267. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  268. package/Tests/Types/Monitor/SeriesContext/SeriesDebugHints.test.ts +131 -0
  269. package/Tests/Types/Monitor/SeriesContext/SeriesLabelDisplay.test.ts +10 -0
  270. package/Tests/Types/Monitor/VMwareAlertTemplates.test.ts +1608 -0
  271. package/Tests/Types/Monitor/VMwareMetricCatalog.test.ts +488 -0
  272. package/Tests/Types/OnCallDutyPolicy/OverrideProvenance.test.ts +295 -0
  273. package/Tests/Types/Runner/RunnerLiveStatus.test.ts +2 -2
  274. package/Tests/Types/SignupPassword.test.ts +205 -0
  275. package/Tests/Types/StatusPage/StatusPageLanguage.test.ts +44 -0
  276. package/Tests/Types/SupportedLanguages.test.ts +119 -0
  277. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +19 -0
  278. package/Tests/UI/ColorPickerBuild.test.ts +86 -0
  279. package/Tests/UI/Components/Breadcrumbs.test.tsx +32 -0
  280. package/Tests/UI/Components/Forms/ModelFormPreservesUserInput.test.tsx +937 -0
  281. package/Tests/UI/Components/Forms/ModelFormWriteOnlyColumnSelect.test.tsx +230 -0
  282. package/Tests/UI/Components/Forms/ValidationFormSteps.test.ts +3 -4
  283. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +907 -0
  284. package/Tests/UI/Components/ModelTable/ModelTableCreateAfterEdit.test.tsx +514 -0
  285. package/Tests/UI/Components/MonitorGraphs/Uptime.test.tsx +301 -0
  286. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +2 -1
  287. package/Tests/UI/Components/TooltipLazyContent.test.tsx +373 -0
  288. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsMessagingEndpointGuidance.test.tsx +43 -12
  289. package/Tests/UI/ReactDomBuild.test.ts +104 -0
  290. package/Tests/UI/ReactRouterSingletonBuild.test.ts +11 -1
  291. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +148 -0
  292. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +29 -0
  293. package/Tests/UI/Utils/DashboardStackingLayers.test.ts +197 -0
  294. package/Tests/UI/Utils/LabelRuleImportExport.test.ts +546 -0
  295. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +109 -2
  296. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +7 -2
  297. package/Tests/UI/Utils/UserEmailRegistrationStatus.test.tsx +295 -0
  298. package/Tests/UI/Utils/WebAuthn.test.ts +265 -0
  299. package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +5 -0
  300. package/Tests/Utils/Dashboard/Components/DashboardVMwareListComponents.test.ts +548 -0
  301. package/Tests/Utils/Dashboard/DashboardResourceListSharedArgs.test.ts +17 -3
  302. package/Tests/Utils/LabelRuleImportExport.test.ts +583 -0
  303. package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
  304. package/Tests/Utils/Monitor/MonitorTemplateSyncUtil.test.ts +590 -0
  305. package/Tests/Utils/RequestFailedDetails.test.ts +325 -0
  306. package/Tests/Utils/Telemetry/CloudInstanceIdentity.test.ts +255 -0
  307. package/Tests/Utils/Telemetry/EntityRelationship.test.ts +167 -0
  308. package/Tests/Utils/WebAuthnTestUtil.ts +79 -0
  309. package/Tests/__mocks__/simplewebauthn.js +33 -4
  310. package/Types/AI/CodeFixTaskContext.ts +122 -0
  311. package/Types/AI/CodeFixTaskType.ts +62 -0
  312. package/Types/Accounts/AccountsLanguage.ts +1 -0
  313. package/Types/AdminDashboard/AdminDashboardLanguage.ts +1 -0
  314. package/Types/Calendar/CalendarEvent.ts +16 -0
  315. package/Types/Cloud/CloudPlatform.ts +372 -0
  316. package/Types/CodeRepository/GitHubCommand.ts +69 -0
  317. package/Types/Dashboard/DashboardComponentType.ts +2 -0
  318. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  319. package/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.ts +23 -0
  320. package/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.ts +30 -0
  321. package/Types/Dashboard/DashboardLanguage.ts +1 -0
  322. package/Types/Dashboard/DashboardTemplates.ts +314 -0
  323. package/Types/Docs/DocsLanguage.ts +1 -0
  324. package/Types/Exception/EgressGuardException.ts +65 -0
  325. package/Types/Icon/IconProp.ts +1 -0
  326. package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +36 -0
  327. package/Types/Monitor/MonitorCriteriaInstance.ts +1 -0
  328. package/Types/Monitor/MonitorStep.ts +78 -17
  329. package/Types/Monitor/MonitorStepMetricViewConfigUtil.ts +1 -0
  330. package/Types/Monitor/MonitorStepVMwareMonitor.ts +127 -0
  331. package/Types/Monitor/MonitorTemplateSyncField.ts +291 -0
  332. package/Types/Monitor/MonitorType.ts +24 -0
  333. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +33 -0
  334. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +2 -0
  335. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +3 -0
  336. package/Types/Monitor/SeriesContext/SeriesDebugHints.ts +158 -0
  337. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +61 -0
  338. package/Types/Monitor/VMwareAlertTemplates.ts +1070 -0
  339. package/Types/Monitor/VMwareMetricCatalog.ts +914 -0
  340. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +29 -0
  341. package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +16 -0
  342. package/Types/Password.ts +84 -5
  343. package/Types/Permission.ts +265 -0
  344. package/Types/Probe/RequestFailedDetails.ts +7 -0
  345. package/Types/Runner/RunnerLiveStatus.ts +1 -1
  346. package/Types/SecurityEvent/GoogleSecOpsDiagnostics.ts +56 -0
  347. package/Types/StatusPage/StatusPageLanguage.ts +1 -0
  348. package/Types/Telemetry/EntityType.ts +21 -0
  349. package/Types/Telemetry/ServiceType.ts +1 -0
  350. package/Typings/Index.d.ts +63 -0
  351. package/UI/Components/Breadcrumbs/Breadcrumbs.tsx +2 -2
  352. package/UI/Components/Calendar/Calendar.css +78 -0
  353. package/UI/Components/Calendar/Calendar.tsx +28 -3
  354. package/UI/Components/Forms/BasicForm.tsx +44 -2
  355. package/UI/Components/Forms/Fields/ColorPicker.tsx +2 -1
  356. package/UI/Components/Forms/Fields/FormField.tsx +16 -3
  357. package/UI/Components/Forms/ModelForm.tsx +159 -5
  358. package/UI/Components/Forms/Types/Field.ts +8 -1
  359. package/UI/Components/Graphs/DayUptimeGraph.tsx +8 -10
  360. package/UI/Components/Icon/Icon.tsx +16 -0
  361. package/UI/Components/Input/Input.tsx +42 -7
  362. package/UI/Components/LabelRule/ImportLabelRulesModal.tsx +441 -0
  363. package/UI/Components/LabelRule/LabelRuleTable.tsx +142 -0
  364. package/UI/Components/ModelTable/BaseModelTable.tsx +22 -5
  365. package/UI/Components/ModelTable/ModelTable.tsx +14 -6
  366. package/UI/Components/MonitorGraphs/Uptime.tsx +17 -27
  367. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +3 -1
  368. package/UI/Components/Tooltip/Tooltip.tsx +52 -6
  369. package/UI/Utils/DashboardStackingLayers.ts +85 -0
  370. package/UI/Utils/LabelRuleImportExport.ts +310 -0
  371. package/UI/Utils/ModelAPI/ModelAPI.ts +4 -3
  372. package/UI/Utils/TelemetryService.ts +4 -3
  373. package/UI/Utils/UseDashboardGridDnd.ts +4 -1
  374. package/UI/Utils/UserEmailRegistrationStatus.ts +33 -5
  375. package/UI/Utils/WebAuthn.ts +220 -0
  376. package/UI/esbuild-config.js +4 -0
  377. package/Utils/API.ts +34 -0
  378. package/Utils/Dashboard/Components/DashboardVMwareHostListComponent.ts +38 -0
  379. package/Utils/Dashboard/Components/DashboardVMwareResourceListShared.ts +70 -0
  380. package/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.ts +76 -0
  381. package/Utils/Dashboard/Components/Index.ts +16 -0
  382. package/Utils/LabelRuleImportExport.ts +496 -0
  383. package/Utils/Monitor/MonitorTemplateSyncUtil.ts +164 -0
  384. package/Utils/NetworkDiscovery/DiscoveryScanStatus.ts +8 -0
  385. package/Utils/Telemetry/CloudInstanceIdentity.ts +94 -0
  386. package/Utils/Telemetry/EntityKey.ts +19 -0
  387. package/Utils/Telemetry/EntityRelationship.ts +19 -0
  388. package/build/dist/Models/DatabaseModels/Alert.js +54 -0
  389. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  390. package/build/dist/Models/DatabaseModels/CloudResource.js +44 -7
  391. package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
  392. package/build/dist/Models/DatabaseModels/CodeRepository.js +87 -0
  393. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  394. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +60 -7
  395. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -1
  396. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js +287 -0
  397. package/build/dist/Models/DatabaseModels/GoogleSecOpsConnectionRun.js.map +1 -0
  398. package/build/dist/Models/DatabaseModels/Incident.js +54 -0
  399. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  400. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  401. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  402. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +54 -0
  403. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  404. package/build/dist/Models/DatabaseModels/User.js +57 -4
  405. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  406. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +47 -2
  407. package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -1
  408. package/build/dist/Models/DatabaseModels/UserWebAuthn.js +18 -0
  409. package/build/dist/Models/DatabaseModels/UserWebAuthn.js.map +1 -1
  410. package/build/dist/Models/DatabaseModels/VMwareResource.js +1201 -0
  411. package/build/dist/Models/DatabaseModels/VMwareResource.js.map +1 -0
  412. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +1149 -0
  413. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -0
  414. package/build/dist/Models/DatabaseModels/VMwareVCenterFeed.js +648 -0
  415. package/build/dist/Models/DatabaseModels/VMwareVCenterFeed.js.map +1 -0
  416. package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js +522 -0
  417. package/build/dist/Models/DatabaseModels/VMwareVCenterLabelRule.js.map +1 -0
  418. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js +603 -0
  419. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerRule.js.map +1 -0
  420. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js +503 -0
  421. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerTeam.js.map +1 -0
  422. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js +502 -0
  423. package/build/dist/Models/DatabaseModels/VMwareVCenterOwnerUser.js.map +1 -0
  424. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +22 -1
  425. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  426. package/build/dist/Server/API/AIAgentDataAPI.js +63 -3
  427. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  428. package/build/dist/Server/API/AIAgentGitHubAPI.js +363 -0
  429. package/build/dist/Server/API/AIAgentGitHubAPI.js.map +1 -0
  430. package/build/dist/Server/API/AIChatAPI.js +19 -1
  431. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  432. package/build/dist/Server/API/BillingAPI.js +22 -0
  433. package/build/dist/Server/API/BillingAPI.js.map +1 -1
  434. package/build/dist/Server/API/DashboardAPI.js +10 -0
  435. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  436. package/build/dist/Server/API/GitHubAPI.js +33 -5
  437. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  438. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js +56 -0
  439. package/build/dist/Server/API/GoogleSecOpsConnectionAPI.js.map +1 -0
  440. package/build/dist/Server/API/UserWebAuthnAPI.js +17 -1
  441. package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
  442. package/build/dist/Server/API/VMwareResourceAPI.js +106 -0
  443. package/build/dist/Server/API/VMwareResourceAPI.js.map +1 -0
  444. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.js +41 -0
  445. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791800000000-SplitWebAuthnChallengeByPurpose.js.map +1 -0
  446. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.js +14 -0
  447. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791900000000-AddSeverityAndStateToNotificationEmailRollup.js.map +1 -0
  448. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.js +241 -0
  449. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792000000000-AddVMwareTables.js.map +1 -0
  450. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.js +36 -0
  451. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792100000000-AddGitHubCommandSettingsToCodeRepository.js.map +1 -0
  452. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.js +12 -0
  453. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792200000000-AddUserWebAuthnPurpose.js.map +1 -0
  454. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.js +34 -0
  455. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1792300000000-AddGoogleSecOpsDiagnostics.js.map +1 -0
  456. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  457. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  458. package/build/dist/Server/Middleware/IdentityRateLimit.js +80 -0
  459. package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
  460. package/build/dist/Server/Services/AIRunService.js +14 -1
  461. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  462. package/build/dist/Server/Services/BillingPaymentMethodService.js +71 -21
  463. package/build/dist/Server/Services/BillingPaymentMethodService.js.map +1 -1
  464. package/build/dist/Server/Services/BillingService.js +210 -22
  465. package/build/dist/Server/Services/BillingService.js.map +1 -1
  466. package/build/dist/Server/Services/CloudResourceInstanceService.js +66 -0
  467. package/build/dist/Server/Services/CloudResourceInstanceService.js.map +1 -1
  468. package/build/dist/Server/Services/ExceptionAggregationService.js +1 -0
  469. package/build/dist/Server/Services/ExceptionAggregationService.js.map +1 -1
  470. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js +9 -0
  471. package/build/dist/Server/Services/GoogleSecOpsConnectionRunService.js.map +1 -0
  472. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js +7 -0
  473. package/build/dist/Server/Services/GoogleSecOpsConnectionService.js.map +1 -1
  474. package/build/dist/Server/Services/Index.js +16 -0
  475. package/build/dist/Server/Services/Index.js.map +1 -1
  476. package/build/dist/Server/Services/LogAggregationService.js +1 -0
  477. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  478. package/build/dist/Server/Services/MetricAggregationService.js +1 -0
  479. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  480. package/build/dist/Server/Services/MobilePasskeyLoginService.js +137 -0
  481. package/build/dist/Server/Services/MobilePasskeyLoginService.js.map +1 -0
  482. package/build/dist/Server/Services/MonitorService.js +34 -1
  483. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  484. package/build/dist/Server/Services/MonitorTemplateService.js +64 -26
  485. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  486. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +124 -1
  487. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
  488. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +142 -2
  489. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
  490. package/build/dist/Server/Services/OpenTelemetryIngestService.js +28 -13
  491. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  492. package/build/dist/Server/Services/PayAsYouGoBillingService.js +297 -0
  493. package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -0
  494. package/build/dist/Server/Services/ProjectService.js +38 -2
  495. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  496. package/build/dist/Server/Services/ServerlessFunctionInstanceService.js +66 -0
  497. package/build/dist/Server/Services/ServerlessFunctionInstanceService.js.map +1 -1
  498. package/build/dist/Server/Services/TeamMemberService.js +85 -28
  499. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  500. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +61 -10
  501. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  502. package/build/dist/Server/Services/TelemetryUsageBillingService.js +62 -5
  503. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  504. package/build/dist/Server/Services/TraceAggregationService.js +5 -4
  505. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  506. package/build/dist/Server/Services/UserWebAuthnService.js +345 -113
  507. package/build/dist/Server/Services/UserWebAuthnService.js.map +1 -1
  508. package/build/dist/Server/Services/VMwareResourceService.js +395 -0
  509. package/build/dist/Server/Services/VMwareResourceService.js.map +1 -0
  510. package/build/dist/Server/Services/VMwareVCenterFeedService.js +89 -0
  511. package/build/dist/Server/Services/VMwareVCenterFeedService.js.map +1 -0
  512. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js +197 -0
  513. package/build/dist/Server/Services/VMwareVCenterLabelRuleEngineService.js.map +1 -0
  514. package/build/dist/Server/Services/VMwareVCenterLabelRuleService.js +13 -0
  515. package/build/dist/Server/Services/VMwareVCenterLabelRuleService.js.map +1 -0
  516. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js +214 -0
  517. package/build/dist/Server/Services/VMwareVCenterOwnerRuleEngineService.js.map +1 -0
  518. package/build/dist/Server/Services/VMwareVCenterOwnerRuleService.js +13 -0
  519. package/build/dist/Server/Services/VMwareVCenterOwnerRuleService.js.map +1 -0
  520. package/build/dist/Server/Services/VMwareVCenterOwnerTeamService.js +129 -0
  521. package/build/dist/Server/Services/VMwareVCenterOwnerTeamService.js.map +1 -0
  522. package/build/dist/Server/Services/VMwareVCenterOwnerUserService.js +122 -0
  523. package/build/dist/Server/Services/VMwareVCenterOwnerUserService.js.map +1 -0
  524. package/build/dist/Server/Services/VMwareVCenterService.js +533 -0
  525. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -0
  526. package/build/dist/Server/Services/WorkflowVariableService.js +169 -0
  527. package/build/dist/Server/Services/WorkflowVariableService.js.map +1 -1
  528. package/build/dist/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.js +12 -1
  529. package/build/dist/Server/Types/Billing/MeteredPlan/ActiveMonitoringMeteredPlan.js.map +1 -1
  530. package/build/dist/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.js +25 -2
  531. package/build/dist/Server/Types/Billing/MeteredPlan/TelemetryMeteredPlan.js.map +1 -1
  532. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  533. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.js +275 -0
  534. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubAgentTaskTrigger.js.map +1 -0
  535. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.js +226 -0
  536. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandAuthorizer.js.map +1 -0
  537. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.js +297 -0
  538. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubCommandParser.js.map +1 -0
  539. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubConversation.js +582 -0
  540. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubConversation.js.map +1 -0
  541. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.js +275 -0
  542. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubReplyComposer.js.map +1 -0
  543. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubRunReply.js +365 -0
  544. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubRunReply.js.map +1 -0
  545. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.js +103 -0
  546. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookEvents.js.map +1 -0
  547. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.js +661 -0
  548. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubWebhookHandler.js.map +1 -0
  549. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +113 -0
  550. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  551. package/build/dist/Server/Utils/DataSource/EgressGuard.js +99 -15
  552. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  553. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +2 -0
  554. package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -1
  555. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +18 -0
  556. package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -1
  557. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +31 -2
  558. package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -1
  559. package/build/dist/Server/Utils/LogRedaction.js +2 -1
  560. package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
  561. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +1 -1
  562. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +219 -4
  563. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  564. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +12 -4
  565. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  566. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +5 -3
  567. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -1
  568. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +22 -9
  569. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -1
  570. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  571. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  572. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +21 -0
  573. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  574. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +21 -6
  575. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  576. package/build/dist/Server/Utils/ResourceFeed/ResourceFeedUtil.js +3 -3
  577. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js +9 -9
  578. package/build/dist/Server/Utils/SecurityEvent/ConnectorErrorMessage.js.map +1 -1
  579. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js +92 -71
  580. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsClient.js.map +1 -1
  581. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js +428 -143
  582. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsPoller.js.map +1 -1
  583. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js +376 -0
  584. package/build/dist/Server/Utils/SecurityEvent/GoogleSecOps/GoogleSecOpsRunExecutor.js.map +1 -0
  585. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +5 -0
  586. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  587. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -1
  588. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +136 -1
  589. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  590. package/build/dist/Server/Utils/Telemetry/VMwareSnapshotScan.js +933 -0
  591. package/build/dist/Server/Utils/Telemetry/VMwareSnapshotScan.js.map +1 -0
  592. package/build/dist/Types/AI/CodeFixTaskContext.js +40 -0
  593. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  594. package/build/dist/Types/AI/CodeFixTaskType.js +57 -0
  595. package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -1
  596. package/build/dist/Types/Accounts/AccountsLanguage.js +1 -0
  597. package/build/dist/Types/Accounts/AccountsLanguage.js.map +1 -1
  598. package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js +1 -0
  599. package/build/dist/Types/AdminDashboard/AdminDashboardLanguage.js.map +1 -1
  600. package/build/dist/Types/Cloud/CloudPlatform.js +277 -0
  601. package/build/dist/Types/Cloud/CloudPlatform.js.map +1 -0
  602. package/build/dist/Types/CodeRepository/GitHubCommand.js +52 -0
  603. package/build/dist/Types/CodeRepository/GitHubCommand.js.map +1 -0
  604. package/build/dist/Types/Dashboard/DashboardComponentType.js +2 -0
  605. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  606. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  607. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  608. package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.js +2 -0
  609. package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareHostListComponent.js.map +1 -0
  610. package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.js +2 -0
  611. package/build/dist/Types/Dashboard/DashboardComponents/DashboardVMwareVirtualMachineListComponent.js.map +1 -0
  612. package/build/dist/Types/Dashboard/DashboardLanguage.js +1 -0
  613. package/build/dist/Types/Dashboard/DashboardLanguage.js.map +1 -1
  614. package/build/dist/Types/Dashboard/DashboardTemplates.js +286 -0
  615. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  616. package/build/dist/Types/Docs/DocsLanguage.js +1 -0
  617. package/build/dist/Types/Docs/DocsLanguage.js.map +1 -1
  618. package/build/dist/Types/Exception/EgressGuardException.js +59 -0
  619. package/build/dist/Types/Exception/EgressGuardException.js.map +1 -0
  620. package/build/dist/Types/Icon/IconProp.js +1 -0
  621. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  622. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +1 -0
  623. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  624. package/build/dist/Types/Monitor/MonitorStep.js +61 -18
  625. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  626. package/build/dist/Types/Monitor/MonitorStepMetricViewConfigUtil.js +1 -0
  627. package/build/dist/Types/Monitor/MonitorStepMetricViewConfigUtil.js.map +1 -1
  628. package/build/dist/Types/Monitor/MonitorStepVMwareMonitor.js +71 -0
  629. package/build/dist/Types/Monitor/MonitorStepVMwareMonitor.js.map +1 -0
  630. package/build/dist/Types/Monitor/MonitorTemplateSyncField.js +211 -0
  631. package/build/dist/Types/Monitor/MonitorTemplateSyncField.js.map +1 -0
  632. package/build/dist/Types/Monitor/MonitorType.js +23 -0
  633. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  634. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +28 -0
  635. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  636. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +1 -0
  637. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  638. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +2 -0
  639. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -1
  640. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js +120 -0
  641. package/build/dist/Types/Monitor/SeriesContext/SeriesDebugHints.js.map +1 -1
  642. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +60 -0
  643. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  644. package/build/dist/Types/Monitor/VMwareAlertTemplates.js +775 -0
  645. package/build/dist/Types/Monitor/VMwareAlertTemplates.js.map +1 -0
  646. package/build/dist/Types/Monitor/VMwareMetricCatalog.js +799 -0
  647. package/build/dist/Types/Monitor/VMwareMetricCatalog.js.map +1 -0
  648. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +25 -0
  649. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
  650. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +5 -0
  651. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
  652. package/build/dist/Types/Password.js +63 -5
  653. package/build/dist/Types/Password.js.map +1 -1
  654. package/build/dist/Types/Permission.js +234 -0
  655. package/build/dist/Types/Permission.js.map +1 -1
  656. package/build/dist/Types/Probe/RequestFailedDetails.js +7 -0
  657. package/build/dist/Types/Probe/RequestFailedDetails.js.map +1 -1
  658. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js +2 -0
  659. package/build/dist/Types/SecurityEvent/GoogleSecOpsDiagnostics.js.map +1 -0
  660. package/build/dist/Types/StatusPage/StatusPageLanguage.js +1 -0
  661. package/build/dist/Types/StatusPage/StatusPageLanguage.js.map +1 -1
  662. package/build/dist/Types/Telemetry/EntityType.js +21 -0
  663. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  664. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  665. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  666. package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js +2 -2
  667. package/build/dist/UI/Components/Breadcrumbs/Breadcrumbs.js.map +1 -1
  668. package/build/dist/UI/Components/Calendar/Calendar.js +24 -4
  669. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  670. package/build/dist/UI/Components/Forms/BasicForm.js +28 -3
  671. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  672. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +1 -1
  673. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  674. package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -3
  675. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  676. package/build/dist/UI/Components/Forms/ModelForm.js +89 -6
  677. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  678. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +5 -6
  679. package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
  680. package/build/dist/UI/Components/Icon/Icon.js +14 -0
  681. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  682. package/build/dist/UI/Components/Input/Input.js +37 -8
  683. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  684. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js +228 -0
  685. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js.map +1 -0
  686. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js +102 -0
  687. package/build/dist/UI/Components/LabelRule/LabelRuleTable.js.map +1 -0
  688. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +15 -2
  689. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  690. package/build/dist/UI/Components/ModelTable/ModelTable.js +13 -5
  691. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  692. package/build/dist/UI/Components/MonitorGraphs/Uptime.js +14 -15
  693. package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
  694. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +2 -0
  695. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  696. package/build/dist/UI/Components/Tooltip/Tooltip.js +33 -4
  697. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  698. package/build/dist/UI/Utils/DashboardStackingLayers.js +44 -0
  699. package/build/dist/UI/Utils/DashboardStackingLayers.js.map +1 -0
  700. package/build/dist/UI/Utils/LabelRuleImportExport.js +195 -0
  701. package/build/dist/UI/Utils/LabelRuleImportExport.js.map +1 -0
  702. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +4 -4
  703. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  704. package/build/dist/UI/Utils/TelemetryService.js +3 -2
  705. package/build/dist/UI/Utils/TelemetryService.js.map +1 -1
  706. package/build/dist/UI/Utils/UseDashboardGridDnd.js +2 -1
  707. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -1
  708. package/build/dist/UI/Utils/UserEmailRegistrationStatus.js +21 -4
  709. package/build/dist/UI/Utils/UserEmailRegistrationStatus.js.map +1 -1
  710. package/build/dist/UI/Utils/WebAuthn.js +121 -0
  711. package/build/dist/UI/Utils/WebAuthn.js.map +1 -0
  712. package/build/dist/Utils/API.js +29 -0
  713. package/build/dist/Utils/API.js.map +1 -1
  714. package/build/dist/Utils/Dashboard/Components/DashboardVMwareHostListComponent.js +33 -0
  715. package/build/dist/Utils/Dashboard/Components/DashboardVMwareHostListComponent.js.map +1 -0
  716. package/build/dist/Utils/Dashboard/Components/DashboardVMwareResourceListShared.js +54 -0
  717. package/build/dist/Utils/Dashboard/Components/DashboardVMwareResourceListShared.js.map +1 -0
  718. package/build/dist/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.js +60 -0
  719. package/build/dist/Utils/Dashboard/Components/DashboardVMwareVirtualMachineListComponent.js.map +1 -0
  720. package/build/dist/Utils/Dashboard/Components/Index.js +8 -0
  721. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  722. package/build/dist/Utils/LabelRuleImportExport.js +356 -0
  723. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -0
  724. package/build/dist/Utils/Monitor/MonitorTemplateSyncUtil.js +110 -0
  725. package/build/dist/Utils/Monitor/MonitorTemplateSyncUtil.js.map +1 -0
  726. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js +6 -0
  727. package/build/dist/Utils/NetworkDiscovery/DiscoveryScanStatus.js.map +1 -1
  728. package/build/dist/Utils/Telemetry/CloudInstanceIdentity.js +88 -0
  729. package/build/dist/Utils/Telemetry/CloudInstanceIdentity.js.map +1 -0
  730. package/build/dist/Utils/Telemetry/EntityKey.js +15 -0
  731. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  732. package/build/dist/Utils/Telemetry/EntityRelationship.js +13 -0
  733. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
  734. package/package.json +1 -1
@@ -9,6 +9,7 @@ import { WidenSecurityEventLastErrorColumns1789800000000 } from "../../../Server
9
9
  import SchemaMigrations from "../../../Server/Infrastructure/Postgres/SchemaMigrations/Index";
10
10
  import DetectionRuleService from "../../../Server/Services/DetectionRuleService";
11
11
  import GoogleSecOpsConnectionService from "../../../Server/Services/GoogleSecOpsConnectionService";
12
+ import { REDACTED, redactLogString } from "../../../Server/Utils/LogRedaction";
12
13
  import ConnectorErrorMessage, {
13
14
  MAX_CONNECTOR_ERROR_MESSAGE_LENGTH,
14
15
  } from "../../../Server/Utils/SecurityEvent/ConnectorErrorMessage";
@@ -36,30 +37,49 @@ import { beforeAll, describe, expect, test } from "@jest/globals";
36
37
  * varchar(500), and DatabaseService.checkMaxLengthOfFields rejects any
37
38
  * string longer than a column's declared max with a BadDataException. The
38
39
  * poller's catch block writes { lastPolledAt, lastError } to record a
39
- * failed poll, and a Google SecOps client error is a ~46 character prefix
40
- * plus up to 500 characters of echoed response body 546, past the bound.
41
- * So the write that was recording the failure became a second failure,
42
- * threw out of the catch block, and took pollAllDueConnections down with
43
- * it: nothing stamped, every remaining connection in that tick skipped,
40
+ * failed poll, and a Google SecOps client error is a short prefix plus an
41
+ * echo of whatever Google sent backcomfortably past the bound. So the
42
+ * write that was recording the failure became a second failure, threw out
43
+ * of the catch block, and took pollAllDueConnections down with it:
44
+ * nothing stamped, every remaining connection in that tick skipped,
44
45
  * repeated every minute forever. The customer's row read lastPolledAt =
45
46
  * null AND lastError = null, because the two columns meant to explain the
46
47
  * outage were exactly the ones the outage prevented from being written.
47
48
  * DetectionRuleEvaluator had the identical pattern on DetectionRule
48
49
  * .lastError, where ClickHouse errors echo the whole compiled query.
49
50
  *
50
- * Four things have to line up, and a regression in any one of them brings
51
- * the silent outage back:
51
+ * THE CURRENT CONTRACT and why the old cap is gone. GoogleSecOpsClient
52
+ * used to clip every echoed body with `.slice(0, BODY_ECHO_LIMIT)`, and an
53
+ * earlier version of this file leaned on that cap as its bound: read the
54
+ * number out of the client, assert the stored value was prefix + exactly
55
+ * that many characters. That cap was deliberately removed. The echo sites
56
+ * now run the body through the client's own redactErrorBody() (which
57
+ * decodes nested JSON before handing it to redactLogString /
58
+ * redactLogValue), which strips credentials but truncates nothing — an
59
+ * operator gets the WHOLE redacted diagnostic. GoogleSecOpsPoller stores it
60
+ * with ConnectorErrorMessage.toMessage(error, { truncate: false }), opting
61
+ * out of the connector clamp entirely, which is only safe because
62
+ * lastError is unbounded `text`. So the property that makes echoing a
63
+ * customer-supplied body safe is REDACTION, not length, and the property
64
+ * that makes storing it safe is that the column has no maximum at all.
65
+ *
66
+ * Five things have to line up, and a regression in any one of them brings
67
+ * the silent outage — or a stored credential — back:
52
68
  * 1. both entities declare VeryLongText / `text` with no length, so
53
69
  * getMaxLengthFromTableColumnType returns undefined and the length
54
70
  * check cannot reject a stored error at all,
55
71
  * 2. the widest message the producers can actually emit really is
56
72
  * accepted — pinned end to end, from every one of the client's own
57
73
  * failure paths through ConnectorErrorMessage.toMessage to the real
58
- * DatabaseService length check,
59
- * 3. the migration widens the live Postgres columns with ALTER COLUMN
74
+ * DatabaseService length check, with the poller's own
75
+ * { truncate: false } storing it whole,
76
+ * 3. every echoed body is redacted, so a private_key / client_secret /
77
+ * token in a response body — including one buried in nested JSON
78
+ * inside an error message — never reaches the column verbatim,
79
+ * 4. the migration widens the live Postgres columns with ALTER COLUMN
60
80
  * ... TYPE text rather than DROP + ADD, which would discard every
61
81
  * error already stored, and
62
- * 4. the migration is registered in SchemaMigrations/Index.ts — an
82
+ * 5. the migration is registered in SchemaMigrations/Index.ts — an
63
83
  * unregistered migration never runs, so production would stay on
64
84
  * varchar(500) while every entity-level assertion here still passed.
65
85
  * That combination is precisely how this failure comes back.
@@ -92,89 +112,6 @@ const MIGRATIONS_INDEX_SOURCE: string = fs.readFileSync(
92
112
  "utf8",
93
113
  );
94
114
 
95
- const GOOGLE_SECOPS_CLIENT_SOURCE: string = fs.readFileSync(
96
- path.join(
97
- __dirname,
98
- "..",
99
- "..",
100
- "..",
101
- "Server",
102
- "Utils",
103
- "SecurityEvent",
104
- "GoogleSecOps",
105
- "GoogleSecOpsClient.ts",
106
- ),
107
- "utf8",
108
- );
109
-
110
- /*
111
- * How many characters of whatever Google sent back the client is willing to
112
- * echo, read out of the client itself rather than restated here. Restating
113
- * it would let the client widen its echo without a single test noticing
114
- * that the stored value grew with it.
115
- *
116
- * The premise this file was written on — "there are two error templates and
117
- * both write `responseText.slice(0, 500)`" — no longer holds. The client
118
- * reports the failures that arrive on an HTTP 200 as well now (an empty
119
- * body, a body that is not JSON, a shape the parser does not recognize, a
120
- * query Chronicle rejected in band), and each of those echoes the thing it
121
- * could not read through a NAMED constant rather than an inline literal. A
122
- * scan pinned to the inline form kept passing while it covered less than a
123
- * third of the sites, which is the failure mode this function exists to
124
- * prevent. So: every `.slice(0, N)` in the client, named bounds resolved.
125
- */
126
- function responseBodyEchoLimits(): Array<number> {
127
- const pattern: RegExp = /\.slice\(\s*0\s*,\s*(\w+)\s*\)/g;
128
- const limits: Array<number> = [];
129
-
130
- let match: RegExpExecArray | null = pattern.exec(GOOGLE_SECOPS_CLIENT_SOURCE);
131
- while (match) {
132
- limits.push(resolveNumericToken(String(match[1])));
133
- match = pattern.exec(GOOGLE_SECOPS_CLIENT_SOURCE);
134
- }
135
-
136
- return limits;
137
- }
138
-
139
- /*
140
- * An inline bound is its own value; a named one is resolved out of the
141
- * client's `const NAME: number = N` declaration. An unresolvable name
142
- * throws rather than becoming NaN and satisfying "they are all equal" by
143
- * accident.
144
- */
145
- const INLINE_BOUND_PATTERN: RegExp = /^\d+$/;
146
-
147
- function resolveNumericToken(token: string): number {
148
- if (INLINE_BOUND_PATTERN.test(token)) {
149
- return Number(token);
150
- }
151
-
152
- const declaration: RegExpMatchArray | null =
153
- GOOGLE_SECOPS_CLIENT_SOURCE.match(
154
- new RegExp(`\\b${token}\\s*:\\s*number\\s*=\\s*(\\d+)`),
155
- );
156
-
157
- if (!declaration || declaration[1] === undefined) {
158
- throw new Error(
159
- `GoogleSecOpsClient truncates with .slice(0, ${token}) but declares no numeric ${token} — this file cannot bound what it stores`,
160
- );
161
- }
162
-
163
- return Number(declaration[1]);
164
- }
165
-
166
- function responseBodyEchoLimit(): number {
167
- const limits: Array<number> = responseBodyEchoLimits();
168
-
169
- if (limits.length === 0) {
170
- throw new Error(
171
- "GoogleSecOpsClient no longer truncates anything with .slice(0, N) — this file's premise, that every stored error is bounded by a cap the client applies before ConnectorErrorMessage ever sees it, needs revisiting",
172
- );
173
- }
174
-
175
- return Math.max(...limits);
176
- }
177
-
178
115
  const { privateKey } = generateKeyPairSync("rsa", {
179
116
  modulusLength: 2048,
180
117
  privateKeyEncoding: { type: "pkcs8", format: "pem" },
@@ -184,8 +121,8 @@ const { privateKey } = generateKeyPairSync("rsa", {
184
121
  /*
185
122
  * The real token endpoint, not an example.com stand-in: the client now
186
123
  * refuses a token_uri outside Google's hosts, because that URL is
187
- * customer-supplied and the first 500 characters of whatever answers it are
188
- * echoed straight into lastError. Nothing here reaches the network — the
124
+ * customer-supplied and whatever answers it is echoed (redacted, and in
125
+ * full) straight into lastError. Nothing here reaches the network — the
189
126
  * fetch is injected — so the host only has to satisfy that check.
190
127
  */
191
128
  const SERVICE_ACCOUNT_JSON: string = JSON.stringify({
@@ -198,10 +135,76 @@ const INSTANCE: string =
198
135
  "projects/my-project/locations/us/instances/3f0a-instance";
199
136
 
200
137
  /*
201
- * Comfortably longer than anything the client will keep, so both templates
202
- * echo a full-width body and the resulting message is the widest possible.
138
+ * The client no longer clips what it echoes, so the width of a stored error
139
+ * is the width of the body Google sent. This is deliberately FAR wider than
140
+ * MAX_CONNECTOR_ERROR_MESSAGE_LENGTH — four times it — for two reasons:
141
+ * the resulting message is one the connector clamp WOULD cut if the poller
142
+ * had not opted out, so the untruncated-storage path is genuinely
143
+ * exercised rather than trivially satisfied, and it is far past the
144
+ * varchar(500) bound whose reappearance is the outage this file guards.
145
+ * It is a local constant on purpose: nothing in the client bounds it any
146
+ * more, so there is nothing left to read out of the client.
147
+ */
148
+ const OVERSIZED_RESPONSE_BODY_LENGTH: number =
149
+ MAX_CONNECTOR_ERROR_MESSAGE_LENGTH * 4;
150
+
151
+ const OVERSIZED_RESPONSE_BODY: string = "x".repeat(
152
+ OVERSIZED_RESPONSE_BODY_LENGTH,
153
+ );
154
+
155
+ /*
156
+ * Credential-shaped values, in the shapes a token endpoint or a Chronicle
157
+ * error envelope actually carries them. None of these is real; what matters
158
+ * is that each one is the sort of value the redactor must never let through
159
+ * into a column an operator reads in the dashboard.
160
+ */
161
+ const LEAKED_CLIENT_SECRET: string = "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9a3b";
162
+ const LEAKED_ACCESS_TOKEN: string =
163
+ "ya29.c.b0Aaekm1J7NotARealTokenValue0123456789";
164
+ const LEAKED_PRIVATE_KEY_BODY: string =
165
+ "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEANotARealKey";
166
+ const LEAKED_PRIVATE_KEY_PEM: string = `-----BEGIN PRIVATE KEY-----\n${LEAKED_PRIVATE_KEY_BODY}\n-----END PRIVATE KEY-----\n`;
167
+
168
+ const LEAKED_SECRETS: Array<string> = [
169
+ LEAKED_CLIENT_SECRET,
170
+ LEAKED_ACCESS_TOKEN,
171
+ LEAKED_PRIVATE_KEY_BODY,
172
+ ];
173
+
174
+ /*
175
+ * Credentials sitting in their own fields, which is what an OAuth error
176
+ * response or a misconfigured proxy echo looks like.
177
+ */
178
+ const FLAT_CREDENTIAL_BODY: string = JSON.stringify({
179
+ error: {
180
+ code: 403,
181
+ status: "PERMISSION_DENIED",
182
+ message: "The caller does not have permission.",
183
+ client_secret: LEAKED_CLIENT_SECRET,
184
+ access_token: LEAKED_ACCESS_TOKEN,
185
+ private_key: LEAKED_PRIVATE_KEY_PEM,
186
+ },
187
+ });
188
+
189
+ /*
190
+ * The case commit c0f9e0c2db fixed: the credential JSON is a STRING inside
191
+ * the error message, so its key quotes arrive escaped. A purely textual
192
+ * redactor never sees `"client_secret":` in that form and walks straight
193
+ * past it — which is why redactErrorBody decodes the outer JSON before
194
+ * redacting. The test below asserts both halves of that: the raw textual
195
+ * pass really is fooled, and the client's echo is not.
203
196
  */
204
- const OVERSIZED_RESPONSE_BODY: string = "x".repeat(responseBodyEchoLimit() * 4);
197
+ const NESTED_CREDENTIAL_BODY: string = JSON.stringify({
198
+ error: {
199
+ code: 400,
200
+ status: "INVALID_ARGUMENT",
201
+ message: JSON.stringify({
202
+ client_secret: LEAKED_CLIENT_SECRET,
203
+ access_token: LEAKED_ACCESS_TOKEN,
204
+ private_key: LEAKED_PRIVATE_KEY_PEM,
205
+ }),
206
+ },
207
+ });
205
208
 
206
209
  function makeFetch(
207
210
  responses: Array<{ status: number; body: string }>,
@@ -256,6 +259,18 @@ async function thrownClientError(
256
259
  throw new Error("Expected GoogleSecOpsClient to throw, but it did not");
257
260
  }
258
261
 
262
+ /*
263
+ * Exactly what GoogleSecOpsPoller.ts writes into lastError: the connector
264
+ * clamp explicitly disabled, then one more redaction pass. Both halves are
265
+ * reproduced here rather than approximated, because "the value the poller
266
+ * stores fits the column" is the whole claim of this file.
267
+ */
268
+ function storedLastError(error: Error): string {
269
+ return redactLogString(
270
+ ConnectorErrorMessage.toMessage(error, { truncate: false }),
271
+ );
272
+ }
273
+
259
274
  interface LastErrorColumn {
260
275
  label: string;
261
276
  table: string;
@@ -427,12 +442,12 @@ describe("the widest error the producers can emit is storable", () => {
427
442
  let widestClientError: Error;
428
443
 
429
444
  beforeAll(async () => {
430
- // Fails at the JWT-bearer token exchange: the first template.
445
+ // Fails at the JWT-bearer token exchange: the first echo site.
431
446
  tokenExchangeError = await thrownClientError([
432
447
  { status: 503, body: OVERSIZED_RESPONSE_BODY },
433
448
  ]);
434
449
 
435
- // Token succeeds, the alerts call fails: the second template.
450
+ // Token succeeds, the alerts call fails: the second echo site.
436
451
  alertsFetchError = await thrownClientError([
437
452
  successfulTokenResponse(),
438
453
  { status: 500, body: OVERSIZED_RESPONSE_BODY },
@@ -444,46 +459,59 @@ describe("the widest error the producers can emit is storable", () => {
444
459
  : tokenExchangeError;
445
460
  });
446
461
 
447
- test("every body the client echoes is capped at the same limit", () => {
462
+ test("each HTTP failure echoes the WHOLE response body, with nothing clipped off the end", () => {
448
463
  /*
449
- * The premise, restated honestly. It is no longer "exactly two
450
- * templates" the count is whatever the client has, and what must hold
451
- * is that all of them truncate at one number. A single site echoing
452
- * further than the rest would widen the stored value without widening
453
- * anything that bounds it, and the two-site scan this replaced would
454
- * not have seen it: four of the seven sites did not exist when that
455
- * assertion was written.
464
+ * What replaced the cap. There is no longer a number to read out of
465
+ * the client and compare against; the assertion is that the body the
466
+ * client was handed survives into the message in one piece, tail
467
+ * included. A `.slice(0, N)` reintroduced at either site fails here,
468
+ * because the last character of the body would stop being the last
469
+ * character of the message.
456
470
  */
457
- const limits: Array<number> = responseBodyEchoLimits();
458
-
459
- expect(limits.length).toBeGreaterThan(2);
460
- expect(new Set(limits).size).toBe(1);
461
- expect(responseBodyEchoLimit()).toBe(limits[0]);
462
- });
463
-
464
- test("each template is a fixed prefix plus a full-width echo of the response body", () => {
465
- const echoLimit: number = responseBodyEchoLimit();
466
-
467
471
  for (const error of [tokenExchangeError, alertsFetchError]) {
468
- // The tail is the echoed body, clipped to the client's own cap.
469
- expect(error.message.endsWith("x".repeat(echoLimit))).toBe(true);
470
- expect(error.message.endsWith("x".repeat(echoLimit + 1))).toBe(false);
472
+ expect(error.message).toContain(OVERSIZED_RESPONSE_BODY);
473
+ expect(error.message.endsWith(OVERSIZED_RESPONSE_BODY)).toBe(true);
471
474
 
472
475
  // ...and ahead of it, a non-empty prefix naming the HTTP status.
473
476
  const prefix: string = error.message.slice(
474
477
  0,
475
- error.message.length - echoLimit,
478
+ error.message.length - OVERSIZED_RESPONSE_BODY_LENGTH,
476
479
  );
477
480
  expect(prefix.length).toBeGreaterThan(0);
478
481
  expect(prefix).toContain("HTTP");
479
482
  }
480
483
  });
481
484
 
485
+ test("the message width tracks the body width — nothing bounds it but the body itself", async () => {
486
+ /*
487
+ * Falsifies the test above from the other side. Hand the same failure
488
+ * path a body twice as wide and the message grows by exactly the extra
489
+ * characters: no cap, no ceiling, no rounding. Any truncation
490
+ * anywhere on this path — in the client, in the redactor, in the
491
+ * exception — would make the two messages converge instead.
492
+ */
493
+ const narrow: Error = await thrownClientError([
494
+ successfulTokenResponse(),
495
+ { status: 500, body: OVERSIZED_RESPONSE_BODY },
496
+ ]);
497
+ const wide: Error = await thrownClientError([
498
+ successfulTokenResponse(),
499
+ { status: 500, body: OVERSIZED_RESPONSE_BODY + OVERSIZED_RESPONSE_BODY },
500
+ ]);
501
+
502
+ expect(wide.message.length - narrow.message.length).toBe(
503
+ OVERSIZED_RESPONSE_BODY_LENGTH,
504
+ );
505
+ });
506
+
482
507
  test("the widest client error overflows the bound lastError used to carry", () => {
483
508
  /*
484
509
  * This is the string that killed the poller. Prefix + echoed body is
485
510
  * larger than varchar(500), so writing it back onto the row raised
486
- * BadDataException from inside the catch block.
511
+ * BadDataException from inside the catch block. It is also past the
512
+ * connector clamp, which is exactly why the poller opts out of that
513
+ * clamp and why the column has to be unbounded rather than merely
514
+ * wider.
487
515
  */
488
516
  const oldMaxLength: number = getMaxLengthFromTableColumnType(
489
517
  TableColumnType.LongText,
@@ -491,31 +519,64 @@ describe("the widest error the producers can emit is storable", () => {
491
519
 
492
520
  expect(widestClientError.message.length).toBeGreaterThan(oldMaxLength);
493
521
 
494
- // The overflow is not marginal: the echoed body alone fills the old column.
495
- expect(responseBodyEchoLimit()).toBe(oldMaxLength);
522
+ // The overflow is not marginal: the echoed body alone dwarfs the old column.
523
+ expect(OVERSIZED_RESPONSE_BODY_LENGTH).toBeGreaterThan(oldMaxLength);
524
+ expect(widestClientError.message.length).toBeGreaterThan(
525
+ MAX_CONNECTOR_ERROR_MESSAGE_LENGTH,
526
+ );
496
527
  });
497
528
 
498
- test("toMessage keeps the widest client error intact and under the connector cap", () => {
499
- const stored: string = ConnectorErrorMessage.toMessage(widestClientError);
529
+ test("the poller's { truncate: false } stores the widest client error whole", () => {
530
+ /*
531
+ * GoogleSecOpsPoller writes ConnectorErrorMessage.toMessage(error,
532
+ * { truncate: false }). The operator is meant to get the complete
533
+ * redacted diagnostic, so the returned value must be the message
534
+ * unchanged — no clamp, and specifically no "... (truncated)" marker,
535
+ * whose presence would mean part of the diagnostic was thrown away.
536
+ */
537
+ const stored: string = ConnectorErrorMessage.toMessage(widestClientError, {
538
+ truncate: false,
539
+ });
500
540
 
501
- // Prefix + 500 still fits in 1000, so nothing is lost from an API error.
502
541
  expect(stored).toBe(widestClientError.message);
503
- expect(stored.length).toBeLessThanOrEqual(
504
- MAX_CONNECTOR_ERROR_MESSAGE_LENGTH,
505
- );
542
+ expect(stored).not.toContain("... (truncated)");
543
+ expect(stored.length).toBeGreaterThan(MAX_CONNECTOR_ERROR_MESSAGE_LENGTH);
544
+ });
545
+
546
+ test("the DEFAULT toMessage still clamps, so the cap stays pinned for callers that use it", () => {
547
+ /*
548
+ * Opting out is per call site. Every caller that does NOT pass
549
+ * { truncate: false } must still be clamped to
550
+ * MAX_CONNECTOR_ERROR_MESSAGE_LENGTH with the marker, or a narrow
551
+ * destination somewhere else in the codebase silently starts
552
+ * overflowing.
553
+ */
554
+ for (const error of [
555
+ tokenExchangeError,
556
+ alertsFetchError,
557
+ new Error("y".repeat(MAX_CONNECTOR_ERROR_MESSAGE_LENGTH * 10)),
558
+ ]) {
559
+ const clamped: string = ConnectorErrorMessage.toMessage(error);
560
+
561
+ expect(clamped.length).toBe(MAX_CONNECTOR_ERROR_MESSAGE_LENGTH);
562
+ expect(clamped.endsWith("... (truncated)")).toBe(true);
563
+ }
506
564
  });
507
565
 
508
566
  test.each(LAST_ERROR_COLUMNS)(
509
- "$label accepts the widest client error — the real length check does not reject it",
567
+ "$label accepts the widest client error stored WHOLE — the real length check does not reject it",
510
568
  (column: LastErrorColumn) => {
511
569
  /*
512
- * The end-to-end guard: the same value the poller would store, run
513
- * through the same DatabaseService validation that used to throw.
514
- * Pre-fix (LongText/varchar(500)) this raised BadDataException, the
515
- * throw escaped pollAllDueConnections, and the tick died.
570
+ * The end-to-end guard: the same value the poller would store
571
+ * untruncated and redacted, exactly as GoogleSecOpsPoller builds it
572
+ * run through the same DatabaseService validation that used to
573
+ * throw. Pre-fix (LongText/varchar(500)) this raised
574
+ * BadDataException, the throw escaped pollAllDueConnections, and the
575
+ * tick died.
516
576
  */
517
- const stored: string = ConnectorErrorMessage.toMessage(widestClientError);
577
+ const stored: string = storedLastError(widestClientError);
518
578
 
579
+ expect(stored.length).toBeGreaterThan(MAX_CONNECTOR_ERROR_MESSAGE_LENGTH);
519
580
  expect(() => {
520
581
  return column.checkLastError(stored);
521
582
  }).not.toThrow();
@@ -531,7 +592,7 @@ describe("the widest error the producers can emit is storable", () => {
531
592
  * LongText and it throws exactly as lastError used to. The only
532
593
  * thing that changed is the declared column type.
533
594
  */
534
- const stored: string = ConnectorErrorMessage.toMessage(widestClientError);
595
+ const stored: string = storedLastError(widestClientError);
535
596
 
536
597
  expect(
537
598
  getMaxLengthFromTableColumnType(
@@ -551,9 +612,10 @@ describe("the widest error the producers can emit is storable", () => {
551
612
  (column: LastErrorColumn) => {
552
613
  /*
553
614
  * The evaluator's side: a ClickHouse error echoes the whole
554
- * compiled query, so it has no natural bound. toMessage clamps it
555
- * to exactly MAX_CONNECTOR_ERROR_MESSAGE_LENGTH still double the
556
- * old varchar(500), so widening the column is what makes even the
615
+ * compiled query, so it has no natural bound. That caller keeps the
616
+ * default clamp, which cuts it to exactly
617
+ * MAX_CONNECTOR_ERROR_MESSAGE_LENGTH still double the old
618
+ * varchar(500), so widening the column is what makes even the
557
619
  * clamped value storable.
558
620
  */
559
621
  const clickhouseError: Error = new Error(
@@ -573,23 +635,6 @@ describe("the widest error the producers can emit is storable", () => {
573
635
  }).not.toThrow();
574
636
  },
575
637
  );
576
-
577
- test("the connector cap is the ceiling on anything that reaches these columns", () => {
578
- /*
579
- * Ties the clamp to the column: whatever the producers throw, what is
580
- * actually written is at most MAX_CONNECTOR_ERROR_MESSAGE_LENGTH, and
581
- * a text column has no bound to compare that against.
582
- */
583
- for (const error of [
584
- tokenExchangeError,
585
- alertsFetchError,
586
- new Error("y".repeat(MAX_CONNECTOR_ERROR_MESSAGE_LENGTH * 10)),
587
- ]) {
588
- expect(ConnectorErrorMessage.toMessage(error).length).toBeLessThanOrEqual(
589
- MAX_CONNECTOR_ERROR_MESSAGE_LENGTH,
590
- );
591
- }
592
- });
593
638
  });
594
639
 
595
640
  interface InBandFailure {
@@ -598,33 +643,44 @@ interface InBandFailure {
598
643
  body: string;
599
644
  /* Everything the client's message carries ahead of the echoed text. */
600
645
  prefix: string;
646
+ /*
647
+ * Whether this path echoes the body it could not read. An empty body has
648
+ * nothing to echo, and a body that is not JSON at all is reported by
649
+ * kind rather than quoted — so those two are prefix-only, and pinning
650
+ * that distinction is what stops a future change from quietly turning a
651
+ * fixed string into an unbounded echo without a test noticing.
652
+ */
653
+ echoesBody: boolean;
601
654
  }
602
655
 
603
656
  /*
604
657
  * The failures Chronicle reports on an HTTP 200. They are not covered by the
605
- * two templates above because before the client learned to read the stream
658
+ * two HTTP paths above because before the client learned to read the stream
606
659
  * envelope they did not reach lastError at all — an unreadable body was
607
660
  * reported as a healthy poll that found nothing. Each of them now echoes the
608
- * text it could not read, which is a new way for the stored value to grow,
609
- * so each has to clear the same end-to-end path: the client's own cap, the
610
- * connector clamp, and the real length check on both columns.
661
+ * text it could not read, in full, which is a new way for the stored value
662
+ * to grow, so each has to clear the same end-to-end path: the poller's
663
+ * untruncated toMessage and the real length check on both columns.
611
664
  */
612
665
  const IN_BAND_FAILURES: Array<InBandFailure> = [
613
666
  {
614
667
  label: "an empty body",
615
668
  body: "",
616
669
  prefix: "Google SecOps alerts fetch returned an empty body.",
670
+ echoesBody: false,
617
671
  },
618
672
  {
619
673
  label: "a body that is not JSON",
620
674
  body: `<html>${OVERSIZED_RESPONSE_BODY}</html>`,
621
675
  prefix: "Google SecOps alerts fetch returned a non-JSON body.",
676
+ echoesBody: false,
622
677
  },
623
678
  {
624
679
  label: "a shape the parser does not recognize",
625
680
  body: JSON.stringify([{ somethingElseEntirely: OVERSIZED_RESPONSE_BODY }]),
626
681
  prefix:
627
682
  "Google SecOps alerts fetch returned an unrecognized response shape: ",
683
+ echoesBody: true,
628
684
  },
629
685
  {
630
686
  label: "a query Chronicle rejected in band",
@@ -636,12 +692,13 @@ const IN_BAND_FAILURES: Array<InBandFailure> = [
636
692
  ]),
637
693
  prefix:
638
694
  "Google SecOps alerts query was rejected by Chronicle on an HTTP 200: ",
695
+ echoesBody: true,
639
696
  },
640
697
  ];
641
698
 
642
699
  describe("the failures Chronicle reports on an HTTP 200 are storable too", () => {
643
700
  test.each(IN_BAND_FAILURES)(
644
- "$label is echoed under the client's own cap and stored whole",
701
+ "$label is echoed in full and stored whole",
645
702
  async (failure: InBandFailure) => {
646
703
  const error: Error = await thrownClientError([
647
704
  successfulTokenResponse(),
@@ -650,23 +707,154 @@ describe("the failures Chronicle reports on an HTTP 200 are storable too", () =>
650
707
 
651
708
  expect(error.message.startsWith(failure.prefix)).toBe(true);
652
709
 
710
+ if (failure.echoesBody) {
711
+ /*
712
+ * The echo is complete, not clipped — same contract as the HTTP
713
+ * paths, and the same reason the column has to be unbounded: this
714
+ * message is already past MAX_CONNECTOR_ERROR_MESSAGE_LENGTH.
715
+ */
716
+ expect(error.message).toContain(OVERSIZED_RESPONSE_BODY);
717
+ expect(error.message.length).toBeGreaterThan(
718
+ MAX_CONNECTOR_ERROR_MESSAGE_LENGTH,
719
+ );
720
+ } else {
721
+ // Reported by kind, so the body never widens the stored value at all.
722
+ expect(error.message).toBe(failure.prefix);
723
+ }
724
+
653
725
  /*
654
- * Prefix plus at most one full-width echo the same shape as the
655
- * HTTP templates, so nothing here is wider than the case the column
656
- * was widened for.
726
+ * The poller opts out of the clamp, so lastError carries the whole
727
+ * thing however wide it is.
657
728
  */
658
- expect(error.message.length).toBeLessThanOrEqual(
659
- failure.prefix.length + responseBodyEchoLimit(),
660
- );
661
-
662
- // The clamp leaves it untouched, so lastError carries the whole thing.
663
- const stored: string = ConnectorErrorMessage.toMessage(error);
729
+ const stored: string = ConnectorErrorMessage.toMessage(error, {
730
+ truncate: false,
731
+ });
664
732
 
665
733
  expect(stored).toBe(error.message);
666
- expect(stored.length).toBeLessThanOrEqual(
667
- MAX_CONNECTOR_ERROR_MESSAGE_LENGTH,
668
- );
734
+ expect(stored).not.toContain("... (truncated)");
735
+
736
+ for (const column of LAST_ERROR_COLUMNS) {
737
+ expect(() => {
738
+ return column.checkLastError(storedLastError(error));
739
+ }).not.toThrow();
740
+ }
741
+ },
742
+ );
743
+ });
744
+
745
+ /*
746
+ * Redaction is what makes echoing a customer-supplied body safe now that
747
+ * nothing clips it. The body is attacker-influenced (a token endpoint that
748
+ * mirrors the request, a proxy that dumps headers) and, worse, routinely
749
+ * carries the tenant's OWN credentials back — and lastError is rendered in
750
+ * the dashboard and swept up by support bundles. So the property that used
751
+ * to be "at most 500 characters reach the column" is now "no credential
752
+ * reaches the column at all", and it has to hold on every path that echoes.
753
+ */
754
+ interface RedactedEchoCase {
755
+ label: string;
756
+ responses: Array<{ status: number; body: string }>;
757
+ }
758
+
759
+ const REDACTED_ECHO_CASES: Array<RedactedEchoCase> = [
760
+ {
761
+ label: "the token exchange echoing credential fields",
762
+ responses: [{ status: 400, body: FLAT_CREDENTIAL_BODY }],
763
+ },
764
+ {
765
+ label: "the token exchange echoing credentials nested inside a message",
766
+ responses: [{ status: 400, body: NESTED_CREDENTIAL_BODY }],
767
+ },
768
+ {
769
+ label: "the alerts fetch echoing credential fields",
770
+ responses: [
771
+ successfulTokenResponse(),
772
+ { status: 403, body: FLAT_CREDENTIAL_BODY },
773
+ ],
774
+ },
775
+ {
776
+ label: "the alerts fetch echoing credentials nested inside a message",
777
+ responses: [
778
+ successfulTokenResponse(),
779
+ { status: 403, body: NESTED_CREDENTIAL_BODY },
780
+ ],
781
+ },
782
+ {
783
+ label: "an unrecognized HTTP 200 shape echoing credential fields",
784
+ responses: [
785
+ successfulTokenResponse(),
786
+ {
787
+ status: 200,
788
+ body: JSON.stringify({
789
+ client_secret: LEAKED_CLIENT_SECRET,
790
+ access_token: LEAKED_ACCESS_TOKEN,
791
+ private_key: LEAKED_PRIVATE_KEY_PEM,
792
+ }),
793
+ },
794
+ ],
795
+ },
796
+ {
797
+ label: "an in-band query rejection echoing credentials nested in a message",
798
+ responses: [
799
+ successfulTokenResponse(),
800
+ {
801
+ status: 200,
802
+ body: JSON.stringify([
803
+ {
804
+ validSnapshotQuery: false,
805
+ queryValidationErrors: [
806
+ {
807
+ message: JSON.stringify({
808
+ client_secret: LEAKED_CLIENT_SECRET,
809
+ access_token: LEAKED_ACCESS_TOKEN,
810
+ private_key: LEAKED_PRIVATE_KEY_PEM,
811
+ }),
812
+ },
813
+ ],
814
+ },
815
+ ]),
816
+ },
817
+ ],
818
+ },
819
+ ];
820
+
821
+ describe("the echoed body is redacted, which is what replaced the cap", () => {
822
+ test("a purely textual pass really is fooled by nested credential JSON", () => {
823
+ /*
824
+ * The premise behind redactErrorBody decoding the outer JSON first
825
+ * (commit c0f9e0c2db). Inside a JSON string the credential's key quotes
826
+ * arrive escaped as \" , which no textual rule keyed on `"key":` can
827
+ * match — so running redactLogString over the raw body leaves the
828
+ * secret in the clear. If this ever stops being true the decode step
829
+ * has become redundant, and the case below stops proving anything.
830
+ */
831
+ expect(redactLogString(NESTED_CREDENTIAL_BODY)).toContain(
832
+ LEAKED_CLIENT_SECRET,
833
+ );
834
+ });
835
+
836
+ test.each(REDACTED_ECHO_CASES)(
837
+ "$label never puts the credential in lastError",
838
+ async (echoCase: RedactedEchoCase) => {
839
+ const error: Error = await thrownClientError(echoCase.responses);
840
+ const stored: string = storedLastError(error);
841
+
842
+ for (const secret of LEAKED_SECRETS) {
843
+ expect(error.message).not.toContain(secret);
844
+ expect(stored).not.toContain(secret);
845
+ }
846
+
847
+ /*
848
+ * Falsifiable: the body really did reach the message, and the reason
849
+ * the secret is missing from it is that the redactor replaced the
850
+ * value — not that the client quietly dropped the whole echo, which
851
+ * would satisfy "does not contain" while destroying the diagnostic
852
+ * this column exists to carry.
853
+ */
854
+ expect(error.message).toContain(REDACTED);
855
+ expect(stored).toContain(REDACTED);
669
856
 
857
+ // And the redacted echo is still stored whole, on an unbounded column.
670
858
  for (const column of LAST_ERROR_COLUMNS) {
671
859
  expect(() => {
672
860
  return column.checkLastError(stored);