@oneuptime/common 12.0.6 → 12.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/AIInsight.ts +1 -1
- package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
- package/Models/DatabaseModels/DeletedProject.ts +595 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Monitor.ts +111 -0
- package/Models/DatabaseModels/Project.ts +3 -3
- package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
- package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
- package/Models/DatabaseModels/WorkflowLog.ts +38 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
- package/Server/API/FileAPI.ts +15 -2
- package/Server/API/MicrosoftTeamsAPI.ts +6 -1
- package/Server/API/ProjectAPI.ts +214 -0
- package/Server/API/StatusPageAPI.ts +39 -6
- package/Server/API/UserAPI.ts +16 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
- package/Server/Services/AIAgentService.ts +20 -0
- package/Server/Services/DashboardDomainService.ts +73 -28
- package/Server/Services/DatabaseService.ts +1 -0
- package/Server/Services/DeletedProjectService.ts +138 -0
- package/Server/Services/FileService.ts +61 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
- package/Server/Services/IncidentPublicNoteService.ts +18 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +311 -0
- package/Server/Services/ProbeService.ts +20 -0
- package/Server/Services/ProjectService.ts +297 -1
- package/Server/Services/PushNotificationService.ts +71 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
- package/Server/Services/StatusPageAnnouncementService.ts +53 -0
- package/Server/Services/StatusPageDomainService.ts +73 -28
- package/Server/Services/TeamMemberService.ts +117 -12
- package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
- package/Server/Services/TelemetryEntityService.ts +114 -1
- package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
- package/Server/Services/UserWebhookService.ts +34 -109
- package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
- package/Server/Types/Database/DeleteById.ts +2 -0
- package/Server/Types/Database/DeleteOneBy.ts +6 -0
- package/Server/Types/Domain.ts +41 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
- package/Server/Types/Workflow/Components/API/Get.ts +2 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
- package/Server/Types/Workflow/Components/API/Post.ts +2 -1
- package/Server/Types/Workflow/Components/API/Put.ts +2 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +85 -3
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
- package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
- package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
- package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
- package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
- package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
- package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
- package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
- package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
- package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
- package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
- package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
- package/Server/Types/Workflow/TriggerCode.ts +12 -0
- package/Server/Types/Workflow/Workflow.ts +5 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
- package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
- package/Server/Utils/DataSource/EgressGuard.ts +176 -16
- package/Server/Utils/DataSource/HttpFetch.ts +6 -45
- package/Server/Utils/Execute.ts +8 -0
- package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
- package/Server/Utils/LLM/LLMService.ts +57 -12
- package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
- package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
- package/Server/Utils/Monitor/MonitorResource.ts +36 -0
- package/Server/Utils/Response.ts +142 -6
- package/Server/Utils/SSRFProtection.ts +273 -60
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
- package/Server/Utils/VM/VMAPI.ts +56 -8
- package/Server/Utils/VM/VMRunner.ts +88 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
- package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
- package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
- package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
- package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
- package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
- package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
- package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
- package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
- package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
- package/Tests/Server/API/ProjectAPI.test.ts +299 -1
- package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
- package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
- package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
- package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
- package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
- package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
- package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
- package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
- package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
- package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
- package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
- package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
- package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
- package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
- package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
- package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
- package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
- package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
- package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
- package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
- package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
- package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
- package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
- package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
- package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
- package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
- package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
- package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
- package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
- package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
- package/Tests/Types/JSONFunctions.test.ts +252 -1
- package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
- package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
- package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
- package/Tests/Types/Workflow/Templates.test.ts +403 -0
- package/Tests/UI/Components/404.test.tsx +1 -1
- package/Tests/UI/Components/Alert.test.tsx +1 -1
- package/Tests/UI/Components/Badge.test.tsx +1 -1
- package/Tests/UI/Components/BasicForm.test.tsx +39 -10
- package/Tests/UI/Components/Button.test.tsx +1 -1
- package/Tests/UI/Components/Card.test.tsx +1 -1
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
- package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
- package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
- package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
- package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
- package/Tests/UI/Components/Dropdown.test.tsx +1 -1
- package/Tests/UI/Components/FilePicker.test.tsx +1 -1
- package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
- package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
- package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
- package/Tests/UI/Components/HiddenText.test.tsx +1 -1
- package/Tests/UI/Components/Input.test.tsx +1 -1
- package/Tests/UI/Components/Loader.test.tsx +1 -1
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +43 -1
- package/Tests/UI/Components/MasterPage.test.tsx +1 -1
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +579 -0
- package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
- package/Tests/UI/Components/NavBar.test.tsx +1 -1
- package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
- package/Tests/UI/Components/Pagination.test.tsx +1 -1
- package/Tests/UI/Components/Pill.test.tsx +1 -1
- package/Tests/UI/Components/Probe.test.tsx +1 -1
- package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
- package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
- package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
- package/Tests/UI/Components/SideOver.test.tsx +500 -6
- package/Tests/UI/Components/Tabs.test.tsx +1 -1
- package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +50 -8
- package/Tests/UI/Components/TextArea.test.tsx +1 -1
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
- package/Tests/UI/Components/Toast.test.tsx +1 -1
- package/Tests/UI/Components/Toggle.test.tsx +1 -1
- package/Tests/UI/Components/TopSection.test.tsx +1 -1
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
- package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
- package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
- package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
- package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
- package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
- package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
- package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
- package/Tests/Utils/Realtime.test.ts +78 -0
- package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
- package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
- package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
- package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
- package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
- package/Types/AI/FixPullRequestCiStatus.ts +1 -1
- package/Types/AI/FixVerificationStatus.ts +2 -2
- package/Types/API/Hostname.ts +92 -4
- package/Types/API/URL.ts +43 -25
- package/Types/Billing/BalanceAdjustmentType.ts +14 -0
- package/Types/Billing/ProjectBalanceType.ts +13 -0
- package/Types/Domain.ts +26 -0
- package/Types/File/MimeType.ts +11 -0
- package/Types/JSONFunctions.ts +15 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
- package/Types/SerializableObjectDictionary.ts +133 -39
- package/Types/Telemetry/EntitySource.ts +40 -0
- package/Types/Telemetry/EntityType.ts +27 -0
- package/Types/Telemetry/EntityTypeGroups.ts +65 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
- package/Types/Workflow/Component.ts +29 -0
- package/Types/Workflow/Components/API.ts +35 -0
- package/Types/Workflow/Components/BaseModel.ts +96 -28
- package/Types/Workflow/StepTrace.ts +181 -0
- package/Types/Workflow/TemplateSyntax.ts +499 -0
- package/Types/Workflow/Templates.ts +316 -0
- package/Typings/Index.d.ts +12 -0
- package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
- package/UI/Components/Dictionary/Dictionary.tsx +23 -6
- package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
- package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
- package/UI/Components/Forms/Types/Field.ts +7 -0
- package/UI/Components/Forms/Validation.ts +63 -1
- package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
- package/UI/Components/Input/Input.tsx +31 -3
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
- package/UI/Components/Modal/ConfirmModal.tsx +10 -5
- package/UI/Components/Modal/Modal.tsx +64 -51
- package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
- package/UI/Components/SideOver/SideOver.tsx +195 -68
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
- package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
- package/UI/Components/Workflow/Component.tsx +28 -26
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
- package/UI/Components/Workflow/GraphLint.ts +591 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
- package/UI/Components/Workflow/ModelSchema.ts +196 -0
- package/UI/Components/Workflow/RunForm.tsx +41 -7
- package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
- package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
- package/UI/Components/Workflow/Utils.ts +93 -1
- package/UI/Components/Workflow/Workflow.tsx +77 -4
- package/UI/Types/LayeredDismissal.ts +31 -0
- package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
- package/UI/Utils/PageScrollLock.ts +66 -0
- package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
- package/Utils/Dashboard/VariableInterpolation.ts +19 -1
- package/Utils/LegacySerializedArray.ts +60 -0
- package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
- package/Utils/Telemetry/EntityKey.ts +66 -0
- package/Utils/Telemetry/SavedViewFilters.ts +88 -0
- package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
- package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
- package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +3 -3
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/FileAPI.js +14 -2
- package/build/dist/Server/API/FileAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +157 -4
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +27 -3
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +16 -1
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +17 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +55 -18
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +1 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DeletedProjectService.js +124 -0
- package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
- package/build/dist/Server/Services/FileService.js +52 -0
- package/build/dist/Server/Services/FileService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +232 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +17 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +228 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +56 -0
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
- package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
- package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +97 -6
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +31 -87
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Domain.js +37 -0
- package/build/dist/Server/Types/Domain.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +63 -2
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/Execute.js +2 -2
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +112 -5
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +219 -53
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
- package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
- package/build/dist/Types/API/Hostname.js +73 -4
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/API/URL.js +42 -24
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
- package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
- package/build/dist/Types/Domain.js +22 -0
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +11 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +14 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +133 -39
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +39 -0
- package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +27 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
- package/build/dist/Types/Workflow/Component.js +21 -0
- package/build/dist/Types/Workflow/Component.js.map +1 -1
- package/build/dist/Types/Workflow/Components/API.js +35 -0
- package/build/dist/Types/Workflow/Components/API.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +87 -28
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/StepTrace.js +104 -0
- package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +218 -0
- package/build/dist/Types/Workflow/Templates.js.map +1 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +44 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +12 -4
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +55 -39
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +20 -19
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
- package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
- package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Utils.js +73 -1
- package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Types/LayeredDismissal.js +21 -0
- package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +52 -0
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
- package/build/dist/Utils/LegacySerializedArray.js +51 -0
- package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
- package/jest.config.json +3 -0
- package/package.json +1 -1
- package/tsconfig.json +3 -1
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
2
|
+
import MonitorStatus from "../../../Models/DatabaseModels/MonitorStatus";
|
|
3
|
+
import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
|
|
4
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
5
|
+
import MonitorDependencyRule, {
|
|
6
|
+
DependencySuppressionResult,
|
|
7
|
+
ParentMonitorStatusRef,
|
|
8
|
+
SuppressingParent,
|
|
9
|
+
} from "../../../Utils/Monitor/MonitorDependencyRule";
|
|
10
|
+
import MonitorService from "../../Services/MonitorService";
|
|
11
|
+
import QueryHelper from "../../Types/Database/QueryHelper";
|
|
12
|
+
import logger from "../Logger";
|
|
13
|
+
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Re-exported so server-side callers (and the existing tests) keep a
|
|
17
|
+
* single import site; the rule itself lives in
|
|
18
|
+
* Common/Utils/Monitor/MonitorDependencyRule so the dashboard can share
|
|
19
|
+
* it without importing server modules.
|
|
20
|
+
*/
|
|
21
|
+
export type {
|
|
22
|
+
DependencySuppressionResult,
|
|
23
|
+
ParentMonitorStatusRef,
|
|
24
|
+
SuppressingParent,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
* Alert-dependency suppression (the per-monitor counterpart of the
|
|
29
|
+
* per-series MonitorMaintenanceSuppression): when a monitor declares
|
|
30
|
+
* `dependsOnMonitors` and any of those parents is currently in a
|
|
31
|
+
* suppressing status, alert/incident *creation* for this monitor is
|
|
32
|
+
* skipped for the evaluation. The monitor itself keeps evaluating — its
|
|
33
|
+
* status timeline, metrics, and the resolve path for already-open
|
|
34
|
+
* alerts/incidents are untouched. That keeps the child visibly Offline on
|
|
35
|
+
* status pages (and lets grand-children observe the outage through the
|
|
36
|
+
* child's real status, which is what makes one-hop checks transitive)
|
|
37
|
+
* while silencing the redundant paging.
|
|
38
|
+
*
|
|
39
|
+
* Which parent statuses suppress: the monitor's
|
|
40
|
+
* `suppressAlertsWhenParentMonitorStatuses` list when configured,
|
|
41
|
+
* otherwise any status flagged `isOfflineState`. The decision itself is
|
|
42
|
+
* MonitorDependencyRule.getSuppressingParents, shared with the dashboard
|
|
43
|
+
* banner.
|
|
44
|
+
*/
|
|
45
|
+
export default class MonitorDependencySuppression {
|
|
46
|
+
/*
|
|
47
|
+
* Resolve the suppression decision for one evaluation. Zero queries on
|
|
48
|
+
* the common path — a monitor with no dependencies returns immediately —
|
|
49
|
+
* and exactly one query (the parents' current statuses) otherwise. This
|
|
50
|
+
* sits on the hottest Postgres path in the product, so the monitor's
|
|
51
|
+
* dependency ids must arrive pre-selected on the monitor row rather than
|
|
52
|
+
* being re-read here.
|
|
53
|
+
*/
|
|
54
|
+
@CaptureSpan()
|
|
55
|
+
public static async getDependencySuppression(input: {
|
|
56
|
+
monitor: Monitor;
|
|
57
|
+
}): Promise<DependencySuppressionResult> {
|
|
58
|
+
const monitorId: string = (
|
|
59
|
+
input.monitor.id ||
|
|
60
|
+
input.monitor._id ||
|
|
61
|
+
""
|
|
62
|
+
).toString();
|
|
63
|
+
|
|
64
|
+
const parentIds: Array<ObjectID> = (input.monitor.dependsOnMonitors || [])
|
|
65
|
+
.map((parent: Monitor) => {
|
|
66
|
+
return (parent.id || parent._id)?.toString() || "";
|
|
67
|
+
})
|
|
68
|
+
.filter((id: string) => {
|
|
69
|
+
/*
|
|
70
|
+
* A self-edge should never exist (validation rejects it, uuids
|
|
71
|
+
* compared case-insensitively), but if one was persisted through
|
|
72
|
+
* an older payload shape it must not let a monitor suppress its
|
|
73
|
+
* own offline alerts — that would silence exactly the outage the
|
|
74
|
+
* monitor exists to report.
|
|
75
|
+
*/
|
|
76
|
+
return id.length > 0 && id.toLowerCase() !== monitorId.toLowerCase();
|
|
77
|
+
})
|
|
78
|
+
.map((id: string) => {
|
|
79
|
+
return new ObjectID(id);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
if (parentIds.length === 0) {
|
|
83
|
+
return { isSuppressed: false, suppressingParents: [] };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const parents: Array<Monitor> = await MonitorService.findBy({
|
|
87
|
+
query: {
|
|
88
|
+
_id: QueryHelper.any(parentIds),
|
|
89
|
+
},
|
|
90
|
+
select: {
|
|
91
|
+
_id: true,
|
|
92
|
+
name: true,
|
|
93
|
+
currentMonitorStatus: {
|
|
94
|
+
_id: true,
|
|
95
|
+
name: true,
|
|
96
|
+
isOfflineState: true,
|
|
97
|
+
},
|
|
98
|
+
/*
|
|
99
|
+
* The parents' own parent ids, for the runtime mutual-cycle guard
|
|
100
|
+
* below. Selected here so the guard costs no extra query.
|
|
101
|
+
*/
|
|
102
|
+
dependsOnMonitors: {
|
|
103
|
+
_id: true,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
skip: 0,
|
|
107
|
+
limit: LIMIT_PER_PROJECT,
|
|
108
|
+
props: {
|
|
109
|
+
isRoot: true,
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const parentRefs: Array<ParentMonitorStatusRef> = [];
|
|
114
|
+
|
|
115
|
+
for (const parent of parents) {
|
|
116
|
+
/*
|
|
117
|
+
* Runtime mutual-cycle guard: write-time validation walks the graph
|
|
118
|
+
* before persisting, but two concurrent updates can each pass
|
|
119
|
+
* validation and jointly commit a cycle (A depends on B, B depends
|
|
120
|
+
* on A). If that cycle suppressed, a shared outage would take both
|
|
121
|
+
* monitors offline and page NOBODY. Fail open instead: a parent
|
|
122
|
+
* that itself depends on this monitor is ignored for suppression,
|
|
123
|
+
* so a raced-in cycle degrades to normal (noisy) paging rather than
|
|
124
|
+
* a silent blackout.
|
|
125
|
+
*/
|
|
126
|
+
const isMutualCycle: boolean = (parent.dependsOnMonitors || []).some(
|
|
127
|
+
(grandParent: Monitor) => {
|
|
128
|
+
const grandParentId: string = (
|
|
129
|
+
grandParent.id ||
|
|
130
|
+
grandParent._id ||
|
|
131
|
+
""
|
|
132
|
+
).toString();
|
|
133
|
+
|
|
134
|
+
return (
|
|
135
|
+
grandParentId.length > 0 &&
|
|
136
|
+
grandParentId.toLowerCase() === monitorId.toLowerCase()
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
if (isMutualCycle) {
|
|
142
|
+
logger.warn(
|
|
143
|
+
`${monitorId} - Monitor dependency cycle detected at evaluation time with parent ${parent.id?.toString()} ("${parent.name}"). The parent is ignored for suppression so alerts still fire. Remove one side of the cycle.`,
|
|
144
|
+
);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
parentRefs.push({
|
|
149
|
+
monitorId: parent.id?.toString() || "",
|
|
150
|
+
monitorName: parent.name || "Unnamed monitor",
|
|
151
|
+
statusId: parent.currentMonitorStatus?.id?.toString(),
|
|
152
|
+
statusName: parent.currentMonitorStatus?.name,
|
|
153
|
+
isOfflineState: Boolean(parent.currentMonitorStatus?.isOfflineState),
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const configuredSuppressionStatusIds: Set<string> = new Set<string>(
|
|
158
|
+
(input.monitor.suppressAlertsWhenParentMonitorStatuses || [])
|
|
159
|
+
.map((status: MonitorStatus) => {
|
|
160
|
+
return (status.id || status._id)?.toString() || "";
|
|
161
|
+
})
|
|
162
|
+
.filter((id: string) => {
|
|
163
|
+
return id.length > 0;
|
|
164
|
+
}),
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
const suppressingParents: Array<SuppressingParent> =
|
|
168
|
+
this.getSuppressingParents({
|
|
169
|
+
parents: parentRefs,
|
|
170
|
+
configuredSuppressionStatusIds,
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
return {
|
|
174
|
+
isSuppressed: suppressingParents.length > 0,
|
|
175
|
+
suppressingParents,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Delegates kept so callers and tests have one server-side entry point.
|
|
180
|
+
public static getSuppressingParents(input: {
|
|
181
|
+
parents: Array<ParentMonitorStatusRef>;
|
|
182
|
+
configuredSuppressionStatusIds: Set<string>;
|
|
183
|
+
}): Array<SuppressingParent> {
|
|
184
|
+
return MonitorDependencyRule.getSuppressingParents(input);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public static buildSuppressionReason(
|
|
188
|
+
suppressingParents: Array<SuppressingParent>,
|
|
189
|
+
): string {
|
|
190
|
+
return MonitorDependencyRule.buildSuppressionReason(suppressingParents);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -44,6 +44,9 @@ import logger, { LogAttributes } from "../Logger";
|
|
|
44
44
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
45
45
|
import DataToProcess from "./DataToProcess";
|
|
46
46
|
import MonitorTemplateUtil from "./MonitorTemplateUtil";
|
|
47
|
+
import MonitorDependencySuppression, {
|
|
48
|
+
DependencySuppressionResult,
|
|
49
|
+
} from "./MonitorDependencySuppression";
|
|
47
50
|
import { JSONObject } from "../../../Types/JSON";
|
|
48
51
|
import OneUptimeDate from "../../../Types/Date";
|
|
49
52
|
import MonitorEvaluationSummary from "../../../Types/Monitor/MonitorEvaluationSummary";
|
|
@@ -288,6 +291,14 @@ export default class MonitorIncident {
|
|
|
288
291
|
* are suppressed at creation time. See MonitorMaintenanceSuppression.
|
|
289
292
|
*/
|
|
290
293
|
suppressedSeriesFingerprints?: Set<string> | undefined;
|
|
294
|
+
/**
|
|
295
|
+
* Alert-dependency suppression: when set and isSuppressed, a parent
|
|
296
|
+
* monitor this monitor depends on is currently in a suppressing
|
|
297
|
+
* status, so ALL incident creation for this evaluation is skipped.
|
|
298
|
+
* Only creation — already-open incidents still follow the normal
|
|
299
|
+
* resolve path above. See MonitorDependencySuppression.
|
|
300
|
+
*/
|
|
301
|
+
dependencySuppression?: DependencySuppressionResult | undefined;
|
|
291
302
|
/**
|
|
292
303
|
* Event-driven monitors (incoming-request / webhook fan-out) must not
|
|
293
304
|
* use the metric snapshot model where a series absent from this tick's
|
|
@@ -342,6 +353,35 @@ export default class MonitorIncident {
|
|
|
342
353
|
return;
|
|
343
354
|
}
|
|
344
355
|
|
|
356
|
+
/*
|
|
357
|
+
* Alert-dependency suppression: a parent monitor is in a suppressing
|
|
358
|
+
* status (offline by default), so skip creating any incident for this
|
|
359
|
+
* evaluation. Placed after the open-incident resolve pass above on
|
|
360
|
+
* purpose — an incident raised before the parent went down must still
|
|
361
|
+
* resolve normally; only new creation is silenced.
|
|
362
|
+
*/
|
|
363
|
+
if (input.dependencySuppression?.isSuppressed) {
|
|
364
|
+
const suppressionReason: string =
|
|
365
|
+
MonitorDependencySuppression.buildSuppressionReason(
|
|
366
|
+
input.dependencySuppression.suppressingParents,
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
logger.debug(
|
|
370
|
+
`${input.monitor.id?.toString()} - Skipping incident creation: ${suppressionReason}.`,
|
|
371
|
+
incidentLogAttributes,
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
input.evaluationSummary?.events.push({
|
|
375
|
+
type: "incident-skipped",
|
|
376
|
+
title: "Incident suppressed by monitor dependency",
|
|
377
|
+
message: `Skipped creating incidents because ${suppressionReason}. This monitor's status still updates normally; open incidents still auto-resolve.`,
|
|
378
|
+
relatedCriteriaId: input.criteriaInstance.data?.id,
|
|
379
|
+
at: OneUptimeDate.getCurrentDate(),
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
345
385
|
/*
|
|
346
386
|
* Proxmox/Ceph monitors: resolve the monitored cluster once per
|
|
347
387
|
* evaluation (lookup-only, from the step config's clusterIdentifier)
|
|
@@ -45,6 +45,9 @@ import MonitorSummaryCapture from "./MonitorSummaryCapture";
|
|
|
45
45
|
import MonitorSummarySnapshot from "../../../Types/Monitor/MonitorSummarySnapshot";
|
|
46
46
|
import IncomingRequestIncidentGrouping from "./IncomingRequestIncidentGrouping";
|
|
47
47
|
import MonitorMaintenanceSuppression from "./MonitorMaintenanceSuppression";
|
|
48
|
+
import MonitorDependencySuppression, {
|
|
49
|
+
DependencySuppressionResult,
|
|
50
|
+
} from "./MonitorDependencySuppression";
|
|
48
51
|
import MonitorStatusTimelineUtil from "./MonitorStatusTimeline";
|
|
49
52
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
50
53
|
import ExceptionMessages from "../../../Types/Exception/ExceptionMessages";
|
|
@@ -150,6 +153,21 @@ export default class MonitorResourceUtil {
|
|
|
150
153
|
name: true,
|
|
151
154
|
},
|
|
152
155
|
customFields: true,
|
|
156
|
+
/*
|
|
157
|
+
* Alert-dependency suppression inputs. Selected here for the same
|
|
158
|
+
* reason as labels: this query already loads the monitor on the
|
|
159
|
+
* hottest path, and both lists are empty for the overwhelming
|
|
160
|
+
* majority of monitors, in which case suppression costs nothing.
|
|
161
|
+
* Ids only — names are fetched by the suppression util's own
|
|
162
|
+
* parents query, so selecting them here would just duplicate the
|
|
163
|
+
* joined row payload on every evaluation.
|
|
164
|
+
*/
|
|
165
|
+
dependsOnMonitors: {
|
|
166
|
+
_id: true,
|
|
167
|
+
},
|
|
168
|
+
suppressAlertsWhenParentMonitorStatuses: {
|
|
169
|
+
_id: true,
|
|
170
|
+
},
|
|
153
171
|
},
|
|
154
172
|
props: {
|
|
155
173
|
isRoot: true,
|
|
@@ -917,6 +935,22 @@ export default class MonitorResourceUtil {
|
|
|
917
935
|
matchesPerSeries: response.perSeriesMatches,
|
|
918
936
|
});
|
|
919
937
|
|
|
938
|
+
/*
|
|
939
|
+
* Alert-dependency suppression: if any parent monitor this monitor
|
|
940
|
+
* depends on is currently in a suppressing status (offline by
|
|
941
|
+
* default), skip creating incidents/alerts for this evaluation.
|
|
942
|
+
* Deliberately computed AFTER the status timeline update above —
|
|
943
|
+
* the child's own status must keep tracking reality (status pages,
|
|
944
|
+
* transitive dependency checks); only the redundant paging is
|
|
945
|
+
* silenced. The resolve path for already-open incidents/alerts is
|
|
946
|
+
* likewise untouched. Zero queries when the monitor has no
|
|
947
|
+
* dependencies configured.
|
|
948
|
+
*/
|
|
949
|
+
const dependencySuppression: DependencySuppressionResult =
|
|
950
|
+
await MonitorDependencySuppression.getDependencySuppression({
|
|
951
|
+
monitor: monitor,
|
|
952
|
+
});
|
|
953
|
+
|
|
920
954
|
/*
|
|
921
955
|
* Freeze the Monitor Summary as it stands right now, before any
|
|
922
956
|
* incident or alert is created from it. Both creators store the
|
|
@@ -945,6 +979,7 @@ export default class MonitorResourceUtil {
|
|
|
945
979
|
},
|
|
946
980
|
matchesPerSeries: response.perSeriesMatches,
|
|
947
981
|
suppressedSeriesFingerprints,
|
|
982
|
+
dependencySuppression,
|
|
948
983
|
/*
|
|
949
984
|
* Incoming-request grouping is event-driven: a webhook describes
|
|
950
985
|
* only the keys in its payload, so absence from this tick is not
|
|
@@ -969,6 +1004,7 @@ export default class MonitorResourceUtil {
|
|
|
969
1004
|
},
|
|
970
1005
|
matchesPerSeries: response.perSeriesMatches,
|
|
971
1006
|
suppressedSeriesFingerprints,
|
|
1007
|
+
dependencySuppression,
|
|
972
1008
|
/*
|
|
973
1009
|
* Incoming-request grouping is event-driven (see the incident
|
|
974
1010
|
* create call above): skip the snapshot absence-resolve pass for
|
package/Server/Utils/Response.ts
CHANGED
|
@@ -21,11 +21,63 @@ import Dictionary from "../../Types/Dictionary";
|
|
|
21
21
|
import Exception from "../../Types/Exception/Exception";
|
|
22
22
|
import { JSONArray, JSONObject } from "../../Types/JSON";
|
|
23
23
|
import ListData from "../../Types/ListData";
|
|
24
|
+
import MimeType from "../../Types/File/MimeType";
|
|
24
25
|
import PositiveNumber from "../../Types/PositiveNumber";
|
|
25
26
|
import Route from "../../Types/API/Route";
|
|
26
27
|
import CaptureSpan from "./Telemetry/CaptureSpan";
|
|
27
28
|
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
28
29
|
|
|
30
|
+
/*
|
|
31
|
+
* Raster image types, which is to say the types that cannot carry script and
|
|
32
|
+
* are therefore safe both to echo back verbatim and to render in our own
|
|
33
|
+
* origin. An SVG is not here on purpose: it is a document, not a picture, and
|
|
34
|
+
* a PDF is not here either because it gets its own scripting engine.
|
|
35
|
+
*
|
|
36
|
+
* The list is deliberately wider than the MimeType enum. Until November 2025
|
|
37
|
+
* (62d74c1d84) the file picker stored the browser's own MIME string verbatim,
|
|
38
|
+
* so installs upgrading through this change hold rows with values that never
|
|
39
|
+
* appeared in the enum - "image/vnd.microsoft.icon" from a favicon upload,
|
|
40
|
+
* "image/jpg" from assorted tools. Collapsing those to octet-stream would stop
|
|
41
|
+
* every one of those avatars and logos from rendering, because nosniff means
|
|
42
|
+
* an <img> cannot recover from a type it was given wrongly.
|
|
43
|
+
*/
|
|
44
|
+
const SAFE_IMAGE_MIME_TYPES: Set<string> = new Set<string>([
|
|
45
|
+
MimeType.png,
|
|
46
|
+
// MimeType.jpg is the same string as MimeType.jpeg, so it is covered.
|
|
47
|
+
MimeType.jpeg,
|
|
48
|
+
MimeType.gif,
|
|
49
|
+
MimeType.webp,
|
|
50
|
+
MimeType.ico,
|
|
51
|
+
MimeType.bmp,
|
|
52
|
+
MimeType.tiff,
|
|
53
|
+
MimeType.avif,
|
|
54
|
+
MimeType.heic,
|
|
55
|
+
"image/jpg",
|
|
56
|
+
"image/pjpeg",
|
|
57
|
+
"image/vnd.microsoft.icon",
|
|
58
|
+
"image/x-ms-bmp",
|
|
59
|
+
]);
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* `fileType` is a plain varchar filled in from the upload request body, so by
|
|
63
|
+
* the time a file is served back it holds whatever string the uploader chose -
|
|
64
|
+
* the MimeType enum is a compile-time type and is erased at runtime. Echoing
|
|
65
|
+
* that string back as Content-Type is what turns "upload an image" into "run
|
|
66
|
+
* script on the dashboard origin", because /api, /file and /dashboard are the
|
|
67
|
+
* same origin. Only types we actually recognise get echoed back.
|
|
68
|
+
*
|
|
69
|
+
* Note this read-side list is wider than the one FileService enforces on
|
|
70
|
+
* upload: new rows are held to the canonical enum, old rows only have to be
|
|
71
|
+
* servable.
|
|
72
|
+
*/
|
|
73
|
+
const ALLOWED_MIME_TYPES: Set<string> = new Set<string>([
|
|
74
|
+
...Object.values(MimeType),
|
|
75
|
+
...SAFE_IMAGE_MIME_TYPES,
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
// What an unrecognised fileType degrades to: opaque bytes, never a document.
|
|
79
|
+
const FALLBACK_MIME_TYPE: string = "application/octet-stream";
|
|
80
|
+
|
|
29
81
|
export default class Response {
|
|
30
82
|
@CaptureSpan()
|
|
31
83
|
public static sendEmptySuccessResponse(
|
|
@@ -67,21 +119,105 @@ export default class Response {
|
|
|
67
119
|
oneUptimeResponse.status(statusCode).send(body);
|
|
68
120
|
}
|
|
69
121
|
|
|
122
|
+
/*
|
|
123
|
+
* Reduce a stored fileType to something safe to hand back as Content-Type.
|
|
124
|
+
* Anything we do not recognise - a made-up string, "text/html", a row
|
|
125
|
+
* written before uploads were validated - becomes opaque bytes.
|
|
126
|
+
*/
|
|
127
|
+
public static getSafeFileType(fileType: string | undefined | null): string {
|
|
128
|
+
const normalizedFileType: string = (fileType || "").trim().toLowerCase();
|
|
129
|
+
|
|
130
|
+
if (ALLOWED_MIME_TYPES.has(normalizedFileType)) {
|
|
131
|
+
return normalizedFileType;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return FALLBACK_MIME_TYPE;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/*
|
|
138
|
+
* The filename goes into a response header, so it gets the same treatment as
|
|
139
|
+
* the MIME string: no quotes, no CR/LF, nothing that could split the header.
|
|
140
|
+
* This is the ASCII fallback only - see getContentDisposition, which pairs it
|
|
141
|
+
* with an encoded copy so a non-Latin name is not reduced to underscores.
|
|
142
|
+
*/
|
|
143
|
+
public static getSafeFileName(name: string | undefined | null): string {
|
|
144
|
+
const safeFileName: string = (name || "")
|
|
145
|
+
.replace(/[^a-zA-Z0-9._-]/g, "_")
|
|
146
|
+
.slice(0, 100);
|
|
147
|
+
|
|
148
|
+
return safeFileName || "download";
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/*
|
|
152
|
+
* RFC 6266: `filename` carries an ASCII-safe fallback for old clients and
|
|
153
|
+
* `filename*` carries the real name percent-encoded, so "月次レポート.pdf"
|
|
154
|
+
* downloads under its own name instead of as a row of underscores. Both are
|
|
155
|
+
* escaped, so neither can close the quoted string or inject a header.
|
|
156
|
+
*/
|
|
157
|
+
public static getContentDisposition(
|
|
158
|
+
disposition: "inline" | "attachment",
|
|
159
|
+
name: string | undefined | null,
|
|
160
|
+
): string {
|
|
161
|
+
const fileName: string = (name || "").trim().slice(0, 100) || "download";
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
* encodeURIComponent leaves !'()* alone and RFC 5987's attr-char does not
|
|
165
|
+
* allow them - single quote especially, since it delimits the value.
|
|
166
|
+
*/
|
|
167
|
+
const encodedFileName: string = encodeURIComponent(fileName).replace(
|
|
168
|
+
/['()*!]/g,
|
|
169
|
+
(character: string): string => {
|
|
170
|
+
return `%${character.charCodeAt(0).toString(16).toUpperCase()}`;
|
|
171
|
+
},
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
return `${disposition}; filename="${Response.getSafeFileName(fileName)}"; filename*=UTF-8''${encodedFileName}`;
|
|
175
|
+
}
|
|
176
|
+
|
|
70
177
|
@CaptureSpan()
|
|
71
178
|
public static async sendFileResponse(
|
|
72
179
|
_req: ExpressRequest | ExpressRequest,
|
|
73
180
|
res: ExpressResponse,
|
|
74
181
|
file: FileModel,
|
|
75
182
|
): Promise<void> {
|
|
76
|
-
/** Create read stream */
|
|
77
|
-
|
|
78
183
|
const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse;
|
|
79
184
|
|
|
80
|
-
|
|
81
|
-
|
|
185
|
+
const fileType: string = Response.getSafeFileType(file.fileType);
|
|
186
|
+
|
|
187
|
+
oneUptimeResponse.set("Content-Type", fileType);
|
|
188
|
+
|
|
189
|
+
/*
|
|
190
|
+
* Belt and braces for the types we do echo back. nosniff stops the browser
|
|
191
|
+
* from guessing its way to a different type; the CSP gives the response an
|
|
192
|
+
* opaque origin with no scripting even if it is opened as a top-level
|
|
193
|
+
* document, so a crafted file cannot reach dashboard cookies; and nothing
|
|
194
|
+
* we serve here is ever meant to be framed.
|
|
195
|
+
*/
|
|
196
|
+
oneUptimeResponse.set("X-Content-Type-Options", "nosniff");
|
|
197
|
+
oneUptimeResponse.set(
|
|
198
|
+
"Content-Security-Policy",
|
|
199
|
+
"sandbox; script-src 'none'; object-src 'none'; frame-ancestors 'none'",
|
|
200
|
+
);
|
|
201
|
+
oneUptimeResponse.set("X-Frame-Options", "DENY");
|
|
202
|
+
|
|
203
|
+
/*
|
|
204
|
+
* Inline is reserved for raster images, which cannot execute anything.
|
|
205
|
+
* Everything else - SVG, PDF, office docs, whatever an older row happens
|
|
206
|
+
* to hold - downloads instead of rendering. This is deliberately not an
|
|
207
|
+
* SVG ban: <img> and <link rel="icon"> ignore Content-Disposition, so
|
|
208
|
+
* status page logos, favicons and avatars still render. The only
|
|
209
|
+
* behaviour that changes is a top-level navigation to the file URL, and
|
|
210
|
+
* that is exactly the navigation an XSS payload needs.
|
|
211
|
+
*/
|
|
212
|
+
oneUptimeResponse.set(
|
|
213
|
+
"Content-Disposition",
|
|
214
|
+
Response.getContentDisposition(
|
|
215
|
+
SAFE_IMAGE_MIME_TYPES.has(fileType) ? "inline" : "attachment",
|
|
216
|
+
file.name,
|
|
217
|
+
),
|
|
218
|
+
);
|
|
219
|
+
|
|
82
220
|
oneUptimeResponse.status(200);
|
|
83
|
-
/** Return response */
|
|
84
|
-
// readstream.pipe(res);
|
|
85
221
|
|
|
86
222
|
oneUptimeResponse.send(file.file);
|
|
87
223
|
}
|