@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
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import CustomFieldType from "../../Types/CustomField/CustomFieldType";
|
|
2
|
+
import { isCustomFieldValueEmpty } from "../../Types/CustomField/CustomFieldValueMapping";
|
|
3
|
+
import {
|
|
4
|
+
customFieldValueToDate,
|
|
5
|
+
customFieldValueToText,
|
|
6
|
+
formatCustomFieldBoolean,
|
|
7
|
+
formatCustomFieldCalendarDate,
|
|
8
|
+
} from "../../Types/CustomField/CustomFieldValueFormat";
|
|
9
|
+
import OneUptimeDate from "../../Types/Date";
|
|
10
|
+
import { JSONObject } from "../../Types/JSON";
|
|
11
|
+
import SubscriberNotificationTemplateCompiler from "../../Types/StatusPage/SubscriberNotificationTemplateCompiler";
|
|
12
|
+
import { escapeMarkdownValue } from "../Markdown/MarkdownEscape";
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* The {{placeholders}} an incident note template can carry, and their values
|
|
16
|
+
* for one incident. The note template's own example has always shown
|
|
17
|
+
* "**Incident**: {{incident.title}}", but until this nothing filled them in:
|
|
18
|
+
* picking a template put the braces into the note as written.
|
|
19
|
+
*
|
|
20
|
+
* Filling happens in the dashboard, when a template is picked in a note's
|
|
21
|
+
* composer, so the author sees - and can change - the filled-in text before
|
|
22
|
+
* posting it. Placeholders are filled by the same single-pass compiler the
|
|
23
|
+
* subscriber templates use (SubscriberNotificationTemplateCompiler), so:
|
|
24
|
+
*
|
|
25
|
+
* - a placeholder with no value here stays exactly as written, for the
|
|
26
|
+
* author to see and fill in by hand;
|
|
27
|
+
* - a value that itself contains "{{...}}" is never expanded again;
|
|
28
|
+
* - "$&" and friends in a value are text, not replacement patterns.
|
|
29
|
+
*
|
|
30
|
+
* The note is Markdown, and after posting it is rendered for the team, on the
|
|
31
|
+
* status page and in subscriber emails. So every plain value is escaped with
|
|
32
|
+
* escapeMarkdownValue - a title cannot become a link, an image or HTML -
|
|
33
|
+
* while a Rich text (Markdown) custom field is placed as the Markdown it is.
|
|
34
|
+
* The renderers then do the rest, as for any note: raw HTML is dropped or
|
|
35
|
+
* escaped, and links keep only safe protocols.
|
|
36
|
+
*
|
|
37
|
+
* Pure, with no database or React imports, so it is tested directly.
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
export type NoteTemplateVariables = Record<string, string>;
|
|
41
|
+
|
|
42
|
+
export interface IncidentNoteTemplateVariableInfo {
|
|
43
|
+
// As written between the braces.
|
|
44
|
+
name: string;
|
|
45
|
+
// What it is filled with; English, and the key of its translation.
|
|
46
|
+
description: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const INCIDENT_NOTE_CUSTOM_FIELD_VARIABLE_PREFIX: string =
|
|
50
|
+
"customFields.";
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
* The placeholders, in the order the note template settings list them. The
|
|
54
|
+
* first and the startedAt one are the names IncidentNoteTemplate's example
|
|
55
|
+
* has documented all along.
|
|
56
|
+
*/
|
|
57
|
+
export const INCIDENT_NOTE_TEMPLATE_VARIABLES: ReadonlyArray<IncidentNoteTemplateVariableInfo> =
|
|
58
|
+
[
|
|
59
|
+
{ name: "incident.title", description: "Title" },
|
|
60
|
+
{ name: "incident.number", description: "Incident Number" },
|
|
61
|
+
{ name: "incident.severity", description: "Incident Severity" },
|
|
62
|
+
{ name: "incident.state", description: "Current State" },
|
|
63
|
+
{ name: "incident.startedAt", description: "Declared At" },
|
|
64
|
+
{ name: "incident.labels", description: "Labels" },
|
|
65
|
+
{
|
|
66
|
+
name: "incident.affectedStatusPages",
|
|
67
|
+
description: "Affected Status Pages",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: `${INCIDENT_NOTE_CUSTOM_FIELD_VARIABLE_PREFIX}<key>`,
|
|
71
|
+
description:
|
|
72
|
+
"An incident custom field, by the Template Variable shown in the incident custom field settings",
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
|
|
76
|
+
// One incident custom field, as the note placeholders need it.
|
|
77
|
+
export interface IncidentNoteTemplateCustomField {
|
|
78
|
+
name: string;
|
|
79
|
+
// The key in {{customFields.<key>}}; fields without one are not offered.
|
|
80
|
+
variableKey?: string | null | undefined;
|
|
81
|
+
customFieldType?: CustomFieldType | null | undefined;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* What is known about the incident. Anything left undefined is unknown - it
|
|
86
|
+
* could not be read - and its placeholder is left as written rather than
|
|
87
|
+
* filled with nothing. An empty list or a missing value on a known incident
|
|
88
|
+
* is known, and fills its placeholder with an empty string.
|
|
89
|
+
*/
|
|
90
|
+
export interface IncidentNoteTemplateSource {
|
|
91
|
+
title?: string | null | undefined;
|
|
92
|
+
incidentNumber?: number | null | undefined;
|
|
93
|
+
incidentNumberWithPrefix?: string | null | undefined;
|
|
94
|
+
severityName?: string | null | undefined;
|
|
95
|
+
stateName?: string | null | undefined;
|
|
96
|
+
declaredAt?: Date | string | null | undefined;
|
|
97
|
+
labelNames?: Array<string> | undefined;
|
|
98
|
+
affectedStatusPageNames?: Array<string> | undefined;
|
|
99
|
+
customFields?: JSONObject | null | undefined;
|
|
100
|
+
customFieldDefinitions?: Array<IncidentNoteTemplateCustomField> | undefined;
|
|
101
|
+
/*
|
|
102
|
+
* How a date and time reads in the note. The default is the author's own
|
|
103
|
+
* time zone, named ("Sep 27 2026, 14:05 BST"), so readers elsewhere can
|
|
104
|
+
* tell which it is.
|
|
105
|
+
*/
|
|
106
|
+
formatDateTime?: ((date: Date) => string) | undefined;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
type FormatDateTimeFunction = (date: Date) => string;
|
|
110
|
+
|
|
111
|
+
const defaultFormatDateTime: FormatDateTimeFunction = (date: Date): string => {
|
|
112
|
+
return OneUptimeDate.getDateAsUserFriendlyLocalFormattedString(date);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// How a value reads is shared with the subscriber messages.
|
|
116
|
+
const toDate: (value: unknown) => Date | null = customFieldValueToDate;
|
|
117
|
+
const toText: (value: unknown) => string = customFieldValueToText;
|
|
118
|
+
|
|
119
|
+
export type FormatCustomFieldValueForNoteFunction = (data: {
|
|
120
|
+
customFieldType?: CustomFieldType | null | undefined;
|
|
121
|
+
value: unknown;
|
|
122
|
+
formatDateTime?: ((date: Date) => string) | undefined;
|
|
123
|
+
}) => string;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* One custom field value as it reads in a note: Yes or No, the options of a
|
|
127
|
+
* multi-select joined with commas, a date and time in the author's time zone,
|
|
128
|
+
* Rich text as its Markdown. Every other value is escaped (escapeMarkdownValue).
|
|
129
|
+
*/
|
|
130
|
+
export const formatCustomFieldValueForNote: FormatCustomFieldValueForNoteFunction =
|
|
131
|
+
(data: {
|
|
132
|
+
customFieldType?: CustomFieldType | null | undefined;
|
|
133
|
+
value: unknown;
|
|
134
|
+
formatDateTime?: ((date: Date) => string) | undefined;
|
|
135
|
+
}): string => {
|
|
136
|
+
const value: unknown = data.value;
|
|
137
|
+
|
|
138
|
+
if (isCustomFieldValueEmpty(value)) {
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const formatDateTime: FormatDateTimeFunction =
|
|
143
|
+
data.formatDateTime || defaultFormatDateTime;
|
|
144
|
+
|
|
145
|
+
switch (data.customFieldType) {
|
|
146
|
+
// Written in the Markdown editor; it is formatting, so it stays that.
|
|
147
|
+
case CustomFieldType.Markdown:
|
|
148
|
+
return toText(value);
|
|
149
|
+
|
|
150
|
+
case CustomFieldType.LongText:
|
|
151
|
+
return escapeMarkdownValue(toText(value), { keepLineBreaks: true });
|
|
152
|
+
|
|
153
|
+
case CustomFieldType.Boolean:
|
|
154
|
+
return escapeMarkdownValue(formatCustomFieldBoolean(value));
|
|
155
|
+
|
|
156
|
+
case CustomFieldType.DateTime: {
|
|
157
|
+
const date: Date | null = toDate(value);
|
|
158
|
+
|
|
159
|
+
return escapeMarkdownValue(date ? formatDateTime(date) : toText(value));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* A calendar date: the day that was picked, read the way the
|
|
164
|
+
* subscriber messages read it (formatCustomFieldCalendarDate), not in
|
|
165
|
+
* the note author's time zone, which need not be the zone it was
|
|
166
|
+
* picked in. A note and an email about the incident say the same day.
|
|
167
|
+
*/
|
|
168
|
+
case CustomFieldType.Date:
|
|
169
|
+
return escapeMarkdownValue(formatCustomFieldCalendarDate(value));
|
|
170
|
+
|
|
171
|
+
default:
|
|
172
|
+
return escapeMarkdownValue(toText(value));
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export type BuildIncidentNoteTemplateVariablesFunction = (
|
|
177
|
+
source: IncidentNoteTemplateSource,
|
|
178
|
+
) => NoteTemplateVariables;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Every placeholder this incident has a value for. Placeholders it cannot
|
|
182
|
+
* fill are left out, so they stay in the note as written.
|
|
183
|
+
*/
|
|
184
|
+
export const buildIncidentNoteTemplateVariables: BuildIncidentNoteTemplateVariablesFunction =
|
|
185
|
+
(source: IncidentNoteTemplateSource): NoteTemplateVariables => {
|
|
186
|
+
const variables: NoteTemplateVariables = {};
|
|
187
|
+
const formatDateTime: FormatDateTimeFunction =
|
|
188
|
+
source.formatDateTime || defaultFormatDateTime;
|
|
189
|
+
|
|
190
|
+
const setText: (name: string, value: string | null | undefined) => void = (
|
|
191
|
+
name: string,
|
|
192
|
+
value: string | null | undefined,
|
|
193
|
+
): void => {
|
|
194
|
+
if (value === undefined || value === null) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
variables[name] = escapeMarkdownValue(value);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
const setList: (name: string, values: Array<string> | undefined) => void = (
|
|
202
|
+
name: string,
|
|
203
|
+
values: Array<string> | undefined,
|
|
204
|
+
): void => {
|
|
205
|
+
if (!values) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
variables[name] = values
|
|
210
|
+
.map((value: string) => {
|
|
211
|
+
return (value || "").trim();
|
|
212
|
+
})
|
|
213
|
+
.filter((value: string) => {
|
|
214
|
+
return value.length > 0;
|
|
215
|
+
})
|
|
216
|
+
.map((value: string) => {
|
|
217
|
+
return escapeMarkdownValue(value);
|
|
218
|
+
})
|
|
219
|
+
.join(", ");
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
setText("incident.title", source.title);
|
|
223
|
+
|
|
224
|
+
if (source.incidentNumberWithPrefix) {
|
|
225
|
+
setText("incident.number", source.incidentNumberWithPrefix);
|
|
226
|
+
} else if (
|
|
227
|
+
typeof source.incidentNumber === "number" &&
|
|
228
|
+
Number.isFinite(source.incidentNumber)
|
|
229
|
+
) {
|
|
230
|
+
setText("incident.number", `#${source.incidentNumber}`);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
setText("incident.severity", source.severityName);
|
|
234
|
+
setText("incident.state", source.stateName);
|
|
235
|
+
|
|
236
|
+
const declaredAt: Date | null = toDate(source.declaredAt);
|
|
237
|
+
|
|
238
|
+
if (declaredAt) {
|
|
239
|
+
setText("incident.startedAt", formatDateTime(declaredAt));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
setList("incident.labels", source.labelNames);
|
|
243
|
+
setList("incident.affectedStatusPages", source.affectedStatusPageNames);
|
|
244
|
+
|
|
245
|
+
/*
|
|
246
|
+
* By the field's template key, which never changes when the field is
|
|
247
|
+
* renamed; the value is read from the bag by the field's current name.
|
|
248
|
+
*/
|
|
249
|
+
if (source.customFieldDefinitions) {
|
|
250
|
+
const bag: JSONObject =
|
|
251
|
+
source.customFields &&
|
|
252
|
+
typeof source.customFields === "object" &&
|
|
253
|
+
!Array.isArray(source.customFields)
|
|
254
|
+
? source.customFields
|
|
255
|
+
: {};
|
|
256
|
+
|
|
257
|
+
for (const definition of source.customFieldDefinitions) {
|
|
258
|
+
const variableKey: string = (definition.variableKey || "").trim();
|
|
259
|
+
const name: string = `${INCIDENT_NOTE_CUSTOM_FIELD_VARIABLE_PREFIX}${variableKey}`;
|
|
260
|
+
|
|
261
|
+
if (
|
|
262
|
+
!variableKey ||
|
|
263
|
+
!definition.name ||
|
|
264
|
+
!SubscriberNotificationTemplateCompiler.isPlaceholderName(name)
|
|
265
|
+
) {
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
variables[name] = formatCustomFieldValueForNote({
|
|
270
|
+
customFieldType: definition.customFieldType,
|
|
271
|
+
value: Object.prototype.hasOwnProperty.call(bag, definition.name)
|
|
272
|
+
? bag[definition.name]
|
|
273
|
+
: undefined,
|
|
274
|
+
formatDateTime: formatDateTime,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
return variables;
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
export type FillNoteTemplateFunction = (
|
|
283
|
+
template: string,
|
|
284
|
+
variables: NoteTemplateVariables | null | undefined,
|
|
285
|
+
) => string;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* A note template with its placeholders filled in. Placeholders with no
|
|
289
|
+
* value, and every placeholder when there are no variables at all, are left
|
|
290
|
+
* as written.
|
|
291
|
+
*/
|
|
292
|
+
export const fillNoteTemplate: FillNoteTemplateFunction = (
|
|
293
|
+
template: string,
|
|
294
|
+
variables: NoteTemplateVariables | null | undefined,
|
|
295
|
+
): string => {
|
|
296
|
+
if (!variables || Object.keys(variables).length === 0) {
|
|
297
|
+
return template;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return SubscriberNotificationTemplateCompiler.compileTemplate(
|
|
301
|
+
template,
|
|
302
|
+
variables,
|
|
303
|
+
);
|
|
304
|
+
};
|
|
@@ -60,4 +60,69 @@ export const escapeMarkdownInline: EscapeMarkdownInlineFunction = (
|
|
|
60
60
|
);
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
/*
|
|
64
|
+
* Escaping for a plain value placed into Markdown that a PERSON goes on to
|
|
65
|
+
* read and edit before it is posted - an incident's title or a custom field
|
|
66
|
+
* value filled into a note template's {{placeholders}}.
|
|
67
|
+
*
|
|
68
|
+
* escapeMarkdownInline above is the wrong tool there. The note composer opens
|
|
69
|
+
* in its visual mode, which shows a backslash escape exactly as written, so a
|
|
70
|
+
* title such as "Site 03 - payments (EU)" would appear to the author as
|
|
71
|
+
* "Site 03 \- payments \(EU\)". Restyling a value is harmless in a draft its
|
|
72
|
+
* author reviews; what must not happen is the value turning into something
|
|
73
|
+
* else once the note is rendered for subscribers. So only the characters that
|
|
74
|
+
* can make a value into a link, an image or HTML are escaped:
|
|
75
|
+
*
|
|
76
|
+
* - `[` and `]`: every link and image, inline or by reference, is built
|
|
77
|
+
* from brackets. `[Reset your password](https://evil.example)` in a title
|
|
78
|
+
* would otherwise arrive in subscribers' email as a live link, and
|
|
79
|
+
* `` as an image fetched on open. The
|
|
80
|
+
* closing bracket matters too: a template may put the value inside a link
|
|
81
|
+
* of its own, and a value must not be able to end that link's text.
|
|
82
|
+
* - `<`: raw HTML and `<https://...>` autolinks both start with it. (The
|
|
83
|
+
* renderers drop raw HTML as well; this keeps it readable as text.)
|
|
84
|
+
* - `\`: a value ending in a backslash would otherwise undo the escape
|
|
85
|
+
* that follows it.
|
|
86
|
+
*
|
|
87
|
+
* A bare address in a value ("https://example.com") is still made a link by
|
|
88
|
+
* the renderers, as it is when someone types one into a note - but such a
|
|
89
|
+
* link shows the address it goes to. No value can make link text that hides
|
|
90
|
+
* its destination.
|
|
91
|
+
*
|
|
92
|
+
* Line breaks become spaces unless `keepLineBreaks` is set (a long text
|
|
93
|
+
* value): a newline could start a heading or a list, which a single-line
|
|
94
|
+
* value has no business doing.
|
|
95
|
+
*
|
|
96
|
+
* Like escapeMarkdownInline, escape once, where the value is placed.
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
const MARKDOWN_LINK_OR_HTML_CHARACTER_PATTERN: RegExp = /[\\[\]<]/g;
|
|
100
|
+
|
|
101
|
+
export type EscapeMarkdownValueFunction = (
|
|
102
|
+
value: string | undefined | null,
|
|
103
|
+
options?: { keepLineBreaks?: boolean | undefined },
|
|
104
|
+
) => string;
|
|
105
|
+
|
|
106
|
+
export const escapeMarkdownValue: EscapeMarkdownValueFunction = (
|
|
107
|
+
value: string | undefined | null,
|
|
108
|
+
options?: { keepLineBreaks?: boolean | undefined },
|
|
109
|
+
): string => {
|
|
110
|
+
if (value === undefined || value === null) {
|
|
111
|
+
return "";
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
let text: string = String(value).replace(
|
|
115
|
+
MARKDOWN_LINK_OR_HTML_CHARACTER_PATTERN,
|
|
116
|
+
(character: string): string => {
|
|
117
|
+
return `\\${character}`;
|
|
118
|
+
},
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
text = options?.keepLineBreaks
|
|
122
|
+
? text.replace(LINE_BREAK_PATTERN, "\n")
|
|
123
|
+
: text.replace(LINE_BREAK_PATTERN, " ");
|
|
124
|
+
|
|
125
|
+
return text;
|
|
126
|
+
};
|
|
127
|
+
|
|
63
128
|
export default escapeMarkdownInline;
|