@oneuptime/common 11.7.2 → 11.7.4
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/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
- package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/Index.ts +5 -0
- package/Models/DatabaseModels/LogDropFilter.ts +89 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
- package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
- package/Models/DatabaseModels/TableView.ts +40 -0
- package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
- package/Server/API/AlertAPI.ts +32 -17
- package/Server/API/BaseAPI.ts +31 -2
- package/Server/API/BaseAnalyticsAPI.ts +36 -2
- package/Server/API/CommonAPI.ts +57 -0
- package/Server/API/IncidentAPI.ts +60 -33
- package/Server/API/IncidentEpisodeAPI.ts +31 -16
- package/Server/API/MonitorAPI.ts +30 -0
- package/Server/API/MonitorTemplateAPI.ts +8 -0
- package/Server/API/ProbeAPI.ts +196 -15
- package/Server/API/ProjectAPI.ts +79 -1
- package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
- package/Server/API/StatusPageAPI.ts +74 -37
- package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Services/AlertEpisodeService.ts +47 -0
- package/Server/Services/AlertService.ts +125 -0
- package/Server/Services/BillingService.ts +98 -0
- package/Server/Services/DatabaseService.ts +184 -20
- package/Server/Services/IncidentEpisodeService.ts +47 -0
- package/Server/Services/IncidentService.ts +123 -0
- package/Server/Services/IncidentTemplateService.ts +123 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/LogDropFilterService.ts +133 -0
- package/Server/Services/MonitorProbeService.ts +94 -4
- package/Server/Services/MonitorService.ts +48 -43
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
- package/Server/Services/ProbeService.ts +66 -0
- package/Server/Services/ProjectService.ts +131 -7
- package/Server/Services/RecommendationDismissalService.ts +52 -0
- package/Server/Services/RunbookAgentJobService.ts +68 -7
- package/Server/Services/ScheduledMaintenanceService.ts +103 -0
- package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
- package/Server/Services/StatusPageGroupService.ts +186 -0
- package/Server/Services/TraceDropFilterService.ts +133 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
- package/Server/Types/Workflow/Components/API/Get.ts +12 -0
- package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
- package/Server/Types/Workflow/Components/API/Post.ts +12 -0
- package/Server/Types/Workflow/Components/API/Put.ts +13 -0
- package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
- package/Server/Utils/DropFilterValidation.ts +127 -0
- package/Server/Utils/Errors.ts +5 -0
- package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
- package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
- package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
- package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
- package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
- package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
- package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
- package/Tests/Server/API/ProbeAPI.test.ts +422 -53
- package/Tests/Server/API/ProjectAPI.test.ts +180 -0
- package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
- package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
- package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
- package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
- package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
- package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
- package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
- package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
- package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
- package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
- package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
- package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
- package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
- package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
- package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
- package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
- package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
- package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
- package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
- package/Tests/Types/DateUserTimezone.test.ts +52 -0
- package/Tests/Types/JSONFunctions.test.ts +103 -1
- package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
- package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
- package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
- package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
- package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
- package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
- package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
- package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
- package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
- package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
- package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
- package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
- package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
- package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
- package/Tests/UI/Components/InfoCard.test.tsx +358 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
- package/Tests/UI/Components/Modal.test.tsx +43 -5
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
- package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
- package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
- package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
- package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
- package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
- package/Tests/Utils/UserPreferences.test.ts +563 -0
- package/Types/Date.ts +15 -6
- package/Types/JSONFunctions.ts +7 -2
- package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
- package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
- package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
- package/Types/Permission.ts +45 -0
- package/Types/Recommendation/RecommendationType.ts +20 -0
- package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
- package/Types/Runbook/RunbookStepTimeout.ts +202 -0
- package/Types/Telemetry/DropFilterSampling.ts +92 -0
- package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
- package/UI/Components/Accordion/Accordion.tsx +10 -2
- package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
- package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
- package/UI/Components/Error/PageError.tsx +0 -4
- package/UI/Components/ErrorBoundary.tsx +252 -15
- package/UI/Components/InfoCard/InfoCard.tsx +58 -1
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
- package/UI/Components/MasterPage/MasterPage.tsx +65 -0
- package/UI/Components/Modal/Modal.tsx +16 -60
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
- package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
- package/UI/Components/ModelTable/Column.ts +17 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
- package/UI/Components/ModelTable/TableView.tsx +24 -2
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
- package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
- package/UI/Components/SideMenu/SideMenu.tsx +24 -4
- package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
- package/UI/Components/Table/Table.tsx +14 -1
- package/UI/Components/Table/TableRow.tsx +180 -175
- package/UI/Components/Table/Types/Column.ts +2 -0
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
- package/UI/Utils/DropdownAlignment.ts +162 -0
- package/UI/Utils/TableFilterUrlState.ts +59 -20
- package/Utils/API.ts +106 -2
- package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
- package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
- package/Utils/StatusPage/GroupTree.ts +307 -0
- package/Utils/StatusPage/ResourceUptime.ts +90 -17
- package/Utils/UserPreferences.ts +53 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
- package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
- package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TableView.js +40 -0
- package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
- package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +22 -13
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +22 -1
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +42 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +43 -26
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorAPI.js +23 -0
- package/build/dist/Server/API/MonitorAPI.js.map +1 -1
- package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
- package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
- package/build/dist/Server/API/ProbeAPI.js +131 -15
- package/build/dist/Server/API/ProbeAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +62 -3
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +61 -33
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
- package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.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/Services/AlertEpisodeService.js +39 -0
- package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +95 -0
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +71 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +140 -17
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +100 -0
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
- package/build/dist/Server/Services/IncidentTemplateService.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/LogDropFilterService.js +93 -0
- package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +73 -5
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +34 -39
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +64 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +103 -7
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
- package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
- package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
- package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
- package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
- package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
- package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
- package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
- package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
- package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
- package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
- package/build/dist/Server/Utils/Errors.js +3 -0
- package/build/dist/Server/Utils/Errors.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
- package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
- package/build/dist/Types/Date.js +14 -4
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +8 -3
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
- package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
- package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
- package/build/dist/Types/Permission.js +40 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
- package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
- package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
- package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
- package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
- package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
- package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
- package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
- package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Error/PageError.js +1 -3
- package/build/dist/UI/Components/Error/PageError.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +145 -11
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
- package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +4 -32
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +308 -40
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
- package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
- package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
- package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +15 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +11 -6
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
- package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
- package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/Utils/API.js +39 -2
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
- package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
- package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
- package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/UserPreferences.js +33 -0
- package/build/dist/Utils/UserPreferences.js.map +1 -1
- package/package.json +1 -1
|
@@ -70,6 +70,9 @@ import WorkspaceNotificationRuleService, {
|
|
|
70
70
|
MessageBlocksByWorkspaceType,
|
|
71
71
|
} from "./WorkspaceNotificationRuleService";
|
|
72
72
|
import MonitorStepsProjectValidator from "../Utils/Monitor/MonitorStepsProjectValidator";
|
|
73
|
+
import ProjectScopedReferenceValidator, {
|
|
74
|
+
resolveReferenceId,
|
|
75
|
+
} from "../Utils/Database/ProjectScopedReferenceValidator";
|
|
73
76
|
import MonitorWorkspaceMessages from "../Utils/Workspace/WorkspaceMessages/Monitor";
|
|
74
77
|
import MonitorFeedService from "./MonitorFeedService";
|
|
75
78
|
import { MonitorFeedEventType } from "../../Models/DatabaseModels/MonitorFeed";
|
|
@@ -388,7 +391,19 @@ export class Service extends DatabaseService<Model> {
|
|
|
388
391
|
protected override async onBeforeUpdate(
|
|
389
392
|
updateBy: UpdateBy<Model>,
|
|
390
393
|
): Promise<OnUpdate<Model>> {
|
|
391
|
-
|
|
394
|
+
/*
|
|
395
|
+
* currentMonitorStatusId is writable by any project member and its FK is
|
|
396
|
+
* ON DELETE NO ACTION, so an id from another project here leaves that
|
|
397
|
+
* project undeletable — the same shape monitorSteps had. The
|
|
398
|
+
* 1785240000000 migration repaired the rows that existed then; this stops
|
|
399
|
+
* new ones. It stays NO ACTION on purpose: deleting a status monitors are
|
|
400
|
+
* currently in should be blocked, not cascaded.
|
|
401
|
+
*/
|
|
402
|
+
const currentMonitorStatusId: ObjectID | string | undefined =
|
|
403
|
+
resolveReferenceId(updateBy.data.currentMonitorStatusId) ||
|
|
404
|
+
resolveReferenceId(updateBy.data.currentMonitorStatus);
|
|
405
|
+
|
|
406
|
+
if (updateBy.data.monitorSteps || currentMonitorStatusId) {
|
|
392
407
|
/*
|
|
393
408
|
* Root/API updates do not always carry a tenantId, so fall back to the
|
|
394
409
|
* project of each monitor the query actually matches.
|
|
@@ -398,10 +413,30 @@ export class Service extends DatabaseService<Model> {
|
|
|
398
413
|
: await this.getProjectIdsForUpdateQuery(updateBy);
|
|
399
414
|
|
|
400
415
|
for (const projectId of projectIds) {
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
416
|
+
if (updateBy.data.monitorSteps) {
|
|
417
|
+
await MonitorStepsProjectValidator.validateMonitorStepsBelongToProject(
|
|
418
|
+
{
|
|
419
|
+
monitorSteps: updateBy.data.monitorSteps as
|
|
420
|
+
| MonitorSteps
|
|
421
|
+
| JSONObject,
|
|
422
|
+
projectId: projectId,
|
|
423
|
+
},
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
await ProjectScopedReferenceValidator.validateReferencesBelongToProject(
|
|
428
|
+
{
|
|
429
|
+
projectId: projectId,
|
|
430
|
+
subject: "monitor",
|
|
431
|
+
references: [
|
|
432
|
+
{
|
|
433
|
+
modelName: "Monitor Status",
|
|
434
|
+
id: currentMonitorStatusId,
|
|
435
|
+
service: MonitorStatusService,
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
},
|
|
439
|
+
);
|
|
405
440
|
}
|
|
406
441
|
}
|
|
407
442
|
|
|
@@ -1207,7 +1242,8 @@ ${createdItem.description?.trim() || "No description provided."}
|
|
|
1207
1242
|
/*
|
|
1208
1243
|
* Only global probes and probes belonging to this project may be attached -
|
|
1209
1244
|
* the id list comes from the browser, so it cannot be trusted to stay inside
|
|
1210
|
-
* the tenant.
|
|
1245
|
+
* the tenant. ProbeService.getProbesAttachableToProject owns that rule and
|
|
1246
|
+
* MonitorProbeService enforces the same one on the CRUD path.
|
|
1211
1247
|
*/
|
|
1212
1248
|
@CaptureSpan()
|
|
1213
1249
|
public async addSelectedProbesToMonitor(
|
|
@@ -1215,47 +1251,16 @@ ${createdItem.description?.trim() || "No description provided."}
|
|
|
1215
1251
|
monitorId: ObjectID,
|
|
1216
1252
|
probeIds: Array<ObjectID>,
|
|
1217
1253
|
): Promise<void> {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
await Promise.all([
|
|
1224
|
-
ProbeService.findBy({
|
|
1225
|
-
query: {
|
|
1226
|
-
_id: QueryHelper.any(probeIds),
|
|
1227
|
-
isGlobalProbe: true,
|
|
1228
|
-
},
|
|
1229
|
-
select: {
|
|
1230
|
-
_id: true,
|
|
1231
|
-
},
|
|
1232
|
-
skip: 0,
|
|
1233
|
-
limit: LIMIT_PER_PROJECT,
|
|
1234
|
-
props: {
|
|
1235
|
-
isRoot: true,
|
|
1236
|
-
},
|
|
1237
|
-
}),
|
|
1238
|
-
ProbeService.findBy({
|
|
1239
|
-
query: {
|
|
1240
|
-
_id: QueryHelper.any(probeIds),
|
|
1241
|
-
isGlobalProbe: false,
|
|
1242
|
-
projectId: projectId,
|
|
1243
|
-
},
|
|
1244
|
-
select: {
|
|
1245
|
-
_id: true,
|
|
1246
|
-
},
|
|
1247
|
-
skip: 0,
|
|
1248
|
-
limit: LIMIT_PER_PROJECT,
|
|
1249
|
-
props: {
|
|
1250
|
-
isRoot: true,
|
|
1251
|
-
},
|
|
1252
|
-
}),
|
|
1253
|
-
]);
|
|
1254
|
+
const probes: Array<Probe> =
|
|
1255
|
+
await ProbeService.getProbesAttachableToProject({
|
|
1256
|
+
probeIds: probeIds,
|
|
1257
|
+
projectId: projectId,
|
|
1258
|
+
});
|
|
1254
1259
|
|
|
1255
1260
|
await this.createMonitorProbes({
|
|
1256
1261
|
projectId: projectId,
|
|
1257
1262
|
monitorId: monitorId,
|
|
1258
|
-
probes:
|
|
1263
|
+
probes: probes,
|
|
1259
1264
|
});
|
|
1260
1265
|
}
|
|
1261
1266
|
|
|
@@ -1,10 +1,80 @@
|
|
|
1
1
|
import DatabaseService from "./DatabaseService";
|
|
2
2
|
import Model from "../../Models/DatabaseModels/NetworkDeviceDiscoveryScan";
|
|
3
|
+
import { OnCreate, OnUpdate } from "../Types/Database/Hooks";
|
|
4
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
5
|
+
import UpdateBy from "../Types/Database/UpdateBy";
|
|
6
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
7
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
8
|
+
import ScanTargetUtil from "../../Utils/NetworkDiscovery/ScanTargetUtil";
|
|
3
9
|
|
|
4
10
|
export class Service extends DatabaseService<Model> {
|
|
5
11
|
public constructor() {
|
|
6
12
|
super(Model);
|
|
7
13
|
}
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Validate the scan target at write time, with the same parser the probe
|
|
17
|
+
* expands it with (Common/Utils/NetworkDiscovery/ScanTargetUtil).
|
|
18
|
+
*
|
|
19
|
+
* Without this, a typo'd target is accepted, sits Pending until a probe
|
|
20
|
+
* claims it, and only surfaces minutes later as a Failed scan with the
|
|
21
|
+
* parser's complaint buried in statusMessage. Octet-range notation makes
|
|
22
|
+
* that far likelier than CIDR did — a reversed range ("10.22-16.0.1-20") or
|
|
23
|
+
* an out-of-range octet is easy to type and impossible to spot by eye — so
|
|
24
|
+
* the feedback belongs on the form, not on a scan result.
|
|
25
|
+
*
|
|
26
|
+
* The size ceiling is checked here too: an oversized target is rejected the
|
|
27
|
+
* moment it is entered rather than after a probe has been handed a sweep it
|
|
28
|
+
* refuses to run.
|
|
29
|
+
*/
|
|
30
|
+
@CaptureSpan()
|
|
31
|
+
protected override async onBeforeCreate(
|
|
32
|
+
createBy: CreateBy<Model>,
|
|
33
|
+
): Promise<OnCreate<Model>> {
|
|
34
|
+
this.validateScanTarget(createBy.data.cidr);
|
|
35
|
+
|
|
36
|
+
return { createBy, carryForward: null };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/*
|
|
40
|
+
* The target column is not user-updatable (its ColumnAccessControl grants no
|
|
41
|
+
* update permission), but root writers — the probe-ingest endpoints, workers,
|
|
42
|
+
* migrations — bypass that. Validating any update that carries the column
|
|
43
|
+
* keeps the invariant true for every writer instead of just the form.
|
|
44
|
+
*/
|
|
45
|
+
@CaptureSpan()
|
|
46
|
+
protected override async onBeforeUpdate(
|
|
47
|
+
updateBy: UpdateBy<Model>,
|
|
48
|
+
): Promise<OnUpdate<Model>> {
|
|
49
|
+
const dataKeys: Array<string> = Object.keys(updateBy.data || {});
|
|
50
|
+
|
|
51
|
+
if (dataKeys.includes("cidr")) {
|
|
52
|
+
this.validateScanTarget(
|
|
53
|
+
(updateBy.data as Record<string, unknown>)["cidr"],
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return { updateBy, carryForward: null };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* The value is passed through UNTOUCHED. It arrives straight from the
|
|
62
|
+
* request JSON — BaseAPI assigns ShortText columns verbatim, and this hook
|
|
63
|
+
* runs before the model's type and length checks — so it may be a number,
|
|
64
|
+
* an object or an array, not just a string. ScanTargetUtil already type-
|
|
65
|
+
* guards and trims internally; normalizing here (the obvious
|
|
66
|
+
* `(target || "").trim()`) would instead throw a TypeError on any truthy
|
|
67
|
+
* non-string and turn an intended 400 into a 500.
|
|
68
|
+
*/
|
|
69
|
+
private validateScanTarget(target: unknown): void {
|
|
70
|
+
const validationError: string | null = ScanTargetUtil.getValidationError(
|
|
71
|
+
target as string,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
if (validationError) {
|
|
75
|
+
throw new BadDataException(validationError);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
8
78
|
}
|
|
9
79
|
|
|
10
80
|
export default new Service();
|
|
@@ -32,6 +32,7 @@ import MonitorService from "./MonitorService";
|
|
|
32
32
|
import PushNotificationMessage from "../../Types/PushNotification/PushNotificationMessage";
|
|
33
33
|
import PushNotificationUtil from "../Utils/PushNotificationUtil";
|
|
34
34
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
35
|
+
import QueryHelper from "../Types/Database/QueryHelper";
|
|
35
36
|
import { IsBillingEnabled } from "../EnvironmentConfig";
|
|
36
37
|
import GlobalCache from "../Infrastructure/GlobalCache";
|
|
37
38
|
import { createWhatsAppMessageFromTemplate } from "../Utils/WhatsAppTemplateUtil";
|
|
@@ -434,6 +435,71 @@ export class Service extends DatabaseService<Model> {
|
|
|
434
435
|
return { createBy: createBy, carryForward: [] };
|
|
435
436
|
}
|
|
436
437
|
|
|
438
|
+
/*
|
|
439
|
+
* Only global probes and probes belonging to this project may be attached to
|
|
440
|
+
* that project's monitors. Probe ids reach the server from the browser - the
|
|
441
|
+
* monitor create form and the Monitor > Probes table both post them - so
|
|
442
|
+
* they cannot be trusted to stay inside the tenant. Every path that attaches
|
|
443
|
+
* a probe to a monitor filters through here.
|
|
444
|
+
*/
|
|
445
|
+
@CaptureSpan()
|
|
446
|
+
public async getProbesAttachableToProject(data: {
|
|
447
|
+
probeIds: Array<ObjectID>;
|
|
448
|
+
projectId: ObjectID;
|
|
449
|
+
}): Promise<Array<Model>> {
|
|
450
|
+
if (data.probeIds.length === 0) {
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const [globalProbes, projectProbes]: [Array<Model>, Array<Model>] =
|
|
455
|
+
await Promise.all([
|
|
456
|
+
this.findBy({
|
|
457
|
+
query: {
|
|
458
|
+
_id: QueryHelper.any(data.probeIds),
|
|
459
|
+
isGlobalProbe: true,
|
|
460
|
+
},
|
|
461
|
+
select: {
|
|
462
|
+
_id: true,
|
|
463
|
+
},
|
|
464
|
+
skip: 0,
|
|
465
|
+
limit: LIMIT_PER_PROJECT,
|
|
466
|
+
props: {
|
|
467
|
+
isRoot: true,
|
|
468
|
+
},
|
|
469
|
+
}),
|
|
470
|
+
this.findBy({
|
|
471
|
+
query: {
|
|
472
|
+
_id: QueryHelper.any(data.probeIds),
|
|
473
|
+
isGlobalProbe: false,
|
|
474
|
+
projectId: data.projectId,
|
|
475
|
+
},
|
|
476
|
+
select: {
|
|
477
|
+
_id: true,
|
|
478
|
+
},
|
|
479
|
+
skip: 0,
|
|
480
|
+
limit: LIMIT_PER_PROJECT,
|
|
481
|
+
props: {
|
|
482
|
+
isRoot: true,
|
|
483
|
+
},
|
|
484
|
+
}),
|
|
485
|
+
]);
|
|
486
|
+
|
|
487
|
+
return [...globalProbes, ...projectProbes];
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
@CaptureSpan()
|
|
491
|
+
public async isProbeAttachableToProject(data: {
|
|
492
|
+
probeId: ObjectID;
|
|
493
|
+
projectId: ObjectID;
|
|
494
|
+
}): Promise<boolean> {
|
|
495
|
+
const probes: Array<Model> = await this.getProbesAttachableToProject({
|
|
496
|
+
probeIds: [data.probeId],
|
|
497
|
+
projectId: data.projectId,
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
return probes.length > 0;
|
|
501
|
+
}
|
|
502
|
+
|
|
437
503
|
@CaptureSpan()
|
|
438
504
|
public async getOwners(probeId: ObjectID): Promise<Array<User>> {
|
|
439
505
|
if (!probeId) {
|
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
} from "../../Types/BrandColors";
|
|
53
53
|
import Color from "../../Types/Color";
|
|
54
54
|
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
55
|
+
import QueryDeepPartialEntity from "../../Types/Database/PartialEntity";
|
|
55
56
|
import OneUptimeDate from "../../Types/Date";
|
|
56
57
|
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
57
58
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
@@ -609,6 +610,99 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
609
610
|
await this.sendSubscriptionChangeWebhookSlackNotification(project.id!);
|
|
610
611
|
}
|
|
611
612
|
|
|
613
|
+
/*
|
|
614
|
+
* Pushes a project's trial end date out to a new date, in the payment
|
|
615
|
+
* provider first and then on the project row.
|
|
616
|
+
*
|
|
617
|
+
* The payment provider is the source of truth for what the customer is
|
|
618
|
+
* actually charged, so it is updated first: if Stripe rejects the change
|
|
619
|
+
* the project row keeps its old trial date rather than showing the customer
|
|
620
|
+
* a trial that is not really there.
|
|
621
|
+
*/
|
|
622
|
+
@CaptureSpan()
|
|
623
|
+
public async extendTrial(params: {
|
|
624
|
+
projectId: ObjectID;
|
|
625
|
+
trialEndsAt: Date;
|
|
626
|
+
extendedByUserId?: ObjectID | undefined;
|
|
627
|
+
}): Promise<void> {
|
|
628
|
+
if (!IsBillingEnabled) {
|
|
629
|
+
throw new BadDataException("Billing is not enabled for this server");
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const project: Model | null = await this.findOneById({
|
|
633
|
+
id: params.projectId,
|
|
634
|
+
select: {
|
|
635
|
+
_id: true,
|
|
636
|
+
trialEndsAt: true,
|
|
637
|
+
paymentProviderSubscriptionId: true,
|
|
638
|
+
paymentProviderMeteredSubscriptionId: true,
|
|
639
|
+
},
|
|
640
|
+
props: {
|
|
641
|
+
isRoot: true,
|
|
642
|
+
},
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
if (!project) {
|
|
646
|
+
throw new BadDataException("Project not found");
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (!project.paymentProviderSubscriptionId) {
|
|
650
|
+
throw new BadDataException("Payment Provider subscription not found");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (!project.paymentProviderMeteredSubscriptionId) {
|
|
654
|
+
throw new BadDataException(
|
|
655
|
+
"Payment Provider metered subscription not found",
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
await BillingService.extendTrial({
|
|
660
|
+
subscriptionId: project.paymentProviderSubscriptionId,
|
|
661
|
+
meteredSubscriptionId: project.paymentProviderMeteredSubscriptionId,
|
|
662
|
+
trialEndsAt: params.trialEndsAt,
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
/*
|
|
666
|
+
* Pushing trial_end out puts the subscriptions back into `trialing`. Read
|
|
667
|
+
* the statuses back rather than assuming them, so the project row - which
|
|
668
|
+
* drives the customer's trial banner and the paywall - matches Stripe.
|
|
669
|
+
*/
|
|
670
|
+
const subscriptionStatus: SubscriptionStatus =
|
|
671
|
+
await BillingService.getSubscriptionStatus(
|
|
672
|
+
project.paymentProviderSubscriptionId,
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
const meteredSubscriptionStatus: SubscriptionStatus =
|
|
676
|
+
await BillingService.getSubscriptionStatus(
|
|
677
|
+
project.paymentProviderMeteredSubscriptionId,
|
|
678
|
+
);
|
|
679
|
+
|
|
680
|
+
await this.updateOneById({
|
|
681
|
+
id: project.id!,
|
|
682
|
+
data: {
|
|
683
|
+
trialEndsAt: params.trialEndsAt,
|
|
684
|
+
paymentProviderSubscriptionStatus: subscriptionStatus,
|
|
685
|
+
paymentProviderMeteredSubscriptionStatus: meteredSubscriptionStatus,
|
|
686
|
+
},
|
|
687
|
+
props: {
|
|
688
|
+
isRoot: true,
|
|
689
|
+
ignoreHooks: true,
|
|
690
|
+
},
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
/*
|
|
694
|
+
* The audit trail for handing out free service. There is no generic
|
|
695
|
+
* admin-action table, so the acting master admin goes in the log line.
|
|
696
|
+
*/
|
|
697
|
+
logger.info(
|
|
698
|
+
`Trial for project ${project.id?.toString()} extended from ${
|
|
699
|
+
project.trialEndsAt?.toISOString() || "none"
|
|
700
|
+
} to ${params.trialEndsAt.toISOString()} by master admin ${
|
|
701
|
+
params.extendedByUserId?.toString() || "unknown"
|
|
702
|
+
}`,
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
|
|
612
706
|
/*
|
|
613
707
|
* The paid-conversion event for ad platforms: fires server-side (immune to
|
|
614
708
|
* ad blockers) whenever a project's subscription plan changes, with enough
|
|
@@ -2040,6 +2134,7 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
2040
2134
|
paymentProviderMeteredSubscriptionId: true,
|
|
2041
2135
|
paymentProviderSubscriptionSeats: true,
|
|
2042
2136
|
paymentProviderPlanId: true,
|
|
2137
|
+
trialEndsAt: true,
|
|
2043
2138
|
},
|
|
2044
2139
|
});
|
|
2045
2140
|
|
|
@@ -2081,6 +2176,21 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
2081
2176
|
throw new BadDataException("Subscription plan not found");
|
|
2082
2177
|
}
|
|
2083
2178
|
|
|
2179
|
+
/*
|
|
2180
|
+
* Reactivating goes through changePlan, which cancels both subscriptions
|
|
2181
|
+
* and creates new ones - so a trial the project still has to run has to be
|
|
2182
|
+
* carried onto the replacements explicitly. Otherwise a customer whose
|
|
2183
|
+
* trial a master admin extended as a goodwill gesture loses the extension
|
|
2184
|
+
* the moment their subscription is reactivated, and is billed right away.
|
|
2185
|
+
*
|
|
2186
|
+
* A trial that has already lapsed is not revived: reactivation is not the
|
|
2187
|
+
* place to hand out free service.
|
|
2188
|
+
*/
|
|
2189
|
+
const endTrialAt: Date | undefined =
|
|
2190
|
+
project.trialEndsAt && OneUptimeDate.isInTheFuture(project.trialEndsAt)
|
|
2191
|
+
? project.trialEndsAt
|
|
2192
|
+
: undefined;
|
|
2193
|
+
|
|
2084
2194
|
const result: {
|
|
2085
2195
|
subscriptionId: string;
|
|
2086
2196
|
meteredSubscriptionId: string;
|
|
@@ -2093,7 +2203,7 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
2093
2203
|
newPlan: subscriptionPlan,
|
|
2094
2204
|
quantity: project.paymentProviderSubscriptionSeats,
|
|
2095
2205
|
isYearly: SubscriptionPlan.isYearlyPlan(project.paymentProviderPlanId),
|
|
2096
|
-
endTrialAt:
|
|
2206
|
+
endTrialAt: endTrialAt,
|
|
2097
2207
|
});
|
|
2098
2208
|
|
|
2099
2209
|
// refresh subscription status.
|
|
@@ -2109,14 +2219,28 @@ export class ProjectService extends DatabaseService<Model> {
|
|
|
2109
2219
|
|
|
2110
2220
|
// now update project with new subscription id.
|
|
2111
2221
|
|
|
2222
|
+
const updateData: QueryDeepPartialEntity<Model> = {
|
|
2223
|
+
paymentProviderSubscriptionId: result.subscriptionId,
|
|
2224
|
+
paymentProviderMeteredSubscriptionId: result.meteredSubscriptionId,
|
|
2225
|
+
paymentProviderSubscriptionStatus: subscriptionState,
|
|
2226
|
+
paymentProviderMeteredSubscriptionStatus: meteredSubscriptionState,
|
|
2227
|
+
};
|
|
2228
|
+
|
|
2229
|
+
/*
|
|
2230
|
+
* The payment provider is the source of truth for the trial the new
|
|
2231
|
+
* subscriptions were created with, so its date wins over the one sent.
|
|
2232
|
+
* The column is left alone when there is no trial to record, rather than
|
|
2233
|
+
* stamping a project whose trial lapsed long ago with a fresh date.
|
|
2234
|
+
*/
|
|
2235
|
+
const newTrialEndsAt: Date | undefined = result.trialEndsAt || endTrialAt;
|
|
2236
|
+
|
|
2237
|
+
if (newTrialEndsAt) {
|
|
2238
|
+
updateData.trialEndsAt = newTrialEndsAt;
|
|
2239
|
+
}
|
|
2240
|
+
|
|
2112
2241
|
await this.updateOneById({
|
|
2113
2242
|
id: project.id!,
|
|
2114
|
-
data:
|
|
2115
|
-
paymentProviderSubscriptionId: result.subscriptionId,
|
|
2116
|
-
paymentProviderMeteredSubscriptionId: result.meteredSubscriptionId,
|
|
2117
|
-
paymentProviderSubscriptionStatus: subscriptionState,
|
|
2118
|
-
paymentProviderMeteredSubscriptionStatus: meteredSubscriptionState,
|
|
2119
|
-
},
|
|
2243
|
+
data: updateData,
|
|
2120
2244
|
props: {
|
|
2121
2245
|
isRoot: true,
|
|
2122
2246
|
},
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import CreateBy from "../Types/Database/CreateBy";
|
|
2
|
+
import { OnCreate } from "../Types/Database/Hooks";
|
|
3
|
+
import DatabaseService from "./DatabaseService";
|
|
4
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
5
|
+
import RecommendationType from "../../Types/Recommendation/RecommendationType";
|
|
6
|
+
import Model from "../../Models/DatabaseModels/RecommendationDismissal";
|
|
7
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
8
|
+
|
|
9
|
+
export class Service extends DatabaseService<Model> {
|
|
10
|
+
public constructor() {
|
|
11
|
+
super(Model);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* `recommendationType` is a string column rather than a Postgres enum (the
|
|
16
|
+
* codebase keeps enums in TypeScript so adding a member needs no migration),
|
|
17
|
+
* which means nothing below this point would reject a typo. A dismissal
|
|
18
|
+
* written under "monitor" instead of "Monitor" is silently invisible: the
|
|
19
|
+
* page filters on the enum value, finds nothing, and the card the user
|
|
20
|
+
* dismissed simply reappears with no error anywhere. Validating at the write
|
|
21
|
+
* boundary is the only place that failure is still cheap.
|
|
22
|
+
*/
|
|
23
|
+
@CaptureSpan()
|
|
24
|
+
protected override async onBeforeCreate(
|
|
25
|
+
createBy: CreateBy<Model>,
|
|
26
|
+
): Promise<OnCreate<Model>> {
|
|
27
|
+
const recommendationType: string | undefined =
|
|
28
|
+
createBy.data.recommendationType;
|
|
29
|
+
|
|
30
|
+
if (!recommendationType) {
|
|
31
|
+
throw new BadDataException("Recommendation type is required.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const validTypes: Array<string> = Object.values(RecommendationType);
|
|
35
|
+
|
|
36
|
+
if (!validTypes.includes(recommendationType)) {
|
|
37
|
+
throw new BadDataException(
|
|
38
|
+
`Invalid recommendation type: ${recommendationType}. Valid types are ${validTypes.join(
|
|
39
|
+
", ",
|
|
40
|
+
)}.`,
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!createBy.data.recommendationId) {
|
|
45
|
+
throw new BadDataException("Recommendation ID is required.");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return { createBy, carryForward: null };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default new Service();
|
|
@@ -4,6 +4,7 @@ import BadDataException from "../../Types/Exception/BadDataException";
|
|
|
4
4
|
import Model from "../../Models/DatabaseModels/RunbookAgentJob";
|
|
5
5
|
import RunbookAgentJobStatus from "../../Types/Runbook/RunbookAgentJobStatus";
|
|
6
6
|
import RunbookStepType from "../../Types/Runbook/RunbookStepType";
|
|
7
|
+
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
7
8
|
import OneUptimeDate from "../../Types/Date";
|
|
8
9
|
import { JSONObject } from "../../Types/JSON";
|
|
9
10
|
import PostgresAppInstance from "../Infrastructure/PostgresDatabase";
|
|
@@ -26,6 +27,24 @@ const DEFAULT_CLAIM_TIMEOUT_MS: number = 2 * 60_000;
|
|
|
26
27
|
|
|
27
28
|
const POLL_INTERVAL_MS: number = 500;
|
|
28
29
|
|
|
30
|
+
/*
|
|
31
|
+
* A job in one of these states will never change again, so its row is a
|
|
32
|
+
* durable record of what the step did. Everything else is still in flight and
|
|
33
|
+
* can be waited on.
|
|
34
|
+
*/
|
|
35
|
+
const TERMINAL_STATUSES: Array<RunbookAgentJobStatus> = [
|
|
36
|
+
RunbookAgentJobStatus.Succeeded,
|
|
37
|
+
RunbookAgentJobStatus.Failed,
|
|
38
|
+
RunbookAgentJobStatus.TimedOut,
|
|
39
|
+
RunbookAgentJobStatus.Cancelled,
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
export function isTerminalAgentJobStatus(
|
|
43
|
+
status: RunbookAgentJobStatus | undefined,
|
|
44
|
+
): boolean {
|
|
45
|
+
return Boolean(status && TERMINAL_STATUSES.includes(status));
|
|
46
|
+
}
|
|
47
|
+
|
|
29
48
|
/*
|
|
30
49
|
* TypeORM's dataSource.query returns `[rows, rowCount]` for UPDATE/DELETE
|
|
31
50
|
* (even with RETURNING), and just `rows` for SELECT/INSERT. This helper
|
|
@@ -95,6 +114,47 @@ export class Service extends DatabaseService<Model> {
|
|
|
95
114
|
return this.create({ data: row, props: { isRoot: true } });
|
|
96
115
|
}
|
|
97
116
|
|
|
117
|
+
/*
|
|
118
|
+
* The job this (execution, step) pair already produced, if any.
|
|
119
|
+
*
|
|
120
|
+
* A runbook execution runs inside a single BullMQ job, so a Worker restart
|
|
121
|
+
* mid-step means the execution is re-delivered and RunRunbook walks back to
|
|
122
|
+
* the same step — which is still persisted as Running. Without this lookup
|
|
123
|
+
* the step would be dispatched a second time and the agent would run the
|
|
124
|
+
* script again. The dispatcher calls this first: a terminal row is the
|
|
125
|
+
* step's result, a live row is something to re-attach to.
|
|
126
|
+
*
|
|
127
|
+
* A step is dispatched at most once per execution, so the newest row is the
|
|
128
|
+
* only one there can be; ordering is belt-and-braces against a torn write
|
|
129
|
+
* from a previous release.
|
|
130
|
+
*/
|
|
131
|
+
@CaptureSpan()
|
|
132
|
+
public async findLatestJobForStep(data: {
|
|
133
|
+
runbookExecutionId: ObjectID;
|
|
134
|
+
stepId: string;
|
|
135
|
+
}): Promise<Model | null> {
|
|
136
|
+
const jobs: Array<Model> = await this.findBy({
|
|
137
|
+
query: {
|
|
138
|
+
runbookExecutionId: data.runbookExecutionId,
|
|
139
|
+
stepId: data.stepId,
|
|
140
|
+
},
|
|
141
|
+
select: {
|
|
142
|
+
_id: true,
|
|
143
|
+
status: true,
|
|
144
|
+
output: true,
|
|
145
|
+
exitCode: true,
|
|
146
|
+
errorMessage: true,
|
|
147
|
+
createdAt: true,
|
|
148
|
+
},
|
|
149
|
+
sort: { createdAt: SortOrder.Descending },
|
|
150
|
+
limit: 1,
|
|
151
|
+
skip: 0,
|
|
152
|
+
props: { isRoot: true },
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
return jobs[0] || null;
|
|
156
|
+
}
|
|
157
|
+
|
|
98
158
|
/*
|
|
99
159
|
* Atomically claim the oldest Pending job in the agent's project targeted
|
|
100
160
|
* at this specific agent. Uses FOR UPDATE SKIP LOCKED so concurrent agents
|
|
@@ -279,15 +339,21 @@ export class Service extends DatabaseService<Model> {
|
|
|
279
339
|
* POLL_INTERVAL_MS until the job reaches a terminal status, or until the
|
|
280
340
|
* combined claim + execution window is exhausted (in which case we mark
|
|
281
341
|
* the job TimedOut ourselves and return it).
|
|
342
|
+
*
|
|
343
|
+
* waitStartedAt anchors that window. It defaults to now — right for a job
|
|
344
|
+
* this Worker just enqueued — but a Worker re-attaching to a job left behind
|
|
345
|
+
* by a restart passes the job's createdAt, so the step keeps the single
|
|
346
|
+
* window its author configured instead of earning a fresh one per redelivery.
|
|
282
347
|
*/
|
|
283
348
|
@CaptureSpan()
|
|
284
349
|
public async pollUntilTerminal(data: {
|
|
285
350
|
jobId: ObjectID;
|
|
286
351
|
claimTimeoutInMs: number;
|
|
287
352
|
executionTimeoutInMs: number;
|
|
353
|
+
waitStartedAt?: Date | undefined;
|
|
288
354
|
}): Promise<Model> {
|
|
289
355
|
const overallDeadline: Date = OneUptimeDate.addRemoveSeconds(
|
|
290
|
-
OneUptimeDate.getCurrentDate(),
|
|
356
|
+
data.waitStartedAt || OneUptimeDate.getCurrentDate(),
|
|
291
357
|
Math.ceil(
|
|
292
358
|
(data.claimTimeoutInMs + data.executionTimeoutInMs + 5_000) / 1000,
|
|
293
359
|
),
|
|
@@ -318,12 +384,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
318
384
|
);
|
|
319
385
|
}
|
|
320
386
|
|
|
321
|
-
if (
|
|
322
|
-
job.status === RunbookAgentJobStatus.Succeeded ||
|
|
323
|
-
job.status === RunbookAgentJobStatus.Failed ||
|
|
324
|
-
job.status === RunbookAgentJobStatus.TimedOut ||
|
|
325
|
-
job.status === RunbookAgentJobStatus.Cancelled
|
|
326
|
-
) {
|
|
387
|
+
if (isTerminalAgentJobStatus(job.status)) {
|
|
327
388
|
return job;
|
|
328
389
|
}
|
|
329
390
|
|