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