@oneuptime/common 14.0.6 → 14.0.8

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 (556) hide show
  1. package/Models/DatabaseModels/Incident.ts +267 -1
  2. package/Models/DatabaseModels/IncidentCustomField.ts +202 -0
  3. package/Models/DatabaseModels/IncidentEpisode.ts +30 -0
  4. package/Models/DatabaseModels/IncidentTemplate.ts +126 -1
  5. package/Models/DatabaseModels/InventoryItem.ts +23 -12
  6. package/Models/DatabaseModels/StatusPage.ts +55 -0
  7. package/Models/DatabaseModels/StatusPageSubscriber.ts +128 -0
  8. package/Server/API/IncidentAPI.ts +162 -0
  9. package/Server/API/StatusPageAPI.ts +487 -171
  10. package/Server/API/StatusPageSubscriberAPI.ts +63 -15
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.ts +217 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.ts +49 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.ts +108 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.ts +33 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.ts +51 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.ts +33 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.ts +168 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.ts +44 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
  20. package/Server/Infrastructure/Semaphore.ts +10 -0
  21. package/Server/Middleware/IdentityRateLimit.ts +108 -3
  22. package/Server/Middleware/SubscriberNotificationPreviewRateLimit.ts +237 -0
  23. package/Server/Middleware/SubscriberNotificationTestSendRateLimit.ts +304 -0
  24. package/Server/Services/AlertService.ts +32 -36
  25. package/Server/Services/DatabaseService.ts +93 -10
  26. package/Server/Services/IncidentAlertService.ts +609 -2
  27. package/Server/Services/IncidentCustomFieldService.ts +276 -1
  28. package/Server/Services/IncidentEpisodePublicNoteService.ts +28 -0
  29. package/Server/Services/IncidentEpisodeService.ts +15 -0
  30. package/Server/Services/IncidentEpisodeStateTimelineService.ts +27 -1
  31. package/Server/Services/IncidentPublicNoteService.ts +30 -1
  32. package/Server/Services/IncidentService.ts +1663 -103
  33. package/Server/Services/IncidentStateTimelineService.ts +13 -0
  34. package/Server/Services/IncidentTemplateService.ts +109 -0
  35. package/Server/Services/InventoryItemService.ts +38 -0
  36. package/Server/Services/IoTDeviceCredentialService.ts +13 -4
  37. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +30 -1
  38. package/Server/Services/ScheduledMaintenanceService.ts +118 -64
  39. package/Server/Services/SmsService.ts +10 -0
  40. package/Server/Services/StatusPageService.ts +65 -8
  41. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +299 -37
  42. package/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.ts +129 -0
  43. package/Server/Services/StatusPageSubscriberService.ts +1161 -64
  44. package/Server/Services/UserNotificationRuleService.ts +55 -53
  45. package/Server/Services/WorkspaceNotificationSummaryService.ts +38 -20
  46. package/Server/Types/Markdown.ts +153 -6
  47. package/Server/Types/Workflow/Components/Email.ts +61 -2
  48. package/Server/Utils/AffectedResources/LinkedAffectedResources.ts +576 -0
  49. package/Server/Utils/Alert/AlertStateChangeAuthorization.ts +129 -0
  50. package/Server/Utils/CustomField/CustomFieldRename.ts +378 -0
  51. package/Server/Utils/DataSource/EgressGuard.ts +66 -21
  52. package/Server/Utils/Inventory/InventoryOverviewAggregation.ts +111 -0
  53. package/Server/Utils/Mail/PinnedSmtpSocket.ts +130 -0
  54. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +10 -0
  55. package/Server/Utils/Response.ts +31 -0
  56. package/Server/Utils/SSRFProtection.ts +76 -16
  57. package/Server/Utils/StatusPage/IncidentStatusPageScope.ts +948 -0
  58. package/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.ts +656 -0
  59. package/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.ts +805 -0
  60. package/Server/Utils/StatusPage/StatusPageExclusion.ts +18 -0
  61. package/Server/Utils/StatusPage/StatusPageReadAccess.ts +125 -0
  62. package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.ts +151 -0
  63. package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.ts +70 -0
  64. package/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.ts +421 -0
  65. package/Server/Utils/StatusPage/SubscriberNotificationClaim.ts +107 -0
  66. package/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.ts +1049 -0
  67. package/Server/Utils/StatusPage/SubscriberNotificationFanOut.ts +180 -0
  68. package/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.ts +839 -0
  69. package/Server/Utils/StatusPage/SubscriberNotificationResendAccess.ts +393 -0
  70. package/Server/Utils/StatusPage/SubscriberNotificationRunLimit.ts +246 -0
  71. package/Server/Utils/StatusPage/SubscriberNotificationTiming.ts +133 -0
  72. package/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.ts +215 -0
  73. package/Server/Utils/StatusPageResource.ts +51 -20
  74. package/Server/Utils/Topology/TopologyConcurrencyLimiter.ts +229 -0
  75. package/Server/Utils/Topology/TopologyQueries.ts +1350 -0
  76. package/Server/Utils/Topology/TopologyRequest.ts +463 -0
  77. package/Server/Utils/Topology/TopologyResponseCache.ts +183 -0
  78. package/Server/Utils/Topology/TopologySql.ts +1024 -0
  79. package/Server/Utils/VM/VMAPI.ts +1 -0
  80. package/Server/Utils/VM/VMRunner.ts +10 -0
  81. package/Server/Utils/Workflow/OAuth2TokenClient.ts +10 -0
  82. package/Server/Views/Partials/SensitiveUrlToken.ejs +8 -5
  83. package/Tests/App/Accounts/RegisterVerifyEmail.test.tsx +748 -0
  84. package/Tests/App/Accounts/ResendVerificationEmail.test.tsx +1222 -0
  85. package/Tests/App/Accounts/VerificationEmailResendUtils.test.ts +797 -0
  86. package/Tests/App/Accounts/VerifyEmailPending.test.tsx +538 -0
  87. package/Tests/App/Accounts/VerifyEmailResend.test.tsx +779 -0
  88. package/Tests/App/Dashboard/AcknowledgeAlertsOnDeclare.test.ts +369 -0
  89. package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +1 -1
  90. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +510 -123
  91. package/Tests/App/Dashboard/AlertsTableAffectedResources.test.tsx +490 -0
  92. package/Tests/App/Dashboard/ChangeAlertStateDeclareIncident.test.tsx +886 -0
  93. package/Tests/App/Dashboard/CreateReviewStepRoleSummary.test.tsx +1250 -0
  94. package/Tests/App/Dashboard/CreateReviewStepSelectionSummary.test.tsx +738 -0
  95. package/Tests/App/Dashboard/CustomFieldsSettingsIncidentOptions.test.tsx +357 -0
  96. package/Tests/App/Dashboard/DeclareIncidentFromAlert.test.ts +417 -0
  97. package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +1948 -229
  98. package/Tests/App/Dashboard/EntityDetailPanelLifecycle.test.tsx +493 -0
  99. package/Tests/App/Dashboard/EntityDetailPanelNavigation.test.tsx +439 -0
  100. package/Tests/App/Dashboard/EventNotes.test.tsx +776 -0
  101. package/Tests/App/Dashboard/EventNotesPages.test.tsx +119 -0
  102. package/Tests/App/Dashboard/EventNotesUtil.test.ts +116 -17
  103. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +534 -6
  104. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +798 -2
  105. package/Tests/App/Dashboard/FetchStateAndSeverityElements.test.tsx +669 -0
  106. package/Tests/App/Dashboard/FetchUsers.test.tsx +230 -0
  107. package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +91 -1
  108. package/Tests/App/Dashboard/IncidentCreateAcknowledgeAlerts.test.tsx +1611 -0
  109. package/Tests/App/Dashboard/IncidentCreateDetailsStep.test.tsx +643 -0
  110. package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +8 -1
  111. package/Tests/App/Dashboard/IncidentCreateStatusPageScope.test.tsx +601 -0
  112. package/Tests/App/Dashboard/IncidentCustomFieldTemplateVariables.test.tsx +386 -0
  113. package/Tests/App/Dashboard/IncidentNoteTemplatePlaceholders.test.tsx +124 -0
  114. package/Tests/App/Dashboard/IncidentNoteTemplateVariablesLoader.test.ts +305 -0
  115. package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +112 -0
  116. package/Tests/App/Dashboard/IncidentSettingsRenotifyOnPublish.test.tsx +674 -0
  117. package/Tests/App/Dashboard/IncidentSettingsStatusPageScope.test.tsx +1051 -0
  118. package/Tests/App/Dashboard/IncidentTemplateCustomFields.test.tsx +384 -0
  119. package/Tests/App/Dashboard/IncidentTemplateStatusPageScopeCard.test.tsx +215 -0
  120. package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +1365 -57
  121. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +964 -23
  122. package/Tests/App/Dashboard/InventoryRelationships.test.tsx +885 -0
  123. package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +113 -1
  124. package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +201 -15
  125. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +508 -36
  126. package/Tests/App/Dashboard/SubscriberAudienceSummary.test.tsx +512 -0
  127. package/Tests/App/Dashboard/SubscriberNotificationPreviewModal.test.tsx +837 -0
  128. package/Tests/App/Dashboard/SubscriberNotificationStatusLabel.test.tsx +88 -0
  129. package/Tests/App/Dashboard/SubscriberNotificationStatusResend.test.tsx +473 -0
  130. package/Tests/App/Dashboard/SubscriberTemplateLivePreview.test.tsx +196 -0
  131. package/Tests/App/Dashboard/TeamAddedSubscribersUnsubscribedNotice.test.tsx +248 -0
  132. package/Tests/App/Dashboard/TopologyDataLifecycle.test.tsx +583 -0
  133. package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +982 -218
  134. package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +818 -114
  135. package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +64 -3
  136. package/Tests/App/StatusPage/StatusPageUnsubscribePage.test.tsx +412 -0
  137. package/Tests/Models/IncidentCustomFieldApiSchemaContract.test.ts +217 -0
  138. package/Tests/Models/IncidentCustomFieldCreateSettingsColumns.test.ts +252 -0
  139. package/Tests/Models/StatusPageSubscriberUnsubscribeColumns.test.ts +218 -0
  140. package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +7 -0
  141. package/Tests/Server/API/IncidentSubscriberAudienceAPI.test.ts +1408 -0
  142. package/Tests/Server/API/StatusPageIncidentScope.test.ts +1868 -0
  143. package/Tests/Server/API/StatusPageIncidentScopePostgres.test.ts +790 -0
  144. package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +10 -1
  145. package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +206 -18
  146. package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +14 -2
  147. package/Tests/Server/API/StatusPageSubscriberCreateResponse.test.ts +217 -0
  148. package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +103 -2
  149. package/Tests/Server/API/StatusPageUnsubscribeAPI.test.ts +396 -0
  150. package/Tests/Server/Infrastructure/Postgres/AddIncidentStatusPageScopeMigration.test.ts +395 -0
  151. package/Tests/Server/Infrastructure/Postgres/AddIncidentTemplateStatusPageScopeFlagMigration.test.ts +150 -0
  152. package/Tests/Server/Infrastructure/Postgres/AddSubscriberNotificationClaimedAtMigration.test.ts +156 -0
  153. package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +90 -21
  154. package/Tests/Server/Infrastructure/Postgres/SkipHiddenIncidentCreatedNotificationsMigration.test.ts +410 -0
  155. package/Tests/Server/Middleware/IdentityRateLimit.test.ts +551 -1
  156. package/Tests/Server/Middleware/SubscriberNotificationPreviewRateLimit.test.ts +238 -0
  157. package/Tests/Server/Middleware/SubscriberNotificationTestSendRateLimit.test.ts +245 -0
  158. package/Tests/Server/Services/AddStatusPageSubscriberUnsubscribeTokenMigration.test.ts +152 -0
  159. package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +221 -36
  160. package/Tests/Server/Services/DatabaseServiceCompareAndSetColumns.test.ts +191 -0
  161. package/Tests/Server/Services/DomainService.test.ts +525 -0
  162. package/Tests/Server/Services/IncidentAlertAcknowledgeOnDeclare.test.ts +2630 -0
  163. package/Tests/Server/Services/IncidentAlertPostgres.test.ts +1625 -1
  164. package/Tests/Server/Services/IncidentCreatedRenotifyOnPublish.test.ts +681 -0
  165. package/Tests/Server/Services/IncidentCreatedResend.test.ts +775 -0
  166. package/Tests/Server/Services/IncidentCustomFieldRenamePostgres.test.ts +713 -0
  167. package/Tests/Server/Services/IncidentCustomFieldService.test.ts +751 -0
  168. package/Tests/Server/Services/IncidentCustomFieldValueValidation.test.ts +556 -0
  169. package/Tests/Server/Services/IncidentDeclareAcknowledgeAlerts.test.ts +2189 -0
  170. package/Tests/Server/Services/IncidentStatusPageScope.test.ts +2971 -0
  171. package/Tests/Server/Services/IncidentStatusPageScopeFeed.test.ts +131 -0
  172. package/Tests/Server/Services/IncidentStatusPageScopePostgres.test.ts +625 -0
  173. package/Tests/Server/Services/IncidentTemplateCustomFieldsCopy.test.ts +311 -0
  174. package/Tests/Server/Services/IncidentTemplateStatusPageScope.test.ts +363 -0
  175. package/Tests/Server/Services/InventoryItemServiceOverviewCounts.test.ts +345 -0
  176. package/Tests/Server/Services/InventoryOverviewPostgres.test.ts +254 -0
  177. package/Tests/Server/Services/IoTDeviceCredentialService.test.ts +819 -0
  178. package/Tests/Server/Services/LinkedAffectedResourcesCreatedFeed.test.ts +420 -0
  179. package/Tests/Server/Services/PublicNoteEditFeedEventType.test.ts +213 -0
  180. package/Tests/Server/Services/PublicNoteResendAccess.test.ts +994 -0
  181. package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +289 -9
  182. package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +92 -36
  183. package/Tests/Server/Services/SmsServiceFailIfNotSent.test.ts +67 -0
  184. package/Tests/Server/Services/StatusPageReportIncidentCounts.test.ts +610 -0
  185. package/Tests/Server/Services/StatusPageSubscriberAudienceCounts.test.ts +201 -0
  186. package/Tests/Server/Services/StatusPageSubscriberAudienceCountsPostgres.test.ts +271 -0
  187. package/Tests/Server/Services/StatusPageSubscriberConfirmationTemplateEscaping.test.ts +200 -0
  188. package/Tests/Server/Services/StatusPageSubscriberNotificationLogRedaction.test.ts +54 -0
  189. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +37 -0
  190. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateIncidentRecordAccess.test.ts +772 -0
  191. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookup.test.ts +506 -0
  192. package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookupPostgres.test.ts +261 -0
  193. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +21 -5
  194. package/Tests/Server/Services/StatusPageSubscriberUnsubscribe.test.ts +1618 -0
  195. package/Tests/Server/Services/StatusPageSubscriberUnsubscribeLinkSenders.test.ts +373 -0
  196. package/Tests/Server/Services/StatusPageSubscriberUnsubscribePostgres.test.ts +388 -0
  197. package/Tests/Server/Services/SubscriberNotificationInFlightRequeue.test.ts +500 -0
  198. package/Tests/Server/Types/MarkdownEmailLinks.test.ts +320 -0
  199. package/Tests/Server/Types/Workflow/Components/Email.test.ts +491 -1
  200. package/Tests/Server/Types/Workflow/Components/EmailSmtpPinning.test.ts +398 -0
  201. package/Tests/Server/Utils/AffectedResources/LinkedAffectedResources.test.ts +858 -0
  202. package/Tests/Server/Utils/Alert/AlertStateChangeAuthorization.test.ts +1172 -0
  203. package/Tests/Server/Utils/CustomField/CustomFieldRename.test.ts +586 -0
  204. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +246 -10
  205. package/Tests/Server/Utils/DataSource/EgressGuardDeploymentConfig.test.ts +226 -0
  206. package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +131 -0
  207. package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +4 -0
  208. package/Tests/Server/Utils/EgressPolicyEnvironment.ts +45 -0
  209. package/Tests/Server/Utils/Mail/PinnedSmtpSocket.test.ts +409 -0
  210. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +23 -0
  211. package/Tests/Server/Utils/SSRFProtection.test.ts +4 -0
  212. package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +4 -0
  213. package/Tests/Server/Utils/SSRFProtectionPrivateNetwork.test.ts +4 -0
  214. package/Tests/Server/Utils/SSRFProtectionResolutionDetail.test.ts +314 -0
  215. package/Tests/Server/Utils/StatusPage/IncidentStatusPageScope.test.ts +1699 -0
  216. package/Tests/Server/Utils/StatusPage/IncidentStatusPageScopeQueriesPostgres.test.ts +508 -0
  217. package/Tests/Server/Utils/StatusPage/IncidentSubscriberAudienceCallerPermission.test.ts +246 -0
  218. package/Tests/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.test.ts +1348 -0
  219. package/Tests/Server/Utils/StatusPage/StatusPageReadAccess.test.ts +221 -0
  220. package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.test.ts +132 -0
  221. package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.test.ts +155 -0
  222. package/Tests/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.test.ts +708 -0
  223. package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaim.test.ts +255 -0
  224. package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaimPostgres.test.ts +528 -0
  225. package/Tests/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.test.ts +1238 -0
  226. package/Tests/Server/Utils/StatusPage/SubscriberNotificationFanOut.test.ts +472 -0
  227. package/Tests/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.test.ts +1168 -0
  228. package/Tests/Server/Utils/StatusPage/SubscriberNotificationRunLimit.test.ts +275 -0
  229. package/Tests/Server/Utils/StatusPage/SubscriberNotificationTiming.test.ts +131 -0
  230. package/Tests/Server/Utils/StatusPageResource.test.ts +98 -0
  231. package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigration.test.ts +386 -0
  232. package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigrationPostgres.test.ts +430 -0
  233. package/Tests/Server/Utils/Topology/TopologyActivityParityPostgres.test.ts +279 -0
  234. package/Tests/Server/Utils/Topology/TopologyConcurrencyLimiter.test.ts +534 -0
  235. package/Tests/Server/Utils/Topology/TopologyEstateGenerator.ts +624 -0
  236. package/Tests/Server/Utils/Topology/TopologyJsonResponse.test.ts +90 -0
  237. package/Tests/Server/Utils/Topology/TopologyQueries.test.ts +1634 -0
  238. package/Tests/Server/Utils/Topology/TopologyQueriesDifferentialPostgres.test.ts +683 -0
  239. package/Tests/Server/Utils/Topology/TopologyQueriesPostgres.test.ts +2624 -0
  240. package/Tests/Server/Utils/Topology/TopologyReference.ts +1018 -0
  241. package/Tests/Server/Utils/Topology/TopologyRequest.test.ts +643 -0
  242. package/Tests/Server/Utils/Topology/TopologyResponseCache.test.ts +305 -0
  243. package/Tests/Server/Utils/Topology/TopologySql.test.ts +973 -0
  244. package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +17 -0
  245. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +75 -0
  246. package/Tests/Types/CustomField/CustomFieldSavedViews.test.ts +247 -0
  247. package/Tests/Types/CustomField/CustomFieldTemplateValues.test.ts +186 -0
  248. package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +48 -0
  249. package/Tests/Types/CustomField/CustomFieldValueFormat.test.ts +215 -0
  250. package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +343 -0
  251. package/Tests/Types/CustomField/CustomFieldVariableKey.test.ts +364 -0
  252. package/Tests/Types/SafeHtml.test.ts +102 -0
  253. package/Tests/Types/StatusPage/IncidentCreatedRenotify.test.ts +419 -0
  254. package/Tests/Types/StatusPage/IncidentCreatedResend.test.ts +118 -0
  255. package/Tests/Types/StatusPage/IncidentScopeAddedPagesNotification.test.ts +558 -0
  256. package/Tests/Types/StatusPage/IncidentSubscriberAudience.test.ts +284 -0
  257. package/Tests/Types/StatusPage/StatusPageSubscriberUnsubscribe.test.ts +341 -0
  258. package/Tests/Types/StatusPage/SubscriberNotificationPreview.test.ts +196 -0
  259. package/Tests/Types/StatusPage/SubscriberNotificationResend.test.ts +201 -0
  260. package/Tests/Types/StatusPage/SubscriberNotificationTemplateCompiler.test.ts +277 -0
  261. package/Tests/Types/StatusPage/SubscriberNotificationTemplatePreview.test.ts +179 -0
  262. package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +324 -0
  263. package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +60 -13
  264. package/Tests/Types/Topology/TopologyTypeRules.test.ts +176 -0
  265. package/Tests/UI/Components/CustomFields/CustomFieldFormFields.test.ts +432 -0
  266. package/Tests/UI/Components/CustomFields/CustomFieldModelFormFields.test.tsx +685 -0
  267. package/Tests/UI/Components/CustomFields/CustomFieldsDetailOrder.test.tsx +469 -0
  268. package/Tests/UI/Components/Forms/ModelFormCustomFieldInputs.test.tsx +325 -0
  269. package/Tests/UI/Components/Forms/ModelFormDropdownOptionsRefused.test.tsx +358 -0
  270. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +22 -0
  271. package/Tests/UI/Monitor/NetworkPathView.test.tsx +289 -0
  272. package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +302 -0
  273. package/Tests/Utils/Incident/IncidentNoteTemplateVariables.test.ts +623 -0
  274. package/Tests/Utils/Markdown/MarkdownEscape.test.ts +89 -0
  275. package/Tests/Utils/ProbeNetworkFailureUtil.test.ts +992 -0
  276. package/Tests/Utils/RequestFailedDetails.test.ts +575 -0
  277. package/Types/CustomField/CustomFieldOrder.ts +55 -0
  278. package/Types/CustomField/CustomFieldSavedViews.ts +225 -0
  279. package/Types/CustomField/CustomFieldTemplateMerge.ts +71 -0
  280. package/Types/CustomField/CustomFieldType.ts +14 -0
  281. package/Types/CustomField/CustomFieldValueFormat.ts +161 -0
  282. package/Types/CustomField/CustomFieldValueValidator.ts +488 -0
  283. package/Types/CustomField/CustomFieldVariableKey.ts +211 -0
  284. package/Types/Incident/IncidentAlertLink.ts +19 -0
  285. package/Types/SafeHtml.ts +93 -0
  286. package/Types/StatusPage/IncidentCreatedRenotify.ts +224 -0
  287. package/Types/StatusPage/IncidentCreatedResend.ts +108 -0
  288. package/Types/StatusPage/IncidentScopeAddedPagesNotification.ts +343 -0
  289. package/Types/StatusPage/IncidentSubscriberAudience.ts +332 -0
  290. package/Types/StatusPage/StatusPageSubscriberUnsubscribe.ts +405 -0
  291. package/Types/StatusPage/SubscriberNotificationInterruption.ts +32 -0
  292. package/Types/StatusPage/SubscriberNotificationPreview.ts +322 -0
  293. package/Types/StatusPage/SubscriberNotificationResend.ts +132 -0
  294. package/Types/StatusPage/SubscriberNotificationTemplateCompiler.ts +180 -0
  295. package/Types/StatusPage/SubscriberNotificationTemplatePreview.ts +301 -0
  296. package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +217 -4
  297. package/Types/StatusPage/SubscriberUpdateNotification.ts +32 -11
  298. package/Types/Telemetry/InventoryLiveness.ts +26 -0
  299. package/Types/Topology/TopologyApi.ts +428 -0
  300. package/Types/Topology/TopologyTypeRules.ts +191 -0
  301. package/UI/Components/CustomFields/CustomFieldFormFields.ts +317 -0
  302. package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +395 -0
  303. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +95 -55
  304. package/UI/Components/Forms/ModelForm.tsx +70 -8
  305. package/UI/Components/Forms/Validation.ts +1 -1
  306. package/UI/Components/ModelFormModal/ModelFormModal.tsx +2 -4
  307. package/UI/Components/ModelTable/AnalyticsModelTable.tsx +2 -6
  308. package/UI/Components/ModelTable/BaseModelTable.tsx +9 -8
  309. package/UI/Components/ModelTable/CustomFieldColumns.tsx +14 -1
  310. package/UI/Components/ModelTable/ModelTable.tsx +6 -7
  311. package/UI/Utils/SensitiveUrlToken.ts +10 -5
  312. package/Utils/API.ts +247 -2
  313. package/Utils/Incident/IncidentFromAlerts.ts +78 -0
  314. package/Utils/Incident/IncidentNoteTemplateVariables.ts +304 -0
  315. package/Utils/Markdown/MarkdownEscape.ts +65 -0
  316. package/Utils/ProbeNetworkFailureUtil.ts +673 -0
  317. package/build/dist/Models/DatabaseModels/Incident.js +267 -1
  318. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  319. package/build/dist/Models/DatabaseModels/IncidentCustomField.js +207 -1
  320. package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
  321. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +31 -0
  322. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  323. package/build/dist/Models/DatabaseModels/IncidentTemplate.js +124 -1
  324. package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
  325. package/build/dist/Models/DatabaseModels/InventoryItem.js +20 -11
  326. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
  327. package/build/dist/Models/DatabaseModels/StatusPage.js +56 -0
  328. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  329. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +131 -0
  330. package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
  331. package/build/dist/Server/API/IncidentAPI.js +100 -1
  332. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  333. package/build/dist/Server/API/StatusPageAPI.js +417 -176
  334. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  335. package/build/dist/Server/API/StatusPageSubscriberAPI.js +52 -13
  336. package/build/dist/Server/API/StatusPageSubscriberAPI.js.map +1 -1
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js +165 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js +41 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js.map +1 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js +57 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js.map +1 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js +23 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js.map +1 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js +40 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js.map +1 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js +26 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js.map +1 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js +89 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js.map +1 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js +29 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js.map +1 -0
  353. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
  354. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  355. package/build/dist/Server/Infrastructure/Semaphore.js +3 -0
  356. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  357. package/build/dist/Server/Middleware/IdentityRateLimit.js +89 -3
  358. package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
  359. package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js +149 -0
  360. package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js.map +1 -0
  361. package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js +190 -0
  362. package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js.map +1 -0
  363. package/build/dist/Server/Services/AlertService.js +21 -33
  364. package/build/dist/Server/Services/AlertService.js.map +1 -1
  365. package/build/dist/Server/Services/DatabaseService.js +56 -7
  366. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  367. package/build/dist/Server/Services/IncidentAlertService.js +457 -3
  368. package/build/dist/Server/Services/IncidentAlertService.js.map +1 -1
  369. package/build/dist/Server/Services/IncidentCustomFieldService.js +204 -8
  370. package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
  371. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
  372. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  373. package/build/dist/Server/Services/IncidentEpisodeService.js +14 -0
  374. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  375. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +26 -0
  376. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  377. package/build/dist/Server/Services/IncidentPublicNoteService.js +26 -1
  378. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  379. package/build/dist/Server/Services/IncidentService.js +1148 -42
  380. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  381. package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
  382. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  383. package/build/dist/Server/Services/IncidentTemplateService.js +83 -0
  384. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  385. package/build/dist/Server/Services/InventoryItemService.js +31 -0
  386. package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
  387. package/build/dist/Server/Services/IoTDeviceCredentialService.js +12 -5
  388. package/build/dist/Server/Services/IoTDeviceCredentialService.js.map +1 -1
  389. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +26 -1
  390. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  391. package/build/dist/Server/Services/ScheduledMaintenanceService.js +84 -57
  392. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  393. package/build/dist/Server/Services/SmsService.js +2 -22
  394. package/build/dist/Server/Services/SmsService.js.map +1 -1
  395. package/build/dist/Server/Services/StatusPageService.js +47 -9
  396. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  397. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +237 -32
  398. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  399. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js +109 -0
  400. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js.map +1 -1
  401. package/build/dist/Server/Services/StatusPageSubscriberService.js +925 -99
  402. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  403. package/build/dist/Server/Services/UserNotificationRuleService.js +55 -51
  404. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  405. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +42 -25
  406. package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
  407. package/build/dist/Server/Types/Markdown.js +110 -6
  408. package/build/dist/Server/Types/Markdown.js.map +1 -1
  409. package/build/dist/Server/Types/Workflow/Components/Email.js +55 -6
  410. package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
  411. package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js +405 -0
  412. package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js.map +1 -0
  413. package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js +112 -0
  414. package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js.map +1 -0
  415. package/build/dist/Server/Utils/CustomField/CustomFieldRename.js +211 -0
  416. package/build/dist/Server/Utils/CustomField/CustomFieldRename.js.map +1 -0
  417. package/build/dist/Server/Utils/DataSource/EgressGuard.js +41 -12
  418. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  419. package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js +81 -0
  420. package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js.map +1 -0
  421. package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js +101 -0
  422. package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js.map +1 -0
  423. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
  424. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  425. package/build/dist/Server/Utils/Response.js +30 -0
  426. package/build/dist/Server/Utils/Response.js.map +1 -1
  427. package/build/dist/Server/Utils/SSRFProtection.js +48 -6
  428. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  429. package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js +631 -0
  430. package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js.map +1 -0
  431. package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js +403 -0
  432. package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js.map +1 -0
  433. package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js +451 -0
  434. package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js.map +1 -0
  435. package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js +13 -0
  436. package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js.map +1 -0
  437. package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js +91 -0
  438. package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js.map +1 -0
  439. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js +101 -0
  440. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js.map +1 -0
  441. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js +47 -0
  442. package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js.map +1 -0
  443. package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js +273 -0
  444. package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js.map +1 -0
  445. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js +73 -0
  446. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js.map +1 -0
  447. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js +722 -0
  448. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js.map +1 -0
  449. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js +102 -0
  450. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js.map +1 -0
  451. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js +527 -0
  452. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js.map +1 -0
  453. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js +278 -0
  454. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js.map +1 -0
  455. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js +137 -0
  456. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js.map +1 -0
  457. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js +103 -0
  458. package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js.map +1 -0
  459. package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js +114 -0
  460. package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js.map +1 -0
  461. package/build/dist/Server/Utils/StatusPageResource.js +39 -7
  462. package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
  463. package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js +178 -0
  464. package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js.map +1 -0
  465. package/build/dist/Server/Utils/Topology/TopologyQueries.js +884 -0
  466. package/build/dist/Server/Utils/Topology/TopologyQueries.js.map +1 -0
  467. package/build/dist/Server/Utils/Topology/TopologyRequest.js +275 -0
  468. package/build/dist/Server/Utils/Topology/TopologyRequest.js.map +1 -0
  469. package/build/dist/Server/Utils/Topology/TopologyResponseCache.js +146 -0
  470. package/build/dist/Server/Utils/Topology/TopologyResponseCache.js.map +1 -0
  471. package/build/dist/Server/Utils/Topology/TopologySql.js +688 -0
  472. package/build/dist/Server/Utils/Topology/TopologySql.js.map +1 -0
  473. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  474. package/build/dist/Server/Utils/VM/VMRunner.js +1 -0
  475. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  476. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +3 -0
  477. package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -1
  478. package/build/dist/Types/CustomField/CustomFieldOrder.js +36 -0
  479. package/build/dist/Types/CustomField/CustomFieldOrder.js.map +1 -0
  480. package/build/dist/Types/CustomField/CustomFieldSavedViews.js +135 -0
  481. package/build/dist/Types/CustomField/CustomFieldSavedViews.js.map +1 -0
  482. package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js +27 -0
  483. package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js.map +1 -0
  484. package/build/dist/Types/CustomField/CustomFieldType.js +12 -0
  485. package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
  486. package/build/dist/Types/CustomField/CustomFieldValueFormat.js +126 -0
  487. package/build/dist/Types/CustomField/CustomFieldValueFormat.js.map +1 -0
  488. package/build/dist/Types/CustomField/CustomFieldValueValidator.js +280 -0
  489. package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -0
  490. package/build/dist/Types/CustomField/CustomFieldVariableKey.js +150 -0
  491. package/build/dist/Types/CustomField/CustomFieldVariableKey.js.map +1 -0
  492. package/build/dist/Types/Incident/IncidentAlertLink.js +17 -0
  493. package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -1
  494. package/build/dist/Types/SafeHtml.js +84 -0
  495. package/build/dist/Types/SafeHtml.js.map +1 -0
  496. package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js +117 -0
  497. package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js.map +1 -0
  498. package/build/dist/Types/StatusPage/IncidentCreatedResend.js +86 -0
  499. package/build/dist/Types/StatusPage/IncidentCreatedResend.js.map +1 -0
  500. package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js +246 -0
  501. package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js.map +1 -0
  502. package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js +183 -0
  503. package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js.map +1 -0
  504. package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js +277 -0
  505. package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js.map +1 -0
  506. package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js +27 -0
  507. package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js.map +1 -0
  508. package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js +190 -0
  509. package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js.map +1 -0
  510. package/build/dist/Types/StatusPage/SubscriberNotificationResend.js +102 -0
  511. package/build/dist/Types/StatusPage/SubscriberNotificationResend.js.map +1 -0
  512. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js +97 -0
  513. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js.map +1 -0
  514. package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js +175 -0
  515. package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js.map +1 -0
  516. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +144 -4
  517. package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -1
  518. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +29 -9
  519. package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -1
  520. package/build/dist/Types/Telemetry/InventoryLiveness.js +23 -0
  521. package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -1
  522. package/build/dist/Types/Topology/TopologyApi.js +55 -0
  523. package/build/dist/Types/Topology/TopologyApi.js.map +1 -0
  524. package/build/dist/Types/Topology/TopologyTypeRules.js +165 -0
  525. package/build/dist/Types/Topology/TopologyTypeRules.js.map +1 -0
  526. package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js +169 -0
  527. package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js.map +1 -0
  528. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +212 -0
  529. package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -0
  530. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +64 -49
  531. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  532. package/build/dist/UI/Components/Forms/ModelForm.js +39 -5
  533. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  534. package/build/dist/UI/Components/Forms/Validation.js +1 -1
  535. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  536. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  537. package/build/dist/UI/Components/ModelTable/AnalyticsModelTable.js.map +1 -1
  538. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +2 -2
  539. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  540. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +13 -1
  541. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  542. package/build/dist/UI/Components/ModelTable/ModelTable.js +1 -1
  543. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  544. package/build/dist/UI/Utils/SensitiveUrlToken.js +10 -5
  545. package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -1
  546. package/build/dist/Utils/API.js +177 -1
  547. package/build/dist/Utils/API.js.map +1 -1
  548. package/build/dist/Utils/Incident/IncidentFromAlerts.js +38 -0
  549. package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -1
  550. package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js +155 -0
  551. package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js.map +1 -0
  552. package/build/dist/Utils/Markdown/MarkdownEscape.js +48 -0
  553. package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -1
  554. package/build/dist/Utils/ProbeNetworkFailureUtil.js +460 -0
  555. package/build/dist/Utils/ProbeNetworkFailureUtil.js.map +1 -0
  556. package/package.json +1 -1
@@ -1,26 +1,65 @@
1
1
  import StatusPageSubscriberService from "../Services/StatusPageSubscriberService";
2
+ import StatusPageService from "../Services/StatusPageService";
2
3
  import Response from "../Utils/Response";
3
4
  import BaseAPI from "./BaseAPI";
4
5
  import StatusPageSubscriber from "../../Models/DatabaseModels/StatusPageSubscriber";
6
+ import ObjectID from "../../Types/ObjectID";
7
+ import StatusPageSubscriberUnsubscribe from "../../Types/StatusPage/StatusPageSubscriberUnsubscribe";
8
+ /*
9
+ * What the old unsubscribe route answers for an id that is not a
10
+ * subscriber's. Static, so nothing from the request is ever echoed into it.
11
+ */
12
+ export const OUT_OF_DATE_UNSUBSCRIBE_LINK_HTML = '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8" /><meta name="robots" content="noindex" /><meta name="referrer" content="no-referrer" /><title>Unsubscribe link out of date</title></head><body><p>This unsubscribe link is out of date. To unsubscribe, use the unsubscribe link at the bottom of a recent message from the status page.</p></body></html>';
5
13
  export default class StatusPageSubscriberAPI extends BaseAPI {
6
14
  constructor() {
7
15
  var _a;
8
16
  super(StatusPageSubscriber, StatusPageSubscriberService);
17
+ /*
18
+ * The unsubscribe link notifications carried until the end of 2023:
19
+ * /api/status-page-subscriber/unsubscribe/{subscriberId}. It used to
20
+ * unsubscribe on the GET itself, knowing only the id - so a mail scanner
21
+ * fetching the link, or an <img> pointed at it from anywhere, cancelled
22
+ * the subscription.
23
+ *
24
+ * It no longer changes anything. An old link still leads somewhere
25
+ * useful: the status page's unsubscribe page, told only the id, which
26
+ * says the link is out of date and to use the one in a recent message
27
+ * (and, on a public page, offers the subscriber's manage page). It never
28
+ * hands out the subscriber's unsubscribe token - that would make the id
29
+ * alone enough to unsubscribe again. Notifications now carry
30
+ * {statusPageUrl}/unsubscribe/{id}-{token}, which asks before it acts.
31
+ */
9
32
  this.router.get(`${(_a = new this.entityType().getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/unsubscribe/:id`, async (req, res, next) => {
10
33
  try {
11
- await this.service.updateOneBy({
12
- query: {
13
- _id: req.params["id"],
14
- },
15
- data: {
16
- isUnsubscribed: true,
17
- },
18
- props: {
19
- isRoot: true,
20
- ignoreHooks: true,
21
- },
22
- });
23
- return Response.sendHtmlResponse(req, res, "<html><body><p> You have been unsubscribed.</p><body><html>");
34
+ const subscriberId = req.params["id"] || "";
35
+ const subscriber = ObjectID.isValidUUID(subscriberId)
36
+ ? await this.service.findOneBy({
37
+ query: {
38
+ _id: subscriberId,
39
+ },
40
+ select: {
41
+ _id: true,
42
+ statusPageId: true,
43
+ },
44
+ props: {
45
+ isRoot: true,
46
+ ignoreHooks: true,
47
+ },
48
+ })
49
+ : null;
50
+ Response.setNoCacheHeaders(res);
51
+ if (!subscriber || !subscriber.id || !subscriber.statusPageId) {
52
+ res.status(404);
53
+ res.setHeader("Content-Type", "text/html; charset=utf-8");
54
+ res.send(OUT_OF_DATE_UNSUBSCRIBE_LINK_HTML);
55
+ return;
56
+ }
57
+ const statusPageUrl = await StatusPageService.getStatusPageURL(subscriber.statusPageId);
58
+ return Response.redirect(req, res, StatusPageSubscriberUnsubscribe.buildLink({
59
+ statusPageUrl: statusPageUrl,
60
+ subscriberId: subscriber.id,
61
+ unsubscribeToken: null,
62
+ }));
24
63
  }
25
64
  catch (err) {
26
65
  next(err);
@@ -1 +1 @@
1
- {"version":3,"file":"StatusPageSubscriberAPI.js","sourceRoot":"","sources":["../../../../Server/API/StatusPageSubscriberAPI.ts"],"names":[],"mappings":"AAAA,OAAO,2BAEN,MAAM,yCAAyC,CAAC;AAMjD,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AACzC,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,oBAAoB,MAAM,kDAAkD,CAAC;AAEpF,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,OAGpD;IACC;;QACE,KAAK,CAAC,oBAAoB,EAAE,2BAA2B,CAAC,CAAC;QAEzD,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,GAAG,MAAA,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,cAAc,EAAE,0CAAE,QAAQ,EAAE,kBAAkB,EACvE,KAAK,EAAE,GAAmB,EAAE,GAAoB,EAAE,IAAkB,EAAE,EAAE;YACtE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;oBAC7B,KAAK,EAAE;wBACL,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,CAAW;qBAChC;oBACD,IAAI,EAAE;wBACJ,cAAc,EAAE,IAAI;qBACrB;oBACD,KAAK,EAAE;wBACL,MAAM,EAAE,IAAI;wBACZ,WAAW,EAAE,IAAI;qBAClB;iBACF,CAAC,CAAC;gBAEH,OAAO,QAAQ,CAAC,gBAAgB,CAC9B,GAAG,EACH,GAAG,EACH,6DAA6D,CAC9D,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"StatusPageSubscriberAPI.js","sourceRoot":"","sources":["../../../../Server/API/StatusPageSubscriberAPI.ts"],"names":[],"mappings":"AAAA,OAAO,2BAEN,MAAM,yCAAyC,CAAC;AACjD,OAAO,iBAAiB,MAAM,+BAA+B,CAAC;AAM9D,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AACzC,OAAO,OAAO,MAAM,WAAW,CAAC;AAChC,OAAO,oBAAoB,MAAM,kDAAkD,CAAC;AACpF,OAAO,QAAQ,MAAM,sBAAsB,CAAC;AAC5C,OAAO,+BAA+B,MAAM,wDAAwD,CAAC;AAErG;;;GAGG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAC5C,wWAAwW,CAAC;AAE3W,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,OAGpD;IACC;;QACE,KAAK,CAAC,oBAAoB,EAAE,2BAA2B,CAAC,CAAC;QAEzD;;;;;;;;;;;;;;WAcG;QACH,IAAI,CAAC,MAAM,CAAC,GAAG,CACb,GAAG,MAAA,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC,cAAc,EAAE,0CAAE,QAAQ,EAAE,kBAAkB,EACvE,KAAK,EAAE,GAAmB,EAAE,GAAoB,EAAE,IAAkB,EAAE,EAAE;YACtE,IAAI,CAAC;gBACH,MAAM,YAAY,GAAY,GAAG,CAAC,MAAM,CAAC,IAAI,CAAY,IAAI,EAAE,CAAC;gBAEhE,MAAM,UAAU,GAAgC,QAAQ,CAAC,WAAW,CAClE,YAAY,CACb;oBACC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;wBAC3B,KAAK,EAAE;4BACL,GAAG,EAAE,YAAY;yBAClB;wBACD,MAAM,EAAE;4BACN,GAAG,EAAE,IAAI;4BACT,YAAY,EAAE,IAAI;yBACnB;wBACD,KAAK,EAAE;4BACL,MAAM,EAAE,IAAI;4BACZ,WAAW,EAAE,IAAI;yBAClB;qBACF,CAAC;oBACJ,CAAC,CAAC,IAAI,CAAC;gBAET,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;gBAEhC,IAAI,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;oBAC9D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAChB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;oBAC1D,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;oBAC5C,OAAO;gBACT,CAAC;gBAED,MAAM,aAAa,GACjB,MAAM,iBAAiB,CAAC,gBAAgB,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;gBAEpE,OAAO,QAAQ,CAAC,QAAQ,CACtB,GAAG,EACH,GAAG,EACH,+BAA+B,CAAC,SAAS,CAAC;oBACxC,aAAa,EAAE,aAAa;oBAC5B,YAAY,EAAE,UAAU,CAAC,EAAE;oBAC3B,gBAAgB,EAAE,IAAI;iBACvB,CAAC,CACH,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,CAAC;YACZ,CAAC;QACH,CAAC,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,165 @@
1
+ import logger from "../../../Utils/Logger";
2
+ export const INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX = "IDX_INVENTORY_ITEM_PROJECT_ENTITY_KEY";
3
+ /*
4
+ * Above this many InventoryItem rows the index is not built here (see
5
+ * "LOCKING" below). Roughly ten seconds of build on modest hardware.
6
+ */
7
+ export const INVENTORY_ITEM_INLINE_INDEX_BUILD_MAX_ROWS = 1000000;
8
+ /* What an operator runs to build the index online, under exactly this name. */
9
+ export const INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX_RUNBOOK = `CREATE INDEX CONCURRENTLY IF NOT EXISTS "${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX}" ON "InventoryItem" ("projectId", "entityKey")`;
10
+ /*
11
+ * Adds ("projectId", "entityKey") on InventoryItem.
12
+ *
13
+ * WHY
14
+ *
15
+ * Relationships name both ends by entity key only. The Topology API resolves
16
+ * those keys to items constantly — the things services call, where they run,
17
+ * the other end of every row in the detail drawer — and the only index that
18
+ * leads with the key today is the unique ("projectId", "entityType",
19
+ * "entityKey"), which a type-less lookup can use only as one probe per type in
20
+ * the project. The queries are written to stay correct and acceptable without
21
+ * this index (they constrain "entityType" to the project's types so the
22
+ * unique index is usable), because on Helm installs migrations run
23
+ * asynchronously and the new API can serve traffic before this has been
24
+ * built. This makes the same lookups one probe.
25
+ *
26
+ * Relationships get no new index on purpose: InventoryItemRelationship is the
27
+ * largest inventory table and a plain CREATE INDEX would block its ingest
28
+ * writes for the whole build.
29
+ *
30
+ * WHY THIS IS HAND-WRITTEN
31
+ *
32
+ * A generated migration cannot bound its own lock wait or runtime, nor decide
33
+ * to leave a build to the operator, and this one runs against a table that
34
+ * ingest writes continuously. The entity declares the index by name with
35
+ * `synchronize: false` (see Types/Database/UnsynchronizedIndex.ts), so the
36
+ * schema builder neither generates a second copy nor drops this one.
37
+ *
38
+ * LOCKING, AND THE RUNBOOK FOR LARGE INSTALLS
39
+ *
40
+ * Migrations run one transaction each (migrationsTransactionMode "each"), so
41
+ * CREATE INDEX CONCURRENTLY is not available here. A plain CREATE INDEX holds
42
+ * a SHARE lock on InventoryItem for as long as the build takes: reads
43
+ * continue, inventory writes queue behind it and fail once their own
44
+ * lock_timeout (3 s in the app) or statement_timeout runs out.
45
+ *
46
+ * The build cannot be given more time than the connection allows. The
47
+ * effective ceiling is the client-side DATABASE_QUERY_TIMEOUT_MS of
48
+ * node-postgres (35 s by default), which no SET can raise: past it the client
49
+ * abandons the query — and the ROLLBACK queued behind it — while the server
50
+ * keeps building and keeps the lock. So statement_timeout stays at the
51
+ * connection's own value (30 s by default, below that ceiling; `DEFAULT`
52
+ * undoes anything an earlier statement on the session may have set), which
53
+ * makes Postgres cancel an overlong build itself and release the lock at
54
+ * once. `lock_timeout` stops the migration from queueing behind a long
55
+ * transaction (and parking every writer behind itself) for more than five
56
+ * seconds; a timeout fails the migration, which the next start retries.
57
+ *
58
+ * A build that would not finish comfortably inside that window is not
59
+ * attempted: when InventoryItem holds more than
60
+ * INVENTORY_ITEM_INLINE_INDEX_BUILD_MAX_ROWS rows (the planner's estimate
61
+ * from pg_class; a bounded count when the table has never been analyzed),
62
+ * this migration logs a warning and completes without the index. The
63
+ * Topology API is correct without it, only slower on key lookups. Such an
64
+ * install should build the index online, at any time, under exactly this
65
+ * name:
66
+ *
67
+ * CREATE INDEX CONCURRENTLY IF NOT EXISTS "IDX_INVENTORY_ITEM_PROJECT_ENTITY_KEY"
68
+ * ON "InventoryItem" ("projectId", "entityKey");
69
+ *
70
+ * Built before the upgrade, this migration finds it and does nothing. A
71
+ * CONCURRENTLY build that failed leaves an INVALID index behind under that
72
+ * name, which IF NOT EXISTS would otherwise accept forever; such a leftover
73
+ * is dropped here first (so the runbook works as written afterwards) and
74
+ * rebuilt when the table is small enough.
75
+ *
76
+ * An online build that is still RUNNING looks exactly like that leftover
77
+ * (pg_index.indisvalid is false until it finishes). Dropping it would queue
78
+ * for an ACCESS EXCLUSIVE lock behind the build and stall every reader and
79
+ * writer of InventoryItem meanwhile, so a build in progress
80
+ * (pg_stat_progress_create_index) is left to finish and this migration
81
+ * completes without touching it.
82
+ */
83
+ export class AddInventoryItemProjectEntityKeyIndex1795200000000 {
84
+ /* Lowered only by tests; TypeORM constructs migrations without arguments. */
85
+ constructor(maxRowsForInlineBuild = INVENTORY_ITEM_INLINE_INDEX_BUILD_MAX_ROWS) {
86
+ this.maxRowsForInlineBuild = maxRowsForInlineBuild;
87
+ this.name = "AddInventoryItemProjectEntityKeyIndex1795200000000";
88
+ }
89
+ async up(queryRunner) {
90
+ await queryRunner.query(`SET LOCAL statement_timeout = DEFAULT`);
91
+ await queryRunner.query(`SET LOCAL lock_timeout = '5s'`);
92
+ const existing = await queryRunner.query(`SELECT x.indisvalid AS "isValid" FROM pg_index x
93
+ JOIN pg_class c ON c.oid = x.indexrelid
94
+ JOIN pg_namespace n ON n.oid = c.relnamespace
95
+ WHERE c.relname = $1 AND n.nspname = current_schema()`, [INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX]);
96
+ if (existing.some((index) => {
97
+ return index.isValid === true;
98
+ })) {
99
+ /* Pre-built by an operator (or already migrated): nothing to do. */
100
+ return;
101
+ }
102
+ if (existing.length > 0) {
103
+ if (await this.isBuildInProgress(queryRunner)) {
104
+ logger.warn(`AddInventoryItemProjectEntityKeyIndex: an online build of ${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX} is in progress; leaving it to finish. If that build fails, drop the INVALID index it leaves behind and run again: ${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX_RUNBOOK};`);
105
+ return;
106
+ }
107
+ await queryRunner.query(`DROP INDEX IF EXISTS "${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX}"`);
108
+ }
109
+ const rows = await this.estimateRows(queryRunner);
110
+ if (rows > this.maxRowsForInlineBuild) {
111
+ logger.warn(`AddInventoryItemProjectEntityKeyIndex: InventoryItem holds about ${Math.round(rows)} rows, more than the ${this.maxRowsForInlineBuild} this migration builds an index over while it blocks inventory writes, so the index ${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX} was NOT created. The Topology maps work without it but resolve entity keys more slowly. Build it online (it does not block writes) by running on the OneUptime database: ${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX_RUNBOOK};`);
112
+ return;
113
+ }
114
+ await queryRunner.query(`CREATE INDEX IF NOT EXISTS "${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX}" ON "InventoryItem" ("projectId", "entityKey")`);
115
+ }
116
+ async down(queryRunner) {
117
+ /*
118
+ * DROP INDEX takes ACCESS EXCLUSIVE on the table; waiting for it would
119
+ * park every reader and writer of InventoryItem behind this statement.
120
+ */
121
+ await queryRunner.query(`SET LOCAL statement_timeout = DEFAULT`);
122
+ await queryRunner.query(`SET LOCAL lock_timeout = '5s'`);
123
+ await queryRunner.query(`DROP INDEX IF EXISTS "${INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX}"`);
124
+ }
125
+ /* Whether a CREATE INDEX (CONCURRENTLY) of this index is running now. */
126
+ async isBuildInProgress(queryRunner) {
127
+ const builds = await queryRunner.query(`SELECT 1 FROM pg_stat_progress_create_index p
128
+ JOIN pg_class c ON c.oid = p.index_relid
129
+ JOIN pg_namespace n ON n.oid = c.relnamespace
130
+ WHERE c.relname = $1 AND n.nspname = current_schema()`, [INVENTORY_ITEM_PROJECT_ENTITY_KEY_INDEX]);
131
+ return builds.length > 0;
132
+ }
133
+ /*
134
+ * How many rows InventoryItem holds, from the statistics the planner uses:
135
+ * pg_class.reltuples scaled from the pages it was measured over to the
136
+ * table's current size (so growth since the last ANALYZE counts). A table
137
+ * that has never been analyzed (reltuples -1), or whose statistics saw no
138
+ * pages although it has some now, is counted instead — only up to just past
139
+ * the threshold, so the count stays cheap on any table.
140
+ */
141
+ async estimateRows(queryRunner) {
142
+ var _a, _b, _c, _d, _e, _f, _g, _h;
143
+ const statistics = await queryRunner.query(`SELECT c.reltuples::float8 AS "reltuples", c.relpages::float8 AS "relpages",
144
+ (pg_relation_size(c.oid) / current_setting('block_size')::int)::float8 AS "pages"
145
+ FROM pg_class c
146
+ JOIN pg_namespace n ON n.oid = c.relnamespace
147
+ WHERE c.relname = 'InventoryItem' AND n.nspname = current_schema()`);
148
+ const reltuples = Number((_b = (_a = statistics[0]) === null || _a === void 0 ? void 0 : _a.reltuples) !== null && _b !== void 0 ? _b : -1);
149
+ const relpages = Number((_d = (_c = statistics[0]) === null || _c === void 0 ? void 0 : _c.relpages) !== null && _d !== void 0 ? _d : 0);
150
+ const pages = Number((_f = (_e = statistics[0]) === null || _e === void 0 ? void 0 : _e.pages) !== null && _f !== void 0 ? _f : 0);
151
+ const isKnown = Number.isFinite(reltuples) &&
152
+ reltuples >= 0 &&
153
+ Number.isFinite(relpages) &&
154
+ Number.isFinite(pages) &&
155
+ (relpages > 0 || pages === 0);
156
+ if (isKnown) {
157
+ return relpages > 0
158
+ ? Math.max(reltuples, (reltuples / relpages) * pages)
159
+ : reltuples;
160
+ }
161
+ const counted = await queryRunner.query(`SELECT COUNT(*)::int AS "count" FROM (SELECT 1 FROM "InventoryItem" LIMIT $1) bounded`, [this.maxRowsForInlineBuild + 1]);
162
+ return Number((_h = (_g = counted[0]) === null || _g === void 0 ? void 0 : _g.count) !== null && _h !== void 0 ? _h : 0);
163
+ }
164
+ }
165
+ //# sourceMappingURL=1795200000000-AddInventoryItemProjectEntityKeyIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795200000000-AddInventoryItemProjectEntityKeyIndex.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Data fix: settle the 'incident created' subscriber notification of hidden
3
+ * incidents that the worker left InProgress.
4
+ *
5
+ * Incident:SendNotificationToSubscribers used to mark an incident's 'created'
6
+ * notification InProgress and then, when the incident was not visible on
7
+ * status pages, move on without settling it. The job only ever picks up
8
+ * Pending rows, so those rows stayed InProgress forever: the dashboard showed
9
+ * "Notifications Being Sent" for good, and nothing could ever send them once
10
+ * the incident was published. The worker now marks them Skipped with a
11
+ * reason, and publishing such an incident can re-queue the notification (see
12
+ * IncidentCreatedRenotify) - but only from Skipped. This moves the rows the old
13
+ * worker stranded to the same Skipped state and reason, so they get that
14
+ * option too.
15
+ *
16
+ * Only hidden incidents are touched. `IS NOT TRUE` also covers a NULL
17
+ * visibility, which the worker treated as hidden. A visible incident that is
18
+ * InProgress may really be sending right now, and is left alone.
19
+ *
20
+ * The message is written out rather than imported so the migration keeps
21
+ * doing what it did when it shipped. It matches
22
+ * IncidentCreatedRenotify.hiddenFromStatusPagesMessage, which is what the
23
+ * worker writes, so migrated rows read exactly like newly skipped ones (a
24
+ * test pins the two together).
25
+ *
26
+ * down() restores nothing: putting rows back into a state that nothing ever
27
+ * leaves would only break them again.
28
+ */
29
+ export const HIDDEN_FROM_STATUS_PAGES_MESSAGE = "Incident is not visible on status pages. Skipping notifications to subscribers.";
30
+ export class SkipHiddenIncidentCreatedNotifications1795300000000 {
31
+ constructor() {
32
+ this.name = "SkipHiddenIncidentCreatedNotifications1795300000000";
33
+ }
34
+ async up(queryRunner) {
35
+ await queryRunner.query(`UPDATE "Incident" SET "subscriberNotificationStatusOnIncidentCreated" = 'Skipped', "subscriberNotificationStatusMessage" = $1 WHERE "subscriberNotificationStatusOnIncidentCreated" = 'InProgress' AND "isVisibleOnStatusPage" IS NOT TRUE`, [HIDDEN_FROM_STATUS_PAGES_MESSAGE]);
36
+ }
37
+ async down(_queryRunner) {
38
+ // Nothing to restore; see the note above.
39
+ }
40
+ }
41
+ //# sourceMappingURL=1795300000000-SkipHiddenIncidentCreatedNotifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795300000000-SkipHiddenIncidentCreatedNotifications.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAC3C,iFAAiF,CAAC;AAEpF,MAAM,OAAO,mDAAmD;IAAhE;QAGS,SAAI,GAAW,qDAAqD,CAAC;IAY9E,CAAC;IAVQ,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,4OAA4O,EAC5O,CAAC,gCAAgC,CAAC,CACnC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,YAAyB;QACzC,0CAA0C;IAC5C,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Per-incident status page scope (Incident.statusPages).
3
+ *
4
+ * - IncidentStatusPage: the status pages an incident is limited to. Its join
5
+ * rows cascade when either side is deleted.
6
+ * - Incident.isScopedToStatusPages: whether the incident is limited to its
7
+ * status pages, so the status page queries can split on it in SQL. Existing
8
+ * incidents are unscoped, which is today's behaviour, so the default needs
9
+ * no backfill. It is never recomputed when join rows cascade away: an
10
+ * incident whose only scoped page is deleted stays scoped - to nothing - and
11
+ * is hidden rather than widened to every page its monitors reach. It is not
12
+ * indexed: false on nearly every row, and an index built here would hold
13
+ * this transaction's lock on Incident, reads included, for the whole build.
14
+ * Adding the NOT NULL DEFAULT false column itself does not rewrite the
15
+ * table.
16
+ * - Incident.statusPagesNotifiedOnCreation: the pages already sent the
17
+ * incident's 'created' notification, so a page added later is told once.
18
+ * - IncidentTemplateStatusPage: the scope an incident template applies.
19
+ * - StatusPage.onlyShowScopedIncidents: pages that never show or notify an
20
+ * unscoped incident. Off for every existing page.
21
+ */
22
+ export class AddIncidentStatusPageScope1795400000000 {
23
+ constructor() {
24
+ this.name = "AddIncidentStatusPageScope1795400000000";
25
+ }
26
+ async up(queryRunner) {
27
+ await queryRunner.query(`CREATE TABLE "IncidentStatusPage" ("incidentId" uuid NOT NULL, "statusPageId" uuid NOT NULL, CONSTRAINT "PK_704cbe88e7fbb614b8276db4326" PRIMARY KEY ("incidentId", "statusPageId"))`);
28
+ await queryRunner.query(`CREATE INDEX "IDX_a4ad6eb224d14cc17708420961" ON "IncidentStatusPage" ("incidentId") `);
29
+ await queryRunner.query(`CREATE INDEX "IDX_12a8bd395d53349410e5fce974" ON "IncidentStatusPage" ("statusPageId") `);
30
+ await queryRunner.query(`CREATE TABLE "IncidentTemplateStatusPage" ("incidentTemplateId" uuid NOT NULL, "statusPageId" uuid NOT NULL, CONSTRAINT "PK_24de18b6b85dd0baf4e0016a807" PRIMARY KEY ("incidentTemplateId", "statusPageId"))`);
31
+ await queryRunner.query(`CREATE INDEX "IDX_20db51def3a2086a8bf62294a1" ON "IncidentTemplateStatusPage" ("incidentTemplateId") `);
32
+ await queryRunner.query(`CREATE INDEX "IDX_b1a0dee8efae60ea4a0c37f6b8" ON "IncidentTemplateStatusPage" ("statusPageId") `);
33
+ await queryRunner.query(`ALTER TABLE "StatusPage" ADD "onlyShowScopedIncidents" boolean NOT NULL DEFAULT false`);
34
+ await queryRunner.query(`ALTER TABLE "Incident" ADD "isScopedToStatusPages" boolean NOT NULL DEFAULT false`);
35
+ await queryRunner.query(`ALTER TABLE "Incident" ADD "statusPagesNotifiedOnCreation" jsonb`);
36
+ await queryRunner.query(`ALTER TABLE "IncidentStatusPage" ADD CONSTRAINT "FK_a4ad6eb224d14cc177084209619" FOREIGN KEY ("incidentId") REFERENCES "Incident"("_id") ON DELETE CASCADE ON UPDATE CASCADE`);
37
+ await queryRunner.query(`ALTER TABLE "IncidentStatusPage" ADD CONSTRAINT "FK_12a8bd395d53349410e5fce9743" FOREIGN KEY ("statusPageId") REFERENCES "StatusPage"("_id") ON DELETE CASCADE ON UPDATE CASCADE`);
38
+ await queryRunner.query(`ALTER TABLE "IncidentTemplateStatusPage" ADD CONSTRAINT "FK_20db51def3a2086a8bf62294a1f" FOREIGN KEY ("incidentTemplateId") REFERENCES "IncidentTemplate"("_id") ON DELETE CASCADE ON UPDATE CASCADE`);
39
+ await queryRunner.query(`ALTER TABLE "IncidentTemplateStatusPage" ADD CONSTRAINT "FK_b1a0dee8efae60ea4a0c37f6b81" FOREIGN KEY ("statusPageId") REFERENCES "StatusPage"("_id") ON DELETE CASCADE ON UPDATE CASCADE`);
40
+ }
41
+ async down(queryRunner) {
42
+ await queryRunner.query(`ALTER TABLE "IncidentTemplateStatusPage" DROP CONSTRAINT "FK_b1a0dee8efae60ea4a0c37f6b81"`);
43
+ await queryRunner.query(`ALTER TABLE "IncidentTemplateStatusPage" DROP CONSTRAINT "FK_20db51def3a2086a8bf62294a1f"`);
44
+ await queryRunner.query(`ALTER TABLE "IncidentStatusPage" DROP CONSTRAINT "FK_12a8bd395d53349410e5fce9743"`);
45
+ await queryRunner.query(`ALTER TABLE "IncidentStatusPage" DROP CONSTRAINT "FK_a4ad6eb224d14cc177084209619"`);
46
+ await queryRunner.query(`ALTER TABLE "Incident" DROP COLUMN "statusPagesNotifiedOnCreation"`);
47
+ await queryRunner.query(`ALTER TABLE "Incident" DROP COLUMN "isScopedToStatusPages"`);
48
+ await queryRunner.query(`ALTER TABLE "StatusPage" DROP COLUMN "onlyShowScopedIncidents"`);
49
+ await queryRunner.query(`DROP INDEX "public"."IDX_b1a0dee8efae60ea4a0c37f6b8"`);
50
+ await queryRunner.query(`DROP INDEX "public"."IDX_20db51def3a2086a8bf62294a1"`);
51
+ await queryRunner.query(`DROP TABLE "IncidentTemplateStatusPage"`);
52
+ await queryRunner.query(`DROP INDEX "public"."IDX_12a8bd395d53349410e5fce974"`);
53
+ await queryRunner.query(`DROP INDEX "public"."IDX_a4ad6eb224d14cc17708420961"`);
54
+ await queryRunner.query(`DROP TABLE "IncidentStatusPage"`);
55
+ }
56
+ }
57
+ //# sourceMappingURL=1795400000000-AddIncidentStatusPageScope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795400000000-AddIncidentStatusPageScope.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,OAAO,uCAAuC;IAApD;QAGS,SAAI,GAAW,yCAAyC,CAAC;IAiFlE,CAAC;IA/EQ,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,sLAAsL,CACvL,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,uFAAuF,CACxF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,yFAAyF,CAC1F,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,8MAA8M,CAC/M,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,uGAAuG,CACxG,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,iGAAiG,CAClG,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,uFAAuF,CACxF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,mFAAmF,CACpF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,kEAAkE,CACnE,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,8KAA8K,CAC/K,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,kLAAkL,CACnL,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,sMAAsM,CACvM,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,0LAA0L,CAC3L,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CACrB,2FAA2F,CAC5F,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,2FAA2F,CAC5F,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,mFAAmF,CACpF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,mFAAmF,CACpF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,oEAAoE,CACrE,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,4DAA4D,CAC7D,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,gEAAgE,CACjE,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,sDAAsD,CACvD,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,sDAAsD,CACvD,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACnE,MAAM,WAAW,CAAC,KAAK,CACrB,sDAAsD,CACvD,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,sDAAsD,CACvD,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAC7D,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ /*
2
+ * IncidentTemplate.isScopedToStatusPages: whether a template limits the
3
+ * incidents declared from it to status pages, kept apart from its list of
4
+ * pages so that a template whose every page was deleted (the join rows
5
+ * cascade away) does not start declaring incidents that reach every status
6
+ * page (see the column in IncidentTemplate).
7
+ *
8
+ * Templates that already list status pages are scoped, so the flag is set for
9
+ * them. Nothing else changes: a template with no pages stays unscoped.
10
+ */
11
+ export class AddIncidentTemplateStatusPageScopeFlag1795500000000 {
12
+ constructor() {
13
+ this.name = "AddIncidentTemplateStatusPageScopeFlag1795500000000";
14
+ }
15
+ async up(queryRunner) {
16
+ await queryRunner.query(`ALTER TABLE "IncidentTemplate" ADD "isScopedToStatusPages" boolean NOT NULL DEFAULT false`);
17
+ await queryRunner.query(`UPDATE "IncidentTemplate" SET "isScopedToStatusPages" = true WHERE "_id" IN (SELECT "incidentTemplateId" FROM "IncidentTemplateStatusPage")`);
18
+ }
19
+ async down(queryRunner) {
20
+ await queryRunner.query(`ALTER TABLE "IncidentTemplate" DROP COLUMN "isScopedToStatusPages"`);
21
+ }
22
+ }
23
+ //# sourceMappingURL=1795500000000-AddIncidentTemplateStatusPageScopeFlag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795500000000-AddIncidentTemplateStatusPageScopeFlag.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,OAAO,mDAAmD;IAAhE;QAGS,SAAI,GAAW,qDAAqD,CAAC;IAiB9E,CAAC;IAfQ,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,2FAA2F,CAC5F,CAAC;QAEF,MAAM,WAAW,CAAC,KAAK,CACrB,6IAA6I,CAC9I,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CACrB,oEAAoE,CACrE,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Unsubscribing without signing in (StatusPageSubscriber.unsubscribeToken,
3
+ * StatusPageSubscriber.unsubscribedAt).
4
+ *
5
+ * - unsubscribeToken: the random secret in each subscriber's unsubscribe
6
+ * link, {statusPageUrl}/unsubscribe/{id}-{token}. Holding the link is what
7
+ * lets a subscriber of a private status page unsubscribe without an account
8
+ * on it. New subscribers get one from StatusPageSubscriberService.
9
+ * - unsubscribedAt: when a subscription was cancelled. Subscriptions
10
+ * cancelled before this column existed have none - there is no record of
11
+ * when they were - and are left empty rather than given a made-up date.
12
+ *
13
+ * Only the two nullable columns, which Postgres adds without rewriting the
14
+ * table. Existing subscribers are given their tokens by the
15
+ * BackfillStatusPageSubscriberUnsubscribeTokens data migration, in batches
16
+ * and outside this migration's transaction: one UPDATE of every row here
17
+ * would hold ADD COLUMN's exclusive lock on the table - blocking every
18
+ * notification, subscribe and subscriber list - for as long as it took, and
19
+ * on a large table it would run into the connection's statement timeout and
20
+ * fail the deploy. Until the backfill reaches a subscriber, the first sender
21
+ * to need its link gives it one (StatusPageSubscriberService
22
+ * .ensureUnsubscribeTokens).
23
+ *
24
+ * down() drops both columns; the tokens cannot be recovered afterwards, and
25
+ * every link already sent stops working.
26
+ */
27
+ export class AddStatusPageSubscriberUnsubscribeToken1795600000000 {
28
+ constructor() {
29
+ this.name = "AddStatusPageSubscriberUnsubscribeToken1795600000000";
30
+ }
31
+ async up(queryRunner) {
32
+ await queryRunner.query(`ALTER TABLE "StatusPageSubscriber" ADD "unsubscribedAt" TIMESTAMP WITH TIME ZONE`);
33
+ await queryRunner.query(`ALTER TABLE "StatusPageSubscriber" ADD "unsubscribeToken" character varying(100)`);
34
+ }
35
+ async down(queryRunner) {
36
+ await queryRunner.query(`ALTER TABLE "StatusPageSubscriber" DROP COLUMN "unsubscribeToken"`);
37
+ await queryRunner.query(`ALTER TABLE "StatusPageSubscriber" DROP COLUMN "unsubscribedAt"`);
38
+ }
39
+ }
40
+ //# sourceMappingURL=1795600000000-AddStatusPageSubscriberUnsubscribeToken.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795600000000-AddStatusPageSubscriberUnsubscribeToken.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,OAAO,oDAAoD;IAAjE;QAGS,SAAI,GAAW,sDAAsD,CAAC;IAmB/E,CAAC;IAjBQ,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,kFAAkF,CACnF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,kFAAkF,CACnF,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CACrB,mEAAmE,CACpE,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,iEAAiE,CAClE,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ /*
2
+ * StatusPageSubscriber.isAddedByTeam: whether the status page's team added a
3
+ * subscriber (from the dashboard, with an API key or by a workflow) rather
4
+ * than the subscriber signing up on the status page. It decides whether the
5
+ * page's owners are told when the subscriber unsubscribes itself - Created
6
+ * By cannot, because an API key's or a workflow's create carries no user.
7
+ *
8
+ * Postgres 11 and later add a NOT NULL column with a constant default without
9
+ * rewriting the table. Subscribers that already exist are marked from Created
10
+ * By by the BackfillStatusPageSubscriberUnsubscribeTokens data migration, in
11
+ * batches outside this transaction (see
12
+ * 1795600000000-AddStatusPageSubscriberUnsubscribeToken for why); until it
13
+ * reaches one, StatusPageSubscriberService reads Created By as well.
14
+ */
15
+ export class AddStatusPageSubscriberIsAddedByTeam1795700000000 {
16
+ constructor() {
17
+ this.name = "AddStatusPageSubscriberIsAddedByTeam1795700000000";
18
+ }
19
+ async up(queryRunner) {
20
+ await queryRunner.query(`ALTER TABLE "StatusPageSubscriber" ADD "isAddedByTeam" boolean NOT NULL DEFAULT false`);
21
+ }
22
+ async down(queryRunner) {
23
+ await queryRunner.query(`ALTER TABLE "StatusPageSubscriber" DROP COLUMN "isAddedByTeam"`);
24
+ }
25
+ }
26
+ //# sourceMappingURL=1795700000000-AddStatusPageSubscriberIsAddedByTeam.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795700000000-AddStatusPageSubscriberIsAddedByTeam.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,iDAAiD;IAA9D;QAGS,SAAI,GAAW,mDAAmD,CAAC;IAa5E,CAAC;IAXQ,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CACrB,gEAAgE,CACjE,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,89 @@
1
+ import { generateCustomFieldVariableKey } from "../../../../Types/CustomField/CustomFieldVariableKey";
2
+ /*
3
+ * Incident custom field settings for declaring incidents and for subscriber
4
+ * emails (OneUptime/oneuptime#4035):
5
+ *
6
+ * - isRequiredOnCreate, sortOrder, showOnCreate and
7
+ * includeInSubscriberNotifications: plain settings. The three flags start
8
+ * off, and no field has an order, so every existing field behaves as it did.
9
+ * - variableKey: the key templates reach a field by, {{customFields.<key>}}.
10
+ * Unique per project (the index), made from the name when a field is
11
+ * created and never changed afterwards. Nullable only because the table
12
+ * already has rows; the backfill below gives each of them a key.
13
+ *
14
+ * The backfill runs here, in the same transaction as the columns, rather than
15
+ * in a batched data migration like the subscriber tokens: definition tables
16
+ * hold a few dozen rows a project, and a key has to exist before anything
17
+ * lists a field's template variable. Keys are made by the same generator the
18
+ * service uses for a new field, so an existing field gets the key it would
19
+ * have got had it been created today. Within a project the oldest field wins
20
+ * the plain key and later ones get _2, _3, ...
21
+ *
22
+ * down() drops the columns and the index; the keys cannot be recovered, and
23
+ * templates that use them stop filling in.
24
+ */
25
+ // Rows written per UPDATE: two parameters each, well under Postgres' limit.
26
+ const BACKFILL_BATCH_SIZE = 500;
27
+ /**
28
+ * Give every incident custom field without a template key one. Idempotent:
29
+ * a key already there is kept, and counted as taken for the others.
30
+ * Returns how many fields it gave a key.
31
+ */
32
+ export const backfillIncidentCustomFieldVariableKeys = async (queryRunner) => {
33
+ const rows = await queryRunner.query(`SELECT "_id", "projectId", "name", "variableKey" FROM "IncidentCustomField" ORDER BY "projectId" ASC, "createdAt" ASC, "_id" ASC`);
34
+ const takenByProject = new Map();
35
+ for (const row of rows) {
36
+ const taken = takenByProject.get(row.projectId) || new Set();
37
+ if (row.variableKey) {
38
+ taken.add(row.variableKey);
39
+ }
40
+ takenByProject.set(row.projectId, taken);
41
+ }
42
+ const assignments = [];
43
+ for (const row of rows) {
44
+ if (row.variableKey) {
45
+ continue;
46
+ }
47
+ const taken = takenByProject.get(row.projectId);
48
+ const variableKey = generateCustomFieldVariableKey({
49
+ name: row.name || "",
50
+ existingKeys: taken,
51
+ });
52
+ taken.add(variableKey);
53
+ assignments.push({ id: row._id, variableKey: variableKey });
54
+ }
55
+ for (let start = 0; start < assignments.length; start += BACKFILL_BATCH_SIZE) {
56
+ const batch = assignments.slice(start, start + BACKFILL_BATCH_SIZE);
57
+ const values = [];
58
+ const parameters = [];
59
+ for (const assignment of batch) {
60
+ parameters.push(assignment.id, assignment.variableKey);
61
+ values.push(`($${parameters.length - 1}::uuid, $${parameters.length}::varchar)`);
62
+ }
63
+ await queryRunner.query(`UPDATE "IncidentCustomField" AS "field" SET "variableKey" = "keys"."variableKey" FROM (VALUES ${values.join(", ")}) AS "keys"("_id", "variableKey") WHERE "field"."_id" = "keys"."_id" AND "field"."variableKey" IS NULL`, parameters);
64
+ }
65
+ return assignments.length;
66
+ };
67
+ export class AddIncidentCustomFieldCreateAndNotificationSettings1795800000000 {
68
+ constructor() {
69
+ this.name = "AddIncidentCustomFieldCreateAndNotificationSettings1795800000000";
70
+ }
71
+ async up(queryRunner) {
72
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" ADD "isRequiredOnCreate" boolean NOT NULL DEFAULT false`);
73
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" ADD "sortOrder" integer`);
74
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" ADD "showOnCreate" boolean NOT NULL DEFAULT false`);
75
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" ADD "includeInSubscriberNotifications" boolean NOT NULL DEFAULT false`);
76
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" ADD "variableKey" character varying(100)`);
77
+ await queryRunner.query(`CREATE UNIQUE INDEX "IDX_0a49bcb055baad4356af439169" ON "IncidentCustomField" ("projectId", "variableKey") `);
78
+ await backfillIncidentCustomFieldVariableKeys(queryRunner);
79
+ }
80
+ async down(queryRunner) {
81
+ await queryRunner.query(`DROP INDEX "public"."IDX_0a49bcb055baad4356af439169"`);
82
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" DROP COLUMN "variableKey"`);
83
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" DROP COLUMN "includeInSubscriberNotifications"`);
84
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" DROP COLUMN "showOnCreate"`);
85
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" DROP COLUMN "sortOrder"`);
86
+ await queryRunner.query(`ALTER TABLE "IncidentCustomField" DROP COLUMN "isRequiredOnCreate"`);
87
+ }
88
+ }
89
+ //# sourceMappingURL=1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /*
2
+ * When a subscriber job claimed the 'incident created', 'postmortem' and
3
+ * 'episode created' notifications (SubscriberNotificationClaim), for the
4
+ * sweeper (StatusPageSubscriber:TimeoutStuckNotifications) to time an
5
+ * interrupted send from. It used updatedAt, which other code writes on a
6
+ * schedule while an incident or episode is open - the owners' reminders,
7
+ * state changes, incidents joining an episode - so a send cut off by a
8
+ * redeploy could stay In progress until the incident went quiet.
9
+ *
10
+ * Nullable timestamps with no default: adding them rewrites nothing. A row
11
+ * claimed before they existed has none, and the sweeper times it from
12
+ * updatedAt, as before.
13
+ */
14
+ export class AddSubscriberNotificationClaimedAt1795900000000 {
15
+ constructor() {
16
+ this.name = "AddSubscriberNotificationClaimedAt1795900000000";
17
+ }
18
+ async up(queryRunner) {
19
+ await queryRunner.query(`ALTER TABLE "IncidentEpisode" ADD "subscriberNotificationClaimedAtOnEpisodeCreated" TIMESTAMP WITH TIME ZONE`);
20
+ await queryRunner.query(`ALTER TABLE "Incident" ADD "subscriberNotificationClaimedAtOnIncidentCreated" TIMESTAMP WITH TIME ZONE`);
21
+ await queryRunner.query(`ALTER TABLE "Incident" ADD "subscriberNotificationClaimedAtOnPostmortemPublished" TIMESTAMP WITH TIME ZONE`);
22
+ }
23
+ async down(queryRunner) {
24
+ await queryRunner.query(`ALTER TABLE "Incident" DROP COLUMN "subscriberNotificationClaimedAtOnPostmortemPublished"`);
25
+ await queryRunner.query(`ALTER TABLE "Incident" DROP COLUMN "subscriberNotificationClaimedAtOnIncidentCreated"`);
26
+ await queryRunner.query(`ALTER TABLE "IncidentEpisode" DROP COLUMN "subscriberNotificationClaimedAtOnEpisodeCreated"`);
27
+ }
28
+ }
29
+ //# sourceMappingURL=1795900000000-AddSubscriberNotificationClaimedAt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"1795900000000-AddSubscriberNotificationClaimedAt.js","sourceRoot":"","sources":["../../../../../../Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,+CAA+C;IAA5D;QAGS,SAAI,GAAW,iDAAiD,CAAC;IAyB1E,CAAC;IAvBQ,KAAK,CAAC,EAAE,CAAC,WAAwB;QACtC,MAAM,WAAW,CAAC,KAAK,CACrB,8GAA8G,CAC/G,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,wGAAwG,CACzG,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,4GAA4G,CAC7G,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,WAAwB;QACxC,MAAM,WAAW,CAAC,KAAK,CACrB,2FAA2F,CAC5F,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,uFAAuF,CACxF,CAAC;QACF,MAAM,WAAW,CAAC,KAAK,CACrB,6FAA6F,CAC9F,CAAC;IACJ,CAAC;CACF"}