@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
@@ -0,0 +1,378 @@
1
+ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
2
+ import TableView from "../../../Models/DatabaseModels/TableView";
3
+ import {
4
+ CustomFieldSavedViewState,
5
+ RenamedCustomFieldSavedViewState,
6
+ renameCustomFieldInSavedView,
7
+ } from "../../../Types/CustomField/CustomFieldSavedViews";
8
+ import LIMIT_MAX from "../../../Types/Database/LimitMax";
9
+ import { JSONObject } from "../../../Types/JSON";
10
+ import ObjectID from "../../../Types/ObjectID";
11
+ import DatabaseService from "../../Services/DatabaseService";
12
+ import TableViewService from "../../Services/TableViewService";
13
+ import QueryHelper from "../../Types/Database/QueryHelper";
14
+ import logger, { LogAttributes } from "../Logger";
15
+ import { ColumnMetadata } from "typeorm/metadata/ColumnMetadata";
16
+ import { EntityManager, EntityMetadata, Repository } from "typeorm";
17
+
18
+ /*
19
+ * RENAMING A CUSTOM FIELD.
20
+ *
21
+ * Custom field values live in each record's `customFields` jsonb bag, keyed
22
+ * by the field's display name, so renaming "Impact" to "Business Impact"
23
+ * orphans every stored value unless the key moves with it. This moves it:
24
+ * one UPDATE per table, for the whole project, that takes the value out from
25
+ * under the old key and puts it back under the new one - and does the same
26
+ * to the saved table views that name the field.
27
+ *
28
+ * THE NEW NAME STARTS CLEAN. Deleting a field leaves its values in the
29
+ * records (see the custom fields docs), so a record can hold a value under
30
+ * the new name that belongs to no field: a deleted field's answer. The
31
+ * renamed field must not pick those up - they were never its values, and an
32
+ * incident field marked for subscriber notifications would send them out -
33
+ * so the same UPDATE removes the new name from every record of the project
34
+ * that holds nothing under the old one. After a rename, the values under the
35
+ * new name are exactly the ones that were under the old.
36
+ *
37
+ * WHY NOT DatabaseService.updateBy. It fires the model's "on update" workflow
38
+ * trigger for every changed row, even with ignoreHooks (see _updateBy), and
39
+ * customers' own workflows listen on incident custom fields. A rename is a
40
+ * change of label, not of any incident's answers; it must not start a
41
+ * workflow run per incident. The raw statements here fire no workflow, no
42
+ * realtime event and no audit entry, bump no `version`, and leave `updatedAt`
43
+ * alone, like the other derived-data writes (CustomFieldMappingService).
44
+ *
45
+ * The table and column names come from the entity metadata, never from the
46
+ * caller, and every value is a bound parameter, so the SQL is not an
47
+ * injection surface.
48
+ */
49
+
50
+ export interface MoveCustomFieldValueKeyInput {
51
+ // The service whose table holds values under the field's name.
52
+ service: DatabaseService<any>;
53
+ projectId: ObjectID;
54
+ oldName: string;
55
+ newName: string;
56
+ // The transaction to run the statement in; on its own when not given.
57
+ manager?: EntityManager | undefined;
58
+ }
59
+
60
+ type GetColumnNameFunction = (
61
+ metadata: EntityMetadata,
62
+ propertyName: string,
63
+ ) => string;
64
+
65
+ const getColumnName: GetColumnNameFunction = (
66
+ metadata: EntityMetadata,
67
+ propertyName: string,
68
+ ): string => {
69
+ const column: ColumnMetadata | undefined =
70
+ metadata.findColumnWithPropertyName(propertyName);
71
+
72
+ if (!column) {
73
+ throw new Error(
74
+ `Cannot rename a custom field on ${metadata.tableName}: it has no "${propertyName}" column.`,
75
+ );
76
+ }
77
+
78
+ return column.databaseName;
79
+ };
80
+
81
+ export interface MoveCustomFieldValueKeyResult {
82
+ // Records whose value moved from the old name to the new one.
83
+ moved: number;
84
+ // Records that held a value under the new name only, now removed.
85
+ cleared: number;
86
+ }
87
+
88
+ /**
89
+ * Move every value stored under `oldName` to `newName`, on every record of
90
+ * the project in the service's table, and clear what records that hold
91
+ * nothing under `oldName` have under `newName`.
92
+ *
93
+ * Only records whose bag is a JSON object holding one of the two names are
94
+ * written. A value the record already held under `newName` is replaced by
95
+ * the one under `oldName`, or removed when there is none: the renamed
96
+ * field's answer is the only one that counts. One statement, so no reader
97
+ * sees the values half moved.
98
+ */
99
+ export const moveCustomFieldValueKey: (
100
+ input: MoveCustomFieldValueKeyInput,
101
+ ) => Promise<MoveCustomFieldValueKeyResult> = async (
102
+ input: MoveCustomFieldValueKeyInput,
103
+ ): Promise<MoveCustomFieldValueKeyResult> => {
104
+ if (!input.oldName || !input.newName || input.oldName === input.newName) {
105
+ return { moved: 0, cleared: 0 };
106
+ }
107
+
108
+ const repository: Repository<BaseModel> = input.service.getRepository();
109
+ const metadata: EntityMetadata = repository.metadata;
110
+ const customFieldsColumn: string = getColumnName(metadata, "customFields");
111
+ const projectIdColumn: string = getColumnName(metadata, "projectId");
112
+
113
+ /*
114
+ * In a CTE so the statement answers with the rows it wrote: TypeORM hands
115
+ * back a top-level UPDATE as [rows, rowCount] whatever happened. RETURNING
116
+ * reads the row as written, so a record holds the new name afterwards
117
+ * exactly when its value was moved there.
118
+ *
119
+ * jsonb_typeof guards the operators: on a jsonb array `-` and `?` act on
120
+ * the array's string elements, and a bag that is not an object is not a
121
+ * bag of named values to rename.
122
+ */
123
+ const sql: string = `WITH "renamed" AS (
124
+ UPDATE "${metadata.tableName}"
125
+ SET "${customFieldsColumn}" = CASE
126
+ WHEN jsonb_exists("${customFieldsColumn}", $2::text)
127
+ THEN ("${customFieldsColumn}" - $2::text) || jsonb_build_object($3::text, "${customFieldsColumn}" -> $2::text)
128
+ ELSE "${customFieldsColumn}" - $3::text
129
+ END
130
+ WHERE "${projectIdColumn}" = $1
131
+ AND jsonb_typeof("${customFieldsColumn}") = 'object'
132
+ AND (
133
+ jsonb_exists("${customFieldsColumn}", $2::text)
134
+ OR jsonb_exists("${customFieldsColumn}", $3::text)
135
+ )
136
+ RETURNING jsonb_exists("${customFieldsColumn}", $3::text) AS "moved"
137
+ ) SELECT
138
+ (COUNT(*) FILTER (WHERE "moved"))::int AS "moved",
139
+ (COUNT(*) FILTER (WHERE NOT "moved"))::int AS "cleared"
140
+ FROM "renamed"`;
141
+
142
+ const manager: EntityManager = input.manager || repository.manager;
143
+
144
+ const result: unknown = await manager.query(sql, [
145
+ input.projectId.toString(),
146
+ input.oldName,
147
+ input.newName,
148
+ ]);
149
+
150
+ const row: JSONObject | undefined = Array.isArray(result)
151
+ ? (result[0] as JSONObject | undefined)
152
+ : undefined;
153
+
154
+ return {
155
+ moved: Number(row?.["moved"]) || 0,
156
+ cleared: Number(row?.["cleared"]) || 0,
157
+ };
158
+ };
159
+
160
+ export interface RenameCustomFieldInTableViewsInput {
161
+ projectId: ObjectID;
162
+ // The saved views to look at, by TableView.tableId.
163
+ tableIds: Array<string>;
164
+ oldName: string;
165
+ newName: string;
166
+ }
167
+
168
+ /**
169
+ * Rewrite the saved table views of the project that name the field, so a
170
+ * view keeps its column and its filter chip after the rename. Returns how
171
+ * many views it rewrote.
172
+ *
173
+ * Each view is written with a compare-and-set on the columns it was read
174
+ * with, so a view someone saves at the same moment is left as they saved it
175
+ * rather than half overwritten.
176
+ */
177
+ export const renameCustomFieldInTableViews: (
178
+ input: RenameCustomFieldInTableViewsInput,
179
+ ) => Promise<number> = async (
180
+ input: RenameCustomFieldInTableViewsInput,
181
+ ): Promise<number> => {
182
+ if (
183
+ !input.oldName ||
184
+ !input.newName ||
185
+ input.oldName === input.newName ||
186
+ input.tableIds.length === 0
187
+ ) {
188
+ return 0;
189
+ }
190
+
191
+ const views: Array<TableView> = await TableViewService.findBy({
192
+ query: {
193
+ projectId: input.projectId,
194
+ tableId: QueryHelper.any(input.tableIds),
195
+ },
196
+ select: {
197
+ _id: true,
198
+ query: true,
199
+ facets: true,
200
+ columns: true,
201
+ },
202
+ limit: LIMIT_MAX,
203
+ skip: 0,
204
+ props: {
205
+ isRoot: true,
206
+ },
207
+ });
208
+
209
+ let renamedCount: number = 0;
210
+
211
+ for (const view of views) {
212
+ const current: CustomFieldSavedViewState = {
213
+ query: (view.query as unknown as JSONObject | undefined) ?? null,
214
+ facets: view.facets ?? null,
215
+ columns: view.columns ?? null,
216
+ };
217
+
218
+ const renamed: RenamedCustomFieldSavedViewState =
219
+ renameCustomFieldInSavedView({
220
+ view: current,
221
+ oldName: input.oldName,
222
+ newName: input.newName,
223
+ });
224
+
225
+ if (!renamed.hasChanged || !view.id) {
226
+ continue;
227
+ }
228
+
229
+ const data: Record<string, unknown> = {};
230
+ const expectedData: Record<string, unknown> = {};
231
+
232
+ for (const key of Object.keys(renamed.changes) as Array<
233
+ keyof CustomFieldSavedViewState
234
+ >) {
235
+ data[key] = renamed.changes[key];
236
+ expectedData[key] = current[key];
237
+ }
238
+
239
+ await TableViewService.updateColumnsByIdWithoutHooks({
240
+ id: view.id,
241
+ data: data as never,
242
+ expectedData: expectedData as never,
243
+ skipUpdateDateColumn: true,
244
+ });
245
+
246
+ renamedCount++;
247
+ }
248
+
249
+ return renamedCount;
250
+ };
251
+
252
+ export interface RenameCustomFieldInput {
253
+ projectId: ObjectID;
254
+ oldName: string;
255
+ newName: string;
256
+ // Every service whose table stores values under the field's name.
257
+ valueServices: Array<DatabaseService<any>>;
258
+ // The saved views of tables that show the field.
259
+ tableViewIds: Array<string>;
260
+ // How the field is named in logs, e.g. "incident custom field".
261
+ definitionName: string;
262
+ /*
263
+ * Called when the values could not be moved, and are all still under the
264
+ * old name, before the failure is thrown: the caller gives the field its
265
+ * old name back, so the values stay in view (see renameCustomField).
266
+ */
267
+ onValuesNotMoved?: (() => Promise<void>) | undefined;
268
+ }
269
+
270
+ export interface RenameCustomFieldResult {
271
+ movedRecordsByTable: Record<string, number>;
272
+ // Records whose stale value under the new name was removed, by table.
273
+ clearedRecordsByTable: Record<string, number>;
274
+ renamedTableViews: number;
275
+ }
276
+
277
+ /**
278
+ * Everything a rename has to move: the stored values in each table, then the
279
+ * saved views.
280
+ *
281
+ * The values move in one transaction across the tables, so either every
282
+ * table holds them under the new name or none does. That matters because
283
+ * the move also clears stale values under the new name: had one table moved
284
+ * and another not, renaming the field back would clear the values the
285
+ * second table still held under the old name. When the transaction fails,
286
+ * onValuesNotMoved runs - the caller puts the field's old name back, so the
287
+ * field and its values agree again - and the failure is thrown. A saved view
288
+ * that could not be rewritten only loses the field's column or filter, and
289
+ * throws too.
290
+ */
291
+ export const renameCustomField: (
292
+ input: RenameCustomFieldInput,
293
+ ) => Promise<RenameCustomFieldResult> = async (
294
+ input: RenameCustomFieldInput,
295
+ ): Promise<RenameCustomFieldResult> => {
296
+ const result: RenameCustomFieldResult = {
297
+ movedRecordsByTable: {},
298
+ clearedRecordsByTable: {},
299
+ renamedTableViews: 0,
300
+ };
301
+
302
+ if (!input.oldName || !input.newName || input.oldName === input.newName) {
303
+ return result;
304
+ }
305
+
306
+ const firstService: DatabaseService<any> | undefined = input.valueServices[0];
307
+
308
+ if (firstService) {
309
+ try {
310
+ await firstService
311
+ .getRepository()
312
+ .manager.transaction(async (manager: EntityManager): Promise<void> => {
313
+ for (const service of input.valueServices) {
314
+ const tableName: string =
315
+ service.getModel().tableName ||
316
+ service.getRepository().metadata.name;
317
+
318
+ const moved: MoveCustomFieldValueKeyResult =
319
+ await moveCustomFieldValueKey({
320
+ service: service,
321
+ projectId: input.projectId,
322
+ oldName: input.oldName,
323
+ newName: input.newName,
324
+ manager: manager,
325
+ });
326
+
327
+ result.movedRecordsByTable[tableName] = moved.moved;
328
+ result.clearedRecordsByTable[tableName] = moved.cleared;
329
+ }
330
+ });
331
+ } catch (err) {
332
+ logger.error(
333
+ `Could not move ${input.definitionName} values from ${JSON.stringify(
334
+ input.oldName,
335
+ )} to ${JSON.stringify(input.newName)}; none were moved.`,
336
+ {
337
+ projectId: input.projectId.toString(),
338
+ } as LogAttributes,
339
+ );
340
+
341
+ if (input.onValuesNotMoved) {
342
+ try {
343
+ await input.onValuesNotMoved();
344
+ } catch (restoreError) {
345
+ logger.error(restoreError, {
346
+ projectId: input.projectId.toString(),
347
+ } as LogAttributes);
348
+ }
349
+ }
350
+
351
+ throw err;
352
+ }
353
+ }
354
+
355
+ result.renamedTableViews = await renameCustomFieldInTableViews({
356
+ projectId: input.projectId,
357
+ tableIds: input.tableViewIds,
358
+ oldName: input.oldName,
359
+ newName: input.newName,
360
+ });
361
+
362
+ logger.info(
363
+ `Renamed ${input.definitionName} values from ${JSON.stringify(
364
+ input.oldName,
365
+ )} to ${JSON.stringify(input.newName)}: ${JSON.stringify(
366
+ result.movedRecordsByTable,
367
+ )} records moved, ${JSON.stringify(
368
+ result.clearedRecordsByTable,
369
+ )} stale values under the new name cleared, ${
370
+ result.renamedTableViews
371
+ } saved views.`,
372
+ {
373
+ projectId: input.projectId.toString(),
374
+ } as LogAttributes,
375
+ );
376
+
377
+ return result;
378
+ };
@@ -15,9 +15,10 @@ import logger from "../Logger";
15
15
  * It started life guarding external Data Source connections — hence the
16
16
  * file's home — but the same policy now covers every sink where a project
17
17
  * member picks the host and a self-hosted install may legitimately point at
18
- * something internal: LLM providers (self-hosted Ollama/vLLM), SMTP OAuth
19
- * token endpoints, status page / dashboard domain verification, OIDC
20
- * discovery and Runbook HTTP steps. Sinks that can only ever be third-party
18
+ * something internal: LLM providers (self-hosted Ollama/vLLM), SMTP servers
19
+ * (project SMTP settings and the workflow Send Email step), SMTP OAuth token
20
+ * endpoints, status page / dashboard domain verification, OIDC discovery and
21
+ * Runbook HTTP steps. Sinks that can only ever be third-party
21
22
  * SaaS (Slack, Teams, subscriber webhooks) use SSRFProtection instead, which
22
23
  * blocks private ranges unconditionally.
23
24
  *
@@ -78,10 +79,21 @@ export interface EgressGuardOptions {
78
79
  */
79
80
  privateNetworkHint?: string | undefined;
80
81
  /*
81
- * Detailed DNS failures and address-policy reasons are useful to operators,
82
- * but tenant-facing callers can compare them to enumerate internal names.
83
- * Defaults to true for backwards compatibility; shared-probe monitor
84
- * requests set it to false and receive one indistinguishable failure.
82
+ * Whether a refused HOSTNAME may say why: which address it resolved to and
83
+ * which policy refused it, or the resolver's own error. That is exactly what
84
+ * an operator needs, and exactly what a tenant must not get — trying names
85
+ * like `redis` or `kubernetes.default.svc.cluster.local` and comparing
86
+ * "resolves to 10.1.2.3" with "could not resolve" maps the internal network
87
+ * without a socket ever being opened. With false, every resolve-path refusal
88
+ * is one sentence ("<Label> host X could not be reached.") and the precise
89
+ * cause goes to the debug log.
90
+ *
91
+ * Undefined ⇒ shouldIncludeResolutionDetail(): detail on a self-hosted
92
+ * install, where whoever configures the target also runs the network; none
93
+ * wherever shouldBlockPrivateAddresses() is true, i.e. multi-tenant SaaS or
94
+ * an operator who asked for SaaS policy. Shared-probe monitor requests pass
95
+ * false outright, whatever the deployment. Literal IPs are unaffected: their
96
+ * refusal echoes only what the caller typed.
85
97
  */
86
98
  includeResolvedAddressInError?: boolean | undefined;
87
99
  /*
@@ -196,6 +208,21 @@ export default class DataSourceEgressGuard {
196
208
  return process.env["BILLING_ENABLED"] === "true";
197
209
  }
198
210
 
211
+ /*
212
+ * Default for EgressGuardOptions.includeResolvedAddressInError, and for the
213
+ * equivalent switch on SSRFProtection. It keys off the private-address
214
+ * POLICY of the deployment, not off any per-call override of it: the oracle
215
+ * exists because the person choosing the target is not trusted with the
216
+ * network's layout, and that is a property of the deployment. So a caller
217
+ * that loosens blockPrivateAddresses on SaaS still gets no detail unless it
218
+ * asks for it explicitly.
219
+ */
220
+ public static shouldIncludeResolutionDetail(
221
+ includeResolvedAddressInError?: boolean | undefined,
222
+ ): boolean {
223
+ return includeResolvedAddressInError ?? !this.shouldBlockPrivateAddresses();
224
+ }
225
+
199
226
  private static ipv4ToInt(ip: string): number {
200
227
  const parts: Array<string> = ip.split(".");
201
228
  let value: number = 0;
@@ -672,15 +699,19 @@ export default class DataSourceEgressGuard {
672
699
  return this.defaultResolve(host, options);
673
700
  });
674
701
 
702
+ const includeDetail: boolean = this.shouldIncludeResolutionDetail(
703
+ options?.includeResolvedAddressInError,
704
+ );
705
+
675
706
  let addresses: Array<ResolvedAddress> = [];
676
707
  try {
677
708
  addresses = await resolveFunction(bareHostname);
678
709
  } catch (error) {
679
- if (options?.includeResolvedAddressInError === false) {
710
+ if (!includeDetail) {
680
711
  /*
681
712
  * The cause is destroyed for the caller by design, so log it here:
682
- * this is the only place an operator can still learn whether a
683
- * monitor failed on DNS or on address policy.
713
+ * this is the only place an operator can still learn whether the
714
+ * target failed on DNS or on address policy.
684
715
  */
685
716
  logger.debug(
686
717
  `EgressGuard: could not resolve ${bareHostname} - ${
@@ -701,7 +732,7 @@ export default class DataSourceEgressGuard {
701
732
  }
702
733
 
703
734
  if (addresses.length === 0) {
704
- if (options?.includeResolvedAddressInError === false) {
735
+ if (!includeDetail) {
705
736
  logger.debug(`EgressGuard: ${bareHostname} resolved to no addresses.`);
706
737
  throw new EgressGuardException(
707
738
  `${label} host ${bareHostname} could not be reached.`,
@@ -720,14 +751,14 @@ export default class DataSourceEgressGuard {
720
751
  options,
721
752
  );
722
753
  if (verdict.blocked) {
723
- if (options?.includeResolvedAddressInError === false) {
754
+ if (!includeDetail) {
724
755
  logger.debug(
725
- `EgressGuard: ${bareHostname} resolved to a blocked address - ${verdict.reason}.`,
756
+ `EgressGuard: ${bareHostname} resolved to a blocked address ${resolved.address} - ${verdict.reason}.`,
726
757
  );
727
758
  /*
728
759
  * Reported as Unreachable, NOT AddressBlocked. Sharing one reason
729
- * with the DNS branches above is what stops a tenant on a shared
730
- * probe from using the difference to enumerate internal names.
760
+ * with the DNS branches above is what stops a tenant from using the
761
+ * difference to enumerate internal names.
731
762
  */
732
763
  throw new EgressGuardException(
733
764
  `${label} host ${bareHostname} could not be reached.`,
@@ -798,6 +829,15 @@ export default class DataSourceEgressGuard {
798
829
  * that was checked the address that gets dialed, closing the DNS-rebind
799
830
  * window between validation and connect. TLS still verifies against the
800
831
  * original hostname because SNI is taken from the URL, not from here.
832
+ *
833
+ * It always answers asynchronously, the way dns.lookup does. Node's
834
+ * net/tls connect can fail every pinned address synchronously (a probe
835
+ * with no IPv6 gets EADDRNOTAVAIL or ENETUNREACH from connect() itself),
836
+ * and when the lookup has answered synchronously that destroys the
837
+ * TLSSocket before tls.connect calls setServername on it. The request then
838
+ * throws "Cannot read properties of null (reading 'setServername')" in
839
+ * place of the real connect error, and that error escapes as an unhandled
840
+ * 'error' event on the socket.
801
841
  */
802
842
  public static createPinnedLookup(
803
843
  addresses: Array<ResolvedAddress>,
@@ -823,22 +863,27 @@ export default class DataSourceEgressGuard {
823
863
  `No IPv${wantedFamily} address is available for the validated host.`,
824
864
  );
825
865
  error.code = "ENOTFOUND";
826
- callback(error, "");
866
+ process.nextTick(() => {
867
+ callback(error, "");
868
+ });
827
869
  return;
828
870
  }
829
871
 
830
872
  if (lookupOptions && lookupOptions.all) {
831
- callback(
832
- null,
873
+ const allAddresses: Array<{ address: string; family: number }> =
833
874
  usableAddresses.map((resolved: ResolvedAddress) => {
834
875
  return { address: resolved.address, family: resolved.family };
835
- }),
836
- );
876
+ });
877
+ process.nextTick(() => {
878
+ callback(null, allAddresses);
879
+ });
837
880
  return;
838
881
  }
839
882
 
840
883
  const first: ResolvedAddress = usableAddresses[0]!;
841
- callback(null, first.address, first.family);
884
+ process.nextTick(() => {
885
+ callback(null, first.address, first.family);
886
+ });
842
887
  };
843
888
  }
844
889
 
@@ -0,0 +1,111 @@
1
+ import {
2
+ AggregateColumn,
3
+ AggregateRow,
4
+ } from "../../Types/Database/AggregateBy";
5
+ import AggregateResultUtil from "../../Types/Database/AggregateResultUtil";
6
+ import Dictionary from "../../../Types/Dictionary";
7
+ import EntitySource from "../../../Types/Telemetry/EntitySource";
8
+ import {
9
+ InventoryLiveness,
10
+ getInventoryLivenessSql,
11
+ } from "../../../Types/Telemetry/InventoryLiveness";
12
+
13
+ /*
14
+ * The Inventory Overview's numbers: the five summary tiles and the per-type
15
+ * breakdown.
16
+ *
17
+ * These used to be folded in the browser from one list read capped at
18
+ * LIMIT_PER_PROJECT, so a project past ten thousand items saw tiles and a
19
+ * breakdown describing whichever ten thousand had been seen most recently,
20
+ * with nothing on the page saying so. They are counted in Postgres instead,
21
+ * in ONE grouped statement: the tiles are sums over the same per-type groups
22
+ * the breakdown lists, so the two are views of one snapshot and cannot
23
+ * disagree.
24
+ *
25
+ * Every tile drills into the Items list, and each filter below is the exact
26
+ * narrowing that tile's list applies — the source facet, or the source facet
27
+ * plus the Stale status facet, whose SQL is the same getInventoryLivenessSql
28
+ * the `inventoryStatus` virtual column is built from.
29
+ *
30
+ * Kept apart from InventoryItemService so the dashboard's tile tests and the
31
+ * Postgres test can use the same columns without loading the service.
32
+ */
33
+ export const INVENTORY_OVERVIEW_GROUP_BY: Array<AggregateColumn> = [
34
+ { expression: `"InventoryItem"."entityType"`, alias: "entityType" },
35
+ ];
36
+
37
+ export const INVENTORY_OVERVIEW_SELECT: Array<AggregateColumn> = [
38
+ { expression: `COUNT(*)`, alias: "itemCount" },
39
+ {
40
+ expression: `COUNT(*) FILTER (WHERE "InventoryItem"."source" = '${EntitySource.Discovered}')`,
41
+ alias: "discoveredCount",
42
+ },
43
+ {
44
+ expression: `COUNT(*) FILTER (WHERE "InventoryItem"."source" = '${EntitySource.Inventory}')`,
45
+ alias: "mirroredCount",
46
+ },
47
+ {
48
+ expression: `COUNT(*) FILTER (WHERE "InventoryItem"."source" = '${EntitySource.Manual}')`,
49
+ alias: "manualCount",
50
+ },
51
+ {
52
+ // Only discovered rows can be stale; the shared rule says NotTracked for the rest.
53
+ expression: `COUNT(*) FILTER (WHERE (${getInventoryLivenessSql(`"InventoryItem"`)}) = '${InventoryLiveness.Stale}')`,
54
+ alias: "staleCount",
55
+ },
56
+ ];
57
+
58
+ export interface InventoryOverviewCounts {
59
+ total: number;
60
+ discovered: number;
61
+ mirrored: number;
62
+ manual: number;
63
+ stale: number;
64
+ // Items per entity type, for the category breakdown. Types that counted zero are absent.
65
+ countsByType: Dictionary<number>;
66
+ }
67
+
68
+ /**
69
+ * Sum the per-type groups into the tile counts, and key the groups by type
70
+ * for the breakdown.
71
+ *
72
+ * `total` counts every row, including rows whose source this build does not
73
+ * recognise — they land in none of the three source buckets, which is why
74
+ * those are not expected to sum to the total. A group with no type still
75
+ * counts towards every tile; it is only left out of the breakdown, which has
76
+ * no row to put it in.
77
+ */
78
+ export function readInventoryOverviewGroups(
79
+ rows: Array<AggregateRow>,
80
+ ): InventoryOverviewCounts {
81
+ const counts: InventoryOverviewCounts = {
82
+ total: 0,
83
+ discovered: 0,
84
+ mirrored: 0,
85
+ manual: 0,
86
+ stale: 0,
87
+ countsByType: {},
88
+ };
89
+
90
+ for (const row of rows) {
91
+ const itemCount: number = AggregateResultUtil.toNumber(row, "itemCount");
92
+
93
+ counts.total += itemCount;
94
+ counts.discovered += AggregateResultUtil.toNumber(row, "discoveredCount");
95
+ counts.mirrored += AggregateResultUtil.toNumber(row, "mirroredCount");
96
+ counts.manual += AggregateResultUtil.toNumber(row, "manualCount");
97
+ counts.stale += AggregateResultUtil.toNumber(row, "staleCount");
98
+
99
+ const entityType: string | null = AggregateResultUtil.toStringOrNull(
100
+ row,
101
+ "entityType",
102
+ );
103
+
104
+ if (entityType && itemCount > 0) {
105
+ counts.countsByType[entityType] =
106
+ (counts.countsByType[entityType] || 0) + itemCount;
107
+ }
108
+ }
109
+
110
+ return counts;
111
+ }