@oneuptime/common 12.0.22 → 12.0.24
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/DetectionRule.ts +55 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/NetworkDevice.ts +44 -0
- package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +584 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +105 -0
- package/Models/DatabaseModels/Project.ts +68 -0
- package/Models/DatabaseModels/User.ts +68 -0
- package/Server/API/TelemetryAPI.ts +29 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789100000000-AddNetworkDeviceAutoImportRule.ts +60 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789200000000-AddSysObjectIdPatternToAutoImportRule.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789300000000-AddAutoApplyVendorHealthTemplate.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.ts +28 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Middleware/GzipRequestBody.ts +311 -0
- package/Server/Middleware/MultipartFormData.ts +87 -3
- package/Server/Services/DetectionRuleService.ts +73 -6
- package/Server/Services/Index.ts +207 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +917 -0
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +181 -0
- package/Server/Services/NetworkDeviceDiscoveryScanService.ts +59 -0
- package/Server/Services/NetworkDeviceService.ts +148 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
- package/Server/Services/OnCallDutyPolicyFeedService.ts +1 -1
- package/Server/Services/ProjectService.ts +29 -19
- package/Server/Services/SecurityEventService.ts +90 -13
- package/Server/Services/StatusPageResourceService.ts +223 -0
- package/Server/Services/TelemetryAttributeService.ts +17 -0
- package/Server/Services/UserService.ts +4 -6
- package/Server/Types/Markdown.ts +161 -67
- package/Server/Utils/AI/Toolbox/OnCallTools.ts +12 -4
- package/Server/Utils/AnalyticsDatabase/Statement.ts +13 -1
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +297 -6
- package/Server/Utils/Attribution.ts +4 -0
- package/Server/Utils/Marketing/MarketingEventUtil.ts +45 -7
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +39 -1
- package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +55 -3
- package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +21 -0
- package/Server/Utils/StartServer.ts +12 -32
- package/Server/Utils/Telemetry/LlmCostBudgetEvaluator.ts +101 -4
- package/Server/Utils/Telemetry/LlmMetricSpend.ts +130 -0
- package/Server/Views/Partials/AnalyticsConsent.ejs +159 -102
- package/Server/Views/Partials/Head.ejs +2 -1
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +776 -38
- package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +359 -0
- package/Tests/App/Dashboard/CorrelateGraph.test.tsx +865 -0
- package/Tests/App/Dashboard/CorrelationGraph.test.ts +346 -0
- package/Tests/App/Dashboard/CriteriaFilterConditionDropdown.test.tsx +256 -0
- package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +738 -0
- package/Tests/App/Dashboard/CriteriaFilterMonitorTypeChange.test.ts +1122 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +283 -0
- package/Tests/App/Dashboard/ExternalStatusPageCriteriaFilter.test.ts +407 -0
- package/Tests/App/Dashboard/MetricSeriesInvestigateMenu.test.tsx +5 -14
- package/Tests/App/Dashboard/MonitorCriteriaActionToggles.test.tsx +426 -0
- package/Tests/App/Dashboard/MonitorStepsCriteriaAlignmentWiring.test.tsx +352 -0
- package/Tests/App/Dashboard/OnCallLayerCardOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/OnCallLayerShiftPreviewOverrides.test.ts +237 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +2 -2
- package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +460 -0
- package/Tests/App/Dashboard/SecurityEventAttributeUtil.test.ts +171 -0
- package/Tests/App/Dashboard/SecurityEventCorrelation.test.ts +857 -0
- package/Tests/App/Dashboard/SecurityEventDetailObservables.test.tsx +194 -0
- package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +124 -0
- package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +79 -19
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +382 -0
- package/Tests/App/StatusPage/BulkAddStatusPageMonitors.test.ts +216 -0
- package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +590 -11
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +757 -0
- package/Tests/Models/DiscoveryScanNameColumn.test.ts +293 -0
- package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +564 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +120 -4
- package/Tests/Server/Middleware/GzipRequestBody.test.ts +725 -0
- package/Tests/Server/Middleware/MultipartFormData.test.ts +298 -0
- package/Tests/Server/Services/AddDetectionRuleDistinctCountColumnsMigration.test.ts +311 -0
- package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +205 -0
- package/Tests/Server/Services/DetectionRuleService.test.ts +134 -2
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +7 -1
- package/Tests/Server/Services/FeedRetentionConsistency.test.ts +131 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +933 -0
- package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +194 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +800 -0
- package/Tests/Server/Services/OnCallScheduleAttachRosterRefresh.test.ts +244 -0
- package/Tests/Server/Services/SecurityEventService.test.ts +376 -0
- package/Tests/Server/Services/StatusPageResourceDuplicates.test.ts +703 -0
- package/Tests/Server/Services/TelemetryAttributeServiceSecurityEvent.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ComponentRegistryParity.test.ts +417 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorWhereOperators.test.ts +677 -0
- package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +43 -0
- package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +15 -11
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +97 -1
- package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +369 -8
- package/Tests/Server/Utils/SecurityEvent/SigmaClickhouseCompiler.test.ts +35 -0
- package/Tests/Server/Utils/Telemetry/LlmCostBudgetEvaluator.test.ts +368 -4
- package/Tests/Server/Utils/Telemetry/LlmMetricSpend.test.ts +245 -0
- package/Tests/Server/Views/AnalyticsConsentPartial.test.ts +48 -5
- package/Tests/Types/Code/YamlSyntax.test.ts +396 -0
- package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +957 -0
- package/Tests/Types/Monitor/MonitorCriteriaActionValidation.test.ts +598 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +49 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +6 -6
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +4 -4
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +4 -3
- package/Tests/Types/Telemetry/LlmMetricConventions.test.ts +193 -0
- package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +0 -12
- package/Tests/UI/Components/CardModelDetailEdit.test.tsx +1 -17
- package/Tests/UI/Components/CodeEditor.test.tsx +474 -10
- package/Tests/UI/Components/Detail/YamlField.test.tsx +105 -0
- package/Tests/UI/Components/EntityDropdownLabelsBulkAdd.test.tsx +319 -0
- package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +231 -0
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +1 -0
- package/Tests/UI/Components/Forms/ValidationYAML.test.ts +234 -0
- package/Tests/UI/Components/ModelTable/AttributeColumns.test.tsx +573 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableAttributeColumns.test.tsx +824 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModalAddableColumns.test.tsx +707 -0
- package/Tests/UI/Components/SideOver.test.tsx +1 -1
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +294 -0
- package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +436 -0
- package/Tests/UI/Components/TableBulkCsvExport.test.tsx +6 -2
- package/Tests/UI/Components/Toggle.test.tsx +25 -0
- package/Tests/UI/Components/YamlEditor.test.tsx +847 -0
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +252 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +516 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +272 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +221 -0
- package/Tests/Utils/NetworkDiscovery/ScanNameUtil.test.ts +312 -0
- package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +164 -0
- package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +468 -0
- package/Tests/Utils/Telemetry/LlmMetricQuery.test.ts +472 -0
- package/Types/Code/YamlSyntax.ts +396 -0
- package/Types/Exception/ExceptionCode.ts +1 -0
- package/Types/Exception/PayloadTooLargeException.ts +8 -0
- package/Types/Marketing/Attribution.ts +10 -0
- package/Types/Marketing/MarketingEvent.ts +4 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +116 -56
- package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +2 -1
- package/Types/NetworkAutomation/RuleRunResult.ts +84 -0
- package/Types/Permission.ts +47 -0
- package/Types/SecurityEvent/DetectionFindingConstants.ts +11 -0
- package/Types/Telemetry/LlmMetricConventions.ts +124 -0
- package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +3 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +10 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +241 -79
- package/UI/Components/CodeEditor/YamlEditor.tsx +369 -0
- package/UI/Components/Detail/Detail.tsx +10 -0
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +33 -0
- package/UI/Components/Forms/Fields/FormField.tsx +31 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
- package/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.ts +2 -0
- package/UI/Components/Forms/Validation.ts +46 -0
- package/UI/Components/Input/Input.tsx +3 -0
- package/UI/Components/ModelTable/AttributeColumns.tsx +321 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +263 -14
- package/UI/Components/ModelTable/Column.ts +8 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +310 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +13 -1
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.tsx +2 -2
- package/UI/Components/SideOver/SideOver.tsx +5 -5
- package/UI/Components/StatusPage/ResourceGrid.tsx +82 -2
- package/UI/Components/StatusPage/ResourceList.tsx +197 -38
- package/UI/Components/Toggle/Toggle.tsx +9 -1
- package/UI/Components/Types/FieldType.ts +1 -0
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +73 -1
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +257 -0
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +183 -0
- package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +95 -0
- package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +66 -0
- package/Utils/NetworkDiscovery/ScanNameUtil.ts +181 -0
- package/Utils/NetworkDiscovery/ScanTargetUtil.ts +82 -0
- package/Utils/StatusPage/ResourceExplorer.ts +258 -0
- package/Utils/Telemetry/LlmMetricQuery.ts +204 -0
- package/build/dist/Models/DatabaseModels/DetectionRule.js +57 -0
- package/build/dist/Models/DatabaseModels/DetectionRule.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/NetworkDevice.js +45 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +609 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +97 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +76 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +76 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +17 -0
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789100000000-AddNetworkDeviceAutoImportRule.js +35 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789100000000-AddNetworkDeviceAutoImportRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789200000000-AddSysObjectIdPatternToAutoImportRule.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789200000000-AddSysObjectIdPatternToAutoImportRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789300000000-AddAutoApplyVendorHealthTemplate.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789300000000-AddAutoApplyVendorHealthTemplate.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js +21 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/GzipRequestBody.js +224 -0
- package/build/dist/Server/Middleware/GzipRequestBody.js.map +1 -0
- package/build/dist/Server/Middleware/MultipartFormData.js +71 -2
- package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
- package/build/dist/Server/Services/DetectionRuleService.js +49 -4
- package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +206 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +711 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +155 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +50 -0
- package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +124 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +68 -13
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +25 -45
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/SecurityEventService.js +57 -5
- package/build/dist/Server/Services/SecurityEventService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageResourceService.js +140 -0
- package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryAttributeService.js +17 -0
- package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +2 -12
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +147 -61
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +12 -4
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +12 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +246 -9
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Attribution.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +27 -7
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +26 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +42 -7
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +18 -0
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +12 -21
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js +76 -5
- package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js +102 -0
- package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js.map +1 -0
- package/build/dist/Types/Code/YamlSyntax.js +212 -0
- package/build/dist/Types/Code/YamlSyntax.js.map +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +8 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -0
- package/build/dist/Types/Marketing/Attribution.js +10 -0
- package/build/dist/Types/Marketing/Attribution.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +112 -51
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +2 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js +24 -0
- package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
- package/build/dist/Types/Permission.js +41 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +9 -0
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
- package/build/dist/Types/Telemetry/LlmMetricConventions.js +98 -0
- package/build/dist/Types/Telemetry/LlmMetricConventions.js.map +1 -0
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
- package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +5 -2
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +206 -76
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js +201 -0
- package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -0
- package/build/dist/UI/Components/Detail/Detail.js +9 -0
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +16 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +14 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js +2 -0
- package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +27 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +1 -1
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/AttributeColumns.js +159 -0
- package/build/dist/UI/Components/ModelTable/AttributeColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +179 -17
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +133 -2
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +7 -1
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js +2 -2
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -5
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +28 -2
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceList.js +87 -20
- package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
- package/build/dist/UI/Components/Toggle/Toggle.js +9 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Types/FieldType.js +1 -0
- package/build/dist/UI/Components/Types/FieldType.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +37 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +149 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +121 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +75 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +59 -0
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js +120 -0
- package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +60 -0
- package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceExplorer.js +171 -0
- package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -1
- package/build/dist/Utils/Telemetry/LlmMetricQuery.js +119 -0
- package/build/dist/Utils/Telemetry/LlmMetricQuery.js.map +1 -0
- package/jest.config.json +2 -0
- package/package.json +1 -1
- package/tsconfig.json +2 -1
- package/Tests/UI/Components/Toast.test.tsx +0 -197
- package/Tests/UI/Components/ToastStacking.test.tsx +0 -198
- package/UI/Components/Toast/Toast.tsx +0 -189
- package/UI/Components/Toast/ToastInit.tsx +0 -110
- package/build/dist/UI/Components/Toast/Toast.js +0 -123
- package/build/dist/UI/Components/Toast/Toast.js.map +0 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +0 -53
- package/build/dist/UI/Components/Toast/ToastInit.js.map +0 -1
|
@@ -13,10 +13,49 @@ import { getQuerySettings } from "../Utils/AnalyticsDatabase/QuerySettingsHelper
|
|
|
13
13
|
export interface DetectionMatchGroup {
|
|
14
14
|
groupValue: string;
|
|
15
15
|
matchCount: number;
|
|
16
|
+
/*
|
|
17
|
+
* uniqExact of the rule's distinctCountField over the group's matches;
|
|
18
|
+
* 0 whenever the rule has no distinct-count field (the query emits a
|
|
19
|
+
* constant, not an aggregate, in that case).
|
|
20
|
+
*/
|
|
21
|
+
distinctCount: number;
|
|
16
22
|
sampleMessage: string;
|
|
17
23
|
sampleObservables: Array<string>;
|
|
18
24
|
}
|
|
19
25
|
|
|
26
|
+
export interface FindDetectionMatchesData {
|
|
27
|
+
projectId: ObjectID;
|
|
28
|
+
startTime: Date;
|
|
29
|
+
endTime: Date;
|
|
30
|
+
whereFragment: Statement;
|
|
31
|
+
groupByExpression: Statement | null;
|
|
32
|
+
distinctCountExpression: Statement | null;
|
|
33
|
+
minMatchCount: number;
|
|
34
|
+
maxGroups: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/*
|
|
38
|
+
* The in-process twin of the HAVING clause findDetectionMatches emits —
|
|
39
|
+
* exported so the evaluator's re-filter and the SQL builder live in one
|
|
40
|
+
* file, and a change to either side of the firing predicate is reviewed
|
|
41
|
+
* next to the other.
|
|
42
|
+
*/
|
|
43
|
+
export function doesGroupMeetDetectionThreshold(data: {
|
|
44
|
+
group: DetectionMatchGroup;
|
|
45
|
+
usesDistinctCount: boolean;
|
|
46
|
+
minMatchCount: number;
|
|
47
|
+
}): boolean {
|
|
48
|
+
if (data.group.matchCount <= 0) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const effectiveCount: number = data.usesDistinctCount
|
|
53
|
+
? data.group.distinctCount
|
|
54
|
+
: data.group.matchCount;
|
|
55
|
+
|
|
56
|
+
return effectiveCount >= Math.max(1, data.minMatchCount);
|
|
57
|
+
}
|
|
58
|
+
|
|
20
59
|
export class SecurityEventService extends AnalyticsDatabaseService<SecurityEvent> {
|
|
21
60
|
public constructor(clickhouseDatabase?: ClickhouseDatabase | undefined) {
|
|
22
61
|
super({ modelType: SecurityEvent, database: clickhouseDatabase });
|
|
@@ -24,18 +63,21 @@ export class SecurityEventService extends AnalyticsDatabaseService<SecurityEvent
|
|
|
24
63
|
|
|
25
64
|
/*
|
|
26
65
|
* Detection-engine query: count matching events in a window, grouped by
|
|
27
|
-
* an optional field expression. `whereFragment`
|
|
28
|
-
* `
|
|
29
|
-
* every rule-controlled value inside them is
|
|
66
|
+
* an optional field expression. `whereFragment`, `groupByExpression`
|
|
67
|
+
* and `distinctCountExpression` are Statements built by
|
|
68
|
+
* SigmaClickhouseCompiler — every rule-controlled value inside them is
|
|
69
|
+
* a bound parameter.
|
|
70
|
+
*
|
|
71
|
+
* When distinctCountExpression is set, the threshold applies to
|
|
72
|
+
* uniqExact of that field, not the raw match count — and empty values
|
|
73
|
+
* are excluded via nullIf, so "5 distinct usernames" never counts rows
|
|
74
|
+
* that carry no username. The threshold is enforced in HAVING so the
|
|
75
|
+
* maxGroups LIMIT keeps only qualifying groups instead of letting
|
|
76
|
+
* noisy-but-under-threshold groups crowd out real ones.
|
|
30
77
|
*/
|
|
31
|
-
public async findDetectionMatches(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
endTime: Date;
|
|
35
|
-
whereFragment: Statement;
|
|
36
|
-
groupByExpression: Statement | null;
|
|
37
|
-
maxGroups: number;
|
|
38
|
-
}): Promise<Array<DetectionMatchGroup>> {
|
|
78
|
+
public async findDetectionMatches(
|
|
79
|
+
data: FindDetectionMatchesData,
|
|
80
|
+
): Promise<Array<DetectionMatchGroup>> {
|
|
39
81
|
if (!this.database) {
|
|
40
82
|
this.useDefaultDatabase();
|
|
41
83
|
}
|
|
@@ -51,8 +93,18 @@ export class SecurityEventService extends AnalyticsDatabaseService<SecurityEvent
|
|
|
51
93
|
statement.append("''");
|
|
52
94
|
}
|
|
53
95
|
|
|
96
|
+
statement.append(" AS groupValue, count() AS matchCount, ");
|
|
97
|
+
|
|
98
|
+
if (data.distinctCountExpression) {
|
|
99
|
+
statement.append("uniqExact(nullIf(");
|
|
100
|
+
statement.append(data.distinctCountExpression);
|
|
101
|
+
statement.append(", ''))");
|
|
102
|
+
} else {
|
|
103
|
+
statement.append("0");
|
|
104
|
+
}
|
|
105
|
+
|
|
54
106
|
statement.append(
|
|
55
|
-
` AS
|
|
107
|
+
` AS distinctCount, any(message) AS sampleMessage, arrayDistinct(arrayFlatten(groupArray(20)(observables))) AS sampleObservables FROM ${databaseName}.${this.model.tableName} WHERE `,
|
|
56
108
|
);
|
|
57
109
|
|
|
58
110
|
statement.append(
|
|
@@ -69,7 +121,31 @@ export class SecurityEventService extends AnalyticsDatabaseService<SecurityEvent
|
|
|
69
121
|
);
|
|
70
122
|
|
|
71
123
|
statement.append(data.whereFragment);
|
|
72
|
-
statement.append(") GROUP BY groupValue
|
|
124
|
+
statement.append(") GROUP BY groupValue");
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* The effective count — what the rule's threshold means — is the
|
|
128
|
+
* distinct count when a distinct expression was given, else the raw
|
|
129
|
+
* match count. A distinct-count rule always gets a HAVING clause,
|
|
130
|
+
* even at threshold 1: a group whose matches all lack the counted
|
|
131
|
+
* field has distinctCount 0 and must not fire.
|
|
132
|
+
*/
|
|
133
|
+
const effectiveCountColumn: string = data.distinctCountExpression
|
|
134
|
+
? "distinctCount"
|
|
135
|
+
: "matchCount";
|
|
136
|
+
const minMatchCount: number = Math.max(1, data.minMatchCount);
|
|
137
|
+
|
|
138
|
+
if (data.distinctCountExpression || minMatchCount > 1) {
|
|
139
|
+
statement.append(` HAVING ${effectiveCountColumn} >= `);
|
|
140
|
+
statement.append(
|
|
141
|
+
SQL`${{
|
|
142
|
+
type: TableColumnType.Number,
|
|
143
|
+
value: minMatchCount,
|
|
144
|
+
}}`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
statement.append(` ORDER BY ${effectiveCountColumn} DESC LIMIT `);
|
|
73
149
|
statement.append(
|
|
74
150
|
SQL`${{
|
|
75
151
|
type: TableColumnType.Number,
|
|
@@ -88,6 +164,7 @@ export class SecurityEventService extends AnalyticsDatabaseService<SecurityEvent
|
|
|
88
164
|
return {
|
|
89
165
|
groupValue: String(row["groupValue"] ?? ""),
|
|
90
166
|
matchCount: Number(row["matchCount"] || 0),
|
|
167
|
+
distinctCount: Number(row["distinctCount"] || 0),
|
|
91
168
|
sampleMessage: String(row["sampleMessage"] ?? ""),
|
|
92
169
|
sampleObservables: Array.isArray(row["sampleObservables"])
|
|
93
170
|
? (row["sampleObservables"] as Array<unknown>).map(
|
|
@@ -17,6 +17,82 @@ import Model from "../../Models/DatabaseModels/StatusPageResource";
|
|
|
17
17
|
import Monitor from "../../Models/DatabaseModels/Monitor";
|
|
18
18
|
import MonitorGroupResource from "../../Models/DatabaseModels/MonitorGroupResource";
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* The ways a create or update can name the resource's target. Everything
|
|
22
|
+
* server side sets the foreign key column, but the dashboard's resource form
|
|
23
|
+
* posts the relation - and the relation does NOT arrive in the same shape on
|
|
24
|
+
* both write paths:
|
|
25
|
+
*
|
|
26
|
+
* - create goes through BaseAPI.createItem, which revives the body with
|
|
27
|
+
* BaseModel.fromJSON, so `monitor` is a real Monitor and `monitor.id` is
|
|
28
|
+
* an ObjectID;
|
|
29
|
+
* - update goes through BaseAPI.updateItem, which only runs
|
|
30
|
+
* JSONFunctions.deserialize. That revives ObjectID/DateTime values, but
|
|
31
|
+
* never nested models, so `monitor` stays the plain `{ _id: "<uuid>" }`
|
|
32
|
+
* the browser sent and has no `id` at all.
|
|
33
|
+
*
|
|
34
|
+
* Reading only `.id` therefore silently saw nothing on every edit-form save,
|
|
35
|
+
* which is the whole path the update guard exists for - so this accepts the
|
|
36
|
+
* id however it arrives.
|
|
37
|
+
*/
|
|
38
|
+
type StatusPageResourceTargetValue =
|
|
39
|
+
| ObjectID
|
|
40
|
+
| string
|
|
41
|
+
| { id?: unknown; _id?: unknown }
|
|
42
|
+
| null
|
|
43
|
+
| undefined;
|
|
44
|
+
|
|
45
|
+
interface StatusPageResourceTargetInput {
|
|
46
|
+
monitorId?: StatusPageResourceTargetValue;
|
|
47
|
+
monitor?: StatusPageResourceTargetValue;
|
|
48
|
+
monitorGroupId?: StatusPageResourceTargetValue;
|
|
49
|
+
monitorGroup?: StatusPageResourceTargetValue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function toTargetObjectID(
|
|
53
|
+
value: StatusPageResourceTargetValue,
|
|
54
|
+
): ObjectID | null {
|
|
55
|
+
if (!value) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (value instanceof ObjectID) {
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (typeof value === "string") {
|
|
64
|
+
return new ObjectID(value);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (typeof value === "object") {
|
|
68
|
+
return (
|
|
69
|
+
toTargetObjectID(value.id as StatusPageResourceTargetValue) ||
|
|
70
|
+
toTargetObjectID(value._id as StatusPageResourceTargetValue)
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface StatusPageResourceTarget {
|
|
78
|
+
monitorId: ObjectID | null;
|
|
79
|
+
monitorGroupId: ObjectID | null;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Named after what the operator sees rather than what the column is, because
|
|
84
|
+
* this reads back to them on the resource form.
|
|
85
|
+
*/
|
|
86
|
+
function duplicateResourceException(
|
|
87
|
+
target: StatusPageResourceTarget,
|
|
88
|
+
): BadDataException {
|
|
89
|
+
const thing: string = target.monitorId ? "monitor" : "monitor group";
|
|
90
|
+
|
|
91
|
+
return new BadDataException(
|
|
92
|
+
`This ${thing} is already added to this status page. A ${thing} can only be added once so it is not shown twice to your customers.`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
20
96
|
export class Service extends DatabaseService<Model> {
|
|
21
97
|
public constructor() {
|
|
22
98
|
super(Model);
|
|
@@ -115,6 +191,76 @@ export class Service extends DatabaseService<Model> {
|
|
|
115
191
|
return statusPageResources;
|
|
116
192
|
}
|
|
117
193
|
|
|
194
|
+
/**
|
|
195
|
+
* The id of the thing a resource points at, whichever way the caller
|
|
196
|
+
* expressed it. The dashboard's resource form posts the relation
|
|
197
|
+
* (`monitor: { _id }`) while everything server side sets the foreign key
|
|
198
|
+
* column, and both mean the same resource.
|
|
199
|
+
*/
|
|
200
|
+
private getResourceMonitorTarget(
|
|
201
|
+
data: StatusPageResourceTargetInput,
|
|
202
|
+
): StatusPageResourceTarget {
|
|
203
|
+
return {
|
|
204
|
+
monitorId:
|
|
205
|
+
toTargetObjectID(data.monitorId) || toTargetObjectID(data.monitor),
|
|
206
|
+
monitorGroupId:
|
|
207
|
+
toTargetObjectID(data.monitorGroupId) ||
|
|
208
|
+
toTargetObjectID(data.monitorGroup),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* A status page lists a monitor once.
|
|
214
|
+
*
|
|
215
|
+
* Nothing stopped the same monitor being added twice, so re-adding a label's
|
|
216
|
+
* monitors after a new one joined that label created a second resource for
|
|
217
|
+
* every monitor already there, and the public page listed each of them twice
|
|
218
|
+
* (issue #3420). The rule engine has always refused to add a monitor that is
|
|
219
|
+
* already on the page for exactly this reason; this makes the same promise
|
|
220
|
+
* hold for every other way a resource is created - the resource form, the
|
|
221
|
+
* bulk add modal, and the API.
|
|
222
|
+
*
|
|
223
|
+
* The check is status-page-wide rather than per group: a monitor in two
|
|
224
|
+
* groups is still a monitor a visitor sees twice.
|
|
225
|
+
*/
|
|
226
|
+
@CaptureSpan()
|
|
227
|
+
public async isResourceAlreadyOnStatusPage(data: {
|
|
228
|
+
statusPageId: ObjectID;
|
|
229
|
+
monitorId?: ObjectID | null | undefined;
|
|
230
|
+
monitorGroupId?: ObjectID | null | undefined;
|
|
231
|
+
excludeResourceId?: ObjectID | null | undefined;
|
|
232
|
+
}): Promise<boolean> {
|
|
233
|
+
if (!data.monitorId && !data.monitorGroupId) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const query: Query<Model> = {
|
|
238
|
+
statusPageId: data.statusPageId,
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
if (data.monitorId) {
|
|
242
|
+
query.monitorId = data.monitorId;
|
|
243
|
+
} else {
|
|
244
|
+
query.monitorGroupId = data.monitorGroupId!;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (data.excludeResourceId) {
|
|
248
|
+
query._id = QueryHelper.notEquals(data.excludeResourceId.toString());
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const existingResource: Model | null = await this.findOneBy({
|
|
252
|
+
query: query,
|
|
253
|
+
select: {
|
|
254
|
+
_id: true,
|
|
255
|
+
},
|
|
256
|
+
props: {
|
|
257
|
+
isRoot: true,
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
return Boolean(existingResource);
|
|
262
|
+
}
|
|
263
|
+
|
|
118
264
|
@CaptureSpan()
|
|
119
265
|
protected override async onBeforeCreate(
|
|
120
266
|
createBy: CreateBy<Model>,
|
|
@@ -125,6 +271,20 @@ export class Service extends DatabaseService<Model> {
|
|
|
125
271
|
);
|
|
126
272
|
}
|
|
127
273
|
|
|
274
|
+
const target: StatusPageResourceTarget = this.getResourceMonitorTarget(
|
|
275
|
+
createBy.data as unknown as StatusPageResourceTargetInput,
|
|
276
|
+
);
|
|
277
|
+
|
|
278
|
+
if (
|
|
279
|
+
await this.isResourceAlreadyOnStatusPage({
|
|
280
|
+
statusPageId: createBy.data.statusPageId,
|
|
281
|
+
monitorId: target.monitorId,
|
|
282
|
+
monitorGroupId: target.monitorGroupId,
|
|
283
|
+
})
|
|
284
|
+
) {
|
|
285
|
+
throw duplicateResourceException(target);
|
|
286
|
+
}
|
|
287
|
+
|
|
128
288
|
if (!createBy.data.order) {
|
|
129
289
|
const query: Query<Model> = {
|
|
130
290
|
statusPageId: createBy.data.statusPageId,
|
|
@@ -222,6 +382,69 @@ export class Service extends DatabaseService<Model> {
|
|
|
222
382
|
protected override async onBeforeUpdate(
|
|
223
383
|
updateBy: UpdateBy<Model>,
|
|
224
384
|
): Promise<OnUpdate<Model>> {
|
|
385
|
+
/*
|
|
386
|
+
* Pointing an existing resource at a monitor the page already lists is the
|
|
387
|
+
* same duplicate onBeforeCreate refuses, just reached from the edit form.
|
|
388
|
+
*/
|
|
389
|
+
const updatedTarget: StatusPageResourceTarget =
|
|
390
|
+
this.getResourceMonitorTarget(
|
|
391
|
+
updateBy.data as unknown as StatusPageResourceTargetInput,
|
|
392
|
+
);
|
|
393
|
+
|
|
394
|
+
if (
|
|
395
|
+
(updatedTarget.monitorId || updatedTarget.monitorGroupId) &&
|
|
396
|
+
updateBy.query._id
|
|
397
|
+
) {
|
|
398
|
+
const resourceBeingUpdated: Model | null = await this.findOneBy({
|
|
399
|
+
query: {
|
|
400
|
+
_id: updateBy.query._id!,
|
|
401
|
+
},
|
|
402
|
+
props: {
|
|
403
|
+
isRoot: true,
|
|
404
|
+
},
|
|
405
|
+
select: {
|
|
406
|
+
_id: true,
|
|
407
|
+
statusPageId: true,
|
|
408
|
+
monitorId: true,
|
|
409
|
+
monitorGroupId: true,
|
|
410
|
+
},
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
const currentTarget: StatusPageResourceTarget =
|
|
414
|
+
this.getResourceMonitorTarget(
|
|
415
|
+
(resourceBeingUpdated ||
|
|
416
|
+
{}) as unknown as StatusPageResourceTargetInput,
|
|
417
|
+
);
|
|
418
|
+
|
|
419
|
+
/*
|
|
420
|
+
* The edit form is a ModelForm, so it posts every field it collects -
|
|
421
|
+
* the monitor included - even when all the operator changed was the
|
|
422
|
+
* display name. Checking an unchanged target would refuse those saves
|
|
423
|
+
* on a status page that already carries a duplicate from before this
|
|
424
|
+
* rule existed, which would leave both of its rows uneditable.
|
|
425
|
+
*/
|
|
426
|
+
const isTargetUnchanged: boolean =
|
|
427
|
+
(!updatedTarget.monitorId ||
|
|
428
|
+
updatedTarget.monitorId.toString() ===
|
|
429
|
+
currentTarget.monitorId?.toString()) &&
|
|
430
|
+
(!updatedTarget.monitorGroupId ||
|
|
431
|
+
updatedTarget.monitorGroupId.toString() ===
|
|
432
|
+
currentTarget.monitorGroupId?.toString());
|
|
433
|
+
|
|
434
|
+
if (
|
|
435
|
+
resourceBeingUpdated?.statusPageId &&
|
|
436
|
+
!isTargetUnchanged &&
|
|
437
|
+
(await this.isResourceAlreadyOnStatusPage({
|
|
438
|
+
statusPageId: resourceBeingUpdated.statusPageId,
|
|
439
|
+
monitorId: updatedTarget.monitorId,
|
|
440
|
+
monitorGroupId: updatedTarget.monitorGroupId,
|
|
441
|
+
excludeResourceId: resourceBeingUpdated.id,
|
|
442
|
+
}))
|
|
443
|
+
) {
|
|
444
|
+
throw duplicateResourceException(updatedTarget);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
225
448
|
if (updateBy.data.order && !updateBy.props.isRoot && updateBy.query._id) {
|
|
226
449
|
const resource: Model | null = await this.findOneBy({
|
|
227
450
|
query: {
|
|
@@ -4,6 +4,7 @@ import LogDatabaseService from "./LogService";
|
|
|
4
4
|
import MetricDatabaseService from "./MetricService";
|
|
5
5
|
import SpanDatabaseService from "./SpanService";
|
|
6
6
|
import ExceptionInstanceService from "./ExceptionInstanceService";
|
|
7
|
+
import SecurityEventService from "./SecurityEventService";
|
|
7
8
|
import MutableMetricDatabaseService, {
|
|
8
9
|
MutableMetricService as MutableMetricServiceClass,
|
|
9
10
|
} from "./MutableMetricService";
|
|
@@ -101,6 +102,22 @@ export class TelemetryAttributeService {
|
|
|
101
102
|
attributeKeysColumn: "attributeKeys",
|
|
102
103
|
timeColumn: "time",
|
|
103
104
|
};
|
|
105
|
+
/*
|
|
106
|
+
* Security events carry the whole source payload flattened into
|
|
107
|
+
* `attributes`, which is where every field the OCSF schema does not
|
|
108
|
+
* have a typed column for ends up (device.hostname,
|
|
109
|
+
* finding_info.title, metadata.product.name, ...). The security
|
|
110
|
+
* events table offers those as optional columns, and this is the
|
|
111
|
+
* list it offers.
|
|
112
|
+
*/
|
|
113
|
+
case TelemetryType.SecurityEvent:
|
|
114
|
+
return {
|
|
115
|
+
service: SecurityEventService,
|
|
116
|
+
tableName: SecurityEventService.model.tableName,
|
|
117
|
+
attributesColumn: "attributes",
|
|
118
|
+
attributeKeysColumn: "attributeKeys",
|
|
119
|
+
timeColumn: "time",
|
|
120
|
+
};
|
|
104
121
|
default:
|
|
105
122
|
return null;
|
|
106
123
|
}
|
|
@@ -42,7 +42,9 @@ import TeamMember from "../../Models/DatabaseModels/TeamMember";
|
|
|
42
42
|
import Model from "../../Models/DatabaseModels/User";
|
|
43
43
|
import SlackUtil from "../Utils/Workspace/Slack/Slack";
|
|
44
44
|
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
45
|
-
import MarketingEventUtil
|
|
45
|
+
import MarketingEventUtil, {
|
|
46
|
+
utmAnalyticsProperties,
|
|
47
|
+
} from "../Utils/Marketing/MarketingEventUtil";
|
|
46
48
|
import { MarketingEventType } from "../../Types/Marketing/MarketingEvent";
|
|
47
49
|
import UserTotpAuthService from "./UserTotpAuthService";
|
|
48
50
|
import UserTwoFactorBackupCodeService from "./UserTwoFactorBackupCodeService";
|
|
@@ -242,11 +244,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
242
244
|
distinctId: createdItem.email.toString(),
|
|
243
245
|
properties: {
|
|
244
246
|
has_password: Boolean(createdItem.password),
|
|
245
|
-
|
|
246
|
-
utm_medium: createdItem.utmMedium || "",
|
|
247
|
-
utm_campaign: createdItem.utmCampaign || "",
|
|
248
|
-
utm_term: createdItem.utmTerm || "",
|
|
249
|
-
utm_content: createdItem.utmContent || "",
|
|
247
|
+
...utmAnalyticsProperties(createdItem as unknown as JSONObject),
|
|
250
248
|
utm_url: createdItem.utmUrl || "",
|
|
251
249
|
click_ids: createdItem.clickIds || {},
|
|
252
250
|
first_touch: createdItem.firstTouchAttribution || {},
|