@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,138 @@
|
|
|
1
|
+
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
2
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
3
|
+
import DatabaseService from "./DatabaseService";
|
|
4
|
+
import UserService from "./UserService";
|
|
5
|
+
import Model from "../../Models/DatabaseModels/DeletedProject";
|
|
6
|
+
import Project from "../../Models/DatabaseModels/Project";
|
|
7
|
+
import User from "../../Models/DatabaseModels/User";
|
|
8
|
+
import OneUptimeDate from "../../Types/Date";
|
|
9
|
+
import ObjectID from "../../Types/ObjectID";
|
|
10
|
+
import Phone from "../../Types/Phone";
|
|
11
|
+
|
|
12
|
+
export class Service extends DatabaseService<Model> {
|
|
13
|
+
public constructor() {
|
|
14
|
+
super(Model);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Records a project that has just been deleted so the team can follow up with
|
|
19
|
+
* the customer. The project row is already gone by the time this runs, so
|
|
20
|
+
* everything written here has to come from the snapshot the caller took
|
|
21
|
+
* before the delete (ProjectService.onBeforeDelete).
|
|
22
|
+
*
|
|
23
|
+
* SaaS only. Self-hosted installs have no one to reach out to, and the
|
|
24
|
+
* gate lives here rather than at the call site so every caller gets it.
|
|
25
|
+
*
|
|
26
|
+
* Returns the row it wrote, or null when logging was skipped.
|
|
27
|
+
*/
|
|
28
|
+
@CaptureSpan()
|
|
29
|
+
public async logProjectDeletion(data: {
|
|
30
|
+
project: Project;
|
|
31
|
+
deletedByUserId?: ObjectID | undefined;
|
|
32
|
+
deletionReason?: string | undefined;
|
|
33
|
+
}): Promise<Model | null> {
|
|
34
|
+
if (!IsBillingEnabled) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const project: Project = data.project;
|
|
39
|
+
|
|
40
|
+
if (!project.id) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* Who to reach out to. The user who deleted the project is usually also
|
|
46
|
+
* the one who created it - reuse the snapshot in that case instead of
|
|
47
|
+
* spending a query on it.
|
|
48
|
+
*/
|
|
49
|
+
let deletedByUser: User | null = null;
|
|
50
|
+
|
|
51
|
+
if (data.deletedByUserId) {
|
|
52
|
+
if (
|
|
53
|
+
project.createdByUser &&
|
|
54
|
+
project.createdByUserId?.toString() === data.deletedByUserId.toString()
|
|
55
|
+
) {
|
|
56
|
+
deletedByUser = project.createdByUser;
|
|
57
|
+
} else {
|
|
58
|
+
deletedByUser = await UserService.findOneById({
|
|
59
|
+
id: data.deletedByUserId,
|
|
60
|
+
select: {
|
|
61
|
+
_id: true,
|
|
62
|
+
name: true,
|
|
63
|
+
email: true,
|
|
64
|
+
companyName: true,
|
|
65
|
+
companyPhoneNumber: true,
|
|
66
|
+
companySize: true,
|
|
67
|
+
jobRole: true,
|
|
68
|
+
},
|
|
69
|
+
props: {
|
|
70
|
+
isRoot: true,
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const createdByUser: User | undefined = project.createdByUser;
|
|
77
|
+
|
|
78
|
+
const deletedProject: Model = new Model();
|
|
79
|
+
|
|
80
|
+
deletedProject.projectId = project.id;
|
|
81
|
+
deletedProject.projectName = project.name || "";
|
|
82
|
+
deletedProject.projectSlug = project.slug;
|
|
83
|
+
deletedProject.projectCreatedAt = project.createdAt;
|
|
84
|
+
deletedProject.projectDeletedAt = OneUptimeDate.getCurrentDate();
|
|
85
|
+
deletedProject.deletionReason = data.deletionReason;
|
|
86
|
+
|
|
87
|
+
deletedProject.projectDeletedByUserId = data.deletedByUserId;
|
|
88
|
+
deletedProject.projectDeletedByUserName = deletedByUser?.name?.toString();
|
|
89
|
+
deletedProject.projectDeletedByUserEmail = deletedByUser?.email;
|
|
90
|
+
|
|
91
|
+
deletedProject.projectCreatedByUserId = project.createdByUserId;
|
|
92
|
+
deletedProject.projectCreatedByUserName = createdByUser?.name?.toString();
|
|
93
|
+
deletedProject.projectCreatedByUserEmail = createdByUser?.email;
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
* Company details are collected at signup and hang off the User, so take
|
|
97
|
+
* them from whoever created the project and fall back to whoever deleted
|
|
98
|
+
* it - between the two there is usually one filled-in answer.
|
|
99
|
+
*/
|
|
100
|
+
const companyName: string | undefined =
|
|
101
|
+
createdByUser?.companyName || deletedByUser?.companyName;
|
|
102
|
+
const companyPhoneNumber: Phone | undefined =
|
|
103
|
+
createdByUser?.companyPhoneNumber || deletedByUser?.companyPhoneNumber;
|
|
104
|
+
const companySize: string | undefined =
|
|
105
|
+
createdByUser?.companySize || deletedByUser?.companySize;
|
|
106
|
+
const jobRole: string | undefined =
|
|
107
|
+
createdByUser?.jobRole || deletedByUser?.jobRole;
|
|
108
|
+
|
|
109
|
+
deletedProject.companyName = companyName;
|
|
110
|
+
deletedProject.companyPhoneNumber = companyPhoneNumber;
|
|
111
|
+
deletedProject.companySize = companySize;
|
|
112
|
+
deletedProject.jobRole = jobRole;
|
|
113
|
+
|
|
114
|
+
deletedProject.planName = project.planName;
|
|
115
|
+
deletedProject.paymentProviderPlanId = project.paymentProviderPlanId;
|
|
116
|
+
deletedProject.paymentProviderCustomerId =
|
|
117
|
+
project.paymentProviderCustomerId;
|
|
118
|
+
deletedProject.paymentProviderSubscriptionId =
|
|
119
|
+
project.paymentProviderSubscriptionId;
|
|
120
|
+
deletedProject.paymentProviderSubscriptionStatus =
|
|
121
|
+
project.paymentProviderSubscriptionStatus;
|
|
122
|
+
deletedProject.paymentProviderSubscriptionSeats =
|
|
123
|
+
project.paymentProviderSubscriptionSeats;
|
|
124
|
+
deletedProject.trialEndsAt = project.trialEndsAt;
|
|
125
|
+
|
|
126
|
+
deletedProject.activeMonitorCount = project.currentActiveMonitorsCount;
|
|
127
|
+
deletedProject.wasProjectBlocked = project.isBlocked ?? false;
|
|
128
|
+
|
|
129
|
+
return await this.create({
|
|
130
|
+
data: deletedProject,
|
|
131
|
+
props: {
|
|
132
|
+
isRoot: true,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export default new Service();
|
|
@@ -4,15 +4,30 @@ import FindBy from "../Types/Database/FindBy";
|
|
|
4
4
|
import { OnCreate, OnDelete, OnFind, OnUpdate } from "../Types/Database/Hooks";
|
|
5
5
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
6
6
|
import DatabaseService from "./DatabaseService";
|
|
7
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
7
8
|
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
|
|
8
9
|
import File from "../../Models/DatabaseModels/File";
|
|
10
|
+
import MimeType from "../../Types/File/MimeType";
|
|
11
|
+
import ObjectID from "../../Types/ObjectID";
|
|
9
12
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
13
|
+
import logger from "../Utils/Logger";
|
|
10
14
|
import crypto from "crypto";
|
|
11
15
|
|
|
12
16
|
const generateImageAccessToken: () => string = (): string => {
|
|
13
17
|
return crypto.randomBytes(32).toString("hex");
|
|
14
18
|
};
|
|
15
19
|
|
|
20
|
+
/*
|
|
21
|
+
* fileType is declared as MimeType but persisted as a varchar, so the enum
|
|
22
|
+
* buys nothing at runtime - the API will happily store "text/html" if a client
|
|
23
|
+
* asks for it. Response.sendFileResponse refuses to echo an unknown type back,
|
|
24
|
+
* but keeping junk out of the column in the first place means the stored row
|
|
25
|
+
* matches what we are willing to serve.
|
|
26
|
+
*/
|
|
27
|
+
const ALLOWED_MIME_TYPES: Set<string> = new Set<string>(
|
|
28
|
+
Object.values(MimeType),
|
|
29
|
+
);
|
|
30
|
+
|
|
16
31
|
export class Service extends DatabaseService<File> {
|
|
17
32
|
public constructor() {
|
|
18
33
|
super(File);
|
|
@@ -22,6 +37,18 @@ export class Service extends DatabaseService<File> {
|
|
|
22
37
|
protected override async onBeforeCreate(
|
|
23
38
|
createBy: CreateBy<File>,
|
|
24
39
|
): Promise<OnCreate<File>> {
|
|
40
|
+
const fileType: string = (createBy.data.fileType || "")
|
|
41
|
+
.trim()
|
|
42
|
+
.toLowerCase();
|
|
43
|
+
|
|
44
|
+
if (!ALLOWED_MIME_TYPES.has(fileType)) {
|
|
45
|
+
throw new BadDataException(
|
|
46
|
+
"This file type is not supported. Please upload a supported file type.",
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
createBy.data.fileType = fileType as MimeType;
|
|
51
|
+
|
|
25
52
|
/*
|
|
26
53
|
* Always generate an unguessable access token server-side. The token
|
|
27
54
|
* is the only safe way to address an inline-uploaded image in
|
|
@@ -56,6 +83,40 @@ export class Service extends DatabaseService<File> {
|
|
|
56
83
|
return { deleteBy, carryForward: null };
|
|
57
84
|
}
|
|
58
85
|
|
|
86
|
+
/*
|
|
87
|
+
* Marks a file as anonymously readable. Uploads from the file picker
|
|
88
|
+
* arrive private, so attaching one as an intentionally public asset
|
|
89
|
+
* (probe icon, AI agent icon) is the point at which it becomes public
|
|
90
|
+
* — those are served by the id-based image route, which serves only
|
|
91
|
+
* public files. Best-effort: a visibility sync failure must never fail
|
|
92
|
+
* the write the user actually asked for.
|
|
93
|
+
*/
|
|
94
|
+
@CaptureSpan()
|
|
95
|
+
public async makeFilePublic(
|
|
96
|
+
fileId: ObjectID | undefined | null,
|
|
97
|
+
): Promise<void> {
|
|
98
|
+
if (!fileId) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
await this.updateOneById({
|
|
104
|
+
id: fileId,
|
|
105
|
+
data: {
|
|
106
|
+
isPublic: true,
|
|
107
|
+
},
|
|
108
|
+
props: {
|
|
109
|
+
isRoot: true,
|
|
110
|
+
ignoreHooks: true,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
} catch (err) {
|
|
114
|
+
logger.error(
|
|
115
|
+
`Failed to mark file ${fileId.toString()} public: ${String(err)}`,
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
59
120
|
@CaptureSpan()
|
|
60
121
|
protected override async onBeforeFind(
|
|
61
122
|
findBy: FindBy<File>,
|
|
@@ -14,6 +14,7 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
|
14
14
|
import StatusPageSubscriberNotificationStatus from "../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
|
|
15
15
|
import File from "../../Models/DatabaseModels/File";
|
|
16
16
|
import FileAttachmentMarkdownUtil from "../Utils/FileAttachmentMarkdownUtil";
|
|
17
|
+
import { syncIsPublicForMarkdownImages } from "../Utils/InlineImageAccessTokenSync";
|
|
17
18
|
|
|
18
19
|
export class Service extends DatabaseService<Model> {
|
|
19
20
|
public constructor() {
|
|
@@ -116,6 +117,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
116
117
|
const userId: ObjectID | null | undefined =
|
|
117
118
|
createdItem.createdByUserId || createdItem.createdByUser?.id;
|
|
118
119
|
|
|
120
|
+
/*
|
|
121
|
+
* A public note is always rendered on the status page, so any inline
|
|
122
|
+
* image the markdown editor uploaded as private must flip to public
|
|
123
|
+
* for anonymous status page viewers to be able to render it.
|
|
124
|
+
*/
|
|
125
|
+
await syncIsPublicForMarkdownImages(
|
|
126
|
+
createdItem.note,
|
|
127
|
+
true,
|
|
128
|
+
`incident episode public note ${createdItem.id?.toString()}`,
|
|
129
|
+
);
|
|
130
|
+
|
|
119
131
|
const incidentEpisodeId: ObjectID = createdItem.incidentEpisodeId!;
|
|
120
132
|
const projectId: ObjectID = createdItem.projectId!;
|
|
121
133
|
const episodeNumberResult: {
|
|
@@ -185,6 +197,12 @@ ${(createdItem.note || "") + attachmentsMarkdown}
|
|
|
185
197
|
for (const updatedItem of updatedItems) {
|
|
186
198
|
const episode: IncidentEpisode = updatedItem.incidentEpisode!;
|
|
187
199
|
|
|
200
|
+
await syncIsPublicForMarkdownImages(
|
|
201
|
+
updatedItem.note,
|
|
202
|
+
true,
|
|
203
|
+
`incident episode public note ${updatedItem.id?.toString()}`,
|
|
204
|
+
);
|
|
205
|
+
|
|
188
206
|
const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
|
|
189
207
|
updatedItem.id!,
|
|
190
208
|
"/incident-episode-public-note/attachment",
|
|
@@ -14,6 +14,7 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
|
14
14
|
import StatusPageSubscriberNotificationStatus from "../../Types/StatusPage/StatusPageSubscriberNotificationStatus";
|
|
15
15
|
import File from "../../Models/DatabaseModels/File";
|
|
16
16
|
import FileAttachmentMarkdownUtil from "../Utils/FileAttachmentMarkdownUtil";
|
|
17
|
+
import { syncIsPublicForMarkdownImages } from "../Utils/InlineImageAccessTokenSync";
|
|
17
18
|
|
|
18
19
|
export class Service extends DatabaseService<Model> {
|
|
19
20
|
public constructor() {
|
|
@@ -116,6 +117,17 @@ export class Service extends DatabaseService<Model> {
|
|
|
116
117
|
const userId: ObjectID | null | undefined =
|
|
117
118
|
createdItem.createdByUserId || createdItem.createdByUser?.id;
|
|
118
119
|
|
|
120
|
+
/*
|
|
121
|
+
* A public note is always rendered on the status page, so any inline
|
|
122
|
+
* image the markdown editor uploaded as private must flip to public
|
|
123
|
+
* for anonymous status page viewers to be able to render it.
|
|
124
|
+
*/
|
|
125
|
+
await syncIsPublicForMarkdownImages(
|
|
126
|
+
createdItem.note,
|
|
127
|
+
true,
|
|
128
|
+
`incident public note ${createdItem.id?.toString()}`,
|
|
129
|
+
);
|
|
130
|
+
|
|
119
131
|
const incidentId: ObjectID = createdItem.incidentId!;
|
|
120
132
|
const projectId: ObjectID = createdItem.projectId!;
|
|
121
133
|
const incidentNumberResult: {
|
|
@@ -187,6 +199,12 @@ ${(createdItem.note || "") + attachmentsMarkdown}
|
|
|
187
199
|
for (const updatedItem of updatedItems) {
|
|
188
200
|
const incident: Incident = updatedItem.incident!;
|
|
189
201
|
|
|
202
|
+
await syncIsPublicForMarkdownImages(
|
|
203
|
+
updatedItem.note,
|
|
204
|
+
true,
|
|
205
|
+
`incident public note ${updatedItem.id?.toString()}`,
|
|
206
|
+
);
|
|
207
|
+
|
|
190
208
|
const attachmentsMarkdown: string = await this.getAttachmentsMarkdown(
|
|
191
209
|
updatedItem.id!,
|
|
192
210
|
"/incident-public-note/attachment",
|
package/Server/Services/Index.ts
CHANGED
|
@@ -283,10 +283,12 @@ import NetworkFlowService from "./NetworkFlowService";
|
|
|
283
283
|
import OnCallDutyPolicyTimeLogService from "./OnCallDutyPolicyTimeLogService";
|
|
284
284
|
import ProjectSCIMLogService from "./ProjectSCIMLogService";
|
|
285
285
|
import StatusPageSCIMLogService from "./StatusPageSCIMLogService";
|
|
286
|
+
import DeletedProjectService from "./DeletedProjectService";
|
|
286
287
|
|
|
287
288
|
const services: Array<BaseService> = [
|
|
288
289
|
OnCallDutyPolicyTimeLogService,
|
|
289
290
|
AcmeCertificateService,
|
|
291
|
+
DeletedProjectService,
|
|
290
292
|
PromoCodeService,
|
|
291
293
|
EnterpriseLicenseService,
|
|
292
294
|
EnterpriseLicenseInstanceService,
|
|
@@ -464,9 +464,307 @@ export class Service extends DatabaseService<Model> {
|
|
|
464
464
|
}
|
|
465
465
|
}
|
|
466
466
|
|
|
467
|
+
if (
|
|
468
|
+
updateBy.data.dependsOnMonitors !== undefined ||
|
|
469
|
+
updateBy.data.suppressAlertsWhenParentMonitorStatuses !== undefined
|
|
470
|
+
) {
|
|
471
|
+
/*
|
|
472
|
+
* The matched monitors' own ids (self/cycle checks) and projects
|
|
473
|
+
* (parent scoping) are needed; root/API updates do not always carry
|
|
474
|
+
* a tenantId. Validation itself is hoisted: the proposed lists are
|
|
475
|
+
* identical for every matched monitor, so existence/project checks
|
|
476
|
+
* run once per distinct project and the cycle walk runs once for
|
|
477
|
+
* all targets — not once per monitor (a bulk update could match
|
|
478
|
+
* thousands).
|
|
479
|
+
*/
|
|
480
|
+
const monitorsToValidate: Array<Model> = await this.findBy({
|
|
481
|
+
query: updateBy.query,
|
|
482
|
+
select: {
|
|
483
|
+
_id: true,
|
|
484
|
+
projectId: true,
|
|
485
|
+
},
|
|
486
|
+
limit: LIMIT_MAX,
|
|
487
|
+
skip: 0,
|
|
488
|
+
props: {
|
|
489
|
+
isRoot: true,
|
|
490
|
+
ignoreHooks: true,
|
|
491
|
+
},
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
await this.validateDependencyConfiguration({
|
|
495
|
+
targets: monitorsToValidate.map((monitor: Model) => {
|
|
496
|
+
return {
|
|
497
|
+
monitorId: monitor.id || null,
|
|
498
|
+
projectId: updateBy.props.tenantId || monitor.projectId || null,
|
|
499
|
+
};
|
|
500
|
+
}),
|
|
501
|
+
proposedParents: updateBy.data.dependsOnMonitors,
|
|
502
|
+
proposedSuppressionStatuses:
|
|
503
|
+
updateBy.data.suppressAlertsWhenParentMonitorStatuses,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
|
|
467
507
|
return { updateBy, carryForward: null };
|
|
468
508
|
}
|
|
469
509
|
|
|
510
|
+
/*
|
|
511
|
+
* Guards for the alert-dependency configuration. `undefined` means "not
|
|
512
|
+
* part of this write" and validates nothing; null or an empty array
|
|
513
|
+
* (clearing the config) is always valid. The proposed lists arrive in
|
|
514
|
+
* whatever shape the API produced — relation objects, ObjectIDs, or
|
|
515
|
+
* bare uuid strings (which DatabaseService.sanitizeCreateOrUpdate only
|
|
516
|
+
* converts to entities AFTER this hook has run) — so extraction goes
|
|
517
|
+
* through resolveReferenceId, and every id comparison is normalized to
|
|
518
|
+
* lower case because Postgres matches uuids case-insensitively while
|
|
519
|
+
* ObjectID preserves the caller's casing.
|
|
520
|
+
*/
|
|
521
|
+
public async validateDependencyConfiguration(input: {
|
|
522
|
+
/**
|
|
523
|
+
* The monitors this write applies to. monitorId is null on create —
|
|
524
|
+
* a new monitor cannot be part of a cycle yet.
|
|
525
|
+
*/
|
|
526
|
+
targets: Array<{
|
|
527
|
+
monitorId: ObjectID | null;
|
|
528
|
+
projectId: ObjectID | null;
|
|
529
|
+
}>;
|
|
530
|
+
proposedParents: unknown;
|
|
531
|
+
proposedSuppressionStatuses: unknown;
|
|
532
|
+
}): Promise<void> {
|
|
533
|
+
const distinctProjectIds: Array<ObjectID> = [];
|
|
534
|
+
const seenProjectIds: Set<string> = new Set<string>();
|
|
535
|
+
|
|
536
|
+
for (const target of input.targets) {
|
|
537
|
+
const key: string | undefined = target.projectId
|
|
538
|
+
?.toString()
|
|
539
|
+
.trim()
|
|
540
|
+
.toLowerCase();
|
|
541
|
+
|
|
542
|
+
if (key && !seenProjectIds.has(key)) {
|
|
543
|
+
seenProjectIds.add(key);
|
|
544
|
+
distinctProjectIds.push(target.projectId!);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
if (input.proposedParents !== undefined) {
|
|
549
|
+
const parentIds: Array<ObjectID> = this.extractRelationIds(
|
|
550
|
+
input.proposedParents,
|
|
551
|
+
);
|
|
552
|
+
|
|
553
|
+
if (parentIds.length > 0) {
|
|
554
|
+
const parentIdSet: Set<string> = new Set<string>(
|
|
555
|
+
parentIds.map((id: ObjectID) => {
|
|
556
|
+
return id.toString();
|
|
557
|
+
}),
|
|
558
|
+
);
|
|
559
|
+
|
|
560
|
+
for (const target of input.targets) {
|
|
561
|
+
const targetKey: string | undefined = target.monitorId
|
|
562
|
+
?.toString()
|
|
563
|
+
.trim()
|
|
564
|
+
.toLowerCase();
|
|
565
|
+
|
|
566
|
+
if (targetKey && parentIdSet.has(targetKey)) {
|
|
567
|
+
throw new BadDataException("A monitor cannot depend on itself.");
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/*
|
|
572
|
+
* Existence + same-project via the house validator (which owns
|
|
573
|
+
* the case normalization and message wording). Once per distinct
|
|
574
|
+
* project: parents must belong to every matched monitor's
|
|
575
|
+
* project, so a cross-project bulk update correctly fails.
|
|
576
|
+
*/
|
|
577
|
+
for (const projectId of distinctProjectIds) {
|
|
578
|
+
await ProjectScopedReferenceValidator.validateReferencesBelongToProject(
|
|
579
|
+
{
|
|
580
|
+
projectId: projectId,
|
|
581
|
+
subject: "monitor",
|
|
582
|
+
references: parentIds.map((parentId: ObjectID) => {
|
|
583
|
+
return {
|
|
584
|
+
modelName: "Monitor",
|
|
585
|
+
id: parentId,
|
|
586
|
+
service: this,
|
|
587
|
+
};
|
|
588
|
+
}),
|
|
589
|
+
},
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
const targetMonitorIds: Array<ObjectID> = input.targets
|
|
594
|
+
.map((target: { monitorId: ObjectID | null }) => {
|
|
595
|
+
return target.monitorId;
|
|
596
|
+
})
|
|
597
|
+
.filter((monitorId: ObjectID | null): monitorId is ObjectID => {
|
|
598
|
+
return Boolean(monitorId);
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
if (targetMonitorIds.length > 0) {
|
|
602
|
+
await this.throwIfDependencyCycle({
|
|
603
|
+
targetMonitorIds,
|
|
604
|
+
proposedParentIds: parentIds,
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
if (input.proposedSuppressionStatuses !== undefined) {
|
|
611
|
+
const statusIds: Array<ObjectID> = this.extractRelationIds(
|
|
612
|
+
input.proposedSuppressionStatuses,
|
|
613
|
+
);
|
|
614
|
+
|
|
615
|
+
if (statusIds.length > 0) {
|
|
616
|
+
for (const projectId of distinctProjectIds) {
|
|
617
|
+
await ProjectScopedReferenceValidator.validateReferencesBelongToProject(
|
|
618
|
+
{
|
|
619
|
+
projectId: projectId,
|
|
620
|
+
subject: "monitor",
|
|
621
|
+
references: statusIds.map((statusId: ObjectID) => {
|
|
622
|
+
return {
|
|
623
|
+
modelName: "Monitor Status",
|
|
624
|
+
id: statusId,
|
|
625
|
+
service: MonitorStatusService,
|
|
626
|
+
};
|
|
627
|
+
}),
|
|
628
|
+
},
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/*
|
|
636
|
+
* Walk the dependency graph upward from the proposed parents; reaching
|
|
637
|
+
* any monitor being updated means the write would close a cycle, which
|
|
638
|
+
* would make suppression self-referential (A suppressed because of B,
|
|
639
|
+
* B suppressed because of A) and must be rejected. One BFS covers every
|
|
640
|
+
* target of a bulk update. The visited set bounds the walk even if a
|
|
641
|
+
* cycle already exists among ancestors, and the depth cap keeps the
|
|
642
|
+
* check cheap on degenerate graphs.
|
|
643
|
+
*
|
|
644
|
+
* This validates committed state, so two updates racing each other can
|
|
645
|
+
* still jointly commit a cycle this walk could not see; the runtime
|
|
646
|
+
* mutual-cycle guard in MonitorDependencySuppression fails open (pages
|
|
647
|
+
* instead of suppressing) if that ever happens.
|
|
648
|
+
*/
|
|
649
|
+
private async throwIfDependencyCycle(input: {
|
|
650
|
+
targetMonitorIds: Array<ObjectID>;
|
|
651
|
+
proposedParentIds: Array<ObjectID>;
|
|
652
|
+
}): Promise<void> {
|
|
653
|
+
const maxDepth: number = 32;
|
|
654
|
+
|
|
655
|
+
const targetIdSet: Set<string> = new Set<string>(
|
|
656
|
+
input.targetMonitorIds.map((monitorId: ObjectID) => {
|
|
657
|
+
return monitorId.toString().trim().toLowerCase();
|
|
658
|
+
}),
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
const visited: Set<string> = new Set<string>();
|
|
662
|
+
let frontier: Array<ObjectID> = [...input.proposedParentIds];
|
|
663
|
+
|
|
664
|
+
for (let depth: number = 0; depth < maxDepth; depth++) {
|
|
665
|
+
if (frontier.length === 0) {
|
|
666
|
+
return;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (
|
|
670
|
+
frontier.some((id: ObjectID) => {
|
|
671
|
+
return targetIdSet.has(id.toString().trim().toLowerCase());
|
|
672
|
+
})
|
|
673
|
+
) {
|
|
674
|
+
throw new BadDataException(
|
|
675
|
+
"This dependency would create a cycle: one of the selected monitors (or a monitor it depends on) already depends on this monitor.",
|
|
676
|
+
);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
for (const id of frontier) {
|
|
680
|
+
visited.add(id.toString().trim().toLowerCase());
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
const rows: Array<Model> = await this.findBy({
|
|
684
|
+
query: {
|
|
685
|
+
_id: QueryHelper.any(frontier),
|
|
686
|
+
},
|
|
687
|
+
select: {
|
|
688
|
+
_id: true,
|
|
689
|
+
dependsOnMonitors: {
|
|
690
|
+
_id: true,
|
|
691
|
+
},
|
|
692
|
+
},
|
|
693
|
+
limit: LIMIT_PER_PROJECT,
|
|
694
|
+
skip: 0,
|
|
695
|
+
props: {
|
|
696
|
+
isRoot: true,
|
|
697
|
+
},
|
|
698
|
+
});
|
|
699
|
+
|
|
700
|
+
/*
|
|
701
|
+
* Fail CLOSED on truncation: a frontier level wider than the query
|
|
702
|
+
* limit means ancestors were dropped and a real cycle routed
|
|
703
|
+
* through the remainder would be admitted. Refuse instead — the
|
|
704
|
+
* sibling existence check fails closed the same way.
|
|
705
|
+
*/
|
|
706
|
+
if (rows.length >= LIMIT_PER_PROJECT) {
|
|
707
|
+
throw new BadDataException(
|
|
708
|
+
"This dependency graph is too large to verify for cycles. Please reduce the number of monitors sharing one dependency level.",
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
const next: Array<ObjectID> = [];
|
|
713
|
+
|
|
714
|
+
for (const row of rows) {
|
|
715
|
+
for (const grandParentId of this.extractRelationIds(
|
|
716
|
+
row.dependsOnMonitors || [],
|
|
717
|
+
)) {
|
|
718
|
+
if (!visited.has(grandParentId.toString())) {
|
|
719
|
+
next.push(grandParentId);
|
|
720
|
+
visited.add(grandParentId.toString());
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
frontier = next;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
if (frontier.length > 0) {
|
|
729
|
+
throw new BadDataException(
|
|
730
|
+
`Monitor dependency chains deeper than ${maxDepth} levels are not supported.`,
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/*
|
|
736
|
+
* Ids arrive as relation objects ({_id}), ObjectIDs, or bare uuid
|
|
737
|
+
* strings depending on which API path produced the payload —
|
|
738
|
+
* resolveReferenceId handles all three (reading only ._id/.id here
|
|
739
|
+
* silently missed the bare-string shape, which DatabaseService
|
|
740
|
+
* persists). Returned ids are normalized to lower case so every
|
|
741
|
+
* comparison downstream matches the way Postgres matches uuids. null /
|
|
742
|
+
* non-array input (explicit null is TypeORM's clear-all for relation
|
|
743
|
+
* columns) yields an empty list: nothing to validate.
|
|
744
|
+
*/
|
|
745
|
+
private extractRelationIds(relationArray: unknown): Array<ObjectID> {
|
|
746
|
+
if (!Array.isArray(relationArray)) {
|
|
747
|
+
return [];
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
const ids: Array<ObjectID> = [];
|
|
751
|
+
const seen: Set<string> = new Set<string>();
|
|
752
|
+
|
|
753
|
+
for (const item of relationArray) {
|
|
754
|
+
const rawId: string | undefined = resolveReferenceId(item)
|
|
755
|
+
?.toString()
|
|
756
|
+
.trim()
|
|
757
|
+
.toLowerCase();
|
|
758
|
+
|
|
759
|
+
if (rawId && !seen.has(rawId)) {
|
|
760
|
+
seen.add(rawId);
|
|
761
|
+
ids.push(new ObjectID(rawId));
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
return ids;
|
|
766
|
+
}
|
|
767
|
+
|
|
470
768
|
private async getProjectIdsForUpdateQuery(
|
|
471
769
|
updateBy: UpdateBy<Model>,
|
|
472
770
|
): Promise<Array<ObjectID>> {
|
|
@@ -781,6 +1079,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
781
1079
|
projectId: createBy.props.tenantId,
|
|
782
1080
|
});
|
|
783
1081
|
|
|
1082
|
+
await this.validateDependencyConfiguration({
|
|
1083
|
+
// A new monitor cannot be part of a cycle yet, hence monitorId null.
|
|
1084
|
+
targets: [
|
|
1085
|
+
{
|
|
1086
|
+
monitorId: null,
|
|
1087
|
+
projectId: createBy.props.tenantId,
|
|
1088
|
+
},
|
|
1089
|
+
],
|
|
1090
|
+
proposedParents: createBy.data.dependsOnMonitors,
|
|
1091
|
+
proposedSuppressionStatuses:
|
|
1092
|
+
createBy.data.suppressAlertsWhenParentMonitorStatuses,
|
|
1093
|
+
});
|
|
1094
|
+
|
|
784
1095
|
/*
|
|
785
1096
|
* A new monitor starts in the project's operational status. A project can
|
|
786
1097
|
* hold MORE than one operational state (a user - or an E2E fixture - can
|
|
@@ -29,6 +29,7 @@ import DatabaseConfig from "../DatabaseConfig";
|
|
|
29
29
|
import URL from "../../Types/API/URL";
|
|
30
30
|
import UpdateBy from "../Types/Database/UpdateBy";
|
|
31
31
|
import MonitorService from "./MonitorService";
|
|
32
|
+
import FileService from "./FileService";
|
|
32
33
|
import PushNotificationMessage from "../../Types/PushNotification/PushNotificationMessage";
|
|
33
34
|
import PushNotificationUtil from "../Utils/PushNotificationUtil";
|
|
34
35
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
@@ -435,6 +436,21 @@ export class Service extends DatabaseService<Model> {
|
|
|
435
436
|
return { createBy: createBy, carryForward: [] };
|
|
436
437
|
}
|
|
437
438
|
|
|
439
|
+
/*
|
|
440
|
+
* A probe icon is rendered by the id-based image route, which serves
|
|
441
|
+
* only public files. The file picker uploads it private, so attaching
|
|
442
|
+
* it to a probe is the point at which it becomes public.
|
|
443
|
+
*/
|
|
444
|
+
@CaptureSpan()
|
|
445
|
+
protected override async onCreateSuccess(
|
|
446
|
+
_onCreate: OnCreate<Model>,
|
|
447
|
+
createdItem: Model,
|
|
448
|
+
): Promise<Model> {
|
|
449
|
+
await FileService.makeFilePublic(createdItem.iconFileId);
|
|
450
|
+
|
|
451
|
+
return createdItem;
|
|
452
|
+
}
|
|
453
|
+
|
|
438
454
|
/*
|
|
439
455
|
* Only global probes and probes belonging to this project may be attached to
|
|
440
456
|
* that project's monitors. Probe ids reach the server from the browser - the
|
|
@@ -626,6 +642,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
626
642
|
await this.invalidateProbeAuthCache(updatedItemIds);
|
|
627
643
|
}
|
|
628
644
|
|
|
645
|
+
await FileService.makeFilePublic(
|
|
646
|
+
onUpdate.updateBy.data.iconFileId as ObjectID | undefined,
|
|
647
|
+
);
|
|
648
|
+
|
|
629
649
|
if (
|
|
630
650
|
onUpdate.carryForward &&
|
|
631
651
|
onUpdate.carryForward.probesToNotifyOwners.length > 0
|