@oneuptime/common 14.0.11 → 14.0.12

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 (1406) hide show
  1. package/Models/AnalyticsModels/AuditLog.ts +63 -0
  2. package/Models/AnalyticsModels/Log.ts +26 -3
  3. package/Models/AnalyticsModels/Metric.ts +28 -3
  4. package/Models/AnalyticsModels/MetricItemAggMV1m.ts +21 -3
  5. package/Models/AnalyticsModels/SloHistory.ts +6 -4
  6. package/Models/DatabaseModels/AutoRemediationRule.ts +1 -1
  7. package/Models/DatabaseModels/CodeRepository.ts +1 -1
  8. package/Models/DatabaseModels/Dashboard.ts +148 -0
  9. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +11 -0
  10. package/Models/DatabaseModels/DatabaseServerEndpoint.ts +1 -0
  11. package/Models/DatabaseModels/EnterpriseLicense.ts +2 -0
  12. package/Models/DatabaseModels/EnterpriseLicenseInstance.ts +1 -0
  13. package/Models/DatabaseModels/IncomingCallLog.ts +13 -0
  14. package/Models/DatabaseModels/Index.ts +6 -0
  15. package/Models/DatabaseModels/LlmModelPrice.ts +1 -0
  16. package/Models/DatabaseModels/McpOAuthClient.ts +191 -0
  17. package/Models/DatabaseModels/McpOAuthGrant.ts +464 -0
  18. package/Models/DatabaseModels/McpOAuthToken.ts +228 -0
  19. package/Models/DatabaseModels/Monitor.ts +157 -0
  20. package/Models/DatabaseModels/MonitorSecret.ts +93 -1
  21. package/Models/DatabaseModels/NetworkEndpoint.ts +1 -0
  22. package/Models/DatabaseModels/OnCallDutyPolicy.ts +155 -0
  23. package/Models/DatabaseModels/Project.ts +44 -101
  24. package/Models/DatabaseModels/StatusPage.ts +155 -0
  25. package/Models/DatabaseModels/TelemetrySourceMap.ts +1 -0
  26. package/Models/DatabaseModels/Workflow.ts +226 -7
  27. package/Server/API/AIAgentDataAPI.ts +1 -1
  28. package/Server/API/AutoRemediationAPI.ts +9 -41
  29. package/Server/API/CommonAPI.ts +19 -0
  30. package/Server/API/DashboardAPI.ts +7 -3
  31. package/Server/API/StatusPageAPI.ts +143 -89
  32. package/Server/EnvironmentConfig.ts +27 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1796800000000-FoldAiSwitchesIntoEnableAi.ts +105 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1796900000000-AddMcpOAuthTables.ts +97 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1797000000000-AddWorkflowIncomingEmailSecretKey.ts +36 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1797100000000-AddMonitorSecretAccess.ts +55 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1797200000000-AddArchiveToMoreResources.ts +167 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  39. package/Server/Middleware/McpDelegationAuthorization.ts +204 -0
  40. package/Server/Middleware/McpOAuthRateLimit.ts +287 -0
  41. package/Server/Middleware/ProjectAuthorization.ts +23 -2
  42. package/Server/Middleware/UserAuthorization.ts +12 -0
  43. package/Server/Services/AIService.ts +2 -2
  44. package/Server/Services/AnalyticsDatabaseService.ts +22 -5
  45. package/Server/Services/ApiKeyService.ts +31 -7
  46. package/Server/Services/AutoRemediationRuleEngineService.ts +15 -27
  47. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  48. package/Server/Services/DashboardService.ts +7 -2
  49. package/Server/Services/DatabaseServerService.ts +219 -0
  50. package/Server/Services/DatabaseService.ts +29 -32
  51. package/Server/Services/InboundEmail/InboundEmailProvider.ts +44 -0
  52. package/Server/Services/InboundEmail/Providers/SendGridInboundProvider.ts +57 -1
  53. package/Server/Services/IncomingCallMissedCallNotificationService.ts +280 -0
  54. package/Server/Services/IncomingCallPolicyService.ts +118 -0
  55. package/Server/Services/Index.ts +8 -0
  56. package/Server/Services/KubernetesClusterAiAccessService.ts +10 -47
  57. package/Server/Services/KubernetesClusterService.ts +3 -3
  58. package/Server/Services/LogAggregationService.ts +38 -5
  59. package/Server/Services/McpOAuthClientService.ts +148 -0
  60. package/Server/Services/McpOAuthGrantService.ts +275 -0
  61. package/Server/Services/McpOAuthTokenService.ts +213 -0
  62. package/Server/Services/MetricAggregationService.ts +4 -4
  63. package/Server/Services/MonitorGroupService.ts +49 -28
  64. package/Server/Services/MonitorProbeService.ts +1 -0
  65. package/Server/Services/MonitorSecretService.ts +425 -0
  66. package/Server/Services/MonitorService.ts +15 -1
  67. package/Server/Services/OnCallDutyPolicyService.ts +36 -2
  68. package/Server/Services/ProjectService.ts +53 -24
  69. package/Server/Services/ResourceAiAccessService.ts +3 -14
  70. package/Server/Services/RunnerJobService.ts +2 -2
  71. package/Server/Services/RunnerService.ts +2 -2
  72. package/Server/Services/StatusPageService.ts +66 -8
  73. package/Server/Services/StatusPageSubscriberService.ts +23 -0
  74. package/Server/Services/TeamMemberService.ts +352 -84
  75. package/Server/Services/UserNotificationSettingService.ts +20 -0
  76. package/Server/Services/WorkflowService.ts +31 -0
  77. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +6 -0
  78. package/Server/Types/Database/Permissions/Index.ts +10 -0
  79. package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +2 -0
  80. package/Server/Types/Workflow/Components/Conditions/IfElse.ts +36 -138
  81. package/Server/Types/Workflow/Components/IncomingEmail.ts +216 -0
  82. package/Server/Types/Workflow/Components/Index.ts +32 -18
  83. package/Server/Types/Workflow/Components/Schedule.ts +25 -4
  84. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +1 -1
  85. package/Server/Utils/AI/CodeFix/CodeFixRunQueue.ts +1 -1
  86. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +58 -50
  87. package/Server/Utils/AI/CodeFix/OpenPullRequestCap.ts +25 -19
  88. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +15 -68
  89. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +37 -53
  90. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +8 -8
  91. package/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.ts +1 -1
  92. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +12 -19
  93. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +6 -5
  94. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -3
  95. package/Server/Utils/AI/SRE/Insights/InsightScanner.ts +5 -5
  96. package/Server/Utils/AI/SRE/Insights/Triage.ts +6 -5
  97. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +8 -7
  98. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +1 -1
  99. package/Server/Utils/AI/SRE/InvestigationQueue.ts +65 -57
  100. package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
  101. package/Server/Utils/AI/Toolbox/AIActionTools.ts +11 -1
  102. package/Server/Utils/AI/Toolbox/AIMetaTools.ts +14 -8
  103. package/Server/Utils/AI/Toolbox/MonitorTools.ts +21 -3
  104. package/Server/Utils/AI/Toolbox/OnCallTools.ts +43 -9
  105. package/Server/Utils/AI/Toolbox/StatusPageTools.ts +36 -7
  106. package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +26 -7
  107. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +3 -1
  108. package/Server/Utils/Express.ts +23 -0
  109. package/Server/Utils/IncomingCall/MissedCallNotification.ts +322 -0
  110. package/Server/Utils/Mcp/McpDelegationToken.ts +171 -0
  111. package/Server/Utils/Mcp/McpOAuthConfig.ts +191 -0
  112. package/Server/Utils/Mcp/McpOAuthGrantAccess.ts +303 -0
  113. package/Server/Utils/Mcp/McpOAuthSecret.ts +149 -0
  114. package/Server/Utils/Mcp/McpOAuthSignedToken.ts +225 -0
  115. package/Server/Utils/Mcp/McpOAuthSso.ts +274 -0
  116. package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +43 -0
  117. package/Server/Utils/Monitor/MonitorResource.ts +16 -3
  118. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +5 -8
  119. package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +3 -3
  120. package/Server/Utils/Slo/SloMetricUtil.ts +3 -3
  121. package/Server/Utils/Telemetry/DatabaseEndpointDiscovery.ts +11 -3
  122. package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +7 -0
  123. package/Server/Utils/Telemetry/ServiceDependencyDiscovery.ts +171 -17
  124. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +2 -0
  125. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +2 -0
  126. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +2 -0
  127. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +2 -0
  128. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +4 -0
  129. package/Server/Utils/Workspace/Slack/Actions/Alert.ts +2 -0
  130. package/Server/Utils/Workspace/Slack/Actions/AlertEpisode.ts +2 -0
  131. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +4 -0
  132. package/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.ts +2 -0
  133. package/Tests/App/Accounts/LoginPasskey.test.tsx +27 -0
  134. package/Tests/App/Accounts/McpAuthorizePage.test.tsx +2034 -0
  135. package/Tests/App/AdvancedMenuSectionsCollapsed.test.tsx +446 -0
  136. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +55 -19
  137. package/Tests/App/Dashboard/AIInvestigationSettingsLimits.test.tsx +451 -0
  138. package/Tests/App/Dashboard/AIInvestigationStage.test.ts +141 -0
  139. package/Tests/App/Dashboard/AiAccessModes.test.ts +261 -0
  140. package/Tests/App/Dashboard/AiAccessRow.test.tsx +401 -0
  141. package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +19 -6
  142. package/Tests/App/Dashboard/AlertsSideMenu.test.tsx +76 -33
  143. package/Tests/App/Dashboard/AnswerSources.test.tsx +359 -0
  144. package/Tests/App/Dashboard/ArchivableResourceListPages.test.tsx +655 -0
  145. package/Tests/App/Dashboard/ArchivedResourceBanner.test.tsx +543 -0
  146. package/Tests/App/Dashboard/ArchivedResourceNavigation.test.tsx +634 -0
  147. package/Tests/App/Dashboard/ArchivedResourceViewLayouts.test.tsx +321 -0
  148. package/Tests/App/Dashboard/BulkChangeStateModalSteps.test.ts +109 -0
  149. package/Tests/App/Dashboard/CodeProduct.test.tsx +194 -0
  150. package/Tests/App/Dashboard/ConversationComposer.test.tsx +439 -0
  151. package/Tests/App/Dashboard/CoreListEmptyStates.test.tsx +5 -3
  152. package/Tests/App/Dashboard/CorrelateResultSummary.test.tsx +15 -3
  153. package/Tests/App/Dashboard/CreateOAuthWorkflowVariableFormSteps.test.tsx +925 -0
  154. package/Tests/App/Dashboard/CreateOAuthWorkflowVariableModal.test.tsx +267 -20
  155. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +493 -100
  156. package/Tests/App/Dashboard/DangerZone.test.tsx +146 -3
  157. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +0 -3
  158. package/Tests/App/Dashboard/DeleteDialogsNameTheResource.test.tsx +257 -0
  159. package/Tests/App/Dashboard/DeveloperDocsGuides.test.ts +458 -0
  160. package/Tests/App/Dashboard/DeveloperDocsLocales.test.ts +124 -0
  161. package/Tests/App/Dashboard/DeveloperDocsPage.test.tsx +471 -0
  162. package/Tests/App/Dashboard/DeveloperMenuSections.test.tsx +657 -0
  163. package/Tests/App/Dashboard/DisabledWarningArchived.test.tsx +196 -0
  164. package/Tests/App/Dashboard/DiscoveryScanEditForm.test.tsx +52 -82
  165. package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +67 -0
  166. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +47 -0
  167. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +2 -1
  168. package/Tests/App/Dashboard/HomeOverviewStatsFirstRun.test.tsx +19 -2
  169. package/Tests/App/Dashboard/IncidentAlertLinkSideMenus.test.tsx +3 -1
  170. package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +19 -6
  171. package/Tests/App/Dashboard/IncidentsSideMenu.test.tsx +82 -49
  172. package/Tests/App/Dashboard/InventoryItemSideMenu.test.tsx +1 -0
  173. package/Tests/App/Dashboard/InvestigationConversation.test.tsx +1401 -43
  174. package/Tests/App/Dashboard/InvestigationConversationData.test.ts +452 -0
  175. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +134 -1
  176. package/Tests/App/Dashboard/InvestigationNotice.test.tsx +300 -0
  177. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +525 -53
  178. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +106 -30
  179. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +743 -9
  180. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +838 -81
  181. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +958 -7
  182. package/Tests/App/Dashboard/McpAuthorizationResume.test.tsx +495 -0
  183. package/Tests/App/Dashboard/McpServerPage.test.tsx +1106 -0
  184. package/Tests/App/Dashboard/MessageQueueSideMenus.test.tsx +16 -4
  185. package/Tests/App/Dashboard/MonitorCriteriaAdvancedOptions.test.tsx +267 -0
  186. package/Tests/App/Dashboard/MonitorOverviewInput.test.ts +3 -0
  187. package/Tests/App/Dashboard/MonitorSecretsAccessForm.test.tsx +727 -0
  188. package/Tests/App/Dashboard/MonitorViewLayout.test.tsx +37 -0
  189. package/Tests/App/Dashboard/MovedRunnerSettingsRedirects.test.tsx +345 -0
  190. package/Tests/App/Dashboard/NavigationSearchKeywords.test.tsx +4 -1
  191. package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +36 -4
  192. package/Tests/App/Dashboard/NotificationRuleFormParts.test.tsx +247 -0
  193. package/Tests/App/Dashboard/OAuthIdentityProviders.test.tsx +589 -0
  194. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +12 -1
  195. package/Tests/App/Dashboard/PermissionModePicker.test.tsx +316 -0
  196. package/Tests/App/Dashboard/ProductMenuBreadcrumbs.test.tsx +83 -39
  197. package/Tests/App/Dashboard/ProductOrientation.test.tsx +37 -4
  198. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +244 -76
  199. package/Tests/App/Dashboard/RecommendationsLoadedContext.test.tsx +57 -1
  200. package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +190 -23
  201. package/Tests/App/Dashboard/ResourceAiAgentAttentionServerParity.test.ts +5 -11
  202. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +458 -103
  203. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +8 -4
  204. package/Tests/App/Dashboard/ResourceArchiveCopy.test.ts +218 -0
  205. package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +16 -2
  206. package/Tests/App/Dashboard/RumSessionReplaySideMenu.test.tsx +1 -0
  207. package/Tests/App/Dashboard/RunbookRunnerRoutes.test.tsx +403 -0
  208. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +26 -17
  209. package/Tests/App/Dashboard/RunnerNavigation.test.tsx +577 -0
  210. package/Tests/App/Dashboard/RunnerPagesInRunbooksFlow.test.tsx +581 -0
  211. package/Tests/App/Dashboard/RunnerProductSearch.test.tsx +195 -0
  212. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +19 -6
  213. package/Tests/App/Dashboard/ScheduledMaintenanceSideMenu.test.tsx +2 -1
  214. package/Tests/App/Dashboard/SecurityEventSeverityPill.test.tsx +39 -15
  215. package/Tests/App/Dashboard/SloListSideMenu.test.tsx +2 -1
  216. package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +20 -1
  217. package/Tests/App/Dashboard/SloViewSideMenu.test.tsx +14 -2
  218. package/Tests/App/Dashboard/TelemetryIngestionKeyEdit.test.tsx +107 -13
  219. package/Tests/App/Dashboard/UserElementEmail.test.tsx +50 -0
  220. package/Tests/App/Dashboard/UserSettingsEmailPreferences.test.tsx +42 -8
  221. package/Tests/App/Dashboard/UserSettingsNotificationSettings.test.tsx +51 -1
  222. package/Tests/App/Dashboard/WorkflowBuilderArchived.test.tsx +490 -0
  223. package/Tests/App/Dashboard/WorkflowBuilderIncomingEmailSecretKey.test.tsx +436 -0
  224. package/Tests/App/Dashboard/WorkflowBuilderRunDownload.test.tsx +416 -0
  225. package/Tests/App/Dashboard/WorkflowBuilderTurnOn.test.tsx +828 -0
  226. package/Tests/App/Dashboard/WorkflowBuilderWebhookSecretKey.test.tsx +499 -0
  227. package/Tests/App/Dashboard/WorkflowRunsLogsMenus.test.tsx +758 -0
  228. package/Tests/App/Dashboard/WorkflowRunsPages.test.tsx +507 -0
  229. package/Tests/App/Dashboard/WorkflowSettingsPage.test.tsx +172 -0
  230. package/Tests/App/Dashboard/WorkflowTemplatePicker.test.tsx +1425 -0
  231. package/Tests/App/Dashboard/WorkflowVariableCreateFormSteps.test.tsx +473 -0
  232. package/Tests/App/Dashboard/WorkflowVariableOAuthSettingsEditSteps.test.tsx +390 -0
  233. package/Tests/App/Dashboard/WorkflowVariableUtil.test.ts +357 -30
  234. package/Tests/App/Dashboard/WorkflowVariableView.test.tsx +49 -0
  235. package/Tests/App/Dashboard/WorkflowVariablesTable.test.tsx +72 -2
  236. package/Tests/App/Dashboard/WorkspaceNotificationRuleFormSteps.test.tsx +499 -0
  237. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +31 -0
  238. package/Tests/DialogActionRules.ts +1696 -0
  239. package/Tests/Helpers/FormStepsScan.ts +1917 -0
  240. package/Tests/Helpers/ToggleUsageScan.ts +302 -0
  241. package/Tests/Models/AnalyticsModels/TelemetryTtlSettings.test.ts +164 -0
  242. package/Tests/Models/DatabaseModels/ArchivableResourceModels.test.ts +475 -0
  243. package/Tests/Models/DatabaseModels/IncomingCallLogWorkflow.test.ts +130 -0
  244. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +0 -1
  245. package/Tests/Models/DatabaseModels/WorkflowIncomingEmailSecretKeyAccessControl.test.ts +252 -0
  246. package/Tests/Models/DatabaseModels/WorkflowWebhookSecretKeyAccessControl.test.ts +223 -0
  247. package/Tests/Models/McpOAuthModels.test.ts +951 -0
  248. package/Tests/Server/API/AIInvestigationAPI.test.ts +6 -4
  249. package/Tests/Server/API/ArchivedPublicRoutes.test.ts +481 -0
  250. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +144 -105
  251. package/Tests/Server/API/AutoRemediationApproveEnableAiGate.test.ts +816 -0
  252. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +37 -5
  253. package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +68 -57
  254. package/Tests/Server/API/CommonAPIAuditIdentityProps.test.ts +468 -0
  255. package/Tests/Server/API/ResourceAiAccessAPI.test.ts +0 -4
  256. package/Tests/Server/API/StatusPagePublicReadsLeaveOutArchivedMonitors.test.ts +126 -0
  257. package/Tests/Server/Infrastructure/Postgres/AddArchiveToMoreResourcesMigration.test.ts +200 -0
  258. package/Tests/Server/Infrastructure/Postgres/FoldAiSwitchesIntoEnableAiMigration.test.ts +543 -0
  259. package/Tests/Server/Infrastructure/Postgres/FoldAiSwitchesIntoEnableAiPostgres.test.ts +862 -0
  260. package/Tests/Server/Middleware/McpDelegationAuthorization.test.ts +862 -0
  261. package/Tests/Server/Middleware/McpOAuthRateLimit.test.ts +959 -0
  262. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyIdentity.test.ts +361 -0
  263. package/Tests/Server/Middleware/UserAuthorizationMcpDelegation.test.ts +568 -0
  264. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +60 -0
  265. package/Tests/Server/Services/AddMcpOAuthTablesMigration.test.ts +616 -0
  266. package/Tests/Server/Services/AiAccessEnableAiMasterSwitch.test.ts +761 -0
  267. package/Tests/Server/Services/AnalyticsDatabaseServiceReadOnlyCredentialBeforeHooks.test.ts +224 -0
  268. package/Tests/Server/Services/ApiKeyServiceResolvedName.test.ts +307 -0
  269. package/Tests/Server/Services/ArchivedStatusPageAndDashboardAccess.test.ts +505 -0
  270. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +61 -4
  271. package/Tests/Server/Services/AutoRemediationCommandRuleEngine.test.ts +64 -13
  272. package/Tests/Server/Services/AutoRemediationEnableAiMasterSwitch.test.ts +767 -0
  273. package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +47 -8
  274. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +1 -1
  275. package/Tests/Server/Services/AutoRemediationRuleEngineService.test.ts +48 -6
  276. package/Tests/Server/Services/DatabaseServerService.test.ts +420 -0
  277. package/Tests/Server/Services/DatabaseServerSqlPostgres.test.ts +296 -2
  278. package/Tests/Server/Services/DatabaseServiceReadOnlyCredentialBeforeHooks.test.ts +396 -0
  279. package/Tests/Server/Services/InboundEmail/SendGridInboundProviderRecipients.test.ts +172 -0
  280. package/Tests/Server/Services/IncomingCallMissedCallNotificationService.test.ts +690 -0
  281. package/Tests/Server/Services/IncomingCallPolicyFindOwners.test.ts +287 -0
  282. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +4 -3
  283. package/Tests/Server/Services/KubernetesClusterAiAccessAgentRunnerAssignments.test.ts +1 -1
  284. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +2 -4
  285. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +26 -13
  286. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +180 -44
  287. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +14 -10
  288. package/Tests/Server/Services/LogAggregationService.test.ts +101 -1
  289. package/Tests/Server/Services/McpOAuthClientService.test.ts +562 -0
  290. package/Tests/Server/Services/McpOAuthGrantService.test.ts +899 -0
  291. package/Tests/Server/Services/McpOAuthPostgres.test.ts +942 -0
  292. package/Tests/Server/Services/McpOAuthTokenService.test.ts +782 -0
  293. package/Tests/Server/Services/MonitorGroupServiceBatchedStatuses.test.ts +35 -1
  294. package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +35 -0
  295. package/Tests/Server/Services/MonitorSecretAccessPostgres.test.ts +883 -0
  296. package/Tests/Server/Services/MonitorSecretService.test.ts +1097 -0
  297. package/Tests/Server/Services/OnCallDutyPolicyArchive.test.ts +157 -0
  298. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +132 -82
  299. package/Tests/Server/Services/ResourceAiAccessService.test.ts +28 -14
  300. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +0 -2
  301. package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +5 -0
  302. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +13 -1
  303. package/Tests/Server/Services/TeamMemberInvitationAcceptancePostgres.test.ts +942 -0
  304. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +6 -1
  305. package/Tests/Server/Services/TeamMemberProjectInvitationAcceptance.test.ts +1256 -0
  306. package/Tests/Server/Services/TeamMemberSeatLimitExistingMember.test.ts +498 -0
  307. package/Tests/Server/Services/UserNotificationSettingIncomingCallDefaults.test.ts +190 -0
  308. package/Tests/Server/Services/WorkflowIncomingEmailSecretKeyPostgres.test.ts +323 -0
  309. package/Tests/Server/Services/WorkflowService.test.ts +188 -0
  310. package/Tests/Server/Types/Workflow/Components/CustomCodeScriptError.test.ts +19 -20
  311. package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +357 -66
  312. package/Tests/Server/Types/Workflow/Components/IncomingEmailTrigger.test.ts +670 -0
  313. package/Tests/Server/Types/Workflow/Components/TriggersSkipArchivedWorkflows.test.ts +257 -0
  314. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +317 -184
  315. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +47 -23
  316. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +142 -12
  317. package/Tests/Server/Utils/AI/AIMetaTools.test.ts +31 -0
  318. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +2 -0
  319. package/Tests/Server/Utils/AI/ArchivedResourcesInAITools.test.ts +622 -0
  320. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +30 -1
  321. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +5 -4
  322. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +202 -98
  323. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +1 -1
  324. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +1 -1
  325. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +102 -58
  326. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +24 -0
  327. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +41 -5
  328. package/Tests/Server/Utils/AI/OpenPullRequestCap.test.ts +62 -22
  329. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +14 -10
  330. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +205 -104
  331. package/Tests/Server/Utils/AI/RemediationExecutionRunnerEnableAiGate.test.ts +598 -0
  332. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +94 -158
  333. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +48 -66
  334. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +0 -4
  335. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +8 -1
  336. package/Tests/Server/Utils/IncomingCall/MissedCallNotification.test.ts +555 -0
  337. package/Tests/Server/Utils/Mcp/McpDelegationToken.test.ts +677 -0
  338. package/Tests/Server/Utils/Mcp/McpOAuthConfig.test.ts +549 -0
  339. package/Tests/Server/Utils/Mcp/McpOAuthGrantAccess.test.ts +1476 -0
  340. package/Tests/Server/Utils/Mcp/McpOAuthSecret.test.ts +721 -0
  341. package/Tests/Server/Utils/Mcp/McpOAuthSignedToken.test.ts +1042 -0
  342. package/Tests/Server/Utils/Mcp/McpOAuthSso.test.ts +1399 -0
  343. package/Tests/Server/Utils/Monitor/GeneratedInboundAddressRedaction.test.ts +109 -0
  344. package/Tests/Server/Utils/Monitor/MonitorPauseFlagsGuard.test.ts +237 -0
  345. package/Tests/Server/Utils/Monitor/MonitorResourceArchived.test.ts +165 -0
  346. package/Tests/Server/Utils/Telemetry/DatabaseEndpointDiscovery.test.ts +262 -0
  347. package/Tests/Server/Utils/Telemetry/ServiceDependencyDiscovery.test.ts +976 -77
  348. package/Tests/Server/Utils/Topology/TopologyConcurrencyLimiter.test.ts +94 -39
  349. package/Tests/Server/Utils/Workspace/ArchivedOnCallPoliciesNotOffered.test.ts +133 -0
  350. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +10 -3
  351. package/Tests/Types/AI/AIWorkloadLimits.test.ts +101 -0
  352. package/Tests/Types/BaseDatabase/ReadOnlyCredential.test.ts +931 -0
  353. package/Tests/Types/Call/CallProvider.test.ts +54 -1
  354. package/Tests/Types/DatabaseServer/DatabaseEndpoint.test.ts +227 -1
  355. package/Tests/Types/IncomingCall/MissedIncomingCall.test.ts +137 -0
  356. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +23 -0
  357. package/Tests/Types/Mcp/McpOAuthScope.test.ts +491 -0
  358. package/Tests/Types/Monitor/MonitorSecretAccess.test.ts +347 -0
  359. package/Tests/Types/NotificationSetting/IncomingCallMissedNotificationEvent.test.ts +77 -0
  360. package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +5 -5
  361. package/Tests/Types/Workflow/BaseModelComponents.test.ts +56 -50
  362. package/Tests/Types/Workflow/ComponentDocumentation.test.ts +1396 -0
  363. package/Tests/Types/Workflow/Components/BaseModelWriteSteps.test.ts +158 -0
  364. package/Tests/Types/Workflow/Components/JSON.test.ts +6 -2
  365. package/Tests/Types/Workflow/ConditionEvaluation.test.ts +793 -0
  366. package/Tests/Types/Workflow/DocumentationText.test.ts +169 -0
  367. package/Tests/Types/Workflow/IncomingEmailTrigger.test.ts +446 -0
  368. package/Tests/Types/Workflow/IncomingEmailTriggerDocumentation.test.ts +174 -0
  369. package/Tests/Types/Workflow/StepSamples.test.ts +846 -0
  370. package/Tests/Types/Workflow/StepTrace.test.ts +128 -0
  371. package/Tests/Types/Workflow/StepTraceValueSample.test.ts +205 -0
  372. package/Tests/Types/Workflow/SystemColumns.test.ts +114 -0
  373. package/Tests/Types/Workflow/Templates.test.ts +345 -0
  374. package/Tests/Types/Workflow/WebhookTrigger.test.ts +221 -0
  375. package/Tests/Types/Workflow/WorkflowEnabled.test.ts +107 -0
  376. package/Tests/Types/Workspace/NotificationRuleValidationHalves.test.ts +217 -0
  377. package/Tests/UI/Components/ActionButton/RowActionsTrigger.test.tsx +748 -0
  378. package/Tests/UI/Components/BasicFormModalSteps.test.tsx +113 -0
  379. package/Tests/UI/Components/BulkUpdateFormConfirmDetails.test.tsx +148 -0
  380. package/Tests/UI/Components/Button.test.tsx +52 -13
  381. package/Tests/UI/Components/Card.test.tsx +211 -2
  382. package/Tests/UI/Components/CodeEditor/CodeEditorToolbarActions.test.tsx +121 -0
  383. package/Tests/UI/Components/CollapsibleSection.test.tsx +152 -0
  384. package/Tests/UI/Components/ComponentsModal.test.tsx +555 -930
  385. package/Tests/UI/Components/ComponentsModalUsability.test.tsx +279 -401
  386. package/Tests/UI/Components/ConfirmModal.test.tsx +195 -0
  387. package/Tests/UI/Components/DeleteConfirmation/DeleteConfirmation.test.tsx +524 -0
  388. package/Tests/UI/Components/Detail/DropdownColors.test.tsx +11 -9
  389. package/Tests/UI/Components/Detail/EntityFields.test.tsx +10 -4
  390. package/Tests/UI/Components/DictionaryRenderTextValueInput.test.tsx +94 -0
  391. package/Tests/UI/Components/Dropdown/DropdownValueBadge.test.tsx +79 -10
  392. package/Tests/UI/Components/Forms/BasicFormSubmitAllSteps.test.tsx +293 -0
  393. package/Tests/UI/Components/Forms/FormFieldCheckboxTranslation.test.tsx +14 -12
  394. package/Tests/UI/Components/Forms/FormFieldCustomElementLabel.test.tsx +156 -0
  395. package/Tests/UI/Components/Forms/FormFieldDictionaryError.test.tsx +198 -0
  396. package/Tests/UI/Components/Forms/FormFieldLongText.test.tsx +200 -0
  397. package/Tests/UI/Components/Forms/FormFieldToggleRow.test.tsx +388 -0
  398. package/Tests/UI/Components/Forms/LongFormStepsGuard.test.ts +586 -0
  399. package/Tests/UI/Components/Forms/ModelFormFormOnlyFields.test.tsx +254 -0
  400. package/Tests/UI/Components/Forms/OverloadedFormStepsGuard.test.ts +505 -0
  401. package/Tests/UI/Components/Forms/ValidationRequiredWhen.test.ts +122 -0
  402. package/Tests/UI/Components/Icon.test.tsx +43 -0
  403. package/Tests/UI/Components/Modal.test.tsx +495 -1
  404. package/Tests/UI/Components/ModalSecondaryButton.test.tsx +122 -0
  405. package/Tests/UI/Components/ModelCardPermissionGating.test.tsx +13 -9
  406. package/Tests/UI/Components/ModelDelete.test.tsx +7 -0
  407. package/Tests/UI/Components/ModelDeleteNames.test.tsx +784 -0
  408. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteAndEmptyStates.test.tsx +9 -2
  409. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteConfirmation.test.tsx +4 -1
  410. package/Tests/UI/Components/ModelTable/BaseModelTableDeleteNames.test.tsx +573 -0
  411. package/Tests/UI/Components/ModelTable/BaseModelTableEmptyStateAction.test.tsx +30 -9
  412. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +6 -3
  413. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +20 -14
  414. package/Tests/UI/Components/NavBar.test.tsx +45 -0
  415. package/Tests/UI/Components/Pill.test.tsx +369 -50
  416. package/Tests/UI/Components/PillColors.test.ts +524 -0
  417. package/Tests/UI/Components/SideMenu.test.tsx +461 -0
  418. package/Tests/UI/Components/SideMenuSection.test.tsx +200 -0
  419. package/Tests/UI/Components/SideMenuSectionState.test.tsx +362 -0
  420. package/Tests/UI/Components/SteppedEditFormSave.test.tsx +499 -0
  421. package/Tests/UI/Components/TableRowActions.test.tsx +110 -0
  422. package/Tests/UI/Components/TextAreaAutoGrow.test.tsx +387 -0
  423. package/Tests/UI/Components/Toggle.test.tsx +846 -6
  424. package/Tests/UI/Components/ToggleUsageGuard.test.ts +274 -0
  425. package/Tests/UI/Components/Workflow/ArgumentInputTypes.test.ts +710 -0
  426. package/Tests/UI/Components/Workflow/ArgumentsForm.test.tsx +934 -0
  427. package/Tests/UI/Components/Workflow/ArgumentsFormAdvancedSettings.test.tsx +207 -0
  428. package/Tests/UI/Components/Workflow/BreakableCode.test.tsx +153 -0
  429. package/Tests/UI/Components/Workflow/ColumnEditor/AddColumnPicker.test.tsx +685 -0
  430. package/Tests/UI/Components/Workflow/ColumnEditor/AddColumnPickerDarkMode.test.ts +252 -0
  431. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnControl.test.ts +207 -5
  432. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnPickerOptions.test.ts +570 -0
  433. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnUse.test.ts +248 -0
  434. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnValueInputLongText.test.tsx +90 -0
  435. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnValueInputValuePicker.test.tsx +282 -0
  436. package/Tests/UI/Components/Workflow/Component.test.tsx +465 -0
  437. package/Tests/UI/Components/Workflow/ComponentPicker/ComponentPickerDarkMode.test.ts +239 -0
  438. package/Tests/UI/Components/Workflow/ComponentPicker/ComponentPickerRealCatalog.test.tsx +399 -0
  439. package/Tests/UI/Components/Workflow/ComponentPicker/ComponentSearch.test.ts +660 -0
  440. package/Tests/UI/Components/Workflow/ComponentPicker/PickerCatalog.test.ts +352 -0
  441. package/Tests/UI/Components/Workflow/ComponentPicker/PickerFixtures.ts +240 -0
  442. package/Tests/UI/Components/Workflow/ComponentPortViewer.test.tsx +91 -0
  443. package/Tests/UI/Components/Workflow/ComponentReturnValueViewer.test.tsx +248 -0
  444. package/Tests/UI/Components/Workflow/ComponentSettingsDeleteConfirmation.test.tsx +245 -0
  445. package/Tests/UI/Components/Workflow/ComponentSettingsModal.test.tsx +1033 -0
  446. package/Tests/UI/Components/Workflow/ComponentSettingsModalDarkMode.test.ts +276 -0
  447. package/Tests/UI/Components/Workflow/ComponentSettingsModalDocumentation.test.tsx +478 -0
  448. package/Tests/UI/Components/Workflow/ComponentSettingsModalIncomingEmail.test.tsx +606 -0
  449. package/Tests/UI/Components/Workflow/ComponentSettingsModalLayout.test.tsx +478 -0
  450. package/Tests/UI/Components/Workflow/ComponentSettingsModalStepSamples.test.tsx +343 -0
  451. package/Tests/UI/Components/Workflow/ComponentSettingsModalValidity.test.tsx +223 -0
  452. package/Tests/UI/Components/Workflow/ComponentSettingsRunStepConfirmation.test.tsx +286 -0
  453. package/Tests/UI/Components/Workflow/Condition/ConditionCanvasCard.test.tsx +208 -0
  454. package/Tests/UI/Components/Workflow/Condition/ConditionEditor.test.tsx +906 -0
  455. package/Tests/UI/Components/Workflow/Condition/ConditionGraphLint.test.ts +204 -0
  456. package/Tests/UI/Components/Workflow/Condition/ConditionModel.test.ts +986 -0
  457. package/Tests/UI/Components/Workflow/CronScheduleFieldVariable.test.tsx +115 -0
  458. package/Tests/UI/Components/Workflow/DocumentationViewer.test.tsx +592 -0
  459. package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +467 -0
  460. package/Tests/UI/Components/Workflow/IncomingEmailTriggerPanel.test.tsx +865 -0
  461. package/Tests/UI/Components/Workflow/IncomingEmailTriggerPanelI18n.test.ts +164 -0
  462. package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +35 -19
  463. package/Tests/UI/Components/Workflow/ModelColumnEditorFieldLists.render.test.tsx +660 -0
  464. package/Tests/UI/Components/Workflow/ModelFieldPicker.test.tsx +230 -0
  465. package/Tests/UI/Components/Workflow/NodePlacement.test.ts +379 -1
  466. package/Tests/UI/Components/Workflow/StepTracePresentation.test.ts +705 -0
  467. package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +1039 -35
  468. package/Tests/UI/Components/Workflow/StepTraceViewerDarkMode.test.ts +275 -0
  469. package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +131 -0
  470. package/Tests/UI/Components/Workflow/UseWorkflowEnabled.test.tsx +612 -0
  471. package/Tests/UI/Components/Workflow/ValuePicker/ArgumentControl.test.ts +80 -0
  472. package/Tests/UI/Components/Workflow/ValuePicker/InsertValueButton.test.tsx +114 -0
  473. package/Tests/UI/Components/Workflow/ValuePicker/NoPickThisValueLinks.test.ts +111 -0
  474. package/Tests/UI/Components/Workflow/ValuePicker/ReferenceDescription.test.ts +257 -0
  475. package/Tests/UI/Components/Workflow/ValuePicker/StepGraph.test.ts +271 -0
  476. package/Tests/UI/Components/Workflow/ValuePicker/StepSampleSource.test.ts +763 -0
  477. package/Tests/UI/Components/Workflow/ValuePicker/StepSampleSourceIncomingEmail.test.ts +234 -0
  478. package/Tests/UI/Components/Workflow/ValuePicker/StepValueSource.test.ts +366 -0
  479. package/Tests/UI/Components/Workflow/ValuePicker/TemplateText.test.ts +256 -0
  480. package/Tests/UI/Components/Workflow/ValuePicker/TemplateTextDom.test.ts +264 -0
  481. package/Tests/UI/Components/Workflow/ValuePicker/TemplateTextEditor.test.tsx +740 -0
  482. package/Tests/UI/Components/Workflow/ValuePicker/TemplateTextHistory.test.ts +139 -0
  483. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerContext.test.tsx +473 -0
  484. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerContextRefresh.test.tsx +444 -0
  485. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerDarkMode.test.ts +231 -0
  486. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerMenu.test.tsx +612 -0
  487. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerMenuSamples.test.tsx +784 -0
  488. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerPopupPosition.test.ts +113 -0
  489. package/Tests/UI/Components/Workflow/ValuePicker/ValuePickerTestUtils.tsx +171 -0
  490. package/Tests/UI/Components/Workflow/ValuePicker/ValueSingleField.test.tsx +350 -0
  491. package/Tests/UI/Components/Workflow/ValuePicker/ValueSuggestion.test.ts +377 -0
  492. package/Tests/UI/Components/Workflow/ValuePicker/ValueSuggestionSamples.test.ts +357 -0
  493. package/Tests/UI/Components/Workflow/ValuePicker/ValueTextField.test.tsx +430 -0
  494. package/Tests/UI/Components/Workflow/ValuePicker/VariableValueSource.test.ts +101 -0
  495. package/Tests/UI/Components/Workflow/WebhookTriggerPanel.test.tsx +833 -0
  496. package/Tests/UI/Components/Workflow/WebhookTriggerPanelI18n.test.ts +193 -0
  497. package/Tests/UI/Components/Workflow/Workflow.test.tsx +716 -86
  498. package/Tests/UI/Components/Workflow/WorkflowEnabledDarkMode.test.ts +178 -0
  499. package/Tests/UI/Components/Workflow/WorkflowEnabledI18n.test.tsx +319 -0
  500. package/Tests/UI/Components/Workflow/WorkflowEnabledSwitch.test.tsx +144 -0
  501. package/Tests/UI/Components/Workflow/WorkflowIncomingEmailSecretKey.test.ts +393 -0
  502. package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +598 -1
  503. package/Tests/UI/Components/Workflow/WorkflowRunExport.test.ts +750 -0
  504. package/Tests/UI/Components/Workflow/WorkflowRunExportActions.test.tsx +556 -0
  505. package/Tests/UI/Components/Workflow/WorkflowRunExportI18n.test.ts +200 -0
  506. package/Tests/UI/Components/Workflow/WorkflowStatusLabel.test.tsx +75 -0
  507. package/Tests/UI/Components/Workflow/WorkflowTurnOnModal.test.tsx +256 -0
  508. package/Tests/UI/Components/Workflow/WorkflowTurnedOffNotice.test.tsx +99 -0
  509. package/Tests/UI/Components/Workflow/WorkflowWebhookSecretKey.test.ts +422 -0
  510. package/Tests/UI/DeleteConfirmationNamesGuard.test.ts +643 -0
  511. package/Tests/UI/DialogActionRules.test.ts +716 -0
  512. package/Tests/UI/DialogPrimaryActionGuard.test.ts +528 -0
  513. package/Tests/UI/Styles/PillDarkTheme.test.tsx +177 -0
  514. package/Tests/UI/Styles/ToggleTheme.test.ts +685 -0
  515. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +17 -2
  516. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +3 -2
  517. package/Tests/UI/Utils/McpOAuthPendingAuthorization.test.ts +825 -0
  518. package/Tests/UI/Utils/McpOAuthPendingAuthorizationHttps.test.ts +88 -0
  519. package/Tests/UI/Utils/ModelDisplayName.test.ts +450 -0
  520. package/Tests/UI/Utils/TranslateTemplate.test.ts +149 -0
  521. package/Tests/Utils/AiRemediation/KubectlWriteScopeParityCases.ts +1 -1
  522. package/Tests/Utils/DeveloperDocs/AiAssistantExamples.test.ts +228 -0
  523. package/Tests/Utils/DeveloperDocs/ApiExamples.test.ts +252 -0
  524. package/Tests/Utils/DeveloperDocs/Hcl.test.ts +358 -0
  525. package/Tests/Utils/DeveloperDocs/HclTestValue.ts +56 -0
  526. package/Tests/Utils/DeveloperDocs/TerraformConfig.test.ts +590 -0
  527. package/Tests/Utils/DeveloperDocs/TerraformMonitorSteps.test.ts +608 -0
  528. package/Tests/Utils/DeveloperDocs/TerraformProviderSchemaContract.test.ts +250 -0
  529. package/Tests/Utils/DeveloperDocs/TerraformSchema.test.ts +284 -0
  530. package/Tests/Utils/Email/EmailAddressList.test.ts +149 -0
  531. package/Tests/Utils/Monitor/IncomingEmailMonitorAddress.test.ts +131 -0
  532. package/Tests/Utils/Monitor/MonitorOverviewArchived.test.ts +266 -0
  533. package/Tests/Utils/Monitor/MonitorPauseState.test.ts +143 -0
  534. package/Tests/Utils/Rum/SessionIdentity.test.ts +146 -0
  535. package/Tests/Utils/StatusPage/ArchivedMonitorResources.test.ts +99 -0
  536. package/Types/AI/AIRunType.ts +7 -6
  537. package/Types/AI/AIWorkloadLimits.ts +82 -0
  538. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +2 -2
  539. package/Types/AnalyticsDatabase/RetentionTtl.ts +57 -0
  540. package/Types/BaseDatabase/DatabaseCommonInteractionProps.ts +21 -0
  541. package/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.ts +24 -0
  542. package/Types/BaseDatabase/EnableWorkflowOn.ts +8 -0
  543. package/Types/Call/CallProvider.ts +7 -0
  544. package/Types/Database/TableMetadata.ts +10 -0
  545. package/Types/DatabaseServer/DatabaseEndpoint.ts +43 -0
  546. package/Types/Email/EmailTemplateType.ts +2 -0
  547. package/Types/Exception/ExceptionMessages.ts +1 -0
  548. package/Types/IncomingCall/MissedIncomingCall.ts +72 -0
  549. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +5 -0
  550. package/Types/Mcp/McpOAuthClientAuthMethod.ts +17 -0
  551. package/Types/Mcp/McpOAuthScope.ts +180 -0
  552. package/Types/Mcp/McpOAuthTicket.ts +21 -0
  553. package/Types/Mcp/McpOAuthTokenType.ts +18 -0
  554. package/Types/Monitor/MonitorSecretAccess.ts +185 -0
  555. package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +13 -2
  556. package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +1 -1
  557. package/Types/NotificationSetting/NotificationSettingEventType.ts +3 -0
  558. package/Types/OnCallDutyPolicy/OnCallDutyPolicyArchive.ts +19 -0
  559. package/Types/Permission.ts +44 -0
  560. package/Types/ResourceAiAgent/ResourceAiAccess.ts +7 -2
  561. package/Types/StatusPage/StatusPageArchive.ts +20 -0
  562. package/Types/Workflow/Component.ts +61 -2
  563. package/Types/Workflow/ComponentID.ts +1 -0
  564. package/Types/Workflow/Components/AI.ts +2 -4
  565. package/Types/Workflow/Components/API.ts +46 -26
  566. package/Types/Workflow/Components/BaseModel.ts +28 -37
  567. package/Types/Workflow/Components/Condition.ts +82 -30
  568. package/Types/Workflow/Components/ConditionComparison.ts +348 -0
  569. package/Types/Workflow/Components/ConditionEvaluation.ts +438 -0
  570. package/Types/Workflow/Components/Email.ts +1 -1
  571. package/Types/Workflow/Components/IncomingEmail.ts +140 -0
  572. package/Types/Workflow/Components/JSON.ts +11 -3
  573. package/Types/Workflow/Components/JavaScript.ts +0 -2
  574. package/Types/Workflow/Components/Manual.ts +2 -3
  575. package/Types/Workflow/Components/Schedule.ts +1 -2
  576. package/Types/Workflow/Components/Slack.ts +12 -4
  577. package/Types/Workflow/Components/Sleep.ts +4 -4
  578. package/Types/Workflow/Components/Webhook.ts +5 -7
  579. package/Types/Workflow/Components.ts +4 -2
  580. package/Types/Workflow/DatabaseOperation.ts +67 -0
  581. package/Types/Workflow/Documentation/AIDocumentation.ts +94 -0
  582. package/Types/Workflow/Documentation/APIDocumentation.ts +94 -0
  583. package/Types/Workflow/Documentation/ComponentDocumentation.ts +92 -0
  584. package/Types/Workflow/Documentation/DatabaseDocumentation.ts +666 -0
  585. package/Types/Workflow/Documentation/DocumentationContext.ts +245 -0
  586. package/Types/Workflow/Documentation/DocumentationLinks.ts +117 -0
  587. package/Types/Workflow/Documentation/DocumentationText.ts +141 -0
  588. package/Types/Workflow/Documentation/Index.ts +114 -0
  589. package/Types/Workflow/Documentation/MessagingDocumentation.ts +316 -0
  590. package/Types/Workflow/Documentation/ModelExamples.ts +333 -0
  591. package/Types/Workflow/Documentation/TriggerDocumentation.ts +217 -0
  592. package/Types/Workflow/Documentation/UtilityDocumentation.ts +338 -0
  593. package/Types/Workflow/IncomingEmailTrigger.ts +384 -0
  594. package/Types/Workflow/StepSamples.ts +965 -0
  595. package/Types/Workflow/StepTrace.ts +311 -6
  596. package/Types/Workflow/SystemColumns.ts +84 -0
  597. package/Types/Workflow/Templates.ts +279 -2
  598. package/Types/Workflow/WebhookTrigger.ts +87 -0
  599. package/Types/Workflow/WorkflowArchive.ts +45 -0
  600. package/Types/Workflow/WorkflowEnabled.ts +51 -0
  601. package/Types/Workflow/WorkflowStatus.ts +36 -0
  602. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +32 -2
  603. package/UI/Components/ActionButton/RowActions.tsx +8 -5
  604. package/UI/Components/ActionCard/ActionCard.tsx +22 -2
  605. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +1 -0
  606. package/UI/Components/BulkUpdate/BulkOwnerActions.tsx +1 -0
  607. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +6 -0
  608. package/UI/Components/Button/Button.tsx +19 -11
  609. package/UI/Components/Card/Card.tsx +64 -19
  610. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +1 -4
  611. package/UI/Components/CodeEditor/CodeEditor.tsx +69 -0
  612. package/UI/Components/CollapsibleSection/CollapsibleSection.tsx +19 -3
  613. package/UI/Components/DeleteConfirmation/DeleteConfirmationMessage.tsx +175 -0
  614. package/UI/Components/DeleteConfirmation/DeleteItemNames.tsx +71 -0
  615. package/UI/Components/DeleteConfirmation/NamedSentence.tsx +55 -0
  616. package/UI/Components/DeleteConfirmation/TypeToConfirmDelete.tsx +90 -0
  617. package/UI/Components/Dictionary/Dictionary.tsx +31 -1
  618. package/UI/Components/Dropdown/DropdownValueBadge.tsx +21 -13
  619. package/UI/Components/EditionLabel/EditionLabel.tsx +6 -1
  620. package/UI/Components/Error/PageError.tsx +1 -1
  621. package/UI/Components/EventItem/EventItem.tsx +1 -11
  622. package/UI/Components/FormModal/BasicFormModal.tsx +23 -0
  623. package/UI/Components/Forms/BasicForm.tsx +188 -78
  624. package/UI/Components/Forms/BasicModelForm.tsx +2 -0
  625. package/UI/Components/Forms/Fields/FormField.tsx +70 -5
  626. package/UI/Components/Forms/ModelForm.tsx +8 -0
  627. package/UI/Components/Forms/Steps/Step.tsx +29 -6
  628. package/UI/Components/Forms/Steps/Steps.tsx +10 -0
  629. package/UI/Components/Forms/Types/Field.ts +41 -1
  630. package/UI/Components/Forms/Validation.ts +18 -4
  631. package/UI/Components/Icon/Icon.tsx +7 -2
  632. package/UI/Components/Label/Label.tsx +0 -2
  633. package/UI/Components/LabelRule/ImportLabelRulesModal.tsx +1 -2
  634. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +8 -0
  635. package/UI/Components/Modal/ConfirmModal.tsx +39 -8
  636. package/UI/Components/Modal/Modal.tsx +136 -10
  637. package/UI/Components/Modal/ModalFooter.tsx +28 -10
  638. package/UI/Components/ModelDelete/ModelDelete.tsx +168 -6
  639. package/UI/Components/ModelFormModal/ModelFormModal.tsx +47 -9
  640. package/UI/Components/ModelTable/BaseModelTable.tsx +58 -91
  641. package/UI/Components/ModelTable/TableView.tsx +14 -2
  642. package/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.tsx +1 -2
  643. package/UI/Components/Navbar/NavBar.tsx +3 -2
  644. package/UI/Components/Pill/Pill.tsx +53 -43
  645. package/UI/Components/Pill/PillColors.ts +464 -0
  646. package/UI/Components/RuleRun/RunRuleNowModal.tsx +6 -0
  647. package/UI/Components/SideMenu/SideMenu.tsx +136 -12
  648. package/UI/Components/SideMenu/SideMenuSection.tsx +43 -4
  649. package/UI/Components/SideMenu/SideMenuSectionState.ts +200 -0
  650. package/UI/Components/TextArea/TextArea.tsx +174 -3
  651. package/UI/Components/Toggle/Toggle.tsx +256 -43
  652. package/UI/Components/Workflow/ArgumentsForm.tsx +496 -359
  653. package/UI/Components/Workflow/BreakableCode.tsx +88 -0
  654. package/UI/Components/Workflow/ColumnEditor/AddColumnPicker.tsx +577 -0
  655. package/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.tsx +20 -5
  656. package/UI/Components/Workflow/ColumnEditor/ColumnControl.ts +63 -4
  657. package/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.tsx +21 -4
  658. package/UI/Components/Workflow/ColumnEditor/ColumnPickerOptions.ts +387 -0
  659. package/UI/Components/Workflow/ColumnEditor/ColumnUse.ts +126 -0
  660. package/UI/Components/Workflow/ColumnEditor/ColumnValueInput.tsx +151 -84
  661. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +13 -9
  662. package/UI/Components/Workflow/ColumnEditor/ModelRecordForm.tsx +36 -27
  663. package/UI/Components/Workflow/Component.tsx +129 -12
  664. package/UI/Components/Workflow/ComponentPicker/ComponentSearch.ts +1259 -0
  665. package/UI/Components/Workflow/ComponentPicker/PickerCatalog.ts +419 -0
  666. package/UI/Components/Workflow/ComponentPicker/PickerItems.tsx +300 -0
  667. package/UI/Components/Workflow/ComponentPortViewer.tsx +24 -60
  668. package/UI/Components/Workflow/ComponentPrimaryPanel.tsx +171 -0
  669. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +67 -88
  670. package/UI/Components/Workflow/ComponentSettingsModal.tsx +345 -105
  671. package/UI/Components/Workflow/ComponentSettingsSection.tsx +103 -0
  672. package/UI/Components/Workflow/ComponentsModal.tsx +958 -601
  673. package/UI/Components/Workflow/Condition/ConditionEditor.tsx +484 -0
  674. package/UI/Components/Workflow/Condition/ConditionModel.ts +785 -0
  675. package/UI/Components/Workflow/CronScheduleField.tsx +53 -37
  676. package/UI/Components/Workflow/DocumentationViewer.tsx +399 -118
  677. package/UI/Components/Workflow/DownloadWorkflowRun.ts +137 -0
  678. package/UI/Components/Workflow/GraphLint.ts +9 -1
  679. package/UI/Components/Workflow/GraphLintSummary.ts +142 -2
  680. package/UI/Components/Workflow/IncomingEmailTriggerPanel.tsx +502 -0
  681. package/UI/Components/Workflow/ManualTriggerPanel.tsx +41 -0
  682. package/UI/Components/Workflow/ModelColumnEditor.tsx +7 -10
  683. package/UI/Components/Workflow/ModelFieldPicker.tsx +66 -2
  684. package/UI/Components/Workflow/ModelSchema.ts +19 -24
  685. package/UI/Components/Workflow/NodePlacement.ts +235 -1
  686. package/UI/Components/Workflow/RunModal.tsx +1 -1
  687. package/UI/Components/Workflow/StepTracePresentation.ts +537 -0
  688. package/UI/Components/Workflow/StepTraceViewer.tsx +644 -83
  689. package/UI/Components/Workflow/UseRunWatch.ts +17 -0
  690. package/UI/Components/Workflow/UseWorkflowEnabled.ts +275 -0
  691. package/UI/Components/Workflow/Utils.ts +119 -103
  692. package/UI/Components/Workflow/ValuePicker/ArgumentControl.ts +146 -0
  693. package/UI/Components/Workflow/ValuePicker/DefaultValueSources.ts +148 -0
  694. package/UI/Components/Workflow/ValuePicker/InsertValueButton.tsx +116 -0
  695. package/UI/Components/Workflow/ValuePicker/ReferenceChip.tsx +162 -0
  696. package/UI/Components/Workflow/ValuePicker/ReferenceDescription.ts +303 -0
  697. package/UI/Components/Workflow/ValuePicker/StepGraph.ts +240 -0
  698. package/UI/Components/Workflow/ValuePicker/StepSampleSource.ts +537 -0
  699. package/UI/Components/Workflow/ValuePicker/StepValueSource.ts +291 -0
  700. package/UI/Components/Workflow/ValuePicker/TemplateText.ts +303 -0
  701. package/UI/Components/Workflow/ValuePicker/TemplateTextDom.ts +563 -0
  702. package/UI/Components/Workflow/ValuePicker/TemplateTextEditor.tsx +1233 -0
  703. package/UI/Components/Workflow/ValuePicker/TemplateTextHistory.ts +138 -0
  704. package/UI/Components/Workflow/ValuePicker/ValuePickerContext.tsx +529 -0
  705. package/UI/Components/Workflow/ValuePicker/ValuePickerMenu.tsx +1003 -0
  706. package/UI/Components/Workflow/ValuePicker/ValuePickerPopup.tsx +310 -0
  707. package/UI/Components/Workflow/ValuePicker/ValueSingleField.tsx +274 -0
  708. package/UI/Components/Workflow/ValuePicker/ValueSuggestion.ts +694 -0
  709. package/UI/Components/Workflow/ValuePicker/ValueTextField.tsx +334 -0
  710. package/UI/Components/Workflow/ValuePicker/VariableValueSource.ts +132 -0
  711. package/UI/Components/Workflow/WebhookTriggerPanel.tsx +522 -0
  712. package/UI/Components/Workflow/Workflow.tsx +381 -36
  713. package/UI/Components/Workflow/WorkflowEnabledCopy.ts +55 -0
  714. package/UI/Components/Workflow/WorkflowEnabledSwitch.tsx +44 -0
  715. package/UI/Components/Workflow/WorkflowIncomingEmailSecretKey.ts +156 -0
  716. package/UI/Components/Workflow/WorkflowLogModal.tsx +98 -17
  717. package/UI/Components/Workflow/WorkflowRunExport.ts +435 -0
  718. package/UI/Components/Workflow/WorkflowRunExportActions.tsx +242 -0
  719. package/UI/Components/Workflow/WorkflowStatus.tsx +25 -26
  720. package/UI/Components/Workflow/WorkflowTurnOnModal.tsx +119 -0
  721. package/UI/Components/Workflow/WorkflowTurnedOffNotice.tsx +91 -0
  722. package/UI/Components/Workflow/WorkflowWebhookSecretKey.ts +184 -0
  723. package/UI/Styles/Theme.css +74 -3
  724. package/UI/Utils/McpOAuthPendingAuthorization.ts +132 -0
  725. package/UI/Utils/ModelDisplayName.ts +294 -0
  726. package/UI/Utils/TranslateTemplate.ts +123 -0
  727. package/Utils/DeveloperDocs/AiAssistantExamples.ts +383 -0
  728. package/Utils/DeveloperDocs/ApiExamples.ts +355 -0
  729. package/Utils/DeveloperDocs/ExampleValues.ts +111 -0
  730. package/Utils/DeveloperDocs/Hcl.ts +697 -0
  731. package/Utils/DeveloperDocs/TerraformConfig.ts +805 -0
  732. package/Utils/DeveloperDocs/TerraformMonitorSteps.ts +583 -0
  733. package/Utils/DeveloperDocs/TerraformSchema.ts +565 -0
  734. package/Utils/DeveloperDocs/TerraformValues.ts +375 -0
  735. package/Utils/Email/EmailAddressList.ts +165 -0
  736. package/Utils/ModelImportExport.ts +17 -0
  737. package/Utils/Monitor/IncomingEmailMonitorAddress.ts +73 -4
  738. package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +27 -1
  739. package/Utils/Monitor/MonitorPauseState.ts +90 -0
  740. package/Utils/Rum/SessionIdentity.ts +88 -0
  741. package/Utils/StatusPage/ArchivedMonitorResources.ts +38 -0
  742. package/build/dist/Models/AnalyticsModels/AuditLog.js +56 -0
  743. package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
  744. package/build/dist/Models/AnalyticsModels/Log.js +26 -2
  745. package/build/dist/Models/AnalyticsModels/Log.js.map +1 -1
  746. package/build/dist/Models/AnalyticsModels/Metric.js +28 -2
  747. package/build/dist/Models/AnalyticsModels/Metric.js.map +1 -1
  748. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js +21 -2
  749. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js.map +1 -1
  750. package/build/dist/Models/AnalyticsModels/SloHistory.js +6 -4
  751. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -1
  752. package/build/dist/Models/DatabaseModels/AutoRemediationRule.js +1 -1
  753. package/build/dist/Models/DatabaseModels/AutoRemediationRule.js.map +1 -1
  754. package/build/dist/Models/DatabaseModels/CodeRepository.js +1 -1
  755. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  756. package/build/dist/Models/DatabaseModels/Dashboard.js +151 -1
  757. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  758. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +8 -0
  759. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  760. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js +1 -0
  761. package/build/dist/Models/DatabaseModels/DatabaseServerEndpoint.js.map +1 -1
  762. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +2 -0
  763. package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
  764. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js +1 -0
  765. package/build/dist/Models/DatabaseModels/EnterpriseLicenseInstance.js.map +1 -1
  766. package/build/dist/Models/DatabaseModels/IncomingCallLog.js +15 -1
  767. package/build/dist/Models/DatabaseModels/IncomingCallLog.js.map +1 -1
  768. package/build/dist/Models/DatabaseModels/Index.js +6 -0
  769. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  770. package/build/dist/Models/DatabaseModels/LlmModelPrice.js +1 -0
  771. package/build/dist/Models/DatabaseModels/LlmModelPrice.js.map +1 -1
  772. package/build/dist/Models/DatabaseModels/McpOAuthClient.js +215 -0
  773. package/build/dist/Models/DatabaseModels/McpOAuthClient.js.map +1 -0
  774. package/build/dist/Models/DatabaseModels/McpOAuthGrant.js +494 -0
  775. package/build/dist/Models/DatabaseModels/McpOAuthGrant.js.map +1 -0
  776. package/build/dist/Models/DatabaseModels/McpOAuthToken.js +256 -0
  777. package/build/dist/Models/DatabaseModels/McpOAuthToken.js.map +1 -0
  778. package/build/dist/Models/DatabaseModels/Monitor.js +160 -1
  779. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  780. package/build/dist/Models/DatabaseModels/MonitorSecret.js +89 -1
  781. package/build/dist/Models/DatabaseModels/MonitorSecret.js.map +1 -1
  782. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +1 -0
  783. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -1
  784. package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js +158 -1
  785. package/build/dist/Models/DatabaseModels/OnCallDutyPolicy.js.map +1 -1
  786. package/build/dist/Models/DatabaseModels/Project.js +42 -102
  787. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  788. package/build/dist/Models/DatabaseModels/StatusPage.js +158 -1
  789. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  790. package/build/dist/Models/DatabaseModels/TelemetrySourceMap.js +1 -0
  791. package/build/dist/Models/DatabaseModels/TelemetrySourceMap.js.map +1 -1
  792. package/build/dist/Models/DatabaseModels/Workflow.js +230 -8
  793. package/build/dist/Models/DatabaseModels/Workflow.js.map +1 -1
  794. package/build/dist/Server/API/AIAgentDataAPI.js +1 -1
  795. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  796. package/build/dist/Server/API/AutoRemediationAPI.js +9 -31
  797. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  798. package/build/dist/Server/API/CommonAPI.js +15 -0
  799. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  800. package/build/dist/Server/API/DashboardAPI.js +7 -3
  801. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  802. package/build/dist/Server/API/StatusPageAPI.js +54 -13
  803. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  804. package/build/dist/Server/EnvironmentConfig.js +23 -0
  805. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  806. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796800000000-FoldAiSwitchesIntoEnableAi.js +79 -0
  807. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796800000000-FoldAiSwitchesIntoEnableAi.js.map +1 -0
  808. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796900000000-AddMcpOAuthTables.js +50 -0
  809. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796900000000-AddMcpOAuthTables.js.map +1 -0
  810. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797000000000-AddWorkflowIncomingEmailSecretKey.js +25 -0
  811. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797000000000-AddWorkflowIncomingEmailSecretKey.js.map +1 -0
  812. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797100000000-AddMonitorSecretAccess.js +32 -0
  813. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797100000000-AddMonitorSecretAccess.js.map +1 -0
  814. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797200000000-AddArchiveToMoreResources.js +76 -0
  815. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797200000000-AddArchiveToMoreResources.js.map +1 -0
  816. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  817. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  818. package/build/dist/Server/Middleware/McpDelegationAuthorization.js +138 -0
  819. package/build/dist/Server/Middleware/McpDelegationAuthorization.js.map +1 -0
  820. package/build/dist/Server/Middleware/McpOAuthRateLimit.js +191 -0
  821. package/build/dist/Server/Middleware/McpOAuthRateLimit.js.map +1 -0
  822. package/build/dist/Server/Middleware/ProjectAuthorization.js +20 -1
  823. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  824. package/build/dist/Server/Middleware/UserAuthorization.js +11 -0
  825. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  826. package/build/dist/Server/Services/AIService.js +2 -2
  827. package/build/dist/Server/Services/AIService.js.map +1 -1
  828. package/build/dist/Server/Services/AnalyticsDatabaseService.js +15 -5
  829. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  830. package/build/dist/Server/Services/ApiKeyService.js +11 -8
  831. package/build/dist/Server/Services/ApiKeyService.js.map +1 -1
  832. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +19 -27
  833. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  834. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  835. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  836. package/build/dist/Server/Services/DashboardService.js +7 -2
  837. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  838. package/build/dist/Server/Services/DatabaseServerService.js +161 -1
  839. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
  840. package/build/dist/Server/Services/DatabaseService.js +28 -17
  841. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  842. package/build/dist/Server/Services/InboundEmail/InboundEmailProvider.js +17 -0
  843. package/build/dist/Server/Services/InboundEmail/InboundEmailProvider.js.map +1 -1
  844. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js +45 -5
  845. package/build/dist/Server/Services/InboundEmail/Providers/SendGridInboundProvider.js.map +1 -1
  846. package/build/dist/Server/Services/IncomingCallMissedCallNotificationService.js +227 -0
  847. package/build/dist/Server/Services/IncomingCallMissedCallNotificationService.js.map +1 -0
  848. package/build/dist/Server/Services/IncomingCallPolicyService.js +97 -0
  849. package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -1
  850. package/build/dist/Server/Services/Index.js +8 -0
  851. package/build/dist/Server/Services/Index.js.map +1 -1
  852. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +5 -36
  853. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  854. package/build/dist/Server/Services/KubernetesClusterService.js +3 -3
  855. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  856. package/build/dist/Server/Services/LogAggregationService.js +31 -5
  857. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  858. package/build/dist/Server/Services/McpOAuthClientService.js +134 -0
  859. package/build/dist/Server/Services/McpOAuthClientService.js.map +1 -0
  860. package/build/dist/Server/Services/McpOAuthGrantService.js +256 -0
  861. package/build/dist/Server/Services/McpOAuthGrantService.js.map +1 -0
  862. package/build/dist/Server/Services/McpOAuthTokenService.js +175 -0
  863. package/build/dist/Server/Services/McpOAuthTokenService.js.map +1 -0
  864. package/build/dist/Server/Services/MetricAggregationService.js +4 -4
  865. package/build/dist/Server/Services/MonitorGroupService.js +20 -5
  866. package/build/dist/Server/Services/MonitorGroupService.js.map +1 -1
  867. package/build/dist/Server/Services/MonitorProbeService.js +1 -0
  868. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  869. package/build/dist/Server/Services/MonitorSecretService.js +346 -0
  870. package/build/dist/Server/Services/MonitorSecretService.js.map +1 -1
  871. package/build/dist/Server/Services/MonitorService.js +15 -1
  872. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  873. package/build/dist/Server/Services/OnCallDutyPolicyService.js +29 -2
  874. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  875. package/build/dist/Server/Services/ProjectService.js +26 -15
  876. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  877. package/build/dist/Server/Services/ResourceAiAccessService.js +0 -9
  878. package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -1
  879. package/build/dist/Server/Services/RunnerJobService.js +2 -2
  880. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  881. package/build/dist/Server/Services/RunnerService.js +2 -2
  882. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  883. package/build/dist/Server/Services/StatusPageService.js +59 -2
  884. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  885. package/build/dist/Server/Services/StatusPageSubscriberService.js +17 -0
  886. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  887. package/build/dist/Server/Services/TeamMemberService.js +306 -72
  888. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  889. package/build/dist/Server/Services/UserNotificationSettingService.js +18 -0
  890. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  891. package/build/dist/Server/Services/WorkflowService.js +27 -0
  892. package/build/dist/Server/Services/WorkflowService.js.map +1 -1
  893. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +3 -0
  894. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  895. package/build/dist/Server/Types/Database/Permissions/Index.js +5 -0
  896. package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
  897. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +2 -0
  898. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
  899. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +28 -106
  900. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
  901. package/build/dist/Server/Types/Workflow/Components/IncomingEmail.js +166 -0
  902. package/build/dist/Server/Types/Workflow/Components/IncomingEmail.js.map +1 -0
  903. package/build/dist/Server/Types/Workflow/Components/Index.js +16 -6
  904. package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
  905. package/build/dist/Server/Types/Workflow/Components/Schedule.js +20 -4
  906. package/build/dist/Server/Types/Workflow/Components/Schedule.js.map +1 -1
  907. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +1 -1
  908. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js +1 -1
  909. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +43 -57
  910. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  911. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js +17 -28
  912. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js.map +1 -1
  913. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +18 -50
  914. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  915. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +27 -52
  916. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  917. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +4 -4
  918. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  919. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js +1 -1
  920. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js.map +1 -1
  921. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +8 -24
  922. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  923. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +6 -5
  924. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  925. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js +2 -2
  926. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js +5 -5
  927. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js +4 -3
  928. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js.map +1 -1
  929. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +4 -4
  930. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  931. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +1 -1
  932. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  933. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +52 -45
  934. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  935. package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
  936. package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js.map +1 -1
  937. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +9 -1
  938. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  939. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +13 -8
  940. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -1
  941. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +18 -3
  942. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
  943. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +45 -14
  944. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -1
  945. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +31 -7
  946. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -1
  947. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +22 -7
  948. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -1
  949. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +3 -1
  950. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  951. package/build/dist/Server/Utils/Express.js.map +1 -1
  952. package/build/dist/Server/Utils/IncomingCall/MissedCallNotification.js +204 -0
  953. package/build/dist/Server/Utils/IncomingCall/MissedCallNotification.js.map +1 -0
  954. package/build/dist/Server/Utils/Mcp/McpDelegationToken.js +92 -0
  955. package/build/dist/Server/Utils/Mcp/McpDelegationToken.js.map +1 -0
  956. package/build/dist/Server/Utils/Mcp/McpOAuthConfig.js +159 -0
  957. package/build/dist/Server/Utils/Mcp/McpOAuthConfig.js.map +1 -0
  958. package/build/dist/Server/Utils/Mcp/McpOAuthGrantAccess.js +204 -0
  959. package/build/dist/Server/Utils/Mcp/McpOAuthGrantAccess.js.map +1 -0
  960. package/build/dist/Server/Utils/Mcp/McpOAuthSecret.js +118 -0
  961. package/build/dist/Server/Utils/Mcp/McpOAuthSecret.js.map +1 -0
  962. package/build/dist/Server/Utils/Mcp/McpOAuthSignedToken.js +126 -0
  963. package/build/dist/Server/Utils/Mcp/McpOAuthSignedToken.js.map +1 -0
  964. package/build/dist/Server/Utils/Mcp/McpOAuthSso.js +159 -0
  965. package/build/dist/Server/Utils/Mcp/McpOAuthSso.js.map +1 -0
  966. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +25 -0
  967. package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -1
  968. package/build/dist/Server/Utils/Monitor/MonitorResource.js +16 -18
  969. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  970. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +3 -11
  971. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
  972. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +3 -3
  973. package/build/dist/Server/Utils/Slo/SloMetricUtil.js +3 -3
  974. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js +11 -4
  975. package/build/dist/Server/Utils/Telemetry/DatabaseEndpointDiscovery.js.map +1 -1
  976. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +7 -0
  977. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -1
  978. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js +133 -16
  979. package/build/dist/Server/Utils/Telemetry/ServiceDependencyDiscovery.js.map +1 -1
  980. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +2 -0
  981. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  982. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +2 -0
  983. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  984. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +2 -0
  985. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  986. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +2 -0
  987. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  988. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +4 -0
  989. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -1
  990. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js +2 -0
  991. package/build/dist/Server/Utils/Workspace/Slack/Actions/Alert.js.map +1 -1
  992. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js +2 -0
  993. package/build/dist/Server/Utils/Workspace/Slack/Actions/AlertEpisode.js.map +1 -1
  994. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +4 -0
  995. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -1
  996. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js +2 -0
  997. package/build/dist/Server/Utils/Workspace/Slack/Actions/IncidentEpisode.js.map +1 -1
  998. package/build/dist/Types/AI/AIRunType.js +7 -6
  999. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  1000. package/build/dist/Types/AI/AIWorkloadLimits.js +59 -0
  1001. package/build/dist/Types/AI/AIWorkloadLimits.js.map +1 -0
  1002. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +2 -2
  1003. package/build/dist/Types/AnalyticsDatabase/RetentionTtl.js +55 -0
  1004. package/build/dist/Types/AnalyticsDatabase/RetentionTtl.js.map +1 -0
  1005. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js +17 -0
  1006. package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js.map +1 -1
  1007. package/build/dist/Types/Database/TableMetadata.js +3 -0
  1008. package/build/dist/Types/Database/TableMetadata.js.map +1 -1
  1009. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js +36 -0
  1010. package/build/dist/Types/DatabaseServer/DatabaseEndpoint.js.map +1 -1
  1011. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  1012. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  1013. package/build/dist/Types/Exception/ExceptionMessages.js +1 -0
  1014. package/build/dist/Types/Exception/ExceptionMessages.js.map +1 -1
  1015. package/build/dist/Types/IncomingCall/MissedIncomingCall.js +61 -0
  1016. package/build/dist/Types/IncomingCall/MissedIncomingCall.js.map +1 -0
  1017. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  1018. package/build/dist/Types/Mcp/McpOAuthClientAuthMethod.js +18 -0
  1019. package/build/dist/Types/Mcp/McpOAuthClientAuthMethod.js.map +1 -0
  1020. package/build/dist/Types/Mcp/McpOAuthScope.js +140 -0
  1021. package/build/dist/Types/Mcp/McpOAuthScope.js.map +1 -0
  1022. package/build/dist/Types/Mcp/McpOAuthTicket.js +20 -0
  1023. package/build/dist/Types/Mcp/McpOAuthTicket.js.map +1 -0
  1024. package/build/dist/Types/Mcp/McpOAuthTokenType.js +17 -0
  1025. package/build/dist/Types/Mcp/McpOAuthTokenType.js.map +1 -0
  1026. package/build/dist/Types/Monitor/MonitorSecretAccess.js +111 -0
  1027. package/build/dist/Types/Monitor/MonitorSecretAccess.js.map +1 -0
  1028. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +11 -2
  1029. package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -1
  1030. package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +1 -1
  1031. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +2 -0
  1032. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  1033. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyArchive.js +16 -0
  1034. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyArchive.js.map +1 -0
  1035. package/build/dist/Types/Permission.js +40 -0
  1036. package/build/dist/Types/Permission.js.map +1 -1
  1037. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -1
  1038. package/build/dist/Types/StatusPage/StatusPageArchive.js +16 -0
  1039. package/build/dist/Types/StatusPage/StatusPageArchive.js.map +1 -0
  1040. package/build/dist/Types/Workflow/Component.js +19 -0
  1041. package/build/dist/Types/Workflow/Component.js.map +1 -1
  1042. package/build/dist/Types/Workflow/ComponentID.js +1 -0
  1043. package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
  1044. package/build/dist/Types/Workflow/Components/AI.js +2 -4
  1045. package/build/dist/Types/Workflow/Components/AI.js.map +1 -1
  1046. package/build/dist/Types/Workflow/Components/API.js +26 -26
  1047. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  1048. package/build/dist/Types/Workflow/Components/BaseModel.js +22 -28
  1049. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  1050. package/build/dist/Types/Workflow/Components/Condition.js +70 -29
  1051. package/build/dist/Types/Workflow/Components/Condition.js.map +1 -1
  1052. package/build/dist/Types/Workflow/Components/ConditionComparison.js +256 -0
  1053. package/build/dist/Types/Workflow/Components/ConditionComparison.js.map +1 -0
  1054. package/build/dist/Types/Workflow/Components/ConditionEvaluation.js +279 -0
  1055. package/build/dist/Types/Workflow/Components/ConditionEvaluation.js.map +1 -0
  1056. package/build/dist/Types/Workflow/Components/Email.js +1 -1
  1057. package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
  1058. package/build/dist/Types/Workflow/Components/IncomingEmail.js +129 -0
  1059. package/build/dist/Types/Workflow/Components/IncomingEmail.js.map +1 -0
  1060. package/build/dist/Types/Workflow/Components/JSON.js +10 -3
  1061. package/build/dist/Types/Workflow/Components/JSON.js.map +1 -1
  1062. package/build/dist/Types/Workflow/Components/JavaScript.js +0 -2
  1063. package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
  1064. package/build/dist/Types/Workflow/Components/Manual.js +2 -2
  1065. package/build/dist/Types/Workflow/Components/Manual.js.map +1 -1
  1066. package/build/dist/Types/Workflow/Components/Schedule.js +1 -1
  1067. package/build/dist/Types/Workflow/Components/Schedule.js.map +1 -1
  1068. package/build/dist/Types/Workflow/Components/Slack.js +11 -3
  1069. package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
  1070. package/build/dist/Types/Workflow/Components/Sleep.js +4 -4
  1071. package/build/dist/Types/Workflow/Components/Sleep.js.map +1 -1
  1072. package/build/dist/Types/Workflow/Components/Webhook.js +4 -6
  1073. package/build/dist/Types/Workflow/Components/Webhook.js.map +1 -1
  1074. package/build/dist/Types/Workflow/Components.js +4 -2
  1075. package/build/dist/Types/Workflow/Components.js.map +1 -1
  1076. package/build/dist/Types/Workflow/DatabaseOperation.js +50 -0
  1077. package/build/dist/Types/Workflow/DatabaseOperation.js.map +1 -0
  1078. package/build/dist/Types/Workflow/Documentation/AIDocumentation.js +78 -0
  1079. package/build/dist/Types/Workflow/Documentation/AIDocumentation.js.map +1 -0
  1080. package/build/dist/Types/Workflow/Documentation/APIDocumentation.js +69 -0
  1081. package/build/dist/Types/Workflow/Documentation/APIDocumentation.js.map +1 -0
  1082. package/build/dist/Types/Workflow/Documentation/ComponentDocumentation.js +44 -0
  1083. package/build/dist/Types/Workflow/Documentation/ComponentDocumentation.js.map +1 -0
  1084. package/build/dist/Types/Workflow/Documentation/DatabaseDocumentation.js +488 -0
  1085. package/build/dist/Types/Workflow/Documentation/DatabaseDocumentation.js.map +1 -0
  1086. package/build/dist/Types/Workflow/Documentation/DocumentationContext.js +139 -0
  1087. package/build/dist/Types/Workflow/Documentation/DocumentationContext.js.map +1 -0
  1088. package/build/dist/Types/Workflow/Documentation/DocumentationLinks.js +62 -0
  1089. package/build/dist/Types/Workflow/Documentation/DocumentationLinks.js.map +1 -0
  1090. package/build/dist/Types/Workflow/Documentation/DocumentationText.js +104 -0
  1091. package/build/dist/Types/Workflow/Documentation/DocumentationText.js.map +1 -0
  1092. package/build/dist/Types/Workflow/Documentation/Index.js +58 -0
  1093. package/build/dist/Types/Workflow/Documentation/Index.js.map +1 -0
  1094. package/build/dist/Types/Workflow/Documentation/MessagingDocumentation.js +247 -0
  1095. package/build/dist/Types/Workflow/Documentation/MessagingDocumentation.js.map +1 -0
  1096. package/build/dist/Types/Workflow/Documentation/ModelExamples.js +210 -0
  1097. package/build/dist/Types/Workflow/Documentation/ModelExamples.js.map +1 -0
  1098. package/build/dist/Types/Workflow/Documentation/TriggerDocumentation.js +184 -0
  1099. package/build/dist/Types/Workflow/Documentation/TriggerDocumentation.js.map +1 -0
  1100. package/build/dist/Types/Workflow/Documentation/UtilityDocumentation.js +290 -0
  1101. package/build/dist/Types/Workflow/Documentation/UtilityDocumentation.js.map +1 -0
  1102. package/build/dist/Types/Workflow/IncomingEmailTrigger.js +275 -0
  1103. package/build/dist/Types/Workflow/IncomingEmailTrigger.js.map +1 -0
  1104. package/build/dist/Types/Workflow/StepSamples.js +601 -0
  1105. package/build/dist/Types/Workflow/StepSamples.js.map +1 -0
  1106. package/build/dist/Types/Workflow/StepTrace.js +135 -4
  1107. package/build/dist/Types/Workflow/StepTrace.js.map +1 -1
  1108. package/build/dist/Types/Workflow/SystemColumns.js +65 -0
  1109. package/build/dist/Types/Workflow/SystemColumns.js.map +1 -0
  1110. package/build/dist/Types/Workflow/Templates.js +178 -2
  1111. package/build/dist/Types/Workflow/Templates.js.map +1 -1
  1112. package/build/dist/Types/Workflow/WebhookTrigger.js +55 -0
  1113. package/build/dist/Types/Workflow/WebhookTrigger.js.map +1 -0
  1114. package/build/dist/Types/Workflow/WorkflowArchive.js +29 -0
  1115. package/build/dist/Types/Workflow/WorkflowArchive.js.map +1 -0
  1116. package/build/dist/Types/Workflow/WorkflowEnabled.js +39 -0
  1117. package/build/dist/Types/Workflow/WorkflowEnabled.js.map +1 -0
  1118. package/build/dist/Types/Workflow/WorkflowStatus.js +24 -0
  1119. package/build/dist/Types/Workflow/WorkflowStatus.js.map +1 -1
  1120. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +23 -3
  1121. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  1122. package/build/dist/UI/Components/ActionButton/RowActions.js +8 -5
  1123. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -1
  1124. package/build/dist/UI/Components/ActionCard/ActionCard.js +20 -2
  1125. package/build/dist/UI/Components/ActionCard/ActionCard.js.map +1 -1
  1126. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
  1127. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  1128. package/build/dist/UI/Components/BulkUpdate/BulkOwnerActions.js +1 -1
  1129. package/build/dist/UI/Components/BulkUpdate/BulkOwnerActions.js.map +1 -1
  1130. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -0
  1131. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  1132. package/build/dist/UI/Components/Button/Button.js +19 -11
  1133. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  1134. package/build/dist/UI/Components/Card/Card.js +23 -3
  1135. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  1136. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +1 -3
  1137. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  1138. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +37 -0
  1139. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  1140. package/build/dist/UI/Components/CollapsibleSection/CollapsibleSection.js +7 -3
  1141. package/build/dist/UI/Components/CollapsibleSection/CollapsibleSection.js.map +1 -1
  1142. package/build/dist/UI/Components/DeleteConfirmation/DeleteConfirmationMessage.js +97 -0
  1143. package/build/dist/UI/Components/DeleteConfirmation/DeleteConfirmationMessage.js.map +1 -0
  1144. package/build/dist/UI/Components/DeleteConfirmation/DeleteItemNames.js +34 -0
  1145. package/build/dist/UI/Components/DeleteConfirmation/DeleteItemNames.js.map +1 -0
  1146. package/build/dist/UI/Components/DeleteConfirmation/NamedSentence.js +11 -0
  1147. package/build/dist/UI/Components/DeleteConfirmation/NamedSentence.js.map +1 -0
  1148. package/build/dist/UI/Components/DeleteConfirmation/TypeToConfirmDelete.js +44 -0
  1149. package/build/dist/UI/Components/DeleteConfirmation/TypeToConfirmDelete.js.map +1 -0
  1150. package/build/dist/UI/Components/Dictionary/Dictionary.js +17 -1
  1151. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  1152. package/build/dist/UI/Components/Dropdown/DropdownValueBadge.js +12 -10
  1153. package/build/dist/UI/Components/Dropdown/DropdownValueBadge.js.map +1 -1
  1154. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +1 -1
  1155. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  1156. package/build/dist/UI/Components/Error/PageError.js +1 -1
  1157. package/build/dist/UI/Components/Error/PageError.js.map +1 -1
  1158. package/build/dist/UI/Components/EventItem/EventItem.js +1 -4
  1159. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  1160. package/build/dist/UI/Components/FormModal/BasicFormModal.js +17 -3
  1161. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  1162. package/build/dist/UI/Components/Forms/BasicForm.js +115 -54
  1163. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  1164. package/build/dist/UI/Components/Forms/BasicModelForm.js +1 -1
  1165. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  1166. package/build/dist/UI/Components/Forms/Fields/FormField.js +40 -9
  1167. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  1168. package/build/dist/UI/Components/Forms/ModelForm.js +5 -1
  1169. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  1170. package/build/dist/UI/Components/Forms/Steps/Step.js +16 -5
  1171. package/build/dist/UI/Components/Forms/Steps/Step.js.map +1 -1
  1172. package/build/dist/UI/Components/Forms/Steps/Steps.js +3 -1
  1173. package/build/dist/UI/Components/Forms/Steps/Steps.js.map +1 -1
  1174. package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
  1175. package/build/dist/UI/Components/Forms/Validation.js +13 -4
  1176. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  1177. package/build/dist/UI/Components/Icon/Icon.js +7 -2
  1178. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  1179. package/build/dist/UI/Components/Label/Label.js +0 -2
  1180. package/build/dist/UI/Components/Label/Label.js.map +1 -1
  1181. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js +1 -1
  1182. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js.map +1 -1
  1183. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +8 -0
  1184. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  1185. package/build/dist/UI/Components/Modal/ConfirmModal.js +22 -3
  1186. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  1187. package/build/dist/UI/Components/Modal/Modal.js +76 -9
  1188. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  1189. package/build/dist/UI/Components/Modal/ModalFooter.js +22 -6
  1190. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  1191. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +84 -7
  1192. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  1193. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +38 -13
  1194. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  1195. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +41 -69
  1196. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  1197. package/build/dist/UI/Components/ModelTable/TableView.js +13 -1
  1198. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  1199. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js +1 -1
  1200. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js.map +1 -1
  1201. package/build/dist/UI/Components/Navbar/NavBar.js +3 -2
  1202. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  1203. package/build/dist/UI/Components/Pill/Pill.js +25 -22
  1204. package/build/dist/UI/Components/Pill/Pill.js.map +1 -1
  1205. package/build/dist/UI/Components/Pill/PillColors.js +297 -0
  1206. package/build/dist/UI/Components/Pill/PillColors.js.map +1 -0
  1207. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js +7 -1
  1208. package/build/dist/UI/Components/RuleRun/RunRuleNowModal.js.map +1 -1
  1209. package/build/dist/UI/Components/SideMenu/SideMenu.js +81 -9
  1210. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  1211. package/build/dist/UI/Components/SideMenu/SideMenuSection.js +21 -4
  1212. package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
  1213. package/build/dist/UI/Components/SideMenu/SideMenuSectionState.js +150 -0
  1214. package/build/dist/UI/Components/SideMenu/SideMenuSectionState.js.map +1 -0
  1215. package/build/dist/UI/Components/TextArea/TextArea.js +122 -4
  1216. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  1217. package/build/dist/UI/Components/Toggle/Toggle.js +115 -22
  1218. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  1219. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +272 -257
  1220. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  1221. package/build/dist/UI/Components/Workflow/BreakableCode.js +33 -0
  1222. package/build/dist/UI/Components/Workflow/BreakableCode.js.map +1 -0
  1223. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnPicker.js +293 -0
  1224. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnPicker.js.map +1 -0
  1225. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js +17 -2
  1226. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js.map +1 -1
  1227. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js +42 -4
  1228. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js.map +1 -1
  1229. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js +9 -4
  1230. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js.map +1 -1
  1231. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnPickerOptions.js +252 -0
  1232. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnPickerOptions.js.map +1 -0
  1233. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnUse.js +88 -0
  1234. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnUse.js.map +1 -0
  1235. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js +79 -44
  1236. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js.map +1 -1
  1237. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +13 -8
  1238. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -1
  1239. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js +19 -21
  1240. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js.map +1 -1
  1241. package/build/dist/UI/Components/Workflow/Component.js +74 -8
  1242. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  1243. package/build/dist/UI/Components/Workflow/ComponentPicker/ComponentSearch.js +864 -0
  1244. package/build/dist/UI/Components/Workflow/ComponentPicker/ComponentSearch.js.map +1 -0
  1245. package/build/dist/UI/Components/Workflow/ComponentPicker/PickerCatalog.js +254 -0
  1246. package/build/dist/UI/Components/Workflow/ComponentPicker/PickerCatalog.js.map +1 -0
  1247. package/build/dist/UI/Components/Workflow/ComponentPicker/PickerItems.js +105 -0
  1248. package/build/dist/UI/Components/Workflow/ComponentPicker/PickerItems.js.map +1 -0
  1249. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js +15 -45
  1250. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js.map +1 -1
  1251. package/build/dist/UI/Components/Workflow/ComponentPrimaryPanel.js +88 -0
  1252. package/build/dist/UI/Components/Workflow/ComponentPrimaryPanel.js.map +1 -0
  1253. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +24 -57
  1254. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  1255. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +196 -55
  1256. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  1257. package/build/dist/UI/Components/Workflow/ComponentSettingsSection.js +34 -0
  1258. package/build/dist/UI/Components/Workflow/ComponentSettingsSection.js.map +1 -0
  1259. package/build/dist/UI/Components/Workflow/ComponentsModal.js +523 -329
  1260. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  1261. package/build/dist/UI/Components/Workflow/Condition/ConditionEditor.js +199 -0
  1262. package/build/dist/UI/Components/Workflow/Condition/ConditionEditor.js.map +1 -0
  1263. package/build/dist/UI/Components/Workflow/Condition/ConditionModel.js +458 -0
  1264. package/build/dist/UI/Components/Workflow/Condition/ConditionModel.js.map +1 -0
  1265. package/build/dist/UI/Components/Workflow/CronScheduleField.js +25 -19
  1266. package/build/dist/UI/Components/Workflow/CronScheduleField.js.map +1 -1
  1267. package/build/dist/UI/Components/Workflow/DocumentationViewer.js +107 -61
  1268. package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
  1269. package/build/dist/UI/Components/Workflow/DownloadWorkflowRun.js +78 -0
  1270. package/build/dist/UI/Components/Workflow/DownloadWorkflowRun.js.map +1 -0
  1271. package/build/dist/UI/Components/Workflow/GraphLint.js +7 -2
  1272. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -1
  1273. package/build/dist/UI/Components/Workflow/GraphLintSummary.js +59 -1
  1274. package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -1
  1275. package/build/dist/UI/Components/Workflow/IncomingEmailTriggerPanel.js +215 -0
  1276. package/build/dist/UI/Components/Workflow/IncomingEmailTriggerPanel.js.map +1 -0
  1277. package/build/dist/UI/Components/Workflow/ManualTriggerPanel.js +27 -0
  1278. package/build/dist/UI/Components/Workflow/ManualTriggerPanel.js.map +1 -0
  1279. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +5 -1
  1280. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
  1281. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js +44 -2
  1282. package/build/dist/UI/Components/Workflow/ModelFieldPicker.js.map +1 -1
  1283. package/build/dist/UI/Components/Workflow/ModelSchema.js +7 -8
  1284. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -1
  1285. package/build/dist/UI/Components/Workflow/NodePlacement.js +123 -1
  1286. package/build/dist/UI/Components/Workflow/NodePlacement.js.map +1 -1
  1287. package/build/dist/UI/Components/Workflow/RunModal.js +1 -1
  1288. package/build/dist/UI/Components/Workflow/StepTracePresentation.js +318 -0
  1289. package/build/dist/UI/Components/Workflow/StepTracePresentation.js.map +1 -0
  1290. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +282 -42
  1291. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  1292. package/build/dist/UI/Components/Workflow/UseRunWatch.js +4 -0
  1293. package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -1
  1294. package/build/dist/UI/Components/Workflow/UseWorkflowEnabled.js +171 -0
  1295. package/build/dist/UI/Components/Workflow/UseWorkflowEnabled.js.map +1 -0
  1296. package/build/dist/UI/Components/Workflow/Utils.js +95 -88
  1297. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  1298. package/build/dist/UI/Components/Workflow/ValuePicker/ArgumentControl.js +113 -0
  1299. package/build/dist/UI/Components/Workflow/ValuePicker/ArgumentControl.js.map +1 -0
  1300. package/build/dist/UI/Components/Workflow/ValuePicker/DefaultValueSources.js +95 -0
  1301. package/build/dist/UI/Components/Workflow/ValuePicker/DefaultValueSources.js.map +1 -0
  1302. package/build/dist/UI/Components/Workflow/ValuePicker/InsertValueButton.js +46 -0
  1303. package/build/dist/UI/Components/Workflow/ValuePicker/InsertValueButton.js.map +1 -0
  1304. package/build/dist/UI/Components/Workflow/ValuePicker/ReferenceChip.js +88 -0
  1305. package/build/dist/UI/Components/Workflow/ValuePicker/ReferenceChip.js.map +1 -0
  1306. package/build/dist/UI/Components/Workflow/ValuePicker/ReferenceDescription.js +187 -0
  1307. package/build/dist/UI/Components/Workflow/ValuePicker/ReferenceDescription.js.map +1 -0
  1308. package/build/dist/UI/Components/Workflow/ValuePicker/StepGraph.js +147 -0
  1309. package/build/dist/UI/Components/Workflow/ValuePicker/StepGraph.js.map +1 -0
  1310. package/build/dist/UI/Components/Workflow/ValuePicker/StepSampleSource.js +345 -0
  1311. package/build/dist/UI/Components/Workflow/ValuePicker/StepSampleSource.js.map +1 -0
  1312. package/build/dist/UI/Components/Workflow/ValuePicker/StepValueSource.js +181 -0
  1313. package/build/dist/UI/Components/Workflow/ValuePicker/StepValueSource.js.map +1 -0
  1314. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateText.js +172 -0
  1315. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateText.js.map +1 -0
  1316. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateTextDom.js +342 -0
  1317. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateTextDom.js.map +1 -0
  1318. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateTextEditor.js +701 -0
  1319. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateTextEditor.js.map +1 -0
  1320. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateTextHistory.js +104 -0
  1321. package/build/dist/UI/Components/Workflow/ValuePicker/TemplateTextHistory.js.map +1 -0
  1322. package/build/dist/UI/Components/Workflow/ValuePicker/ValuePickerContext.js +319 -0
  1323. package/build/dist/UI/Components/Workflow/ValuePicker/ValuePickerContext.js.map +1 -0
  1324. package/build/dist/UI/Components/Workflow/ValuePicker/ValuePickerMenu.js +502 -0
  1325. package/build/dist/UI/Components/Workflow/ValuePicker/ValuePickerMenu.js.map +1 -0
  1326. package/build/dist/UI/Components/Workflow/ValuePicker/ValuePickerPopup.js +176 -0
  1327. package/build/dist/UI/Components/Workflow/ValuePicker/ValuePickerPopup.js.map +1 -0
  1328. package/build/dist/UI/Components/Workflow/ValuePicker/ValueSingleField.js +111 -0
  1329. package/build/dist/UI/Components/Workflow/ValuePicker/ValueSingleField.js.map +1 -0
  1330. package/build/dist/UI/Components/Workflow/ValuePicker/ValueSuggestion.js +356 -0
  1331. package/build/dist/UI/Components/Workflow/ValuePicker/ValueSuggestion.js.map +1 -0
  1332. package/build/dist/UI/Components/Workflow/ValuePicker/ValueTextField.js +168 -0
  1333. package/build/dist/UI/Components/Workflow/ValuePicker/ValueTextField.js.map +1 -0
  1334. package/build/dist/UI/Components/Workflow/ValuePicker/VariableValueSource.js +80 -0
  1335. package/build/dist/UI/Components/Workflow/ValuePicker/VariableValueSource.js.map +1 -0
  1336. package/build/dist/UI/Components/Workflow/WebhookTriggerPanel.js +225 -0
  1337. package/build/dist/UI/Components/Workflow/WebhookTriggerPanel.js.map +1 -0
  1338. package/build/dist/UI/Components/Workflow/Workflow.js +256 -39
  1339. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  1340. package/build/dist/UI/Components/Workflow/WorkflowEnabledCopy.js +33 -0
  1341. package/build/dist/UI/Components/Workflow/WorkflowEnabledCopy.js.map +1 -0
  1342. package/build/dist/UI/Components/Workflow/WorkflowEnabledSwitch.js +18 -0
  1343. package/build/dist/UI/Components/Workflow/WorkflowEnabledSwitch.js.map +1 -0
  1344. package/build/dist/UI/Components/Workflow/WorkflowIncomingEmailSecretKey.js +97 -0
  1345. package/build/dist/UI/Components/Workflow/WorkflowIncomingEmailSecretKey.js.map +1 -0
  1346. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +41 -7
  1347. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -1
  1348. package/build/dist/UI/Components/Workflow/WorkflowRunExport.js +258 -0
  1349. package/build/dist/UI/Components/Workflow/WorkflowRunExport.js.map +1 -0
  1350. package/build/dist/UI/Components/Workflow/WorkflowRunExportActions.js +124 -0
  1351. package/build/dist/UI/Components/Workflow/WorkflowRunExportActions.js.map +1 -0
  1352. package/build/dist/UI/Components/Workflow/WorkflowStatus.js +16 -23
  1353. package/build/dist/UI/Components/Workflow/WorkflowStatus.js.map +1 -1
  1354. package/build/dist/UI/Components/Workflow/WorkflowTurnOnModal.js +60 -0
  1355. package/build/dist/UI/Components/Workflow/WorkflowTurnOnModal.js.map +1 -0
  1356. package/build/dist/UI/Components/Workflow/WorkflowTurnedOffNotice.js +34 -0
  1357. package/build/dist/UI/Components/Workflow/WorkflowTurnedOffNotice.js.map +1 -0
  1358. package/build/dist/UI/Components/Workflow/WorkflowWebhookSecretKey.js +112 -0
  1359. package/build/dist/UI/Components/Workflow/WorkflowWebhookSecretKey.js.map +1 -0
  1360. package/build/dist/UI/Utils/McpOAuthPendingAuthorization.js +111 -0
  1361. package/build/dist/UI/Utils/McpOAuthPendingAuthorization.js.map +1 -0
  1362. package/build/dist/UI/Utils/ModelDisplayName.js +197 -0
  1363. package/build/dist/UI/Utils/ModelDisplayName.js.map +1 -0
  1364. package/build/dist/UI/Utils/TranslateTemplate.js +63 -0
  1365. package/build/dist/UI/Utils/TranslateTemplate.js.map +1 -0
  1366. package/build/dist/Utils/DeveloperDocs/AiAssistantExamples.js +278 -0
  1367. package/build/dist/Utils/DeveloperDocs/AiAssistantExamples.js.map +1 -0
  1368. package/build/dist/Utils/DeveloperDocs/ApiExamples.js +225 -0
  1369. package/build/dist/Utils/DeveloperDocs/ApiExamples.js.map +1 -0
  1370. package/build/dist/Utils/DeveloperDocs/ExampleValues.js +90 -0
  1371. package/build/dist/Utils/DeveloperDocs/ExampleValues.js.map +1 -0
  1372. package/build/dist/Utils/DeveloperDocs/Hcl.js +449 -0
  1373. package/build/dist/Utils/DeveloperDocs/Hcl.js.map +1 -0
  1374. package/build/dist/Utils/DeveloperDocs/TerraformConfig.js +503 -0
  1375. package/build/dist/Utils/DeveloperDocs/TerraformConfig.js.map +1 -0
  1376. package/build/dist/Utils/DeveloperDocs/TerraformMonitorSteps.js +332 -0
  1377. package/build/dist/Utils/DeveloperDocs/TerraformMonitorSteps.js.map +1 -0
  1378. package/build/dist/Utils/DeveloperDocs/TerraformSchema.js +420 -0
  1379. package/build/dist/Utils/DeveloperDocs/TerraformSchema.js.map +1 -0
  1380. package/build/dist/Utils/DeveloperDocs/TerraformValues.js +280 -0
  1381. package/build/dist/Utils/DeveloperDocs/TerraformValues.js.map +1 -0
  1382. package/build/dist/Utils/Email/EmailAddressList.js +132 -0
  1383. package/build/dist/Utils/Email/EmailAddressList.js.map +1 -0
  1384. package/build/dist/Utils/ModelImportExport.js +15 -0
  1385. package/build/dist/Utils/ModelImportExport.js.map +1 -1
  1386. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js +54 -3
  1387. package/build/dist/Utils/Monitor/IncomingEmailMonitorAddress.js.map +1 -1
  1388. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +19 -1
  1389. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -1
  1390. package/build/dist/Utils/Monitor/MonitorPauseState.js +66 -0
  1391. package/build/dist/Utils/Monitor/MonitorPauseState.js.map +1 -0
  1392. package/build/dist/Utils/Rum/SessionIdentity.js +73 -0
  1393. package/build/dist/Utils/Rum/SessionIdentity.js.map +1 -1
  1394. package/build/dist/Utils/StatusPage/ArchivedMonitorResources.js +31 -0
  1395. package/build/dist/Utils/StatusPage/ArchivedMonitorResources.js.map +1 -0
  1396. package/package.json +1 -1
  1397. package/test-setup.sh +15 -1
  1398. package/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.tsx +0 -177
  1399. package/UI/Components/Workflow/ComponentValuePickerModal.tsx +0 -325
  1400. package/UI/Components/Workflow/VariableModal.tsx +0 -59
  1401. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js +0 -86
  1402. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js.map +0 -1
  1403. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +0 -144
  1404. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +0 -1
  1405. package/build/dist/UI/Components/Workflow/VariableModal.js +0 -31
  1406. package/build/dist/UI/Components/Workflow/VariableModal.js.map +0 -1
@@ -0,0 +1,2034 @@
1
+ import "@testing-library/jest-dom";
2
+ import {
3
+ afterEach,
4
+ beforeEach,
5
+ describe,
6
+ expect,
7
+ jest,
8
+ test,
9
+ } from "@jest/globals";
10
+ import {
11
+ act,
12
+ cleanup,
13
+ fireEvent,
14
+ render,
15
+ screen,
16
+ within,
17
+ } from "@testing-library/react";
18
+ import { Mock, SpyInstance } from "jest-mock";
19
+ import React from "react";
20
+ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
21
+ import HTTPResponse from "../../../Types/API/HTTPResponse";
22
+ import CookieName from "../../../Types/CookieName";
23
+ import { JSONObject } from "../../../Types/JSON";
24
+ import { APP_API_URL } from "../../../UI/Config";
25
+ import API from "../../../UI/Utils/API/API";
26
+ import Cookie from "../../../UI/Utils/Cookie";
27
+ import McpOAuthPendingAuthorization from "../../../UI/Utils/McpOAuthPendingAuthorization";
28
+ import Navigation from "../../../UI/Utils/Navigation";
29
+ import i18n from "../../../../App/FeatureSet/Accounts/src/Utils/i18n";
30
+ import {
31
+ MCP_OAUTH_CONSENT_APPROVE_API_URL,
32
+ MCP_OAUTH_CONSENT_DENY_API_URL,
33
+ MCP_OAUTH_CONSENT_DETAILS_API_URL,
34
+ } from "../../../../App/FeatureSet/Accounts/src/Utils/ApiPaths";
35
+ import McpAuthorizeUtil, {
36
+ KNOWN_DISPLAY_ERROR_CODES,
37
+ } from "../../../../App/FeatureSet/Accounts/src/Utils/McpAuthorize";
38
+ import McpAuthorizePage from "../../../../App/FeatureSet/Accounts/src/Pages/McpAuthorize";
39
+
40
+ /*
41
+ * The MCP consent screen, rendered for real with the Accounts translations.
42
+ *
43
+ * This is the page an MCP client sends a person to, and the only place in the
44
+ * product where a person hands their access to something else. So what it
45
+ * shows, what it offers and what it sends are each pinned from the outside:
46
+ *
47
+ * - It says who is asking in the terms that cannot be faked - where the
48
+ * browser goes next, and the host a client's metadata document lives on -
49
+ * and says plainly when all it has is a name the client typed.
50
+ * - It never offers more than the client asked for, never preselects among
51
+ * several projects, and never lets a project the server refused be chosen.
52
+ * - It sends exactly the request it was opened with, the project and the
53
+ * access that are on screen, and then goes where the SERVER says - unless
54
+ * that is somewhere a browser must not be sent.
55
+ * - Nothing in the address bar is ever printed: an error is a code with
56
+ * fixed wording, and a request is an opaque ticket.
57
+ * - A visitor who is not signed in keeps their request across the sign-in.
58
+ *
59
+ * The page, the pending-request cookie and i18next are real; only the network
60
+ * (API.post) and the final navigation (window.location.assign) are recorded
61
+ * instead of performed. The wording is read from the locale through i18n, so
62
+ * the suite follows the copy rather than freezing it.
63
+ */
64
+
65
+ const TICKET: string = `v1.${"cGF5bG9hZA".repeat(4)}.${"s".repeat(43)}`;
66
+ const OTHER_TICKET: string = `v1.${"b3RoZXI".repeat(4)}.${"t".repeat(43)}`;
67
+
68
+ const PAGE_PATH: string = "/accounts/mcp-authorize";
69
+ const PAGE_URL: string = `http://localhost${PAGE_PATH}`;
70
+
71
+ // Where the dashboard is served, and so where the pending request is kept.
72
+ const DASHBOARD_PATH: string = "/dashboard";
73
+ const PENDING_REQUEST_COOKIE: string = "oneuptime-mcp-oauth-pending-request";
74
+
75
+ const PRODUCTION_ID: string = "11111111-1111-4111-8111-111111111111";
76
+ const STAGING_ID: string = "22222222-2222-4222-8222-222222222222";
77
+ const FINANCE_ID: string = "33333333-3333-4333-8333-333333333333";
78
+ const SIDE_PROJECT_ID: string = "44444444-4444-4444-8444-444444444444";
79
+
80
+ const HOSTED_REDIRECT: string =
81
+ "https://claude.ai/api/mcp/auth_callback?code=oumcp_ac_abc&state=xyz&iss=http%3A%2F%2Flocalhost%2Fmcp";
82
+ const DENIED_REDIRECT: string =
83
+ "https://claude.ai/api/mcp/auth_callback?error=access_denied&error_description=The+request+was+denied.&state=xyz";
84
+
85
+ const TEST_UTILS_ACT_DEPRECATION: string =
86
+ "`ReactDOMTestUtils.act` is deprecated";
87
+
88
+ interface ProjectAnswer {
89
+ id: string;
90
+ name: string;
91
+ isEligible: boolean;
92
+ refusal: string | null;
93
+ }
94
+
95
+ const PRODUCTION: ProjectAnswer = {
96
+ id: PRODUCTION_ID,
97
+ name: "Acme Production",
98
+ isEligible: true,
99
+ refusal: null,
100
+ };
101
+ const STAGING: ProjectAnswer = {
102
+ id: STAGING_ID,
103
+ name: "Acme Staging",
104
+ isEligible: true,
105
+ refusal: null,
106
+ };
107
+ const FINANCE_NEEDS_SSO: ProjectAnswer = {
108
+ id: FINANCE_ID,
109
+ name: "Acme Finance",
110
+ isEligible: false,
111
+ refusal: "sso",
112
+ };
113
+ const SIDE_PROJECT_ON_FREE_PLAN: ProjectAnswer = {
114
+ id: SIDE_PROJECT_ID,
115
+ name: "Side Project",
116
+ isEligible: false,
117
+ refusal: "plan",
118
+ };
119
+
120
+ // A client identified by a metadata document, sending the code to its site.
121
+ const HOSTED_CLIENT: JSONObject = {
122
+ name: "Claude",
123
+ verifiedHost: "claude.ai",
124
+ uri: "https://claude.ai/",
125
+ redirectTarget: "claude.ai",
126
+ isLoopbackRedirect: false,
127
+ };
128
+
129
+ // A client that registered itself, listening on this machine.
130
+ const LOCAL_CLIENT: JSONObject = {
131
+ name: "Claude Code",
132
+ verifiedHost: null,
133
+ uri: null,
134
+ redirectTarget: "localhost:33418",
135
+ isLoopbackRedirect: true,
136
+ };
137
+
138
+ type DetailsFunction = (overrides?: JSONObject) => JSONObject;
139
+
140
+ const details: DetailsFunction = (overrides: JSONObject = {}): JSONObject => {
141
+ return {
142
+ client: HOSTED_CLIENT,
143
+ requestedAccess: "write",
144
+ user: { email: "ada@example.com", name: "Ada Lovelace" },
145
+ projects: [PRODUCTION] as unknown as JSONObject,
146
+ ...overrides,
147
+ };
148
+ };
149
+
150
+ type Answer = () => Promise<HTTPResponse<JSONObject>>;
151
+
152
+ type OkFunction = (body: JSONObject) => Answer;
153
+
154
+ const ok: OkFunction = (body: JSONObject): Answer => {
155
+ return async (): Promise<HTTPResponse<JSONObject>> => {
156
+ return new HTTPResponse<JSONObject>(200, body, {});
157
+ };
158
+ };
159
+
160
+ type RefusedFunction = (statusCode: number, message: string) => Answer;
161
+
162
+ // What API.post resolves with for a non-2xx answer.
163
+ const refused: RefusedFunction = (
164
+ statusCode: number,
165
+ message: string,
166
+ ): Answer => {
167
+ return async (): Promise<HTTPResponse<JSONObject>> => {
168
+ return new HTTPErrorResponse(statusCode, { message }, {});
169
+ };
170
+ };
171
+
172
+ interface Deferred {
173
+ answer: Answer;
174
+ resolve: (response: HTTPResponse<JSONObject>) => Promise<void>;
175
+ }
176
+
177
+ type DeferredFunction = () => Deferred;
178
+
179
+ // An answer that arrives when the test says so.
180
+ const deferred: DeferredFunction = (): Deferred => {
181
+ let release: (response: HTTPResponse<JSONObject>) => void = (): void => {};
182
+
183
+ const promise: Promise<HTTPResponse<JSONObject>> = new Promise<
184
+ HTTPResponse<JSONObject>
185
+ >((resolve: (response: HTTPResponse<JSONObject>) => void) => {
186
+ release = resolve;
187
+ });
188
+
189
+ return {
190
+ answer: (): Promise<HTTPResponse<JSONObject>> => {
191
+ return promise;
192
+ },
193
+ resolve: async (response: HTTPResponse<JSONObject>): Promise<void> => {
194
+ await act(async () => {
195
+ release(response);
196
+ await promise;
197
+ });
198
+ },
199
+ };
200
+ };
201
+
202
+ interface PostedRequest {
203
+ url: string;
204
+ data: unknown;
205
+ }
206
+
207
+ let posted: Array<PostedRequest> = [];
208
+ let answers: { details: Answer; approve: Answer; deny: Answer };
209
+ let assign: Mock<(url: string) => void>;
210
+ let consoleErrors: SpyInstance<typeof console.error>;
211
+
212
+ const originalLocation: Location = window.location;
213
+
214
+ type ConfigureLocationFunction = (search: string) => void;
215
+
216
+ /*
217
+ * The page reads its query off window.location and leaves through
218
+ * window.location.assign. jsdom's own Location cannot be spied on, so it is
219
+ * replaced with a URL that has a recording `assign`. The document itself is
220
+ * moved to the page's real path as well, because that is what decides which
221
+ * cookies the page can see: the pending request is kept for the dashboard's
222
+ * path, so the consent screen writes it without being able to read it back.
223
+ */
224
+ const configureLocation: ConfigureLocationFunction = (search: string): void => {
225
+ window.history.pushState({}, "", `${PAGE_PATH}${search}`);
226
+
227
+ Object.defineProperty(window, "location", {
228
+ configurable: true,
229
+ value: Object.assign(new globalThis.URL(`${PAGE_URL}${search}`), {
230
+ assign,
231
+ }),
232
+ });
233
+ };
234
+
235
+ type RenderPageFunction = (
236
+ search?: string,
237
+ ) => Promise<ReturnType<typeof render>>;
238
+
239
+ const renderPage: RenderPageFunction = async (
240
+ search: string = `?request=${TICKET}`,
241
+ ): Promise<ReturnType<typeof render>> => {
242
+ configureLocation(search);
243
+
244
+ let result: ReturnType<typeof render> | undefined;
245
+
246
+ await act(async () => {
247
+ result = render(<McpAuthorizePage />);
248
+ });
249
+
250
+ return result as ReturnType<typeof render>;
251
+ };
252
+
253
+ type SayFunction = (key: string, values?: Record<string, string>) => string;
254
+
255
+ // The wording the page should show, straight from the locale.
256
+ const say: SayFunction = (
257
+ key: string,
258
+ values?: Record<string, string>,
259
+ ): string => {
260
+ return i18n.t(`mcpAuthorize.${key}`, values || {});
261
+ };
262
+
263
+ type RequestsToFunction = (url: { toString: () => string }) => Array<unknown>;
264
+
265
+ const requestsTo: RequestsToFunction = (url: {
266
+ toString: () => string;
267
+ }): Array<unknown> => {
268
+ return posted
269
+ .filter((request: PostedRequest): boolean => {
270
+ return request.url === url.toString();
271
+ })
272
+ .map((request: PostedRequest): unknown => {
273
+ return request.data;
274
+ });
275
+ };
276
+
277
+ type ElementFunction = () => HTMLElement;
278
+
279
+ const approveButton: ElementFunction = (): HTMLElement => {
280
+ return screen.getByTestId("mcp-authorize-approve");
281
+ };
282
+
283
+ const denyButton: ElementFunction = (): HTMLElement => {
284
+ return screen.getByTestId("mcp-authorize-deny");
285
+ };
286
+
287
+ type SelectFunction = () => HTMLSelectElement;
288
+
289
+ const projectSelect: SelectFunction = (): HTMLSelectElement => {
290
+ return screen.getByTestId("mcp-authorize-project") as HTMLSelectElement;
291
+ };
292
+
293
+ type OptionsFunction = () => Array<HTMLOptionElement>;
294
+
295
+ const projectOptions: OptionsFunction = (): Array<HTMLOptionElement> => {
296
+ return Array.from(projectSelect().options);
297
+ };
298
+
299
+ type RadioFunction = (level: "read" | "write") => HTMLInputElement | null;
300
+
301
+ const accessRadio: RadioFunction = (
302
+ level: "read" | "write",
303
+ ): HTMLInputElement | null => {
304
+ return screen.queryByTestId(
305
+ `mcp-authorize-access-${level}`,
306
+ ) as HTMLInputElement | null;
307
+ };
308
+
309
+ type ClickFunction = (element: HTMLElement) => Promise<void>;
310
+
311
+ const click: ClickFunction = async (element: HTMLElement): Promise<void> => {
312
+ await act(async () => {
313
+ fireEvent.click(element);
314
+ });
315
+ };
316
+
317
+ type ChooseProjectFunction = (projectId: string) => Promise<void>;
318
+
319
+ const chooseProject: ChooseProjectFunction = async (
320
+ projectId: string,
321
+ ): Promise<void> => {
322
+ await act(async () => {
323
+ fireEvent.change(projectSelect(), { target: { value: projectId } });
324
+ });
325
+ };
326
+
327
+ type AsTheDashboardFunction = <T>(read: () => T) => T;
328
+
329
+ /*
330
+ * Runs `read` with the document where the dashboard is served - the only
331
+ * place the pending request's cookie is visible - and puts the document back
332
+ * on the consent screen afterwards.
333
+ */
334
+ const asTheDashboard: AsTheDashboardFunction = <T,>(read: () => T): T => {
335
+ const pagePath: string = `${window.location.pathname}${window.location.search}`;
336
+
337
+ window.history.pushState({}, "", DASHBOARD_PATH);
338
+
339
+ try {
340
+ return read();
341
+ } finally {
342
+ window.history.pushState({}, "", pagePath);
343
+ }
344
+ };
345
+
346
+ type IsRememberedFunction = () => boolean;
347
+
348
+ // Whether a request is waiting for the dashboard. Looks; does not take.
349
+ const isRequestRemembered: IsRememberedFunction = (): boolean => {
350
+ return asTheDashboard((): boolean => {
351
+ return document.cookie.includes(`${PENDING_REQUEST_COOKIE}=`);
352
+ });
353
+ };
354
+
355
+ type RememberedFunction = () => string | null;
356
+
357
+ /*
358
+ * The request the dashboard would be sent back with after a sign-in, read the
359
+ * way the dashboard reads it. Reading it forgets it, as it does there.
360
+ */
361
+ const rememberedRoute: RememberedFunction = (): string | null => {
362
+ return asTheDashboard((): string | null => {
363
+ return McpOAuthPendingAuthorization.consumeRoute()?.toString() || null;
364
+ });
365
+ };
366
+
367
+ type TextsFunction = (root: Node) => Array<string>;
368
+
369
+ // Every piece of text a person can read under `root`.
370
+ const visibleTexts: TextsFunction = (root: Node): Array<string> => {
371
+ const texts: Array<string> = [];
372
+
373
+ for (const child of Array.from(root.childNodes)) {
374
+ if (child.nodeType === Node.TEXT_NODE) {
375
+ const text: string = (child.textContent || "").trim();
376
+
377
+ if (text) {
378
+ texts.push(text);
379
+ }
380
+
381
+ continue;
382
+ }
383
+
384
+ texts.push(...visibleTexts(child));
385
+ }
386
+
387
+ return texts;
388
+ };
389
+
390
+ beforeEach(() => {
391
+ posted = [];
392
+ assign = jest.fn<(url: string) => void>();
393
+ answers = {
394
+ details: ok(details()),
395
+ approve: ok({ redirectUrl: HOSTED_REDIRECT }),
396
+ deny: ok({ redirectUrl: DENIED_REDIRECT }),
397
+ };
398
+
399
+ McpOAuthPendingAuthorization.clear();
400
+ consoleErrors = jest.spyOn(console, "error");
401
+
402
+ jest
403
+ .spyOn(API, "post")
404
+ .mockImplementation(
405
+ async (
406
+ options: Parameters<typeof API.post>[0],
407
+ ): Promise<HTTPResponse<JSONObject>> => {
408
+ const url: string = options.url.toString();
409
+
410
+ posted.push({ url, data: options.data });
411
+
412
+ if (url === MCP_OAUTH_CONSENT_DETAILS_API_URL.toString()) {
413
+ return answers.details();
414
+ }
415
+
416
+ if (url === MCP_OAUTH_CONSENT_APPROVE_API_URL.toString()) {
417
+ return answers.approve();
418
+ }
419
+
420
+ if (url === MCP_OAUTH_CONSENT_DENY_API_URL.toString()) {
421
+ return answers.deny();
422
+ }
423
+
424
+ // What signing a visitor out posts to; only one test gets that far.
425
+ if (url.endsWith("/logout")) {
426
+ return new HTTPResponse<JSONObject>(200, {}, {});
427
+ }
428
+
429
+ throw new Error(`Unexpected request to ${url}`);
430
+ },
431
+ );
432
+ });
433
+
434
+ afterEach(async () => {
435
+ cleanup();
436
+
437
+ const reportedErrors: Array<string> = consoleErrors.mock.calls
438
+ .map((call: Array<unknown>): string => {
439
+ return call.map(String).join(" ");
440
+ })
441
+ .filter((message: string): boolean => {
442
+ return !message.includes(TEST_UTILS_ACT_DEPRECATION);
443
+ });
444
+
445
+ jest.restoreAllMocks();
446
+ McpOAuthPendingAuthorization.clear();
447
+
448
+ Object.defineProperty(window, "location", {
449
+ configurable: true,
450
+ value: originalLocation,
451
+ });
452
+ window.history.pushState({}, "", "/");
453
+
454
+ if (i18n.language !== "en") {
455
+ await i18n.changeLanguage("en");
456
+ }
457
+
458
+ // React warnings (bad keys, uncontrolled inputs) are failures here.
459
+ expect(reportedErrors).toEqual([]);
460
+ });
461
+
462
+ describe("the consent screen's API addresses", () => {
463
+ test("are on the app's own origin, under /mcp/oauth/consent and not under /api", () => {
464
+ const apiUrl: globalThis.URL = new globalThis.URL(APP_API_URL.toString());
465
+
466
+ // The API itself lives under /api; these three deliberately do not.
467
+ expect(apiUrl.pathname).toBe("/api");
468
+
469
+ const expected: Array<[{ toString: () => string }, string]> = [
470
+ [MCP_OAUTH_CONSENT_DETAILS_API_URL, "/mcp/oauth/consent/details"],
471
+ [MCP_OAUTH_CONSENT_APPROVE_API_URL, "/mcp/oauth/consent/approve"],
472
+ [MCP_OAUTH_CONSENT_DENY_API_URL, "/mcp/oauth/consent/deny"],
473
+ ];
474
+
475
+ for (const [url, path] of expected) {
476
+ const parsed: globalThis.URL = new globalThis.URL(url.toString());
477
+
478
+ expect(parsed.origin).toBe(apiUrl.origin);
479
+ expect(parsed.pathname).toBe(path);
480
+ expect(parsed.search).toBe("");
481
+ expect(parsed.hash).toBe("");
482
+ }
483
+ });
484
+
485
+ test("the wording really is loaded: a key resolves to a sentence, not to itself", () => {
486
+ // Every expectation below compares against say(); this keeps it honest.
487
+ expect(say("title")).not.toBe("mcpAuthorize.title");
488
+ expect(say("title").length).toBeGreaterThan(0);
489
+ expect(say("wantsAccess", { clientName: "Claude" })).toContain("Claude");
490
+ expect(say("errors.server_error")).not.toContain("mcpAuthorize");
491
+ });
492
+ });
493
+
494
+ describe("opened without a usable request", () => {
495
+ test("no request at all shows the fixed missing-request wording and asks the server nothing", async () => {
496
+ await renderPage("");
497
+
498
+ const problem: HTMLElement = screen.getByTestId("mcp-authorize-problem");
499
+
500
+ expect(problem).toHaveTextContent(say("errorTitle"));
501
+ expect(problem).toHaveTextContent(say("errors.missing_request"));
502
+ expect(problem).toHaveTextContent(say("errorHelp"));
503
+ expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent(
504
+ say("title"),
505
+ );
506
+
507
+ expect(posted).toEqual([]);
508
+ expect(assign).not.toHaveBeenCalled();
509
+ expect(rememberedRoute()).toBeNull();
510
+
511
+ // Nothing to decide, so nothing to press.
512
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
513
+ expect(screen.queryByTestId("mcp-authorize-deny")).toBeNull();
514
+ });
515
+
516
+ test.each([
517
+ ["words", "request=please+let+me+in"],
518
+ ["markup", "request=%3Cscript%3Ealert(1)%3C%2Fscript%3E"],
519
+ ["a ticket with a part missing", `request=v1.${"s".repeat(43)}`],
520
+ ["a ticket with a short signature", `request=v1.abc.${"s".repeat(42)}`],
521
+ ["a ticket of another version", `request=v2.abc.${"s".repeat(43)}`],
522
+ ["a JSON web token", "request=eyJhbGciOiJIUzI1NiJ9.eyJ1IjoxfQ.c2ln"],
523
+ ["an empty value", "request="],
524
+ ])(
525
+ "%s in place of a ticket is treated as no request, and is never sent or shown",
526
+ async (_label: string, query: string) => {
527
+ const { container } = await renderPage(`?${query}`);
528
+
529
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
530
+ say("errors.missing_request"),
531
+ );
532
+ expect(posted).toEqual([]);
533
+ expect(rememberedRoute()).toBeNull();
534
+
535
+ const value: string = decodeURIComponent(
536
+ query.slice("request=".length).replace(/\+/g, " "),
537
+ );
538
+
539
+ if (value) {
540
+ expect(container.textContent).not.toContain(value);
541
+ }
542
+
543
+ expect(container.querySelector("script")).toBeNull();
544
+ },
545
+ );
546
+ });
547
+
548
+ describe("opened with an error from the authorization endpoint", () => {
549
+ test.each(KNOWN_DISPLAY_ERROR_CODES)(
550
+ "%s shows that code's own fixed wording",
551
+ async (code: string) => {
552
+ await renderPage(`?error=${code}`);
553
+
554
+ const problem: HTMLElement = screen.getByTestId("mcp-authorize-problem");
555
+
556
+ expect(problem).toHaveTextContent(say(`errors.${code}`));
557
+ expect(problem).toHaveTextContent(say("errorTitle"));
558
+ expect(problem).toHaveTextContent(say("errorHelp"));
559
+
560
+ // A code is never echoed; it selects a sentence.
561
+ expect(say(`errors.${code}`)).not.toContain("mcpAuthorize.errors");
562
+ expect(problem.textContent).not.toContain(code);
563
+ expect(posted).toEqual([]);
564
+ },
565
+ );
566
+
567
+ test("each code has wording of its own, apart from the generic one it falls back to", () => {
568
+ const sentences: Set<string> = new Set<string>(
569
+ KNOWN_DISPLAY_ERROR_CODES.map((code: string): string => {
570
+ return say(`errors.${code}`);
571
+ }),
572
+ );
573
+
574
+ expect(sentences.size).toBe(KNOWN_DISPLAY_ERROR_CODES.length);
575
+ });
576
+
577
+ test.each([
578
+ ["markup", "<img src=x onerror=alert(1)>", "onerror"],
579
+ ["a script tag", "<script>alert(document.cookie)</script>", "alert("],
580
+ [
581
+ "a sentence somebody wants OneUptime to say",
582
+ "Your account is locked. Call +1 555 0100 to unlock it.",
583
+ "555 0100",
584
+ ],
585
+ ["a code the page does not know", "totally_made_up", "totally_made_up"],
586
+ ["the page's own missing-request code", "missing_request", ""],
587
+ ["a path into another part of the locale", "../login.title", "login.title"],
588
+ ["an OAuth error code", "access_denied", "access_denied"],
589
+ ])(
590
+ "%s in ?error= shows the generic wording, and none of the address bar's text",
591
+ async (_label: string, value: string, fragment: string) => {
592
+ const { container } = await renderPage(
593
+ `?error=${encodeURIComponent(value)}`,
594
+ );
595
+
596
+ const problem: HTMLElement = screen.getByTestId("mcp-authorize-problem");
597
+
598
+ expect(problem).toHaveTextContent(say("errors.server_error"));
599
+ expect(problem).not.toHaveTextContent(say("errors.missing_request"));
600
+
601
+ if (fragment) {
602
+ expect(container.textContent).not.toContain(fragment);
603
+ expect(container.innerHTML).not.toContain(fragment);
604
+ }
605
+
606
+ // The logo is the page's only image, and nothing became a script.
607
+ expect(container.querySelectorAll("img")).toHaveLength(1);
608
+ expect(container.querySelector("script")).toBeNull();
609
+ expect(posted).toEqual([]);
610
+ },
611
+ );
612
+
613
+ test("an error wins over a request in the same address: nothing is loaded or remembered", async () => {
614
+ await renderPage(`?error=unknown_client&request=${TICKET}`);
615
+
616
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
617
+ say("errors.unknown_client"),
618
+ );
619
+ expect(posted).toEqual([]);
620
+ expect(rememberedRoute()).toBeNull();
621
+ });
622
+
623
+ test("an empty ?error= is no error: the request is loaded", async () => {
624
+ await renderPage(`?error=&request=${TICKET}`);
625
+
626
+ expect(screen.queryByTestId("mcp-authorize-problem")).toBeNull();
627
+ expect(requestsTo(MCP_OAUTH_CONSENT_DETAILS_API_URL)).toEqual([
628
+ { request: TICKET },
629
+ ]);
630
+ });
631
+ });
632
+
633
+ describe("loading the request", () => {
634
+ test("asks the server about exactly the ticket in the address", async () => {
635
+ const { container } = await renderPage(`?request=${OTHER_TICKET}`);
636
+
637
+ expect(posted).toEqual([
638
+ {
639
+ url: MCP_OAUTH_CONSENT_DETAILS_API_URL.toString(),
640
+ data: { request: OTHER_TICKET },
641
+ },
642
+ ]);
643
+
644
+ // The ticket is machinery: it is sent, never shown.
645
+ expect(screen.getByTestId("mcp-authorize-client")).toBeInTheDocument();
646
+ expect(container.innerHTML).not.toContain(OTHER_TICKET);
647
+ });
648
+
649
+ test("shows a loader, and nothing to decide on, until the server answers", async () => {
650
+ const pending: Deferred = deferred();
651
+ answers.details = pending.answer;
652
+
653
+ await renderPage();
654
+
655
+ expect(screen.getByRole("status")).toBeInTheDocument();
656
+ expect(screen.queryByTestId("mcp-authorize-client")).toBeNull();
657
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
658
+ expect(screen.queryByTestId("mcp-authorize-deny")).toBeNull();
659
+ expect(screen.queryByTestId("mcp-authorize-problem")).toBeNull();
660
+
661
+ await pending.resolve(new HTTPResponse<JSONObject>(200, details(), {}));
662
+
663
+ expect(screen.queryByRole("status")).toBeNull();
664
+ expect(screen.getByTestId("mcp-authorize-client")).toBeInTheDocument();
665
+ expect(approveButton()).toBeInTheDocument();
666
+ });
667
+
668
+ test("a refusal from the server is shown in the server's words", async () => {
669
+ answers.details = refused(
670
+ 400,
671
+ "This authorization request has expired. Go back to your MCP client and start connecting again.",
672
+ );
673
+
674
+ await renderPage();
675
+
676
+ const problem: HTMLElement = screen.getByTestId("mcp-authorize-problem");
677
+
678
+ expect(problem).toHaveTextContent(say("errorTitle"));
679
+ expect(problem).toHaveTextContent(
680
+ "This authorization request has expired. Go back to your MCP client and start connecting again.",
681
+ );
682
+ expect(problem).toHaveTextContent(say("errorHelp"));
683
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
684
+ });
685
+
686
+ test("a refusal that contains markup is shown as text", async () => {
687
+ answers.details = refused(403, "<img src=x onerror=alert(1)> Forbidden");
688
+
689
+ const { container } = await renderPage();
690
+
691
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
692
+ "<img src=x onerror=alert(1)> Forbidden",
693
+ );
694
+ expect(container.querySelectorAll("img")).toHaveLength(1);
695
+ });
696
+
697
+ test("a request that fails outright is reported, not left spinning", async () => {
698
+ answers.details = async (): Promise<HTTPResponse<JSONObject>> => {
699
+ throw new Error("Network Error");
700
+ };
701
+
702
+ await renderPage();
703
+
704
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
705
+ "Network Error",
706
+ );
707
+ expect(screen.queryByRole("status")).toBeNull();
708
+ });
709
+
710
+ test.each([
711
+ ["an empty answer", {}],
712
+ ["an answer with no projects list", { ...details(), projects: null }],
713
+ ["an answer with no client", { ...details(), client: null }],
714
+ ["an answer with no user", { ...details(), user: "ada@example.com" }],
715
+ ] as Array<[string, JSONObject]>)(
716
+ "%s shows the generic error rather than a half-drawn screen",
717
+ async (_label: string, body: JSONObject) => {
718
+ answers.details = ok(body);
719
+
720
+ await renderPage();
721
+
722
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
723
+ say("errors.server_error"),
724
+ );
725
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
726
+ expect(screen.queryByTestId("mcp-authorize-client")).toBeNull();
727
+ },
728
+ );
729
+ });
730
+
731
+ describe("who is asking", () => {
732
+ test("the client's name is in the sentence under the title", async () => {
733
+ await renderPage();
734
+
735
+ expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent(
736
+ say("title"),
737
+ );
738
+ expect(screen.getByTestId("mcp-authorize-subtitle")).toHaveTextContent(
739
+ say("wantsAccess", { clientName: "Claude" }),
740
+ );
741
+ });
742
+
743
+ test("a client identified by a metadata document shows the host it is published at", async () => {
744
+ await renderPage();
745
+
746
+ const who: HTMLElement = screen.getByTestId("mcp-authorize-client");
747
+
748
+ expect(within(who).getByText(say("verifiedHostLabel"))).toBeInTheDocument();
749
+ expect(screen.getByTestId("mcp-authorize-verified-host")).toHaveTextContent(
750
+ "claude.ai",
751
+ );
752
+ expect(screen.getByTestId("mcp-authorize-verified-host").textContent).toBe(
753
+ "claude.ai",
754
+ );
755
+ expect(within(who).getByText(say("verifiedHostHelp"))).toBeInTheDocument();
756
+
757
+ // The host is the verified part, so nothing says "unverified" beside it.
758
+ expect(screen.queryByTestId("mcp-authorize-unverified-name")).toBeNull();
759
+ expect(screen.queryByText(say("unverifiedNameHelp"))).toBeNull();
760
+ });
761
+
762
+ test("a client that only has a name it chose is said to be unverified, and shows no host", async () => {
763
+ answers.details = ok(details({ client: LOCAL_CLIENT }));
764
+
765
+ await renderPage();
766
+
767
+ expect(
768
+ screen.getByTestId("mcp-authorize-unverified-name"),
769
+ ).toHaveTextContent(say("unverifiedNameHelp"));
770
+
771
+ expect(screen.queryByTestId("mcp-authorize-verified-host")).toBeNull();
772
+ expect(screen.queryByText(say("verifiedHostLabel"))).toBeNull();
773
+ expect(screen.queryByText(say("verifiedHostHelp"))).toBeNull();
774
+ });
775
+
776
+ test("an empty verified host counts as none", async () => {
777
+ answers.details = ok(
778
+ details({ client: { ...HOSTED_CLIENT, verifiedHost: "" } }),
779
+ );
780
+
781
+ await renderPage();
782
+
783
+ expect(screen.queryByTestId("mcp-authorize-verified-host")).toBeNull();
784
+ expect(
785
+ screen.getByTestId("mcp-authorize-unverified-name"),
786
+ ).toBeInTheDocument();
787
+ });
788
+
789
+ test("a name is shown exactly as the client typed it, never interpreted", async () => {
790
+ const name: string =
791
+ "Tom & Jerry's <b>MCP</b> <img src=x onerror=alert(1)>";
792
+
793
+ answers.details = ok(details({ client: { ...LOCAL_CLIENT, name } }));
794
+
795
+ const { container } = await renderPage();
796
+
797
+ expect(screen.getByTestId("mcp-authorize-subtitle").textContent).toBe(
798
+ say("wantsAccess", { clientName: name }),
799
+ );
800
+ expect(screen.getByTestId("mcp-authorize-subtitle").textContent).toContain(
801
+ name,
802
+ );
803
+ expect(container.querySelector("b")).toBeNull();
804
+ expect(container.querySelectorAll("img")).toHaveLength(1);
805
+ });
806
+
807
+ test("the member sees which account is about to be used", async () => {
808
+ await renderPage();
809
+
810
+ expect(screen.getByTestId("mcp-authorize-signed-in-as")).toHaveTextContent(
811
+ say("signedInAs", { email: "ada@example.com" }),
812
+ );
813
+ });
814
+ });
815
+
816
+ describe("where the browser goes next", () => {
817
+ test("a hosted client: the host, in the sent-to wording, with no device warning", async () => {
818
+ await renderPage();
819
+
820
+ const who: HTMLElement = screen.getByTestId("mcp-authorize-client");
821
+
822
+ expect(within(who).getByText(say("redirectLabel"))).toBeInTheDocument();
823
+ expect(
824
+ screen.getByTestId("mcp-authorize-redirect-target").textContent,
825
+ ).toBe(say("redirectToHost", { target: "claude.ai" }));
826
+ expect(screen.queryByTestId("mcp-authorize-loopback-warning")).toBeNull();
827
+ expect(screen.queryByText(say("loopbackWarning"))).toBeNull();
828
+ });
829
+
830
+ test("a client on this machine: the this-device wording, and the warning that any local app could be listening", async () => {
831
+ answers.details = ok(details({ client: LOCAL_CLIENT }));
832
+
833
+ await renderPage();
834
+
835
+ expect(
836
+ screen.getByTestId("mcp-authorize-redirect-target").textContent,
837
+ ).toBe(say("redirectToThisDevice", { target: "localhost:33418" }));
838
+
839
+ const warning: HTMLElement = screen.getByTestId(
840
+ "mcp-authorize-loopback-warning",
841
+ );
842
+
843
+ expect(warning).toHaveTextContent(say("loopbackWarning"));
844
+ expect(warning).toHaveAttribute("role", "alert");
845
+ });
846
+
847
+ test("the two wordings are different sentences", () => {
848
+ expect(say("redirectToHost", { target: "x" })).not.toBe(
849
+ say("redirectToThisDevice", { target: "x" }),
850
+ );
851
+ });
852
+
853
+ test("a hosted client with a verified host can still be going to this device, and is warned about", async () => {
854
+ answers.details = ok(
855
+ details({
856
+ client: {
857
+ ...HOSTED_CLIENT,
858
+ redirectTarget: "127.0.0.1:8976",
859
+ isLoopbackRedirect: true,
860
+ },
861
+ }),
862
+ );
863
+
864
+ await renderPage();
865
+
866
+ expect(screen.getByTestId("mcp-authorize-verified-host")).toHaveTextContent(
867
+ "claude.ai",
868
+ );
869
+ expect(
870
+ screen.getByTestId("mcp-authorize-loopback-warning"),
871
+ ).toBeInTheDocument();
872
+ expect(
873
+ screen.getByTestId("mcp-authorize-redirect-target").textContent,
874
+ ).toBe(say("redirectToThisDevice", { target: "127.0.0.1:8976" }));
875
+ });
876
+ });
877
+
878
+ describe("choosing the project", () => {
879
+ test("the list is labelled, starts with a placeholder, and names every project in the server's order", async () => {
880
+ answers.details = ok(
881
+ details({
882
+ projects: [
883
+ FINANCE_NEEDS_SSO,
884
+ PRODUCTION,
885
+ SIDE_PROJECT_ON_FREE_PLAN,
886
+ STAGING,
887
+ ] as unknown as JSONObject,
888
+ }),
889
+ );
890
+
891
+ await renderPage();
892
+
893
+ expect(screen.getByLabelText(say("projectLabel"))).toBe(projectSelect());
894
+ expect(screen.getByText(say("projectHelp"))).toBeInTheDocument();
895
+
896
+ expect(
897
+ projectOptions().map((option: HTMLOptionElement): string => {
898
+ return option.value;
899
+ }),
900
+ ).toEqual(["", FINANCE_ID, PRODUCTION_ID, SIDE_PROJECT_ID, STAGING_ID]);
901
+ expect(projectOptions()[0]!.textContent).toBe(say("projectPlaceholder"));
902
+ });
903
+
904
+ test("a project the server refused cannot be picked, and says why", async () => {
905
+ answers.details = ok(
906
+ details({
907
+ projects: [
908
+ PRODUCTION,
909
+ FINANCE_NEEDS_SSO,
910
+ SIDE_PROJECT_ON_FREE_PLAN,
911
+ {
912
+ id: "55555555-5555-4555-8555-555555555555",
913
+ name: "Locked Down",
914
+ isEligible: false,
915
+ refusal: "blocked",
916
+ },
917
+ {
918
+ id: "66666666-6666-4666-8666-666666666666",
919
+ name: "Left Behind",
920
+ isEligible: false,
921
+ refusal: "not-a-member",
922
+ },
923
+ ] as unknown as JSONObject,
924
+ }),
925
+ );
926
+
927
+ await renderPage();
928
+
929
+ const options: Array<HTMLOptionElement> = projectOptions();
930
+
931
+ expect(options[1]!.textContent).toBe("Acme Production");
932
+ expect(options[1]!.disabled).toBe(false);
933
+
934
+ expect(options[2]!.textContent).toBe(
935
+ say("projectRefusal.sso", { name: "Acme Finance" }),
936
+ );
937
+ expect(options[3]!.textContent).toBe(
938
+ say("projectRefusal.plan", { name: "Side Project" }),
939
+ );
940
+ expect(options[4]!.textContent).toBe(
941
+ say("projectRefusal.blocked", { name: "Locked Down" }),
942
+ );
943
+ expect(options[5]!.textContent).toBe(
944
+ say("projectRefusal.not-a-member", { name: "Left Behind" }),
945
+ );
946
+
947
+ for (const option of options.slice(2)) {
948
+ expect(option.disabled).toBe(true);
949
+ // The reason is in the option itself, beside the project's name.
950
+ expect(option.textContent).not.toContain("mcpAuthorize");
951
+ }
952
+
953
+ // Four reasons, four different sentences, even for the same project.
954
+ expect(
955
+ new Set<string>(
956
+ ["sso", "plan", "blocked", "not-a-member"].map(
957
+ (reason: string): string => {
958
+ return say(`projectRefusal.${reason}`, { name: "Acme" });
959
+ },
960
+ ),
961
+ ).size,
962
+ ).toBe(4);
963
+ });
964
+
965
+ test("a reason the page does not know reads as the plainest one, never as a raw key", async () => {
966
+ answers.details = ok(
967
+ details({
968
+ projects: [
969
+ PRODUCTION,
970
+ { ...FINANCE_NEEDS_SSO, refusal: "quota_exceeded" },
971
+ { ...SIDE_PROJECT_ON_FREE_PLAN, refusal: null },
972
+ ] as unknown as JSONObject,
973
+ }),
974
+ );
975
+
976
+ await renderPage();
977
+
978
+ expect(projectOptions()[2]!.textContent).toBe(
979
+ say("projectRefusal.not-a-member", { name: "Acme Finance" }),
980
+ );
981
+ expect(projectOptions()[3]!.textContent).toBe(
982
+ say("projectRefusal.not-a-member", { name: "Side Project" }),
983
+ );
984
+ expect(projectSelect().textContent).not.toContain("quota_exceeded");
985
+ expect(projectSelect().textContent).not.toContain("projectRefusal");
986
+ });
987
+
988
+ test("the only project a client can be connected to is preselected, and Authorize is ready", async () => {
989
+ answers.details = ok(
990
+ details({
991
+ projects: [
992
+ FINANCE_NEEDS_SSO,
993
+ PRODUCTION,
994
+ SIDE_PROJECT_ON_FREE_PLAN,
995
+ ] as unknown as JSONObject,
996
+ }),
997
+ );
998
+
999
+ await renderPage();
1000
+
1001
+ expect(projectSelect().value).toBe(PRODUCTION_ID);
1002
+ expect(approveButton()).toBeEnabled();
1003
+ });
1004
+
1005
+ test("with several, none is preselected and Authorize waits for a choice", async () => {
1006
+ answers.details = ok(
1007
+ details({ projects: [PRODUCTION, STAGING] as unknown as JSONObject }),
1008
+ );
1009
+
1010
+ await renderPage();
1011
+
1012
+ expect(projectSelect().value).toBe("");
1013
+ expect(approveButton()).toBeDisabled();
1014
+
1015
+ // Pressing it anyway sends nothing.
1016
+ await click(approveButton());
1017
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toEqual([]);
1018
+
1019
+ await chooseProject(STAGING_ID);
1020
+
1021
+ expect(projectSelect().value).toBe(STAGING_ID);
1022
+ expect(approveButton()).toBeEnabled();
1023
+
1024
+ // Going back to the placeholder takes the choice away again.
1025
+ await chooseProject("");
1026
+
1027
+ expect(approveButton()).toBeDisabled();
1028
+ });
1029
+
1030
+ test("with none the client can be connected to: a notice, every project greyed out, and only Cancel to press", async () => {
1031
+ answers.details = ok(
1032
+ details({
1033
+ projects: [
1034
+ FINANCE_NEEDS_SSO,
1035
+ SIDE_PROJECT_ON_FREE_PLAN,
1036
+ ] as unknown as JSONObject,
1037
+ }),
1038
+ );
1039
+
1040
+ await renderPage();
1041
+
1042
+ expect(
1043
+ screen.getByTestId("mcp-authorize-no-eligible-projects"),
1044
+ ).toHaveTextContent(say("noEligibleProjects"));
1045
+ expect(screen.queryByTestId("mcp-authorize-no-projects")).toBeNull();
1046
+
1047
+ expect(projectSelect().value).toBe("");
1048
+ expect(
1049
+ projectOptions()
1050
+ .slice(1)
1051
+ .every((option: HTMLOptionElement): boolean => {
1052
+ return option.disabled;
1053
+ }),
1054
+ ).toBe(true);
1055
+
1056
+ // There is nothing to grant access to, so the access choice is not asked.
1057
+ expect(screen.queryByTestId("mcp-authorize-access")).toBeNull();
1058
+ expect(approveButton()).toBeDisabled();
1059
+ expect(denyButton()).toBeEnabled();
1060
+ });
1061
+
1062
+ test("with no projects at all: a notice instead of an empty list", async () => {
1063
+ answers.details = ok(details({ projects: [] as unknown as JSONObject }));
1064
+
1065
+ await renderPage();
1066
+
1067
+ expect(screen.getByTestId("mcp-authorize-no-projects")).toHaveTextContent(
1068
+ say("noProjects"),
1069
+ );
1070
+ expect(
1071
+ screen.queryByTestId("mcp-authorize-no-eligible-projects"),
1072
+ ).toBeNull();
1073
+ expect(screen.queryByTestId("mcp-authorize-project")).toBeNull();
1074
+ expect(screen.queryByTestId("mcp-authorize-access")).toBeNull();
1075
+ expect(approveButton()).toBeDisabled();
1076
+ expect(denyButton()).toBeEnabled();
1077
+ });
1078
+
1079
+ test("neither notice is shown when there is a project to choose", async () => {
1080
+ await renderPage();
1081
+
1082
+ expect(screen.queryByTestId("mcp-authorize-no-projects")).toBeNull();
1083
+ expect(
1084
+ screen.queryByTestId("mcp-authorize-no-eligible-projects"),
1085
+ ).toBeNull();
1086
+ });
1087
+
1088
+ test("a project's name is shown as text", async () => {
1089
+ answers.details = ok(
1090
+ details({
1091
+ projects: [
1092
+ { ...PRODUCTION, name: "<b>Acme</b> & Sons" },
1093
+ ] as unknown as JSONObject,
1094
+ }),
1095
+ );
1096
+
1097
+ const { container } = await renderPage();
1098
+
1099
+ expect(projectOptions()[1]!.textContent).toBe("<b>Acme</b> & Sons");
1100
+ expect(container.querySelector("b")).toBeNull();
1101
+ });
1102
+ });
1103
+
1104
+ describe("choosing what the client may do", () => {
1105
+ test("a client that asked for write is offered both, with write chosen", async () => {
1106
+ await renderPage();
1107
+
1108
+ const choice: HTMLElement = screen.getByTestId("mcp-authorize-access");
1109
+
1110
+ expect(within(choice).getByText(say("accessLabel"))).toBeInTheDocument();
1111
+ expect(within(choice).getAllByRole("radio")).toHaveLength(2);
1112
+
1113
+ expect(accessRadio("write")).not.toBeNull();
1114
+ expect(accessRadio("write")!.checked).toBe(true);
1115
+ expect(accessRadio("read")!.checked).toBe(false);
1116
+
1117
+ expect(
1118
+ screen.getByRole("radio", {
1119
+ name: `${say("accessWriteTitle")} ${say("accessWriteDescription")}`,
1120
+ }),
1121
+ ).toBe(accessRadio("write"));
1122
+ expect(
1123
+ screen.getByRole("radio", {
1124
+ name: `${say("accessReadTitle")} ${say("accessReadDescription")}`,
1125
+ }),
1126
+ ).toBe(accessRadio("read"));
1127
+ });
1128
+
1129
+ test("the member can give that client less than it asked for", async () => {
1130
+ await renderPage();
1131
+
1132
+ await click(accessRadio("read")!);
1133
+
1134
+ expect(accessRadio("read")!.checked).toBe(true);
1135
+ expect(accessRadio("write")!.checked).toBe(false);
1136
+
1137
+ await click(approveButton());
1138
+
1139
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toEqual([
1140
+ { request: TICKET, projectId: PRODUCTION_ID, access: "read" },
1141
+ ]);
1142
+ });
1143
+
1144
+ test("and can change their mind back before authorizing", async () => {
1145
+ await renderPage();
1146
+
1147
+ await click(accessRadio("read")!);
1148
+ await click(accessRadio("write")!);
1149
+ await click(approveButton());
1150
+
1151
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toEqual([
1152
+ { request: TICKET, projectId: PRODUCTION_ID, access: "write" },
1153
+ ]);
1154
+ });
1155
+
1156
+ test("a client that asked only to read is never offered write", async () => {
1157
+ answers.details = ok(details({ requestedAccess: "read" }));
1158
+
1159
+ await renderPage();
1160
+
1161
+ expect(accessRadio("write")).toBeNull();
1162
+ expect(screen.queryByText(say("accessWriteTitle"))).toBeNull();
1163
+ expect(screen.queryByText(say("accessWriteDescription"))).toBeNull();
1164
+
1165
+ expect(
1166
+ within(screen.getByTestId("mcp-authorize-access")).getAllByRole("radio"),
1167
+ ).toHaveLength(1);
1168
+ expect(accessRadio("read")!.checked).toBe(true);
1169
+
1170
+ await click(approveButton());
1171
+
1172
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toEqual([
1173
+ { request: TICKET, projectId: PRODUCTION_ID, access: "read" },
1174
+ ]);
1175
+ });
1176
+
1177
+ test.each([
1178
+ ["nothing", undefined],
1179
+ ["a word the page does not know", "admin"],
1180
+ ["write in capitals", "WRITE"],
1181
+ ["a scope name", "mcp:write"],
1182
+ ] as Array<[string, string | undefined]>)(
1183
+ "an answer that says %s about access is treated as read",
1184
+ async (_label: string, requestedAccess: string | undefined) => {
1185
+ const body: JSONObject = details();
1186
+
1187
+ if (requestedAccess === undefined) {
1188
+ delete body["requestedAccess"];
1189
+ } else {
1190
+ body["requestedAccess"] = requestedAccess;
1191
+ }
1192
+
1193
+ answers.details = ok(body);
1194
+
1195
+ await renderPage();
1196
+
1197
+ expect(accessRadio("write")).toBeNull();
1198
+ expect(accessRadio("read")!.checked).toBe(true);
1199
+ },
1200
+ );
1201
+
1202
+ test("the member is told the client is bound by their own permissions, and where to disconnect it", async () => {
1203
+ await renderPage();
1204
+
1205
+ expect(screen.getByText(say("permissionsNote"))).toBeInTheDocument();
1206
+ });
1207
+ });
1208
+
1209
+ describe("authorizing", () => {
1210
+ test("sends the request, the chosen project and the chosen access, then goes where the server says", async () => {
1211
+ answers.details = ok(
1212
+ details({ projects: [PRODUCTION, STAGING] as unknown as JSONObject }),
1213
+ );
1214
+
1215
+ await renderPage();
1216
+ await chooseProject(STAGING_ID);
1217
+ await click(approveButton());
1218
+
1219
+ expect(posted.slice(1)).toEqual([
1220
+ {
1221
+ url: MCP_OAUTH_CONSENT_APPROVE_API_URL.toString(),
1222
+ data: { request: TICKET, projectId: STAGING_ID, access: "write" },
1223
+ },
1224
+ ]);
1225
+
1226
+ expect(assign).toHaveBeenCalledTimes(1);
1227
+ expect(assign).toHaveBeenCalledWith(HOSTED_REDIRECT);
1228
+ expect(requestsTo(MCP_OAUTH_CONSENT_DENY_API_URL)).toEqual([]);
1229
+ });
1230
+
1231
+ test("tells the member they are being sent back, and takes the form away", async () => {
1232
+ await renderPage();
1233
+ await click(approveButton());
1234
+
1235
+ expect(screen.getByTestId("mcp-authorize-subtitle")).toHaveTextContent(
1236
+ say("redirecting", { clientName: "Claude" }),
1237
+ );
1238
+ expect(screen.getByTestId("mcp-authorize-redirecting")).toHaveTextContent(
1239
+ say("redirectingHelp"),
1240
+ );
1241
+
1242
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
1243
+ expect(screen.queryByTestId("mcp-authorize-deny")).toBeNull();
1244
+ expect(screen.queryByTestId("mcp-authorize-project")).toBeNull();
1245
+ });
1246
+
1247
+ test.each([
1248
+ ["a loopback address", "http://localhost:33418/callback?code=oumcp_ac_abc"],
1249
+ [
1250
+ "an editor's own scheme",
1251
+ "cursor://anysphere.cursor-retrieval/oauth/user-mcp/callback?code=oumcp_ac_abc",
1252
+ ],
1253
+ ])(
1254
+ "follows %s exactly as the server wrote it",
1255
+ async (_label: string, redirectUrl: string) => {
1256
+ answers.approve = ok({ redirectUrl });
1257
+
1258
+ await renderPage();
1259
+ await click(approveButton());
1260
+
1261
+ expect(assign).toHaveBeenCalledTimes(1);
1262
+ expect(assign).toHaveBeenCalledWith(redirectUrl);
1263
+ },
1264
+ );
1265
+
1266
+ test.each([
1267
+ ["a script address", "javascript:alert(document.cookie)"],
1268
+ ["a script address in capitals", "JAVASCRIPT:alert(1)"],
1269
+ ["a script address behind whitespace", " javascript:alert(1)"],
1270
+ ["a data address", "data:text/html,<script>alert(1)</script>"],
1271
+ ["a vbscript address", "vbscript:msgbox(1)"],
1272
+ ["a blob address", "blob:http://localhost/0b2f8c0e"],
1273
+ ["a file address", "file:///etc/passwd"],
1274
+ ["about:blank", "about:blank"],
1275
+ ["a path", "/dashboard"],
1276
+ ["no address", ""],
1277
+ ["a number", 42],
1278
+ ["nothing", undefined],
1279
+ ["an object", { href: HOSTED_REDIRECT }],
1280
+ ] as Array<[string, unknown]>)(
1281
+ "does not follow %s, and shows the generic error instead",
1282
+ async (_label: string, redirectUrl: unknown) => {
1283
+ answers.approve = ok(
1284
+ redirectUrl === undefined
1285
+ ? {}
1286
+ : ({ redirectUrl } as unknown as JSONObject),
1287
+ );
1288
+
1289
+ await renderPage();
1290
+ await click(approveButton());
1291
+
1292
+ expect(assign).not.toHaveBeenCalled();
1293
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
1294
+ say("errors.server_error"),
1295
+ );
1296
+ expect(screen.queryByTestId("mcp-authorize-redirecting")).toBeNull();
1297
+ },
1298
+ );
1299
+
1300
+ test("a refusal is shown in the server's words, and the member can try again", async () => {
1301
+ answers.approve = refused(
1302
+ 422,
1303
+ "This project requires single sign-on. Sign in to it with SSO in this browser, then connect your MCP client again.",
1304
+ );
1305
+
1306
+ await renderPage();
1307
+ await click(approveButton());
1308
+
1309
+ const error: HTMLElement = screen.getByTestId("mcp-authorize-submit-error");
1310
+
1311
+ expect(error).toHaveTextContent(
1312
+ "This project requires single sign-on. Sign in to it with SSO in this browser, then connect your MCP client again.",
1313
+ );
1314
+ expect(error).toHaveAttribute("role", "alert");
1315
+ expect(assign).not.toHaveBeenCalled();
1316
+
1317
+ // Still on the form, with everything usable again.
1318
+ expect(approveButton()).toBeEnabled();
1319
+ expect(denyButton()).toBeEnabled();
1320
+ expect(projectSelect()).toBeEnabled();
1321
+ expect(accessRadio("read")).toBeEnabled();
1322
+ expect(accessRadio("write")).toBeEnabled();
1323
+
1324
+ answers.approve = ok({ redirectUrl: HOSTED_REDIRECT });
1325
+ await click(approveButton());
1326
+
1327
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toHaveLength(2);
1328
+ expect(assign).toHaveBeenCalledWith(HOSTED_REDIRECT);
1329
+ });
1330
+
1331
+ test("an old refusal is cleared as soon as the member tries again", async () => {
1332
+ answers.approve = refused(402, "This project's plan does not include it.");
1333
+
1334
+ await renderPage();
1335
+ await click(approveButton());
1336
+
1337
+ expect(
1338
+ screen.getByTestId("mcp-authorize-submit-error"),
1339
+ ).toBeInTheDocument();
1340
+
1341
+ const second: Deferred = deferred();
1342
+ answers.approve = second.answer;
1343
+
1344
+ await click(approveButton());
1345
+
1346
+ expect(screen.queryByTestId("mcp-authorize-submit-error")).toBeNull();
1347
+
1348
+ await second.resolve(
1349
+ new HTTPResponse<JSONObject>(200, { redirectUrl: HOSTED_REDIRECT }, {}),
1350
+ );
1351
+ });
1352
+
1353
+ test("a request that fails outright is reported the same way", async () => {
1354
+ answers.approve = async (): Promise<HTTPResponse<JSONObject>> => {
1355
+ throw new Error("Network Error");
1356
+ };
1357
+
1358
+ await renderPage();
1359
+ await click(approveButton());
1360
+
1361
+ expect(screen.getByTestId("mcp-authorize-submit-error")).toHaveTextContent(
1362
+ "Network Error",
1363
+ );
1364
+ expect(approveButton()).toBeEnabled();
1365
+ expect(assign).not.toHaveBeenCalled();
1366
+ });
1367
+
1368
+ test("while the answer is on its way nothing can be pressed twice, or changed", async () => {
1369
+ const pending: Deferred = deferred();
1370
+ answers.approve = pending.answer;
1371
+
1372
+ await renderPage();
1373
+ await click(approveButton());
1374
+
1375
+ expect(approveButton()).toBeDisabled();
1376
+ expect(denyButton()).toBeDisabled();
1377
+ expect(projectSelect()).toBeDisabled();
1378
+ expect(accessRadio("read")).toBeDisabled();
1379
+ expect(accessRadio("write")).toBeDisabled();
1380
+
1381
+ await click(approveButton());
1382
+ await click(denyButton());
1383
+
1384
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toHaveLength(1);
1385
+ expect(requestsTo(MCP_OAUTH_CONSENT_DENY_API_URL)).toHaveLength(0);
1386
+
1387
+ await pending.resolve(
1388
+ new HTTPResponse<JSONObject>(200, { redirectUrl: HOSTED_REDIRECT }, {}),
1389
+ );
1390
+
1391
+ expect(assign).toHaveBeenCalledTimes(1);
1392
+ });
1393
+ });
1394
+
1395
+ describe("cancelling", () => {
1396
+ test("sends only the request, and goes where the server says", async () => {
1397
+ await renderPage();
1398
+ await click(denyButton());
1399
+
1400
+ expect(posted.slice(1)).toEqual([
1401
+ {
1402
+ url: MCP_OAUTH_CONSENT_DENY_API_URL.toString(),
1403
+ data: { request: TICKET },
1404
+ },
1405
+ ]);
1406
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toEqual([]);
1407
+
1408
+ expect(assign).toHaveBeenCalledTimes(1);
1409
+ expect(assign).toHaveBeenCalledWith(DENIED_REDIRECT);
1410
+ });
1411
+
1412
+ test("works before any project is chosen", async () => {
1413
+ answers.details = ok(
1414
+ details({ projects: [PRODUCTION, STAGING] as unknown as JSONObject }),
1415
+ );
1416
+
1417
+ await renderPage();
1418
+
1419
+ expect(approveButton()).toBeDisabled();
1420
+
1421
+ await click(denyButton());
1422
+
1423
+ expect(assign).toHaveBeenCalledWith(DENIED_REDIRECT);
1424
+ });
1425
+
1426
+ test("does not follow an address a browser must not be sent to", async () => {
1427
+ answers.deny = ok({ redirectUrl: "javascript:alert(1)" });
1428
+
1429
+ await renderPage();
1430
+ await click(denyButton());
1431
+
1432
+ expect(assign).not.toHaveBeenCalled();
1433
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
1434
+ say("errors.server_error"),
1435
+ );
1436
+ });
1437
+
1438
+ test("while the answer is on its way Authorize cannot be pressed", async () => {
1439
+ const pending: Deferred = deferred();
1440
+ answers.deny = pending.answer;
1441
+
1442
+ await renderPage();
1443
+ await click(denyButton());
1444
+
1445
+ expect(approveButton()).toBeDisabled();
1446
+ expect(denyButton()).toBeDisabled();
1447
+
1448
+ await click(approveButton());
1449
+ await click(denyButton());
1450
+
1451
+ expect(requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL)).toHaveLength(0);
1452
+ expect(requestsTo(MCP_OAUTH_CONSENT_DENY_API_URL)).toHaveLength(1);
1453
+
1454
+ await pending.resolve(
1455
+ new HTTPResponse<JSONObject>(200, { redirectUrl: DENIED_REDIRECT }, {}),
1456
+ );
1457
+
1458
+ expect(assign).toHaveBeenCalledWith(DENIED_REDIRECT);
1459
+ });
1460
+
1461
+ test("the two buttons carry the locale's own labels", async () => {
1462
+ await renderPage();
1463
+
1464
+ expect(approveButton()).toHaveTextContent(say("authorizeButton"));
1465
+ expect(denyButton()).toHaveTextContent(say("denyButton"));
1466
+ expect(say("authorizeButton")).not.toBe(say("denyButton"));
1467
+ });
1468
+ });
1469
+
1470
+ describe("a visitor who is not signed in", () => {
1471
+ /*
1472
+ * The server answers 401, and the API client (not this page) sends the
1473
+ * browser to the sign-in page. What the page owes that visitor is the
1474
+ * request, still waiting in its cookie when they come back.
1475
+ */
1476
+ test("the request is remembered before the server is asked anything", async () => {
1477
+ const pending: Deferred = deferred();
1478
+ answers.details = pending.answer;
1479
+
1480
+ await renderPage();
1481
+
1482
+ expect(posted).toHaveLength(1);
1483
+ expect(rememberedRoute()).toBe(`/accounts/mcp-authorize?request=${TICKET}`);
1484
+
1485
+ await pending.resolve(new HTTPResponse<JSONObject>(200, details(), {}));
1486
+ });
1487
+
1488
+ test("the page writes the request where only the dashboard can read it", async () => {
1489
+ /*
1490
+ * The cookie belongs to the dashboard's path: it is not sent to the
1491
+ * identity endpoints (which clear every cookie they are sent), and the
1492
+ * dashboard is where a sign-in ends. So from the consent screen's own
1493
+ * address it is invisible, and from the dashboard's it is there.
1494
+ */
1495
+ answers.details = refused(401, "Sign in to OneUptime to continue.");
1496
+
1497
+ await renderPage();
1498
+
1499
+ expect(window.location.pathname).toBe(PAGE_PATH);
1500
+ expect(document.cookie).not.toContain(PENDING_REQUEST_COOKIE);
1501
+ expect(document.cookie).not.toContain(TICKET);
1502
+
1503
+ expect(isRequestRemembered()).toBe(true);
1504
+ expect(
1505
+ asTheDashboard((): string => {
1506
+ return document.cookie;
1507
+ }),
1508
+ ).toContain(`${PENDING_REQUEST_COOKIE}=${TICKET}`);
1509
+ });
1510
+
1511
+ test("a 401 leaves the request remembered and shows nothing alarming", async () => {
1512
+ answers.details = refused(401, "Sign in to OneUptime to continue.");
1513
+
1514
+ const { container } = await renderPage();
1515
+
1516
+ expect(screen.queryByTestId("mcp-authorize-problem")).toBeNull();
1517
+ expect(container.textContent).not.toContain(
1518
+ "Sign in to OneUptime to continue.",
1519
+ );
1520
+ expect(screen.queryByText(say("errorTitle"))).toBeNull();
1521
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
1522
+
1523
+ // The page keeps waiting while the browser is on its way to sign in.
1524
+ expect(screen.getByRole("status")).toBeInTheDocument();
1525
+
1526
+ expect(rememberedRoute()).toBe(`/accounts/mcp-authorize?request=${TICKET}`);
1527
+ });
1528
+
1529
+ test("the remembered request is the one this visit was opened with", async () => {
1530
+ answers.details = refused(401, "Sign in.");
1531
+
1532
+ await renderPage(`?request=${OTHER_TICKET}`);
1533
+
1534
+ expect(rememberedRoute()).toBe(
1535
+ `/accounts/mcp-authorize?request=${OTHER_TICKET}`,
1536
+ );
1537
+ });
1538
+
1539
+ test("once the screen has loaded the request is forgotten, so the dashboard does not bounce back here later", async () => {
1540
+ await renderPage();
1541
+
1542
+ expect(screen.getByTestId("mcp-authorize-client")).toBeInTheDocument();
1543
+ expect(rememberedRoute()).toBeNull();
1544
+ });
1545
+
1546
+ test.each([
1547
+ ["expired", 400],
1548
+ ["forbidden", 403],
1549
+ ["refused by the rate limit", 429],
1550
+ ["met by a server fault", 500],
1551
+ ])(
1552
+ "a request that is %s is forgotten too: coming back to it would only fail again",
1553
+ async (_label: string, statusCode: number) => {
1554
+ answers.details = refused(statusCode, "No.");
1555
+
1556
+ await renderPage();
1557
+
1558
+ expect(screen.getByTestId("mcp-authorize-problem")).toBeInTheDocument();
1559
+ expect(rememberedRoute()).toBeNull();
1560
+ },
1561
+ );
1562
+
1563
+ test("a session that ends while the screen is open: the request is remembered again on Authorize", async () => {
1564
+ await renderPage();
1565
+
1566
+ // Forgotten when the screen loaded.
1567
+ expect(isRequestRemembered()).toBe(false);
1568
+
1569
+ answers.approve = refused(401, "Your session has expired.");
1570
+ await click(approveButton());
1571
+
1572
+ expect(assign).not.toHaveBeenCalled();
1573
+ expect(screen.queryByTestId("mcp-authorize-submit-error")).toBeNull();
1574
+ expect(screen.queryByTestId("mcp-authorize-problem")).toBeNull();
1575
+
1576
+ // Nothing can be pressed while the browser leaves for the sign-in page.
1577
+ expect(approveButton()).toBeDisabled();
1578
+ expect(denyButton()).toBeDisabled();
1579
+
1580
+ expect(rememberedRoute()).toBe(`/accounts/mcp-authorize?request=${TICKET}`);
1581
+ });
1582
+
1583
+ test("and on Cancel", async () => {
1584
+ await renderPage();
1585
+
1586
+ expect(isRequestRemembered()).toBe(false);
1587
+
1588
+ answers.deny = refused(401, "Your session has expired.");
1589
+ await click(denyButton());
1590
+
1591
+ expect(assign).not.toHaveBeenCalled();
1592
+ expect(rememberedRoute()).toBe(`/accounts/mcp-authorize?request=${TICKET}`);
1593
+ });
1594
+
1595
+ test("what the API client does with a 401 - sign the visitor out, go to the sign-in page - leaves the request behind for the way back", async () => {
1596
+ /*
1597
+ * The stand-in for API.post above only hands the page a 401. The real
1598
+ * client also acts on it (BaseAPI.handleError), and the first thing it
1599
+ * does is sign the visitor out, which removes the session cookies. This
1600
+ * runs that for real: the request has to still be there afterwards, or
1601
+ * nobody who signs in on the way to connecting a client ever gets back.
1602
+ */
1603
+ answers.details = refused(401, "Sign in to OneUptime to continue.");
1604
+
1605
+ await renderPage();
1606
+
1607
+ Cookie.setItem(CookieName.Email, "ada@example.com");
1608
+ expect(document.cookie).toContain(CookieName.Email);
1609
+
1610
+ const navigate: SpyInstance<typeof Navigation.navigate> = jest
1611
+ .spyOn(Navigation, "navigate")
1612
+ .mockImplementation((): void => {});
1613
+
1614
+ await act(async () => {
1615
+ API.handleError(
1616
+ new HTTPErrorResponse(
1617
+ 401,
1618
+ { message: "Sign in to OneUptime to continue." },
1619
+ {},
1620
+ ),
1621
+ );
1622
+ });
1623
+
1624
+ // Signed out...
1625
+ expect(document.cookie).not.toContain(CookieName.Email);
1626
+
1627
+ // ...sent to sign in, as a full page navigation...
1628
+ expect(navigate).toHaveBeenCalledTimes(1);
1629
+ expect(String(navigate.mock.calls[0]![0])).toBe("/accounts/login");
1630
+ expect(navigate.mock.calls[0]![1]).toEqual({ forceNavigate: true });
1631
+
1632
+ // ...and the request is still waiting.
1633
+ expect(rememberedRoute()).toBe(`/accounts/mcp-authorize?request=${TICKET}`);
1634
+ });
1635
+ });
1636
+
1637
+ describe("every sentence on the screen comes from the locale", () => {
1638
+ const MARK: string = "[[marked]] ";
1639
+ const LANGUAGE: string = "ko";
1640
+
1641
+ let originalBundle: JSONObject = {};
1642
+
1643
+ type MarkedFunction = (node: unknown) => unknown;
1644
+
1645
+ // The same section, every string wearing a prefix no real copy has.
1646
+ const marked: MarkedFunction = (node: unknown): unknown => {
1647
+ if (typeof node === "string") {
1648
+ return `${MARK}${node}`;
1649
+ }
1650
+
1651
+ if (node && typeof node === "object") {
1652
+ const copy: Record<string, unknown> = {};
1653
+
1654
+ for (const [key, value] of Object.entries(
1655
+ node as Record<string, unknown>,
1656
+ )) {
1657
+ copy[key] = marked(value);
1658
+ }
1659
+
1660
+ return copy;
1661
+ }
1662
+
1663
+ return node;
1664
+ };
1665
+
1666
+ type UnmarkedFunction = (root: Node, allowed: Array<string>) => Array<string>;
1667
+
1668
+ // Text on the screen that neither came from the locale nor is plain data.
1669
+ const unmarkedTexts: UnmarkedFunction = (
1670
+ root: Node,
1671
+ allowed: Array<string>,
1672
+ ): Array<string> => {
1673
+ return visibleTexts(root).filter((text: string): boolean => {
1674
+ return !text.startsWith(MARK.trim()) && !allowed.includes(text);
1675
+ });
1676
+ };
1677
+
1678
+ beforeEach(async () => {
1679
+ originalBundle = JSON.parse(
1680
+ JSON.stringify(i18n.getResourceBundle(LANGUAGE, "translation")),
1681
+ ) as JSONObject;
1682
+
1683
+ i18n.addResourceBundle(
1684
+ LANGUAGE,
1685
+ "translation",
1686
+ {
1687
+ mcpAuthorize: marked(
1688
+ (i18n.getResourceBundle("en", "translation") as JSONObject)[
1689
+ "mcpAuthorize"
1690
+ ],
1691
+ ),
1692
+ },
1693
+ true,
1694
+ true,
1695
+ );
1696
+
1697
+ await act(async () => {
1698
+ await i18n.changeLanguage(LANGUAGE);
1699
+ });
1700
+ });
1701
+
1702
+ afterEach(async () => {
1703
+ await act(async () => {
1704
+ await i18n.changeLanguage("en");
1705
+ });
1706
+
1707
+ i18n.addResourceBundle(LANGUAGE, "translation", originalBundle, true, true);
1708
+ });
1709
+
1710
+ test("the consent form, for a hosted client", async () => {
1711
+ answers.details = ok(
1712
+ details({
1713
+ projects: [
1714
+ PRODUCTION,
1715
+ STAGING,
1716
+ FINANCE_NEEDS_SSO,
1717
+ ] as unknown as JSONObject,
1718
+ }),
1719
+ );
1720
+
1721
+ const { container } = await renderPage();
1722
+
1723
+ expect(say("title").startsWith(MARK)).toBe(true);
1724
+ expect(screen.getByRole("heading", { level: 2 })).toHaveTextContent(
1725
+ say("title"),
1726
+ );
1727
+
1728
+ // Not vacuous: the walk really does see the screen's sentences.
1729
+ expect(visibleTexts(container).length).toBeGreaterThanOrEqual(20);
1730
+ expect(visibleTexts(container)).toContain(say("permissionsNote"));
1731
+ expect(visibleTexts(container)).toContain(say("authorizeButton"));
1732
+
1733
+ // The verified host and the names of selectable projects are data.
1734
+ expect(
1735
+ unmarkedTexts(container, [
1736
+ "claude.ai",
1737
+ "Acme Production",
1738
+ "Acme Staging",
1739
+ ]),
1740
+ ).toEqual([]);
1741
+
1742
+ // And without those allowances the same check does notice plain text.
1743
+ expect(unmarkedTexts(container, [])).toEqual([
1744
+ "claude.ai",
1745
+ "Acme Production",
1746
+ "Acme Staging",
1747
+ ]);
1748
+ });
1749
+
1750
+ test("the consent form, for a client on this machine with nothing to connect to", async () => {
1751
+ answers.details = ok(
1752
+ details({
1753
+ client: LOCAL_CLIENT,
1754
+ requestedAccess: "read",
1755
+ projects: [FINANCE_NEEDS_SSO] as unknown as JSONObject,
1756
+ }),
1757
+ );
1758
+
1759
+ const { container } = await renderPage();
1760
+
1761
+ expect(unmarkedTexts(container, [])).toEqual([]);
1762
+ });
1763
+
1764
+ test("the consent form, for a member with no projects", async () => {
1765
+ answers.details = ok(details({ projects: [] as unknown as JSONObject }));
1766
+
1767
+ const { container } = await renderPage();
1768
+
1769
+ expect(unmarkedTexts(container, ["claude.ai"])).toEqual([]);
1770
+ });
1771
+
1772
+ test("the error screen", async () => {
1773
+ const { container } = await renderPage("?error=redirect_uri_mismatch");
1774
+
1775
+ expect(unmarkedTexts(container, [])).toEqual([]);
1776
+ });
1777
+
1778
+ test("the missing-request screen", async () => {
1779
+ const { container } = await renderPage("");
1780
+
1781
+ expect(unmarkedTexts(container, [])).toEqual([]);
1782
+ });
1783
+
1784
+ test("the sending-you-back screen", async () => {
1785
+ const { container } = await renderPage();
1786
+
1787
+ await click(approveButton());
1788
+
1789
+ expect(screen.getByTestId("mcp-authorize-redirecting")).toBeInTheDocument();
1790
+ expect(unmarkedTexts(container, [])).toEqual([]);
1791
+ });
1792
+ });
1793
+
1794
+ describe("shown inside another page's frame", () => {
1795
+ /*
1796
+ * A consent screen drawn inside somebody else's page can be dressed up as
1797
+ * anything, and its Authorize button clicked by trickery. The bundled proxy
1798
+ * forbids framing /accounts; the page holds the same line itself, for an
1799
+ * install whose own proxy does not. jsdom is never framed, so the page's
1800
+ * own question is answered for it here; the question itself
1801
+ * (McpAuthorizeUtil.isFramed) is tested in App's McpAuthorizeUtil suite.
1802
+ */
1803
+ beforeEach(() => {
1804
+ jest.spyOn(McpAuthorizeUtil, "isFramed").mockReturnValue(true);
1805
+ });
1806
+
1807
+ test("it refuses to work: nothing is asked of the server and nothing can be authorized", async () => {
1808
+ await renderPage();
1809
+
1810
+ expect(posted).toEqual([]);
1811
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
1812
+ expect(screen.queryByTestId("mcp-authorize-deny")).toBeNull();
1813
+ expect(screen.queryByTestId("mcp-authorize-project")).toBeNull();
1814
+ expect(screen.getByTestId("mcp-authorize-problem")).toHaveTextContent(
1815
+ say("errors.framed"),
1816
+ );
1817
+ });
1818
+
1819
+ test("the request is not remembered for a later sign-in either", async () => {
1820
+ await renderPage();
1821
+
1822
+ expect(isRequestRemembered()).toBe(false);
1823
+ });
1824
+
1825
+ test("it says only that, whatever error the address carries", async () => {
1826
+ await renderPage("?error=unknown_client");
1827
+
1828
+ const problem: HTMLElement = screen.getByTestId("mcp-authorize-problem");
1829
+
1830
+ expect(problem).toHaveTextContent(say("errors.framed"));
1831
+ expect(problem).not.toHaveTextContent(say("errors.unknown_client"));
1832
+ });
1833
+ });
1834
+
1835
+ describe("the frame verdict belongs to the page", () => {
1836
+ test("it cannot be put on the screen through the address", async () => {
1837
+ await renderPage("?error=framed");
1838
+
1839
+ const problem: HTMLElement = screen.getByTestId("mcp-authorize-problem");
1840
+
1841
+ expect(problem).toHaveTextContent(say("errors.server_error"));
1842
+ expect(problem).not.toHaveTextContent(say("errors.framed"));
1843
+ });
1844
+
1845
+ test("a page in its own tab is not treated as framed", async () => {
1846
+ await renderPage();
1847
+
1848
+ expect(McpAuthorizeUtil.isFramed()).toBe(false);
1849
+ expect(screen.getByTestId("mcp-authorize-approve")).toBeInTheDocument();
1850
+ });
1851
+ });
1852
+
1853
+ describe("when the server cannot be reached at all", () => {
1854
+ /*
1855
+ * No answer is not a refusal: the page shows the failure and stays where
1856
+ * it is. It must not leave the request behind, or the next visit to the
1857
+ * dashboard within ten minutes would be bounced back here for no reason
1858
+ * the person can see. (A 401 is the one outcome that keeps it: that visit
1859
+ * is on its way to a sign-in.)
1860
+ */
1861
+ test("the failure is shown and no Authorize button is drawn", async () => {
1862
+ answers.details = async (): Promise<HTTPResponse<JSONObject>> => {
1863
+ throw new Error("Network Error");
1864
+ };
1865
+
1866
+ await renderPage();
1867
+
1868
+ expect(screen.getByTestId("mcp-authorize-problem")).toBeInTheDocument();
1869
+ expect(screen.queryByTestId("mcp-authorize-approve")).toBeNull();
1870
+ });
1871
+
1872
+ test("the request is not left behind for the dashboard", async () => {
1873
+ answers.details = async (): Promise<HTTPResponse<JSONObject>> => {
1874
+ throw new Error("Network Error");
1875
+ };
1876
+
1877
+ await renderPage();
1878
+
1879
+ expect(isRequestRemembered()).toBe(false);
1880
+ });
1881
+ });
1882
+
1883
+ describe("read right to left", () => {
1884
+ /*
1885
+ * Persian is laid out right to left. A page with no direction of its own
1886
+ * draws those sentences left to right, and each one that mixes in a Latin
1887
+ * name comes out with its pieces in the wrong order - "X wants to access
1888
+ * OneUptime" can end up reading the other way round. So the page takes its
1889
+ * direction from the language, and sets the values it drops into a
1890
+ * sentence apart with Unicode isolates.
1891
+ */
1892
+ const LEFT_TO_RIGHT_ISOLATE: string = String.fromCodePoint(0x2066);
1893
+ const FIRST_STRONG_ISOLATE: string = String.fromCodePoint(0x2068);
1894
+ const POP_DIRECTIONAL_ISOLATE: string = String.fromCodePoint(0x2069);
1895
+
1896
+ type IsolatedFunction = (value: string) => string;
1897
+
1898
+ // A name: keeps the direction of its own first letter.
1899
+ const isolated: IsolatedFunction = (value: string): string => {
1900
+ return `${FIRST_STRONG_ISOLATE}${value}${POP_DIRECTIONAL_ISOLATE}`;
1901
+ };
1902
+
1903
+ // A host, address or email: stated to be left to right.
1904
+ const isolatedLeftToRight: IsolatedFunction = (value: string): string => {
1905
+ return `${LEFT_TO_RIGHT_ISOLATE}${value}${POP_DIRECTIONAL_ISOLATE}`;
1906
+ };
1907
+
1908
+ type DirectionOfFunction = (container: HTMLElement) => string | null;
1909
+
1910
+ // The direction of the page's outermost element.
1911
+ const directionOf: DirectionOfFunction = (
1912
+ container: HTMLElement,
1913
+ ): string | null => {
1914
+ return (container.firstElementChild as HTMLElement).getAttribute("dir");
1915
+ };
1916
+
1917
+ describe("in Persian", () => {
1918
+ beforeEach(async () => {
1919
+ await act(async () => {
1920
+ await i18n.changeLanguage("fa");
1921
+ });
1922
+ });
1923
+
1924
+ test("the consent form runs right to left", async () => {
1925
+ const { container } = await renderPage();
1926
+
1927
+ expect(i18n.dir()).toBe("rtl");
1928
+ expect(directionOf(container)).toBe("rtl");
1929
+ expect(screen.getByTestId("mcp-authorize-approve")).toBeInTheDocument();
1930
+ });
1931
+
1932
+ test("the error screen runs right to left", async () => {
1933
+ const { container } = await renderPage("?error=unknown_client");
1934
+
1935
+ expect(directionOf(container)).toBe("rtl");
1936
+ });
1937
+
1938
+ test("the handing-back screen runs right to left", async () => {
1939
+ const { container } = await renderPage();
1940
+
1941
+ await click(approveButton());
1942
+
1943
+ expect(
1944
+ screen.getByTestId("mcp-authorize-redirecting"),
1945
+ ).toBeInTheDocument();
1946
+ expect(directionOf(container)).toBe("rtl");
1947
+ });
1948
+
1949
+ test("the client's name is set apart inside its sentence", async () => {
1950
+ await renderPage();
1951
+
1952
+ expect(screen.getByTestId("mcp-authorize-subtitle").textContent).toBe(
1953
+ say("wantsAccess", { clientName: isolated("Claude") }),
1954
+ );
1955
+ });
1956
+
1957
+ test("an address is stated to be left to right, so it is shown as written", async () => {
1958
+ /*
1959
+ * "[::1]:33418" has no letters, so an isolate that takes its direction
1960
+ * from the first letter inside it falls back to the page's and draws
1961
+ * the address backwards. It has to be told.
1962
+ */
1963
+ answers.details = ok(
1964
+ details({
1965
+ client: {
1966
+ ...LOCAL_CLIENT,
1967
+ redirectTarget: "[::1]:33418",
1968
+ },
1969
+ }),
1970
+ );
1971
+
1972
+ await renderPage();
1973
+
1974
+ expect(
1975
+ screen.getByTestId("mcp-authorize-redirect-target").textContent,
1976
+ ).toBe(
1977
+ say("redirectToThisDevice", {
1978
+ target: isolatedLeftToRight("[::1]:33418"),
1979
+ }),
1980
+ );
1981
+ });
1982
+
1983
+ test("the signed-in address is left to right, and a refused project's name is set apart", async () => {
1984
+ answers.details = ok(
1985
+ details({
1986
+ projects: [PRODUCTION, FINANCE_NEEDS_SSO] as unknown as JSONObject,
1987
+ }),
1988
+ );
1989
+
1990
+ await renderPage();
1991
+
1992
+ expect(screen.getByTestId("mcp-authorize-signed-in-as").textContent).toBe(
1993
+ say("signedInAs", { email: isolatedLeftToRight("ada@example.com") }),
1994
+ );
1995
+
1996
+ expect(
1997
+ projectOptions().map((option: HTMLOptionElement): string => {
1998
+ return option.textContent || "";
1999
+ }),
2000
+ ).toContain(
2001
+ say("projectRefusal.sso", { name: isolated(FINANCE_NEEDS_SSO.name) }),
2002
+ );
2003
+ });
2004
+
2005
+ test("what is SENT is never wrapped: the request, project and access are the plain values", async () => {
2006
+ await renderPage();
2007
+
2008
+ await click(approveButton());
2009
+
2010
+ const sent: string = JSON.stringify(
2011
+ requestsTo(MCP_OAUTH_CONSENT_APPROVE_API_URL),
2012
+ );
2013
+
2014
+ expect(sent).toContain(PRODUCTION_ID);
2015
+ expect(sent).not.toContain(LEFT_TO_RIGHT_ISOLATE);
2016
+ expect(sent).not.toContain(FIRST_STRONG_ISOLATE);
2017
+ expect(sent).not.toContain(POP_DIRECTIONAL_ISOLATE);
2018
+ });
2019
+ });
2020
+
2021
+ describe("in English", () => {
2022
+ test("the page runs left to right and nothing is wrapped", async () => {
2023
+ const { container } = await renderPage();
2024
+
2025
+ expect(directionOf(container)).toBe("ltr");
2026
+ expect(container.textContent).not.toContain(LEFT_TO_RIGHT_ISOLATE);
2027
+ expect(container.textContent).not.toContain(FIRST_STRONG_ISOLATE);
2028
+ expect(container.textContent).not.toContain(POP_DIRECTIONAL_ISOLATE);
2029
+ expect(screen.getByTestId("mcp-authorize-subtitle").textContent).toBe(
2030
+ say("wantsAccess", { clientName: "Claude" }),
2031
+ );
2032
+ });
2033
+ });
2034
+ });