@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
@@ -39,6 +39,7 @@ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/Database
39
39
  import FileModel from "../../../Models/DatabaseModels/DatabaseBaseModel/FileModel";
40
40
  import Label from "../../../Models/DatabaseModels/Label";
41
41
  import URL from "../../../Types/API/URL";
42
+ import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
42
43
  import { ColumnAccessControl } from "../../../Types/BaseDatabase/AccessControl";
43
44
  import { Black, VeryLightGray } from "../../../Types/BrandColors";
44
45
  import Color from "../../../Types/Color";
@@ -61,11 +62,39 @@ import React, { MutableRefObject, ReactElement, useRef, useState } from "react";
61
62
  import useAsyncEffect from "use-async-effect";
62
63
  import Select from "../../../Types/BaseDatabase/Select";
63
64
 
65
+ /*
66
+ * Whether a dropdown's list request was refused because the person may not
67
+ * read that model (the server answers NotAuthorizedException with 422).
68
+ */
69
+ export const isListRefusedForLackOfPermission: (err: unknown) => boolean = (
70
+ err: unknown,
71
+ ): boolean => {
72
+ return err instanceof HTTPErrorResponse && err.statusCode === 422;
73
+ };
74
+
64
75
  export enum FormType {
65
76
  Create,
66
77
  Update,
67
78
  }
68
79
 
80
+ /*
81
+ * Runs on a Create form just before the request goes out, with the model built
82
+ * from the form's model columns and the misc data the request will carry (the
83
+ * same object: what the hook adds or removes there is what is sent).
84
+ *
85
+ * `formValues` is every value the form holds, exactly as submitted - the
86
+ * inputs that are not model columns included. Read those values from here
87
+ * rather than from `miscDataProps`, which keeps only the truthy ones: a
88
+ * number input holding 0 or a switch left off would otherwise vanish.
89
+ */
90
+ export type ModelFormOnBeforeCreate<
91
+ TBaseModel extends BaseModel | AnalyticsBaseModel,
92
+ > = (
93
+ item: TBaseModel,
94
+ miscDataProps: JSONObject,
95
+ formValues: JSONObject,
96
+ ) => Promise<TBaseModel>;
97
+
69
98
  export interface ModelField<TBaseModel extends BaseModel | AnalyticsBaseModel>
70
99
  extends Field<TBaseModel> {
71
100
  overrideField?:
@@ -114,9 +143,7 @@ export interface ComponentProps<TBaseModel extends BaseModel> {
114
143
  initialValues?: FormValues<TBaseModel> | undefined;
115
144
  modelIdToEdit?: ObjectID | undefined;
116
145
  onError?: ((error: string) => void) | undefined;
117
- onBeforeCreate?:
118
- | ((item: TBaseModel, miscDataProps: JSONObject) => Promise<TBaseModel>)
119
- | undefined;
146
+ onBeforeCreate?: ModelFormOnBeforeCreate<TBaseModel> | undefined;
120
147
  saveRequestOptions?: RequestOptions | undefined;
121
148
  doNotFetchExistingModel?: boolean | undefined;
122
149
  modelAPI?: typeof ModelAPI | undefined;
@@ -587,8 +614,22 @@ const ModelForm: <TBaseModel extends BaseModel>(
587
614
 
588
615
  setIsFetchingDropdownOptions(true);
589
616
 
590
- try {
591
- for (const field of fieldsToFetch) {
617
+ /*
618
+ * Each dropdown is fetched on its own, so one that fails still leaves the
619
+ * others their options. The first failure is shown once they are done,
620
+ * except a list the person may not read at all: that dropdown is simply
621
+ * left empty (and remembered as empty), as EntityDropdown does for its
622
+ * own requests. Reading the related model is a separate permission from
623
+ * editing this one, so someone may edit a field whose options they cannot
624
+ * list - an incident member and the status pages an incident is limited
625
+ * to - and a form-wide error on every step would say the form is broken
626
+ * when it is not. Pages that care explain the empty list next to the
627
+ * field.
628
+ */
629
+ let firstFetchError: unknown = null;
630
+
631
+ for (const field of fieldsToFetch) {
632
+ try {
592
633
  if (field.dropdownModal && field.dropdownModal.type) {
593
634
  const tempModel: BaseModel = new field.dropdownModal.type();
594
635
  const select: any = {
@@ -788,9 +829,26 @@ const ModelForm: <TBaseModel extends BaseModel>(
788
829
  selectByAccessControlProps: field.selectByAccessControlProps,
789
830
  });
790
831
  }
832
+ } catch (err) {
833
+ if (isListRefusedForLackOfPermission(err) && field.dropdownModal) {
834
+ field.dropdownOptions = [];
835
+
836
+ setCachedDropdownOptions(field.dropdownModal, {
837
+ dropdownOptions: [],
838
+ selectByAccessControlProps: undefined,
839
+ });
840
+
841
+ continue;
842
+ }
843
+
844
+ if (firstFetchError === null) {
845
+ firstFetchError = err;
846
+ }
791
847
  }
792
- } catch (err) {
793
- setError(API.getFriendlyMessage(err));
848
+ }
849
+
850
+ if (firstFetchError !== null) {
851
+ setError(API.getFriendlyMessage(firstFetchError));
794
852
  }
795
853
 
796
854
  if (generation === fieldsRunGeneration.current) {
@@ -1024,7 +1082,11 @@ const ModelForm: <TBaseModel extends BaseModel>(
1024
1082
  ) as TBaseModel;
1025
1083
 
1026
1084
  if (props.onBeforeCreate && props.formType === FormType.Create) {
1027
- tBaseModel = await props.onBeforeCreate(tBaseModel, miscDataProps);
1085
+ tBaseModel = await props.onBeforeCreate(
1086
+ tBaseModel,
1087
+ miscDataProps,
1088
+ values as JSONObject,
1089
+ );
1028
1090
  }
1029
1091
 
1030
1092
  result = await modelAPI.createOrUpdate<TBaseModel>({
@@ -51,7 +51,7 @@ const interpolateTemplate: (
51
51
  * we fall back to JS-interpolating the English template, so placeholders are
52
52
  * never shown literally and behavior is unchanged where i18n isn't set up.
53
53
  */
54
- const translateValidationMessage: (
54
+ export const translateValidationMessage: (
55
55
  template: string,
56
56
  values?: InterpolationValues,
57
57
  ) => string = (template: string, values: InterpolationValues = {}): string => {
@@ -5,12 +5,12 @@ import ButtonType from "../Button/ButtonTypes";
5
5
  import { FormProps } from "../Forms/BasicForm";
6
6
  import ModelForm, {
7
7
  ComponentProps as ModelFormComponentProps,
8
+ ModelFormOnBeforeCreate,
8
9
  } from "../Forms/ModelForm";
9
10
  import FormValues from "../Forms/Types/FormValues";
10
11
  import FormAnalyticsName from "../Forms/Utils/FormAnalyticsName";
11
12
  import Modal, { ModalWidth } from "../Modal/Modal";
12
13
  import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
13
- import { JSONObject } from "../../../Types/JSON";
14
14
  import ObjectID from "../../../Types/ObjectID";
15
15
  import React, { MutableRefObject, ReactElement, useRef, useState } from "react";
16
16
 
@@ -28,9 +28,7 @@ export interface ComponentProps<TBaseModel extends BaseModel> {
28
28
  submitButtonStyleType?: undefined | ButtonStyleType;
29
29
  formProps: ModelFormComponentProps<TBaseModel>;
30
30
  modelIdToEdit?: ObjectID | undefined;
31
- onBeforeCreate?:
32
- | ((item: TBaseModel, miscDataProps: JSONObject) => Promise<TBaseModel>)
33
- | undefined;
31
+ onBeforeCreate?: ModelFormOnBeforeCreate<TBaseModel> | undefined;
34
32
  footer?: ReactElement | undefined;
35
33
  formRef?: undefined | MutableRefObject<FormProps<FormValues<TBaseModel>>>;
36
34
  }
@@ -13,6 +13,7 @@ import Select from "../../../Types/BaseDatabase/Select";
13
13
  import Sort from "../../../Types/BaseDatabase/Sort";
14
14
  import GroupBy from "../../../Types/BaseDatabase/GroupBy";
15
15
  import RequestOptions from "../../Utils/API/RequestOptions";
16
+ import { ModelFormOnBeforeCreate } from "../Forms/ModelForm";
16
17
 
17
18
  export interface ComponentProps<TBaseModel extends AnalyticsBaseModel>
18
19
  extends BaseTableProps<TBaseModel> {
@@ -47,12 +48,7 @@ const AnalyticsModelTable: <TBaseModel extends AnalyticsBaseModel>(
47
48
  showCreateEditModal: (_data: {
48
49
  modalType: ModalType;
49
50
  modelIdToEdit?: ObjectID | undefined;
50
- onBeforeCreate?:
51
- | ((
52
- item: TBaseModel,
53
- miscDataProps: JSONObject,
54
- ) => Promise<TBaseModel>)
55
- | undefined;
51
+ onBeforeCreate?: ModelFormOnBeforeCreate<TBaseModel> | undefined;
56
52
  onSuccess?: ((item: TBaseModel) => void) | undefined;
57
53
  onClose?: (() => void) | undefined;
58
54
  }): ReactElement => {
@@ -45,7 +45,7 @@ import ErrorMessage from "../ErrorMessage/ErrorMessage";
45
45
  import ClassicFilterType from "../Filters/Types/Filter";
46
46
  import FilterData from "../Filters/Types/FilterData";
47
47
  import { FormProps, FormSummaryConfig } from "../Forms/BasicForm";
48
- import { ModelField } from "../Forms/ModelForm";
48
+ import { ModelField, ModelFormOnBeforeCreate } from "../Forms/ModelForm";
49
49
  import { FormStep } from "../Forms/Types/FormStep";
50
50
  import FormValues from "../Forms/Types/FormValues";
51
51
  import List from "../List/List";
@@ -186,9 +186,7 @@ export interface BaseTableCallbacks<
186
186
  showCreateEditModal: (data: {
187
187
  modalType: ModalType;
188
188
  modelIdToEdit?: ObjectID | undefined;
189
- onBeforeCreate?:
190
- | ((item: TBaseModel, miscDataProps: JSONObject) => Promise<TBaseModel>)
191
- | undefined;
189
+ onBeforeCreate?: ModelFormOnBeforeCreate<TBaseModel> | undefined;
192
190
  onSuccess?: ((item: TBaseModel) => void) | undefined;
193
191
  onClose?: (() => void) | undefined;
194
192
  }) => ReactElement;
@@ -283,9 +281,7 @@ export interface BaseTableProps<
283
281
  groupBy?: GroupBy<TBaseModel> | undefined;
284
282
  onBeforeFetch?: (() => Promise<TBaseModel>) | undefined;
285
283
  createInitialValues?: FormValues<TBaseModel> | undefined;
286
- onBeforeCreate?:
287
- | ((item: TBaseModel, miscDataProps: JSONObject) => Promise<TBaseModel>)
288
- | undefined;
284
+ onBeforeCreate?: ModelFormOnBeforeCreate<TBaseModel> | undefined;
289
285
  // Runs after both create and edit; modalType identifies which form was saved.
290
286
  onCreateSuccess?:
291
287
  | ((item: TBaseModel, modalType?: ModalType) => Promise<TBaseModel>)
@@ -4764,6 +4760,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
4764
4760
  onBeforeCreate: async (
4765
4761
  item: TBaseModel,
4766
4762
  miscDataProps: JSONObject,
4763
+ formValues: JSONObject,
4767
4764
  ) => {
4768
4765
  if (
4769
4766
  showAs === ShowAs.OrderedStatesList &&
@@ -4777,7 +4774,11 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
4777
4774
  }
4778
4775
 
4779
4776
  if (props.onBeforeCreate) {
4780
- item = await props.onBeforeCreate(item, miscDataProps);
4777
+ item = await props.onBeforeCreate(
4778
+ item,
4779
+ miscDataProps,
4780
+ formValues,
4781
+ );
4781
4782
  }
4782
4783
 
4783
4784
  return item;
@@ -7,6 +7,7 @@ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/Database
7
7
  import CustomFieldType from "../../../Types/CustomField/CustomFieldType";
8
8
  import OneUptimeDate from "../../../Types/Date";
9
9
  import { CustomFieldDefinition } from "../../../Types/CustomField/CustomFieldDefinition";
10
+ import { CUSTOM_FIELD_COLUMN_ID_PREFIX } from "../../../Types/CustomField/CustomFieldSavedViews";
10
11
  import {
11
12
  CustomFieldDropdownOption,
12
13
  parseCustomFieldDropdownOptions,
@@ -316,6 +317,14 @@ export const renderCustomFieldValue: RenderCustomFieldValueFunction = (data: {
316
317
  return <span>{JSON.stringify(value)}</span>;
317
318
  }
318
319
 
320
+ /*
321
+ * Long text keeps its line breaks, as the type promises and as the Custom
322
+ * Fields card and its email show it; runs of spaces still collapse.
323
+ */
324
+ if (definition.customFieldType === CustomFieldType.LongText) {
325
+ return <span className="whitespace-pre-line">{String(value)}</span>;
326
+ }
327
+
319
328
  return <span>{String(value)}</span>;
320
329
  };
321
330
 
@@ -343,7 +352,11 @@ export const getCustomFieldColumns: GetCustomFieldColumnsFunction = <
343
352
  return (data.definitions || []).map(
344
353
  (definition: CustomFieldDefinition): Column<TBaseModel> => {
345
354
  return {
346
- id: `${CustomFieldsColumnKey}.${definition.name}`,
355
+ /*
356
+ * The prefix is shared with renaming a field, which rewrites saved
357
+ * views' column lists (CustomFieldSavedViews).
358
+ */
359
+ id: `${CUSTOM_FIELD_COLUMN_ID_PREFIX}${definition.name}`,
347
360
  field: {
348
361
  [CustomFieldsColumnKey]: true,
349
362
  } as Column<TBaseModel>["field"],
@@ -7,7 +7,11 @@ import PermissionGate, {
7
7
  ModelAction,
8
8
  PermissionGateResult,
9
9
  } from "../../Utils/PermissionGate";
10
- import { FormType, ModelField } from "../Forms/ModelForm";
10
+ import {
11
+ FormType,
12
+ ModelField,
13
+ ModelFormOnBeforeCreate,
14
+ } from "../Forms/ModelForm";
11
15
  import ModelFormModal from "../ModelFormModal/ModelFormModal";
12
16
  import BaseModelTable, {
13
17
  BaseTableProps,
@@ -260,12 +264,7 @@ const ModelTable: <TBaseModel extends BaseModel>(
260
264
  showCreateEditModal: (data: {
261
265
  modalType: ModalType;
262
266
  modelIdToEdit?: ObjectID | undefined;
263
- onBeforeCreate?:
264
- | ((
265
- item: TBaseModel,
266
- miscDataProps: JSONObject,
267
- ) => Promise<TBaseModel>)
268
- | undefined;
267
+ onBeforeCreate?: ModelFormOnBeforeCreate<TBaseModel> | undefined;
269
268
  onSuccess?: ((item: TBaseModel) => void) | undefined;
270
269
  onClose?: (() => void) | undefined;
271
270
  }): ReactElement => {
@@ -19,12 +19,17 @@
19
19
  const STORAGE_KEY: string = "oneuptime-sensitive-url-token";
20
20
 
21
21
  /*
22
- * Route segments whose NEXT path segment is a single-use bearer token. Matched
23
- * against the second-to-last segment, so this covers
24
- * /accounts/reset-password/<token>, /reset-password/<token> and
25
- * /status-page/<id>/reset-password/<token> alike.
22
+ * Route segments whose NEXT path segment is a bearer token. Matched against
23
+ * the second-to-last segment, so this covers /accounts/reset-password/<token>,
24
+ * /reset-password/<token> and /status-page/<id>/reset-password/<token> alike.
25
+ * "unsubscribe" is a status page subscriber's unsubscribe link, whose last
26
+ * segment is <subscriberId>-<token> (Common/Types/StatusPage/StatusPageSubscriberUnsubscribe).
26
27
  */
27
- const TOKEN_ROUTES: Array<string> = ["reset-password", "verify-email"];
28
+ const TOKEN_ROUTES: Array<string> = [
29
+ "reset-password",
30
+ "verify-email",
31
+ "unsubscribe",
32
+ ];
28
33
 
29
34
  interface HandoffWindow extends Window {
30
35
  __ONEUPTIME_SENSITIVE_URL_TOKEN__?: string | undefined;
package/Utils/API.ts CHANGED
@@ -28,9 +28,52 @@ import Sleep from "../Types/Sleep";
28
28
  import HTTPResponseBodyReader, {
29
29
  HTTPResponseBodyBudget,
30
30
  } from "./HTTPResponseBodyReader";
31
+ import HostAddressUtil from "./HostAddressUtil";
32
+ import ProbeNetworkFailureUtil, {
33
+ ProbeNetworkFailure,
34
+ ProbeNetworkFailureKind,
35
+ ProbeNetworkOperation,
36
+ } from "./ProbeNetworkFailureUtil";
31
37
  import type { Agent as HttpAgent } from "http";
32
38
  import type { Agent as HttpsAgent } from "https";
33
39
 
40
+ /*
41
+ * A request that failed on the probe itself, before anything reached the
42
+ * target. See API.getProbeSideRequestFailure.
43
+ */
44
+ interface ProbeSideRequestFailure {
45
+ failure: ProbeNetworkFailure;
46
+ // The request's host, bare, or a stand-in when the error does not carry it.
47
+ host: string;
48
+ isIPv6Destination: boolean;
49
+ }
50
+
51
+ // What a probe-side failure calls the target when the error has no request URL.
52
+ const UNKNOWN_REQUEST_HOST: string = "the server";
53
+
54
+ // How far down an error's `cause` / `errors` the connect addresses are read.
55
+ const MAX_CONNECT_ADDRESS_DEPTH: number = 5;
56
+
57
+ /*
58
+ * The code a probe-side failure is reported under. Taken from the
59
+ * classification rather than the thrown error because fetch's TypeError and
60
+ * the API monitor's APIException have no usable code of their own, and an
61
+ * aggregate carries only its first attempt's. NoRouteToHost never comes out
62
+ * of a TCP connect; it is listed so the map stays total.
63
+ */
64
+ const PROBE_NETWORK_FAILURE_ERROR_CODES: Record<
65
+ ProbeNetworkFailureKind,
66
+ string
67
+ > = {
68
+ [ProbeNetworkFailureKind.NoSourceAddress]: "EADDRNOTAVAIL",
69
+ [ProbeNetworkFailureKind.AddressFamilyNotSupported]: "EAFNOSUPPORT",
70
+ [ProbeNetworkFailureKind.NetworkUnreachable]: "ENETUNREACH",
71
+ [ProbeNetworkFailureKind.NoRouteToHost]: "EHOSTUNREACH",
72
+ };
73
+
74
+ const NETWORK_UNREACHABLE_DESCRIPTION: string =
75
+ "Network unreachable. There is no route to the network where the server resides. This is typically a routing or connectivity issue.";
76
+
34
77
  /*
35
78
  * Diagnostic summary of one settled fetch() call, retries included. Handed
36
79
  * to RequestOptions.onRequestComplete so a caller can log WHERE a request
@@ -1299,6 +1342,30 @@ export default class API {
1299
1342
  };
1300
1343
  }
1301
1344
 
1345
+ /*
1346
+ * The connect failed on the probe, before the request left it. Checked
1347
+ * ahead of the string rules below because none of them describe it:
1348
+ * EADDRNOTAVAIL matched nothing and fell through to "The request was sent
1349
+ * but no response was returned", when nothing was sent at all, and a
1350
+ * probe with no IPv6 was told there was no route to the network where the
1351
+ * server resides. Still the TCP connection phase, since connect() is what
1352
+ * failed. The failure cause the monitor reports alongside this already
1353
+ * quotes the OS error (getProbeNetworkFailureDescription), so this only
1354
+ * says what it means for the request.
1355
+ */
1356
+ const probeSideFailure: ProbeSideRequestFailure | null =
1357
+ API.getProbeSideRequestFailure(error);
1358
+
1359
+ if (probeSideFailure) {
1360
+ return {
1361
+ failedPhase: RequestFailedPhase.TCPConnection,
1362
+ errorCode:
1363
+ PROBE_NETWORK_FAILURE_ERROR_CODES[probeSideFailure.failure.kind],
1364
+ errorDescription: API.getProbeSideFailureDetails(probeSideFailure),
1365
+ rawErrorMessage,
1366
+ };
1367
+ }
1368
+
1302
1369
  // Helper to determine the phase and description based on error code/message
1303
1370
  const lowerMessage: string = rawErrorMessage.toLowerCase();
1304
1371
 
@@ -1460,8 +1527,7 @@ export default class API {
1460
1527
  return {
1461
1528
  failedPhase: RequestFailedPhase.TCPConnection,
1462
1529
  errorCode: errorCode || "ENETUNREACH",
1463
- errorDescription:
1464
- "Network unreachable. There is no route to the network where the server resides. This is typically a routing or connectivity issue.",
1530
+ errorDescription: NETWORK_UNREACHABLE_DESCRIPTION,
1465
1531
  rawErrorMessage,
1466
1532
  };
1467
1533
  }
@@ -1512,4 +1578,183 @@ export default class API {
1512
1578
  rawErrorMessage,
1513
1579
  };
1514
1580
  }
1581
+
1582
+ /*
1583
+ * The failure cause for a monitor request that failed on the probe itself,
1584
+ * in the shared probe-side wording (which quotes the OS error), or null for
1585
+ * any other failure. A probe with no usable IPv6 fails every IPv6 URL with
1586
+ * a bare "connect EADDRNOTAVAIL ...", which reads as the customer's site
1587
+ * being down while it may be answering perfectly well.
1588
+ *
1589
+ * ENETUNREACH from a TCP connect can also be a router's "no route" to the
1590
+ * destination, so it is only reworded for an IPv6 destination, where the
1591
+ * shared wording says "most likely". Otherwise it keeps its message.
1592
+ *
1593
+ * Separate from getFriendlyErrorMessage on purpose: that one is also used
1594
+ * by the dashboard and by the server's own outbound requests, where "this
1595
+ * probe" would be false. Only the Website and API monitors call this.
1596
+ */
1597
+ public static getProbeNetworkFailureDescription(
1598
+ error: unknown,
1599
+ ): string | null {
1600
+ const probeSideFailure: ProbeSideRequestFailure | null =
1601
+ API.getProbeSideRequestFailure(error);
1602
+
1603
+ if (
1604
+ !probeSideFailure ||
1605
+ (!probeSideFailure.failure.isCertain &&
1606
+ !probeSideFailure.isIPv6Destination)
1607
+ ) {
1608
+ return null;
1609
+ }
1610
+
1611
+ return ProbeNetworkFailureUtil.describe({
1612
+ host: probeSideFailure.host,
1613
+ failure: probeSideFailure.failure,
1614
+ isIPv6Destination: probeSideFailure.isIPv6Destination,
1615
+ });
1616
+ }
1617
+
1618
+ /*
1619
+ * Classifies a request error as a connect that failed on the probe, with
1620
+ * the host to name and whether to word it as IPv6.
1621
+ *
1622
+ * IPv6 wording needs evidence. It is used when every address the probe
1623
+ * tried to connect to was IPv6 or, when the error names no address, when
1624
+ * the request URL's host is an IPv6 literal. A dual-stack name whose IPv4
1625
+ * attempt failed as well is not an IPv6 problem, and neither is an IPv4
1626
+ * proxy the probe could not reach on the way to an IPv6 target.
1627
+ */
1628
+ private static getProbeSideRequestFailure(
1629
+ error: unknown,
1630
+ ): ProbeSideRequestFailure | null {
1631
+ // The guard refuses before any socket exists; its message is its own.
1632
+ if (error instanceof EgressGuardException) {
1633
+ return null;
1634
+ }
1635
+
1636
+ /*
1637
+ * The API monitor gets the AxiosError wrapped in an APIException (see
1638
+ * getErrorResponse). The wrapper's own code is an ExceptionCode number
1639
+ * and its message carries the errno but not the OS text, so the
1640
+ * classifier would find nothing on it.
1641
+ */
1642
+ const requestError: unknown =
1643
+ error instanceof APIException && error.error ? error.error : error;
1644
+
1645
+ const failure: ProbeNetworkFailure | null =
1646
+ ProbeNetworkFailureUtil.classifyError({
1647
+ error: requestError,
1648
+ operation: ProbeNetworkOperation.TcpConnect,
1649
+ });
1650
+
1651
+ if (!failure) {
1652
+ return null;
1653
+ }
1654
+
1655
+ const requestHost: string | null = API.getRequestHost(requestError);
1656
+ const connectAddresses: Array<string> = [];
1657
+ API.collectConnectAddresses(requestError, 0, connectAddresses);
1658
+
1659
+ const isIPv6Destination: boolean =
1660
+ connectAddresses.length > 0
1661
+ ? connectAddresses.every((address: string) => {
1662
+ return HostAddressUtil.isIPv6(address);
1663
+ })
1664
+ : Boolean(requestHost && HostAddressUtil.isIPv6(requestHost));
1665
+
1666
+ return {
1667
+ failure: failure,
1668
+ host: requestHost || UNKNOWN_REQUEST_HOST,
1669
+ isIPv6Destination: isIPv6Destination,
1670
+ };
1671
+ }
1672
+
1673
+ /*
1674
+ * The "Error Details" text for a probe-side failure. ENETUNREACH that is
1675
+ * not towards IPv6 keeps the family-neutral description it always had.
1676
+ */
1677
+ private static getProbeSideFailureDetails(
1678
+ probeSideFailure: ProbeSideRequestFailure,
1679
+ ): string {
1680
+ const failure: ProbeNetworkFailure = probeSideFailure.failure;
1681
+
1682
+ if (!probeSideFailure.isIPv6Destination) {
1683
+ return failure.isCertain
1684
+ ? "The probe could not open the connection from its own side, so the request was never sent and the server was never contacted. The failure is on the probe, not on the server."
1685
+ : NETWORK_UNREACHABLE_DESCRIPTION;
1686
+ }
1687
+
1688
+ /*
1689
+ * EADDRNOTAVAIL from a TCP connect is also what a probe that has run
1690
+ * out of local ports gets, IPv6 or not, so it is not stated as missing
1691
+ * IPv6.
1692
+ */
1693
+ if (failure.isCertain && failure.isCauseAmbiguous) {
1694
+ return "The probe could not open the IPv6 connection from its own side, so the request was never sent and the server was never contacted. The failure is on the probe, not on the server.";
1695
+ }
1696
+
1697
+ if (failure.isCertain) {
1698
+ return "The probe cannot send IPv6 traffic, so the request was never sent and the server was never contacted. The failure is on the probe, not on the server.";
1699
+ }
1700
+
1701
+ return "There was no IPv6 route to the server. Most likely the probe has no IPv6 route rather than the server being down.";
1702
+ }
1703
+
1704
+ /*
1705
+ * The host of the URL an axios request was sent to, without IPv6
1706
+ * brackets, or null when the error is not an axios one or has no usable
1707
+ * URL. It is the hop that failed, which after a redirect is not
1708
+ * necessarily the monitor's own URL.
1709
+ */
1710
+ private static getRequestHost(error: unknown): string | null {
1711
+ if (!axios.isAxiosError(error) || !error.config?.url) {
1712
+ return null;
1713
+ }
1714
+
1715
+ try {
1716
+ const requestUrl: globalThis.URL = new globalThis.URL(
1717
+ error.config.url,
1718
+ error.config.baseURL || undefined,
1719
+ );
1720
+
1721
+ return HostAddressUtil.stripBrackets(requestUrl.hostname) || null;
1722
+ } catch {
1723
+ return null;
1724
+ }
1725
+ }
1726
+
1727
+ /*
1728
+ * Every `address` a socket error in the chain names: the error's own, its
1729
+ * cause's (axios and fetch keep the socket error there) and each attempt
1730
+ * of an aggregate (Node's happy-eyeballs connect, one error per address).
1731
+ */
1732
+ private static collectConnectAddresses(
1733
+ value: unknown,
1734
+ depth: number,
1735
+ addresses: Array<string>,
1736
+ ): void {
1737
+ if (
1738
+ !value ||
1739
+ typeof value !== "object" ||
1740
+ depth > MAX_CONNECT_ADDRESS_DEPTH
1741
+ ) {
1742
+ return;
1743
+ }
1744
+
1745
+ const errorLike: { address?: unknown; errors?: unknown; cause?: unknown } =
1746
+ value as { address?: unknown; errors?: unknown; cause?: unknown };
1747
+
1748
+ if (typeof errorLike.address === "string" && errorLike.address) {
1749
+ addresses.push(HostAddressUtil.stripBrackets(errorLike.address));
1750
+ }
1751
+
1752
+ if (Array.isArray(errorLike.errors)) {
1753
+ for (const attempt of errorLike.errors) {
1754
+ API.collectConnectAddresses(attempt, depth + 1, addresses);
1755
+ }
1756
+ }
1757
+
1758
+ API.collectConnectAddresses(errorLike.cause, depth + 1, addresses);
1759
+ }
1515
1760
  }