@oneuptime/common 14.0.10 → 14.0.11

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 (837) hide show
  1. package/Models/DatabaseModels/AIConversation.ts +127 -1
  2. package/Models/DatabaseModels/CephCluster.ts +12 -0
  3. package/Models/DatabaseModels/CloudResource.ts +12 -0
  4. package/Models/DatabaseModels/DatabaseServer.ts +12 -0
  5. package/Models/DatabaseModels/DockerHost.ts +12 -0
  6. package/Models/DatabaseModels/DockerSwarmCluster.ts +12 -0
  7. package/Models/DatabaseModels/GlobalOidc.ts +0 -4
  8. package/Models/DatabaseModels/GlobalOidcProject.ts +0 -4
  9. package/Models/DatabaseModels/GlobalSso.ts +0 -4
  10. package/Models/DatabaseModels/GlobalSsoProject.ts +0 -4
  11. package/Models/DatabaseModels/Host.ts +12 -0
  12. package/Models/DatabaseModels/IncidentForm.ts +594 -0
  13. package/Models/DatabaseModels/IncidentFormSubmission.ts +283 -0
  14. package/Models/DatabaseModels/IncidentTemplate.ts +59 -0
  15. package/Models/DatabaseModels/Index.ts +14 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +12 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +12 -0
  18. package/Models/DatabaseModels/MessageQueue.ts +1102 -0
  19. package/Models/DatabaseModels/MessageQueueLabelRule.ts +553 -0
  20. package/Models/DatabaseModels/MessageQueueOwnerRule.ts +633 -0
  21. package/Models/DatabaseModels/MessageQueueOwnerTeam.ts +491 -0
  22. package/Models/DatabaseModels/MessageQueueOwnerUser.ts +490 -0
  23. package/Models/DatabaseModels/PodmanHost.ts +12 -0
  24. package/Models/DatabaseModels/Project.ts +59 -0
  25. package/Models/DatabaseModels/ProjectOidc.ts +0 -4
  26. package/Models/DatabaseModels/ProjectSso.ts +0 -4
  27. package/Models/DatabaseModels/ProxmoxCluster.ts +12 -0
  28. package/Models/DatabaseModels/RumApplication.ts +12 -0
  29. package/Models/DatabaseModels/ServerlessFunction.ts +12 -0
  30. package/Models/DatabaseModels/Service.ts +12 -0
  31. package/Models/DatabaseModels/StatusPageOidc.ts +0 -4
  32. package/Models/DatabaseModels/StatusPageSso.ts +0 -4
  33. package/Models/DatabaseModels/TeamComplianceSetting.ts +47 -2
  34. package/Models/DatabaseModels/VMwareVCenter.ts +12 -0
  35. package/Server/API/AIChatAPI.ts +13 -114
  36. package/Server/API/AIInvestigationAPI.ts +3 -3
  37. package/Server/API/AIInvestigationConversationAPI.ts +266 -0
  38. package/Server/API/IncidentFormAPI.ts +376 -0
  39. package/Server/API/ProjectOIDC.ts +16 -25
  40. package/Server/API/ProjectSSO.ts +16 -24
  41. package/Server/API/StatusPageAPI.ts +42 -77
  42. package/Server/Enterprise/EnterpriseEdition.ts +93 -28
  43. package/Server/Enterprise/EnterpriseFeature.ts +25 -3
  44. package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +1 -1
  45. package/Server/Enterprise/EnterpriseServerModule.ts +4 -1
  46. package/Server/EnvironmentConfig.ts +1 -1
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.ts +129 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.ts +52 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.ts +75 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.ts +477 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  52. package/Server/Middleware/IncidentFormRateLimit.ts +847 -0
  53. package/Server/Middleware/UserAuthorization.ts +16 -38
  54. package/Server/Services/AIService.ts +10 -13
  55. package/Server/Services/IncidentCustomFieldService.ts +112 -2
  56. package/Server/Services/IncidentEpisodeMemberService.ts +24 -4
  57. package/Server/Services/IncidentEpisodeService.ts +10 -1
  58. package/Server/Services/IncidentFormService.ts +1566 -0
  59. package/Server/Services/IncidentFormSubmissionService.ts +97 -0
  60. package/Server/Services/IncidentGroupingEngineService.ts +45 -8
  61. package/Server/Services/IncidentService.ts +123 -5
  62. package/Server/Services/IncidentTemplateService.ts +22 -0
  63. package/Server/Services/Index.ts +14 -0
  64. package/Server/Services/MessageQueueLabelRuleEngineService.ts +321 -0
  65. package/Server/Services/MessageQueueLabelRuleService.ts +14 -0
  66. package/Server/Services/MessageQueueOwnerRuleEngineService.ts +412 -0
  67. package/Server/Services/MessageQueueOwnerRuleService.ts +14 -0
  68. package/Server/Services/MessageQueueOwnerTeamService.ts +62 -0
  69. package/Server/Services/MessageQueueOwnerUserService.ts +62 -0
  70. package/Server/Services/MessageQueueService.ts +1463 -0
  71. package/Server/Services/OpenTelemetryIngestService.ts +37 -4
  72. package/Server/Services/ProjectService.ts +0 -59
  73. package/Server/Services/StatusPagePrivateUserService.ts +1 -4
  74. package/Server/Services/StatusPageService.ts +1 -51
  75. package/Server/Services/TeamComplianceSettingService.ts +163 -42
  76. package/Server/Services/UserNotificationRuleService.ts +8 -1
  77. package/Server/Services/WorkspaceNotificationSummaryService.ts +12 -3
  78. package/Server/Types/Database/Permissions/CreatePermission.ts +17 -3
  79. package/Server/Types/Database/Permissions/EditionPermission.ts +140 -38
  80. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +16 -0
  81. package/Server/Types/Database/Permissions/TablePermission.ts +3 -3
  82. package/Server/Types/Database/Permissions/UpdatePermission.ts +20 -6
  83. package/Server/Utils/AI/Chat/AgentContextCompactor.ts +200 -0
  84. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +307 -48
  85. package/Server/Utils/AI/Chat/ChatRunCancellation.ts +156 -0
  86. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +78 -18
  87. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  88. package/Server/Utils/AI/Chat/ToolOutputPager.ts +322 -0
  89. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +88 -30
  90. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +13 -1
  91. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +0 -32
  92. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +27 -25
  93. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +7 -1
  94. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +34 -14
  95. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +69 -24
  96. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +9 -0
  97. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +53 -10
  98. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +27 -10
  99. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +27 -10
  100. package/Server/Utils/AI/SRE/InvestigationQueue.ts +16 -19
  101. package/Server/Utils/AI/SRE/InvestigationThread.ts +646 -0
  102. package/Server/Utils/AI/SRE/InvestigationThreadService.ts +715 -0
  103. package/Server/Utils/AI/Toolbox/Serializer.ts +10 -3
  104. package/Server/Utils/EditionEnforcement.ts +19 -202
  105. package/Server/Utils/LLM/LLMService.ts +259 -63
  106. package/Server/Utils/RelaxedScimTeamLocksReport.ts +245 -0
  107. package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +25 -0
  108. package/Server/Utils/SameOriginRequest.ts +203 -0
  109. package/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.ts +2 -0
  110. package/Server/Utils/Telemetry/EntityRegistry.ts +4 -1
  111. package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +1402 -0
  112. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +4 -1
  113. package/Server/Utils/VendorAssets.ts +3 -3
  114. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +3 -1
  115. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +3 -1
  116. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +10 -1
  117. package/Tests/App/Accounts/IncidentFormPage.test.tsx +2036 -0
  118. package/Tests/App/Accounts/IncidentFormServerMessages.test.ts +119 -0
  119. package/Tests/App/Accounts/IncidentFormUtils.test.ts +1157 -0
  120. package/Tests/App/Accounts/LoginPasskey.test.tsx +6 -4
  121. package/Tests/App/Accounts/LoginSso.test.tsx +724 -0
  122. package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +338 -0
  123. package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +331 -0
  124. package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +47 -33
  125. package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +1021 -0
  126. package/Tests/App/Dashboard/AffectedResourcesDisplay.test.tsx +876 -78
  127. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +20 -3
  128. package/Tests/App/Dashboard/CephProxmoxVMwareDocumentationCards.test.tsx +359 -0
  129. package/Tests/App/Dashboard/CephSetupGuide.test.ts +961 -0
  130. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +381 -95
  131. package/Tests/App/Dashboard/CloudSetupGuide.test.ts +1463 -0
  132. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +174 -12
  133. package/Tests/App/Dashboard/ContainerSetupGuideCards.test.tsx +345 -0
  134. package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +501 -0
  135. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -1
  136. package/Tests/App/Dashboard/DatabaseDocumentationCard.test.tsx +400 -0
  137. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +5 -0
  138. package/Tests/App/Dashboard/DatabaseSetupGuide.test.ts +1869 -0
  139. package/Tests/App/Dashboard/DatabaseTelemetryScope.test.ts +44 -0
  140. package/Tests/App/Dashboard/DatabaseTelemetryTabs.test.tsx +50 -9
  141. package/Tests/App/Dashboard/DockerSetupGuide.test.ts +899 -0
  142. package/Tests/App/Dashboard/DockerSwarmSetupGuide.test.ts +964 -0
  143. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +141 -7
  144. package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +52 -39
  145. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +7 -1
  146. package/Tests/App/Dashboard/GettingStartedTaskRoutes.test.tsx +331 -0
  147. package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +925 -0
  148. package/Tests/App/Dashboard/HostDocumentationCard.test.tsx +225 -0
  149. package/Tests/App/Dashboard/HostSetupGuide.test.ts +1183 -0
  150. package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +69 -45
  151. package/Tests/App/Dashboard/IncidentCreateTemplateCustomFieldSettings.test.tsx +745 -0
  152. package/Tests/App/Dashboard/IncidentCreateTemplateOwners.test.tsx +414 -0
  153. package/Tests/App/Dashboard/IncidentCustomFieldCreateSettingsForm.test.ts +1042 -0
  154. package/Tests/App/Dashboard/IncidentCustomFieldSettingsCard.test.tsx +1816 -0
  155. package/Tests/App/Dashboard/IncidentFormPlan.test.ts +89 -0
  156. package/Tests/App/Dashboard/IncidentFormShareLinkCard.test.tsx +846 -0
  157. package/Tests/App/Dashboard/IncidentFormsPages.test.tsx +1324 -0
  158. package/Tests/App/Dashboard/IncidentTemplateCustomFieldSettings.test.tsx +630 -0
  159. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +13 -0
  160. package/Tests/App/Dashboard/IncomingEmailMonitorLinkVerifyHint.test.tsx +104 -0
  161. package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1107 -0
  162. package/Tests/App/Dashboard/InvestigationConversationData.test.ts +546 -0
  163. package/Tests/App/Dashboard/InvestigationEvidenceList.test.tsx +170 -5
  164. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +207 -2
  165. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +729 -34
  166. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +9 -21
  167. package/Tests/App/Dashboard/InvestigationReportView.test.tsx +274 -37
  168. package/Tests/App/Dashboard/InvestigationStatusBadge.test.tsx +130 -0
  169. package/Tests/App/Dashboard/IoTDocumentationCard.test.tsx +218 -0
  170. package/Tests/App/Dashboard/IoTSetupGuide.test.ts +1124 -0
  171. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +20 -6
  172. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +107 -83
  173. package/Tests/App/Dashboard/KubernetesSetupGuide.test.ts +787 -0
  174. package/Tests/App/Dashboard/MessageQueueBreadcrumbs.test.tsx +228 -0
  175. package/Tests/App/Dashboard/MessageQueueBrokerHealth.test.tsx +1538 -0
  176. package/Tests/App/Dashboard/MessageQueueBrokerHealthMetricChart.test.tsx +969 -0
  177. package/Tests/App/Dashboard/MessageQueueBrokerHealthReads.test.ts +889 -0
  178. package/Tests/App/Dashboard/MessageQueueBrokerMetricsReach.test.ts +236 -0
  179. package/Tests/App/Dashboard/MessageQueueDocumentationCard.test.tsx +479 -0
  180. package/Tests/App/Dashboard/MessageQueueListPages.test.tsx +1232 -0
  181. package/Tests/App/Dashboard/MessageQueueMetricDescriptions.test.ts +244 -0
  182. package/Tests/App/Dashboard/MessageQueueMonitorLink.test.ts +952 -0
  183. package/Tests/App/Dashboard/MessageQueueMonitorLinkMonitorCreate.test.tsx +859 -0
  184. package/Tests/App/Dashboard/MessageQueueOverview.test.tsx +1773 -0
  185. package/Tests/App/Dashboard/MessageQueueOverviewPresentation.test.ts +196 -0
  186. package/Tests/App/Dashboard/MessageQueuePresentation.test.ts +799 -0
  187. package/Tests/App/Dashboard/MessageQueueProducersConsumers.test.tsx +680 -0
  188. package/Tests/App/Dashboard/MessageQueueRoutes.test.tsx +383 -0
  189. package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +278 -0
  190. package/Tests/App/Dashboard/MessageQueueSetupGuide.test.ts +2778 -0
  191. package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +273 -0
  192. package/Tests/App/Dashboard/MessageQueueSpanPopulations.test.ts +930 -0
  193. package/Tests/App/Dashboard/MessageQueueSpanStore.ts +351 -0
  194. package/Tests/App/Dashboard/MessageQueueTelemetryScope.test.ts +375 -0
  195. package/Tests/App/Dashboard/MessageQueueTelemetryScopeTabs.test.tsx +668 -0
  196. package/Tests/App/Dashboard/MessageQueueViewPages.test.tsx +685 -0
  197. package/Tests/App/Dashboard/MonitorAndHomeNotOperationalMenus.test.tsx +342 -0
  198. package/Tests/App/Dashboard/MonitorCreateFirstRunDefaults.test.tsx +623 -0
  199. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +442 -0
  200. package/Tests/App/Dashboard/MonitorLogsPageViewSummary.test.tsx +814 -0
  201. package/Tests/App/Dashboard/MonitorSetupCardBodies.test.tsx +246 -0
  202. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +8 -0
  203. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +27 -12
  204. package/Tests/App/Dashboard/PlanGatedPage.test.tsx +292 -0
  205. package/Tests/App/Dashboard/PodmanSetupGuide.test.ts +948 -0
  206. package/Tests/App/Dashboard/ProductOrientation.test.tsx +5 -4
  207. package/Tests/App/Dashboard/ProductSettingsSectionCollapsed.test.tsx +266 -0
  208. package/Tests/App/Dashboard/ProxmoxSetupGuide.test.ts +1318 -0
  209. package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +555 -0
  210. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +298 -9
  211. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +453 -0
  212. package/Tests/App/Dashboard/ResourceArchiveSettings.test.tsx +16 -0
  213. package/Tests/App/Dashboard/ResourceConnectionGuideCard.test.tsx +444 -0
  214. package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsInfra.test.tsx +798 -0
  215. package/Tests/App/Dashboard/ResourceConnectionGuideOverviewsPlatforms.test.tsx +717 -0
  216. package/Tests/App/Dashboard/ResourceConnectionGuides.test.ts +981 -0
  217. package/Tests/App/Dashboard/ResourceConnectionState.test.ts +132 -0
  218. package/Tests/App/Dashboard/RumDocumentationCard.test.tsx +293 -0
  219. package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +467 -0
  220. package/Tests/App/Dashboard/RumSetupGuide.test.ts +758 -0
  221. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +25 -0
  222. package/Tests/App/Dashboard/ServerlessDocumentationCard.test.tsx +254 -0
  223. package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1074 -0
  224. package/Tests/App/Dashboard/SetupGuide.test.ts +246 -0
  225. package/Tests/App/Dashboard/SetupGuideCard.test.tsx +756 -0
  226. package/Tests/App/Dashboard/SloListSideMenu.test.tsx +120 -0
  227. package/Tests/App/Dashboard/SsoPages.test.tsx +833 -0
  228. package/Tests/App/Dashboard/TelemetryDocumentation.test.tsx +253 -0
  229. package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +730 -0
  230. package/Tests/App/Dashboard/VMwareSetupGuide.test.ts +1033 -0
  231. package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +87 -7
  232. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +28 -9
  233. package/Tests/Models/DatabaseModels/IncidentFormModel.test.ts +1250 -0
  234. package/Tests/Models/DatabaseModels/MessageQueueModels.test.ts +1983 -0
  235. package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
  236. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +190 -14
  237. package/Tests/Models/IncidentTemplateCustomFieldSettingsColumn.test.ts +291 -0
  238. package/Tests/Server/API/AIInvestigationConversationAPI.test.ts +412 -0
  239. package/Tests/Server/API/GlobalConfigLicense.test.ts +38 -9
  240. package/Tests/Server/API/IncidentFormAPI.test.ts +942 -0
  241. package/Tests/Server/API/IncidentFormPublicRoutes.test.ts +1653 -0
  242. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -1
  243. package/Tests/Server/API/{SsoProviderListingsEdition.test.ts → SsoProviderListings.test.ts} +164 -110
  244. package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +76 -54
  245. package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +125 -42
  246. package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +36 -10
  247. package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +51 -9
  248. package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +13 -8
  249. package/Tests/Server/Enterprise/SsoInCommunityEdition.test.ts +540 -0
  250. package/Tests/Server/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
  251. package/Tests/Server/Infrastructure/Postgres/AddIncidentFormsMigration.test.ts +438 -0
  252. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleNotificationChannelsMigration.test.ts +255 -0
  253. package/Tests/Server/Infrastructure/Postgres/MessageQueueTablesMigration.test.ts +637 -0
  254. package/Tests/Server/Middleware/IncidentFormRateLimit.test.ts +1630 -0
  255. package/Tests/Server/Middleware/UserAuthorization.test.ts +16 -17
  256. package/Tests/Server/Middleware/UserAuthorizationSsoEnforcement.test.ts +544 -0
  257. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +37 -8
  258. package/Tests/Server/Services/IncidentCreatedFeedTitle.test.ts +212 -0
  259. package/Tests/Server/Services/IncidentCustomFieldDeleteFormQuestions.test.ts +297 -0
  260. package/Tests/Server/Services/IncidentFormOwnersCreatedNotification.test.ts +497 -0
  261. package/Tests/Server/Services/IncidentFormPostgres.test.ts +958 -0
  262. package/Tests/Server/Services/IncidentFormPublicForm.test.ts +1260 -0
  263. package/Tests/Server/Services/IncidentFormPublicSubmission.test.ts +2520 -0
  264. package/Tests/Server/Services/IncidentFormRegistration.test.ts +159 -0
  265. package/Tests/Server/Services/IncidentFormService.test.ts +663 -0
  266. package/Tests/Server/Services/IncidentFormSubmissionService.test.ts +430 -0
  267. package/Tests/Server/Services/IncidentFormSubmissionTemplateBranch.test.ts +473 -0
  268. package/Tests/Server/Services/IncidentGroupingTemplateSubstitution.test.ts +81 -0
  269. package/Tests/Server/Services/IncidentTemplateCustomFieldSettings.test.ts +262 -0
  270. package/Tests/Server/Services/IncidentTemplateOwnersOnDeclare.test.ts +566 -0
  271. package/Tests/Server/Services/IncidentTitleMarkdownSinks.test.ts +640 -0
  272. package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +3 -3
  273. package/Tests/Server/Services/MessageQueueOwnerServices.test.ts +440 -0
  274. package/Tests/Server/Services/MessageQueueRegistries.test.ts +577 -0
  275. package/Tests/Server/Services/MessageQueueRuleEngines.test.ts +900 -0
  276. package/Tests/Server/Services/MessageQueueService.test.ts +2210 -0
  277. package/Tests/Server/Services/MessageQueueSqlPostgres.test.ts +1271 -0
  278. package/Tests/Server/Services/OpenTelemetryResourceRetentionMemo.test.ts +28 -1
  279. package/Tests/Server/Services/OpenTelemetryRetentionOverrideEdition.test.ts +474 -0
  280. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +21 -0
  281. package/Tests/Server/Services/OwnerRowUniqueness.test.ts +3 -0
  282. package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +0 -1
  283. package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +56 -6
  284. package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -1
  285. package/Tests/Server/Services/SsoRequirementReads.test.ts +454 -0
  286. package/Tests/Server/Services/SsoRequirementWrites.test.ts +529 -0
  287. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +3 -3
  288. package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +107 -89
  289. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +1068 -176
  290. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +1962 -200
  291. package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +654 -297
  292. package/Tests/Server/Types/Database/Permissions/RetentionOverrideColumns.test.ts +784 -0
  293. package/Tests/Server/Types/Database/Permissions/SsoScalePlanGate.test.ts +418 -0
  294. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +0 -1
  295. package/Tests/Server/Utils/AI/AIInvestigationEngineRunLimits.test.ts +136 -0
  296. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +15 -14
  297. package/Tests/Server/Utils/AI/AgentContextCompactor.test.ts +351 -0
  298. package/Tests/Server/Utils/AI/ChatAgentRunnerSharedThread.test.ts +842 -0
  299. package/Tests/Server/Utils/AI/ChatRunCancellation.test.ts +195 -0
  300. package/Tests/Server/Utils/AI/CodeFixReadiness.test.ts +10 -57
  301. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +20 -24
  302. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +7 -30
  303. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +225 -29
  304. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +266 -25
  305. package/Tests/Server/Utils/AI/InvestigationThread.test.ts +580 -0
  306. package/Tests/Server/Utils/AI/InvestigationThreadService.test.ts +801 -0
  307. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +525 -43
  308. package/Tests/Server/Utils/AI/KubectlJobRunner.test.ts +4 -2
  309. package/Tests/Server/Utils/AI/LLMServiceUnreachableProvider.test.ts +435 -0
  310. package/Tests/Server/Utils/AI/ObservabilityAssistantLimits.test.ts +462 -0
  311. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +14 -25
  312. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +2 -0
  313. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +297 -15
  314. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +10 -6
  315. package/Tests/Server/Utils/AI/ToolOutputPager.test.ts +382 -0
  316. package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +23 -4
  317. package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +25 -6
  318. package/Tests/Server/Utils/AI/Toolbox/Serializer.test.ts +14 -3
  319. package/Tests/Server/Utils/EditionEnforcement.test.ts +107 -147
  320. package/Tests/Server/Utils/{CommunityEditionSsoReport.test.ts → RelaxedScimTeamLocksReport.test.ts} +212 -208
  321. package/Tests/Server/Utils/SameOriginRequest.test.ts +372 -0
  322. package/Tests/Server/Utils/Telemetry/EntityRegistry.test.ts +20 -0
  323. package/Tests/Server/Utils/Telemetry/MessageQueueDiscovery.test.ts +2590 -0
  324. package/Tests/Server/Utils/Telemetry/MessageQueueSpanQueryTwin.ts +246 -0
  325. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +23 -0
  326. package/Tests/Types/AI/AIAgentRunLimits.test.ts +255 -0
  327. package/Tests/Types/Code/JsonSyntax.test.ts +1300 -0
  328. package/Tests/Types/CustomField/CustomFieldCreateSettings.test.ts +1113 -0
  329. package/Tests/Types/CustomField/CustomFieldMappingCatalog.test.ts +91 -0
  330. package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +30 -0
  331. package/Tests/Types/Incident/IncidentFormIpAllowlist.test.ts +227 -0
  332. package/Tests/Types/Incident/IncidentFormPublic.test.ts +1916 -0
  333. package/Tests/Types/MessageQueue/MessageQueueEntityKey.test.ts +916 -0
  334. package/Tests/Types/MessageQueue/MessageQueueIdentity.test.ts +567 -0
  335. package/Tests/Types/MessageQueue/MessageQueueManualIdentity.test.ts +686 -0
  336. package/Tests/Types/MessageQueue/MessageQueueMetricCatalog.test.ts +1726 -0
  337. package/Tests/Types/MessageQueue/MessageQueueMetricResolution.test.ts +1758 -0
  338. package/Tests/Types/MessageQueue/MessagingInstrumentationFixtures.test.ts +4686 -0
  339. package/Tests/Types/MessageQueue/MessagingSystem.test.ts +840 -0
  340. package/Tests/Types/MessageQueue/MessagingTelemetryFixtures.ts +3287 -0
  341. package/Tests/Types/MessageQueue/MessagingTelemetryResolver.test.ts +2966 -0
  342. package/Tests/Types/Monitor/MessageQueueAlertTemplates.test.ts +5401 -0
  343. package/Tests/Types/Monitor/MetricEngineFold.ts +154 -0
  344. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +5 -3
  345. package/Tests/Types/Team/ComplianceRule.test.ts +588 -37
  346. package/Tests/Types/Team/TeamComplianceStatus.test.ts +64 -11
  347. package/Tests/Types/XML.test.ts +51 -0
  348. package/Tests/UI/Components/CodeEditor/CodeEditor.test.tsx +2362 -0
  349. package/Tests/UI/Components/CodeEditor/CodeEditorCommands.test.ts +810 -0
  350. package/Tests/UI/Components/CodeEditor/CodeEditorHighlight.test.ts +338 -0
  351. package/Tests/UI/Components/CodeEditor/CodeEditorLanguages.test.ts +222 -0
  352. package/Tests/UI/Components/CodeEditor/CodeEditorStyles.test.ts +807 -0
  353. package/Tests/UI/Components/CodeEditor/NoMonaco.test.ts +245 -0
  354. package/Tests/UI/Components/CodeEditor/YamlEditor.test.tsx +729 -0
  355. package/Tests/UI/Components/CopyTextButton.test.tsx +76 -0
  356. package/Tests/UI/Components/EditionLabelLapseCopy.ts +51 -14
  357. package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +131 -23
  358. package/Tests/UI/Components/ErrorMessageAction.test.tsx +142 -0
  359. package/Tests/UI/Components/FacetSidebarInScope.test.tsx +459 -0
  360. package/Tests/UI/Components/FacetValuesInScope.test.ts +270 -0
  361. package/Tests/UI/Components/Forms/FormFieldCodeEditors.test.tsx +294 -0
  362. package/Tests/UI/Components/Forms/FormFieldMarkdown.test.tsx +126 -0
  363. package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +22 -75
  364. package/Tests/UI/Components/Forms/ModelFormOnBeforeCreateMiscData.test.tsx +254 -0
  365. package/Tests/UI/Components/Icon.test.tsx +32 -0
  366. package/Tests/UI/Components/Input.test.tsx +31 -0
  367. package/Tests/UI/Components/LockedFilterChipScope.test.tsx +501 -0
  368. package/Tests/UI/Components/MarkdownConverters.test.ts +253 -1
  369. package/Tests/UI/Components/MarkdownEditor.test.tsx +2785 -2
  370. package/Tests/UI/Components/MarkdownEditorHistory.test.ts +243 -0
  371. package/Tests/UI/Components/MarkdownListEditing.test.ts +1118 -0
  372. package/Tests/UI/Components/MarkdownPaste.test.ts +1180 -0
  373. package/Tests/UI/Components/MarkdownViewerCopy.test.tsx +466 -0
  374. package/Tests/UI/Components/MarkdownVisualEditing.test.ts +1089 -0
  375. package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +623 -0
  376. package/Tests/UI/Components/ResetObjectID.test.tsx +282 -0
  377. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
  378. package/Tests/UI/Components/Table/EmptyTableMessage.test.ts +439 -0
  379. package/Tests/UI/Components/Table/TableEmptyState.test.tsx +352 -0
  380. package/Tests/UI/Components/TableRowMobileTitles.test.tsx +78 -0
  381. package/Tests/UI/Components/TextArea.test.tsx +19 -0
  382. package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +12 -29
  383. package/Tests/UI/Components/fixtures/MarkdownPasteFixtures.ts +460 -0
  384. package/Tests/UI/EsbuildConfig.test.ts +115 -39
  385. package/Tests/UI/EsbuildEnterpriseAlias.test.ts +4 -4
  386. package/Tests/UI/Monitor/MonitorLogSummaryRender.test.tsx +377 -0
  387. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +81 -1
  388. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +17 -0
  389. package/Tests/Utils/LabelRuleImportExport.test.ts +5 -0
  390. package/Tests/Utils/Markdown/DashboardMarkdownRenderer.ts +81 -0
  391. package/Tests/Utils/Markdown/UntrustedMarkdown.test.ts +1339 -0
  392. package/Tests/Utils/Monitor/MonitorLogSummaryUtil.test.ts +862 -0
  393. package/Types/AI/AIAgentRunLimits.ts +146 -0
  394. package/Types/Code/CodeType.ts +2 -0
  395. package/Types/Code/JsonSyntax.ts +923 -0
  396. package/Types/CustomField/CustomFieldCreateSettings.ts +549 -0
  397. package/Types/CustomField/CustomFieldMappingCatalog.ts +77 -0
  398. package/Types/CustomField/CustomFieldValueValidator.ts +10 -7
  399. package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +1 -1
  400. package/Types/Icon/IconProp.ts +2 -0
  401. package/Types/Incident/IncidentFormIpAllowlist.ts +206 -0
  402. package/Types/Incident/IncidentFormPublic.ts +1145 -0
  403. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +10 -3
  404. package/Types/MessageQueue/MessageQueueIdentity.ts +256 -0
  405. package/Types/MessageQueue/MessageQueueManualIdentity.ts +325 -0
  406. package/Types/MessageQueue/MessageQueueMetricCatalog.ts +1357 -0
  407. package/Types/MessageQueue/MessagingSystem.ts +518 -0
  408. package/Types/MessageQueue/MessagingTelemetryResolver.ts +2311 -0
  409. package/Types/Monitor/MessageQueueAlertTemplates.ts +2128 -0
  410. package/Types/Permission.ts +310 -0
  411. package/Types/ResourceAiAgent/ResourceAiAccess.ts +10 -4
  412. package/Types/Rules/RuleCriteriaFieldRegistry.ts +12 -0
  413. package/Types/Rules/RuleRun.ts +4 -0
  414. package/Types/Team/ComplianceNotificationChannel.ts +4 -3
  415. package/Types/Team/ComplianceRule.ts +71 -18
  416. package/Types/Team/ComplianceRuleType.ts +2 -2
  417. package/Types/Team/TeamComplianceStatus.ts +6 -2
  418. package/Types/Telemetry/EntityType.ts +16 -0
  419. package/Types/Telemetry/LockedFilterDetail.ts +22 -0
  420. package/Types/XML.ts +26 -0
  421. package/UI/Components/CodeEditor/CodeEditor.css +379 -0
  422. package/UI/Components/CodeEditor/CodeEditor.tsx +1128 -294
  423. package/UI/Components/CodeEditor/CodeEditorCommands.ts +774 -0
  424. package/UI/Components/CodeEditor/CodeEditorHighlight.ts +106 -0
  425. package/UI/Components/CodeEditor/CodeEditorLanguages.ts +164 -0
  426. package/UI/Components/CodeEditor/YamlEditor.tsx +28 -326
  427. package/UI/Components/CopyTextButton/CopyTextButton.tsx +5 -1
  428. package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +6 -25
  429. package/UI/Components/EditionLabel/EditionLabel.tsx +14 -13
  430. package/UI/Components/ErrorMessage/ErrorMessage.tsx +11 -1
  431. package/UI/Components/Forms/Fields/FormField.tsx +8 -0
  432. package/UI/Components/Forms/Types/Field.ts +8 -0
  433. package/UI/Components/Icon/Icon.tsx +18 -0
  434. package/UI/Components/Input/Input.tsx +11 -4
  435. package/UI/Components/LogsViewer/LogsViewer.tsx +4 -0
  436. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +21 -3
  437. package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
  438. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +877 -79
  439. package/UI/Components/Markdown.tsx/MarkdownEditorHistory.ts +284 -0
  440. package/UI/Components/Markdown.tsx/MarkdownListEditing.ts +1362 -0
  441. package/UI/Components/Markdown.tsx/MarkdownPaste.ts +1326 -0
  442. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +106 -10
  443. package/UI/Components/Markdown.tsx/MarkdownVisualEditing.ts +1032 -0
  444. package/UI/Components/ModelTable/BaseModelTable.tsx +85 -7
  445. package/UI/Components/ResetObjectID/ResetObjectID.tsx +35 -9
  446. package/UI/Components/Table/EmptyTableMessage.ts +81 -0
  447. package/UI/Components/Table/Table.tsx +50 -21
  448. package/UI/Components/Table/TableRow.tsx +9 -1
  449. package/UI/Components/TelemetryViewer/FacetVisibility.ts +97 -2
  450. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +13 -0
  451. package/UI/Components/TelemetryViewer/components/LockedFilterChip.tsx +214 -7
  452. package/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.tsx +21 -3
  453. package/UI/Components/TextArea/TextArea.tsx +9 -2
  454. package/UI/Components/Workflow/ModelFieldPicker.tsx +10 -12
  455. package/UI/Styles/Theme.css +8 -0
  456. package/UI/esbuild-config.js +2 -32
  457. package/Utils/LabelRuleImportExport.ts +2 -0
  458. package/Utils/Markdown/UntrustedMarkdown.ts +1513 -0
  459. package/Utils/Monitor/IncomingEmailMonitorRequestUtil.ts +41 -0
  460. package/Utils/Monitor/MonitorLogSummaryUtil.ts +212 -0
  461. package/Utils/Telemetry/EntityKey.ts +48 -0
  462. package/build/dist/Models/DatabaseModels/AIConversation.js +125 -1
  463. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
  464. package/build/dist/Models/DatabaseModels/CephCluster.js +12 -0
  465. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  466. package/build/dist/Models/DatabaseModels/CloudResource.js +12 -0
  467. package/build/dist/Models/DatabaseModels/CloudResource.js.map +1 -1
  468. package/build/dist/Models/DatabaseModels/DatabaseServer.js +12 -0
  469. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  470. package/build/dist/Models/DatabaseModels/DockerHost.js +12 -0
  471. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  472. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +12 -0
  473. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  474. package/build/dist/Models/DatabaseModels/GlobalOidc.js +0 -4
  475. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  476. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +0 -4
  477. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  478. package/build/dist/Models/DatabaseModels/GlobalSso.js +0 -4
  479. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  480. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +0 -4
  481. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  482. package/build/dist/Models/DatabaseModels/Host.js +12 -0
  483. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  484. package/build/dist/Models/DatabaseModels/IncidentForm.js +605 -0
  485. package/build/dist/Models/DatabaseModels/IncidentForm.js.map +1 -0
  486. package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js +299 -0
  487. package/build/dist/Models/DatabaseModels/IncidentFormSubmission.js.map +1 -0
  488. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +60 -0
  489. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  490. package/build/dist/Models/DatabaseModels/Index.js +14 -0
  491. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  492. package/build/dist/Models/DatabaseModels/IoTFleet.js +12 -0
  493. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  494. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +12 -0
  495. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  496. package/build/dist/Models/DatabaseModels/MessageQueue.js +1106 -0
  497. package/build/dist/Models/DatabaseModels/MessageQueue.js.map +1 -0
  498. package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js +562 -0
  499. package/build/dist/Models/DatabaseModels/MessageQueueLabelRule.js.map +1 -0
  500. package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js +643 -0
  501. package/build/dist/Models/DatabaseModels/MessageQueueOwnerRule.js.map +1 -0
  502. package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js +506 -0
  503. package/build/dist/Models/DatabaseModels/MessageQueueOwnerTeam.js.map +1 -0
  504. package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js +505 -0
  505. package/build/dist/Models/DatabaseModels/MessageQueueOwnerUser.js.map +1 -0
  506. package/build/dist/Models/DatabaseModels/PodmanHost.js +12 -0
  507. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  508. package/build/dist/Models/DatabaseModels/Project.js +61 -0
  509. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  510. package/build/dist/Models/DatabaseModels/ProjectOidc.js +0 -4
  511. package/build/dist/Models/DatabaseModels/ProjectOidc.js.map +1 -1
  512. package/build/dist/Models/DatabaseModels/ProjectSso.js +0 -4
  513. package/build/dist/Models/DatabaseModels/ProjectSso.js.map +1 -1
  514. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +12 -0
  515. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  516. package/build/dist/Models/DatabaseModels/RumApplication.js +12 -0
  517. package/build/dist/Models/DatabaseModels/RumApplication.js.map +1 -1
  518. package/build/dist/Models/DatabaseModels/ServerlessFunction.js +12 -0
  519. package/build/dist/Models/DatabaseModels/ServerlessFunction.js.map +1 -1
  520. package/build/dist/Models/DatabaseModels/Service.js +12 -0
  521. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  522. package/build/dist/Models/DatabaseModels/StatusPageOidc.js +0 -4
  523. package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
  524. package/build/dist/Models/DatabaseModels/StatusPageSso.js +0 -4
  525. package/build/dist/Models/DatabaseModels/StatusPageSso.js.map +1 -1
  526. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +49 -3
  527. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  528. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +12 -0
  529. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  530. package/build/dist/Server/API/AIChatAPI.js +9 -103
  531. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  532. package/build/dist/Server/API/AIInvestigationAPI.js +3 -3
  533. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  534. package/build/dist/Server/API/AIInvestigationConversationAPI.js +162 -0
  535. package/build/dist/Server/API/AIInvestigationConversationAPI.js.map +1 -0
  536. package/build/dist/Server/API/IncidentFormAPI.js +245 -0
  537. package/build/dist/Server/API/IncidentFormAPI.js.map +1 -0
  538. package/build/dist/Server/API/ProjectOIDC.js +16 -24
  539. package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
  540. package/build/dist/Server/API/ProjectSSO.js +16 -24
  541. package/build/dist/Server/API/ProjectSSO.js.map +1 -1
  542. package/build/dist/Server/API/StatusPageAPI.js +42 -75
  543. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  544. package/build/dist/Server/Enterprise/EnterpriseEdition.js +79 -25
  545. package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -1
  546. package/build/dist/Server/Enterprise/EnterpriseFeature.js +24 -3
  547. package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -1
  548. package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +1 -1
  549. package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -1
  550. package/build/dist/Server/EnvironmentConfig.js +1 -1
  551. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js +63 -0
  552. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796400000000-AddIncidentForms.js.map +1 -0
  553. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js +41 -0
  554. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796500000000-AddTeamComplianceRuleNotificationChannels.js.map +1 -0
  555. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js +40 -0
  556. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796600000000-AddAIInvestigationConversationAndTimeLimits.js.map +1 -0
  557. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js +183 -0
  558. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796700000000-AddMessageQueueTables.js.map +1 -0
  559. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  560. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  561. package/build/dist/Server/Middleware/IncidentFormRateLimit.js +559 -0
  562. package/build/dist/Server/Middleware/IncidentFormRateLimit.js.map +1 -0
  563. package/build/dist/Server/Middleware/UserAuthorization.js +11 -30
  564. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  565. package/build/dist/Server/Services/AIService.js +10 -13
  566. package/build/dist/Server/Services/AIService.js.map +1 -1
  567. package/build/dist/Server/Services/IncidentCustomFieldService.js +83 -0
  568. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  569. package/build/dist/Server/Services/IncidentEpisodeMemberService.js +8 -4
  570. package/build/dist/Server/Services/IncidentEpisodeMemberService.js.map +1 -1
  571. package/build/dist/Server/Services/IncidentEpisodeService.js +10 -1
  572. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  573. package/build/dist/Server/Services/IncidentFormService.js +1202 -0
  574. package/build/dist/Server/Services/IncidentFormService.js.map +1 -0
  575. package/build/dist/Server/Services/IncidentFormSubmissionService.js +91 -0
  576. package/build/dist/Server/Services/IncidentFormSubmissionService.js.map +1 -0
  577. package/build/dist/Server/Services/IncidentGroupingEngineService.js +20 -8
  578. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  579. package/build/dist/Server/Services/IncidentService.js +106 -4
  580. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  581. package/build/dist/Server/Services/IncidentTemplateService.js +18 -0
  582. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  583. package/build/dist/Server/Services/Index.js +14 -0
  584. package/build/dist/Server/Services/Index.js.map +1 -1
  585. package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js +262 -0
  586. package/build/dist/Server/Services/MessageQueueLabelRuleEngineService.js.map +1 -0
  587. package/build/dist/Server/Services/MessageQueueLabelRuleService.js +13 -0
  588. package/build/dist/Server/Services/MessageQueueLabelRuleService.js.map +1 -0
  589. package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js +334 -0
  590. package/build/dist/Server/Services/MessageQueueOwnerRuleEngineService.js.map +1 -0
  591. package/build/dist/Server/Services/MessageQueueOwnerRuleService.js +13 -0
  592. package/build/dist/Server/Services/MessageQueueOwnerRuleService.js.map +1 -0
  593. package/build/dist/Server/Services/MessageQueueOwnerTeamService.js +62 -0
  594. package/build/dist/Server/Services/MessageQueueOwnerTeamService.js.map +1 -0
  595. package/build/dist/Server/Services/MessageQueueOwnerUserService.js +62 -0
  596. package/build/dist/Server/Services/MessageQueueOwnerUserService.js.map +1 -0
  597. package/build/dist/Server/Services/MessageQueueService.js +1140 -0
  598. package/build/dist/Server/Services/MessageQueueService.js.map +1 -0
  599. package/build/dist/Server/Services/OpenTelemetryIngestService.js +25 -4
  600. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  601. package/build/dist/Server/Services/ProjectService.js +0 -54
  602. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  603. package/build/dist/Server/Services/StatusPagePrivateUserService.js +1 -4
  604. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  605. package/build/dist/Server/Services/StatusPageService.js +0 -46
  606. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  607. package/build/dist/Server/Services/TeamComplianceSettingService.js +120 -31
  608. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  609. package/build/dist/Server/Services/UserNotificationRuleService.js +8 -1
  610. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  611. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +12 -3
  612. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
  613. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +6 -3
  614. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  615. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +109 -37
  616. package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
  617. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +16 -0
  618. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  619. package/build/dist/Server/Types/Database/Permissions/TablePermission.js +3 -3
  620. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +9 -6
  621. package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
  622. package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js +128 -0
  623. package/build/dist/Server/Utils/AI/Chat/AgentContextCompactor.js.map +1 -0
  624. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +192 -50
  625. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  626. package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js +133 -0
  627. package/build/dist/Server/Utils/AI/Chat/ChatRunCancellation.js.map +1 -0
  628. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +53 -13
  629. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  630. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  631. package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js +206 -0
  632. package/build/dist/Server/Utils/AI/Chat/ToolOutputPager.js.map +1 -0
  633. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +53 -26
  634. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  635. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +4 -2
  636. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  637. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -29
  638. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  639. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +24 -24
  640. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  641. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +7 -2
  642. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  643. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +29 -14
  644. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  645. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +38 -14
  646. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -1
  647. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +2 -0
  648. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -1
  649. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +40 -10
  650. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  651. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +19 -7
  652. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  653. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +19 -7
  654. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  655. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +15 -18
  656. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  657. package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js +412 -0
  658. package/build/dist/Server/Utils/AI/SRE/InvestigationThread.js.map +1 -0
  659. package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js +495 -0
  660. package/build/dist/Server/Utils/AI/SRE/InvestigationThreadService.js.map +1 -0
  661. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +10 -3
  662. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
  663. package/build/dist/Server/Utils/EditionEnforcement.js +20 -158
  664. package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -1
  665. package/build/dist/Server/Utils/LLM/LLMService.js +193 -54
  666. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  667. package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js +160 -0
  668. package/build/dist/Server/Utils/RelaxedScimTeamLocksReport.js.map +1 -0
  669. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +25 -0
  670. package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
  671. package/build/dist/Server/Utils/SameOriginRequest.js +151 -0
  672. package/build/dist/Server/Utils/SameOriginRequest.js.map +1 -0
  673. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js +2 -0
  674. package/build/dist/Server/Utils/TeamMember/ProjectLeaveResourceCleanup.js.map +1 -1
  675. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +4 -1
  676. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  677. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +1015 -0
  678. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -0
  679. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +4 -1
  680. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -1
  681. package/build/dist/Server/Utils/VendorAssets.js +3 -3
  682. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +3 -1
  683. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  684. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +3 -1
  685. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  686. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +10 -1
  687. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  688. package/build/dist/Types/AI/AIAgentRunLimits.js +91 -0
  689. package/build/dist/Types/AI/AIAgentRunLimits.js.map +1 -0
  690. package/build/dist/Types/Code/CodeType.js +2 -0
  691. package/build/dist/Types/Code/CodeType.js.map +1 -1
  692. package/build/dist/Types/Code/JsonSyntax.js +604 -0
  693. package/build/dist/Types/Code/JsonSyntax.js.map +1 -0
  694. package/build/dist/Types/CustomField/CustomFieldCreateSettings.js +310 -0
  695. package/build/dist/Types/CustomField/CustomFieldCreateSettings.js.map +1 -0
  696. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js +38 -0
  697. package/build/dist/Types/CustomField/CustomFieldMappingCatalog.js.map +1 -1
  698. package/build/dist/Types/CustomField/CustomFieldValueValidator.js +10 -7
  699. package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -1
  700. package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +1 -1
  701. package/build/dist/Types/Icon/IconProp.js +2 -0
  702. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  703. package/build/dist/Types/Incident/IncidentFormIpAllowlist.js +119 -0
  704. package/build/dist/Types/Incident/IncidentFormIpAllowlist.js.map +1 -0
  705. package/build/dist/Types/Incident/IncidentFormPublic.js +678 -0
  706. package/build/dist/Types/Incident/IncidentFormPublic.js.map +1 -0
  707. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +10 -3
  708. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  709. package/build/dist/Types/MessageQueue/MessageQueueIdentity.js +184 -0
  710. package/build/dist/Types/MessageQueue/MessageQueueIdentity.js.map +1 -0
  711. package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js +190 -0
  712. package/build/dist/Types/MessageQueue/MessageQueueManualIdentity.js.map +1 -0
  713. package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js +1057 -0
  714. package/build/dist/Types/MessageQueue/MessageQueueMetricCatalog.js.map +1 -0
  715. package/build/dist/Types/MessageQueue/MessagingSystem.js +394 -0
  716. package/build/dist/Types/MessageQueue/MessagingSystem.js.map +1 -0
  717. package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js +1768 -0
  718. package/build/dist/Types/MessageQueue/MessagingTelemetryResolver.js.map +1 -0
  719. package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js +1207 -0
  720. package/build/dist/Types/Monitor/MessageQueueAlertTemplates.js.map +1 -0
  721. package/build/dist/Types/Permission.js +274 -0
  722. package/build/dist/Types/Permission.js.map +1 -1
  723. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +10 -4
  724. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -1
  725. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +12 -0
  726. package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
  727. package/build/dist/Types/Rules/RuleRun.js +4 -0
  728. package/build/dist/Types/Rules/RuleRun.js.map +1 -1
  729. package/build/dist/Types/Team/ComplianceNotificationChannel.js +4 -3
  730. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -1
  731. package/build/dist/Types/Team/ComplianceRule.js +48 -14
  732. package/build/dist/Types/Team/ComplianceRule.js.map +1 -1
  733. package/build/dist/Types/Team/ComplianceRuleType.js +2 -2
  734. package/build/dist/Types/Telemetry/EntityType.js +16 -0
  735. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  736. package/build/dist/Types/XML.js +23 -0
  737. package/build/dist/Types/XML.js.map +1 -1
  738. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +641 -266
  739. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  740. package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js +464 -0
  741. package/build/dist/UI/Components/CodeEditor/CodeEditorCommands.js.map +1 -0
  742. package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js +69 -0
  743. package/build/dist/UI/Components/CodeEditor/CodeEditorHighlight.js.map +1 -0
  744. package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js +108 -0
  745. package/build/dist/UI/Components/CodeEditor/CodeEditorLanguages.js.map +1 -0
  746. package/build/dist/UI/Components/CodeEditor/YamlEditor.js +14 -186
  747. package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -1
  748. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js +5 -1
  749. package/build/dist/UI/Components/CopyTextButton/CopyTextButton.js.map +1 -1
  750. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +5 -14
  751. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -1
  752. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +14 -13
  753. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  754. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +1 -1
  755. package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
  756. package/build/dist/UI/Components/Forms/Fields/FormField.js +8 -3
  757. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  758. package/build/dist/UI/Components/Icon/Icon.js +8 -0
  759. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  760. package/build/dist/UI/Components/Input/Input.js +11 -3
  761. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  762. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +2 -1
  763. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  764. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +14 -4
  765. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  766. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
  767. package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
  768. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +710 -65
  769. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  770. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js +238 -0
  771. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditorHistory.js.map +1 -0
  772. package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js +1028 -0
  773. package/build/dist/UI/Components/Markdown.tsx/MarkdownListEditing.js.map +1 -0
  774. package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js +1088 -0
  775. package/build/dist/UI/Components/Markdown.tsx/MarkdownPaste.js.map +1 -0
  776. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +70 -10
  777. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  778. package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js +887 -0
  779. package/build/dist/UI/Components/Markdown.tsx/MarkdownVisualEditing.js.map +1 -0
  780. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +57 -6
  781. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  782. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js +7 -5
  783. package/build/dist/UI/Components/ResetObjectID/ResetObjectID.js.map +1 -1
  784. package/build/dist/UI/Components/Table/EmptyTableMessage.js +51 -0
  785. package/build/dist/UI/Components/Table/EmptyTableMessage.js.map +1 -0
  786. package/build/dist/UI/Components/Table/Table.js +30 -11
  787. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  788. package/build/dist/UI/Components/Table/TableRow.js +9 -2
  789. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  790. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js +63 -1
  791. package/build/dist/UI/Components/TelemetryViewer/FacetVisibility.js.map +1 -1
  792. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +4 -2
  793. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  794. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js +91 -10
  795. package/build/dist/UI/Components/TelemetryViewer/components/LockedFilterChip.js.map +1 -1
  796. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js +14 -4
  797. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryFacetSidebar.js.map +1 -1
  798. package/build/dist/UI/Components/TextArea/TextArea.js +9 -3
  799. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  800. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +1 -2
  801. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
  802. package/build/dist/Utils/LabelRuleImportExport.js +2 -0
  803. package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
  804. package/build/dist/Utils/Markdown/UntrustedMarkdown.js +988 -0
  805. package/build/dist/Utils/Markdown/UntrustedMarkdown.js.map +1 -0
  806. package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js +34 -0
  807. package/build/dist/Utils/Monitor/IncomingEmailMonitorRequestUtil.js.map +1 -0
  808. package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js +148 -0
  809. package/build/dist/Utils/Monitor/MonitorLogSummaryUtil.js.map +1 -0
  810. package/build/dist/Utils/Telemetry/EntityKey.js +36 -0
  811. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  812. package/package.json +1 -3
  813. package/Server/Utils/CommunityEditionSsoReport.ts +0 -361
  814. package/Tests/App/Accounts/LoginSsoEdition.test.tsx +0 -616
  815. package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +0 -217
  816. package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +0 -271
  817. package/Tests/App/Dashboard/CloudDocumentationMarkdown.test.ts +0 -215
  818. package/Tests/App/Dashboard/TelemetryResourceRetentionSettings.test.tsx +0 -784
  819. package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +0 -518
  820. package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +0 -419
  821. package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +0 -769
  822. package/Tests/UI/Components/CodeEditor.test.tsx +0 -638
  823. package/Tests/UI/Components/MonacoLoader.test.ts +0 -67
  824. package/Tests/UI/Components/MonacoRuntime.test.ts +0 -121
  825. package/Tests/UI/Components/Telemetry/TelemetryRetentionConfigForm.test.tsx +0 -329
  826. package/Tests/UI/Components/YamlEditor.test.tsx +0 -847
  827. package/UI/Components/CodeEditor/MonacoLoader.ts +0 -36
  828. package/UI/Components/Telemetry/TelemetryRetentionConfigForm.tsx +0 -319
  829. package/UI/Components/Telemetry/TelemetryRetentionConfigSummary.tsx +0 -223
  830. package/build/dist/Server/Utils/CommunityEditionSsoReport.js +0 -223
  831. package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +0 -1
  832. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js +0 -34
  833. package/build/dist/UI/Components/CodeEditor/MonacoLoader.js.map +0 -1
  834. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js +0 -171
  835. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigForm.js.map +0 -1
  836. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js +0 -119
  837. package/build/dist/UI/Components/Telemetry/TelemetryRetentionConfigSummary.js.map +0 -1
@@ -0,0 +1,1145 @@
1
+ import { parseCustomFieldDropdownOptions } from "../CustomField/CustomFieldDropdownOption";
2
+ import CustomFieldType from "../CustomField/CustomFieldType";
3
+ import { isCustomFieldValueEmpty } from "../CustomField/CustomFieldValueMapping";
4
+ import {
5
+ CustomFieldValueValidationError,
6
+ validateCustomFieldValues,
7
+ } from "../CustomField/CustomFieldValueValidator";
8
+ import ColumnLength from "../Database/ColumnLength";
9
+ import Email from "../Email";
10
+ import { JSONObject, JSONValue } from "../JSON";
11
+
12
+ /*
13
+ * The public half of incident forms: what the page anyone with a form's link
14
+ * opens is told about the form, what it sends back, and the one set of rules
15
+ * a submission is held to.
16
+ *
17
+ * A form is filled in by people with no OneUptime account, so nothing on the
18
+ * way in is trusted. The server builds the incident only from what
19
+ * validateIncidentFormSubmission hands back - a value assembled field by
20
+ * field from the answers the form actually asks for. Anything else in the
21
+ * request (a projectId, a state, isPrivate, an answer to a field the form
22
+ * does not ask) never reaches it. Every text is trimmed and capped so it fits
23
+ * the column it lands in, and every custom field answer is checked with the
24
+ * same rules as an API write (validateCustomFieldValues) plus the form's own
25
+ * Required.
26
+ *
27
+ * Pure, with no database or React imports: the server enforces these rules,
28
+ * and the public page can show the same limits before anything is sent.
29
+ */
30
+
31
+ /*
32
+ * How the form treats one of its built-in questions. Only the description
33
+ * has a setting today: Title is always asked and always required.
34
+ */
35
+ export enum IncidentFormFieldSetting {
36
+ Required = "Required",
37
+ Optional = "Optional",
38
+ Hidden = "Hidden",
39
+ }
40
+
41
+ // Every setting, in the order a picker lists them.
42
+ export const INCIDENT_FORM_FIELD_SETTINGS: ReadonlyArray<IncidentFormFieldSetting> =
43
+ [
44
+ IncidentFormFieldSetting.Required,
45
+ IncidentFormFieldSetting.Optional,
46
+ IncidentFormFieldSetting.Hidden,
47
+ ];
48
+
49
+ // What a form asks for the description when nobody chose otherwise.
50
+ export const DEFAULT_INCIDENT_FORM_DESCRIPTION_SETTING: IncidentFormFieldSetting =
51
+ IncidentFormFieldSetting.Optional;
52
+
53
+ export type IsIncidentFormFieldSettingFunction = (
54
+ value: unknown,
55
+ ) => value is IncidentFormFieldSetting;
56
+
57
+ /** Whether a value is one of the settings, spelled exactly as stored. */
58
+ export const isIncidentFormFieldSetting: IsIncidentFormFieldSettingFunction = (
59
+ value: unknown,
60
+ ): value is IncidentFormFieldSetting => {
61
+ return (
62
+ typeof value === "string" &&
63
+ (INCIDENT_FORM_FIELD_SETTINGS as ReadonlyArray<string>).includes(value)
64
+ );
65
+ };
66
+
67
+ /*
68
+ * The longest answers a form takes. Each is at most the column the answer is
69
+ * stored in, so a submission that passes here cannot then fail to save:
70
+ *
71
+ * - the title becomes Incident.title, a varchar(500);
72
+ * - the description becomes Incident.description (text) - capped anyway,
73
+ * since the request body may be up to 50 MB and an incident description
74
+ * is read in emails, Slack and on status pages;
75
+ * - each custom field text answer is stored in Incident.customFields;
76
+ * - the reporter's name and email are stored on IncidentFormSubmission, in
77
+ * a varchar(100) each (an email longer than that is not one anybody can
78
+ * sign up to OneUptime with either).
79
+ */
80
+ export const INCIDENT_FORM_TITLE_MAX_LENGTH: number = ColumnLength.LongText;
81
+ export const INCIDENT_FORM_DESCRIPTION_MAX_LENGTH: number = 20000;
82
+ export const INCIDENT_FORM_CUSTOM_FIELD_TEXT_MAX_LENGTH: number = 10000;
83
+ export const INCIDENT_FORM_REPORTER_NAME_MAX_LENGTH: number =
84
+ ColumnLength.ShortText;
85
+ export const INCIDENT_FORM_REPORTER_EMAIL_MAX_LENGTH: number =
86
+ ColumnLength.Email;
87
+
88
+ /*
89
+ * The most entries a multi-select answer may have: this many, or the
90
+ * field's number of options when it has more. The page sends each option
91
+ * at most once, so a real answer never comes near it; what it bounds is a
92
+ * request that sends a million entries, each of which would otherwise be
93
+ * cleaned, sorted and quoted back in the refusal (or, for a field nobody
94
+ * gave options to, stored on the incident).
95
+ */
96
+ export const INCIDENT_FORM_MULTI_SELECT_MAX_CHOICES: number = 100;
97
+
98
+ /*
99
+ * The titles of the built-in questions. The public page labels its fields
100
+ * with them (through its locale files) and the server names them in its
101
+ * error messages, so both say "Your Email is required." about the same box.
102
+ */
103
+ export interface IncidentFormQuestionLabels {
104
+ title: string;
105
+ description: string;
106
+ severity: string;
107
+ reporterName: string;
108
+ reporterEmail: string;
109
+ }
110
+
111
+ export const INCIDENT_FORM_QUESTION_LABELS: IncidentFormQuestionLabels = {
112
+ title: "Title",
113
+ description: "Description",
114
+ severity: "Severity",
115
+ reporterName: "Your Name",
116
+ reporterEmail: "Your Email",
117
+ };
118
+
119
+ /*
120
+ * The message templates, worded as the form's own client-side checks word
121
+ * them (Forms/Validation and CUSTOM_FIELD_MUST_BE_CHECKED_MESSAGE), so an
122
+ * answer refused by the server reads like one refused in the browser.
123
+ */
124
+ const REQUIRED_MESSAGE: string = "{{field}} is required.";
125
+ const TOO_LONG_MESSAGE: string =
126
+ "{{field}} cannot be more than {{maxLength}} characters.";
127
+ const MUST_BE_CHECKED_MESSAGE: string = "{{field}} must be checked.";
128
+ const TOO_MANY_CHOICES_MESSAGE: string =
129
+ "{{field}} cannot have more than {{maxLength}} choices.";
130
+ const NOT_A_LIST_MESSAGE: string = "{{field}} takes one answer, not a list.";
131
+ const NESTED_CHOICE_MESSAGE: string =
132
+ "{{field}} takes a list of its options, not lists or objects within it.";
133
+ const OBJECT_ANSWER_MESSAGE: string =
134
+ "{{field}} takes one answer, not an object.";
135
+ const OBJECT_CHOICES_MESSAGE: string =
136
+ "{{field}} takes a list of its options, not an object.";
137
+
138
+ type FillMessageFunction = (
139
+ template: string,
140
+ values: { field: string; maxLength?: number },
141
+ ) => string;
142
+
143
+ /*
144
+ * Replacer functions, not replacement strings: a field named "Cost ($)" or
145
+ * "$& total" must come out as typed, and a replacement string would read its
146
+ * "$" patterns.
147
+ */
148
+ const fillMessage: FillMessageFunction = (
149
+ template: string,
150
+ values: { field: string; maxLength?: number },
151
+ ): string => {
152
+ return template
153
+ .replace("{{field}}", (): string => {
154
+ return values.field;
155
+ })
156
+ .replace("{{maxLength}}", (): string => {
157
+ return String(values.maxLength ?? "");
158
+ });
159
+ };
160
+
161
+ /*
162
+ * A header the public page's own script adds to every request it makes, and
163
+ * the value it gives it. Reading a form needs it: another site's page can
164
+ * have a visitor's browser send that GET - an <img>, a link, a no-cors
165
+ * fetch - carrying neither of the headers that say where a request came
166
+ * from (over plain HTTP a browser sends neither on such a request), but it
167
+ * cannot add a header of its own to one. A request that adds one is
168
+ * preflighted first, and then carries the Origin that gives it away
169
+ * (SameOriginRequest). The name is in lower case, as the server reads
170
+ * header names.
171
+ */
172
+ export const INCIDENT_FORM_PAGE_HEADER: string = "x-oneuptime-incident-form";
173
+ export const INCIDENT_FORM_PAGE_HEADER_VALUE: string = "1";
174
+
175
+ /*
176
+ * One custom field the form asks for, as the public page renders it. Only
177
+ * what the page needs to draw the input: never the field's id, its template
178
+ * variable key, its project-wide switches or its mapping, and a dropdown's
179
+ * options only for a dropdown.
180
+ */
181
+ export interface PublicIncidentFormField {
182
+ name: string;
183
+ description?: string | undefined;
184
+ customFieldType: CustomFieldType;
185
+ dropdownOptions?: string | undefined;
186
+ isRequired: boolean;
187
+ }
188
+
189
+ // A severity the reporter can pick, when the form lets them pick one.
190
+ export interface PublicIncidentFormSeverity {
191
+ _id: string;
192
+ name: string;
193
+ color?: string | undefined;
194
+ }
195
+
196
+ // Everything the public page is told about a form.
197
+ export interface PublicIncidentForm {
198
+ name: string;
199
+ // Shown at the top of the page, as Markdown.
200
+ description?: string | undefined;
201
+ descriptionSetting: IncidentFormFieldSetting;
202
+ isReporterDetailsRequired: boolean;
203
+ // Only when the form lets the reporter choose the severity.
204
+ severities?: Array<PublicIncidentFormSeverity> | undefined;
205
+ // The form's own severity, to preselect in that list.
206
+ defaultIncidentSeverityId?: string | undefined;
207
+ // The custom fields the form asks for, in the order to show them.
208
+ customFields: Array<PublicIncidentFormField>;
209
+ isCaptchaRequired: boolean;
210
+ }
211
+
212
+ /*
213
+ * The answers, as the public page sends them. Custom field answers are keyed
214
+ * by the field's name, as PublicIncidentFormField names it.
215
+ */
216
+ export interface PublicIncidentFormSubmissionData {
217
+ title: string;
218
+ description?: string | undefined;
219
+ incidentSeverityId?: string | undefined;
220
+ reporterName?: string | undefined;
221
+ reporterEmail?: string | undefined;
222
+ customFields?: JSONObject | undefined;
223
+ }
224
+
225
+ // The body of the submit request.
226
+ export interface PublicIncidentFormSubmissionRequest {
227
+ data: PublicIncidentFormSubmissionData;
228
+ captchaToken?: string | undefined;
229
+ }
230
+
231
+ // What the reporter is shown once the incident is declared.
232
+ export interface PublicIncidentFormSubmissionResult {
233
+ // The incident's number as the project shows it, e.g. "INC-42" or "#42".
234
+ incidentNumber?: string | undefined;
235
+ // The form's thank-you text, as Markdown.
236
+ successMessage?: string | undefined;
237
+ }
238
+
239
+ /*
240
+ * The form's settings a submission is checked against. Every property is
241
+ * optional so an IncidentForm read from the database can be passed as it is;
242
+ * a setting that was not read falls back to the column's default, and the
243
+ * two switches fall back to their stricter side.
244
+ */
245
+ export interface IncidentFormSubmissionRules {
246
+ descriptionSetting?: IncidentFormFieldSetting | string | null | undefined;
247
+ isReporterDetailsRequired?: boolean | null | undefined;
248
+ allowReporterToChooseSeverity?: boolean | null | undefined;
249
+ }
250
+
251
+ /*
252
+ * A custom field the form asks for: one of getIncidentFormAskedDefinitions'
253
+ * results, whose isRequiredOnCreate says whether the FORM requires it.
254
+ * Loose enough that IncidentCustomField rows can be passed as they are.
255
+ */
256
+ export interface IncidentFormAskedDefinition {
257
+ name?: string | null | undefined;
258
+ description?: string | null | undefined;
259
+ customFieldType?: string | null | undefined;
260
+ dropdownOptions?: string | null | undefined;
261
+ isRequiredOnCreate?: boolean | null | undefined;
262
+ }
263
+
264
+ // A submission that passed: what the incident may be built from.
265
+ export interface ValidatedIncidentFormSubmission {
266
+ title: string;
267
+ // Only when the form asks for it and the reporter wrote something.
268
+ description?: string | undefined;
269
+ // Only when the form lets the reporter choose, and they chose.
270
+ incidentSeverityId?: string | undefined;
271
+ reporterName?: string | undefined;
272
+ // Lowercased, as Email stores it.
273
+ reporterEmail?: string | undefined;
274
+ /*
275
+ * The answers to the fields the form asks for, keyed by field name. An
276
+ * answer left empty is left out, so a template's value for that field
277
+ * still applies (see mergeTemplateCustomFields).
278
+ */
279
+ customFields: JSONObject;
280
+ }
281
+
282
+ export type IncidentFormSubmissionValidationResult =
283
+ | {
284
+ isValid: false;
285
+ errors: Array<string>;
286
+ }
287
+ | {
288
+ isValid: true;
289
+ value: ValidatedIncidentFormSubmission;
290
+ };
291
+
292
+ type IsPlainObjectFunction = (
293
+ value: unknown,
294
+ ) => value is Record<string, unknown>;
295
+
296
+ const isPlainObject: IsPlainObjectFunction = (
297
+ value: unknown,
298
+ ): value is Record<string, unknown> => {
299
+ return (
300
+ value !== null &&
301
+ typeof value === "object" &&
302
+ !Array.isArray(value) &&
303
+ !(value instanceof Date)
304
+ );
305
+ };
306
+
307
+ type HasOwnFunction = (target: Record<string, unknown>, key: string) => boolean;
308
+
309
+ const hasOwn: HasOwnFunction = (
310
+ target: Record<string, unknown>,
311
+ key: string,
312
+ ): boolean => {
313
+ return Object.prototype.hasOwnProperty.call(target, key);
314
+ };
315
+
316
+ /*
317
+ * Postgres cannot store a NUL character in a text column, nor in a jsonb
318
+ * string, so one pasted into an answer would fail the insert - after the
319
+ * checks here had passed. Nobody means to type one. no-control-regex is
320
+ * disabled for these two on purpose: matching control characters is exactly
321
+ * what they are for.
322
+ */
323
+ // eslint-disable-next-line no-control-regex
324
+ const NUL_CHARACTERS: RegExp = /\u0000/g;
325
+
326
+ // Control characters, line breaks and tabs included.
327
+ // eslint-disable-next-line no-control-regex
328
+ const CONTROL_CHARACTER_RUNS: RegExp = /[\u0000-\u001F\u007F]+/g;
329
+
330
+ type CleanTextFunction = (value: string) => string;
331
+
332
+ /*
333
+ * A one-line answer (the title, the reporter's name): line breaks, tabs and
334
+ * other control characters become spaces - a title is shown on one line in
335
+ * lists, emails and chat messages - runs of spaces become one, and the ends
336
+ * are trimmed.
337
+ */
338
+ const cleanSingleLine: CleanTextFunction = (value: string): string => {
339
+ return value
340
+ .replace(CONTROL_CHARACTER_RUNS, " ")
341
+ .replace(/ {2,}/g, " ")
342
+ .trim();
343
+ };
344
+
345
+ /*
346
+ * A Markdown or multi-line answer. Blank lines before the text and
347
+ * whitespace after it are dropped, but the first line keeps its own
348
+ * indentation: four spaces there start a code block, and trimming them would
349
+ * turn the reporter's pasted log into a paragraph.
350
+ */
351
+ const cleanMultiLine: CleanTextFunction = (value: string): string => {
352
+ return value
353
+ .replace(NUL_CHARACTERS, "")
354
+ .replace(/^\s*\n/, "")
355
+ .trimEnd();
356
+ };
357
+
358
+ // A dropdown option, a number or a date typed as text.
359
+ const cleanScalarText: CleanTextFunction = (value: string): string => {
360
+ return value.replace(NUL_CHARACTERS, "").trim();
361
+ };
362
+
363
+ type NormalizedFieldFunction = (
364
+ definition: IncidentFormAskedDefinition,
365
+ ) => PublicIncidentFormField | null;
366
+
367
+ const KNOWN_CUSTOM_FIELD_TYPES: ReadonlyArray<string> =
368
+ Object.values(CustomFieldType);
369
+
370
+ const DROPDOWN_TYPES: ReadonlyArray<CustomFieldType> = [
371
+ CustomFieldType.Dropdown,
372
+ CustomFieldType.MultiSelectDropdown,
373
+ ];
374
+
375
+ /*
376
+ * One asked definition as the public page sees it and as its answers are
377
+ * checked. A field with no type - rows from before types were required - or
378
+ * a type this version does not know is asked and checked as Text: the admin
379
+ * put it on the form, and text is what an untyped field has always held.
380
+ */
381
+ const toPublicField: NormalizedFieldFunction = (
382
+ definition: IncidentFormAskedDefinition,
383
+ ): PublicIncidentFormField | null => {
384
+ if (
385
+ !definition ||
386
+ typeof definition.name !== "string" ||
387
+ definition.name.length === 0
388
+ ) {
389
+ return null;
390
+ }
391
+
392
+ const customFieldType: CustomFieldType =
393
+ typeof definition.customFieldType === "string" &&
394
+ KNOWN_CUSTOM_FIELD_TYPES.includes(definition.customFieldType)
395
+ ? (definition.customFieldType as CustomFieldType)
396
+ : CustomFieldType.Text;
397
+
398
+ const field: PublicIncidentFormField = {
399
+ name: definition.name,
400
+ customFieldType: customFieldType,
401
+ isRequired: definition.isRequiredOnCreate === true,
402
+ };
403
+
404
+ if (
405
+ typeof definition.description === "string" &&
406
+ definition.description.trim().length > 0
407
+ ) {
408
+ field.description = definition.description;
409
+ }
410
+
411
+ if (
412
+ DROPDOWN_TYPES.includes(customFieldType) &&
413
+ typeof definition.dropdownOptions === "string" &&
414
+ definition.dropdownOptions.trim().length > 0
415
+ ) {
416
+ field.dropdownOptions = definition.dropdownOptions;
417
+ }
418
+
419
+ return field;
420
+ };
421
+
422
+ export type GetPublicIncidentFormFieldsFunction = (
423
+ askedDefinitions: Array<IncidentFormAskedDefinition>,
424
+ ) => Array<PublicIncidentFormField>;
425
+
426
+ /**
427
+ * The custom fields the public page shows, in the order given (pass the
428
+ * result of getIncidentFormAskedDefinitions). A definition without a name is
429
+ * left out, and so is a second one with a name already listed - answers are
430
+ * keyed by name, so it could not be told apart.
431
+ */
432
+ export const getPublicIncidentFormFields: GetPublicIncidentFormFieldsFunction =
433
+ (
434
+ askedDefinitions: Array<IncidentFormAskedDefinition>,
435
+ ): Array<PublicIncidentFormField> => {
436
+ const fields: Array<PublicIncidentFormField> = [];
437
+ const seenNames: Set<string> = new Set<string>();
438
+
439
+ for (const definition of askedDefinitions || []) {
440
+ const field: PublicIncidentFormField | null = toPublicField(definition);
441
+
442
+ if (!field || seenNames.has(field.name)) {
443
+ continue;
444
+ }
445
+
446
+ seenNames.add(field.name);
447
+ fields.push(field);
448
+ }
449
+
450
+ return fields;
451
+ };
452
+
453
+ type ReadDescriptionSettingFunction = (
454
+ value: unknown,
455
+ ) => IncidentFormFieldSetting;
456
+
457
+ // A stored setting, or the column's default for anything else.
458
+ const readDescriptionSetting: ReadDescriptionSettingFunction = (
459
+ value: unknown,
460
+ ): IncidentFormFieldSetting => {
461
+ return isIncidentFormFieldSetting(value)
462
+ ? value
463
+ : DEFAULT_INCIDENT_FORM_DESCRIPTION_SETTING;
464
+ };
465
+
466
+ /*
467
+ * The form, as far as the public page is concerned. Loose for the same
468
+ * reason as IncidentFormSubmissionRules: an IncidentForm row fits.
469
+ */
470
+ export interface PublicIncidentFormSource extends IncidentFormSubmissionRules {
471
+ name?: string | null | undefined;
472
+ description?: string | null | undefined;
473
+ incidentSeverityId?: { toString: () => string } | string | null | undefined;
474
+ }
475
+
476
+ export type GetPublicIncidentFormFunction = (data: {
477
+ form: PublicIncidentFormSource;
478
+ askedDefinitions: Array<IncidentFormAskedDefinition>;
479
+ // The project's severities, in the order to list them.
480
+ severities: Array<PublicIncidentFormSeverity>;
481
+ isCaptchaRequired: boolean;
482
+ }) => PublicIncidentForm;
483
+
484
+ /**
485
+ * What the public page is told about a form, built field by field so that
486
+ * nothing else about the form - its share key, its template, its IP
487
+ * allowlist, its project - is ever sent. The project's severities are only
488
+ * listed when the reporter may choose one.
489
+ */
490
+ export const getPublicIncidentForm: GetPublicIncidentFormFunction = (data: {
491
+ form: PublicIncidentFormSource;
492
+ askedDefinitions: Array<IncidentFormAskedDefinition>;
493
+ severities: Array<PublicIncidentFormSeverity>;
494
+ isCaptchaRequired: boolean;
495
+ }): PublicIncidentForm => {
496
+ const publicForm: PublicIncidentForm = {
497
+ name: typeof data.form.name === "string" ? data.form.name : "",
498
+ descriptionSetting: readDescriptionSetting(data.form.descriptionSetting),
499
+ isReporterDetailsRequired: data.form.isReporterDetailsRequired !== false,
500
+ customFields: getPublicIncidentFormFields(data.askedDefinitions),
501
+ isCaptchaRequired: data.isCaptchaRequired === true,
502
+ };
503
+
504
+ if (
505
+ typeof data.form.description === "string" &&
506
+ data.form.description.trim().length > 0
507
+ ) {
508
+ publicForm.description = data.form.description;
509
+ }
510
+
511
+ if (data.form.allowReporterToChooseSeverity === true) {
512
+ const severities: Array<PublicIncidentFormSeverity> = [];
513
+
514
+ // Only the three properties the page draws, whatever the caller passed.
515
+ for (const severity of data.severities || []) {
516
+ if (!severity || typeof severity._id !== "string" || !severity._id) {
517
+ continue;
518
+ }
519
+
520
+ const listed: PublicIncidentFormSeverity = {
521
+ _id: severity._id,
522
+ name: typeof severity.name === "string" ? severity.name : "",
523
+ };
524
+
525
+ if (typeof severity.color === "string" && severity.color) {
526
+ listed.color = severity.color;
527
+ }
528
+
529
+ severities.push(listed);
530
+ }
531
+
532
+ publicForm.severities = severities;
533
+
534
+ const formSeverityId: string = data.form.incidentSeverityId
535
+ ? data.form.incidentSeverityId.toString().toLowerCase()
536
+ : "";
537
+
538
+ const formSeverity: PublicIncidentFormSeverity | undefined =
539
+ severities.find((severity: PublicIncidentFormSeverity): boolean => {
540
+ return severity._id.toLowerCase() === formSeverityId;
541
+ });
542
+
543
+ if (formSeverity) {
544
+ publicForm.defaultIncidentSeverityId = formSeverity._id;
545
+ }
546
+ }
547
+
548
+ return publicForm;
549
+ };
550
+
551
+ type CleanAnswerFunction = (
552
+ field: PublicIncidentFormField,
553
+ value: unknown,
554
+ ) => unknown;
555
+
556
+ /*
557
+ * An answer as it is checked and stored: text cleaned as its field shows
558
+ * it, "true" / "false" as the booleans the dashboard's own checkbox stores,
559
+ * and a multi-select as a list with each option once. Anything else is left
560
+ * for the checks to judge.
561
+ */
562
+ const cleanAnswer: CleanAnswerFunction = (
563
+ field: PublicIncidentFormField,
564
+ value: unknown,
565
+ ): unknown => {
566
+ if (typeof value === "string") {
567
+ switch (field.customFieldType) {
568
+ case CustomFieldType.Text:
569
+ return cleanSingleLine(value);
570
+
571
+ case CustomFieldType.LongText:
572
+ case CustomFieldType.Markdown:
573
+ return cleanMultiLine(value);
574
+
575
+ case CustomFieldType.Boolean: {
576
+ const text: string = cleanScalarText(value);
577
+
578
+ if (text === "true") {
579
+ return true;
580
+ }
581
+
582
+ if (text === "false") {
583
+ return false;
584
+ }
585
+
586
+ return text;
587
+ }
588
+
589
+ case CustomFieldType.MultiSelectDropdown: {
590
+ const text: string = cleanScalarText(value);
591
+
592
+ return text.length > 0 ? [text] : [];
593
+ }
594
+
595
+ default:
596
+ return cleanScalarText(value);
597
+ }
598
+ }
599
+
600
+ if (
601
+ Array.isArray(value) &&
602
+ field.customFieldType === CustomFieldType.MultiSelectDropdown
603
+ ) {
604
+ const entries: Array<unknown> = [];
605
+ const seen: Set<string> = new Set<string>();
606
+
607
+ for (const entry of value) {
608
+ const cleaned: unknown =
609
+ typeof entry === "string" ? cleanScalarText(entry) : entry;
610
+
611
+ if (cleaned === "") {
612
+ continue;
613
+ }
614
+
615
+ const key: string = `${typeof cleaned}:${String(cleaned)}`;
616
+
617
+ if (seen.has(key)) {
618
+ continue;
619
+ }
620
+
621
+ seen.add(key);
622
+ entries.push(cleaned);
623
+ }
624
+
625
+ return entries;
626
+ }
627
+
628
+ return value;
629
+ };
630
+
631
+ type IsTooLongFunction = (value: unknown, maxLength: number) => boolean;
632
+
633
+ // A text answer, or any text entry of a list, longer than the cap.
634
+ const isTooLong: IsTooLongFunction = (
635
+ value: unknown,
636
+ maxLength: number,
637
+ ): boolean => {
638
+ if (typeof value === "string") {
639
+ return value.length > maxLength;
640
+ }
641
+
642
+ if (Array.isArray(value)) {
643
+ return value.some((entry: unknown): boolean => {
644
+ return typeof entry === "string" && entry.length > maxLength;
645
+ });
646
+ }
647
+
648
+ return false;
649
+ };
650
+
651
+ type ValidateAnswersFunction = (data: {
652
+ fields: Array<PublicIncidentFormField>;
653
+ answers: Record<string, unknown>;
654
+ errors: Array<string>;
655
+ }) => JSONObject;
656
+
657
+ type GetMaxChoicesFunction = (field: PublicIncidentFormField) => number;
658
+
659
+ // See INCIDENT_FORM_MULTI_SELECT_MAX_CHOICES.
660
+ const getMaxChoices: GetMaxChoicesFunction = (
661
+ field: PublicIncidentFormField,
662
+ ): number => {
663
+ return Math.max(
664
+ INCIDENT_FORM_MULTI_SELECT_MAX_CHOICES,
665
+ parseCustomFieldDropdownOptions(field.dropdownOptions).length,
666
+ );
667
+ };
668
+
669
+ /*
670
+ * The custom field answers a submission may store. Only the fields the form
671
+ * asks for are read; an answer keyed by any other name is dropped unread.
672
+ */
673
+ const validateAnswers: ValidateAnswersFunction = (data: {
674
+ fields: Array<PublicIncidentFormField>;
675
+ answers: Record<string, unknown>;
676
+ errors: Array<string>;
677
+ }): JSONObject => {
678
+ const accepted: JSONObject = {};
679
+
680
+ for (const field of data.fields) {
681
+ const answer: unknown = hasOwn(data.answers, field.name)
682
+ ? data.answers[field.name]
683
+ : undefined;
684
+
685
+ /*
686
+ * An answer is one value - text, a number, a yes/no - or, for a
687
+ * multi-select, a list of them; nothing the form's page sends is an
688
+ * object. So an object is refused here, unread: checking it against
689
+ * its field (validateCustomFieldValues) would turn all of it into text
690
+ * twice before refusing it, and the request may carry millions of keys
691
+ * or a nesting millions deep, whose conversion alone blocks the server
692
+ * for seconds - a minute, at the body's 50 MB.
693
+ */
694
+ if (
695
+ answer !== null &&
696
+ typeof answer === "object" &&
697
+ !Array.isArray(answer)
698
+ ) {
699
+ data.errors.push(
700
+ fillMessage(
701
+ field.customFieldType === CustomFieldType.MultiSelectDropdown
702
+ ? OBJECT_CHOICES_MESSAGE
703
+ : OBJECT_ANSWER_MESSAGE,
704
+ { field: field.name },
705
+ ),
706
+ );
707
+ continue;
708
+ }
709
+
710
+ /*
711
+ * A list is bounded before anything reads its entries: cleaning,
712
+ * de-duplicating and checking them, and quoting the ones that are not
713
+ * options back in the refusal, all cost as much as the list is long,
714
+ * and the request may carry millions. Only a multi-select takes a list
715
+ * at all, and only as many entries as it could have choices.
716
+ */
717
+ if (Array.isArray(answer) && answer.length > 0) {
718
+ if (field.customFieldType !== CustomFieldType.MultiSelectDropdown) {
719
+ data.errors.push(
720
+ fillMessage(NOT_A_LIST_MESSAGE, { field: field.name }),
721
+ );
722
+ continue;
723
+ }
724
+
725
+ const maxChoices: number = getMaxChoices(field);
726
+
727
+ if (answer.length > maxChoices) {
728
+ data.errors.push(
729
+ fillMessage(TOO_MANY_CHOICES_MESSAGE, {
730
+ field: field.name,
731
+ maxLength: maxChoices,
732
+ }),
733
+ );
734
+ continue;
735
+ }
736
+
737
+ /*
738
+ * Each choice is one option, so a list or an object inside the list
739
+ * is refused here, unread: turning a list nested thousands deep into
740
+ * text, as cleaning and checking the entries would, overflows the
741
+ * stack - a refusal must never become a thrown error.
742
+ */
743
+ if (
744
+ answer.some((entry: unknown): boolean => {
745
+ return entry !== null && typeof entry === "object";
746
+ })
747
+ ) {
748
+ data.errors.push(
749
+ fillMessage(NESTED_CHOICE_MESSAGE, { field: field.name }),
750
+ );
751
+ continue;
752
+ }
753
+ }
754
+
755
+ const value: unknown = cleanAnswer(field, answer);
756
+
757
+ if (isCustomFieldValueEmpty(value)) {
758
+ if (field.isRequired) {
759
+ data.errors.push(
760
+ fillMessage(
761
+ field.customFieldType === CustomFieldType.Boolean
762
+ ? MUST_BE_CHECKED_MESSAGE
763
+ : REQUIRED_MESSAGE,
764
+ { field: field.name },
765
+ ),
766
+ );
767
+ }
768
+
769
+ continue;
770
+ }
771
+
772
+ if (isTooLong(value, INCIDENT_FORM_CUSTOM_FIELD_TEXT_MAX_LENGTH)) {
773
+ data.errors.push(
774
+ fillMessage(TOO_LONG_MESSAGE, {
775
+ field: field.name,
776
+ maxLength: INCIDENT_FORM_CUSTOM_FIELD_TEXT_MAX_LENGTH,
777
+ }),
778
+ );
779
+ continue;
780
+ }
781
+
782
+ const typeErrors: Array<CustomFieldValueValidationError> =
783
+ validateCustomFieldValues({
784
+ definitions: [
785
+ {
786
+ name: field.name,
787
+ customFieldType: field.customFieldType,
788
+ dropdownOptions: field.dropdownOptions,
789
+ },
790
+ ],
791
+ customFields: { [field.name]: value },
792
+ storedCustomFields: {},
793
+ });
794
+
795
+ if (typeErrors.length > 0) {
796
+ data.errors.push(
797
+ ...typeErrors.map((error: CustomFieldValueValidationError): string => {
798
+ return error.message;
799
+ }),
800
+ );
801
+ continue;
802
+ }
803
+
804
+ /*
805
+ * A required yes/no question is an acknowledgement: only a tick answers
806
+ * it, as on the dashboard (CUSTOM_FIELD_MUST_BE_CHECKED_MESSAGE).
807
+ */
808
+ if (
809
+ field.isRequired &&
810
+ field.customFieldType === CustomFieldType.Boolean &&
811
+ value !== true
812
+ ) {
813
+ data.errors.push(
814
+ fillMessage(MUST_BE_CHECKED_MESSAGE, { field: field.name }),
815
+ );
816
+ continue;
817
+ }
818
+
819
+ /*
820
+ * Defined, not assigned: a field may be named "__proto__", and assigning
821
+ * that name would set the object's prototype instead of storing the
822
+ * answer.
823
+ */
824
+ Object.defineProperty(accepted, field.name, {
825
+ value: value as JSONValue,
826
+ enumerable: true,
827
+ writable: true,
828
+ configurable: true,
829
+ });
830
+ }
831
+
832
+ return accepted;
833
+ };
834
+
835
+ /*
836
+ * Email alone finds an address anywhere in a text - "Jane <jane@x.test>"
837
+ * passes it - so the whole answer must also be one ordinary address: the
838
+ * dot-atom half of Email's own pattern, anchored at both ends.
839
+ */
840
+ export const WHOLE_EMAIL_ADDRESS: RegExp =
841
+ /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
842
+
843
+ type ReadTextAnswerFunction = (data: {
844
+ value: unknown;
845
+ label: string;
846
+ clean: CleanTextFunction;
847
+ errors: Array<string>;
848
+ }) => string | null;
849
+
850
+ /*
851
+ * One of the built-in text questions: "" when it was not answered, the
852
+ * cleaned text when it was, and null - with the problem recorded - when the
853
+ * answer is not text at all, so the caller does not also call it missing.
854
+ */
855
+ const readTextAnswer: ReadTextAnswerFunction = (data: {
856
+ value: unknown;
857
+ label: string;
858
+ clean: CleanTextFunction;
859
+ errors: Array<string>;
860
+ }): string | null => {
861
+ if (data.value === undefined || data.value === null) {
862
+ return "";
863
+ }
864
+
865
+ if (typeof data.value !== "string") {
866
+ data.errors.push(`${data.label} must be text.`);
867
+ return null;
868
+ }
869
+
870
+ return data.clean(data.value);
871
+ };
872
+
873
+ type CheckLengthFunction = (data: {
874
+ text: string;
875
+ label: string;
876
+ isRequired: boolean;
877
+ maxLength: number;
878
+ errors: Array<string>;
879
+ }) => void;
880
+
881
+ // Required and too-long checks for a built-in text question.
882
+ const checkLength: CheckLengthFunction = (data: {
883
+ text: string;
884
+ label: string;
885
+ isRequired: boolean;
886
+ maxLength: number;
887
+ errors: Array<string>;
888
+ }): void => {
889
+ if (data.text.length === 0) {
890
+ if (data.isRequired) {
891
+ data.errors.push(fillMessage(REQUIRED_MESSAGE, { field: data.label }));
892
+ }
893
+
894
+ return;
895
+ }
896
+
897
+ if (data.text.length > data.maxLength) {
898
+ data.errors.push(
899
+ fillMessage(TOO_LONG_MESSAGE, {
900
+ field: data.label,
901
+ maxLength: data.maxLength,
902
+ }),
903
+ );
904
+ }
905
+ };
906
+
907
+ export type ValidateIncidentFormSubmissionFunction = (data: {
908
+ form: IncidentFormSubmissionRules;
909
+ // What getIncidentFormAskedDefinitions returns for the form.
910
+ askedDefinitions: Array<IncidentFormAskedDefinition>;
911
+ // The project's severities; only read when the reporter may choose one.
912
+ severities: Array<{ _id: string }>;
913
+ // The `data` of the request body, unread so far.
914
+ data: unknown;
915
+ }) => IncidentFormSubmissionValidationResult;
916
+
917
+ /**
918
+ * Checks a submission against its form and returns either every problem
919
+ * with it, or the answers the incident may be built from. Never throws on a
920
+ * parsed JSON body, whatever it holds.
921
+ *
922
+ * - Title: always required, one line, at most 500 characters.
923
+ * - Description: ignored when the form hides it; required or optional
924
+ * otherwise, at most 20000 characters.
925
+ * - Severity: only read when the form lets the reporter choose, and then it
926
+ * must be one of the project's severities. Leaving it out means the
927
+ * form's own severity.
928
+ * - Name and email: required unless the form says otherwise; when given,
929
+ * the name is at most 100 characters and the email one valid address of
930
+ * at most 100.
931
+ * - Custom fields: only those the form asks, each checked as an API write
932
+ * would be, required ones filled in (a required yes/no ticked), text at
933
+ * most 10000 characters, never an object, a list only for a multi-select
934
+ * and then with at most 100 choices (or as many as it has options), none
935
+ * of them a list or an object. Answers to anything else are dropped.
936
+ *
937
+ * No check costs more for a larger body: text is measured, a list is
938
+ * counted and an object refused before anything reads what they hold.
939
+ */
940
+ export const validateIncidentFormSubmission: ValidateIncidentFormSubmissionFunction =
941
+ (data: {
942
+ form: IncidentFormSubmissionRules;
943
+ askedDefinitions: Array<IncidentFormAskedDefinition>;
944
+ severities: Array<{ _id: string }>;
945
+ data: unknown;
946
+ }): IncidentFormSubmissionValidationResult => {
947
+ if (!isPlainObject(data.data)) {
948
+ return {
949
+ isValid: false,
950
+ errors: [
951
+ "The submission must be an object holding the form's answers.",
952
+ ],
953
+ };
954
+ }
955
+
956
+ const input: Record<string, unknown> = data.data;
957
+ const form: IncidentFormSubmissionRules = data.form || {};
958
+ const labels: IncidentFormQuestionLabels = INCIDENT_FORM_QUESTION_LABELS;
959
+ const errors: Array<string> = [];
960
+
961
+ // Title: always asked, always required.
962
+ const title: string | null = readTextAnswer({
963
+ value: input["title"],
964
+ label: labels.title,
965
+ clean: cleanSingleLine,
966
+ errors: errors,
967
+ });
968
+
969
+ if (title !== null) {
970
+ checkLength({
971
+ text: title,
972
+ label: labels.title,
973
+ isRequired: true,
974
+ maxLength: INCIDENT_FORM_TITLE_MAX_LENGTH,
975
+ errors: errors,
976
+ });
977
+ }
978
+
979
+ // Description: not even read when the form hides it.
980
+ const descriptionSetting: IncidentFormFieldSetting = readDescriptionSetting(
981
+ form.descriptionSetting,
982
+ );
983
+
984
+ let description: string | null = "";
985
+
986
+ if (descriptionSetting !== IncidentFormFieldSetting.Hidden) {
987
+ description = readTextAnswer({
988
+ value: input["description"],
989
+ label: labels.description,
990
+ clean: cleanMultiLine,
991
+ errors: errors,
992
+ });
993
+
994
+ if (description !== null) {
995
+ checkLength({
996
+ text: description,
997
+ label: labels.description,
998
+ isRequired: descriptionSetting === IncidentFormFieldSetting.Required,
999
+ maxLength: INCIDENT_FORM_DESCRIPTION_MAX_LENGTH,
1000
+ errors: errors,
1001
+ });
1002
+ }
1003
+ }
1004
+
1005
+ // Severity: only a choice the form offers, and only when it offers one.
1006
+ let incidentSeverityId: string | undefined = undefined;
1007
+
1008
+ if (form.allowReporterToChooseSeverity === true) {
1009
+ const requested: unknown = input["incidentSeverityId"];
1010
+
1011
+ const isUnanswered: boolean =
1012
+ requested === undefined ||
1013
+ requested === null ||
1014
+ (typeof requested === "string" && requested.trim().length === 0);
1015
+
1016
+ if (!isUnanswered) {
1017
+ const requestedId: string =
1018
+ typeof requested === "string" ? requested.trim().toLowerCase() : "";
1019
+
1020
+ const listed: { _id: string } | undefined = requestedId
1021
+ ? (data.severities || []).find(
1022
+ (severity: { _id: string }): boolean => {
1023
+ return (
1024
+ typeof severity?._id === "string" &&
1025
+ severity._id.toLowerCase() === requestedId
1026
+ );
1027
+ },
1028
+ )
1029
+ : undefined;
1030
+
1031
+ if (listed) {
1032
+ incidentSeverityId = listed._id;
1033
+ } else {
1034
+ errors.push(
1035
+ `${labels.severity} must be one of the severities this form lists.`,
1036
+ );
1037
+ }
1038
+ }
1039
+ }
1040
+
1041
+ // The reporter: required unless the form says otherwise.
1042
+ const detailsRequired: boolean = form.isReporterDetailsRequired !== false;
1043
+
1044
+ const reporterName: string | null = readTextAnswer({
1045
+ value: input["reporterName"],
1046
+ label: labels.reporterName,
1047
+ clean: cleanSingleLine,
1048
+ errors: errors,
1049
+ });
1050
+
1051
+ if (reporterName !== null) {
1052
+ checkLength({
1053
+ text: reporterName,
1054
+ label: labels.reporterName,
1055
+ isRequired: detailsRequired,
1056
+ maxLength: INCIDENT_FORM_REPORTER_NAME_MAX_LENGTH,
1057
+ errors: errors,
1058
+ });
1059
+ }
1060
+
1061
+ let reporterEmail: string | null = readTextAnswer({
1062
+ value: input["reporterEmail"],
1063
+ label: labels.reporterEmail,
1064
+ clean: cleanScalarText,
1065
+ errors: errors,
1066
+ });
1067
+
1068
+ if (reporterEmail !== null) {
1069
+ const errorCount: number = errors.length;
1070
+
1071
+ checkLength({
1072
+ text: reporterEmail,
1073
+ label: labels.reporterEmail,
1074
+ isRequired: detailsRequired,
1075
+ maxLength: INCIDENT_FORM_REPORTER_EMAIL_MAX_LENGTH,
1076
+ errors: errors,
1077
+ });
1078
+
1079
+ if (reporterEmail.length > 0 && errors.length === errorCount) {
1080
+ if (
1081
+ WHOLE_EMAIL_ADDRESS.test(reporterEmail) &&
1082
+ Email.isValid(reporterEmail)
1083
+ ) {
1084
+ reporterEmail = new Email(reporterEmail).toString();
1085
+ } else {
1086
+ errors.push(`${labels.reporterEmail} is not a valid email address.`);
1087
+ }
1088
+ }
1089
+ }
1090
+
1091
+ // Custom fields: only the ones the form asks for are read.
1092
+ const rawAnswers: unknown = input["customFields"];
1093
+ let answers: Record<string, unknown> = {};
1094
+
1095
+ if (isPlainObject(rawAnswers)) {
1096
+ answers = rawAnswers;
1097
+ } else if (rawAnswers !== undefined && rawAnswers !== null) {
1098
+ errors.push(
1099
+ "The custom field answers must be an object keyed by field name.",
1100
+ );
1101
+ }
1102
+
1103
+ const customFields: JSONObject = validateAnswers({
1104
+ fields: getPublicIncidentFormFields(data.askedDefinitions || []),
1105
+ answers: answers,
1106
+ errors: errors,
1107
+ });
1108
+
1109
+ if (errors.length > 0) {
1110
+ return { isValid: false, errors: errors };
1111
+ }
1112
+
1113
+ const value: ValidatedIncidentFormSubmission = {
1114
+ title: title || "",
1115
+ customFields: customFields,
1116
+ };
1117
+
1118
+ if (description) {
1119
+ value.description = description;
1120
+ }
1121
+
1122
+ if (incidentSeverityId) {
1123
+ value.incidentSeverityId = incidentSeverityId;
1124
+ }
1125
+
1126
+ if (reporterName) {
1127
+ value.reporterName = reporterName;
1128
+ }
1129
+
1130
+ if (reporterEmail) {
1131
+ value.reporterEmail = reporterEmail;
1132
+ }
1133
+
1134
+ return { isValid: true, value: value };
1135
+ };
1136
+
1137
+ export type FormatIncidentFormSubmissionErrorsFunction = (
1138
+ errors: Array<string>,
1139
+ ) => string;
1140
+
1141
+ /** Every problem as one message, for an API error response. */
1142
+ export const formatIncidentFormSubmissionErrors: FormatIncidentFormSubmissionErrorsFunction =
1143
+ (errors: Array<string>): string => {
1144
+ return errors.join(" ");
1145
+ };