@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.
- package/Models/DatabaseModels/Incident.ts +267 -1
- package/Models/DatabaseModels/IncidentCustomField.ts +202 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +30 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +126 -1
- package/Models/DatabaseModels/InventoryItem.ts +23 -12
- package/Models/DatabaseModels/StatusPage.ts +55 -0
- package/Models/DatabaseModels/StatusPageSubscriber.ts +128 -0
- package/Server/API/IncidentAPI.ts +162 -0
- package/Server/API/StatusPageAPI.ts +487 -171
- package/Server/API/StatusPageSubscriberAPI.ts +63 -15
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.ts +217 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.ts +108 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.ts +168 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.ts +44 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
- package/Server/Infrastructure/Semaphore.ts +10 -0
- package/Server/Middleware/IdentityRateLimit.ts +108 -3
- package/Server/Middleware/SubscriberNotificationPreviewRateLimit.ts +237 -0
- package/Server/Middleware/SubscriberNotificationTestSendRateLimit.ts +304 -0
- package/Server/Services/AlertService.ts +32 -36
- package/Server/Services/DatabaseService.ts +93 -10
- package/Server/Services/IncidentAlertService.ts +609 -2
- package/Server/Services/IncidentCustomFieldService.ts +276 -1
- package/Server/Services/IncidentEpisodePublicNoteService.ts +28 -0
- package/Server/Services/IncidentEpisodeService.ts +15 -0
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +27 -1
- package/Server/Services/IncidentPublicNoteService.ts +30 -1
- package/Server/Services/IncidentService.ts +1663 -103
- package/Server/Services/IncidentStateTimelineService.ts +13 -0
- package/Server/Services/IncidentTemplateService.ts +109 -0
- package/Server/Services/InventoryItemService.ts +38 -0
- package/Server/Services/IoTDeviceCredentialService.ts +13 -4
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +30 -1
- package/Server/Services/ScheduledMaintenanceService.ts +118 -64
- package/Server/Services/SmsService.ts +10 -0
- package/Server/Services/StatusPageService.ts +65 -8
- package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +299 -37
- package/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.ts +129 -0
- package/Server/Services/StatusPageSubscriberService.ts +1161 -64
- package/Server/Services/UserNotificationRuleService.ts +55 -53
- package/Server/Services/WorkspaceNotificationSummaryService.ts +38 -20
- package/Server/Types/Markdown.ts +153 -6
- package/Server/Types/Workflow/Components/Email.ts +61 -2
- package/Server/Utils/AffectedResources/LinkedAffectedResources.ts +576 -0
- package/Server/Utils/Alert/AlertStateChangeAuthorization.ts +129 -0
- package/Server/Utils/CustomField/CustomFieldRename.ts +378 -0
- package/Server/Utils/DataSource/EgressGuard.ts +66 -21
- package/Server/Utils/Inventory/InventoryOverviewAggregation.ts +111 -0
- package/Server/Utils/Mail/PinnedSmtpSocket.ts +130 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +10 -0
- package/Server/Utils/Response.ts +31 -0
- package/Server/Utils/SSRFProtection.ts +76 -16
- package/Server/Utils/StatusPage/IncidentStatusPageScope.ts +948 -0
- package/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.ts +656 -0
- package/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.ts +805 -0
- package/Server/Utils/StatusPage/StatusPageExclusion.ts +18 -0
- package/Server/Utils/StatusPage/StatusPageReadAccess.ts +125 -0
- package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.ts +151 -0
- package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.ts +70 -0
- package/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.ts +421 -0
- package/Server/Utils/StatusPage/SubscriberNotificationClaim.ts +107 -0
- package/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.ts +1049 -0
- package/Server/Utils/StatusPage/SubscriberNotificationFanOut.ts +180 -0
- package/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.ts +839 -0
- package/Server/Utils/StatusPage/SubscriberNotificationResendAccess.ts +393 -0
- package/Server/Utils/StatusPage/SubscriberNotificationRunLimit.ts +246 -0
- package/Server/Utils/StatusPage/SubscriberNotificationTiming.ts +133 -0
- package/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.ts +215 -0
- package/Server/Utils/StatusPageResource.ts +51 -20
- package/Server/Utils/Topology/TopologyConcurrencyLimiter.ts +229 -0
- package/Server/Utils/Topology/TopologyQueries.ts +1350 -0
- package/Server/Utils/Topology/TopologyRequest.ts +463 -0
- package/Server/Utils/Topology/TopologyResponseCache.ts +183 -0
- package/Server/Utils/Topology/TopologySql.ts +1024 -0
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +10 -0
- package/Server/Utils/Workflow/OAuth2TokenClient.ts +10 -0
- package/Server/Views/Partials/SensitiveUrlToken.ejs +8 -5
- package/Tests/App/Accounts/RegisterVerifyEmail.test.tsx +748 -0
- package/Tests/App/Accounts/ResendVerificationEmail.test.tsx +1222 -0
- package/Tests/App/Accounts/VerificationEmailResendUtils.test.ts +797 -0
- package/Tests/App/Accounts/VerifyEmailPending.test.tsx +538 -0
- package/Tests/App/Accounts/VerifyEmailResend.test.tsx +779 -0
- package/Tests/App/Dashboard/AcknowledgeAlertsOnDeclare.test.ts +369 -0
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +1 -1
- package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +510 -123
- package/Tests/App/Dashboard/AlertsTableAffectedResources.test.tsx +490 -0
- package/Tests/App/Dashboard/ChangeAlertStateDeclareIncident.test.tsx +886 -0
- package/Tests/App/Dashboard/CreateReviewStepRoleSummary.test.tsx +1250 -0
- package/Tests/App/Dashboard/CreateReviewStepSelectionSummary.test.tsx +738 -0
- package/Tests/App/Dashboard/CustomFieldsSettingsIncidentOptions.test.tsx +357 -0
- package/Tests/App/Dashboard/DeclareIncidentFromAlert.test.ts +417 -0
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +1948 -229
- package/Tests/App/Dashboard/EntityDetailPanelLifecycle.test.tsx +493 -0
- package/Tests/App/Dashboard/EntityDetailPanelNavigation.test.tsx +439 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +776 -0
- package/Tests/App/Dashboard/EventNotesPages.test.tsx +119 -0
- package/Tests/App/Dashboard/EventNotesUtil.test.ts +116 -17
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +534 -6
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +798 -2
- package/Tests/App/Dashboard/FetchStateAndSeverityElements.test.tsx +669 -0
- package/Tests/App/Dashboard/FetchUsers.test.tsx +230 -0
- package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +91 -1
- package/Tests/App/Dashboard/IncidentCreateAcknowledgeAlerts.test.tsx +1611 -0
- package/Tests/App/Dashboard/IncidentCreateDetailsStep.test.tsx +643 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +8 -1
- package/Tests/App/Dashboard/IncidentCreateStatusPageScope.test.tsx +601 -0
- package/Tests/App/Dashboard/IncidentCustomFieldTemplateVariables.test.tsx +386 -0
- package/Tests/App/Dashboard/IncidentNoteTemplatePlaceholders.test.tsx +124 -0
- package/Tests/App/Dashboard/IncidentNoteTemplateVariablesLoader.test.ts +305 -0
- package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +112 -0
- package/Tests/App/Dashboard/IncidentSettingsRenotifyOnPublish.test.tsx +674 -0
- package/Tests/App/Dashboard/IncidentSettingsStatusPageScope.test.tsx +1051 -0
- package/Tests/App/Dashboard/IncidentTemplateCustomFields.test.tsx +384 -0
- package/Tests/App/Dashboard/IncidentTemplateStatusPageScopeCard.test.tsx +215 -0
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +1365 -57
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +964 -23
- package/Tests/App/Dashboard/InventoryRelationships.test.tsx +885 -0
- package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +113 -1
- package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +201 -15
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +508 -36
- package/Tests/App/Dashboard/SubscriberAudienceSummary.test.tsx +512 -0
- package/Tests/App/Dashboard/SubscriberNotificationPreviewModal.test.tsx +837 -0
- package/Tests/App/Dashboard/SubscriberNotificationStatusLabel.test.tsx +88 -0
- package/Tests/App/Dashboard/SubscriberNotificationStatusResend.test.tsx +473 -0
- package/Tests/App/Dashboard/SubscriberTemplateLivePreview.test.tsx +196 -0
- package/Tests/App/Dashboard/TeamAddedSubscribersUnsubscribedNotice.test.tsx +248 -0
- package/Tests/App/Dashboard/TopologyDataLifecycle.test.tsx +583 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +982 -218
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +818 -114
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +64 -3
- package/Tests/App/StatusPage/StatusPageUnsubscribePage.test.tsx +412 -0
- package/Tests/Models/IncidentCustomFieldApiSchemaContract.test.ts +217 -0
- package/Tests/Models/IncidentCustomFieldCreateSettingsColumns.test.ts +252 -0
- package/Tests/Models/StatusPageSubscriberUnsubscribeColumns.test.ts +218 -0
- package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +7 -0
- package/Tests/Server/API/IncidentSubscriberAudienceAPI.test.ts +1408 -0
- package/Tests/Server/API/StatusPageIncidentScope.test.ts +1868 -0
- package/Tests/Server/API/StatusPageIncidentScopePostgres.test.ts +790 -0
- package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +10 -1
- package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +206 -18
- package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +14 -2
- package/Tests/Server/API/StatusPageSubscriberCreateResponse.test.ts +217 -0
- package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +103 -2
- package/Tests/Server/API/StatusPageUnsubscribeAPI.test.ts +396 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentStatusPageScopeMigration.test.ts +395 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentTemplateStatusPageScopeFlagMigration.test.ts +150 -0
- package/Tests/Server/Infrastructure/Postgres/AddSubscriberNotificationClaimedAtMigration.test.ts +156 -0
- package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +90 -21
- package/Tests/Server/Infrastructure/Postgres/SkipHiddenIncidentCreatedNotificationsMigration.test.ts +410 -0
- package/Tests/Server/Middleware/IdentityRateLimit.test.ts +551 -1
- package/Tests/Server/Middleware/SubscriberNotificationPreviewRateLimit.test.ts +238 -0
- package/Tests/Server/Middleware/SubscriberNotificationTestSendRateLimit.test.ts +245 -0
- package/Tests/Server/Services/AddStatusPageSubscriberUnsubscribeTokenMigration.test.ts +152 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +221 -36
- package/Tests/Server/Services/DatabaseServiceCompareAndSetColumns.test.ts +191 -0
- package/Tests/Server/Services/DomainService.test.ts +525 -0
- package/Tests/Server/Services/IncidentAlertAcknowledgeOnDeclare.test.ts +2630 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +1625 -1
- package/Tests/Server/Services/IncidentCreatedRenotifyOnPublish.test.ts +681 -0
- package/Tests/Server/Services/IncidentCreatedResend.test.ts +775 -0
- package/Tests/Server/Services/IncidentCustomFieldRenamePostgres.test.ts +713 -0
- package/Tests/Server/Services/IncidentCustomFieldService.test.ts +751 -0
- package/Tests/Server/Services/IncidentCustomFieldValueValidation.test.ts +556 -0
- package/Tests/Server/Services/IncidentDeclareAcknowledgeAlerts.test.ts +2189 -0
- package/Tests/Server/Services/IncidentStatusPageScope.test.ts +2971 -0
- package/Tests/Server/Services/IncidentStatusPageScopeFeed.test.ts +131 -0
- package/Tests/Server/Services/IncidentStatusPageScopePostgres.test.ts +625 -0
- package/Tests/Server/Services/IncidentTemplateCustomFieldsCopy.test.ts +311 -0
- package/Tests/Server/Services/IncidentTemplateStatusPageScope.test.ts +363 -0
- package/Tests/Server/Services/InventoryItemServiceOverviewCounts.test.ts +345 -0
- package/Tests/Server/Services/InventoryOverviewPostgres.test.ts +254 -0
- package/Tests/Server/Services/IoTDeviceCredentialService.test.ts +819 -0
- package/Tests/Server/Services/LinkedAffectedResourcesCreatedFeed.test.ts +420 -0
- package/Tests/Server/Services/PublicNoteEditFeedEventType.test.ts +213 -0
- package/Tests/Server/Services/PublicNoteResendAccess.test.ts +994 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +289 -9
- package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +92 -36
- package/Tests/Server/Services/SmsServiceFailIfNotSent.test.ts +67 -0
- package/Tests/Server/Services/StatusPageReportIncidentCounts.test.ts +610 -0
- package/Tests/Server/Services/StatusPageSubscriberAudienceCounts.test.ts +201 -0
- package/Tests/Server/Services/StatusPageSubscriberAudienceCountsPostgres.test.ts +271 -0
- package/Tests/Server/Services/StatusPageSubscriberConfirmationTemplateEscaping.test.ts +200 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationLogRedaction.test.ts +54 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +37 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateIncidentRecordAccess.test.ts +772 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookup.test.ts +506 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookupPostgres.test.ts +261 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +21 -5
- package/Tests/Server/Services/StatusPageSubscriberUnsubscribe.test.ts +1618 -0
- package/Tests/Server/Services/StatusPageSubscriberUnsubscribeLinkSenders.test.ts +373 -0
- package/Tests/Server/Services/StatusPageSubscriberUnsubscribePostgres.test.ts +388 -0
- package/Tests/Server/Services/SubscriberNotificationInFlightRequeue.test.ts +500 -0
- package/Tests/Server/Types/MarkdownEmailLinks.test.ts +320 -0
- package/Tests/Server/Types/Workflow/Components/Email.test.ts +491 -1
- package/Tests/Server/Types/Workflow/Components/EmailSmtpPinning.test.ts +398 -0
- package/Tests/Server/Utils/AffectedResources/LinkedAffectedResources.test.ts +858 -0
- package/Tests/Server/Utils/Alert/AlertStateChangeAuthorization.test.ts +1172 -0
- package/Tests/Server/Utils/CustomField/CustomFieldRename.test.ts +586 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +246 -10
- package/Tests/Server/Utils/DataSource/EgressGuardDeploymentConfig.test.ts +226 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +131 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +4 -0
- package/Tests/Server/Utils/EgressPolicyEnvironment.ts +45 -0
- package/Tests/Server/Utils/Mail/PinnedSmtpSocket.test.ts +409 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +23 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +4 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +4 -0
- package/Tests/Server/Utils/SSRFProtectionPrivateNetwork.test.ts +4 -0
- package/Tests/Server/Utils/SSRFProtectionResolutionDetail.test.ts +314 -0
- package/Tests/Server/Utils/StatusPage/IncidentStatusPageScope.test.ts +1699 -0
- package/Tests/Server/Utils/StatusPage/IncidentStatusPageScopeQueriesPostgres.test.ts +508 -0
- package/Tests/Server/Utils/StatusPage/IncidentSubscriberAudienceCallerPermission.test.ts +246 -0
- package/Tests/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.test.ts +1348 -0
- package/Tests/Server/Utils/StatusPage/StatusPageReadAccess.test.ts +221 -0
- package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.test.ts +132 -0
- package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.test.ts +155 -0
- package/Tests/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.test.ts +708 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaim.test.ts +255 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaimPostgres.test.ts +528 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.test.ts +1238 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationFanOut.test.ts +472 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.test.ts +1168 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationRunLimit.test.ts +275 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationTiming.test.ts +131 -0
- package/Tests/Server/Utils/StatusPageResource.test.ts +98 -0
- package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigration.test.ts +386 -0
- package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigrationPostgres.test.ts +430 -0
- package/Tests/Server/Utils/Topology/TopologyActivityParityPostgres.test.ts +279 -0
- package/Tests/Server/Utils/Topology/TopologyConcurrencyLimiter.test.ts +534 -0
- package/Tests/Server/Utils/Topology/TopologyEstateGenerator.ts +624 -0
- package/Tests/Server/Utils/Topology/TopologyJsonResponse.test.ts +90 -0
- package/Tests/Server/Utils/Topology/TopologyQueries.test.ts +1634 -0
- package/Tests/Server/Utils/Topology/TopologyQueriesDifferentialPostgres.test.ts +683 -0
- package/Tests/Server/Utils/Topology/TopologyQueriesPostgres.test.ts +2624 -0
- package/Tests/Server/Utils/Topology/TopologyReference.ts +1018 -0
- package/Tests/Server/Utils/Topology/TopologyRequest.test.ts +643 -0
- package/Tests/Server/Utils/Topology/TopologyResponseCache.test.ts +305 -0
- package/Tests/Server/Utils/Topology/TopologySql.test.ts +973 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +17 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +75 -0
- package/Tests/Types/CustomField/CustomFieldSavedViews.test.ts +247 -0
- package/Tests/Types/CustomField/CustomFieldTemplateValues.test.ts +186 -0
- package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +48 -0
- package/Tests/Types/CustomField/CustomFieldValueFormat.test.ts +215 -0
- package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +343 -0
- package/Tests/Types/CustomField/CustomFieldVariableKey.test.ts +364 -0
- package/Tests/Types/SafeHtml.test.ts +102 -0
- package/Tests/Types/StatusPage/IncidentCreatedRenotify.test.ts +419 -0
- package/Tests/Types/StatusPage/IncidentCreatedResend.test.ts +118 -0
- package/Tests/Types/StatusPage/IncidentScopeAddedPagesNotification.test.ts +558 -0
- package/Tests/Types/StatusPage/IncidentSubscriberAudience.test.ts +284 -0
- package/Tests/Types/StatusPage/StatusPageSubscriberUnsubscribe.test.ts +341 -0
- package/Tests/Types/StatusPage/SubscriberNotificationPreview.test.ts +196 -0
- package/Tests/Types/StatusPage/SubscriberNotificationResend.test.ts +201 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplateCompiler.test.ts +277 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplatePreview.test.ts +179 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +324 -0
- package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +60 -13
- package/Tests/Types/Topology/TopologyTypeRules.test.ts +176 -0
- package/Tests/UI/Components/CustomFields/CustomFieldFormFields.test.ts +432 -0
- package/Tests/UI/Components/CustomFields/CustomFieldModelFormFields.test.tsx +685 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailOrder.test.tsx +469 -0
- package/Tests/UI/Components/Forms/ModelFormCustomFieldInputs.test.tsx +325 -0
- package/Tests/UI/Components/Forms/ModelFormDropdownOptionsRefused.test.tsx +358 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +22 -0
- package/Tests/UI/Monitor/NetworkPathView.test.tsx +289 -0
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +302 -0
- package/Tests/Utils/Incident/IncidentNoteTemplateVariables.test.ts +623 -0
- package/Tests/Utils/Markdown/MarkdownEscape.test.ts +89 -0
- package/Tests/Utils/ProbeNetworkFailureUtil.test.ts +992 -0
- package/Tests/Utils/RequestFailedDetails.test.ts +575 -0
- package/Types/CustomField/CustomFieldOrder.ts +55 -0
- package/Types/CustomField/CustomFieldSavedViews.ts +225 -0
- package/Types/CustomField/CustomFieldTemplateMerge.ts +71 -0
- package/Types/CustomField/CustomFieldType.ts +14 -0
- package/Types/CustomField/CustomFieldValueFormat.ts +161 -0
- package/Types/CustomField/CustomFieldValueValidator.ts +488 -0
- package/Types/CustomField/CustomFieldVariableKey.ts +211 -0
- package/Types/Incident/IncidentAlertLink.ts +19 -0
- package/Types/SafeHtml.ts +93 -0
- package/Types/StatusPage/IncidentCreatedRenotify.ts +224 -0
- package/Types/StatusPage/IncidentCreatedResend.ts +108 -0
- package/Types/StatusPage/IncidentScopeAddedPagesNotification.ts +343 -0
- package/Types/StatusPage/IncidentSubscriberAudience.ts +332 -0
- package/Types/StatusPage/StatusPageSubscriberUnsubscribe.ts +405 -0
- package/Types/StatusPage/SubscriberNotificationInterruption.ts +32 -0
- package/Types/StatusPage/SubscriberNotificationPreview.ts +322 -0
- package/Types/StatusPage/SubscriberNotificationResend.ts +132 -0
- package/Types/StatusPage/SubscriberNotificationTemplateCompiler.ts +180 -0
- package/Types/StatusPage/SubscriberNotificationTemplatePreview.ts +301 -0
- package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +217 -4
- package/Types/StatusPage/SubscriberUpdateNotification.ts +32 -11
- package/Types/Telemetry/InventoryLiveness.ts +26 -0
- package/Types/Topology/TopologyApi.ts +428 -0
- package/Types/Topology/TopologyTypeRules.ts +191 -0
- package/UI/Components/CustomFields/CustomFieldFormFields.ts +317 -0
- package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +395 -0
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +95 -55
- package/UI/Components/Forms/ModelForm.tsx +70 -8
- package/UI/Components/Forms/Validation.ts +1 -1
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +2 -4
- package/UI/Components/ModelTable/AnalyticsModelTable.tsx +2 -6
- package/UI/Components/ModelTable/BaseModelTable.tsx +9 -8
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +14 -1
- package/UI/Components/ModelTable/ModelTable.tsx +6 -7
- package/UI/Utils/SensitiveUrlToken.ts +10 -5
- package/Utils/API.ts +247 -2
- package/Utils/Incident/IncidentFromAlerts.ts +78 -0
- package/Utils/Incident/IncidentNoteTemplateVariables.ts +304 -0
- package/Utils/Markdown/MarkdownEscape.ts +65 -0
- package/Utils/ProbeNetworkFailureUtil.ts +673 -0
- package/build/dist/Models/DatabaseModels/Incident.js +267 -1
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +207 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +31 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +124 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.js +20 -11
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +56 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +131 -0
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +100 -1
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +417 -176
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageSubscriberAPI.js +52 -13
- package/build/dist/Server/API/StatusPageSubscriberAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js +165 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js +57 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +3 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/IdentityRateLimit.js +89 -3
- package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
- package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js +149 -0
- package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js +190 -0
- package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AlertService.js +21 -33
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +56 -7
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +457 -3
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +204 -8
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +14 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +26 -0
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +26 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +1148 -42
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +83 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +31 -0
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceCredentialService.js +12 -5
- package/build/dist/Server/Services/IoTDeviceCredentialService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +26 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +84 -57
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/SmsService.js +2 -22
- package/build/dist/Server/Services/SmsService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +47 -9
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +237 -32
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js +109 -0
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +925 -99
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +55 -51
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +42 -25
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +110 -6
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Email.js +55 -6
- package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js +405 -0
- package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js.map +1 -0
- package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js +112 -0
- package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldRename.js +211 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldRename.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +41 -12
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js +81 -0
- package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js.map +1 -0
- package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js +101 -0
- package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +30 -0
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +48 -6
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js +631 -0
- package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js +403 -0
- package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js +451 -0
- package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js +13 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js +91 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js +101 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js +47 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js +273 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js +73 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js +722 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js +102 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js +527 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js +278 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js +137 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js +103 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js +114 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageResource.js +39 -7
- package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
- package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js +178 -0
- package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologyQueries.js +884 -0
- package/build/dist/Server/Utils/Topology/TopologyQueries.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologyRequest.js +275 -0
- package/build/dist/Server/Utils/Topology/TopologyRequest.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologyResponseCache.js +146 -0
- package/build/dist/Server/Utils/Topology/TopologyResponseCache.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologySql.js +688 -0
- package/build/dist/Server/Utils/Topology/TopologySql.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +1 -0
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +3 -0
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldOrder.js +36 -0
- package/build/dist/Types/CustomField/CustomFieldOrder.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldSavedViews.js +135 -0
- package/build/dist/Types/CustomField/CustomFieldSavedViews.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js +27 -0
- package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldType.js +12 -0
- package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldValueFormat.js +126 -0
- package/build/dist/Types/CustomField/CustomFieldValueFormat.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js +280 -0
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldVariableKey.js +150 -0
- package/build/dist/Types/CustomField/CustomFieldVariableKey.js.map +1 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js +17 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -1
- package/build/dist/Types/SafeHtml.js +84 -0
- package/build/dist/Types/SafeHtml.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js +117 -0
- package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentCreatedResend.js +86 -0
- package/build/dist/Types/StatusPage/IncidentCreatedResend.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js +246 -0
- package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js +183 -0
- package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js.map +1 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js +277 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js +27 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js +190 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationResend.js +102 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationResend.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js +97 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js +175 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +144 -4
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -1
- package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +29 -9
- package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -1
- package/build/dist/Types/Telemetry/InventoryLiveness.js +23 -0
- package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -1
- package/build/dist/Types/Topology/TopologyApi.js +55 -0
- package/build/dist/Types/Topology/TopologyApi.js.map +1 -0
- package/build/dist/Types/Topology/TopologyTypeRules.js +165 -0
- package/build/dist/Types/Topology/TopologyTypeRules.js.map +1 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js +169 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js.map +1 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +212 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +64 -49
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +39 -5
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +1 -1
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/AnalyticsModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +13 -1
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +10 -5
- package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -1
- package/build/dist/Utils/API.js +177 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +38 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js +155 -0
- package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js.map +1 -0
- package/build/dist/Utils/Markdown/MarkdownEscape.js +48 -0
- package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -1
- package/build/dist/Utils/ProbeNetworkFailureUtil.js +460 -0
- package/build/dist/Utils/ProbeNetworkFailureUtil.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import SafeHtml from "../SafeHtml";
|
|
2
|
+
import StatusPageSubscriberNotificationEventType from "./StatusPageSubscriberNotificationEventType";
|
|
3
|
+
import StatusPageSubscriberNotificationMethod from "./StatusPageSubscriberNotificationMethod";
|
|
4
|
+
import SubscriberNotificationPreview from "./SubscriberNotificationPreview";
|
|
5
|
+
import SubscriberNotificationTemplateCompiler, {
|
|
6
|
+
SubscriberNotificationEmailBodyTemplateVariables,
|
|
7
|
+
SubscriberNotificationTextTemplateVariables,
|
|
8
|
+
} from "./SubscriberNotificationTemplateCompiler";
|
|
9
|
+
import SubscriberNotificationTemplateVariables, {
|
|
10
|
+
SubscriberNotificationTemplateDynamicVariable,
|
|
11
|
+
SubscriberNotificationTemplateVariable,
|
|
12
|
+
} from "./SubscriberNotificationTemplateVariables";
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* The live preview of a custom subscriber notification template while it is
|
|
16
|
+
* written: the template filled with sample values, by the compiler the
|
|
17
|
+
* subscriber jobs fill it with (SubscriberNotificationTemplateCompiler).
|
|
18
|
+
*
|
|
19
|
+
* Each value comes in the format its channel gets it in, as the jobs give
|
|
20
|
+
* them: an email body gets HTML for the variables that are HTML there (a
|
|
21
|
+
* description, a note, the resource list) and every other value escaped;
|
|
22
|
+
* the subject and SMS get plain text; Slack and Teams get Markdown. So what
|
|
23
|
+
* the preview shows is what a template does with real values - including a
|
|
24
|
+
* placeholder the event does not offer, which is sent as written and is
|
|
25
|
+
* listed as such.
|
|
26
|
+
*
|
|
27
|
+
* The report template is the exception: it is rendered by the full
|
|
28
|
+
* Handlebars engine with a structured report, which placeholders cannot
|
|
29
|
+
* stand in for, so it has no preview.
|
|
30
|
+
*
|
|
31
|
+
* Kept free of React and of the server, so the dashboard renders it and
|
|
32
|
+
* tests can read it directly.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
// One sample value, in the three forms the channels take.
|
|
36
|
+
interface SampleValue {
|
|
37
|
+
text: string;
|
|
38
|
+
markdown?: string | undefined;
|
|
39
|
+
// For a variable that is HTML in an email body.
|
|
40
|
+
html?: string | undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const SAMPLE_STATUS_PAGE_URL: string = "https://status.example.com";
|
|
44
|
+
|
|
45
|
+
const SAMPLE_VALUES: Record<string, SampleValue> = {
|
|
46
|
+
statusPageName: { text: "Acme Status" },
|
|
47
|
+
statusPageUrl: { text: SAMPLE_STATUS_PAGE_URL },
|
|
48
|
+
unsubscribeUrl: {
|
|
49
|
+
text: SubscriberNotificationPreview.getPreviewUnsubscribeUrl(
|
|
50
|
+
SAMPLE_STATUS_PAGE_URL,
|
|
51
|
+
),
|
|
52
|
+
},
|
|
53
|
+
confirmationUrl: {
|
|
54
|
+
text: `${SAMPLE_STATUS_PAGE_URL}/confirm-subscription/sample`,
|
|
55
|
+
},
|
|
56
|
+
manageSubscriptionUrl: {
|
|
57
|
+
text: `${SAMPLE_STATUS_PAGE_URL}/update-subscription/sample`,
|
|
58
|
+
},
|
|
59
|
+
detailsUrl: { text: `${SAMPLE_STATUS_PAGE_URL}/incidents/sample` },
|
|
60
|
+
resourcesAffected: {
|
|
61
|
+
text: "Europe: Checkout API; Americas: Payments API",
|
|
62
|
+
html: "Europe: Checkout API<br/>Americas: Payments API",
|
|
63
|
+
},
|
|
64
|
+
incidentTitle: { text: "Checkout requests are failing" },
|
|
65
|
+
incidentDescription: {
|
|
66
|
+
text: "Customers in Europe cannot complete a checkout. We are investigating.",
|
|
67
|
+
markdown:
|
|
68
|
+
"Customers in **Europe** cannot complete a checkout. We are investigating.",
|
|
69
|
+
html: "<p>Customers in <strong>Europe</strong> cannot complete a checkout. We are investigating.</p>",
|
|
70
|
+
},
|
|
71
|
+
incidentSeverity: { text: "Major" },
|
|
72
|
+
incidentState: { text: "Identified" },
|
|
73
|
+
incidentLabels: { text: "Europe, Payments" },
|
|
74
|
+
affectedStatusPages: { text: "Acme Status, Acme Europe Status" },
|
|
75
|
+
postedAt: { text: "Sep 27, 2026, 10:30 AM UTC" },
|
|
76
|
+
note: {
|
|
77
|
+
text: "We found the cause and are rolling out a fix. Next update in 30 minutes.",
|
|
78
|
+
markdown:
|
|
79
|
+
"We found the cause and are rolling out a fix. **Next update in 30 minutes.**",
|
|
80
|
+
html: "<p>We found the cause and are rolling out a fix. <strong>Next update in 30 minutes.</strong></p>",
|
|
81
|
+
},
|
|
82
|
+
postmortemNote: {
|
|
83
|
+
text: "A configuration change overloaded the payment gateway. We have added a safeguard.",
|
|
84
|
+
markdown:
|
|
85
|
+
"A configuration change overloaded the payment gateway. We have added a **safeguard**.",
|
|
86
|
+
html: "<p>A configuration change overloaded the payment gateway. We have added a <strong>safeguard</strong>.</p>",
|
|
87
|
+
},
|
|
88
|
+
announcementTitle: { text: "New status page features" },
|
|
89
|
+
announcementDescription: {
|
|
90
|
+
text: "You can now choose which services you hear about.",
|
|
91
|
+
markdown: "You can now choose **which services** you hear about.",
|
|
92
|
+
html: "<p>You can now choose <strong>which services</strong> you hear about.</p>",
|
|
93
|
+
},
|
|
94
|
+
scheduledMaintenanceTitle: { text: "Database upgrade" },
|
|
95
|
+
scheduledMaintenanceDescription: {
|
|
96
|
+
text: "Checkout may be slow for up to ten minutes.",
|
|
97
|
+
markdown: "Checkout may be slow for up to **ten minutes**.",
|
|
98
|
+
html: "<p>Checkout may be slow for up to <strong>ten minutes</strong>.</p>",
|
|
99
|
+
},
|
|
100
|
+
scheduledMaintenanceState: { text: "Scheduled" },
|
|
101
|
+
scheduledStartTime: { text: "Sep 30, 2026, 02:00 AM UTC" },
|
|
102
|
+
scheduledEndTime: { text: "Sep 30, 2026, 03:00 AM UTC" },
|
|
103
|
+
episodeTitle: { text: "Checkout degradation" },
|
|
104
|
+
episodeDescription: {
|
|
105
|
+
text: "Several incidents are affecting checkout.",
|
|
106
|
+
markdown: "Several incidents are affecting **checkout**.",
|
|
107
|
+
html: "<p>Several incidents are affecting <strong>checkout</strong>.</p>",
|
|
108
|
+
},
|
|
109
|
+
episodeSeverity: { text: "Major" },
|
|
110
|
+
episodeState: { text: "Identified" },
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export interface SubscriberNotificationTemplateSampleValues {
|
|
114
|
+
// An email template's body: HTML values as SafeHtml, the rest plain.
|
|
115
|
+
emailBody: SubscriberNotificationEmailBodyTemplateVariables;
|
|
116
|
+
// An email subject, SMS and webhook.
|
|
117
|
+
plainText: SubscriberNotificationTextTemplateVariables;
|
|
118
|
+
// Slack and Microsoft Teams.
|
|
119
|
+
markdown: SubscriberNotificationTextTemplateVariables;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface SubscriberNotificationTemplatePreviewResult {
|
|
123
|
+
// False when this event's templates cannot be previewed (the report).
|
|
124
|
+
isAvailable: boolean;
|
|
125
|
+
// Whether body is HTML (an email template's body).
|
|
126
|
+
isHtml: boolean;
|
|
127
|
+
// An email template's subject, filled in; null for other channels, or none.
|
|
128
|
+
subject: string | null;
|
|
129
|
+
body: string;
|
|
130
|
+
// Placeholders the event does not offer: they are sent as written.
|
|
131
|
+
unknownPlaceholders: Array<string>;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export default class SubscriberNotificationTemplatePreview {
|
|
135
|
+
public static isAvailableForEventType(
|
|
136
|
+
eventType: StatusPageSubscriberNotificationEventType | undefined,
|
|
137
|
+
): boolean {
|
|
138
|
+
return (
|
|
139
|
+
Boolean(eventType) &&
|
|
140
|
+
Object.values(StatusPageSubscriberNotificationEventType).includes(
|
|
141
|
+
eventType!,
|
|
142
|
+
) &&
|
|
143
|
+
eventType !== StatusPageSubscriberNotificationEventType.SubscriberReport
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/*
|
|
148
|
+
* A sample for every variable the event offers, and for each custom field
|
|
149
|
+
* placeholder these templates place ({{customFields.<key>}}), in each
|
|
150
|
+
* channel's format.
|
|
151
|
+
*/
|
|
152
|
+
public static getSampleValues(data: {
|
|
153
|
+
eventType: StatusPageSubscriberNotificationEventType;
|
|
154
|
+
templates: Array<string | null | undefined>;
|
|
155
|
+
}): SubscriberNotificationTemplateSampleValues {
|
|
156
|
+
const values: SubscriberNotificationTemplateSampleValues = {
|
|
157
|
+
emailBody: {},
|
|
158
|
+
plainText: {},
|
|
159
|
+
markdown: {},
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
for (const variable of SubscriberNotificationTemplateVariables.getAvailableVariablesForEventType(
|
|
163
|
+
data.eventType,
|
|
164
|
+
)) {
|
|
165
|
+
this.addSample({
|
|
166
|
+
values: values,
|
|
167
|
+
name: variable.name,
|
|
168
|
+
sample: SAMPLE_VALUES[variable.name] || {
|
|
169
|
+
text: `[${variable.name}]`,
|
|
170
|
+
},
|
|
171
|
+
isHtmlInEmailBody: this.isHtmlInEmailBody(variable),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
for (const name of SubscriberNotificationTemplateCompiler.getPlaceholderNames(
|
|
176
|
+
data.templates,
|
|
177
|
+
)) {
|
|
178
|
+
const dynamicVariable: SubscriberNotificationTemplateDynamicVariable | null =
|
|
179
|
+
SubscriberNotificationTemplateVariables.getDynamicVariableForName(
|
|
180
|
+
data.eventType,
|
|
181
|
+
name,
|
|
182
|
+
);
|
|
183
|
+
|
|
184
|
+
if (!dynamicVariable) {
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
this.addSample({
|
|
189
|
+
values: values,
|
|
190
|
+
name: name,
|
|
191
|
+
sample: {
|
|
192
|
+
text: `Sample ${name.slice(dynamicVariable.prefix.length)}`,
|
|
193
|
+
},
|
|
194
|
+
isHtmlInEmailBody: false,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
return values;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// The template, filled with sample values as its channel would be.
|
|
202
|
+
public static render(data: {
|
|
203
|
+
eventType: StatusPageSubscriberNotificationEventType | undefined;
|
|
204
|
+
notificationMethod: StatusPageSubscriberNotificationMethod | undefined;
|
|
205
|
+
templateBody: string | null | undefined;
|
|
206
|
+
emailSubject?: string | null | undefined;
|
|
207
|
+
}): SubscriberNotificationTemplatePreviewResult {
|
|
208
|
+
const isEmail: boolean =
|
|
209
|
+
data.notificationMethod === StatusPageSubscriberNotificationMethod.Email;
|
|
210
|
+
const templateBody: string = data.templateBody || "";
|
|
211
|
+
const emailSubject: string = (isEmail && data.emailSubject) || "";
|
|
212
|
+
|
|
213
|
+
if (!this.isAvailableForEventType(data.eventType)) {
|
|
214
|
+
return {
|
|
215
|
+
isAvailable: false,
|
|
216
|
+
isHtml: isEmail,
|
|
217
|
+
subject: null,
|
|
218
|
+
body: "",
|
|
219
|
+
unknownPlaceholders: [],
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const eventType: StatusPageSubscriberNotificationEventType =
|
|
224
|
+
data.eventType!;
|
|
225
|
+
|
|
226
|
+
const values: SubscriberNotificationTemplateSampleValues =
|
|
227
|
+
this.getSampleValues({
|
|
228
|
+
eventType: eventType,
|
|
229
|
+
templates: [templateBody, emailSubject],
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const unknownPlaceholders: Array<string> = Array.from(
|
|
233
|
+
SubscriberNotificationTemplateCompiler.getPlaceholderNames([
|
|
234
|
+
templateBody,
|
|
235
|
+
emailSubject,
|
|
236
|
+
]),
|
|
237
|
+
)
|
|
238
|
+
.filter((name: string): boolean => {
|
|
239
|
+
return !SubscriberNotificationTemplateVariables.isVariableOffered(
|
|
240
|
+
eventType,
|
|
241
|
+
name,
|
|
242
|
+
);
|
|
243
|
+
})
|
|
244
|
+
.sort();
|
|
245
|
+
|
|
246
|
+
if (isEmail) {
|
|
247
|
+
return {
|
|
248
|
+
isAvailable: true,
|
|
249
|
+
isHtml: true,
|
|
250
|
+
subject: emailSubject
|
|
251
|
+
? SubscriberNotificationTemplateCompiler.compileTemplate(
|
|
252
|
+
emailSubject,
|
|
253
|
+
values.plainText,
|
|
254
|
+
)
|
|
255
|
+
: null,
|
|
256
|
+
body: SubscriberNotificationTemplateCompiler.compileEmailBodyTemplate(
|
|
257
|
+
templateBody,
|
|
258
|
+
values.emailBody,
|
|
259
|
+
),
|
|
260
|
+
unknownPlaceholders: unknownPlaceholders,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const isMarkdownChannel: boolean =
|
|
265
|
+
data.notificationMethod ===
|
|
266
|
+
StatusPageSubscriberNotificationMethod.Slack ||
|
|
267
|
+
data.notificationMethod ===
|
|
268
|
+
StatusPageSubscriberNotificationMethod.MicrosoftTeams;
|
|
269
|
+
|
|
270
|
+
return {
|
|
271
|
+
isAvailable: true,
|
|
272
|
+
isHtml: false,
|
|
273
|
+
subject: null,
|
|
274
|
+
body: SubscriberNotificationTemplateCompiler.compileTemplate(
|
|
275
|
+
templateBody,
|
|
276
|
+
isMarkdownChannel ? values.markdown : values.plainText,
|
|
277
|
+
),
|
|
278
|
+
unknownPlaceholders: unknownPlaceholders,
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private static isHtmlInEmailBody(
|
|
283
|
+
variable: SubscriberNotificationTemplateVariable,
|
|
284
|
+
): boolean {
|
|
285
|
+
return variable.isHtmlInEmailBody === true;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
private static addSample(data: {
|
|
289
|
+
values: SubscriberNotificationTemplateSampleValues;
|
|
290
|
+
name: string;
|
|
291
|
+
sample: SampleValue;
|
|
292
|
+
isHtmlInEmailBody: boolean;
|
|
293
|
+
}): void {
|
|
294
|
+
data.values.plainText[data.name] = data.sample.text;
|
|
295
|
+
data.values.markdown[data.name] = data.sample.markdown || data.sample.text;
|
|
296
|
+
data.values.emailBody[data.name] =
|
|
297
|
+
data.isHtmlInEmailBody && data.sample.html
|
|
298
|
+
? SafeHtml.fromTrustedHtml(data.sample.html)
|
|
299
|
+
: data.sample.text;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
@@ -1,11 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CUSTOM_FIELD_TEMPLATE_VARIABLE_PREFIX,
|
|
3
|
+
isValidCustomFieldVariableKey,
|
|
4
|
+
} from "../CustomField/CustomFieldVariableKey";
|
|
1
5
|
import BadDataException from "../Exception/BadDataException";
|
|
2
6
|
import StatusPageSubscriberNotificationEventType from "./StatusPageSubscriberNotificationEventType";
|
|
7
|
+
import SubscriberNotificationTemplateCompiler from "./SubscriberNotificationTemplateCompiler";
|
|
3
8
|
|
|
4
9
|
export interface SubscriberNotificationTemplateVariable {
|
|
5
10
|
name: string;
|
|
6
11
|
description: string;
|
|
12
|
+
/*
|
|
13
|
+
* In the body of an EMAIL template this variable is HTML already (rendered
|
|
14
|
+
* Markdown, or the resource list built from escaped names) and goes in as
|
|
15
|
+
* it is. Every other variable is plain text there, and is HTML-escaped (see
|
|
16
|
+
* SubscriberNotificationTemplateCompiler). A subject, SMS, Slack and Teams
|
|
17
|
+
* get every variable as text, never as HTML.
|
|
18
|
+
*/
|
|
19
|
+
isHtmlInEmailBody?: boolean;
|
|
7
20
|
}
|
|
8
21
|
|
|
22
|
+
/*
|
|
23
|
+
* A family of variables whose names are not known in advance: one per
|
|
24
|
+
* incident custom field, {{customFields.<key>}}, where <key> is the field's
|
|
25
|
+
* Template Variable key (IncidentCustomField.variableKey). Which keys exist
|
|
26
|
+
* depends on the project, so the family is listed by its prefix, and the
|
|
27
|
+
* worker passes one variable for every field the project has - an empty
|
|
28
|
+
* string when the incident holds no value for it.
|
|
29
|
+
*/
|
|
30
|
+
export interface SubscriberNotificationTemplateDynamicVariable {
|
|
31
|
+
// What every name in the family starts with, dot included.
|
|
32
|
+
prefix: string;
|
|
33
|
+
// How the rest of the name is shown in the reference: "<key>".
|
|
34
|
+
placeholder: string;
|
|
35
|
+
// Whether what follows the prefix is a name in the family.
|
|
36
|
+
isValidKey: (key: string) => boolean;
|
|
37
|
+
description: string;
|
|
38
|
+
/*
|
|
39
|
+
* Some members are HTML in an email body - a Rich text field's rendered
|
|
40
|
+
* Markdown, a Long text field's lines, a Date and time field's time
|
|
41
|
+
* zones - and the rest are plain text, which is escaped there.
|
|
42
|
+
*/
|
|
43
|
+
mayBeHtmlInEmailBody?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* The variables every incident event offers on top of its own: the
|
|
48
|
+
* incident's labels, the status pages it is on, and its custom fields.
|
|
49
|
+
*
|
|
50
|
+
* affectedStatusPages and the custom fields are internal data - a status
|
|
51
|
+
* page's subscribers are usually outside the team, and the list of pages
|
|
52
|
+
* names every other audience the incident reaches - so the worker never puts
|
|
53
|
+
* them into a message on its own. They reach subscribers only where a
|
|
54
|
+
* template author places them, and the template form warns about it.
|
|
55
|
+
*/
|
|
56
|
+
const INCIDENT_VARIABLES: Array<SubscriberNotificationTemplateVariable> = [
|
|
57
|
+
{
|
|
58
|
+
name: "incidentLabels",
|
|
59
|
+
description: "Labels of the incident, separated by commas",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "affectedStatusPages",
|
|
63
|
+
description:
|
|
64
|
+
"Names of every status page the incident is shown on, separated by commas. Internal: it names the status pages of every audience the incident reaches",
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
const INCIDENT_DYNAMIC_VARIABLES: Array<SubscriberNotificationTemplateDynamicVariable> =
|
|
69
|
+
[
|
|
70
|
+
{
|
|
71
|
+
prefix: CUSTOM_FIELD_TEMPLATE_VARIABLE_PREFIX,
|
|
72
|
+
placeholder: "<key>",
|
|
73
|
+
isValidKey: isValidCustomFieldVariableKey,
|
|
74
|
+
description:
|
|
75
|
+
"The value of an incident custom field, by the field's Template Variable key. Internal: any custom field can be placed, whether or not it is marked to be included in subscriber notifications",
|
|
76
|
+
mayBeHtmlInEmailBody: true,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
* The variables that read the team's own incident records rather than what
|
|
82
|
+
* the incident's status pages already show: its labels, and every custom
|
|
83
|
+
* field ({{customFields.<key>}}), marked for subscribers or not. The title,
|
|
84
|
+
* description, severity, state and public notes are on the status page for
|
|
85
|
+
* anyone who can see it; these are not, and the status page roles that may
|
|
86
|
+
* write templates may not read them. So a template can place them only if
|
|
87
|
+
* whoever writes it may read them (Server/Utils/StatusPage/
|
|
88
|
+
* SubscriberTemplateIncidentRecordAccess).
|
|
89
|
+
*
|
|
90
|
+
* {{affectedStatusPages}} is not one of them: it names status pages, which
|
|
91
|
+
* the same roles read.
|
|
92
|
+
*/
|
|
93
|
+
const INCIDENT_RECORD_VARIABLE_NAMES: ReadonlyArray<string> = [
|
|
94
|
+
"incidentLabels",
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
// The incident events, which offer INCIDENT_VARIABLES and the custom fields.
|
|
98
|
+
const INCIDENT_EVENT_TYPES: ReadonlyArray<StatusPageSubscriberNotificationEventType> =
|
|
99
|
+
[
|
|
100
|
+
StatusPageSubscriberNotificationEventType.SubscriberIncidentCreated,
|
|
101
|
+
StatusPageSubscriberNotificationEventType.SubscriberIncidentStateChanged,
|
|
102
|
+
StatusPageSubscriberNotificationEventType.SubscriberIncidentNoteCreated,
|
|
103
|
+
StatusPageSubscriberNotificationEventType.SubscriberIncidentNoteUpdated,
|
|
104
|
+
StatusPageSubscriberNotificationEventType.SubscriberIncidentPostmortemPublished,
|
|
105
|
+
];
|
|
106
|
+
|
|
9
107
|
/*
|
|
10
108
|
* The variables a custom status page subscriber notification template can use
|
|
11
109
|
* for each event type, as {{variableName}}.
|
|
@@ -38,7 +136,11 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
38
136
|
|
|
39
137
|
const commonVariables: Array<SubscriberNotificationTemplateVariable> = [
|
|
40
138
|
...statusPageVariables,
|
|
41
|
-
{
|
|
139
|
+
{
|
|
140
|
+
name: "resourcesAffected",
|
|
141
|
+
description: "List of affected resources",
|
|
142
|
+
isHtmlInEmailBody: true,
|
|
143
|
+
},
|
|
42
144
|
];
|
|
43
145
|
|
|
44
146
|
switch (eventType) {
|
|
@@ -72,9 +174,11 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
72
174
|
{
|
|
73
175
|
name: "incidentDescription",
|
|
74
176
|
description: "Description of the incident",
|
|
177
|
+
isHtmlInEmailBody: true,
|
|
75
178
|
},
|
|
76
179
|
{ name: "incidentSeverity", description: "Severity of the incident" },
|
|
77
180
|
{ name: "detailsUrl", description: "URL to view incident details" },
|
|
181
|
+
...INCIDENT_VARIABLES,
|
|
78
182
|
];
|
|
79
183
|
|
|
80
184
|
case StatusPageSubscriberNotificationEventType.SubscriberIncidentStateChanged:
|
|
@@ -84,6 +188,7 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
84
188
|
{
|
|
85
189
|
name: "incidentDescription",
|
|
86
190
|
description: "Description of the incident",
|
|
191
|
+
isHtmlInEmailBody: true,
|
|
87
192
|
},
|
|
88
193
|
{ name: "incidentSeverity", description: "Severity of the incident" },
|
|
89
194
|
{
|
|
@@ -91,6 +196,7 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
91
196
|
description: "Current state of the incident",
|
|
92
197
|
},
|
|
93
198
|
{ name: "detailsUrl", description: "URL to view incident details" },
|
|
199
|
+
...INCIDENT_VARIABLES,
|
|
94
200
|
];
|
|
95
201
|
|
|
96
202
|
case StatusPageSubscriberNotificationEventType.SubscriberIncidentNoteCreated:
|
|
@@ -104,8 +210,13 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
104
210
|
description: "Current state of the incident",
|
|
105
211
|
},
|
|
106
212
|
{ name: "postedAt", description: "When the note was posted" },
|
|
107
|
-
{
|
|
213
|
+
{
|
|
214
|
+
name: "note",
|
|
215
|
+
description: "Content of the note",
|
|
216
|
+
isHtmlInEmailBody: true,
|
|
217
|
+
},
|
|
108
218
|
{ name: "detailsUrl", description: "URL to view incident details" },
|
|
219
|
+
...INCIDENT_VARIABLES,
|
|
109
220
|
];
|
|
110
221
|
|
|
111
222
|
case StatusPageSubscriberNotificationEventType.SubscriberIncidentPostmortemPublished:
|
|
@@ -116,8 +227,10 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
116
227
|
{
|
|
117
228
|
name: "postmortemNote",
|
|
118
229
|
description: "Content of the postmortem note",
|
|
230
|
+
isHtmlInEmailBody: true,
|
|
119
231
|
},
|
|
120
232
|
{ name: "detailsUrl", description: "URL to view incident details" },
|
|
233
|
+
...INCIDENT_VARIABLES,
|
|
121
234
|
];
|
|
122
235
|
|
|
123
236
|
case StatusPageSubscriberNotificationEventType.SubscriberAnnouncementCreated:
|
|
@@ -131,6 +244,7 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
131
244
|
{
|
|
132
245
|
name: "announcementDescription",
|
|
133
246
|
description: "Description of the announcement",
|
|
247
|
+
isHtmlInEmailBody: true,
|
|
134
248
|
},
|
|
135
249
|
{
|
|
136
250
|
name: "detailsUrl",
|
|
@@ -148,6 +262,7 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
148
262
|
{
|
|
149
263
|
name: "scheduledMaintenanceDescription",
|
|
150
264
|
description: "Description of the scheduled maintenance",
|
|
265
|
+
isHtmlInEmailBody: true,
|
|
151
266
|
},
|
|
152
267
|
{
|
|
153
268
|
name: "scheduledStartTime",
|
|
@@ -173,6 +288,7 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
173
288
|
{
|
|
174
289
|
name: "scheduledMaintenanceDescription",
|
|
175
290
|
description: "Description of the scheduled maintenance",
|
|
291
|
+
isHtmlInEmailBody: true,
|
|
176
292
|
},
|
|
177
293
|
{
|
|
178
294
|
name: "scheduledMaintenanceState",
|
|
@@ -195,13 +311,18 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
195
311
|
{
|
|
196
312
|
name: "scheduledMaintenanceDescription",
|
|
197
313
|
description: "Description of the scheduled maintenance",
|
|
314
|
+
isHtmlInEmailBody: true,
|
|
198
315
|
},
|
|
199
316
|
{
|
|
200
317
|
name: "scheduledMaintenanceState",
|
|
201
318
|
description: "Current state of the scheduled maintenance",
|
|
202
319
|
},
|
|
203
320
|
{ name: "postedAt", description: "When the note was posted" },
|
|
204
|
-
{
|
|
321
|
+
{
|
|
322
|
+
name: "note",
|
|
323
|
+
description: "Content of the note",
|
|
324
|
+
isHtmlInEmailBody: true,
|
|
325
|
+
},
|
|
205
326
|
{
|
|
206
327
|
name: "detailsUrl",
|
|
207
328
|
description: "URL to view scheduled maintenance details",
|
|
@@ -215,6 +336,7 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
215
336
|
{
|
|
216
337
|
name: "episodeDescription",
|
|
217
338
|
description: "Description of the incident",
|
|
339
|
+
isHtmlInEmailBody: true,
|
|
218
340
|
},
|
|
219
341
|
{ name: "episodeSeverity", description: "Severity of the incident" },
|
|
220
342
|
{ name: "detailsUrl", description: "URL to view incident details" },
|
|
@@ -238,7 +360,11 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
238
360
|
...commonVariables,
|
|
239
361
|
{ name: "episodeTitle", description: "Title of the incident" },
|
|
240
362
|
{ name: "episodeSeverity", description: "Severity of the incident" },
|
|
241
|
-
{
|
|
363
|
+
{
|
|
364
|
+
name: "note",
|
|
365
|
+
description: "Content of the note",
|
|
366
|
+
isHtmlInEmailBody: true,
|
|
367
|
+
},
|
|
242
368
|
{ name: "detailsUrl", description: "URL to view incident details" },
|
|
243
369
|
];
|
|
244
370
|
|
|
@@ -319,6 +445,19 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
319
445
|
}
|
|
320
446
|
}
|
|
321
447
|
|
|
448
|
+
// The variables that are HTML, not plain text, in an email template's body.
|
|
449
|
+
public static getEmailBodyHtmlVariableNamesForEventType(
|
|
450
|
+
eventType: StatusPageSubscriberNotificationEventType,
|
|
451
|
+
): Array<string> {
|
|
452
|
+
return this.getAvailableVariablesForEventType(eventType)
|
|
453
|
+
.filter((variable: SubscriberNotificationTemplateVariable): boolean => {
|
|
454
|
+
return variable.isHtmlInEmailBody === true;
|
|
455
|
+
})
|
|
456
|
+
.map((variable: SubscriberNotificationTemplateVariable): string => {
|
|
457
|
+
return variable.name;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
322
461
|
public static getVariableNamesForEventType(
|
|
323
462
|
eventType: StatusPageSubscriberNotificationEventType,
|
|
324
463
|
): Array<string> {
|
|
@@ -328,4 +467,78 @@ export default class SubscriberNotificationTemplateVariables {
|
|
|
328
467
|
},
|
|
329
468
|
);
|
|
330
469
|
}
|
|
470
|
+
|
|
471
|
+
/*
|
|
472
|
+
* The families of variables this event offers on top of the listed ones,
|
|
473
|
+
* by prefix: the incident events' {{customFields.<key>}}.
|
|
474
|
+
*/
|
|
475
|
+
public static getDynamicVariablesForEventType(
|
|
476
|
+
eventType: StatusPageSubscriberNotificationEventType,
|
|
477
|
+
): Array<SubscriberNotificationTemplateDynamicVariable> {
|
|
478
|
+
return INCIDENT_EVENT_TYPES.includes(eventType)
|
|
479
|
+
? INCIDENT_DYNAMIC_VARIABLES.map(
|
|
480
|
+
(
|
|
481
|
+
variable: SubscriberNotificationTemplateDynamicVariable,
|
|
482
|
+
): SubscriberNotificationTemplateDynamicVariable => {
|
|
483
|
+
return { ...variable };
|
|
484
|
+
},
|
|
485
|
+
)
|
|
486
|
+
: [];
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/*
|
|
490
|
+
* The family this name belongs to, when it is one: the prefix followed by
|
|
491
|
+
* a key of the family's shape (for a custom field, the shape its Template
|
|
492
|
+
* Variable key is made in, which the template compiler fills). Null for a
|
|
493
|
+
* listed variable, a bare prefix, or a name the event does not offer.
|
|
494
|
+
*/
|
|
495
|
+
public static getDynamicVariableForName(
|
|
496
|
+
eventType: StatusPageSubscriberNotificationEventType,
|
|
497
|
+
name: string,
|
|
498
|
+
): SubscriberNotificationTemplateDynamicVariable | null {
|
|
499
|
+
for (const variable of this.getDynamicVariablesForEventType(eventType)) {
|
|
500
|
+
if (
|
|
501
|
+
name.startsWith(variable.prefix) &&
|
|
502
|
+
variable.isValidKey(name.slice(variable.prefix.length))
|
|
503
|
+
) {
|
|
504
|
+
return variable;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
/**
|
|
512
|
+
* The placeholders in these texts - a template's body and email subject -
|
|
513
|
+
* that read the team's incident records (INCIDENT_RECORD_VARIABLE_NAMES
|
|
514
|
+
* and any {{customFields.<key>}}, whether or not such a field exists),
|
|
515
|
+
* each once, sorted. Found exactly as the compiler finds what it fills,
|
|
516
|
+
* whatever the template's event type: an update can change the event type
|
|
517
|
+
* without touching the text.
|
|
518
|
+
*/
|
|
519
|
+
public static getIncidentRecordPlaceholders(
|
|
520
|
+
texts: Array<string | null | undefined>,
|
|
521
|
+
): Array<string> {
|
|
522
|
+
return Array.from(
|
|
523
|
+
SubscriberNotificationTemplateCompiler.getPlaceholderNames(texts),
|
|
524
|
+
)
|
|
525
|
+
.filter((name: string): boolean => {
|
|
526
|
+
return (
|
|
527
|
+
INCIDENT_RECORD_VARIABLE_NAMES.includes(name) ||
|
|
528
|
+
name.startsWith(CUSTOM_FIELD_TEMPLATE_VARIABLE_PREFIX)
|
|
529
|
+
);
|
|
530
|
+
})
|
|
531
|
+
.sort();
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// Whether a template for this event can use {{name}}.
|
|
535
|
+
public static isVariableOffered(
|
|
536
|
+
eventType: StatusPageSubscriberNotificationEventType,
|
|
537
|
+
name: string,
|
|
538
|
+
): boolean {
|
|
539
|
+
return (
|
|
540
|
+
this.getVariableNamesForEventType(eventType).includes(name) ||
|
|
541
|
+
this.getDynamicVariableForName(eventType, name) !== null
|
|
542
|
+
);
|
|
543
|
+
}
|
|
331
544
|
}
|
|
@@ -63,27 +63,48 @@ export default class SubscriberUpdateNotification {
|
|
|
63
63
|
|
|
64
64
|
/*
|
|
65
65
|
* Returns why an update notification should not be sent given where the
|
|
66
|
-
* original ("posted") notification is, or null when it may go out
|
|
66
|
+
* original ("posted") notification is, or null when it may go out - or
|
|
67
|
+
* wait (see isOriginalNotificationBeingSent).
|
|
67
68
|
*
|
|
68
|
-
* While the original is still Pending
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
69
|
+
* While the original is still Pending, subscribers have not heard of the
|
|
70
|
+
* item at all, and the original will carry this edit: the edit changed the
|
|
71
|
+
* row's version, so the run that claims the original
|
|
72
|
+
* (SubscriberNotificationClaim, which checks the version it read) has read
|
|
73
|
+
* the item since. A second "updated" message about something they were
|
|
74
|
+
* never told about would only confuse them.
|
|
75
|
+
*
|
|
76
|
+
* InProgress is different: that send read the item before it claimed it,
|
|
77
|
+
* and goes on with what it read, so it may carry the text from before the
|
|
78
|
+
* edit - a typo fixed, or an ETA corrected, right after posting is exactly
|
|
79
|
+
* that case. The update waits for it instead
|
|
80
|
+
* (isOriginalNotificationBeingSent), and goes out once it has settled.
|
|
72
81
|
*
|
|
73
82
|
* Every settled state lets the update through: Success is the normal case,
|
|
74
|
-
* and Skipped or Failed mean subscribers were not told originally
|
|
75
|
-
* editor is now explicitly asking to do.
|
|
83
|
+
* and Skipped or Failed mean subscribers were not told originally (or not
|
|
84
|
+
* all of them), which the editor is now explicitly asking to do.
|
|
76
85
|
*/
|
|
77
86
|
public static getSkipReasonForOriginalNotificationStatus(
|
|
78
87
|
originalStatus: StatusPageSubscriberNotificationStatus | undefined | null,
|
|
79
88
|
): string | null {
|
|
80
|
-
if (
|
|
81
|
-
originalStatus === StatusPageSubscriberNotificationStatus.Pending ||
|
|
82
|
-
originalStatus === StatusPageSubscriberNotificationStatus.InProgress
|
|
83
|
-
) {
|
|
89
|
+
if (originalStatus === StatusPageSubscriberNotificationStatus.Pending) {
|
|
84
90
|
return this.notYetNotifiedMessage;
|
|
85
91
|
}
|
|
86
92
|
|
|
87
93
|
return null;
|
|
88
94
|
}
|
|
95
|
+
|
|
96
|
+
/*
|
|
97
|
+
* Whether the update notification waits: the original ("posted")
|
|
98
|
+
* notification is being sent right now, with the item as it was read
|
|
99
|
+
* before the edit. The update is left Pending, untouched, and the job
|
|
100
|
+
* decides again on a later run, once the original has settled - then it
|
|
101
|
+
* goes out, since subscribers may have been sent the text from before the
|
|
102
|
+
* edit. A send that never settles is failed by the sweeper
|
|
103
|
+
* (StatusPageSubscriber:TimeoutStuckNotifications), which lets it through.
|
|
104
|
+
*/
|
|
105
|
+
public static isOriginalNotificationBeingSent(
|
|
106
|
+
originalStatus: StatusPageSubscriberNotificationStatus | undefined | null,
|
|
107
|
+
): boolean {
|
|
108
|
+
return originalStatus === StatusPageSubscriberNotificationStatus.InProgress;
|
|
109
|
+
}
|
|
89
110
|
}
|