@oneuptime/common 14.0.7 → 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/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/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 +14 -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/DatabaseService.ts +93 -10
- 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 +1535 -65
- package/Server/Services/IncidentStateTimelineService.ts +13 -0
- package/Server/Services/IncidentTemplateService.ts +109 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +30 -1
- package/Server/Services/ScheduledMaintenanceService.ts +68 -18
- 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/Types/Markdown.ts +153 -6
- package/Server/Types/Workflow/Components/Email.ts +61 -2
- package/Server/Utils/CustomField/CustomFieldRename.ts +378 -0
- package/Server/Utils/DataSource/EgressGuard.ts +66 -21
- package/Server/Utils/Mail/PinnedSmtpSocket.ts +130 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +10 -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/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/CustomFieldsSettingsIncidentOptions.test.tsx +357 -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 +242 -5
- package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +91 -1
- 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/PublicNotePagesNotifyDefault.test.tsx +113 -1
- 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 +14 -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/DatabaseService.js +56 -7
- package/build/dist/Server/Services/DatabaseService.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 +1052 -0
- 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/ScheduledMaintenancePublicNoteService.js +26 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +47 -17
- 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/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/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/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/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/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/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/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/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
|
@@ -34,6 +34,7 @@ import AIIncidentPostmortemRunner from "../Utils/AI/SRE/IncidentPostmortemRunner
|
|
|
34
34
|
import InvestigationGrader from "../Utils/AI/SRE/InvestigationGrader";
|
|
35
35
|
import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
|
|
36
36
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
37
|
+
import SubscriberNotificationResendAccess from "../Utils/StatusPage/SubscriberNotificationResendAccess";
|
|
37
38
|
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
38
39
|
import WorkspaceNotificationRuleService from "./WorkspaceNotificationRuleService";
|
|
39
40
|
import Semaphore, { SemaphoreMutex } from "../Infrastructure/Semaphore";
|
|
@@ -748,6 +749,18 @@ ${createdItem.rootCause}`,
|
|
|
748
749
|
protected override async onBeforeUpdate(
|
|
749
750
|
updateBy: UpdateBy<IncidentStateTimeline>,
|
|
750
751
|
): Promise<OnUpdate<IncidentStateTimeline>> {
|
|
752
|
+
/*
|
|
753
|
+
* Retry - a user's Pending - over a state change notification that is
|
|
754
|
+
* being sent would let a second run send it alongside, or be overwritten
|
|
755
|
+
* when the send settles (SubscriberNotificationResendAccess).
|
|
756
|
+
*/
|
|
757
|
+
await SubscriberNotificationResendAccess.assertNotQueuedWhileBeingSent({
|
|
758
|
+
modelType: IncidentStateTimeline,
|
|
759
|
+
service: this,
|
|
760
|
+
updateBy: updateBy,
|
|
761
|
+
statusColumns: ["subscriberNotificationStatus"],
|
|
762
|
+
});
|
|
763
|
+
|
|
751
764
|
const incidentIds: Array<ObjectID> =
|
|
752
765
|
await this.getIncidentIdsForTimelineQuery(updateBy);
|
|
753
766
|
|
|
@@ -10,6 +10,7 @@ import LabelService from "./LabelService";
|
|
|
10
10
|
import MonitorService from "./MonitorService";
|
|
11
11
|
import MonitorStatusService from "./MonitorStatusService";
|
|
12
12
|
import OnCallDutyPolicyService from "./OnCallDutyPolicyService";
|
|
13
|
+
import StatusPageService from "./StatusPageService";
|
|
13
14
|
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
14
15
|
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
15
16
|
import Dictionary from "../../Types/Dictionary";
|
|
@@ -28,6 +29,8 @@ import Query from "../Types/Database/Query";
|
|
|
28
29
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
29
30
|
import OwnerRuleAssignment from "../Utils/Rules/OwnerRuleAssignment";
|
|
30
31
|
import QueryDeepPartialEntity from "../../Types/Database/PartialEntity";
|
|
32
|
+
import StatusPageReadAccess from "../Utils/StatusPage/StatusPageReadAccess";
|
|
33
|
+
import IncidentScopeAddedPagesNotification from "../../Types/StatusPage/IncidentScopeAddedPagesNotification";
|
|
31
34
|
|
|
32
35
|
export class Service extends DatabaseService<Model> {
|
|
33
36
|
public constructor() {
|
|
@@ -52,6 +55,12 @@ export class Service extends DatabaseService<Model> {
|
|
|
52
55
|
const projectId: ObjectID | undefined =
|
|
53
56
|
createBy.props.tenantId || createBy.data.projectId;
|
|
54
57
|
|
|
58
|
+
// Derived from the list, whatever the caller sent (see the column).
|
|
59
|
+
createBy.data.isScopedToStatusPages =
|
|
60
|
+
IncidentScopeAddedPagesNotification.normalizeStatusPageIds(
|
|
61
|
+
createBy.data.statusPages,
|
|
62
|
+
).length > 0;
|
|
63
|
+
|
|
55
64
|
await ProjectScopedReferenceValidator.validateReferencesBelongToProject({
|
|
56
65
|
projectId: projectId,
|
|
57
66
|
subject: "incident template",
|
|
@@ -64,6 +73,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
64
73
|
],
|
|
65
74
|
});
|
|
66
75
|
|
|
76
|
+
/*
|
|
77
|
+
* A template's status pages are picked for everyone who declares from
|
|
78
|
+
* it, so picking them needs the same read access as picking an
|
|
79
|
+
* incident's (see StatusPageReadAccess).
|
|
80
|
+
*/
|
|
81
|
+
await StatusPageReadAccess.assertCallerCanPickStatusPages({
|
|
82
|
+
statusPageIds: IncidentScopeAddedPagesNotification.normalizeStatusPageIds(
|
|
83
|
+
createBy.data.statusPages,
|
|
84
|
+
),
|
|
85
|
+
props: createBy.props,
|
|
86
|
+
subject: "incident template",
|
|
87
|
+
});
|
|
88
|
+
|
|
67
89
|
return { createBy, carryForward: null };
|
|
68
90
|
}
|
|
69
91
|
|
|
@@ -71,6 +93,22 @@ export class Service extends DatabaseService<Model> {
|
|
|
71
93
|
protected override async onBeforeUpdate(
|
|
72
94
|
updateBy: UpdateBy<Model>,
|
|
73
95
|
): Promise<OnUpdate<Model>> {
|
|
96
|
+
/*
|
|
97
|
+
* The scope flag follows a write to the list and nothing else: a client
|
|
98
|
+
* value is dropped, and deleting the template's pages (join rows
|
|
99
|
+
* cascading away) never clears it.
|
|
100
|
+
*/
|
|
101
|
+
const data: Dictionary<unknown> = updateBy.data as Dictionary<unknown>;
|
|
102
|
+
|
|
103
|
+
delete data["isScopedToStatusPages"];
|
|
104
|
+
|
|
105
|
+
if (data["statusPages"] !== undefined) {
|
|
106
|
+
data["isScopedToStatusPages"] =
|
|
107
|
+
IncidentScopeAddedPagesNotification.normalizeStatusPageIds(
|
|
108
|
+
data["statusPages"],
|
|
109
|
+
).length > 0;
|
|
110
|
+
}
|
|
111
|
+
|
|
74
112
|
const references: Array<ProjectScopedReference> =
|
|
75
113
|
this.getProjectScopedReferences(updateBy.data);
|
|
76
114
|
|
|
@@ -131,9 +169,75 @@ export class Service extends DatabaseService<Model> {
|
|
|
131
169
|
});
|
|
132
170
|
}
|
|
133
171
|
|
|
172
|
+
// Once the pages are known to be the project's.
|
|
173
|
+
await this.assertCallerCanReadAddedStatusPages(updateBy);
|
|
174
|
+
|
|
134
175
|
return { updateBy, carryForward: null };
|
|
135
176
|
}
|
|
136
177
|
|
|
178
|
+
/*
|
|
179
|
+
* The status pages an update adds to a template must be pages the caller
|
|
180
|
+
* can read (see StatusPageReadAccess). Pages the template already holds are
|
|
181
|
+
* not checked, so saving a template limited to a page the editor cannot
|
|
182
|
+
* see does not fail. The templates are read as root, limited to the
|
|
183
|
+
* caller's project: the update's own tenant filter is only added after
|
|
184
|
+
* this hook.
|
|
185
|
+
*/
|
|
186
|
+
private async assertCallerCanReadAddedStatusPages(
|
|
187
|
+
updateBy: UpdateBy<Model>,
|
|
188
|
+
): Promise<void> {
|
|
189
|
+
const requested: unknown = (updateBy.data as Dictionary<unknown>)[
|
|
190
|
+
"statusPages"
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
if (updateBy.props.isRoot || requested === undefined) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
const requestedIds: Array<string> =
|
|
198
|
+
IncidentScopeAddedPagesNotification.normalizeStatusPageIds(requested);
|
|
199
|
+
|
|
200
|
+
if (requestedIds.length === 0) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const templates: Array<Model> = await this.findBy({
|
|
205
|
+
query: updateBy.props.tenantId
|
|
206
|
+
? { ...updateBy.query, projectId: updateBy.props.tenantId }
|
|
207
|
+
: updateBy.query,
|
|
208
|
+
select: {
|
|
209
|
+
_id: true,
|
|
210
|
+
statusPages: {
|
|
211
|
+
_id: true,
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
limit: LIMIT_MAX,
|
|
215
|
+
skip: 0,
|
|
216
|
+
props: {
|
|
217
|
+
isRoot: true,
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
const addedIds: Array<string> = [];
|
|
222
|
+
|
|
223
|
+
for (const template of templates) {
|
|
224
|
+
for (const id of IncidentScopeAddedPagesNotification.getScopeChange({
|
|
225
|
+
before: template.statusPages,
|
|
226
|
+
after: requestedIds,
|
|
227
|
+
}).addedStatusPageIds) {
|
|
228
|
+
if (!addedIds.includes(id)) {
|
|
229
|
+
addedIds.push(id);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
await StatusPageReadAccess.assertCallerCanPickStatusPages({
|
|
235
|
+
statusPageIds: addedIds,
|
|
236
|
+
props: updateBy.props,
|
|
237
|
+
subject: "incident template",
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
137
241
|
/*
|
|
138
242
|
* The many-to-many lists whose ids must belong to the template's project.
|
|
139
243
|
* Built per call rather than at module load: these services sit in an
|
|
@@ -157,6 +261,11 @@ export class Service extends DatabaseService<Model> {
|
|
|
157
261
|
modelName: "On-Call Policy",
|
|
158
262
|
service: OnCallDutyPolicyService,
|
|
159
263
|
},
|
|
264
|
+
{
|
|
265
|
+
column: "statusPages",
|
|
266
|
+
modelName: "Status Page",
|
|
267
|
+
service: StatusPageService,
|
|
268
|
+
},
|
|
160
269
|
...getAffectedResourceRelations(this.getModel()),
|
|
161
270
|
];
|
|
162
271
|
}
|
|
@@ -19,6 +19,7 @@ import Query from "../Types/Database/Query";
|
|
|
19
19
|
import File from "../../Models/DatabaseModels/File";
|
|
20
20
|
import FileAttachmentMarkdownUtil from "../Utils/FileAttachmentMarkdownUtil";
|
|
21
21
|
import { syncIsPublicForMarkdownImages } from "../Utils/InlineImageAccessTokenSync";
|
|
22
|
+
import SubscriberNotificationResendAccess from "../Utils/StatusPage/SubscriberNotificationResendAccess";
|
|
22
23
|
|
|
23
24
|
export class Service extends DatabaseService<Model> {
|
|
24
25
|
public constructor() {
|
|
@@ -122,11 +123,24 @@ export class Service extends DatabaseService<Model> {
|
|
|
122
123
|
* An edit tells subscribers nothing unless the editor asked for it on this
|
|
123
124
|
* edit (see SubscriberUpdateNotification). When they did, queue the update
|
|
124
125
|
* notification; the ScheduledMaintenancePublicNote worker job sends it.
|
|
126
|
+
*
|
|
127
|
+
* Sending the note's 'posted' notification again - its status written back
|
|
128
|
+
* to Pending, as the dashboard's Retry does - needs the permission to post
|
|
129
|
+
* a note that notifies subscribers, and a note whose notification can go
|
|
130
|
+
* out again (see SubscriberNotificationResendAccess). So does telling
|
|
131
|
+
* subscribers about an edit, which is also refused while that update
|
|
132
|
+
* notification is being sent.
|
|
125
133
|
*/
|
|
126
134
|
@CaptureSpan()
|
|
127
135
|
protected override async onBeforeUpdate(
|
|
128
136
|
updateBy: UpdateBy<Model>,
|
|
129
137
|
): Promise<OnUpdate<Model>> {
|
|
138
|
+
await SubscriberNotificationResendAccess.assertPublicNoteResendAllowed({
|
|
139
|
+
modelType: Model,
|
|
140
|
+
service: this,
|
|
141
|
+
updateBy: updateBy,
|
|
142
|
+
});
|
|
143
|
+
|
|
130
144
|
if (SubscriberUpdateNotification.isRequested(updateBy.miscDataProps)) {
|
|
131
145
|
updateBy.data.subscriberNotificationStatusOnNoteUpdated =
|
|
132
146
|
StatusPageSubscriberNotificationStatus.Pending;
|
|
@@ -134,6 +148,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
134
148
|
SubscriberUpdateNotification.queuedMessage;
|
|
135
149
|
}
|
|
136
150
|
|
|
151
|
+
/*
|
|
152
|
+
* Telling subscribers about the edit - asked for above, or written as
|
|
153
|
+
* Pending directly (the dashboard's Retry of a failed update) - needs
|
|
154
|
+
* the permission to post a note that notifies subscribers too, and is
|
|
155
|
+
* refused while the update notification is being sent.
|
|
156
|
+
*/
|
|
157
|
+
await SubscriberNotificationResendAccess.assertPublicNoteUpdateNotificationAllowed(
|
|
158
|
+
{
|
|
159
|
+
modelType: Model,
|
|
160
|
+
service: this,
|
|
161
|
+
updateBy: updateBy,
|
|
162
|
+
},
|
|
163
|
+
);
|
|
164
|
+
|
|
137
165
|
return {
|
|
138
166
|
updateBy: updateBy,
|
|
139
167
|
carryForward: null,
|
|
@@ -246,8 +274,9 @@ ${(createdItem.note || "") + attachmentsMarkdown}
|
|
|
246
274
|
{
|
|
247
275
|
scheduledMaintenanceId: updatedItem.scheduledMaintenanceId!,
|
|
248
276
|
projectId: updatedItem.projectId!,
|
|
277
|
+
// An edit to a public note is a public note event, not a private one.
|
|
249
278
|
scheduledMaintenanceFeedEventType:
|
|
250
|
-
ScheduledMaintenanceFeedEventType.
|
|
279
|
+
ScheduledMaintenanceFeedEventType.PublicNote,
|
|
251
280
|
displayColor: Blue500,
|
|
252
281
|
userId: userId || undefined,
|
|
253
282
|
|
|
@@ -60,6 +60,7 @@ import SmsService from "../../Server/Services/SmsService";
|
|
|
60
60
|
import StatusPageResourceService from "../../Server/Services/StatusPageResourceService";
|
|
61
61
|
import StatusPageService from "../../Server/Services/StatusPageService";
|
|
62
62
|
import StatusPageSubscriberService from "../../Server/Services/StatusPageSubscriberService";
|
|
63
|
+
import StatusPageSubscriberUnsubscribe from "../../Types/StatusPage/StatusPageSubscriberUnsubscribe";
|
|
63
64
|
import QueryHelper from "../../Server/Types/Database/QueryHelper";
|
|
64
65
|
import Markdown, { MarkdownContentType } from "../../Server/Types/Markdown";
|
|
65
66
|
import logger, { LogAttributes } from "../../Server/Utils/Logger";
|
|
@@ -90,6 +91,8 @@ import ProjectService from "./ProjectService";
|
|
|
90
91
|
import StatusPageSubscriberNotificationTemplateService, {
|
|
91
92
|
Service as StatusPageSubscriberNotificationTemplateServiceClass,
|
|
92
93
|
} from "./StatusPageSubscriberNotificationTemplateService";
|
|
94
|
+
import StatusPageResourceUtil from "../Utils/StatusPageResource";
|
|
95
|
+
import SafeHtml from "../../Types/SafeHtml";
|
|
93
96
|
import StatusPageSubscriberNotificationTemplate from "../../Models/DatabaseModels/StatusPageSubscriberNotificationTemplate";
|
|
94
97
|
import StatusPageSubscriberNotificationEventType from "../../Types/StatusPage/StatusPageSubscriberNotificationEventType";
|
|
95
98
|
import StatusPageSubscriberNotificationMethod from "../../Types/StatusPage/StatusPageSubscriberNotificationMethod";
|
|
@@ -208,12 +211,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
208
211
|
|
|
209
212
|
// Send email to Email subscribers.
|
|
210
213
|
|
|
214
|
+
/*
|
|
215
|
+
* The resources are read without their groups, so both forms are the
|
|
216
|
+
* names joined by commas. The HTML one, for email bodies, has every
|
|
217
|
+
* name escaped; SMS, Slack, subjects and webhooks get the names as
|
|
218
|
+
* written.
|
|
219
|
+
*/
|
|
211
220
|
const resourcesAffected: string =
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
221
|
+
StatusPageResourceUtil.getResourcesGroupedByGroupNameAsPlainText(
|
|
222
|
+
statusPageToResources[statuspage._id!] || [],
|
|
223
|
+
);
|
|
224
|
+
const resourcesAffectedHtml: string =
|
|
225
|
+
StatusPageResourceUtil.getResourcesGroupedByGroupName(
|
|
226
|
+
statusPageToResources[statuspage._id!] || [],
|
|
227
|
+
);
|
|
217
228
|
|
|
218
229
|
// Fetch custom templates for each notification method
|
|
219
230
|
const [
|
|
@@ -270,7 +281,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
270
281
|
const unsubscribeUrl: string =
|
|
271
282
|
StatusPageSubscriberService.getUnsubscribeLink(
|
|
272
283
|
URL.fromString(statusPageURL),
|
|
273
|
-
subscriber
|
|
284
|
+
subscriber,
|
|
274
285
|
).toString();
|
|
275
286
|
|
|
276
287
|
// Template variables for custom templates, as Markdown (Slack)
|
|
@@ -298,6 +309,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
298
309
|
};
|
|
299
310
|
|
|
300
311
|
if (subscriber.subscriberPhone) {
|
|
312
|
+
/*
|
|
313
|
+
* On a public status page the SMS keeps the shorter manage link,
|
|
314
|
+
* which works there without signing in: an SMS is billed by the
|
|
315
|
+
* segment (see StatusPageSubscriberUnsubscribe.buildSmsLink).
|
|
316
|
+
*/
|
|
317
|
+
const smsUnsubscribeUrl: string =
|
|
318
|
+
StatusPageSubscriberUnsubscribe.buildSmsLink({
|
|
319
|
+
isPublicStatusPage: statuspage.isPublicStatusPage,
|
|
320
|
+
statusPageUrl: statusPageURL,
|
|
321
|
+
subscriberId: subscriber.id!,
|
|
322
|
+
unsubscribeUrl: unsubscribeUrl,
|
|
323
|
+
});
|
|
324
|
+
|
|
301
325
|
let smsMessage: string;
|
|
302
326
|
|
|
303
327
|
if (
|
|
@@ -309,11 +333,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
309
333
|
smsMessage =
|
|
310
334
|
StatusPageSubscriberNotificationTemplateServiceClass.compileTemplate(
|
|
311
335
|
smsTemplate.templateBody,
|
|
312
|
-
|
|
336
|
+
{
|
|
337
|
+
...plainTextTemplateVariables,
|
|
338
|
+
unsubscribeUrl: smsUnsubscribeUrl,
|
|
339
|
+
},
|
|
313
340
|
);
|
|
314
341
|
} else {
|
|
315
342
|
// Use default template
|
|
316
|
-
smsMessage = `Scheduled Maintenance: ${event.title || ""} on ${statusPageName}.${resourcesAffected ? ` Impact: ${resourcesAffected}.` : ""} Details: ${scheduledEventDetailsUrl}. Unsub: ${
|
|
343
|
+
smsMessage = `Scheduled Maintenance: ${event.title || ""} on ${statusPageName}.${resourcesAffected ? ` Impact: ${resourcesAffected}.` : ""} Details: ${scheduledEventDetailsUrl}. Unsub: ${smsUnsubscribeUrl}`;
|
|
317
344
|
}
|
|
318
345
|
|
|
319
346
|
const sms: SMS = {
|
|
@@ -408,7 +435,20 @@ ${resourcesAffected ? `**Resources Affected:** ${resourcesAffected}` : ""}
|
|
|
408
435
|
const statusPageIdString: string | null =
|
|
409
436
|
statuspage.id?.toString() || statuspage._id?.toString() || null;
|
|
410
437
|
|
|
411
|
-
|
|
438
|
+
const scheduledAtHtml: string =
|
|
439
|
+
OneUptimeDate.getDateAsFormattedHTMLInMultipleTimezones({
|
|
440
|
+
date: event.startsAt!,
|
|
441
|
+
timezones: statuspage.subscriberTimezones || [],
|
|
442
|
+
use12HourFormat: true,
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
/*
|
|
446
|
+
* The default template's variables. resourcesAffected,
|
|
447
|
+
* scheduledAt and eventDescription are HTML (the template puts
|
|
448
|
+
* them in its raw-HTML slot); the footer is HTML the status
|
|
449
|
+
* page's admins wrote, as they write the template. Everything
|
|
450
|
+
* else is plain text, which the template escapes.
|
|
451
|
+
*/
|
|
412
452
|
const emailVars: Record<string, string> = {
|
|
413
453
|
statusPageName: statusPageName,
|
|
414
454
|
statusPageUrl: statusPageURL,
|
|
@@ -425,13 +465,8 @@ ${resourcesAffected ? `**Resources Affected:** ${resourcesAffected}` : ""}
|
|
|
425
465
|
: "false",
|
|
426
466
|
subscriberEmailNotificationFooterText:
|
|
427
467
|
statuspage.subscriberEmailNotificationFooterText || "",
|
|
428
|
-
resourcesAffected:
|
|
429
|
-
scheduledAt:
|
|
430
|
-
OneUptimeDate.getDateAsFormattedHTMLInMultipleTimezones({
|
|
431
|
-
date: event.startsAt!,
|
|
432
|
-
timezones: statuspage.subscriberTimezones || [],
|
|
433
|
-
use12HourFormat: true,
|
|
434
|
-
}),
|
|
468
|
+
resourcesAffected: resourcesAffectedHtml,
|
|
469
|
+
scheduledAt: scheduledAtHtml,
|
|
435
470
|
eventTitle: event.title || "",
|
|
436
471
|
eventDescription: eventDescriptionHtml,
|
|
437
472
|
unsubscribeUrl: unsubscribeUrl,
|
|
@@ -448,14 +483,29 @@ ${resourcesAffected ? `**Resources Affected:** ${resourcesAffected}` : ""}
|
|
|
448
483
|
* is configured. The body is HTML, so the description is too.
|
|
449
484
|
* The subject is plain text, including the email-only
|
|
450
485
|
* variables that are HTML in the body.
|
|
486
|
+
*
|
|
487
|
+
* In the body, the plain values are escaped
|
|
488
|
+
* (compileEmailBodyTemplate) and only the ones wrapped in
|
|
489
|
+
* SafeHtml below go in as HTML.
|
|
451
490
|
*/
|
|
452
491
|
const customEmailBody: string =
|
|
453
|
-
StatusPageSubscriberNotificationTemplateServiceClass.
|
|
492
|
+
StatusPageSubscriberNotificationTemplateServiceClass.compileEmailBodyTemplate(
|
|
454
493
|
emailTemplate.templateBody,
|
|
455
494
|
{
|
|
456
495
|
...templateVariables,
|
|
457
496
|
...emailVars,
|
|
458
|
-
|
|
497
|
+
resourcesAffected: SafeHtml.fromTrustedHtml(
|
|
498
|
+
resourcesAffectedHtml,
|
|
499
|
+
),
|
|
500
|
+
scheduledAt: SafeHtml.fromTrustedHtml(scheduledAtHtml),
|
|
501
|
+
eventDescription:
|
|
502
|
+
SafeHtml.fromTrustedHtml(eventDescriptionHtml),
|
|
503
|
+
scheduledMaintenanceDescription:
|
|
504
|
+
SafeHtml.fromTrustedHtml(eventDescriptionHtml),
|
|
505
|
+
subscriberEmailNotificationFooterText:
|
|
506
|
+
SafeHtml.fromTrustedHtml(
|
|
507
|
+
emailVars["subscriberEmailNotificationFooterText"],
|
|
508
|
+
),
|
|
459
509
|
},
|
|
460
510
|
);
|
|
461
511
|
const customEmailSubject: string = emailTemplate.emailSubject
|
|
@@ -41,6 +41,15 @@ export class SmsService extends BaseService {
|
|
|
41
41
|
onCallDutyPolicyExecutionLogTimelineId?: ObjectID | undefined;
|
|
42
42
|
onCallScheduleId?: ObjectID | undefined;
|
|
43
43
|
teamId?: ObjectID | undefined;
|
|
44
|
+
/*
|
|
45
|
+
* Answer with an error, not success, when the Notification service
|
|
46
|
+
* deliberately does not send the SMS: the project has SMS notifications
|
|
47
|
+
* turned off, or too little SMS balance. The status page subscriber
|
|
48
|
+
* sends that count what they delivered pass it
|
|
49
|
+
* (SubscriberNotificationDeliveryRecord), so such an SMS counts as
|
|
50
|
+
* failed rather than sent.
|
|
51
|
+
*/
|
|
52
|
+
failIfNotSent?: boolean | undefined;
|
|
44
53
|
},
|
|
45
54
|
): Promise<HTTPResponse<EmptyResponseData>> {
|
|
46
55
|
const body: JSONObject = {
|
|
@@ -74,6 +83,7 @@ export class SmsService extends BaseService {
|
|
|
74
83
|
options.onCallDutyPolicyExecutionLogTimelineId?.toString(),
|
|
75
84
|
onCallScheduleId: options.onCallScheduleId?.toString(),
|
|
76
85
|
teamId: options.teamId?.toString(),
|
|
86
|
+
...(options.failIfNotSent ? { failIfNotSent: true } : {}),
|
|
77
87
|
};
|
|
78
88
|
|
|
79
89
|
return await API.post<EmptyResponseData>({
|
|
@@ -63,7 +63,8 @@ import MonitorGroupResource from "../../Models/DatabaseModels/MonitorGroupResour
|
|
|
63
63
|
import MonitorGroupService from "./MonitorGroupService";
|
|
64
64
|
import QueryHelper from "../Types/Database/QueryHelper";
|
|
65
65
|
import OneUptimeDate from "../../Types/Date";
|
|
66
|
-
import
|
|
66
|
+
import IncidentStatusPageScope from "../Utils/StatusPage/IncidentStatusPageScope";
|
|
67
|
+
import Select from "../Types/Database/Select";
|
|
67
68
|
import MonitorStatusTimeline from "../../Models/DatabaseModels/MonitorStatusTimeline";
|
|
68
69
|
import MonitorStatusTimelineService, {
|
|
69
70
|
MergedDowntimeTotals,
|
|
@@ -122,6 +123,17 @@ export const STATUS_PAGE_SSO_REQUIREMENT_COLUMNS: ReadonlyArray<string> = [
|
|
|
122
123
|
"requireSsoForLogin",
|
|
123
124
|
];
|
|
124
125
|
|
|
126
|
+
/*
|
|
127
|
+
* What a report's incident counts read of the status page: which project's
|
|
128
|
+
* incidents to count, and whether the page only shows incidents limited to
|
|
129
|
+
* it (IncidentStatusPageScope decides from that which incidents count).
|
|
130
|
+
*/
|
|
131
|
+
export const INCIDENT_COUNT_STATUS_PAGE_SELECT: Select<StatusPage> = {
|
|
132
|
+
_id: true,
|
|
133
|
+
projectId: true,
|
|
134
|
+
onlyShowScopedIncidents: true,
|
|
135
|
+
};
|
|
136
|
+
|
|
125
137
|
export class Service extends DatabaseService<StatusPage> {
|
|
126
138
|
/*
|
|
127
139
|
* Caches the resolved status page URL per statusPageId. `getStatusPageURL`
|
|
@@ -1393,7 +1405,7 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1393
1405
|
const unsubscribeUrl: string =
|
|
1394
1406
|
StatusPageSubscriberService.getUnsubscribeLink(
|
|
1395
1407
|
URL.fromString(statusPageURL),
|
|
1396
|
-
subscriber
|
|
1408
|
+
subscriber,
|
|
1397
1409
|
).toString();
|
|
1398
1410
|
|
|
1399
1411
|
if (subscriber.subscriberEmail) {
|
|
@@ -1432,6 +1444,8 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1432
1444
|
},
|
|
1433
1445
|
select: {
|
|
1434
1446
|
downtimeMonitorStatuses: true,
|
|
1447
|
+
// What the incident counts below are scoped by.
|
|
1448
|
+
...INCIDENT_COUNT_STATUS_PAGE_SELECT,
|
|
1435
1449
|
},
|
|
1436
1450
|
});
|
|
1437
1451
|
|
|
@@ -1499,7 +1513,7 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1499
1513
|
}
|
|
1500
1514
|
|
|
1501
1515
|
const incidentCount: number = await this.getIncidentCountOnStatusPage({
|
|
1502
|
-
|
|
1516
|
+
statusPage: statusPage,
|
|
1503
1517
|
startDate: startDate,
|
|
1504
1518
|
endDate: endDate,
|
|
1505
1519
|
});
|
|
@@ -1661,6 +1675,7 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1661
1675
|
reportItem: {
|
|
1662
1676
|
resourceName: resource.displayName || "",
|
|
1663
1677
|
totalIncidentCount: await this.getIncidentCountByMonitorIds({
|
|
1678
|
+
statusPage: statusPage,
|
|
1664
1679
|
monitorIds: monitorIdsForThisResource,
|
|
1665
1680
|
startDate: startDate,
|
|
1666
1681
|
endDate: endDate,
|
|
@@ -1710,6 +1725,7 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1710
1725
|
|
|
1711
1726
|
const groupMetricsByGroupId: Dictionary<StatusPageReportGroupMetrics> =
|
|
1712
1727
|
await this.getReportGroupMetrics({
|
|
1728
|
+
statusPage: statusPage,
|
|
1713
1729
|
statusPageGroups: statusPageGroups,
|
|
1714
1730
|
entries: entries,
|
|
1715
1731
|
monitorIdsByResourceIndex: monitorIdsByResourceIndex,
|
|
@@ -1817,6 +1833,11 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1817
1833
|
*/
|
|
1818
1834
|
@CaptureSpan()
|
|
1819
1835
|
public async getReportGroupMetrics(data: {
|
|
1836
|
+
/*
|
|
1837
|
+
* The status page the report is for, which the incident counts are
|
|
1838
|
+
* scoped by: loaded with INCIDENT_COUNT_STATUS_PAGE_SELECT.
|
|
1839
|
+
*/
|
|
1840
|
+
statusPage: StatusPage;
|
|
1820
1841
|
statusPageGroups: Array<StatusPageGroup>;
|
|
1821
1842
|
entries: Array<StatusPageReportResourceEntry>;
|
|
1822
1843
|
monitorIdsByResourceIndex: Array<Array<ObjectID>>;
|
|
@@ -1913,6 +1934,7 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1913
1934
|
totalIncidentCount =
|
|
1914
1935
|
monitorIds.length > 0
|
|
1915
1936
|
? await this.getIncidentCountByMonitorIds({
|
|
1937
|
+
statusPage: data.statusPage,
|
|
1916
1938
|
monitorIds: monitorIds,
|
|
1917
1939
|
startDate: data.reportWindow.startDate,
|
|
1918
1940
|
endDate: data.reportWindow.endDate,
|
|
@@ -1963,13 +1985,41 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1963
1985
|
});
|
|
1964
1986
|
}
|
|
1965
1987
|
|
|
1988
|
+
/*
|
|
1989
|
+
* How many incidents the status page shows on these monitors, created in
|
|
1990
|
+
* the window: the report's count for a resource, a group or the page.
|
|
1991
|
+
*
|
|
1992
|
+
* It counts what the page shows, through IncidentStatusPageScope - an
|
|
1993
|
+
* incident limited to other status pages is not counted, nor is an
|
|
1994
|
+
* unlimited one on a page that only shows incidents limited to it - and
|
|
1995
|
+
* only the project's incidents visible on status pages. (Before the scope,
|
|
1996
|
+
* this counted every incident on the monitors, hidden ones and all.)
|
|
1997
|
+
*
|
|
1998
|
+
* The status page must be loaded with INCIDENT_COUNT_STATUS_PAGE_SELECT. It
|
|
1999
|
+
* is passed in rather than read here because a report counts once for each
|
|
2000
|
+
* resource and group.
|
|
2001
|
+
*/
|
|
1966
2002
|
@CaptureSpan()
|
|
1967
2003
|
public async getIncidentCountByMonitorIds(data: {
|
|
2004
|
+
statusPage: StatusPage;
|
|
1968
2005
|
monitorIds: Array<ObjectID>;
|
|
1969
2006
|
startDate: Date;
|
|
1970
2007
|
endDate: Date;
|
|
1971
2008
|
}): Promise<number> {
|
|
1972
|
-
|
|
2009
|
+
// No monitor, so no incident on one to count.
|
|
2010
|
+
if (data.monitorIds.length === 0) {
|
|
2011
|
+
return 0;
|
|
2012
|
+
}
|
|
2013
|
+
|
|
2014
|
+
if (!data.statusPage.projectId) {
|
|
2015
|
+
throw new BadDataException(
|
|
2016
|
+
"Cannot count the incidents on a status page without its project.",
|
|
2017
|
+
);
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
return await IncidentStatusPageScope.countIncidentsForStatusPage({
|
|
2021
|
+
statusPage: data.statusPage,
|
|
2022
|
+
projectId: data.statusPage.projectId,
|
|
1973
2023
|
query: {
|
|
1974
2024
|
monitors: data.monitorIds as any,
|
|
1975
2025
|
createdAt: QueryHelper.inBetween(data.startDate, data.endDate),
|
|
@@ -1978,24 +2028,31 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
1978
2028
|
isRoot: true,
|
|
1979
2029
|
},
|
|
1980
2030
|
});
|
|
1981
|
-
|
|
1982
|
-
return incidentCount.toNumber();
|
|
1983
2031
|
}
|
|
1984
2032
|
|
|
2033
|
+
// How many incidents the status page shows, over all of its monitors.
|
|
1985
2034
|
@CaptureSpan()
|
|
1986
2035
|
public async getIncidentCountOnStatusPage(data: {
|
|
1987
|
-
|
|
2036
|
+
// Loaded with INCIDENT_COUNT_STATUS_PAGE_SELECT.
|
|
2037
|
+
statusPage: StatusPage;
|
|
1988
2038
|
startDate: Date;
|
|
1989
2039
|
endDate: Date;
|
|
1990
2040
|
}): Promise<number> {
|
|
2041
|
+
if (!data.statusPage.id) {
|
|
2042
|
+
throw new BadDataException(
|
|
2043
|
+
"Cannot count the incidents on a status page without its id.",
|
|
2044
|
+
);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
1991
2047
|
const monitorsOnStatusPage: {
|
|
1992
2048
|
monitorsOnStatusPage: Array<ObjectID>;
|
|
1993
2049
|
monitorsInGroup: Dictionary<Array<ObjectID>>;
|
|
1994
2050
|
} = await this.getMonitorIdsOnStatusPage({
|
|
1995
|
-
statusPageId: data.
|
|
2051
|
+
statusPageId: data.statusPage.id,
|
|
1996
2052
|
});
|
|
1997
2053
|
|
|
1998
2054
|
return this.getIncidentCountByMonitorIds({
|
|
2055
|
+
statusPage: data.statusPage,
|
|
1999
2056
|
monitorIds: monitorsOnStatusPage.monitorsOnStatusPage,
|
|
2000
2057
|
startDate: data.startDate,
|
|
2001
2058
|
endDate: data.endDate,
|