@oneuptime/common 14.0.13 → 14.0.14

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 (1045) hide show
  1. package/Models/DatabaseModels/AlertGroupingRule.ts +10 -6
  2. package/Models/DatabaseModels/File.ts +41 -2
  3. package/Models/DatabaseModels/Form.ts +126 -0
  4. package/Models/DatabaseModels/IncidentGroupingRule.ts +10 -6
  5. package/Models/DatabaseModels/LogDropFilter.ts +1 -0
  6. package/Models/DatabaseModels/LogPipeline.ts +1 -0
  7. package/Models/DatabaseModels/LogScrubRule.ts +14 -8
  8. package/Models/DatabaseModels/MetricRecordingRule.ts +2 -1
  9. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.ts +4 -2
  10. package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +22 -9
  11. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +6 -1
  12. package/Models/DatabaseModels/StatusPage.ts +8 -4
  13. package/Models/DatabaseModels/TraceDropFilter.ts +1 -0
  14. package/Models/DatabaseModels/TracePipeline.ts +1 -0
  15. package/Models/DatabaseModels/TraceRecordingRule.ts +2 -1
  16. package/Models/DatabaseModels/TraceScrubRule.ts +14 -8
  17. package/Models/DatabaseModels/UserOnCallLog.ts +4 -2
  18. package/Server/API/CustomDomainRoutes.ts +251 -0
  19. package/Server/API/DashboardAPI.ts +33 -4
  20. package/Server/API/DashboardDomainAPI.ts +63 -93
  21. package/Server/API/StatusPageAPI.ts +92 -0
  22. package/Server/API/StatusPageDomainAPI.ts +59 -96
  23. package/Server/Infrastructure/GlobalCache.ts +84 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1797700000000-AddFormBranding.ts +47 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  26. package/Server/Services/AlertGroupingEngineService.ts +48 -70
  27. package/Server/Services/AlertGroupingRuleService.ts +38 -0
  28. package/Server/Services/CephClusterService.ts +25 -0
  29. package/Server/Services/CloudResourceService.ts +42 -0
  30. package/Server/Services/DashboardDomainService.ts +640 -214
  31. package/Server/Services/DashboardService.ts +30 -8
  32. package/Server/Services/DatabaseService.ts +143 -12
  33. package/Server/Services/DockerHostService.ts +60 -0
  34. package/Server/Services/DockerSwarmClusterService.ts +25 -0
  35. package/Server/Services/FileService.ts +60 -0
  36. package/Server/Services/FormService.ts +212 -2
  37. package/Server/Services/GlobalOidcService.ts +10 -0
  38. package/Server/Services/GlobalSsoService.ts +10 -0
  39. package/Server/Services/HostService.ts +58 -0
  40. package/Server/Services/IncidentGroupingEngineService.ts +48 -70
  41. package/Server/Services/IncidentGroupingRuleService.ts +38 -0
  42. package/Server/Services/IoTFleetService.ts +26 -0
  43. package/Server/Services/KubernetesClusterService.ts +64 -0
  44. package/Server/Services/LabelService.ts +6 -17
  45. package/Server/Services/LogScrubRuleService.ts +50 -0
  46. package/Server/Services/OnCallDutyPolicyScheduleService.ts +264 -0
  47. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +9 -1
  48. package/Server/Services/OnCallNotificationAlertingService.ts +24 -29
  49. package/Server/Services/OnCallSetupReminderService.ts +41 -40
  50. package/Server/Services/PodmanHostService.ts +60 -0
  51. package/Server/Services/ProfileAggregationService.ts +38 -0
  52. package/Server/Services/ProjectCallSMSConfigService.ts +76 -3
  53. package/Server/Services/ProjectOidcService.ts +20 -0
  54. package/Server/Services/ProjectSsoService.ts +20 -0
  55. package/Server/Services/ProxmoxClusterService.ts +25 -0
  56. package/Server/Services/RumApplicationService.ts +45 -0
  57. package/Server/Services/ScheduledMaintenanceService.ts +9 -23
  58. package/Server/Services/ServerlessFunctionService.ts +47 -0
  59. package/Server/Services/ServiceService.ts +33 -10
  60. package/Server/Services/StatusPageDomainService.ts +622 -213
  61. package/Server/Services/StatusPageOidcService.ts +20 -0
  62. package/Server/Services/StatusPageResourceService.ts +89 -34
  63. package/Server/Services/StatusPageService.ts +270 -54
  64. package/Server/Services/StatusPageSsoService.ts +20 -0
  65. package/Server/Services/TraceScrubRuleService.ts +50 -0
  66. package/Server/Services/UserIncomingCallNumberService.ts +28 -14
  67. package/Server/Services/VMwareVCenterService.ts +25 -0
  68. package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +3 -3
  69. package/Server/Utils/Greenlock/CertificateOrder.ts +482 -0
  70. package/Server/Utils/Greenlock/CertificateOrderBudget.ts +134 -0
  71. package/Server/Utils/Greenlock/CertificateOrderFailures.ts +288 -0
  72. package/Server/Utils/Greenlock/CertificateOrderLock.ts +163 -0
  73. package/Server/Utils/Greenlock/CertificateOrderOutcome.ts +29 -0
  74. package/Server/Utils/Greenlock/CertificateOwners.ts +72 -0
  75. package/Server/Utils/Greenlock/CertificateReissueOrder.ts +99 -0
  76. package/Server/Utils/Greenlock/CustomDomainOrders.ts +397 -0
  77. package/Server/Utils/Greenlock/Greenlock.ts +839 -203
  78. package/Server/Utils/Rules/GroupingRuleEpisodeOwners.ts +551 -0
  79. package/Server/Utils/Rules/OwnerRuleAssignment.ts +8 -1
  80. package/Server/Utils/ScrubRuleValidation.ts +248 -0
  81. package/Server/Utils/StatusPage/AffectedStatusPageResources.ts +138 -0
  82. package/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.ts +294 -0
  83. package/Server/Utils/Telemetry/DiscoveredResourceCreate.ts +275 -0
  84. package/Server/Utils/Telemetry/DiscoveredResourceUpdate.ts +217 -0
  85. package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +8 -2
  86. package/Tests/App/Accounts/FormPage.test.tsx +238 -0
  87. package/Tests/App/Accounts/FormUtils.test.ts +108 -0
  88. package/Tests/App/AdminDashboard/AdminAddToProjectMembersTeam.test.tsx +1087 -0
  89. package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +140 -138
  90. package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +144 -145
  91. package/Tests/App/AdminDashboard/AdminSettingsFormsOnePage.test.tsx +907 -0
  92. package/Tests/App/AdminDashboard/AdminSettingsSwitches.test.tsx +906 -0
  93. package/Tests/App/AdminDashboard/AdminSmtpSettingsForm.test.tsx +823 -0
  94. package/Tests/App/AdminDashboard/BulkAddUsersToProjectModal.test.tsx +341 -368
  95. package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +199 -54
  96. package/Tests/App/AdminDashboard/ProjectScopedTeamsPicker.test.tsx +991 -0
  97. package/Tests/App/Dashboard/AIInvestigationSettingsLimits.test.tsx +147 -90
  98. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +224 -104
  99. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +302 -0
  100. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +408 -152
  101. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +55 -0
  102. package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +206 -115
  103. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +32 -0
  104. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +206 -71
  105. package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +45 -9
  106. package/Tests/App/Dashboard/AnnouncementCreateForm.test.tsx +1208 -0
  107. package/Tests/App/Dashboard/AnnouncementEditAndTemplateForms.test.tsx +693 -0
  108. package/Tests/App/Dashboard/AnnouncementFormsStructure.test.ts +546 -0
  109. package/Tests/App/Dashboard/AnnouncementStatusPageSuggestions.test.tsx +425 -0
  110. package/Tests/App/Dashboard/AnnouncementsTableCreateLinks.test.tsx +267 -0
  111. package/Tests/App/Dashboard/ApiKeyCreateForm.test.ts +68 -51
  112. package/Tests/App/Dashboard/ApiKeyViewPermissions.test.tsx +11 -9
  113. package/Tests/App/Dashboard/ApiKeysCreateAccess.test.tsx +24 -16
  114. package/Tests/App/Dashboard/BulkChangeStateModalOnePage.test.tsx +333 -0
  115. package/Tests/App/Dashboard/CardDescriptionsSayWhatFor.test.tsx +307 -0
  116. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +18 -4
  117. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +7 -2
  118. package/Tests/App/Dashboard/ColorFieldsPrefilledPages.test.tsx +453 -0
  119. package/Tests/App/Dashboard/CreateFromRecordBreadcrumbs.test.ts +272 -0
  120. package/Tests/App/Dashboard/CreateFromRecordLinks.test.tsx +495 -0
  121. package/Tests/App/Dashboard/CreateFromRecordPages.test.tsx +1026 -0
  122. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +65 -23
  123. package/Tests/App/Dashboard/CriteriaName.test.ts +5 -1
  124. package/Tests/App/Dashboard/CustomDomainCreateFlow.test.tsx +516 -0
  125. package/Tests/App/Dashboard/CustomDomainDnsSetupModal.test.tsx +547 -0
  126. package/Tests/App/Dashboard/CustomDomainsPages.test.tsx +1077 -0
  127. package/Tests/App/Dashboard/CustomFieldSimpleCreate.test.tsx +2 -2
  128. package/Tests/App/Dashboard/CustomFieldSimpleCreateRender.test.tsx +12 -6
  129. package/Tests/App/Dashboard/CustomFieldsSettingsIncidentOptions.test.tsx +1 -1
  130. package/Tests/App/Dashboard/CustomSmtpConfigForm.test.tsx +969 -0
  131. package/Tests/App/Dashboard/DashboardBlankCanvasAddWidget.test.tsx +425 -0
  132. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +400 -0
  133. package/Tests/App/Dashboard/DashboardComponentsMRTranslation.test.tsx +4 -3
  134. package/Tests/App/Dashboard/DashboardCreateForm.test.ts +375 -0
  135. package/Tests/App/Dashboard/DashboardCreateFromTemplate.test.tsx +727 -0
  136. package/Tests/App/Dashboard/DashboardEmptyCanvasAddWidget.test.tsx +86 -0
  137. package/Tests/App/Dashboard/DashboardPhoneProductsMenu.test.tsx +99 -9
  138. package/Tests/App/Dashboard/DashboardSharingCard.test.tsx +1226 -0
  139. package/Tests/App/Dashboard/DashboardSharingEntryPoints.test.tsx +383 -0
  140. package/Tests/App/Dashboard/DashboardSharingPage.test.tsx +478 -0
  141. package/Tests/App/Dashboard/DeclareFormsAdvancedRender.test.tsx +90 -34
  142. package/Tests/App/Dashboard/DeclareIncidentMonitorsApart.test.tsx +1028 -0
  143. package/Tests/App/Dashboard/DefaultSsoTeams.test.tsx +215 -0
  144. package/Tests/App/Dashboard/DisabledWarningArchived.test.tsx +3 -3
  145. package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +15 -12
  146. package/Tests/App/Dashboard/DiscoveredResourceCreateForms.test.tsx +936 -0
  147. package/Tests/App/Dashboard/EmbeddedMetricCardGroup.test.tsx +720 -0
  148. package/Tests/App/Dashboard/EpisodeMemberRoleAssignmentsFormField.test.tsx +331 -0
  149. package/Tests/App/Dashboard/EpisodePostmortemPage.test.tsx +327 -0
  150. package/Tests/App/Dashboard/EscalationRuleForm.test.ts +2 -2
  151. package/Tests/App/Dashboard/EscalationRuleFormGuard.test.ts +6 -2
  152. package/Tests/App/Dashboard/EscalationRuleOneStep.test.tsx +8 -4
  153. package/Tests/App/Dashboard/EventMeasurements.test.ts +1175 -0
  154. package/Tests/App/Dashboard/EventMeasurementsCard.test.tsx +993 -0
  155. package/Tests/App/Dashboard/EventNoteComposerDialog.test.tsx +939 -0
  156. package/Tests/App/Dashboard/EventNotes.test.tsx +34 -1
  157. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +186 -1
  158. package/Tests/App/Dashboard/EventSettingsSwitchPages.test.tsx +625 -0
  159. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +6 -2
  160. package/Tests/App/Dashboard/FeedNoteComposerDialog.test.tsx +1327 -0
  161. package/Tests/App/Dashboard/FeedNoteDialogHelpers.ts +109 -0
  162. package/Tests/App/Dashboard/FilterChipClearButton.test.tsx +356 -0
  163. package/Tests/App/Dashboard/FormBrandingSection.test.tsx +504 -0
  164. package/Tests/App/Dashboard/FormBrandingValues.test.ts +255 -0
  165. package/Tests/App/Dashboard/FormBuilderParts.test.tsx +38 -1
  166. package/Tests/App/Dashboard/FormBuilderUi.test.tsx +176 -2
  167. package/Tests/App/Dashboard/FormMappingCard.test.tsx +33 -13
  168. package/Tests/App/Dashboard/FormsMovedPagesAndSubmissions.test.tsx +1 -1
  169. package/Tests/App/Dashboard/GeneratedKeyForms.test.tsx +30 -7
  170. package/Tests/App/Dashboard/GlobalProbesOnNewMonitorsCard.test.tsx +258 -0
  171. package/Tests/App/Dashboard/GroupingRuleFormFlow.test.tsx +653 -37
  172. package/Tests/App/Dashboard/GroupingRulePages.test.tsx +218 -9
  173. package/Tests/App/Dashboard/IncidentCreateStatusPageScope.test.tsx +52 -4
  174. package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +230 -338
  175. package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +45 -9
  176. package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +227 -295
  177. package/Tests/App/Dashboard/IncidentLinkedAlertsSettingsPage.test.tsx +157 -181
  178. package/Tests/App/Dashboard/IncidentPostmortemPage.test.tsx +775 -0
  179. package/Tests/App/Dashboard/IncidentRoleFormField.test.tsx +379 -15
  180. package/Tests/App/Dashboard/IncidentRolesSettingsPage.test.tsx +148 -32
  181. package/Tests/App/Dashboard/IncidentTemplateInitialState.test.tsx +430 -0
  182. package/Tests/App/Dashboard/IncidentTemplateMonitorsApart.test.tsx +492 -0
  183. package/Tests/App/Dashboard/IncomingCallEscalationOneStep.test.tsx +830 -0
  184. package/Tests/App/Dashboard/IncomingCallEscalationRuleForm.test.ts +510 -0
  185. package/Tests/App/Dashboard/IncomingCallEscalationRuleFormGuard.test.ts +378 -0
  186. package/Tests/App/Dashboard/IngestionKeyForm.test.ts +664 -0
  187. package/Tests/App/Dashboard/IngestionKeySelectorCreate.test.tsx +523 -0
  188. package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +130 -9
  189. package/Tests/App/Dashboard/IpAllowlistCopy.test.ts +122 -0
  190. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +19 -3
  191. package/Tests/App/Dashboard/KubernetesMetricsSetupEmptyState.test.tsx +275 -0
  192. package/Tests/App/Dashboard/KubernetesMetricsSetupHints.test.tsx +720 -0
  193. package/Tests/App/Dashboard/LabelsFormField.test.tsx +18 -13
  194. package/Tests/App/Dashboard/LegacyDefaultAssigneeNote.test.tsx +359 -0
  195. package/Tests/App/Dashboard/LogMonitorAttributeOperatorPreview.test.tsx +10 -10
  196. package/Tests/App/Dashboard/MarkdownTemplateDialogsWide.test.tsx +42 -20
  197. package/Tests/App/Dashboard/MeasurementForms.test.tsx +191 -5
  198. package/Tests/App/Dashboard/MeasurementPagesI18n.test.ts +2 -0
  199. package/Tests/App/Dashboard/MeasurementSetup.test.ts +5 -2
  200. package/Tests/App/Dashboard/MenuSpecificFoldedSections.test.tsx +38 -12
  201. package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +34 -11
  202. package/Tests/App/Dashboard/MetricAndRecordingRuleFormsRender.test.tsx +1206 -0
  203. package/Tests/App/Dashboard/MetricResultsState.test.ts +248 -0
  204. package/Tests/App/Dashboard/MetricViewResultsState.test.tsx +404 -0
  205. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +1 -1
  206. package/Tests/App/Dashboard/MonitorCriteriaAdvancedOptions.test.tsx +77 -27
  207. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +5 -8
  208. package/Tests/App/Dashboard/MonitorCriteriaHeaderControls.test.tsx +228 -0
  209. package/Tests/App/Dashboard/MonitorCriteriaIncidentRoles.test.tsx +411 -0
  210. package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +5 -1
  211. package/Tests/App/Dashboard/MonitorFormIncidentRoles.test.tsx +460 -0
  212. package/Tests/App/Dashboard/MonitorIntervalRedirect.test.tsx +299 -0
  213. package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +243 -2
  214. package/Tests/App/Dashboard/MonitorProbesAndIntervalPage.test.tsx +638 -0
  215. package/Tests/App/Dashboard/MonitorStepsDefaultStatusAdvanced.test.tsx +2 -2
  216. package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +2 -2
  217. package/Tests/App/Dashboard/MonitoringIntervalCard.test.tsx +493 -0
  218. package/Tests/App/Dashboard/MonitoringSwitch.test.tsx +597 -0
  219. package/Tests/App/Dashboard/MovedRunnerSettingsRedirects.test.tsx +4 -5
  220. package/Tests/App/Dashboard/NotificationChannelOffSwitchLists.test.tsx +636 -0
  221. package/Tests/App/Dashboard/OnCallPolicyCreateFormGuard.test.ts +8 -4
  222. package/Tests/App/Dashboard/OnCallPolicyFirstResponders.test.tsx +1 -1
  223. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +54 -0
  224. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +43 -24
  225. package/Tests/App/Dashboard/OnCallRulesRedirects.test.tsx +530 -0
  226. package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +158 -74
  227. package/Tests/App/Dashboard/OnCallRulesTabs.test.tsx +511 -0
  228. package/Tests/App/Dashboard/OnCallScheduleAddLayerDefaults.test.tsx +236 -0
  229. package/Tests/App/Dashboard/OnCallScheduleCreateFormGuard.test.ts +633 -0
  230. package/Tests/App/Dashboard/OnCallScheduleOverrideClarity.test.tsx +13 -2
  231. package/Tests/App/Dashboard/OnCallScheduleWhoTakesTurns.test.tsx +771 -0
  232. package/Tests/App/Dashboard/OnCallSharedCalendarFeedSettingsForm.test.tsx +357 -0
  233. package/Tests/App/Dashboard/OnCallShiftRemindersAndUpcomingShifts.test.tsx +16 -6
  234. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +112 -23
  235. package/Tests/App/Dashboard/PageSearchIndexCoversMenus.test.tsx +594 -0
  236. package/Tests/App/Dashboard/PageSearchIndexCoversRoutes.test.tsx +271 -0
  237. package/Tests/App/Dashboard/PageSearchRanking.test.tsx +373 -0
  238. package/Tests/App/Dashboard/PostmortemPageParts.test.tsx +548 -0
  239. package/Tests/App/Dashboard/ProbeAgreementCard.test.tsx +483 -0
  240. package/Tests/App/Dashboard/ProductOrientation.test.tsx +9 -2
  241. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +282 -404
  242. package/Tests/App/Dashboard/ProjectAiSettingsSwitchPages.test.tsx +1414 -0
  243. package/Tests/App/Dashboard/ProjectNotificationChannels.test.tsx +1191 -0
  244. package/Tests/App/Dashboard/ProjectSettingsSwitchCards.test.tsx +603 -0
  245. package/Tests/App/Dashboard/RemindersCard.test.tsx +477 -0
  246. package/Tests/App/Dashboard/ResourceDetailsCard.test.tsx +458 -0
  247. package/Tests/App/Dashboard/ResourceRuleForm.test.ts +525 -0
  248. package/Tests/App/Dashboard/ResourceRuleFormsRender.test.tsx +803 -0
  249. package/Tests/App/Dashboard/RoleAccess.test.ts +753 -0
  250. package/Tests/App/Dashboard/RoleCardSelectOptions.test.ts +13 -6
  251. package/Tests/App/Dashboard/RouteUtilPageRoute.test.ts +116 -0
  252. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +1 -1
  253. package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +172 -219
  254. package/Tests/App/Dashboard/RunbookStepHeaderControls.test.tsx +269 -0
  255. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +45 -85
  256. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +16 -23
  257. package/Tests/App/Dashboard/ScheduledMaintenanceAffectedResourcesEditForm.test.tsx +485 -0
  258. package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +27 -2
  259. package/Tests/App/Dashboard/ScheduledMaintenanceCreateForm.test.tsx +65 -28
  260. package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +208 -309
  261. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +36 -53
  262. package/Tests/App/Dashboard/ScheduledMaintenanceFormsStructure.test.ts +83 -14
  263. package/Tests/App/Dashboard/ScheduledMaintenanceMonitorsApart.test.tsx +1085 -0
  264. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +378 -25
  265. package/Tests/App/Dashboard/ScheduledMaintenanceStatusPageSuggestions.test.tsx +513 -0
  266. package/Tests/App/Dashboard/ScheduledMaintenanceTemplateForm.test.tsx +31 -9
  267. package/Tests/App/Dashboard/ScheduledMaintenanceTemplateMonitorsApart.test.tsx +760 -0
  268. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +11 -13
  269. package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +228 -69
  270. package/Tests/App/Dashboard/SelectedProjectSwitches.test.tsx +359 -0
  271. package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1 -1
  272. package/Tests/App/Dashboard/SessionReplayAllowedCard.test.tsx +297 -0
  273. package/Tests/App/Dashboard/SetupGuideCard.test.tsx +7 -1
  274. package/Tests/App/Dashboard/ShortFormsOnePage.test.tsx +591 -0
  275. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +253 -6
  276. package/Tests/App/Dashboard/SloOverviewData.test.tsx +99 -0
  277. package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +3 -1
  278. package/Tests/App/Dashboard/SloSettings.test.tsx +257 -4
  279. package/Tests/App/Dashboard/SsoPages.test.tsx +448 -52
  280. package/Tests/App/Dashboard/StateChangeDialogsFolded.test.tsx +695 -0
  281. package/Tests/App/Dashboard/StateChangeFormFields.test.ts +376 -0
  282. package/Tests/App/Dashboard/StatusPageAccessCard.test.tsx +1088 -0
  283. package/Tests/App/Dashboard/StatusPageAccessCopy.test.ts +450 -0
  284. package/Tests/App/Dashboard/StatusPageAccessMenu.test.tsx +137 -0
  285. package/Tests/App/Dashboard/StatusPageAccessPage.test.tsx +458 -0
  286. package/Tests/App/Dashboard/StatusPageAdvancedSettingsPage.test.tsx +30 -86
  287. package/Tests/App/Dashboard/StatusPageBrandingPage.test.tsx +28 -15
  288. package/Tests/App/Dashboard/StatusPageDisplaySettingsCard.test.tsx +949 -14
  289. package/Tests/App/Dashboard/StatusPagePrivateUsersNotice.test.tsx +233 -0
  290. package/Tests/App/Dashboard/StatusPageReportsCard.test.tsx +1001 -0
  291. package/Tests/App/Dashboard/StatusPageRequireSsoCard.test.tsx +247 -0
  292. package/Tests/App/Dashboard/StatusPageSubscriberSettingsPages.test.tsx +4 -17
  293. package/Tests/App/Dashboard/StatusPageSuggestions.test.tsx +930 -0
  294. package/Tests/App/Dashboard/StatusPageSwitchCardPages.test.tsx +335 -0
  295. package/Tests/App/Dashboard/TeamBlockPermissionsRedirect.test.tsx +332 -0
  296. package/Tests/App/Dashboard/TeamCreateForm.test.ts +206 -0
  297. package/Tests/App/Dashboard/TeamViewPermissions.test.tsx +713 -0
  298. package/Tests/App/Dashboard/TeamViewSideMenuBlockPermissions.test.tsx +113 -0
  299. package/Tests/App/Dashboard/TeamsCreateAccess.test.tsx +799 -0
  300. package/Tests/App/Dashboard/TelemetryDataRuleForms.test.ts +655 -0
  301. package/Tests/App/Dashboard/TelemetryDataRuleFormsRender.test.tsx +1014 -0
  302. package/Tests/App/Dashboard/TelemetryIngestionKeyEdit.test.tsx +6 -3
  303. package/Tests/App/Dashboard/TelemetryIngestionKeyForm.test.tsx +446 -446
  304. package/Tests/App/Dashboard/TelemetryMonitorFiltersFold.test.tsx +613 -0
  305. package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +37 -2
  306. package/Tests/App/Dashboard/TemplateFormsNoInternalDataWarning.test.tsx +3 -3
  307. package/Tests/App/Dashboard/TraceExplorer.test.tsx +338 -0
  308. package/Tests/App/Dashboard/TwilioConfigFirstDefault.test.tsx +786 -0
  309. package/Tests/App/Dashboard/UpcomingShiftGetCover.test.tsx +306 -0
  310. package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +36 -11
  311. package/Tests/App/Dashboard/UserOverrideForm.test.ts +505 -0
  312. package/Tests/App/Dashboard/UserOverrideFormGuard.test.ts +334 -0
  313. package/Tests/App/Dashboard/UserOverrideWhoIsAway.test.tsx +999 -0
  314. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +33 -11
  315. package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +49 -4
  316. package/Tests/App/Dashboard/UsersPageEmptyState.test.tsx +245 -0
  317. package/Tests/App/Dashboard/WorkflowVariableOAuthSettingsEditSteps.test.tsx +13 -6
  318. package/Tests/App/Dashboard/WorkspaceMenusConnected.test.tsx +0 -2
  319. package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +108 -86
  320. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +397 -0
  321. package/Tests/App/StatusPage/StatusPageResourceForm.test.tsx +931 -0
  322. package/Tests/App/StatusPage/StatusPageSubscribeOnePage.test.tsx +686 -0
  323. package/Tests/DialogActionRules.ts +16 -5
  324. package/Tests/Helpers/CardHeaderScan.ts +258 -0
  325. package/Tests/Helpers/FormStepsScan.ts +576 -11
  326. package/Tests/Helpers/MonitorGroupStatusPageRows.ts +237 -0
  327. package/Tests/Helpers/NestedControls.ts +184 -0
  328. package/Tests/Helpers/NestedControlsScan.ts +414 -0
  329. package/Tests/Helpers/SteppedFooterScan.ts +722 -0
  330. package/Tests/Models/DatabaseModels/FormModel.test.ts +31 -7
  331. package/Tests/Models/DatabaseModels/UserOverrideColumnDescriptions.test.ts +123 -0
  332. package/Tests/Models/TelemetryDataRuleColumnDefaults.test.ts +239 -0
  333. package/Tests/ResponsiveFlexLayout.test.ts +111 -0
  334. package/Tests/ResponsiveFlexLayout.ts +165 -0
  335. package/Tests/Server/API/DashboardDomainOrderSslAPI.test.ts +372 -0
  336. package/Tests/Server/API/DashboardDomainVerifyCnameAPI.test.ts +921 -0
  337. package/Tests/Server/API/DashboardSharingPublicRoutes.test.ts +559 -0
  338. package/Tests/Server/API/FormBrandingPublicRoutes.test.ts +680 -0
  339. package/Tests/Server/API/ProjectAPICreateWithTenantHeader.test.ts +300 -0
  340. package/Tests/Server/API/ProjectCreateTestHelpers.ts +211 -0
  341. package/Tests/Server/API/ProjectCreateWithTenantHeaderPostgres.test.ts +387 -0
  342. package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +29 -12
  343. package/Tests/Server/API/StatusPageDomainVerifyCnameAPI.test.ts +1090 -0
  344. package/Tests/Server/API/StatusPageMasterPageAccess.test.ts +254 -0
  345. package/Tests/Server/API/StatusPageReportScheduleWrites.test.ts +829 -0
  346. package/Tests/Server/API/StatusPageUptimeSettingsWrites.test.ts +417 -0
  347. package/Tests/Server/API/StatusPagesListingMonitorsAPI.test.ts +1029 -0
  348. package/Tests/Server/API/StatusPagesListingMonitorsRoute.test.ts +286 -0
  349. package/Tests/Server/Infrastructure/GlobalCache.test.ts +156 -0
  350. package/Tests/Server/Infrastructure/Postgres/MigrateIncidentFormsToFormsMigration.test.ts +52 -1
  351. package/Tests/Server/Services/CustomDomainCertificateLifecycle.test.ts +1559 -0
  352. package/Tests/Server/Services/CustomDomainCertificateReissue.test.ts +186 -16
  353. package/Tests/Server/Services/DashboardAccessChoice.test.ts +657 -0
  354. package/Tests/Server/Services/DashboardCreateFromTemplate.test.ts +200 -0
  355. package/Tests/Server/Services/DashboardDomainCertificateSweeps.test.ts +1142 -0
  356. package/Tests/Server/Services/DiscoveredResourceCreate.test.ts +864 -0
  357. package/Tests/Server/Services/DiscoveredResourceUpdate.test.ts +822 -0
  358. package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +3 -4
  359. package/Tests/Server/Services/FileServiceProject.test.ts +345 -0
  360. package/Tests/Server/Services/FormBranding.test.ts +982 -0
  361. package/Tests/Server/Services/FormPublicForm.test.ts +15 -0
  362. package/Tests/Server/Services/GroupingRuleEpisodeOwners.test.ts +857 -0
  363. package/Tests/Server/Services/IncidentFormPostgres.test.ts +297 -1
  364. package/Tests/Server/Services/MachinePickedColors.test.ts +202 -0
  365. package/Tests/Server/Services/OidcProviderCreateDefaults.test.ts +252 -0
  366. package/Tests/Server/Services/OnCallDutyPolicyScheduleFirstLayer.test.ts +799 -0
  367. package/Tests/Server/Services/OnCallDutyPolicyScheduleFirstLayerPlans.test.ts +172 -0
  368. package/Tests/Server/Services/OnCallDutyPolicyUserOverrideWhoIsAway.test.ts +571 -0
  369. package/Tests/Server/Services/OnCallSetupReminder.test.ts +35 -13
  370. package/Tests/Server/Services/OnCallUndeliverablePageRulesLink.test.ts +217 -0
  371. package/Tests/Server/Services/ProfileAggregationService.test.ts +213 -4
  372. package/Tests/Server/Services/ProjectCallSMSConfigFirstDefault.test.ts +699 -0
  373. package/Tests/Server/Services/ProjectCallSMSConfigFirstDefaultBilling.test.ts +247 -0
  374. package/Tests/Server/Services/SamlProviderCreateDefaults.test.ts +255 -0
  375. package/Tests/Server/Services/ScheduledMaintenanceSubscriberMonitorGroups.test.ts +333 -0
  376. package/Tests/Server/Services/ScrubRuleSaveValidation.test.ts +947 -0
  377. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +17 -4
  378. package/Tests/Server/Services/StatusPageAccessChoice.test.ts +548 -0
  379. package/Tests/Server/Services/StatusPageDomainCertificateSweeps.test.ts +1238 -0
  380. package/Tests/Server/Services/TeamCreateAccessGrant.test.ts +607 -0
  381. package/Tests/Server/Services/TwilioConfigSendersGuard.test.ts +249 -0
  382. package/Tests/Server/Services/VerificationCodesUseProjectTwilioConfig.test.ts +264 -0
  383. package/Tests/Server/Types/Database/Permissions/FormBrandingColumns.test.ts +270 -0
  384. package/Tests/Server/Utils/Greenlock/CertificateCleanup.test.ts +526 -0
  385. package/Tests/Server/Utils/Greenlock/CertificateOrder.test.ts +1062 -0
  386. package/Tests/Server/Utils/Greenlock/CertificateOrderBudget.test.ts +243 -0
  387. package/Tests/Server/Utils/Greenlock/CertificateOrderFailures.test.ts +293 -0
  388. package/Tests/Server/Utils/Greenlock/CertificateOrderLock.test.ts +152 -0
  389. package/Tests/Server/Utils/Greenlock/CertificateOwnersGuard.test.ts +119 -0
  390. package/Tests/Server/Utils/Greenlock/CertificateRenewalOwnership.test.ts +1170 -0
  391. package/Tests/Server/Utils/Greenlock/CertificateRenewalSafety.test.ts +368 -0
  392. package/Tests/Server/Utils/Greenlock/CertificateRenewalSchedule.test.ts +188 -11
  393. package/Tests/Server/Utils/Greenlock/CustomDomainOrders.test.ts +723 -0
  394. package/Tests/Server/Utils/Greenlock/InMemoryRedis.ts +189 -0
  395. package/Tests/Server/Utils/Greenlock/NginxAcmeCertificatesToDisk.test.ts +242 -0
  396. package/Tests/Server/Utils/Greenlock/NginxCustomCertificatesToDisk.test.ts +305 -0
  397. package/Tests/Server/Utils/Greenlock/OrderCertGuards.test.ts +583 -0
  398. package/Tests/Server/Utils/Greenlock/OrderCertStorage.test.ts +203 -0
  399. package/Tests/Server/Utils/StatusPage/AffectedStatusPageResources.test.ts +700 -0
  400. package/Tests/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.test.ts +744 -0
  401. package/Tests/Types/CustomDomain/CustomDomainCertificates.test.ts +106 -0
  402. package/Tests/Types/CustomDomain/CustomDomainVerification.test.ts +94 -0
  403. package/Tests/Types/Dashboard/DashboardAccess.test.ts +460 -0
  404. package/Tests/Types/Filter/FilterConditionUtil.test.ts +59 -0
  405. package/Tests/Types/Form/FormBranding.test.ts +760 -0
  406. package/Tests/Types/IncomingCall/IncomingCallRingTime.test.ts +80 -0
  407. package/Tests/Types/NotificationRule/OnCallRuleKind.test.ts +271 -0
  408. package/Tests/Types/OnCallDutyPolicy/ScheduleFirstLayer.test.ts +300 -0
  409. package/Tests/Types/OnCallDutyPolicy/ScheduleLayerDefaults.test.ts +316 -0
  410. package/Tests/Types/OnCallDutyPolicy/UserOverrideCoverRequest.test.ts +257 -0
  411. package/Tests/Types/SSO/OidcProviderDefaults.test.ts +474 -0
  412. package/Tests/Types/SSO/SamlProviderDefaults.test.ts +150 -0
  413. package/Tests/Types/SSO/SsoProviderDefaults.test.ts +181 -0
  414. package/Tests/Types/StatusPage/StatusPageAccess.test.ts +393 -0
  415. package/Tests/Types/StatusPage/StatusPagesListingMonitors.test.ts +149 -0
  416. package/Tests/Types/Telemetry/ScrubRule.test.ts +375 -0
  417. package/Tests/UI/Components/AdvancedPageSection.test.tsx +201 -61
  418. package/Tests/UI/Components/BasicFormModalSteps.test.tsx +129 -153
  419. package/Tests/UI/Components/Card.test.tsx +354 -367
  420. package/Tests/UI/Components/CardHeaderActionsGuard.test.tsx +605 -0
  421. package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +23 -8
  422. package/Tests/UI/Components/CardModelDetailOnBeforeUpdate.test.tsx +224 -0
  423. package/Tests/UI/Components/CardModelDetailPageButtons.test.tsx +231 -0
  424. package/Tests/UI/Components/ChoiceRows.test.tsx +365 -0
  425. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +341 -5
  426. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +655 -64
  427. package/Tests/UI/Components/Detail/DetailCreatedOnIdLine.test.tsx +669 -0
  428. package/Tests/UI/Components/Detail/DetailIdLineDarkMode.test.ts +34 -7
  429. package/Tests/UI/Components/Detail/DetailIdLineInLocale.test.tsx +71 -0
  430. package/Tests/UI/Components/Detail/DetailRecordIdLine.test.tsx +26 -7
  431. package/Tests/UI/Components/Detail/DetailRecordLine.test.tsx +326 -0
  432. package/Tests/UI/Components/Detail/DetailRecordTime.test.ts +324 -0
  433. package/Tests/UI/Components/DetailCompactStyle.test.tsx +7 -3
  434. package/Tests/UI/Components/Dropdown/DropdownChange.test.ts +163 -0
  435. package/Tests/UI/Components/EntityDropdown.test.tsx +103 -1
  436. package/Tests/UI/Components/EntityDropdownClearButton.test.tsx +638 -0
  437. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +6 -6
  438. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +21 -4
  439. package/Tests/UI/Components/EntityDropdownQuery.test.tsx +411 -0
  440. package/Tests/UI/Components/EntityDropdownQueryHelpers.test.ts +131 -0
  441. package/Tests/UI/Components/FilePicker.test.tsx +220 -1
  442. package/Tests/UI/Components/FoldedSection/FoldedSection.test.tsx +582 -0
  443. package/Tests/UI/Components/FoldedSection/FoldedSectionDarkMode.test.ts +197 -0
  444. package/Tests/UI/Components/FoldedSection/FoldedSectionItem.test.ts +247 -0
  445. package/Tests/UI/Components/FoldedSection/FoldedSectionQueries.ts +86 -0
  446. package/Tests/UI/Components/Forms/AdvancedStepsGuard.test.ts +358 -32
  447. package/Tests/UI/Components/Forms/AnchoredFieldPopupPlacement.test.tsx +195 -0
  448. package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +187 -23
  449. package/Tests/UI/Components/Forms/BasicFormFillsInOnShow.test.tsx +246 -0
  450. package/Tests/UI/Components/Forms/BasicFormFooterSetValue.test.tsx +283 -0
  451. package/Tests/UI/Components/Forms/BasicFormPrimaryActionLastStep.test.tsx +780 -0
  452. package/Tests/UI/Components/Forms/BasicFormSingleStep.test.tsx +232 -0
  453. package/Tests/UI/Components/Forms/BasicFormStepValidation.test.tsx +7 -4
  454. package/Tests/UI/Components/Forms/BasicFormSubmitAllSteps.test.tsx +4 -3
  455. package/Tests/UI/Components/Forms/CreateFormDefaultsGuard.test.ts +252 -7
  456. package/Tests/UI/Components/Forms/DeclareAndCreateFormsGuard.test.ts +247 -7
  457. package/Tests/UI/Components/Forms/DiscoveredResourceCreateFormsGuard.test.ts +492 -0
  458. package/Tests/UI/Components/Forms/FilterConditionOnlyWithTwoFiltersGuard.test.ts +333 -0
  459. package/Tests/UI/Components/Forms/FoldedEditorWidthTiming.test.tsx +127 -0
  460. package/Tests/UI/Components/Forms/FoldedSectionsGuard.test.ts +523 -0
  461. package/Tests/UI/Components/Forms/FollowPickName.test.ts +88 -0
  462. package/Tests/UI/Components/Forms/FormFieldDropdownChange.test.tsx +294 -0
  463. package/Tests/UI/Components/Forms/FormModalWidth.test.tsx +237 -2
  464. package/Tests/UI/Components/Forms/FormSummary.test.tsx +181 -0
  465. package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +110 -86
  466. package/Tests/UI/Components/Forms/LabelsFormFieldGuard.test.ts +101 -96
  467. package/Tests/UI/Components/Forms/LongFormStepsGuard.test.ts +559 -10
  468. package/Tests/UI/Components/Forms/MarkdownFormsAreWide.test.ts +56 -4
  469. package/Tests/UI/Components/Forms/MetricAndRecordingRuleFormsGuard.test.ts +400 -0
  470. package/Tests/UI/Components/Forms/ModelFormColorDefaults.test.tsx +659 -0
  471. package/Tests/UI/Components/Forms/ModelFormCreateDefaults.test.tsx +108 -4
  472. package/Tests/UI/Components/Forms/ModelFormDropdownQuery.test.tsx +403 -0
  473. package/Tests/UI/Components/Forms/ModelFormPreservesUserInput.test.tsx +126 -0
  474. package/Tests/UI/Components/Forms/ModelFormSinglePickPeoplePicker.test.tsx +453 -0
  475. package/Tests/UI/Components/Forms/OidcProviderFormsGuard.test.ts +321 -0
  476. package/Tests/UI/Components/Forms/OneIncidentRolePickerGuard.test.ts +823 -0
  477. package/Tests/UI/Components/Forms/OneSwitchCardsGuard.test.ts +739 -0
  478. package/Tests/UI/Components/Forms/OpenFormSections.test.tsx +169 -0
  479. package/Tests/UI/Components/Forms/OverloadedFormStepsGuard.test.ts +21 -9
  480. package/Tests/UI/Components/Forms/PrimaryActionLastStepGuard.test.ts +478 -0
  481. package/Tests/UI/Components/Forms/ProjectTeamFormsGuard.test.ts +240 -0
  482. package/Tests/UI/Components/Forms/ResourceDetailsOnePlaceGuard.test.ts +936 -0
  483. package/Tests/UI/Components/Forms/ResourceRuleFormsGuard.test.ts +527 -0
  484. package/Tests/UI/Components/Forms/SamlProviderFormsGuard.test.ts +387 -0
  485. package/Tests/UI/Components/Forms/SmallWizardsOnePageGuard.test.ts +331 -0
  486. package/Tests/UI/Components/Forms/SmtpConfigFormsGuard.test.ts +470 -0
  487. package/Tests/UI/Components/Forms/StateChangeDialogsFoldTheNote.test.ts +322 -0
  488. package/Tests/UI/Components/Forms/StatusPageResourceFormsGuard.test.ts +381 -0
  489. package/Tests/UI/Components/Forms/SteppedFormFooter.test.ts +225 -0
  490. package/Tests/UI/Components/Forms/SteppedFormFooterTiming.test.tsx +82 -40
  491. package/Tests/UI/Components/Forms/SwitchCardsGuard.test.ts +339 -0
  492. package/Tests/UI/Components/Forms/TelemetryDataRuleFormsGuard.test.ts +383 -0
  493. package/Tests/UI/Components/Forms/UniqueName.test.ts +163 -0
  494. package/Tests/UI/Components/Forms/Utils/AdvancedFormSection.test.ts +131 -11
  495. package/Tests/UI/Components/Forms/Utils/CreateFormColorDefaults.test.ts +373 -0
  496. package/Tests/UI/Components/Forms/Utils/FoldedFormFields.test.ts +482 -0
  497. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +32 -0
  498. package/Tests/UI/Components/MemberRoleAssignment.test.tsx +51 -7
  499. package/Tests/UI/Components/ModalSecondaryButton.test.tsx +60 -3
  500. package/Tests/UI/Components/ModelFormDraftValues.test.tsx +255 -0
  501. package/Tests/UI/Components/ModelPageHeaderChanged.test.tsx +293 -0
  502. package/Tests/UI/Components/ModelSwitchCard.test.tsx +813 -0
  503. package/Tests/UI/Components/ModelSwitchEvents.test.ts +188 -0
  504. package/Tests/UI/Components/ModelSwitchRow.test.tsx +861 -0
  505. package/Tests/UI/Components/ModelSwitchUtil.test.ts +239 -0
  506. package/Tests/UI/Components/ModelSwitchesCard.test.tsx +699 -0
  507. package/Tests/UI/Components/NavBar.test.tsx +41 -2
  508. package/Tests/UI/Components/NavBarCategoryToggleDarkMode.test.ts +12 -0
  509. package/Tests/UI/Components/NavBarMenuCatalog.test.tsx +197 -30
  510. package/Tests/UI/Components/NavBarMenuFolding.test.tsx +221 -39
  511. package/Tests/UI/Components/NavBarMenuSearch.test.tsx +15 -10
  512. package/Tests/UI/Components/NestedControlsGuard.test.ts +300 -0
  513. package/Tests/UI/Components/PageBreadcrumbOverride.test.tsx +202 -0
  514. package/Tests/UI/Components/PeoplePicker/OwnersFieldGuard.test.ts +269 -5
  515. package/Tests/UI/Components/PeoplePicker/PeoplePickerChange.test.tsx +414 -0
  516. package/Tests/UI/Components/PeoplePicker/PeoplePickerExcludePicks.test.tsx +582 -0
  517. package/Tests/UI/Components/PeoplePicker/PeoplePickerSinglePick.test.tsx +519 -0
  518. package/Tests/UI/Components/PeoplePicker/PeoplePickerSinglePickTypes.test.ts +174 -0
  519. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +8 -3
  520. package/Tests/UI/Components/RuleCriteria/RuleCriteriaNamesGuard.test.ts +14 -6
  521. package/Tests/UI/Components/RuleRun/RuleViewDescription.test.tsx +107 -0
  522. package/Tests/UI/Components/SaveStatus.test.tsx +81 -0
  523. package/Tests/UI/Components/SmtpConfig/SmtpConfigFormFields.test.ts +1078 -0
  524. package/Tests/UI/Components/Sso/OidcProviderForm.test.tsx +608 -0
  525. package/Tests/UI/Components/Sso/OidcProviderFormFields.test.ts +698 -0
  526. package/Tests/UI/Components/Sso/SamlProviderForm.test.tsx +583 -0
  527. package/Tests/UI/Components/Sso/SamlProviderFormFields.test.ts +619 -0
  528. package/Tests/UI/Components/SteppedEditFormSave.test.tsx +199 -141
  529. package/Tests/UI/Components/Table/TableEmptyStateComponent.test.tsx +143 -0
  530. package/Tests/UI/Components/UseSaveModelSwitch.test.tsx +409 -0
  531. package/Tests/UI/Components/Workflow/ArgumentsForm.test.tsx +3 -3
  532. package/Tests/UI/Components/Workflow/ArgumentsFormAdvancedSettings.test.tsx +83 -27
  533. package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +7 -2
  534. package/Tests/UI/Components/useSaveOnChange.test.tsx +341 -0
  535. package/Tests/UI/Monitor/MonitorStepRetrySettings.test.tsx +1 -1
  536. package/Tests/UI/Rum/ReplayTimeline.test.tsx +75 -5
  537. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +97 -0
  538. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +12 -39
  539. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -6
  540. package/Tests/{App/Dashboard → UI/Utils}/DefaultInviteTeam.test.ts +126 -4
  541. package/Tests/UI/Utils/GrantablePermission.test.ts +172 -0
  542. package/Tests/UI/Utils/PermissionGateColumnUpdate.test.ts +211 -0
  543. package/Tests/UI/Utils/TranslateTemplate.test.ts +31 -0
  544. package/Tests/Utils/DistinctColor.test.ts +446 -0
  545. package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +14 -2
  546. package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +1 -1
  547. package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +2 -2
  548. package/Tests/Utils/Slo/SloHealth.test.ts +28 -6
  549. package/Tests/Utils/StatusPage/ReportSchedule.test.ts +867 -0
  550. package/Tests/Utils/Telemetry/DiscoveredResourceName.test.ts +189 -0
  551. package/Tests/Utils/WordMatch.test.ts +104 -0
  552. package/Types/BrandColors.ts +10 -0
  553. package/Types/CustomDomain/CustomDomainCertificates.ts +128 -0
  554. package/Types/CustomDomain/CustomDomainVerification.ts +78 -0
  555. package/Types/Dashboard/DashboardAccess.ts +250 -0
  556. package/Types/Dashboard/DashboardTemplates.ts +33 -0
  557. package/Types/Filter/FilterConditionUtil.ts +29 -0
  558. package/Types/Form/FormBranding.ts +475 -0
  559. package/Types/Form/FormPublic.ts +26 -0
  560. package/Types/IncomingCall/IncomingCallRingTime.ts +48 -0
  561. package/Types/Log/LogScrubField.ts +14 -0
  562. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +1 -1
  563. package/Types/NotificationRule/OnCallRuleKind.ts +194 -0
  564. package/Types/OnCallDutyPolicy/FirstResponders.ts +3 -32
  565. package/Types/OnCallDutyPolicy/MiscDataId.ts +38 -0
  566. package/Types/OnCallDutyPolicy/ScheduleFirstLayer.ts +165 -0
  567. package/Types/OnCallDutyPolicy/ScheduleLayerDefaults.ts +160 -0
  568. package/Types/OnCallDutyPolicy/UserOverrideCoverRequest.ts +148 -0
  569. package/Types/SSO/OidcProviderDefaults.ts +282 -0
  570. package/Types/SSO/SamlProviderDefaults.ts +77 -0
  571. package/Types/SSO/SsoProviderDefaults.ts +101 -0
  572. package/Types/StatusPage/StatusPageAccess.ts +215 -0
  573. package/Types/StatusPage/StatusPagesListingMonitors.ts +150 -0
  574. package/Types/Telemetry/ScrubRule.ts +240 -0
  575. package/UI/Components/AdvancedPageSection/AdvancedPageSection.tsx +59 -29
  576. package/UI/Components/Card/Card.tsx +139 -80
  577. package/UI/Components/ChoiceRows/ChoiceRows.tsx +249 -0
  578. package/UI/Components/CommandPalette/CommandPalette.tsx +28 -12
  579. package/UI/Components/CommandPalette/PaletteFilter.ts +962 -75
  580. package/UI/Components/CommandPalette/PaletteRow.tsx +35 -3
  581. package/UI/Components/CommandPalette/Types.ts +37 -1
  582. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +6 -0
  583. package/UI/Components/Detail/Detail.tsx +52 -15
  584. package/UI/Components/Detail/DetailRecordLine.tsx +96 -0
  585. package/UI/Components/Detail/DetailRecordTime.ts +196 -0
  586. package/UI/Components/Dropdown/DropdownChange.ts +198 -0
  587. package/UI/Components/EntityDropdown/EntityDropdown.tsx +270 -106
  588. package/UI/Components/EntityDropdown/EntityDropdownQuery.ts +119 -0
  589. package/UI/Components/FilePicker/FilePicker.tsx +90 -6
  590. package/UI/Components/FoldedSection/FoldedSection.tsx +370 -0
  591. package/UI/Components/FoldedSection/FoldedSectionItem.ts +141 -0
  592. package/UI/Components/FoldedSection/FoldedSectionTitles.ts +39 -0
  593. package/UI/Components/FormModal/BasicFormModal.tsx +40 -67
  594. package/UI/Components/Forms/BasicForm.tsx +218 -119
  595. package/UI/Components/Forms/BasicModelForm.tsx +0 -2
  596. package/UI/Components/Forms/CollapsibleFormSection.tsx +108 -18
  597. package/UI/Components/Forms/Fields/FormField.tsx +62 -15
  598. package/UI/Components/Forms/Fields/GeneratedKeyField.tsx +1 -5
  599. package/UI/Components/Forms/FormSummary.tsx +5 -3
  600. package/UI/Components/Forms/ModelForm.tsx +123 -16
  601. package/UI/Components/Forms/Types/Field.ts +98 -16
  602. package/UI/Components/Forms/Utils/AdvancedFormSection.ts +102 -31
  603. package/UI/Components/Forms/Utils/CreateFormDefaults.ts +158 -17
  604. package/UI/Components/Forms/Utils/FoldedFormFields.ts +393 -0
  605. package/UI/Components/Forms/Utils/FollowPickName.ts +52 -0
  606. package/UI/Components/Forms/Utils/FormModalWidth.ts +35 -4
  607. package/UI/Components/Forms/Utils/OpenFormSections.ts +104 -0
  608. package/UI/Components/Forms/Utils/SteppedFormFooter.ts +151 -0
  609. package/UI/Components/Forms/Utils/UniqueName.ts +81 -0
  610. package/UI/Components/LabelRule/ImportLabelRulesModal.tsx +22 -3
  611. package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +6 -5
  612. package/UI/Components/Modal/ModalFooter.tsx +10 -1
  613. package/UI/Components/ModelDetail/CardModelDetail.tsx +33 -8
  614. package/UI/Components/ModelFormModal/ModelFormModal.tsx +44 -58
  615. package/UI/Components/ModelSwitch/ModelSwitchCard.tsx +305 -0
  616. package/UI/Components/ModelSwitch/ModelSwitchEvents.ts +109 -0
  617. package/UI/Components/ModelSwitch/ModelSwitchRow.tsx +438 -0
  618. package/UI/Components/ModelSwitch/ModelSwitchUtil.ts +120 -0
  619. package/UI/Components/ModelSwitch/ModelSwitchesCard.tsx +265 -0
  620. package/UI/Components/ModelSwitch/useSaveModelSwitch.ts +144 -0
  621. package/UI/Components/ModelTable/BaseModelTable.tsx +6 -0
  622. package/UI/Components/ModelTable/ModelTable.tsx +5 -0
  623. package/UI/Components/Navbar/NavBar.tsx +10 -9
  624. package/UI/Components/Navbar/NavBarMenuCatalog.ts +57 -22
  625. package/UI/Components/Navbar/NavBarMenuModal.tsx +17 -13
  626. package/UI/Components/Navbar/NavBarMobileMenu.tsx +40 -23
  627. package/UI/Components/Page/ModelHeaderEvents.ts +75 -0
  628. package/UI/Components/Page/ModelPage.tsx +21 -1
  629. package/UI/Components/Page/Page.tsx +68 -13
  630. package/UI/Components/PeoplePicker/PeoplePicker.tsx +150 -45
  631. package/UI/Components/PeoplePicker/PeoplePickerTypes.ts +193 -4
  632. package/UI/Components/PeoplePicker/PeopleSearchPopup.tsx +37 -10
  633. package/UI/Components/PublicForm/PublicFormFavicon.ts +99 -0
  634. package/UI/Components/PublicForm/PublicFormLogo.tsx +81 -0
  635. package/UI/Components/RuleCriteria/RuleCriteriaBuilder.tsx +5 -3
  636. package/UI/Components/RuleRun/RuleView.tsx +2 -5
  637. package/UI/Components/SaveStatus/SaveStatus.tsx +76 -0
  638. package/UI/Components/SaveStatus/useSaveOnChange.ts +178 -0
  639. package/UI/Components/SmtpConfig/SmtpConfigFormFields.ts +815 -0
  640. package/UI/Components/Sso/OidcProviderFormFields.ts +481 -0
  641. package/UI/Components/Sso/SamlProviderFormFields.ts +322 -0
  642. package/UI/Components/Sso/SsoProviderFormFields.ts +331 -0
  643. package/UI/Components/Table/TableEmptyState.tsx +39 -5
  644. package/UI/Components/Workflow/ArgumentsForm.tsx +21 -78
  645. package/UI/Components/Workflow/ComponentPicker/ComponentSearch.ts +18 -145
  646. package/UI/Components/Workflow/WorkflowLogModal.tsx +1 -3
  647. package/UI/Types/UseAnchoredFieldPopup.ts +46 -4
  648. package/UI/Utils/DefaultInviteTeam.ts +306 -0
  649. package/UI/Utils/GrantablePermission.ts +46 -0
  650. package/UI/Utils/PermissionGate.ts +80 -7
  651. package/UI/Utils/TranslateTemplate.ts +22 -0
  652. package/Utils/DistinctColor.ts +223 -0
  653. package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +47 -2
  654. package/Utils/Slo/SloHealth.ts +9 -3
  655. package/Utils/StatusPage/ReportSchedule.ts +462 -0
  656. package/Utils/Telemetry/DiscoveredResourceName.ts +95 -0
  657. package/Utils/WordMatch.ts +185 -0
  658. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +6 -6
  659. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -1
  660. package/build/dist/Models/DatabaseModels/File.js +47 -1
  661. package/build/dist/Models/DatabaseModels/File.js.map +1 -1
  662. package/build/dist/Models/DatabaseModels/Form.js +125 -0
  663. package/build/dist/Models/DatabaseModels/Form.js.map +1 -1
  664. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +6 -6
  665. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
  666. package/build/dist/Models/DatabaseModels/LogDropFilter.js +1 -0
  667. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  668. package/build/dist/Models/DatabaseModels/LogPipeline.js +1 -0
  669. package/build/dist/Models/DatabaseModels/LogPipeline.js.map +1 -1
  670. package/build/dist/Models/DatabaseModels/LogScrubRule.js +14 -8
  671. package/build/dist/Models/DatabaseModels/LogScrubRule.js.map +1 -1
  672. package/build/dist/Models/DatabaseModels/MetricRecordingRule.js +1 -1
  673. package/build/dist/Models/DatabaseModels/MetricRecordingRule.js.map +1 -1
  674. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js +2 -2
  675. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js.map +1 -1
  676. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +20 -9
  677. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
  678. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +6 -1
  679. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  680. package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
  681. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  682. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +1 -0
  683. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  684. package/build/dist/Models/DatabaseModels/TracePipeline.js +1 -0
  685. package/build/dist/Models/DatabaseModels/TracePipeline.js.map +1 -1
  686. package/build/dist/Models/DatabaseModels/TraceRecordingRule.js +1 -1
  687. package/build/dist/Models/DatabaseModels/TraceRecordingRule.js.map +1 -1
  688. package/build/dist/Models/DatabaseModels/TraceScrubRule.js +14 -8
  689. package/build/dist/Models/DatabaseModels/TraceScrubRule.js.map +1 -1
  690. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -2
  691. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  692. package/build/dist/Server/API/CustomDomainRoutes.js +124 -0
  693. package/build/dist/Server/API/CustomDomainRoutes.js.map +1 -0
  694. package/build/dist/Server/API/DashboardAPI.js +22 -4
  695. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  696. package/build/dist/Server/API/DashboardDomainAPI.js +56 -49
  697. package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -1
  698. package/build/dist/Server/API/StatusPageAPI.js +101 -39
  699. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  700. package/build/dist/Server/API/StatusPageDomainAPI.js +52 -51
  701. package/build/dist/Server/API/StatusPageDomainAPI.js.map +1 -1
  702. package/build/dist/Server/Infrastructure/GlobalCache.js +63 -0
  703. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  704. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797700000000-AddFormBranding.js +36 -0
  705. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797700000000-AddFormBranding.js.map +1 -0
  706. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  707. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  708. package/build/dist/Server/Services/AlertGroupingEngineService.js +44 -61
  709. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
  710. package/build/dist/Server/Services/AlertGroupingRuleService.js +45 -0
  711. package/build/dist/Server/Services/AlertGroupingRuleService.js.map +1 -1
  712. package/build/dist/Server/Services/CephClusterService.js +23 -0
  713. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  714. package/build/dist/Server/Services/CloudResourceService.js +39 -0
  715. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  716. package/build/dist/Server/Services/DashboardDomainService.js +510 -172
  717. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  718. package/build/dist/Server/Services/DashboardService.js +22 -9
  719. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  720. package/build/dist/Server/Services/DatabaseService.js +114 -10
  721. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  722. package/build/dist/Server/Services/DockerHostService.js +51 -0
  723. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  724. package/build/dist/Server/Services/DockerSwarmClusterService.js +23 -0
  725. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  726. package/build/dist/Server/Services/FileService.js +45 -0
  727. package/build/dist/Server/Services/FileService.js.map +1 -1
  728. package/build/dist/Server/Services/FormService.js +158 -14
  729. package/build/dist/Server/Services/FormService.js.map +1 -1
  730. package/build/dist/Server/Services/GlobalOidcService.js +9 -0
  731. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
  732. package/build/dist/Server/Services/GlobalSsoService.js +9 -0
  733. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
  734. package/build/dist/Server/Services/HostService.js +50 -0
  735. package/build/dist/Server/Services/HostService.js.map +1 -1
  736. package/build/dist/Server/Services/IncidentGroupingEngineService.js +45 -62
  737. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  738. package/build/dist/Server/Services/IncidentGroupingRuleService.js +45 -0
  739. package/build/dist/Server/Services/IncidentGroupingRuleService.js.map +1 -1
  740. package/build/dist/Server/Services/IoTFleetService.js +23 -0
  741. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  742. package/build/dist/Server/Services/KubernetesClusterService.js +54 -0
  743. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  744. package/build/dist/Server/Services/LabelService.js +6 -16
  745. package/build/dist/Server/Services/LabelService.js.map +1 -1
  746. package/build/dist/Server/Services/LogScrubRuleService.js +31 -0
  747. package/build/dist/Server/Services/LogScrubRuleService.js.map +1 -1
  748. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +202 -0
  749. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  750. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +7 -1
  751. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  752. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +17 -24
  753. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
  754. package/build/dist/Server/Services/OnCallSetupReminderService.js +32 -38
  755. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
  756. package/build/dist/Server/Services/PodmanHostService.js +51 -0
  757. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  758. package/build/dist/Server/Services/ProfileAggregationService.js +34 -0
  759. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
  760. package/build/dist/Server/Services/ProjectCallSMSConfigService.js +53 -3
  761. package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
  762. package/build/dist/Server/Services/ProjectOidcService.js +28 -0
  763. package/build/dist/Server/Services/ProjectOidcService.js.map +1 -1
  764. package/build/dist/Server/Services/ProjectSsoService.js +28 -0
  765. package/build/dist/Server/Services/ProjectSsoService.js.map +1 -1
  766. package/build/dist/Server/Services/ProxmoxClusterService.js +23 -0
  767. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  768. package/build/dist/Server/Services/RumApplicationService.js +42 -0
  769. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  770. package/build/dist/Server/Services/ScheduledMaintenanceService.js +18 -26
  771. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  772. package/build/dist/Server/Services/ServerlessFunctionService.js +44 -0
  773. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  774. package/build/dist/Server/Services/ServiceService.js +30 -4
  775. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  776. package/build/dist/Server/Services/StatusPageDomainService.js +495 -174
  777. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  778. package/build/dist/Server/Services/StatusPageOidcService.js +28 -0
  779. package/build/dist/Server/Services/StatusPageOidcService.js.map +1 -1
  780. package/build/dist/Server/Services/StatusPageResourceService.js +82 -46
  781. package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
  782. package/build/dist/Server/Services/StatusPageService.js +174 -45
  783. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  784. package/build/dist/Server/Services/StatusPageSsoService.js +28 -0
  785. package/build/dist/Server/Services/StatusPageSsoService.js.map +1 -1
  786. package/build/dist/Server/Services/TraceScrubRuleService.js +31 -0
  787. package/build/dist/Server/Services/TraceScrubRuleService.js.map +1 -1
  788. package/build/dist/Server/Services/UserIncomingCallNumberService.js +20 -10
  789. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  790. package/build/dist/Server/Services/VMwareVCenterService.js +23 -0
  791. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  792. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +3 -3
  793. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -1
  794. package/build/dist/Server/Utils/Greenlock/CertificateOrder.js +353 -0
  795. package/build/dist/Server/Utils/Greenlock/CertificateOrder.js.map +1 -0
  796. package/build/dist/Server/Utils/Greenlock/CertificateOrderBudget.js +119 -0
  797. package/build/dist/Server/Utils/Greenlock/CertificateOrderBudget.js.map +1 -0
  798. package/build/dist/Server/Utils/Greenlock/CertificateOrderFailures.js +208 -0
  799. package/build/dist/Server/Utils/Greenlock/CertificateOrderFailures.js.map +1 -0
  800. package/build/dist/Server/Utils/Greenlock/CertificateOrderLock.js +111 -0
  801. package/build/dist/Server/Utils/Greenlock/CertificateOrderLock.js.map +1 -0
  802. package/build/dist/Server/Utils/Greenlock/CertificateOrderOutcome.js +30 -0
  803. package/build/dist/Server/Utils/Greenlock/CertificateOrderOutcome.js.map +1 -0
  804. package/build/dist/Server/Utils/Greenlock/CertificateOwners.js +52 -0
  805. package/build/dist/Server/Utils/Greenlock/CertificateOwners.js.map +1 -0
  806. package/build/dist/Server/Utils/Greenlock/CertificateReissueOrder.js +80 -0
  807. package/build/dist/Server/Utils/Greenlock/CertificateReissueOrder.js.map +1 -0
  808. package/build/dist/Server/Utils/Greenlock/CustomDomainOrders.js +296 -0
  809. package/build/dist/Server/Utils/Greenlock/CustomDomainOrders.js.map +1 -0
  810. package/build/dist/Server/Utils/Greenlock/Greenlock.js +595 -146
  811. package/build/dist/Server/Utils/Greenlock/Greenlock.js.map +1 -1
  812. package/build/dist/Server/Utils/Rules/GroupingRuleEpisodeOwners.js +366 -0
  813. package/build/dist/Server/Utils/Rules/GroupingRuleEpisodeOwners.js.map +1 -0
  814. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +7 -0
  815. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
  816. package/build/dist/Server/Utils/ScrubRuleValidation.js +127 -0
  817. package/build/dist/Server/Utils/ScrubRuleValidation.js.map +1 -0
  818. package/build/dist/Server/Utils/StatusPage/AffectedStatusPageResources.js +97 -0
  819. package/build/dist/Server/Utils/StatusPage/AffectedStatusPageResources.js.map +1 -0
  820. package/build/dist/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.js +195 -0
  821. package/build/dist/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.js.map +1 -0
  822. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceCreate.js +177 -0
  823. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceCreate.js.map +1 -0
  824. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceUpdate.js +129 -0
  825. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceUpdate.js.map +1 -0
  826. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +8 -2
  827. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -1
  828. package/build/dist/Types/BrandColors.js +9 -0
  829. package/build/dist/Types/BrandColors.js.map +1 -1
  830. package/build/dist/Types/CustomDomain/CustomDomainCertificates.js +71 -0
  831. package/build/dist/Types/CustomDomain/CustomDomainCertificates.js.map +1 -0
  832. package/build/dist/Types/CustomDomain/CustomDomainVerification.js +58 -0
  833. package/build/dist/Types/CustomDomain/CustomDomainVerification.js.map +1 -0
  834. package/build/dist/Types/Dashboard/DashboardAccess.js +157 -0
  835. package/build/dist/Types/Dashboard/DashboardAccess.js.map +1 -0
  836. package/build/dist/Types/Dashboard/DashboardTemplates.js +26 -0
  837. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  838. package/build/dist/Types/Filter/FilterConditionUtil.js +24 -0
  839. package/build/dist/Types/Filter/FilterConditionUtil.js.map +1 -0
  840. package/build/dist/Types/Form/FormBranding.js +266 -0
  841. package/build/dist/Types/Form/FormBranding.js.map +1 -0
  842. package/build/dist/Types/Form/FormPublic.js +6 -0
  843. package/build/dist/Types/Form/FormPublic.js.map +1 -1
  844. package/build/dist/Types/IncomingCall/IncomingCallRingTime.js +37 -0
  845. package/build/dist/Types/IncomingCall/IncomingCallRingTime.js.map +1 -0
  846. package/build/dist/Types/Log/LogScrubField.js +15 -0
  847. package/build/dist/Types/Log/LogScrubField.js.map +1 -0
  848. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +1 -1
  849. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  850. package/build/dist/Types/NotificationRule/OnCallRuleKind.js +134 -0
  851. package/build/dist/Types/NotificationRule/OnCallRuleKind.js.map +1 -0
  852. package/build/dist/Types/OnCallDutyPolicy/FirstResponders.js +2 -23
  853. package/build/dist/Types/OnCallDutyPolicy/FirstResponders.js.map +1 -1
  854. package/build/dist/Types/OnCallDutyPolicy/MiscDataId.js +30 -0
  855. package/build/dist/Types/OnCallDutyPolicy/MiscDataId.js.map +1 -0
  856. package/build/dist/Types/OnCallDutyPolicy/ScheduleFirstLayer.js +113 -0
  857. package/build/dist/Types/OnCallDutyPolicy/ScheduleFirstLayer.js.map +1 -0
  858. package/build/dist/Types/OnCallDutyPolicy/ScheduleLayerDefaults.js +95 -0
  859. package/build/dist/Types/OnCallDutyPolicy/ScheduleLayerDefaults.js.map +1 -0
  860. package/build/dist/Types/OnCallDutyPolicy/UserOverrideCoverRequest.js +99 -0
  861. package/build/dist/Types/OnCallDutyPolicy/UserOverrideCoverRequest.js.map +1 -0
  862. package/build/dist/Types/SSO/OidcProviderDefaults.js +189 -0
  863. package/build/dist/Types/SSO/OidcProviderDefaults.js.map +1 -0
  864. package/build/dist/Types/SSO/SamlProviderDefaults.js +55 -0
  865. package/build/dist/Types/SSO/SamlProviderDefaults.js.map +1 -0
  866. package/build/dist/Types/SSO/SsoProviderDefaults.js +67 -0
  867. package/build/dist/Types/SSO/SsoProviderDefaults.js.map +1 -0
  868. package/build/dist/Types/StatusPage/StatusPageAccess.js +132 -0
  869. package/build/dist/Types/StatusPage/StatusPageAccess.js.map +1 -0
  870. package/build/dist/Types/StatusPage/StatusPagesListingMonitors.js +84 -0
  871. package/build/dist/Types/StatusPage/StatusPagesListingMonitors.js.map +1 -0
  872. package/build/dist/Types/Telemetry/ScrubRule.js +180 -0
  873. package/build/dist/Types/Telemetry/ScrubRule.js.map +1 -0
  874. package/build/dist/UI/Components/AdvancedPageSection/AdvancedPageSection.js +9 -7
  875. package/build/dist/UI/Components/AdvancedPageSection/AdvancedPageSection.js.map +1 -1
  876. package/build/dist/UI/Components/Card/Card.js +81 -35
  877. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  878. package/build/dist/UI/Components/ChoiceRows/ChoiceRows.js +54 -0
  879. package/build/dist/UI/Components/ChoiceRows/ChoiceRows.js.map +1 -0
  880. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +25 -12
  881. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  882. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +632 -64
  883. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -1
  884. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +7 -1
  885. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -1
  886. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +7 -1
  887. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  888. package/build/dist/UI/Components/Detail/Detail.js +26 -13
  889. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  890. package/build/dist/UI/Components/Detail/DetailRecordLine.js +32 -0
  891. package/build/dist/UI/Components/Detail/DetailRecordLine.js.map +1 -0
  892. package/build/dist/UI/Components/Detail/DetailRecordTime.js +134 -0
  893. package/build/dist/UI/Components/Detail/DetailRecordTime.js.map +1 -0
  894. package/build/dist/UI/Components/Dropdown/DropdownChange.js +102 -0
  895. package/build/dist/UI/Components/Dropdown/DropdownChange.js.map +1 -0
  896. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +134 -57
  897. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  898. package/build/dist/UI/Components/EntityDropdown/EntityDropdownQuery.js +78 -0
  899. package/build/dist/UI/Components/EntityDropdown/EntityDropdownQuery.js.map +1 -0
  900. package/build/dist/UI/Components/FilePicker/FilePicker.js +55 -6
  901. package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
  902. package/build/dist/UI/Components/FoldedSection/FoldedSection.js +139 -0
  903. package/build/dist/UI/Components/FoldedSection/FoldedSection.js.map +1 -0
  904. package/build/dist/UI/Components/FoldedSection/FoldedSectionItem.js +58 -0
  905. package/build/dist/UI/Components/FoldedSection/FoldedSectionItem.js.map +1 -0
  906. package/build/dist/UI/Components/FoldedSection/FoldedSectionTitles.js +34 -0
  907. package/build/dist/UI/Components/FoldedSection/FoldedSectionTitles.js.map +1 -0
  908. package/build/dist/UI/Components/FormModal/BasicFormModal.js +29 -45
  909. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  910. package/build/dist/UI/Components/Forms/BasicForm.js +148 -89
  911. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  912. package/build/dist/UI/Components/Forms/BasicModelForm.js +1 -1
  913. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  914. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +49 -10
  915. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -1
  916. package/build/dist/UI/Components/Forms/Fields/FormField.js +25 -11
  917. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  918. package/build/dist/UI/Components/Forms/Fields/GeneratedKeyField.js +2 -5
  919. package/build/dist/UI/Components/Forms/Fields/GeneratedKeyField.js.map +1 -1
  920. package/build/dist/UI/Components/Forms/FormSummary.js +5 -3
  921. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  922. package/build/dist/UI/Components/Forms/ModelForm.js +72 -14
  923. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  924. package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
  925. package/build/dist/UI/Components/Forms/Utils/AdvancedFormSection.js +80 -23
  926. package/build/dist/UI/Components/Forms/Utils/AdvancedFormSection.js.map +1 -1
  927. package/build/dist/UI/Components/Forms/Utils/CreateFormDefaults.js +91 -9
  928. package/build/dist/UI/Components/Forms/Utils/CreateFormDefaults.js.map +1 -1
  929. package/build/dist/UI/Components/Forms/Utils/FoldedFormFields.js +243 -0
  930. package/build/dist/UI/Components/Forms/Utils/FoldedFormFields.js.map +1 -0
  931. package/build/dist/UI/Components/Forms/Utils/FollowPickName.js +32 -0
  932. package/build/dist/UI/Components/Forms/Utils/FollowPickName.js.map +1 -0
  933. package/build/dist/UI/Components/Forms/Utils/FormModalWidth.js +25 -5
  934. package/build/dist/UI/Components/Forms/Utils/FormModalWidth.js.map +1 -1
  935. package/build/dist/UI/Components/Forms/Utils/OpenFormSections.js +32 -0
  936. package/build/dist/UI/Components/Forms/Utils/OpenFormSections.js.map +1 -0
  937. package/build/dist/UI/Components/Forms/Utils/SteppedFormFooter.js +71 -0
  938. package/build/dist/UI/Components/Forms/Utils/SteppedFormFooter.js.map +1 -0
  939. package/build/dist/UI/Components/Forms/Utils/UniqueName.js +56 -0
  940. package/build/dist/UI/Components/Forms/Utils/UniqueName.js.map +1 -0
  941. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js +17 -1
  942. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js.map +1 -1
  943. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +1 -2
  944. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
  945. package/build/dist/UI/Components/Modal/ModalFooter.js +8 -1
  946. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  947. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +19 -6
  948. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  949. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +33 -43
  950. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  951. package/build/dist/UI/Components/ModelSwitch/ModelSwitchCard.js +151 -0
  952. package/build/dist/UI/Components/ModelSwitch/ModelSwitchCard.js.map +1 -0
  953. package/build/dist/UI/Components/ModelSwitch/ModelSwitchEvents.js +54 -0
  954. package/build/dist/UI/Components/ModelSwitch/ModelSwitchEvents.js.map +1 -0
  955. package/build/dist/UI/Components/ModelSwitch/ModelSwitchRow.js +201 -0
  956. package/build/dist/UI/Components/ModelSwitch/ModelSwitchRow.js.map +1 -0
  957. package/build/dist/UI/Components/ModelSwitch/ModelSwitchUtil.js +60 -0
  958. package/build/dist/UI/Components/ModelSwitch/ModelSwitchUtil.js.map +1 -0
  959. package/build/dist/UI/Components/ModelSwitch/ModelSwitchesCard.js +116 -0
  960. package/build/dist/UI/Components/ModelSwitch/ModelSwitchesCard.js.map +1 -0
  961. package/build/dist/UI/Components/ModelSwitch/useSaveModelSwitch.js +68 -0
  962. package/build/dist/UI/Components/ModelSwitch/useSaveModelSwitch.js.map +1 -0
  963. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -0
  964. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  965. package/build/dist/UI/Components/ModelTable/ModelTable.js +3 -1
  966. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  967. package/build/dist/UI/Components/Navbar/NavBar.js +2 -2
  968. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  969. package/build/dist/UI/Components/Navbar/NavBarMenuCatalog.js +21 -10
  970. package/build/dist/UI/Components/Navbar/NavBarMenuCatalog.js.map +1 -1
  971. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +10 -7
  972. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  973. package/build/dist/UI/Components/Navbar/NavBarMobileMenu.js +17 -9
  974. package/build/dist/UI/Components/Navbar/NavBarMobileMenu.js.map +1 -1
  975. package/build/dist/UI/Components/Page/ModelHeaderEvents.js +43 -0
  976. package/build/dist/UI/Components/Page/ModelHeaderEvents.js.map +1 -0
  977. package/build/dist/UI/Components/Page/ModelPage.js +19 -1
  978. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  979. package/build/dist/UI/Components/Page/Page.js +31 -13
  980. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  981. package/build/dist/UI/Components/PeoplePicker/PeoplePicker.js +62 -20
  982. package/build/dist/UI/Components/PeoplePicker/PeoplePicker.js.map +1 -1
  983. package/build/dist/UI/Components/PeoplePicker/PeoplePickerTypes.js +98 -1
  984. package/build/dist/UI/Components/PeoplePicker/PeoplePickerTypes.js.map +1 -1
  985. package/build/dist/UI/Components/PeoplePicker/PeopleSearchPopup.js +35 -14
  986. package/build/dist/UI/Components/PeoplePicker/PeopleSearchPopup.js.map +1 -1
  987. package/build/dist/UI/Components/PublicForm/PublicFormFavicon.js +66 -0
  988. package/build/dist/UI/Components/PublicForm/PublicFormFavicon.js.map +1 -0
  989. package/build/dist/UI/Components/PublicForm/PublicFormLogo.js +38 -0
  990. package/build/dist/UI/Components/PublicForm/PublicFormLogo.js.map +1 -0
  991. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js +5 -3
  992. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js.map +1 -1
  993. package/build/dist/UI/Components/RuleRun/RuleView.js +2 -2
  994. package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -1
  995. package/build/dist/UI/Components/SaveStatus/SaveStatus.js +46 -0
  996. package/build/dist/UI/Components/SaveStatus/SaveStatus.js.map +1 -0
  997. package/build/dist/UI/Components/SaveStatus/useSaveOnChange.js +98 -0
  998. package/build/dist/UI/Components/SaveStatus/useSaveOnChange.js.map +1 -0
  999. package/build/dist/UI/Components/SmtpConfig/SmtpConfigFormFields.js +503 -0
  1000. package/build/dist/UI/Components/SmtpConfig/SmtpConfigFormFields.js.map +1 -0
  1001. package/build/dist/UI/Components/Sso/OidcProviderFormFields.js +283 -0
  1002. package/build/dist/UI/Components/Sso/OidcProviderFormFields.js.map +1 -0
  1003. package/build/dist/UI/Components/Sso/SamlProviderFormFields.js +182 -0
  1004. package/build/dist/UI/Components/Sso/SamlProviderFormFields.js.map +1 -0
  1005. package/build/dist/UI/Components/Sso/SsoProviderFormFields.js +208 -0
  1006. package/build/dist/UI/Components/Sso/SsoProviderFormFields.js.map +1 -0
  1007. package/build/dist/UI/Components/Table/TableEmptyState.js +17 -4
  1008. package/build/dist/UI/Components/Table/TableEmptyState.js.map +1 -1
  1009. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +17 -52
  1010. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  1011. package/build/dist/UI/Components/Workflow/ComponentPicker/ComponentSearch.js +7 -89
  1012. package/build/dist/UI/Components/Workflow/ComponentPicker/ComponentSearch.js.map +1 -1
  1013. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +1 -1
  1014. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -1
  1015. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +22 -3
  1016. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  1017. package/build/dist/UI/Utils/DefaultInviteTeam.js +207 -0
  1018. package/build/dist/UI/Utils/DefaultInviteTeam.js.map +1 -0
  1019. package/build/dist/UI/Utils/GrantablePermission.js +31 -0
  1020. package/build/dist/UI/Utils/GrantablePermission.js.map +1 -1
  1021. package/build/dist/UI/Utils/PermissionGate.js +54 -3
  1022. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  1023. package/build/dist/UI/Utils/TranslateTemplate.js +16 -0
  1024. package/build/dist/UI/Utils/TranslateTemplate.js.map +1 -1
  1025. package/build/dist/Utils/DistinctColor.js +151 -0
  1026. package/build/dist/Utils/DistinctColor.js.map +1 -0
  1027. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +12 -1
  1028. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -1
  1029. package/build/dist/Utils/Slo/SloHealth.js +9 -3
  1030. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  1031. package/build/dist/Utils/StatusPage/ReportSchedule.js +304 -0
  1032. package/build/dist/Utils/StatusPage/ReportSchedule.js.map +1 -0
  1033. package/build/dist/Utils/Telemetry/DiscoveredResourceName.js +65 -0
  1034. package/build/dist/Utils/Telemetry/DiscoveredResourceName.js.map +1 -0
  1035. package/build/dist/Utils/WordMatch.js +115 -0
  1036. package/build/dist/Utils/WordMatch.js.map +1 -0
  1037. package/package.json +1 -1
  1038. package/Tests/App/Dashboard/BulkChangeStateModalSteps.test.ts +0 -109
  1039. package/Tests/App/StatusPage/StatusPageSubscribeFromFirstStep.test.tsx +0 -382
  1040. package/Tests/UI/Components/Forms/BasicFormFinishFromAnyStep.test.tsx +0 -729
  1041. package/Tests/UI/Components/Forms/FinishFromAnyStep.test.ts +0 -571
  1042. package/Tests/UI/Components/Forms/FinishFromAnyStepGuard.test.ts +0 -566
  1043. package/UI/Components/Forms/Utils/FinishFromAnyStep.ts +0 -284
  1044. package/build/dist/UI/Components/Forms/Utils/FinishFromAnyStep.js +0 -132
  1045. package/build/dist/UI/Components/Forms/Utils/FinishFromAnyStep.js.map +0 -1
@@ -3,6 +3,14 @@ import DeleteBy from "../Types/Database/DeleteBy";
3
3
  import UpdateBy from "../Types/Database/UpdateBy";
4
4
  import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
5
5
  import GreenlockUtil from "../Utils/Greenlock/Greenlock";
6
+ import CertificateOrder, {
7
+ CertificateOrderOutcome,
8
+ } from "../Utils/Greenlock/CertificateOrder";
9
+ import CustomDomainOrders from "../Utils/Greenlock/CustomDomainOrders";
10
+ import { CertificateOrderLockHandle } from "../Utils/Greenlock/CertificateOrderLock";
11
+ import { CertificateOrderReason } from "../Utils/Greenlock/CertificateOrderBudget";
12
+ import CertificateOrderFailures from "../Utils/Greenlock/CertificateOrderFailures";
13
+ import CertificateReissueOrder from "../Utils/Greenlock/CertificateReissueOrder";
6
14
  import logger, { LogAttributes } from "../Utils/Logger";
7
15
  import DatabaseService from "./DatabaseService";
8
16
  import DomainService from "./DomainService";
@@ -15,19 +23,47 @@ import ObjectID from "../../Types/ObjectID";
15
23
  import AcmeCertificate from "../../Models/DatabaseModels/AcmeCertificate";
16
24
  import DomainModel from "../../Models/DatabaseModels/Domain";
17
25
  import DashboardDomain from "../../Models/DatabaseModels/DashboardDomain";
18
- import AcmeCertificateService from "./AcmeCertificateService";
19
26
  import Telemetry, { Span } from "../Utils/Telemetry";
20
27
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
21
28
  import { DashboardCNameRecord } from "../EnvironmentConfig";
22
29
  import Domain from "../Types/Domain";
23
30
  import OneUptimeDate from "../../Types/Date";
24
31
  import CertificateReissueUtil from "../../Utils/CertificateReissue";
25
- import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
26
32
  import QueryHelper from "../Types/Database/QueryHelper";
33
+ import ArrayUtil from "../../Utils/Array";
34
+ import { CustomDomainVerificationResult } from "../../Types/CustomDomain/CustomDomainVerification";
35
+ import { CustomDomainCertificate } from "../../Types/CustomDomain/CustomDomainCertificates";
27
36
 
28
37
  const DASHBOARD_DOMAIN_EGRESS_LABEL: string = "Dashboard domain";
29
38
 
30
39
  export class Service extends DatabaseService<DashboardDomain> {
40
+ /*
41
+ * How many certificates the dashboard sweeps may order: the first orders
42
+ * and the re-orders of a certificate that has gone missing together, in
43
+ * one 15-minute window (SWEEP_ORDER_BUDGET, CertificateOrder.takeOrderSlot)
44
+ * - and, separately, how many the dashboard renewal run renews per run.
45
+ *
46
+ * Every order spends from the one Let's Encrypt account the whole
47
+ * installation shares - 300 new orders per account per three hours - and
48
+ * status page certificates, the larger fleet, are ordered and renewed from
49
+ * it too. These caps keep a backlog - such as the first runs re-ordering
50
+ * every dashboard certificate the status page renewal job used to delete -
51
+ * worked off a few domains per run rather than in one burst, and none of
52
+ * them can order beyond the installation's own budget for that account
53
+ * (CertificateOrderBudget), which every order of every kind draws from.
54
+ */
55
+ public static readonly ORDER_MAX_PER_RUN: number = 5;
56
+
57
+ // The budget the dashboard ordering sweeps share (CertificateOrder.takeOrderSlot).
58
+ public static readonly SWEEP_ORDER_BUDGET: string = "DashboardDomainSweeps";
59
+
60
+ /*
61
+ * How many domains the verification and provisioning sweeps check at once.
62
+ * Each check is a bounded request out to a customer domain; the same
63
+ * figure the status page provisioning sweep uses.
64
+ */
65
+ public static readonly DOMAIN_CHECK_CONCURRENCY: number = 10;
66
+
31
67
  public constructor() {
32
68
  super(DashboardDomain);
33
69
  }
@@ -171,9 +207,81 @@ export class Service extends DatabaseService<DashboardDomain> {
171
207
  await GreenlockUtil.removeDomain(domain);
172
208
  }
173
209
 
210
+ /*
211
+ * The domain with its full name and whether it serves an uploaded
212
+ * certificate, read once when the caller did not have them both.
213
+ */
214
+ private async getDomainToOrder(
215
+ dashboardDomain: DashboardDomain,
216
+ ): Promise<DashboardDomain> {
217
+ if (!dashboardDomain.id) {
218
+ throw new BadDataException(
219
+ "Domain ID is required to order a certificate",
220
+ );
221
+ }
222
+
223
+ if (
224
+ dashboardDomain.fullDomain &&
225
+ dashboardDomain.isCustomCertificate !== undefined
226
+ ) {
227
+ return dashboardDomain;
228
+ }
229
+
230
+ const fetchedDashboardDomain: DashboardDomain | null = await this.findOneBy(
231
+ {
232
+ query: {
233
+ _id: dashboardDomain.id.toString(),
234
+ },
235
+ select: {
236
+ _id: true,
237
+ fullDomain: true,
238
+ isCustomCertificate: true,
239
+ projectId: true,
240
+ },
241
+ props: {
242
+ isRoot: true,
243
+ },
244
+ },
245
+ );
246
+
247
+ if (!fetchedDashboardDomain) {
248
+ throw new BadDataException("DomainModel not found");
249
+ }
250
+
251
+ if (!fetchedDashboardDomain.fullDomain) {
252
+ throw new BadDataException(
253
+ "Unable to order certificate because domain is null",
254
+ );
255
+ }
256
+
257
+ return fetchedDashboardDomain;
258
+ }
259
+
260
+ /*
261
+ * Order this domain's certificate and record it: a first certificate
262
+ * (the default), or a reissue. GreenlockUtil.orderCert places it under the
263
+ * name's order lock - the one handed in, or its own - and within the
264
+ * installation's Let's Encrypt allowance; the outcome says whether it
265
+ * ordered. A CNAME check that fails refuses the order and no longer
266
+ * deletes the domain's certificate.
267
+ */
174
268
  @CaptureSpan()
175
- public async orderCert(dashboardDomain: DashboardDomain): Promise<void> {
176
- return Telemetry.startActiveSpan<Promise<void>>({
269
+ public async orderCert(
270
+ dashboardDomain: DashboardDomain,
271
+ options?: {
272
+ reason?: CertificateOrderReason | undefined;
273
+ // The name's order lock, when the caller holds it.
274
+ lock?: CertificateOrderLockHandle | undefined;
275
+ // The caller has just found the domain's CNAME record.
276
+ cnameVerifiedJustNow?: boolean | undefined;
277
+ /*
278
+ * The caller's share of orders (CertificateOrder.getOrderShare),
279
+ * asked once the CNAME check has passed.
280
+ */
281
+ mayOrder?: (() => Promise<boolean>) | undefined;
282
+ },
283
+ ): Promise<CertificateOrderOutcome> {
284
+ return Telemetry.startActiveSpan<Promise<CertificateOrderOutcome>>({
177
285
  name: "DashboardDomainService.orderCert",
178
286
  options: {
179
287
  attributes: {
@@ -181,64 +289,54 @@ export class Service extends DatabaseService<DashboardDomain> {
181
289
  _id: dashboardDomain.id?.toString(),
182
290
  },
183
291
  },
184
- fn: async (span: Span): Promise<void> => {
292
+ fn: async (span: Span): Promise<CertificateOrderOutcome> => {
185
293
  try {
186
- if (!dashboardDomain.fullDomain) {
187
- const fetchedDashboardDomain: DashboardDomain | null =
188
- await this.findOneBy({
189
- query: {
190
- _id: dashboardDomain.id!.toString(),
191
- },
192
- select: {
193
- _id: true,
194
- fullDomain: true,
195
- },
196
- props: {
197
- isRoot: true,
198
- },
199
- });
200
-
201
- if (!fetchedDashboardDomain) {
202
- throw new BadDataException("DomainModel not found");
203
- }
204
-
205
- dashboardDomain = fetchedDashboardDomain;
206
- }
294
+ const domainToOrder: DashboardDomain =
295
+ await this.getDomainToOrder(dashboardDomain);
207
296
 
208
- if (!dashboardDomain.fullDomain) {
209
- throw new BadDataException(
210
- "Unable to order certificate because domain is null",
211
- );
212
- }
213
-
214
- logger.debug(
215
- "Ordering SSL for domain: " + dashboardDomain.fullDomain,
216
- { fullDomain: dashboardDomain.fullDomain } as LogAttributes,
217
- );
297
+ logger.debug("Ordering SSL for domain: " + domainToOrder.fullDomain, {
298
+ fullDomain: domainToOrder.fullDomain,
299
+ } as LogAttributes);
218
300
 
219
- await GreenlockUtil.orderCert({
220
- domain: dashboardDomain.fullDomain as string,
221
- validateCname: async (fullDomain: string) => {
222
- return await this.isCnameValid(fullDomain);
223
- },
224
- });
301
+ const outcome: CertificateOrderOutcome =
302
+ await GreenlockUtil.orderCert({
303
+ domain: domainToOrder.fullDomain as string,
304
+ reason:
305
+ options?.reason || CertificateOrderReason.FirstCertificate,
306
+ validateCname: options?.cnameVerifiedJustNow
307
+ ? null
308
+ : async (fullDomain: string) => {
309
+ return await this.isCnameValid(fullDomain);
310
+ },
311
+ lock: options?.lock,
312
+ mayOrder: options?.mayOrder,
313
+ });
225
314
 
226
- logger.debug(
227
- "SSL ordered for domain: " + dashboardDomain.fullDomain,
228
- { fullDomain: dashboardDomain.fullDomain } as LogAttributes,
229
- );
315
+ if (outcome === CertificateOrderOutcome.Ordered) {
316
+ logger.debug(
317
+ "SSL ordered for domain: " + domainToOrder.fullDomain,
318
+ { fullDomain: domainToOrder.fullDomain } as LogAttributes,
319
+ );
230
320
 
231
- await this.updateOneById({
232
- id: dashboardDomain.id!,
233
- data: {
234
- isSslOrdered: true,
235
- },
236
- props: {
237
- isRoot: true,
238
- },
239
- });
321
+ /*
322
+ * Verified as well as ordered: Let's Encrypt has just fetched
323
+ * its challenge from this domain, so the domain reaches us.
324
+ */
325
+ await this.updateOneById({
326
+ id: domainToOrder.id!,
327
+ data: {
328
+ isCnameVerified: true,
329
+ isSslOrdered: true,
330
+ },
331
+ props: {
332
+ isRoot: true,
333
+ },
334
+ });
335
+ }
240
336
 
241
337
  Telemetry.endSpan(span);
338
+
339
+ return outcome;
242
340
  } catch (err) {
243
341
  Telemetry.recordExceptionMarkSpanAsErrorAndEndSpan({
244
342
  span,
@@ -251,6 +349,146 @@ export class Service extends DatabaseService<DashboardDomain> {
251
349
  });
252
350
  }
253
351
 
352
+ /*
353
+ * Records these domains as ordered: they have a certificate, ordered
354
+ * before, so nothing is ordered. One write for all of them, and only on
355
+ * domains that are still verified (see StatusPageDomainService's twin).
356
+ */
357
+ private async recordCertificatesAsOrdered(
358
+ domainIds: Array<ObjectID>,
359
+ ): Promise<void> {
360
+ if (domainIds.length === 0) {
361
+ return;
362
+ }
363
+
364
+ await this.updateBy({
365
+ query: {
366
+ _id: QueryHelper.any(
367
+ domainIds.map((id: ObjectID) => {
368
+ return id.toString();
369
+ }),
370
+ ),
371
+ isCnameVerified: true,
372
+ isSslOrdered: false,
373
+ },
374
+ data: {
375
+ isSslOrdered: true,
376
+ },
377
+ limit: LIMIT_MAX,
378
+ skip: 0,
379
+ props: {
380
+ isRoot: true,
381
+ },
382
+ });
383
+ }
384
+
385
+ /*
386
+ * Order this domain's free certificate unless it has one already, or one
387
+ * is being ordered for it right now (CertificateOrder.orderIfMissing): the
388
+ * one way a first certificate is ordered, whether by Check now, by the
389
+ * dashboard sweeps or by the order-ssl API, so a name is never ordered
390
+ * twice. Never for a domain that serves a certificate its owner uploaded.
391
+ * Throws what the order throws, so a caller can show why.
392
+ */
393
+ @CaptureSpan()
394
+ public async orderCertIfMissing(
395
+ dashboardDomain: DashboardDomain,
396
+ options?: {
397
+ // An order of the sweeps: it draws from their shared window budget.
398
+ fromSweep?: boolean | undefined;
399
+ // An order somebody asked for: it draws from the on-demand budget.
400
+ onDemand?: boolean | undefined;
401
+ // The caller has just found the domain's CNAME record.
402
+ cnameVerifiedJustNow?: boolean | undefined;
403
+ // Order for an expired certificate too (Check now).
404
+ renewIfExpired?: boolean | undefined;
405
+ },
406
+ ): Promise<CertificateOrderOutcome> {
407
+ const domainToOrder: DashboardDomain =
408
+ await this.getDomainToOrder(dashboardDomain);
409
+
410
+ if (domainToOrder.isCustomCertificate) {
411
+ throw new BadDataException(
412
+ "This domain uses a certificate you uploaded, so there is no free SSL certificate to order for it.",
413
+ );
414
+ }
415
+
416
+ const domainId: ObjectID = domainToOrder.id!;
417
+
418
+ return await CertificateOrder.orderIfMissing({
419
+ domain: domainToOrder.fullDomain as string,
420
+ renewIfExpired: options?.renewIfExpired,
421
+ recordAsOrdered: async (): Promise<void> => {
422
+ await this.recordCertificatesAsOrdered([domainId]);
423
+ },
424
+ order: async (
425
+ lock: CertificateOrderLockHandle,
426
+ ): Promise<CertificateOrderOutcome> => {
427
+ return await this.orderCert(domainToOrder, {
428
+ reason: CertificateOrderReason.FirstCertificate,
429
+ lock: lock,
430
+ cnameVerifiedJustNow: options?.cnameVerifiedJustNow,
431
+ mayOrder: CertificateOrder.getOrderShare({
432
+ sweep: options?.fromSweep
433
+ ? {
434
+ budget: Service.SWEEP_ORDER_BUDGET,
435
+ maxPerWindow: Service.ORDER_MAX_PER_RUN,
436
+ }
437
+ : undefined,
438
+ onDemand: options?.onDemand
439
+ ? { projectId: domainToOrder.projectId?.toString() }
440
+ : undefined,
441
+ }),
442
+ });
443
+ },
444
+ });
445
+ }
446
+
447
+ /*
448
+ * Called by verify-cname - the domain's Check now - once it has found the
449
+ * domain's CNAME record: order the domain's free certificate now rather
450
+ * than at the next run of the order sweep, and say what happens to its
451
+ * certificate next. The same step as a status page domain's
452
+ * (CustomDomainOrders.orderOnceCnameIsVerified): one on-demand order per
453
+ * domain per 15 minutes, counted against the domain's project, under the
454
+ * name's lock and within the installation's Let's Encrypt allowance; never
455
+ * for an uploaded certificate; Issued only for a certificate that is there
456
+ * and has not expired. Never rejects.
457
+ */
458
+ @CaptureSpan()
459
+ public async orderCertOnceCnameIsVerified(
460
+ dashboardDomain: DashboardDomain,
461
+ options?: { waitInMs?: number | undefined },
462
+ ): Promise<CustomDomainVerificationResult> {
463
+ return await CustomDomainOrders.orderOnceCnameIsVerified({
464
+ domain: dashboardDomain,
465
+ waitInMs: options?.waitInMs,
466
+ recordAsOrdered: async (): Promise<void> => {
467
+ await this.recordCertificatesAsOrdered([dashboardDomain.id!]);
468
+ },
469
+ orderIfMissing: async (): Promise<CertificateOrderOutcome> => {
470
+ return await this.orderCertIfMissing(dashboardDomain, {
471
+ onDemand: true,
472
+ // The route found the record a moment ago.
473
+ cnameVerifiedJustNow: true,
474
+ renewIfExpired: true,
475
+ });
476
+ },
477
+ });
478
+ }
479
+
480
+ /*
481
+ * Where the certificates of these domains stand, for the Custom Domains
482
+ * page's Status column (CustomDomainCertificates): each one's expiry, and
483
+ * its last failed order while no order since has succeeded.
484
+ */
485
+ @CaptureSpan()
486
+ public async getCertificates(
487
+ domains: Array<DashboardDomain>,
488
+ ): Promise<Array<CustomDomainCertificate>> {
489
+ return await CustomDomainOrders.getCertificates(domains);
490
+ }
491
+
254
492
  /*
255
493
  * Reissue this domain's Let's Encrypt certificate because a customer asked
256
494
  * for it, rather than because it is close to expiring.
@@ -313,69 +551,72 @@ export class Service extends DatabaseService<DashboardDomain> {
313
551
  }
314
552
 
315
553
  /*
316
- * A domain that never ordered a certificate has nothing to reissue - the
317
- * dashboard shows "Order Free SSL" for it, which is the correct button.
554
+ * A domain that never ordered a certificate has nothing to reissue. Its
555
+ * first certificate is ordered on its own once the CNAME is verified, and
556
+ * the dashboard shows Reissue SSL only after that.
318
557
  */
319
558
  if (!dashboardDomain.isSslOrdered) {
320
559
  throw new BadDataException(
321
- "No SSL certificate has been ordered for this domain yet. Please order one first.",
560
+ "No SSL certificate has been ordered for this domain yet. One is ordered automatically once its CNAME record is verified.",
322
561
  );
323
562
  }
324
563
 
325
- /*
326
- * Claim the cooldown before ordering anything, and claim it by putting the
327
- * cooldown condition in the WHERE clause rather than in an `if` above the
328
- * write. Two clicks that arrive together both read a row that is not
329
- * cooling down; only the write can decide which one of them gets to spend
330
- * the CA's allowance.
331
- *
332
- * The stamp goes down BEFORE the order and is never rolled back on
333
- * failure. A rejected order still costs a validation attempt against the
334
- * shared account, and a domain whose order fails is exactly the domain
335
- * somebody presses again - so a failed attempt has to start the clock the
336
- * same way a successful one does.
337
- */
338
- const claimedRowCount: number = await this.updateOneBy({
339
- query: {
340
- _id: domainId.toString(),
341
- certificateReissueRequestedAt: QueryHelper.lessThanEqualToOrNull(
342
- CertificateReissueUtil.getCooldownCutoff(now),
343
- ),
344
- },
345
- data: {
346
- certificateReissueRequestedAt: now,
564
+ await CertificateReissueOrder.reissue({
565
+ domain: dashboardDomain.fullDomain,
566
+ now: now,
567
+ lastReissueRequestedAt: dashboardDomain.certificateReissueRequestedAt,
568
+ claimCooldown: async (): Promise<number> => {
569
+ /*
570
+ * Claim the cooldown before ordering anything, and claim it by
571
+ * putting the cooldown condition in the WHERE clause rather than in
572
+ * an `if` above the write. Two clicks that arrive together both read
573
+ * a row that is not cooling down; only the write can decide which
574
+ * one of them gets to spend the CA's allowance.
575
+ */
576
+ return await this.updateOneBy({
577
+ query: {
578
+ _id: domainId.toString(),
579
+ certificateReissueRequestedAt: QueryHelper.lessThanEqualToOrNull(
580
+ CertificateReissueUtil.getCooldownCutoff(now),
581
+ ),
582
+ },
583
+ data: {
584
+ certificateReissueRequestedAt: now,
585
+ },
586
+ props: {
587
+ isRoot: true,
588
+ },
589
+ });
347
590
  },
348
- props: {
349
- isRoot: true,
591
+ giveCooldownBack: async (): Promise<void> => {
592
+ await this.updateOneBy({
593
+ query: {
594
+ _id: domainId.toString(),
595
+ certificateReissueRequestedAt: now,
596
+ },
597
+ data: {
598
+ certificateReissueRequestedAt:
599
+ dashboardDomain.certificateReissueRequestedAt || null,
600
+ } as never,
601
+ props: {
602
+ isRoot: true,
603
+ },
604
+ });
350
605
  },
351
- });
352
-
353
- if (claimedRowCount === 0) {
354
- if (dashboardDomain.certificateReissueRequestedAt) {
355
- throw new TooManyRequestsException(
356
- CertificateReissueUtil.getCooldownMessage(
357
- dashboardDomain.certificateReissueRequestedAt,
358
- now,
359
- ),
606
+ order: async (
607
+ lock: CertificateOrderLockHandle,
608
+ ): Promise<CertificateOrderOutcome> => {
609
+ logger.debug(
610
+ "Reissuing SSL certificate for domain: " + dashboardDomain.fullDomain,
611
+ { fullDomain: dashboardDomain.fullDomain } as LogAttributes,
360
612
  );
361
- }
362
-
363
- /*
364
- * The row matched the cooldown a moment ago and does not now: another
365
- * request claimed it in between, or the domain was deleted. Either way
366
- * the caller must not order.
367
- */
368
- throw new BadDataException(
369
- "Could not start a certificate reissue for this domain. Please refresh the page and try again.",
370
- );
371
- }
372
-
373
- logger.debug(
374
- "Reissuing SSL certificate for domain: " + dashboardDomain.fullDomain,
375
- { fullDomain: dashboardDomain.fullDomain } as LogAttributes,
376
- );
377
613
 
378
- await this.orderCert(dashboardDomain);
614
+ return await this.orderCert(dashboardDomain, {
615
+ reason: CertificateOrderReason.Reissue,
616
+ lock: lock,
617
+ });
618
+ },
619
+ });
379
620
  }
380
621
 
381
622
  @CaptureSpan()
@@ -387,6 +628,7 @@ export class Service extends DatabaseService<DashboardDomain> {
387
628
  },
388
629
  select: {
389
630
  _id: true,
631
+ fullDomain: true,
390
632
  },
391
633
  limit: LIMIT_MAX,
392
634
  skip: 0,
@@ -395,9 +637,20 @@ export class Service extends DatabaseService<DashboardDomain> {
395
637
  },
396
638
  });
397
639
 
398
- for (const domain of domains) {
399
- await this.updateSslProvisioningStatus(domain);
400
- }
640
+ await ArrayUtil.forEachWithConcurrency(
641
+ domains,
642
+ Service.DOMAIN_CHECK_CONCURRENCY,
643
+ async (domain: DashboardDomain): Promise<void> => {
644
+ try {
645
+ await this.updateSslProvisioningStatus(domain);
646
+ } catch (err) {
647
+ // one unreachable domain must not end the sweep for the rest.
648
+ logger.error(err, {
649
+ fullDomain: domain.fullDomain,
650
+ } as LogAttributes);
651
+ }
652
+ },
653
+ );
401
654
  }
402
655
 
403
656
  private async isSSLProvisioned(
@@ -461,7 +714,32 @@ export class Service extends DatabaseService<DashboardDomain> {
461
714
  }
462
715
 
463
716
  @CaptureSpan()
464
- public async isCnameValid(fullDomain: string): Promise<boolean> {
717
+ public async isCnameValid(
718
+ fullDomain: string,
719
+ options?: {
720
+ /*
721
+ * Whether the answer is written to the domain row: verified, or
722
+ * unverified, unordered and unprovisioned. The renewal run passes
723
+ * false - a DNS blip while it renews must not reset a domain whose
724
+ * certificate it keeps; the provisioning sweep still notices a
725
+ * record that is really gone.
726
+ */
727
+ recordResult?: boolean | undefined;
728
+ },
729
+ ): Promise<boolean> {
730
+ const recordResult: (cnameStatus: boolean) => Promise<void> = async (
731
+ cnameStatus: boolean,
732
+ ): Promise<void> => {
733
+ if (options?.recordResult === false) {
734
+ return;
735
+ }
736
+
737
+ await this.updateCnameStatusForDashboardDomain({
738
+ domain: fullDomain,
739
+ cnameStatus: cnameStatus,
740
+ });
741
+ };
742
+
465
743
  try {
466
744
  logger.debug("Checking for CNAME " + fullDomain, {
467
745
  fullDomain,
@@ -508,10 +786,7 @@ export class Service extends DatabaseService<DashboardDomain> {
508
786
  logger.debug(result, { fullDomain } as LogAttributes);
509
787
 
510
788
  if (result.isSuccess()) {
511
- await this.updateCnameStatusForDashboardDomain({
512
- domain: fullDomain,
513
- cnameStatus: true,
514
- });
789
+ await recordResult(true);
515
790
 
516
791
  return true;
517
792
  }
@@ -539,10 +814,7 @@ export class Service extends DatabaseService<DashboardDomain> {
539
814
  logger.debug(resultHttps, { fullDomain } as LogAttributes);
540
815
 
541
816
  if (resultHttps.isSuccess()) {
542
- await this.updateCnameStatusForDashboardDomain({
543
- domain: fullDomain,
544
- cnameStatus: true,
545
- });
817
+ await recordResult(true);
546
818
 
547
819
  return true;
548
820
  }
@@ -569,10 +841,7 @@ export class Service extends DatabaseService<DashboardDomain> {
569
841
  `No CNAME record found for ${fullDomain}. Expected record: ${DashboardCNameRecord}`,
570
842
  { fullDomain } as LogAttributes,
571
843
  );
572
- await this.updateCnameStatusForDashboardDomain({
573
- domain: fullDomain,
574
- cnameStatus: false,
575
- });
844
+ await recordResult(false);
576
845
  return false;
577
846
  }
578
847
 
@@ -586,10 +855,7 @@ export class Service extends DatabaseService<DashboardDomain> {
586
855
  { fullDomain } as LogAttributes,
587
856
  );
588
857
 
589
- await this.updateCnameStatusForDashboardDomain({
590
- domain: fullDomain,
591
- cnameStatus: true,
592
- });
858
+ await recordResult(true);
593
859
 
594
860
  return true;
595
861
  }
@@ -606,25 +872,33 @@ export class Service extends DatabaseService<DashboardDomain> {
606
872
  logger.debug(err, { fullDomain } as LogAttributes);
607
873
  }
608
874
 
609
- await this.updateCnameStatusForDashboardDomain({
610
- domain: fullDomain,
611
- cnameStatus: false,
612
- });
875
+ await recordResult(false);
613
876
 
614
877
  return false;
615
878
  } catch (err) {
616
879
  logger.debug("Failed checking for CNAME " + fullDomain);
617
880
  logger.debug(err);
618
881
 
619
- await this.updateCnameStatusForDashboardDomain({
620
- domain: fullDomain,
621
- cnameStatus: false,
622
- });
882
+ await recordResult(false);
623
883
 
624
884
  return false;
625
885
  }
626
886
  }
627
887
 
888
+ /*
889
+ * Record whether this domain's certificate is being served yet.
890
+ *
891
+ * Unlike the status page sweep this never orders a certificate. A probe
892
+ * that fails right after an order is usually racing nginx, which writes
893
+ * new certificates to disk every 15 minutes, and re-ordering then spends a
894
+ * second order on the same name. The two cases that do need an order have
895
+ * capped sweeps of their own: checkOrderStatus re-orders a certificate that
896
+ * has gone missing, and the renewal run renews one that is about to expire.
897
+ *
898
+ * When the probe fails the CNAME is checked again, so a domain whose record
899
+ * was removed goes back to asking for it. The result is written only when
900
+ * it changes: this sweep visits every ordered domain every 15 minutes.
901
+ */
628
902
  @CaptureSpan()
629
903
  public async updateSslProvisioningStatus(
630
904
  domain: DashboardDomain,
@@ -641,6 +915,7 @@ export class Service extends DatabaseService<DashboardDomain> {
641
915
  _id: true,
642
916
  fullDomain: true,
643
917
  cnameVerificationToken: true,
918
+ isSslProvisioned: true,
644
919
  },
645
920
  props: {
646
921
  isRoot: true,
@@ -652,56 +927,88 @@ export class Service extends DatabaseService<DashboardDomain> {
652
927
  }
653
928
 
654
929
  logger.debug(
655
- `DashboardCerts:RemoveCerts - Checking CNAME ${dashboardDomain.fullDomain}`,
930
+ `DashboardCerts:CheckSslProvisioningStatus - Checking ${dashboardDomain.fullDomain}`,
656
931
  { fullDomain: dashboardDomain.fullDomain } as LogAttributes,
657
932
  );
658
933
 
659
- const isValid: boolean = await this.isSSLProvisioned(
934
+ const isProvisioned: boolean = await this.isSSLProvisioned(
660
935
  dashboardDomain.fullDomain!,
661
936
  dashboardDomain.cnameVerificationToken!,
662
937
  );
663
938
 
664
- if (!isValid) {
665
- const isCnameValid: boolean = await this.isCnameValid(
666
- dashboardDomain.fullDomain!,
667
- );
939
+ if (!isProvisioned) {
940
+ // isCnameValid also records the result on the domain.
941
+ await this.isCnameValid(dashboardDomain.fullDomain!);
942
+ }
668
943
 
944
+ if (Boolean(dashboardDomain.isSslProvisioned) !== isProvisioned) {
669
945
  await this.updateOneById({
670
946
  id: dashboardDomain.id!,
671
947
  data: {
672
- isSslProvisioned: false,
948
+ isSslProvisioned: isProvisioned,
673
949
  },
674
950
  props: {
675
951
  isRoot: true,
676
952
  },
677
953
  });
954
+ }
955
+ }
678
956
 
679
- if (isCnameValid) {
680
- try {
681
- await this.orderCert(dashboardDomain);
682
- } catch (err) {
683
- logger.error(
684
- "Cannot order cert for domain: " + dashboardDomain.fullDomain,
685
- { fullDomain: dashboardDomain.fullDomain } as LogAttributes,
686
- );
687
- logger.error(err, {
688
- fullDomain: dashboardDomain.fullDomain,
689
- } as LogAttributes);
690
- }
691
- }
692
- } else {
693
- await this.updateOneById({
694
- id: dashboardDomain.id!,
695
- data: {
696
- isSslProvisioned: true,
957
+ /*
958
+ * Order the first certificate of each of these domains, whose CNAME is
959
+ * verified: at most ORDER_MAX_PER_RUN orders in a window between the
960
+ * sweeps that order, picked afresh every run; a domain that has a
961
+ * certificate already is only recorded as ordered, and one whose orders
962
+ * keep failing waits longer after each failure
963
+ * (CustomDomainOrders.orderForVerifiedDomainsWithoutOne, which the status
964
+ * page sweeps share).
965
+ */
966
+ private async orderCertsForVerifiedDomainsWithoutOne(
967
+ domains: Array<DashboardDomain>,
968
+ options?: {
969
+ // Every one of them was verified a moment ago, by this caller.
970
+ cnameVerifiedJustNow?: boolean | undefined;
971
+ },
972
+ ): Promise<void> {
973
+ await CustomDomainOrders.orderForVerifiedDomainsWithoutOne<DashboardDomain>(
974
+ {
975
+ domains: domains,
976
+ maxPerRun: Service.ORDER_MAX_PER_RUN,
977
+ recordAsOrdered: async (domainIds: Array<ObjectID>): Promise<void> => {
978
+ await this.recordCertificatesAsOrdered(domainIds);
697
979
  },
698
- props: {
699
- isRoot: true,
980
+ orderIfMissing: async (
981
+ domain: DashboardDomain,
982
+ ): Promise<CertificateOrderOutcome> => {
983
+ return await this.orderCertIfMissing(domain, {
984
+ fromSweep: true,
985
+ cnameVerifiedJustNow: options?.cnameVerifiedJustNow,
986
+ });
700
987
  },
701
- });
702
- }
988
+ },
989
+ );
703
990
  }
704
991
 
992
+ /*
993
+ * Order the first certificate for domains whose CNAME is verified.
994
+ *
995
+ * Only verified domains: verifyCnameWhoseCnameisNotVerified checks the
996
+ * rest - and orders each one's certificate the moment it is verified, so
997
+ * this sweep is the fallback for the rest - and ordering one whose record
998
+ * is not in place would only fail the CNAME check again.
999
+ *
1000
+ * A domain that already has a certificate is only recorded as ordered -
1001
+ * all of them in one write. That is the domain whose CNAME check failed
1002
+ * for a moment - which marks it unordered - and then passed again.
1003
+ * Ordering for it would spend an order on a duplicate (Let's Encrypt
1004
+ * allows five a week per name), and if its certificate is due, the renewal
1005
+ * run orders it in this same tick. The rest are ordered through
1006
+ * orderCertIfMissing, at most ORDER_MAX_PER_RUN in a window between the
1007
+ * sweeps that order, picked afresh every run
1008
+ * (GreenlockUtil.pickForThisRun), so a domain whose order keeps failing
1009
+ * cannot hold a slot the others are waiting for; it also waits longer
1010
+ * after each failure in a row (CertificateOrderFailures).
1011
+ */
705
1012
  @CaptureSpan()
706
1013
  public async orderSSLForDomainsWhichAreNotOrderedYet(): Promise<void> {
707
1014
  return Telemetry.startActiveSpan<Promise<void>>({
@@ -709,34 +1016,25 @@ export class Service extends DatabaseService<DashboardDomain> {
709
1016
  options: { attributes: {} },
710
1017
  fn: async (span: Span): Promise<void> => {
711
1018
  try {
712
- const domains: Array<DashboardDomain> = await this.findBy({
1019
+ const domains: Array<DashboardDomain> = await this.findAllBy({
713
1020
  query: {
1021
+ isCnameVerified: true,
714
1022
  isSslOrdered: false,
715
1023
  isCustomCertificate: false,
716
1024
  },
717
1025
  select: {
718
1026
  _id: true,
719
1027
  fullDomain: true,
1028
+ isSslOrdered: true,
1029
+ isCustomCertificate: true,
720
1030
  },
721
- limit: LIMIT_MAX,
722
1031
  skip: 0,
723
1032
  props: {
724
1033
  isRoot: true,
725
1034
  },
726
1035
  });
727
1036
 
728
- for (const domain of domains) {
729
- try {
730
- logger.debug("Ordering SSL for domain: " + domain.fullDomain, {
731
- fullDomain: domain.fullDomain,
732
- } as LogAttributes);
733
- await this.orderCert(domain);
734
- } catch (e) {
735
- logger.error(e, {
736
- fullDomain: domain.fullDomain,
737
- } as LogAttributes);
738
- }
739
- }
1037
+ await this.orderCertsForVerifiedDomainsWithoutOne(domains);
740
1038
 
741
1039
  Telemetry.endSpan(span);
742
1040
  } catch (err) {
@@ -751,6 +1049,15 @@ export class Service extends DatabaseService<DashboardDomain> {
751
1049
  });
752
1050
  }
753
1051
 
1052
+ /*
1053
+ * Check every domain whose CNAME is not verified yet, at most
1054
+ * DOMAIN_CHECK_CONCURRENCY at a time, and order the certificate of each
1055
+ * one that is verified now straight away rather than at the next run of
1056
+ * the order sweep - as the status page sweep does. So a domain is served
1057
+ * on its own certificate within about 15 minutes of its record going live
1058
+ * - nginx writes new certificates every 15 minutes - whether or not
1059
+ * anyone clicked Check now.
1060
+ */
754
1061
  @CaptureSpan()
755
1062
  public async verifyCnameWhoseCnameisNotVerified(): Promise<void> {
756
1063
  const domains: Array<DashboardDomain> = await this.findBy({
@@ -760,6 +1067,8 @@ export class Service extends DatabaseService<DashboardDomain> {
760
1067
  select: {
761
1068
  _id: true,
762
1069
  fullDomain: true,
1070
+ isCustomCertificate: true,
1071
+ isSslOrdered: true,
763
1072
  },
764
1073
  limit: LIMIT_MAX,
765
1074
  skip: 0,
@@ -768,20 +1077,97 @@ export class Service extends DatabaseService<DashboardDomain> {
768
1077
  },
769
1078
  });
770
1079
 
771
- for (const domain of domains) {
772
- try {
773
- await this.isCnameValid(domain.fullDomain as string);
774
- } catch (e) {
775
- logger.error(e, { fullDomain: domain.fullDomain } as LogAttributes);
776
- }
1080
+ const verifiedNow: Array<DashboardDomain> = [];
1081
+
1082
+ await ArrayUtil.forEachWithConcurrency(
1083
+ domains,
1084
+ Service.DOMAIN_CHECK_CONCURRENCY,
1085
+ async (domain: DashboardDomain): Promise<void> => {
1086
+ try {
1087
+ // isCnameValid also records the result on the domain.
1088
+ const isVerified: boolean = await this.isCnameValid(
1089
+ domain.fullDomain as string,
1090
+ );
1091
+
1092
+ if (isVerified && !domain.isCustomCertificate) {
1093
+ verifiedNow.push(domain);
1094
+ }
1095
+ } catch (e) {
1096
+ logger.error(e, { fullDomain: domain.fullDomain } as LogAttributes);
1097
+ }
1098
+ },
1099
+ );
1100
+
1101
+ try {
1102
+ /*
1103
+ * Each was verified by this run a moment ago, so the orders do not
1104
+ * check the CNAME again.
1105
+ */
1106
+ await this.orderCertsForVerifiedDomainsWithoutOne(verifiedNow, {
1107
+ cnameVerifiedJustNow: true,
1108
+ });
1109
+ } catch (e) {
1110
+ // The order sweep orders them on its next run.
1111
+ logger.error(e);
1112
+ }
1113
+ }
1114
+
1115
+ /*
1116
+ * Which of these certificate domains are dashboard domains. The renewal
1117
+ * run renews - and removes - only the certificates this returns, so the
1118
+ * certificates of status page domains and of the primary host, which share
1119
+ * the AcmeCertificate table, are never mistaken for dashboard domains
1120
+ * whose CNAME stopped validating.
1121
+ *
1122
+ * A domain serving a certificate its owner uploaded still claims its
1123
+ * Let's Encrypt certificate, which stays renewed meanwhile: nginx serves
1124
+ * the uploaded one for that name (AcmeWriteCertificates leaves it alone),
1125
+ * and switching back is then instant, on every nginx replica, including
1126
+ * ones that start with an empty certificate directory.
1127
+ */
1128
+ @CaptureSpan()
1129
+ public async getOwnedDomains(domains: Array<string>): Promise<Array<string>> {
1130
+ if (domains.length === 0) {
1131
+ return [];
777
1132
  }
1133
+
1134
+ const dashboardDomains: Array<DashboardDomain> = await this.findBy({
1135
+ query: {
1136
+ fullDomain: QueryHelper.any(domains),
1137
+ },
1138
+ select: {
1139
+ fullDomain: true,
1140
+ },
1141
+ limit: LIMIT_MAX,
1142
+ skip: 0,
1143
+ props: {
1144
+ isRoot: true,
1145
+ },
1146
+ });
1147
+
1148
+ return dashboardDomains
1149
+ .map((dashboardDomain: DashboardDomain) => {
1150
+ return dashboardDomain.fullDomain || "";
1151
+ })
1152
+ .filter((fullDomain: string) => {
1153
+ return fullDomain.length > 0;
1154
+ });
778
1155
  }
779
1156
 
780
1157
  @CaptureSpan()
781
1158
  public async renewCertsWhichAreExpiringSoon(): Promise<void> {
782
1159
  await GreenlockUtil.renewAllCertsWhichAreExpiringSoon({
1160
+ maxPerRun: Service.ORDER_MAX_PER_RUN,
1161
+ getOwnedDomains: async (domains: Array<string>) => {
1162
+ return await this.getOwnedDomains(domains);
1163
+ },
1164
+ /*
1165
+ * A check that writes nothing: a DNS blip while a certificate is
1166
+ * renewed must not mark the domain unverified and unordered while its
1167
+ * certificate keeps serving.
1168
+ */
783
1169
  validateCname: async (fullDomain: string) => {
784
- return await this.isCnameValid(fullDomain);
1170
+ return await this.isCnameValid(fullDomain, { recordResult: false });
785
1171
  },
786
1172
  notifyDomainRemoved: async (domain: string) => {
787
1173
  await this.updateOneBy({
@@ -804,9 +1190,22 @@ export class Service extends DatabaseService<DashboardDomain> {
804
1190
  });
805
1191
  }
806
1192
 
1193
+ /*
1194
+ * Re-order the certificate of a domain that says it has one ordered but
1195
+ * whose certificate is gone, at most ORDER_MAX_PER_RUN per run.
1196
+ *
1197
+ * This is how dashboard domains recover from the status page renewal job,
1198
+ * which until it learned to check ownership deleted every dashboard
1199
+ * certificate that came due for renewal while the domain kept saying
1200
+ * "ordered" - nginx then served the stale copy on disk until it expired.
1201
+ * Domains are picked afresh every run, for the same reason as in the
1202
+ * first-order sweep above, and re-ordered through orderCertIfMissing, so a
1203
+ * re-order never races another order for the same name and shares the
1204
+ * sweeps' budget.
1205
+ */
807
1206
  @CaptureSpan()
808
1207
  public async checkOrderStatus(): Promise<void> {
809
- const domains: Array<DashboardDomain> = await this.findBy({
1208
+ const domains: Array<DashboardDomain> = await this.findAllBy({
810
1209
  query: {
811
1210
  isSslOrdered: true,
812
1211
  isCustomCertificate: false,
@@ -814,42 +1213,69 @@ export class Service extends DatabaseService<DashboardDomain> {
814
1213
  select: {
815
1214
  _id: true,
816
1215
  fullDomain: true,
817
- cnameVerificationToken: true,
1216
+ isCustomCertificate: true,
818
1217
  },
819
- limit: LIMIT_MAX,
820
1218
  skip: 0,
821
1219
  props: {
822
1220
  isRoot: true,
823
1221
  },
824
1222
  });
825
1223
 
826
- for (const domain of domains) {
827
- if (!domain.fullDomain) {
828
- continue;
829
- }
1224
+ const fullDomains: Array<string> = domains
1225
+ .map((domain: DashboardDomain) => {
1226
+ return domain.fullDomain || "";
1227
+ })
1228
+ .filter((fullDomain: string) => {
1229
+ return fullDomain.length > 0;
1230
+ });
830
1231
 
831
- const acmeCert: AcmeCertificate | null =
832
- await AcmeCertificateService.findOneBy({
833
- query: {
834
- domain: domain.fullDomain,
835
- },
836
- select: {
837
- _id: true,
838
- },
839
- props: {
840
- isRoot: true,
841
- },
842
- });
1232
+ if (fullDomains.length === 0) {
1233
+ return;
1234
+ }
843
1235
 
844
- if (!acmeCert) {
845
- try {
846
- await this.orderCert(domain);
847
- } catch (err) {
848
- logger.error("Cannot order cert for domain: " + domain.fullDomain, {
849
- fullDomain: domain.fullDomain,
850
- } as LogAttributes);
851
- logger.error(err, { fullDomain: domain.fullDomain } as LogAttributes);
852
- }
1236
+ const certificates: Map<string, AcmeCertificate> =
1237
+ await GreenlockUtil.findCertificatesByDomain(
1238
+ fullDomains.map((fullDomain: string) => {
1239
+ return CertificateOrder.normalizeDomain(fullDomain);
1240
+ }),
1241
+ );
1242
+
1243
+ const now: Date = OneUptimeDate.getCurrentDate();
1244
+
1245
+ const domainsWithoutCertificate: Array<DashboardDomain> =
1246
+ await CertificateOrderFailures.withoutThoseWaitingToRetry({
1247
+ items: domains.filter((domain: DashboardDomain) => {
1248
+ return (
1249
+ Boolean(domain.id) &&
1250
+ Boolean(domain.fullDomain) &&
1251
+ !certificates.has(
1252
+ CertificateOrder.normalizeDomain(domain.fullDomain as string),
1253
+ )
1254
+ );
1255
+ }),
1256
+ getDomain: (domain: DashboardDomain): string => {
1257
+ return domain.fullDomain as string;
1258
+ },
1259
+ now: now,
1260
+ });
1261
+
1262
+ const batch: Array<DashboardDomain> = GreenlockUtil.pickForThisRun({
1263
+ items: domainsWithoutCertificate,
1264
+ max: Service.ORDER_MAX_PER_RUN,
1265
+ now: now,
1266
+ getKey: (domain: DashboardDomain): string => {
1267
+ return domain.fullDomain || "";
1268
+ },
1269
+ });
1270
+
1271
+ for (const domain of batch) {
1272
+ try {
1273
+ await this.orderCertIfMissing(domain, { fromSweep: true });
1274
+ } catch (err) {
1275
+ logger.error("Cannot order cert for domain: " + domain.fullDomain, {
1276
+ fullDomain: domain.fullDomain,
1277
+ } as LogAttributes);
1278
+ logger.error(err, { fullDomain: domain.fullDomain } as LogAttributes);
853
1279
  }
854
1280
  }
855
1281
  }