@oneuptime/common 13.0.7 → 14.0.0
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/AuditLog.ts +23 -15
- package/Models/DatabaseModels/GlobalConfig.ts +24 -0
- package/Models/DatabaseModels/Monitor.ts +3 -2
- package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
- package/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.ts +1 -1
- package/Models/DatabaseModels/ProjectOnCallCalendarFeed.ts +1 -1
- package/Models/DatabaseModels/UserOnCallCalendarFeed.ts +1 -1
- package/Scripts/generate-service-worker.js +65 -4
- package/Server/API/AIBillingAPI.ts +1 -0
- package/Server/API/AIInsightAPI.ts +1 -4
- package/Server/API/AIInvestigationAPI.ts +1 -4
- package/Server/API/AIReadinessAPI.ts +4 -5
- package/Server/API/AlertAPI.ts +1 -0
- package/Server/API/AutoRemediationAPI.ts +1 -4
- package/Server/API/BaseAPI.ts +34 -0
- package/Server/API/BaseAnalyticsAPI.ts +80 -9
- package/Server/API/BillingAPI.ts +2 -0
- package/Server/API/BillingInvoiceAPI.ts +1 -0
- package/Server/API/BillingPaymentMethodAPI.ts +2 -0
- package/Server/API/CodeFixRunAPI.ts +1 -3
- package/Server/API/CommonAPI.ts +68 -4
- package/Server/API/DashboardAPI.ts +12 -12
- package/Server/API/GlobalConfigAPI.ts +243 -460
- package/Server/API/IncidentAPI.ts +2 -0
- package/Server/API/IncidentEpisodeAPI.ts +1 -0
- package/Server/API/NotificationAPI.ts +1 -0
- package/Server/API/OnCallCalendarAPI.ts +4 -5
- package/Server/API/OnCallDutyPolicyAPI.ts +7 -0
- package/Server/API/OnCallReadinessAPI.ts +4 -1
- package/Server/API/OnCallScheduleTimelineAPI.ts +731 -0
- package/Server/API/ProjectAPI.ts +1 -0
- package/Server/API/ProjectOIDC.ts +25 -16
- package/Server/API/ProjectSSO.ts +24 -16
- package/Server/API/ScheduledMaintenanceAPI.ts +1 -0
- package/Server/API/StatusPageAPI.ts +261 -74
- package/Server/API/TeamMemberAPI.ts +13 -1
- package/Server/API/UserCallAPI.ts +2 -0
- package/Server/API/UserEmailAPI.ts +2 -0
- package/Server/API/UserIncomingCallNumberAPI.ts +2 -0
- package/Server/API/UserMicrosoftTeamsAPI.ts +1 -0
- package/Server/API/UserSlackAPI.ts +1 -0
- package/Server/API/UserSmsAPI.ts +2 -0
- package/Server/API/UserTotpAuthAPI.ts +1 -0
- package/Server/API/UserWebAuthnAPI.ts +2 -0
- package/Server/API/UserWebhookAPI.ts +1 -0
- package/Server/API/UserWhatsAppAPI.ts +2 -0
- package/Server/Enterprise/EnterpriseEdition.ts +649 -0
- package/Server/Enterprise/EnterpriseFeature.ts +48 -0
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
- package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
- package/Server/EnvironmentConfig.ts +147 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +13 -2
- package/Server/Middleware/UserAuthorization.ts +117 -21
- package/Server/Services/ApiKeyPermissionService.ts +101 -4
- package/Server/Services/AuditLogService.ts +84 -1079
- package/Server/Services/DatabaseService.ts +245 -0
- package/Server/Services/DetectionRuleService.ts +5 -4
- package/Server/Services/EnterpriseLicenseService.ts +38 -0
- package/Server/Services/GlobalConfigService.ts +80 -1
- package/Server/Services/MonitorProbeService.ts +116 -20
- package/Server/Services/MonitorService.ts +56 -4
- package/Server/Services/MonitorStatusTimelineService.ts +284 -0
- package/Server/Services/MonitorTemplateService.ts +26 -0
- package/Server/Services/OnCallDutyPolicyChildService.ts +261 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +2 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.ts +2 -2
- package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +2 -2
- package/Server/Services/PayAsYouGoBillingService.ts +23 -28
- package/Server/Services/ProjectService.ts +302 -0
- package/Server/Services/RumSessionPinService.ts +293 -22
- package/Server/Services/StatusPagePrivateUserService.ts +7 -3
- package/Server/Services/StatusPageService.ts +78 -1
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TeamPermissionService.ts +120 -26
- package/Server/Services/TeamService.ts +10 -0
- package/Server/Services/ThreatIntelFeedService.ts +6 -3
- package/Server/Services/UserService.ts +10 -17
- package/Server/Types/Database/Permissions/BasePermission.ts +9 -7
- package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
- package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
- package/Server/Types/Database/Permissions/Index.ts +75 -11
- package/Server/Types/Database/Permissions/TablePermission.ts +34 -31
- package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
- package/Server/Types/Markdown.ts +41 -0
- package/Server/Utils/AI/AIChatPrivacyFilter.ts +8 -0
- package/Server/Utils/AI/AIRunPrivacyFilter.ts +8 -0
- package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
- package/Server/Utils/EditionEnforcement.ts +233 -0
- package/Server/Utils/FrontendEnvironment.ts +41 -2
- package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
- package/Server/Utils/MasterAdminPageAccess.ts +61 -0
- package/Server/Utils/Monitor/AffectedResourceList.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/MonitorAlert.ts +3 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
- package/Server/Utils/Monitor/MonitorIncident.ts +3 -1
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
- package/Server/Utils/OnCall/OnCallCalendarFeedRenderer.ts +1 -1
- package/Server/Utils/Realtime.ts +163 -45
- package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +11 -28
- package/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.ts +170 -0
- package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +1 -1
- package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.ts +6 -2
- package/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.ts +10 -9
- package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
- package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
- package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
- package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
- package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +1059 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +376 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerHiddenTypes.test.tsx +757 -0
- package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +307 -0
- package/Tests/App/Dashboard/ArgumentsFormGroupByUnlistedAttributes.test.tsx +131 -0
- package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
- package/Tests/App/Dashboard/DashboardHeaderRequests.test.tsx +1 -1
- package/Tests/App/Dashboard/DashboardMonitorLabelVariable.test.tsx +9 -1
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +24 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +162 -8
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
- package/Tests/App/Dashboard/EntityFilterDropdownArchivedSlos.test.tsx +105 -6
- package/Tests/App/Dashboard/EntityFilterDropdownUnlistedSelection.test.tsx +434 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +276 -1
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/OnCallCalendarFeedSideMenus.test.tsx +9 -1
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +58 -42
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +42 -5
- package/Tests/App/Dashboard/ResourceAuditLogsSideMenus.test.tsx +34 -23
- package/Tests/App/Dashboard/ScheduleTimeline.test.tsx +1580 -0
- package/Tests/App/Dashboard/ScheduleTimelineAPI.test.ts +280 -0
- package/Tests/App/Dashboard/ScheduleTimelineModel.test.ts +673 -0
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +133 -70
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
- package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +86 -3
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -58
- package/Tests/App/Dashboard/SecurityEventsGuideContent.test.ts +1313 -0
- package/Tests/App/Dashboard/SecurityEventsHowItWorksCard.test.tsx +536 -0
- package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
- package/Tests/App/Dashboard/SecurityEventsNoResults.test.tsx +222 -0
- package/Tests/App/Dashboard/SecurityEventsThreatIntelPage.test.tsx +199 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
- package/Tests/App/Dashboard/SloOverviewHero.test.tsx +171 -36
- package/Tests/App/Dashboard/SloViewSideMenu.test.tsx +215 -0
- package/Tests/App/Dashboard/SloViewSideMenuCounts.test.tsx +40 -3
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +12 -4
- package/Tests/App/PublicDashboard/PublicDashboardWidgetListAuth.test.tsx +623 -0
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
- package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
- package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
- package/Tests/Models/OnCallCalendarFeedModels.test.ts +23 -1
- package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +138 -5
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +187 -0
- package/Tests/Server/API/AIInvestigationAvailabilityAuthorization.test.ts +51 -3
- package/Tests/Server/API/AIInvestigationEvidenceAPI.test.ts +55 -2
- package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
- package/Tests/Server/API/BaseAnalyticsAPIAggregateCache.test.ts +729 -0
- package/Tests/Server/API/BillingPayAsYouGoStatus.test.ts +93 -7
- package/Tests/Server/API/BillingPaymentMethodAPI.test.ts +36 -3
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +1003 -24
- package/Tests/Server/API/DashboardPublicRateLimit.test.ts +6 -3
- package/Tests/Server/API/ExpiredSessionAIRoutes.test.ts +708 -0
- package/Tests/Server/API/ExpiredSessionCustomRoutes.test.ts +928 -0
- package/Tests/Server/API/ExpiredSessionMonitorTemplate.test.ts +319 -0
- package/Tests/Server/API/ExpiredSessionOnCallDutyPolicy.test.ts +336 -0
- package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +820 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +766 -381
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +115 -12
- package/Tests/Server/API/OnCallCalendarAPI.test.ts +375 -8
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +196 -912
- package/Tests/Server/API/OnCallScheduleTimelineAPI.test.ts +1513 -0
- package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +119 -7
- package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +111 -4
- package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +615 -0
- package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +89 -2
- package/Tests/Server/API/SessionReplayAPI.test.ts +121 -0
- package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
- package/Tests/Server/API/StatusPageMasterPasswordRateLimit.test.ts +4 -2
- package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +441 -0
- package/Tests/Server/API/StatusPageTestEmailReportAuth.test.ts +664 -0
- package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
- package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +7 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +6 -0
- package/Tests/Server/API/UserNotificationSettingAPI.test.ts +65 -4
- package/Tests/Server/API/UserProjectsAPI.test.ts +63 -3
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +48 -2
- package/Tests/Server/API/UserWebAuthnAuthenticationOptionsRoute.test.ts +11 -2
- package/Tests/Server/API/UserWebAuthnBackupCodeMinting.test.ts +46 -3
- package/Tests/Server/API/UserWebAuthnPasskeyAPI.test.ts +18 -2
- package/Tests/Server/API/ZZVerifyChatsAuth.test.ts +24 -7
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
- package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
- package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
- package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
- package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
- package/Tests/Server/Middleware/ExpiredSessionUserMiddleware.test.ts +563 -0
- package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +299 -19
- package/Tests/Server/Middleware/PublicRouteUserMiddleware.test.ts +453 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +24 -0
- package/Tests/Server/Services/ApiKeyPermissionSecurity.test.ts +2 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +3 -3
- package/Tests/Server/Services/AuditLogService.test.ts +460 -990
- package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
- package/Tests/Server/Services/DatabaseServiceCreateSuppliedId.test.ts +147 -0
- package/Tests/Server/Services/DatabaseServiceLoginBeforeHooks.test.ts +1078 -0
- package/Tests/Server/Services/DatabaseServiceTenantRelationGuard.test.ts +259 -0
- package/Tests/Server/Services/DatabaseServiceWriteOperatorValues.test.ts +147 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
- package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
- package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
- package/Tests/Server/Services/MonitorPayAsYouGoBilling.test.ts +115 -1
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
- package/Tests/Server/Services/OnCallChildCreateAuthorizationPostgres.test.ts +711 -0
- package/Tests/Server/Services/OnCallDutyPolicyChildService.test.ts +733 -0
- package/Tests/Server/Services/PayAsYouGoBillingService.test.ts +190 -140
- package/Tests/Server/Services/PayAsYouGoStripeRateLimitBudget.test.ts +4 -9
- package/Tests/Server/Services/PermissionBlockDeletion.test.ts +780 -0
- package/Tests/Server/Services/PermissionBlockDeletionPostgres.test.ts +628 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
- package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +77 -1
- package/Tests/Server/Services/RumSessionPinCreatePermission.test.ts +715 -0
- package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
- package/Tests/Server/Services/TeamMemberMultiTenantReadPostgres.test.ts +394 -0
- package/Tests/Server/Services/TeamPrivilegeEscalation.test.ts +6 -0
- package/Tests/Server/Services/TelemetryPayAsYouGoBilling.test.ts +131 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +13 -2
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Database/Permissions/ModelPermissionAnonymousRefusal.test.ts +518 -0
- package/Tests/Server/Types/Database/Permissions/MultiTenantPermissions.test.ts +350 -0
- package/Tests/Server/Types/Database/Permissions/OnCallCalendarFeedPermissions.test.ts +282 -25
- package/Tests/Server/Types/Database/Permissions/TableLevelBlockPermission.test.ts +459 -0
- package/Tests/Server/Types/Markdown.test.ts +181 -0
- package/Tests/Server/Utils/AI/AIRunPrivacyFilter.test.ts +101 -9
- package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +88 -4
- package/Tests/Server/Utils/AI/Toolbox/ExceptionTools.test.ts +459 -0
- package/Tests/Server/Utils/AI/Toolbox/LogTools.test.ts +794 -0
- package/Tests/Server/Utils/AI/Toolbox/RecentChangesTools.test.ts +574 -0
- package/Tests/Server/Utils/AI/Toolbox/SecurityEventTools.test.ts +596 -0
- package/Tests/Server/Utils/CaptchaRequestAndLogging.test.ts +395 -0
- package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
- package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
- package/Tests/Server/Utils/MasterAdminPageAccess.test.ts +251 -0
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
- package/Tests/Server/Utils/Monitor/MonitorActionTimestamps.test.ts +616 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +934 -96
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
- package/Tests/Server/Utils/Realtime.test.ts +502 -0
- package/Tests/Server/Utils/SecurityEvent/Connectors/GoogleSecOps/GoogleSecOpsConnectorSeverity.test.ts +216 -0
- package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +142 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.test.ts +140 -0
- package/Tests/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepairClickhouseIntegration.test.ts +542 -0
- package/Tests/Server/Utils/Telemetry/ChangeEventRow.test.ts +743 -0
- package/Tests/Server/Utils/Telemetry/RuntimeMetrics.test.ts +465 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Alert.test.ts +202 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeams/Messages/ScheduledMaintenance.test.ts +231 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/Alert.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/AlertEpisode.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/Incident.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/IncidentEpisode.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/Slack/Messages/ScheduledMaintenance.test.ts +247 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
- package/Tests/Types/AI/AIInsightEvidence.test.ts +206 -0
- package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
- package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
- package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtilAnonymous.test.ts +144 -0
- package/Tests/Types/Call/CallProvider.test.ts +528 -0
- package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
- package/Tests/Types/Kubernetes/KubernetesCostIngest.test.ts +236 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleTimeline.test.ts +736 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleTimelineLayout.test.ts +996 -0
- package/Tests/Types/SecurityEvent/SigmaRule.test.ts +142 -0
- package/Tests/Types/Workflow/Components/JSON.test.ts +182 -0
- package/Tests/UI/Components/BasicFormDropdownNormalization.test.tsx +116 -1
- package/Tests/UI/Components/Dropdown/DropdownAsyncOptions.test.tsx +81 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
- package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +165 -171
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
- package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
- package/Tests/UI/Components/EventAttachmentList.test.tsx +174 -0
- package/Tests/UI/Components/Forms/BasicFormBurnRateTemplateDefaults.test.tsx +395 -0
- package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +286 -0
- package/Tests/UI/Components/Forms/FormSummary.test.tsx +128 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
- package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
- package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableQueryChange.test.tsx +365 -0
- package/Tests/UI/Components/OpenAuthenticatedUrl.test.ts +358 -0
- package/Tests/UI/Components/SessionAwareImage.test.tsx +496 -0
- package/Tests/UI/Components/TelemetryHistogramZeroBuckets.test.tsx +190 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/Components/TooltipInteractive.test.tsx +97 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardInstallGuidance.test.tsx +1 -1
- package/Tests/UI/Monitor/EvaluationLogListTimestamps.test.tsx +367 -0
- package/Tests/UI/Utils/API/BaseAPIRefreshSession.test.ts +1087 -0
- package/Tests/UI/Utils/API/DashboardHost.ts +12 -0
- package/Tests/UI/Utils/API/FakeAxiosServer.ts +183 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +10 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +2 -0
- package/Tests/UI/Utils/Cookie.test.ts +440 -0
- package/Tests/UI/Utils/ModelAPIRequestClient.test.ts +278 -0
- package/Tests/UI/Utils/Navigation.test.ts +33 -0
- package/Tests/UI/Utils/PricingPlan.test.ts +295 -0
- package/Tests/UI/Utils/Realtime.test.ts +759 -0
- package/Tests/UI/Utils/Telemetry/Telemetry.test.ts +500 -0
- package/Tests/Utils/APIInstanceDispatch.test.ts +311 -0
- package/Tests/Utils/HostAddressUtil.test.ts +138 -0
- package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
- package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
- package/Tests/Utils/SecurityEvent/GoogleSecOpsAlertNormalizerSeverity.test.ts +565 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- package/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.ts +40 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
- package/Types/Database/CanonicalModelInstance.ts +102 -0
- package/Types/Database/TableColumn.ts +20 -6
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
- package/Types/IP/IPv6.ts +6 -1
- package/Types/Monitor/MonitorEvaluationSummary.ts +3 -0
- package/Types/Monitor/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- package/Types/OnCallDutyPolicy/ScheduleTimeline.ts +507 -0
- package/Types/OnCallDutyPolicy/ScheduleTimelineLayout.ts +589 -0
- package/Types/Realtime/EventName.ts +11 -0
- package/Types/SecurityEvent/DetectionFindingConstants.ts +14 -0
- package/Types/SecurityEvent/OcsfSeverity.ts +31 -26
- package/Types/SecurityEvent/SigmaRule.ts +51 -0
- package/Types/SecurityEvent/ThreatIntelConstants.ts +18 -0
- package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
- package/UI/Components/AttachmentList/EventAttachmentList.tsx +30 -2
- package/UI/Components/Dashboard/DashboardVariableControl.tsx +12 -2
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/EditionLabel/EditionLabel.tsx +808 -1195
- package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
- package/UI/Components/EventItem/EventItem.tsx +12 -1
- package/UI/Components/Forms/BasicForm.tsx +151 -126
- package/UI/Components/Forms/CollapsibleFormSection.tsx +63 -0
- package/UI/Components/Forms/Fields/FormField.tsx +10 -4
- package/UI/Components/Forms/FormSummary.tsx +7 -0
- package/UI/Components/Forms/Types/Field.ts +10 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +2 -1
- package/UI/Components/Markdown.tsx/SessionAwareImage.tsx +122 -0
- package/UI/Components/ModelList/ModelList.tsx +11 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +34 -5
- package/UI/Components/ModelTable/TableView.tsx +1 -1
- package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +8 -1
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Utils/API/API.ts +173 -12
- package/UI/Utils/API/RequestOptions.ts +11 -0
- package/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.ts +31 -7
- package/UI/Utils/ModelAPI/ModelAPI.ts +30 -9
- package/UI/Utils/Navigation.ts +9 -0
- package/UI/Utils/OpenAuthenticatedUrl.ts +154 -0
- package/UI/Utils/Realtime.ts +176 -30
- package/UI/esbuild-enterprise.js +263 -0
- package/Utils/API.ts +14 -5
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
- package/Utils/HostAddressUtil.ts +94 -0
- package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- package/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.ts +157 -7
- package/Utils/SecurityEvent/Sigma/SigmaRuleParser.ts +9 -17
- package/Utils/Slo/SloBurnRateTemplate.ts +2 -2
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
- package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleCalendarFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js +1 -1
- package/build/dist/Models/DatabaseModels/ProjectOnCallCalendarFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallCalendarFeed.js.map +1 -1
- package/build/dist/Server/API/AIBillingAPI.js +1 -1
- package/build/dist/Server/API/AIBillingAPI.js.map +1 -1
- package/build/dist/Server/API/AIInsightAPI.js +1 -4
- package/build/dist/Server/API/AIInsightAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +1 -4
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AIReadinessAPI.js +1 -3
- package/build/dist/Server/API/AIReadinessAPI.js.map +1 -1
- package/build/dist/Server/API/AlertAPI.js +1 -1
- package/build/dist/Server/API/AlertAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +1 -4
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +33 -0
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAnalyticsAPI.js +55 -10
- package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
- package/build/dist/Server/API/BillingAPI.js +2 -2
- package/build/dist/Server/API/BillingAPI.js.map +1 -1
- package/build/dist/Server/API/BillingInvoiceAPI.js +1 -1
- package/build/dist/Server/API/BillingInvoiceAPI.js.map +1 -1
- package/build/dist/Server/API/BillingPaymentMethodAPI.js +2 -2
- package/build/dist/Server/API/BillingPaymentMethodAPI.js.map +1 -1
- package/build/dist/Server/API/CodeFixRunAPI.js +1 -3
- package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +50 -5
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +12 -12
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +158 -342
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +2 -2
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
- package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
- package/build/dist/Server/API/NotificationAPI.js +1 -1
- package/build/dist/Server/API/NotificationAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallCalendarAPI.js +1 -4
- package/build/dist/Server/API/OnCallCalendarAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallDutyPolicyAPI.js +6 -0
- package/build/dist/Server/API/OnCallDutyPolicyAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js +4 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js +494 -0
- package/build/dist/Server/API/OnCallScheduleTimelineAPI.js.map +1 -0
- package/build/dist/Server/API/ProjectAPI.js +1 -1
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectOIDC.js +24 -16
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +24 -16
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
- package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +218 -76
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +11 -4
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +2 -2
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +2 -2
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +2 -2
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/UserSlackAPI.js +1 -1
- package/build/dist/Server/API/UserSlackAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +2 -2
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserTotpAuthAPI.js +1 -1
- package/build/dist/Server/API/UserTotpAuthAPI.js.map +1 -1
- package/build/dist/Server/API/UserWebAuthnAPI.js +2 -2
- package/build/dist/Server/API/UserWebAuthnAPI.js.map +1 -1
- package/build/dist/Server/API/UserWebhookAPI.js +1 -1
- package/build/dist/Server/API/UserWebhookAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +2 -2
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +84 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -2
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +94 -15
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +80 -4
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/AuditLogService.js +71 -740
- package/build/dist/Server/Services/AuditLogService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +171 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DetectionRuleService.js +4 -4
- package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +63 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +90 -17
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -4
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyChildService.js +170 -0
- package/build/dist/Server/Services/OnCallDutyPolicyChildService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleTeamService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +2 -2
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
- package/build/dist/Server/Services/PayAsYouGoBillingService.js +20 -27
- package/build/dist/Server/Services/PayAsYouGoBillingService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +231 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +198 -16
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +71 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +10 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamPermissionService.js +89 -27
- package/build/dist/Server/Services/TeamPermissionService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +9 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/ThreatIntelFeedService.js +5 -4
- package/build/dist/Server/Services/ThreatIntelFeedService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -16
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +9 -6
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/Index.js +60 -6
- package/build/dist/Server/Types/Database/Permissions/Index.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +24 -16
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +31 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +7 -0
- package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js +7 -0
- package/build/dist/Server/Utils/AI/AIRunPrivacyFilter.js.map +1 -1
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
- package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
- package/build/dist/Server/Utils/MasterAdminPageAccess.js +39 -0
- package/build/dist/Server/Utils/MasterAdminPageAccess.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +96 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +3 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +449 -261
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +3 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
- package/build/dist/Server/Utils/Realtime.js +126 -37
- package/build/dist/Server/Utils/Realtime.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +7 -25
- package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js +127 -0
- package/build/dist/Server/Utils/SecurityEvent/GoogleSecOpsSeverityRepair.js.map +1 -0
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +1 -1
- package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js +3 -2
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelFeedPoller.js.map +1 -1
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js +4 -8
- package/build/dist/Server/Utils/SecurityEvent/ThreatIntel/ThreatIntelMatcher.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +59 -11
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js +31 -1
- package/build/dist/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
- package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
- package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
- package/build/dist/Types/Database/TableColumn.js +19 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
- package/build/dist/Types/IP/IPv6.js +6 -1
- package/build/dist/Types/IP/IPv6.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js +321 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimeline.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js +372 -0
- package/build/dist/Types/OnCallDutyPolicy/ScheduleTimelineLayout.js.map +1 -0
- package/build/dist/Types/Realtime/EventName.js +10 -0
- package/build/dist/Types/Realtime/EventName.js.map +1 -1
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +11 -0
- package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
- package/build/dist/Types/SecurityEvent/OcsfSeverity.js +30 -25
- package/build/dist/Types/SecurityEvent/OcsfSeverity.js.map +1 -1
- package/build/dist/Types/SecurityEvent/SigmaRule.js +47 -0
- package/build/dist/Types/SecurityEvent/SigmaRule.js.map +1 -1
- package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js +14 -0
- package/build/dist/Types/SecurityEvent/ThreatIntelConstants.js.map +1 -1
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +9 -4
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -1
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js +10 -2
- package/build/dist/UI/Components/Dashboard/DashboardVariableControl.js.map +1 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js +5 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +425 -585
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
- package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
- package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +70 -64
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +27 -0
- package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -0
- package/build/dist/UI/Components/Forms/Fields/FormField.js +10 -7
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/FormSummary.js +7 -0
- package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +2 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js +84 -0
- package/build/dist/UI/Components/Markdown.tsx/SessionAwareImage.js.map +1 -0
- package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +14 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +2 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/UI/Utils/API/API.js +143 -19
- package/build/dist/UI/Utils/API/API.js.map +1 -1
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js +21 -7
- package/build/dist/UI/Utils/AnalyticsModelAPI/AnalyticsModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +26 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +8 -0
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/OpenAuthenticatedUrl.js +92 -0
- package/build/dist/UI/Utils/OpenAuthenticatedUrl.js.map +1 -0
- package/build/dist/UI/Utils/Realtime.js +120 -15
- package/build/dist/UI/Utils/Realtime.js.map +1 -1
- package/build/dist/Utils/API.js +13 -5
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/HostAddressUtil.js +80 -0
- package/build/dist/Utils/HostAddressUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js +123 -6
- package/build/dist/Utils/SecurityEvent/GoogleSecOpsAlertNormalizer.js.map +1 -1
- package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js +4 -18
- package/build/dist/Utils/SecurityEvent/Sigma/SigmaRuleParser.js.map +1 -1
- package/build/dist/Utils/Slo/SloBurnRateTemplate.js +2 -2
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
- package/jest.config.json +3 -1
- package/package.json +1 -1
- package/test-setup.sh +103 -34
- package/tsconfig.json +13 -0
- package/Server/API/EnterpriseLicenseAPI.ts +0 -925
- package/Server/API/TeamComplianceAPI.ts +0 -158
- package/Server/Middleware/SCIMAuthorization.ts +0 -141
- package/Server/Services/TeamComplianceService.ts +0 -733
- package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
- package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
- package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
- package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
- package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
- package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
- package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
- package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
- package/build/dist/Server/Services/TeamComplianceService.js +0 -537
- package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
|
@@ -99,6 +99,7 @@ export default class MonitorIncident {
|
|
|
99
99
|
select: {
|
|
100
100
|
_id: true,
|
|
101
101
|
title: true,
|
|
102
|
+
createdAt: true,
|
|
102
103
|
createdCriteriaId: true,
|
|
103
104
|
createdIncidentTemplateId: true,
|
|
104
105
|
projectId: true,
|
|
@@ -579,6 +580,7 @@ export default class MonitorIncident {
|
|
|
579
580
|
relatedIncidentNumber: alreadyOpenIncident?.incidentNumber,
|
|
580
581
|
relatedIncidentNumberWithPrefix:
|
|
581
582
|
alreadyOpenIncident?.incidentNumberWithPrefix,
|
|
583
|
+
relatedIncidentCreatedAt: alreadyOpenIncident?.createdAt,
|
|
582
584
|
at: OneUptimeDate.getCurrentDate(),
|
|
583
585
|
});
|
|
584
586
|
continue;
|
|
@@ -913,7 +915,7 @@ export default class MonitorIncident {
|
|
|
913
915
|
relatedIncidentNumber: createdIncident.incidentNumber,
|
|
914
916
|
relatedIncidentNumberWithPrefix:
|
|
915
917
|
createdIncident.incidentNumberWithPrefix,
|
|
916
|
-
at: OneUptimeDate.getCurrentDate(),
|
|
918
|
+
at: createdIncident.createdAt || OneUptimeDate.getCurrentDate(),
|
|
917
919
|
});
|
|
918
920
|
} catch (err) {
|
|
919
921
|
/*
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
2
|
+
import MonitoringIntervalUtil, {
|
|
3
|
+
MonitoringIntervalNormalization,
|
|
4
|
+
MonitoringIntervalNormalizationStatus,
|
|
5
|
+
} from "../../../Utils/Monitor/MonitoringIntervalUtil";
|
|
6
|
+
import CronTab from "../CronTab";
|
|
7
|
+
|
|
8
|
+
/*
|
|
9
|
+
* Server-side policy for `Monitor.monitoringInterval`.
|
|
10
|
+
*
|
|
11
|
+
* MonitoringIntervalUtil says what a value MEANS and never throws.
|
|
12
|
+
* This says what we DO about it on a write: understood values are rewritten
|
|
13
|
+
* to canonical cron, and genuinely meaningless ones are refused with a
|
|
14
|
+
* message that names the cron to use instead.
|
|
15
|
+
*
|
|
16
|
+
* WHY THE RUNTIME PARSER GETS THE LAST WORD
|
|
17
|
+
*
|
|
18
|
+
* The isomorphic normalizer is a hand-rolled grammar; the scheduler runs on
|
|
19
|
+
* cron-parser. Where the two disagree, cron-parser wins, because it is what
|
|
20
|
+
* actually computes `nextPingAt`. Validation that rejected an expression the
|
|
21
|
+
* scheduler would happily honour ("@hourly", exotic step/range forms) would
|
|
22
|
+
* be this same bug in mirror image: the UI and the runtime disagreeing about
|
|
23
|
+
* a stored value, with the customer caught in between. So Unrecognized is
|
|
24
|
+
* re-checked against cron-parser before we refuse anything.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
* The shortest cadence the probe fleet can honour.
|
|
29
|
+
*
|
|
30
|
+
* `claimMonitorProbesForProbing` is driven by a cron that ticks once a
|
|
31
|
+
* minute, so a sub-minute schedule is a promise we cannot keep. cron-parser
|
|
32
|
+
* accepts 6-field per-second expressions such as "* * * * * *" quite
|
|
33
|
+
* happily; without this floor an API client could ask for a per-second probe
|
|
34
|
+
* and silently get a per-minute one — the exact class of bug this file
|
|
35
|
+
* exists to close.
|
|
36
|
+
*/
|
|
37
|
+
export const MINIMUM_MONITORING_INTERVAL_IN_SECONDS: number = 60;
|
|
38
|
+
|
|
39
|
+
export default class MonitoringIntervalValidator {
|
|
40
|
+
/**
|
|
41
|
+
* Validate and canonicalize an inbound monitoring interval.
|
|
42
|
+
*
|
|
43
|
+
* Returns the value to persist: null for "no schedule" (legitimate — a
|
|
44
|
+
* Manual monitor is never probed), otherwise a cron expression the
|
|
45
|
+
* scheduler can parse. Throws BadDataException when the value cannot be
|
|
46
|
+
* understood by either the normalizer or cron-parser.
|
|
47
|
+
*/
|
|
48
|
+
public static validateAndNormalize(
|
|
49
|
+
value: string | null | undefined,
|
|
50
|
+
): string | null {
|
|
51
|
+
const result: MonitoringIntervalNormalization =
|
|
52
|
+
MonitoringIntervalUtil.normalize(value);
|
|
53
|
+
|
|
54
|
+
if (result.status === MonitoringIntervalNormalizationStatus.Empty) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (result.cron) {
|
|
59
|
+
MonitoringIntervalValidator.assertMeetsFloor(result.cron, result.input);
|
|
60
|
+
return result.cron;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/*
|
|
64
|
+
* Unrecognized by the grammar. Before refusing, ask the parser that
|
|
65
|
+
* actually schedules the probe — if it can read the expression, the
|
|
66
|
+
* scheduler can honour it and there is nothing to refuse.
|
|
67
|
+
*/
|
|
68
|
+
const trimmed: string = (result.input || "").trim();
|
|
69
|
+
const intervalInSeconds: number | null =
|
|
70
|
+
CronTab.getIntervalInSeconds(trimmed);
|
|
71
|
+
|
|
72
|
+
if (intervalInSeconds !== null) {
|
|
73
|
+
MonitoringIntervalValidator.assertMeetsFloor(trimmed, result.input);
|
|
74
|
+
return trimmed;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
throw new BadDataException(
|
|
78
|
+
`Invalid Monitoring Interval "${trimmed}". Expected a cron expression - use "${MonitoringIntervalUtil.getSuggestedCronForMessage()}" for every 5 minutes.`,
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* Applied to every accepted value, normalized or passed through, because
|
|
84
|
+
* the floor is about what the probe fleet can deliver and not about which
|
|
85
|
+
* code path produced the expression.
|
|
86
|
+
*/
|
|
87
|
+
private static assertMeetsFloor(
|
|
88
|
+
cron: string,
|
|
89
|
+
input: string | null | undefined,
|
|
90
|
+
): void {
|
|
91
|
+
const intervalInSeconds: number | null = CronTab.getIntervalInSeconds(cron);
|
|
92
|
+
|
|
93
|
+
if (
|
|
94
|
+
intervalInSeconds !== null &&
|
|
95
|
+
intervalInSeconds < MINIMUM_MONITORING_INTERVAL_IN_SECONDS
|
|
96
|
+
) {
|
|
97
|
+
throw new BadDataException(
|
|
98
|
+
`Monitoring Interval "${(input || cron).trim()}" is faster than once a minute, which probes cannot deliver. Use "* * * * *" for the fastest supported schedule.`,
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The cron a stored value means, for READ paths.
|
|
105
|
+
*
|
|
106
|
+
* Read paths must stay total: a row written before this validator existed
|
|
107
|
+
* (or restored from a backup, or written through a hook-free path) is not
|
|
108
|
+
* an exception, it is just a row. Callers fall back to their own default
|
|
109
|
+
* when this returns null.
|
|
110
|
+
*/
|
|
111
|
+
public static normalizeForRead(
|
|
112
|
+
value: string | null | undefined,
|
|
113
|
+
): string | null {
|
|
114
|
+
return MonitoringIntervalUtil.toCronOrNull(value);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -176,7 +176,7 @@ export interface EmptyOutcomeOptions {
|
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/* The schedule facts every render needs, read once per request. */
|
|
179
|
-
interface ScheduleInfo {
|
|
179
|
+
export interface ScheduleInfo {
|
|
180
180
|
id: ObjectID;
|
|
181
181
|
name: string;
|
|
182
182
|
timezone?: string | undefined;
|
package/Server/Utils/Realtime.ts
CHANGED
|
@@ -24,6 +24,19 @@ import Dictionary from "../../Types/Dictionary";
|
|
|
24
24
|
import UserPermissionUtil from "./UserPermission/UserPermission";
|
|
25
25
|
import CaptureSpan from "./Telemetry/CaptureSpan";
|
|
26
26
|
|
|
27
|
+
// What became of one ListenToModelEvent request.
|
|
28
|
+
export enum ListenToModelEventOutcome {
|
|
29
|
+
Joined = "Joined",
|
|
30
|
+
// No access token, or one that no longer decodes. The client was told.
|
|
31
|
+
AuthenticationRequired = "AuthenticationRequired",
|
|
32
|
+
// A valid session without access to this tenant or model.
|
|
33
|
+
NotAuthorized = "NotAuthorized",
|
|
34
|
+
// The request itself was malformed.
|
|
35
|
+
InvalidRequest = "InvalidRequest",
|
|
36
|
+
// Something failed while authorizing (for example the permission cache).
|
|
37
|
+
Failed = "Failed",
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
export default abstract class Realtime {
|
|
28
41
|
private static socketServer: SocketServer | null = null;
|
|
29
42
|
|
|
@@ -45,37 +58,19 @@ export default abstract class Realtime {
|
|
|
45
58
|
this.socketServer!.on("connection", (socket: Socket) => {
|
|
46
59
|
logger.debug("New socket connection established");
|
|
47
60
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
logger.error("modelType is not a string", socketLogAttributes);
|
|
62
|
-
throw new BadDataException("modelType is not a string");
|
|
63
|
-
}
|
|
64
|
-
if (typeof data["modelName"] !== "string") {
|
|
65
|
-
logger.error("modelName is not a string", socketLogAttributes);
|
|
66
|
-
throw new BadDataException("modelName is not a string");
|
|
67
|
-
}
|
|
68
|
-
if (typeof data["tenantId"] !== "string") {
|
|
69
|
-
logger.error("tenantId is not a string", socketLogAttributes);
|
|
70
|
-
throw new BadDataException("tenantId is not a string");
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
await Realtime.listenToModelEvent(socket, {
|
|
74
|
-
eventType: data["eventType"] as ModelEventType,
|
|
75
|
-
modelType: data["modelType"] as DatabaseType,
|
|
76
|
-
modelName: data["modelName"] as string,
|
|
77
|
-
tenantId: data["tenantId"] as string,
|
|
78
|
-
});
|
|
61
|
+
/*
|
|
62
|
+
* socket.io calls a listener and throws away what it returns. An async
|
|
63
|
+
* listener that throws is therefore an unhandled rejection: nothing
|
|
64
|
+
* goes back to the client, and the subscription it asked for simply
|
|
65
|
+
* never happens. handleListenToModelEventRequest settles every outcome
|
|
66
|
+
* itself; the catch is a backstop, not the error handling.
|
|
67
|
+
*/
|
|
68
|
+
socket.on(EventName.ListenToModalEvent, (data: JSONObject): void => {
|
|
69
|
+
Realtime.handleListenToModelEventRequest(socket, data).catch(
|
|
70
|
+
(err: unknown) => {
|
|
71
|
+
logger.error(err);
|
|
72
|
+
},
|
|
73
|
+
);
|
|
79
74
|
});
|
|
80
75
|
});
|
|
81
76
|
}
|
|
@@ -83,11 +78,108 @@ export default abstract class Realtime {
|
|
|
83
78
|
return this.socketServer;
|
|
84
79
|
}
|
|
85
80
|
|
|
81
|
+
/*
|
|
82
|
+
* One ListenToModelEvent from a client, start to finish. Never throws: a
|
|
83
|
+
* malformed request, a missing or expired access token, a refused
|
|
84
|
+
* subscription and a failing permission lookup each end here as an outcome,
|
|
85
|
+
* so none of them can become an unhandled rejection in the socket listener.
|
|
86
|
+
*/
|
|
87
|
+
@CaptureSpan()
|
|
88
|
+
public static async handleListenToModelEventRequest(
|
|
89
|
+
socket: Socket,
|
|
90
|
+
data: JSONObject,
|
|
91
|
+
): Promise<ListenToModelEventOutcome> {
|
|
92
|
+
logger.debug("Received ListenToModalEvent with data:");
|
|
93
|
+
logger.debug(data);
|
|
94
|
+
|
|
95
|
+
let request: ListenToModelEventJSON;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
request = Realtime.parseListenToModelEventRequest(data);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
logger.error(err);
|
|
101
|
+
return ListenToModelEventOutcome.InvalidRequest;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
return await Realtime.listenToModelEvent(socket, request);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
// A permission-cache (Redis) failure, say. The room is not joined.
|
|
108
|
+
const failureLogAttributes: LogAttributes = {
|
|
109
|
+
projectId: request.tenantId,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
logger.error(err, failureLogAttributes);
|
|
113
|
+
return ListenToModelEventOutcome.Failed;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private static parseListenToModelEventRequest(
|
|
118
|
+
data: JSONObject,
|
|
119
|
+
): ListenToModelEventJSON {
|
|
120
|
+
if (!data || typeof data !== "object") {
|
|
121
|
+
logger.error("ListenToModelEvent data is not an object");
|
|
122
|
+
throw new BadDataException("ListenToModelEvent data is not an object");
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const socketLogAttributes: LogAttributes = {
|
|
126
|
+
projectId: data["tenantId"]?.toString(),
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
if (typeof data["eventType"] !== "string") {
|
|
130
|
+
logger.error("eventType is not a string", socketLogAttributes);
|
|
131
|
+
throw new BadDataException("eventType is not a string");
|
|
132
|
+
}
|
|
133
|
+
if (typeof data["modelType"] !== "string") {
|
|
134
|
+
logger.error("modelType is not a string", socketLogAttributes);
|
|
135
|
+
throw new BadDataException("modelType is not a string");
|
|
136
|
+
}
|
|
137
|
+
if (typeof data["modelName"] !== "string") {
|
|
138
|
+
logger.error("modelName is not a string", socketLogAttributes);
|
|
139
|
+
throw new BadDataException("modelName is not a string");
|
|
140
|
+
}
|
|
141
|
+
if (typeof data["tenantId"] !== "string") {
|
|
142
|
+
logger.error("tenantId is not a string", socketLogAttributes);
|
|
143
|
+
throw new BadDataException("tenantId is not a string");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
eventType: data["eventType"] as ModelEventType,
|
|
148
|
+
modelType: data["modelType"] as DatabaseType,
|
|
149
|
+
modelName: data["modelName"] as string,
|
|
150
|
+
tenantId: data["tenantId"] as string,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
* The socket has no usable user session: tell the client, which refreshes
|
|
156
|
+
* its session and reconnects so the new handshake carries the new cookie.
|
|
157
|
+
* Dropping the request silently is what used to happen, and it left every
|
|
158
|
+
* subscription made after the access token expired dead (no live counters
|
|
159
|
+
* after switching project, no live logs) with nothing in the browser to
|
|
160
|
+
* show why.
|
|
161
|
+
*/
|
|
162
|
+
private static rejectForMissingAuthentication(
|
|
163
|
+
socket: Socket,
|
|
164
|
+
data: ListenToModelEventJSON,
|
|
165
|
+
reason: string,
|
|
166
|
+
listenLogAttributes: LogAttributes,
|
|
167
|
+
): ListenToModelEventOutcome {
|
|
168
|
+
logger.debug(
|
|
169
|
+
`${reason}, aborting joining room and asking the client to re-authenticate`,
|
|
170
|
+
listenLogAttributes,
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
socket.emit(EventName.AuthenticationRequired, data);
|
|
174
|
+
|
|
175
|
+
return ListenToModelEventOutcome.AuthenticationRequired;
|
|
176
|
+
}
|
|
177
|
+
|
|
86
178
|
@CaptureSpan()
|
|
87
179
|
public static async listenToModelEvent(
|
|
88
180
|
socket: Socket,
|
|
89
181
|
data: ListenToModelEventJSON,
|
|
90
|
-
): Promise<
|
|
182
|
+
): Promise<ListenToModelEventOutcome> {
|
|
91
183
|
const listenLogAttributes: LogAttributes = {
|
|
92
184
|
projectId: data.tenantId?.toString(),
|
|
93
185
|
};
|
|
@@ -116,31 +208,51 @@ export default abstract class Realtime {
|
|
|
116
208
|
this.getAccessTokenFromSocket(socket);
|
|
117
209
|
|
|
118
210
|
if (!userAccessToken) {
|
|
119
|
-
|
|
120
|
-
|
|
211
|
+
return this.rejectForMissingAuthentication(
|
|
212
|
+
socket,
|
|
213
|
+
data,
|
|
214
|
+
"User access token not found in socket",
|
|
121
215
|
listenLogAttributes,
|
|
122
216
|
);
|
|
123
|
-
return;
|
|
124
217
|
}
|
|
125
218
|
|
|
126
219
|
logger.debug("Decoding user access token", listenLogAttributes);
|
|
127
|
-
|
|
128
|
-
|
|
220
|
+
|
|
221
|
+
/*
|
|
222
|
+
* The token is the one the browser sent with the handshake, and it is not
|
|
223
|
+
* re-read for the life of the connection. Once it expires every decode
|
|
224
|
+
* throws, which is the normal state of a dashboard tab left open past the
|
|
225
|
+
* access token's lifetime, not an error in the request.
|
|
226
|
+
*/
|
|
227
|
+
let userAuthorizationData: JSONWebTokenData;
|
|
228
|
+
|
|
229
|
+
try {
|
|
230
|
+
userAuthorizationData = JSONWebToken.decode(userAccessToken);
|
|
231
|
+
} catch {
|
|
232
|
+
return this.rejectForMissingAuthentication(
|
|
233
|
+
socket,
|
|
234
|
+
data,
|
|
235
|
+
"User access token in socket is invalid or expired",
|
|
236
|
+
listenLogAttributes,
|
|
237
|
+
);
|
|
238
|
+
}
|
|
129
239
|
|
|
130
240
|
if (!userAuthorizationData) {
|
|
131
|
-
|
|
132
|
-
|
|
241
|
+
return this.rejectForMissingAuthentication(
|
|
242
|
+
socket,
|
|
243
|
+
data,
|
|
244
|
+
"User authorization data not found in socket",
|
|
133
245
|
listenLogAttributes,
|
|
134
246
|
);
|
|
135
|
-
return;
|
|
136
247
|
}
|
|
137
248
|
|
|
138
249
|
if (!userAuthorizationData.userId) {
|
|
139
|
-
|
|
140
|
-
|
|
250
|
+
return this.rejectForMissingAuthentication(
|
|
251
|
+
socket,
|
|
252
|
+
data,
|
|
253
|
+
"User ID not found in socket",
|
|
141
254
|
listenLogAttributes,
|
|
142
255
|
);
|
|
143
|
-
return;
|
|
144
256
|
}
|
|
145
257
|
|
|
146
258
|
logger.debug("Checking user access permissions", listenLogAttributes);
|
|
@@ -179,7 +291,7 @@ export default abstract class Realtime {
|
|
|
179
291
|
"User does not have access to this tenant, aborting joining room",
|
|
180
292
|
listenLogAttributes,
|
|
181
293
|
);
|
|
182
|
-
return;
|
|
294
|
+
return ListenToModelEventOutcome.NotAuthorized;
|
|
183
295
|
}
|
|
184
296
|
|
|
185
297
|
logger.debug(
|
|
@@ -214,12 +326,16 @@ export default abstract class Realtime {
|
|
|
214
326
|
}
|
|
215
327
|
}
|
|
216
328
|
|
|
329
|
+
/*
|
|
330
|
+
* Authenticated but not allowed. The room is not joined and, as before,
|
|
331
|
+
* nothing is sent back: a fresh session would not change the answer.
|
|
332
|
+
*/
|
|
217
333
|
if (!hasAccess) {
|
|
218
334
|
logger.debug(
|
|
219
335
|
"User does not have access to this tenant, aborting joining room",
|
|
220
336
|
listenLogAttributes,
|
|
221
337
|
);
|
|
222
|
-
return;
|
|
338
|
+
return ListenToModelEventOutcome.NotAuthorized;
|
|
223
339
|
}
|
|
224
340
|
|
|
225
341
|
if (data.modelId) {
|
|
@@ -244,6 +360,8 @@ export default abstract class Realtime {
|
|
|
244
360
|
// join the room.
|
|
245
361
|
await socket.join(roomId);
|
|
246
362
|
}
|
|
363
|
+
|
|
364
|
+
return ListenToModelEventOutcome.Joined;
|
|
247
365
|
}
|
|
248
366
|
|
|
249
367
|
@CaptureSpan()
|
|
@@ -8,13 +8,18 @@ import OcsfSeverity, {
|
|
|
8
8
|
OcsfSeverityId,
|
|
9
9
|
} from "../../../Types/SecurityEvent/OcsfSeverity";
|
|
10
10
|
import { ocsfCategoryForClassUid } from "../../../Types/SecurityEvent/OcsfEventClass";
|
|
11
|
-
import SigmaRule, {
|
|
11
|
+
import SigmaRule, {
|
|
12
|
+
SIGMA_LEVEL_TO_OCSF_SEVERITY,
|
|
13
|
+
isSevereSigmaLevel,
|
|
14
|
+
} from "../../../Types/SecurityEvent/SigmaRule";
|
|
12
15
|
import {
|
|
13
16
|
DETECTION_DISTINCT_COUNT_ATTRIBUTE,
|
|
14
17
|
DETECTION_FINDING_CLASS_NAME,
|
|
15
18
|
DETECTION_FINDING_CLASS_UID,
|
|
16
19
|
DETECTION_GROUP_VALUE_ATTRIBUTE,
|
|
17
20
|
DETECTION_MATCH_COUNT_ATTRIBUTE,
|
|
21
|
+
DETECTION_MAX_GROUPS_PER_EVALUATION,
|
|
22
|
+
DETECTION_MAX_LOOKBACK_IN_MINUTES,
|
|
18
23
|
DETECTION_RULE_ID_ATTRIBUTE,
|
|
19
24
|
DETECTION_RULE_NAME_ATTRIBUTE,
|
|
20
25
|
DETECTION_SIGMA_ID_ATTRIBUTE,
|
|
@@ -49,24 +54,6 @@ import { buildSecurityEventDbRow } from "./SecurityEventRow";
|
|
|
49
54
|
|
|
50
55
|
const DETECTIONS_SERVICE_NAME: string = "OneUptime Detections";
|
|
51
56
|
|
|
52
|
-
/*
|
|
53
|
-
* Cap on how far back one evaluation may scan, whatever lastEvaluatedAt
|
|
54
|
-
* says — a rule re-enabled after a month must not trigger a month-long
|
|
55
|
-
* table scan.
|
|
56
|
-
*/
|
|
57
|
-
const MAX_LOOKBACK_IN_MINUTES: number = 24 * 60;
|
|
58
|
-
|
|
59
|
-
// One alert per distinct group value per cycle, at most.
|
|
60
|
-
const MAX_GROUPS_PER_EVALUATION: number = 100;
|
|
61
|
-
|
|
62
|
-
const SIGMA_LEVEL_TO_OCSF: Record<SigmaLevel, OcsfSeverity> = {
|
|
63
|
-
[SigmaLevel.Informational]: OcsfSeverity.Informational,
|
|
64
|
-
[SigmaLevel.Low]: OcsfSeverity.Low,
|
|
65
|
-
[SigmaLevel.Medium]: OcsfSeverity.Medium,
|
|
66
|
-
[SigmaLevel.High]: OcsfSeverity.High,
|
|
67
|
-
[SigmaLevel.Critical]: OcsfSeverity.Critical,
|
|
68
|
-
};
|
|
69
|
-
|
|
70
57
|
export interface DetectionRuleEvaluationResult {
|
|
71
58
|
ruleId: string;
|
|
72
59
|
matchedGroups: number;
|
|
@@ -190,7 +177,7 @@ export default class DetectionRuleEvaluator {
|
|
|
190
177
|
|
|
191
178
|
const earliestAllowed: Date = OneUptimeDate.addRemoveMinutes(
|
|
192
179
|
endTime,
|
|
193
|
-
-
|
|
180
|
+
-DETECTION_MAX_LOOKBACK_IN_MINUTES,
|
|
194
181
|
);
|
|
195
182
|
|
|
196
183
|
let startTime: Date = rule.lastEvaluatedAt
|
|
@@ -220,7 +207,7 @@ export default class DetectionRuleEvaluator {
|
|
|
220
207
|
groupByExpression,
|
|
221
208
|
distinctCountExpression,
|
|
222
209
|
minMatchCount: matchCountThreshold,
|
|
223
|
-
maxGroups:
|
|
210
|
+
maxGroups: DETECTION_MAX_GROUPS_PER_EVALUATION,
|
|
224
211
|
});
|
|
225
212
|
|
|
226
213
|
/*
|
|
@@ -500,7 +487,7 @@ export default class DetectionRuleEvaluator {
|
|
|
500
487
|
});
|
|
501
488
|
|
|
502
489
|
const severityName: OcsfSeverity =
|
|
503
|
-
|
|
490
|
+
SIGMA_LEVEL_TO_OCSF_SEVERITY[parsedRule.level] || OcsfSeverity.Medium;
|
|
504
491
|
|
|
505
492
|
const { categoryUid, categoryName } = ocsfCategoryForClassUid(
|
|
506
493
|
DETECTION_FINDING_CLASS_UID,
|
|
@@ -625,7 +612,7 @@ export default class DetectionRuleEvaluator {
|
|
|
625
612
|
projectId: data.projectId,
|
|
626
613
|
explicitSeverityId: data.rule.alertSeverityId,
|
|
627
614
|
severityLabel: data.parsedRule.level,
|
|
628
|
-
isSevere:
|
|
615
|
+
isSevere: isSevereSigmaLevel(data.parsedRule.level),
|
|
629
616
|
});
|
|
630
617
|
}
|
|
631
618
|
|
|
@@ -647,11 +634,7 @@ export default class DetectionRuleEvaluator {
|
|
|
647
634
|
projectId: data.projectId,
|
|
648
635
|
explicitSeverityId: data.rule.incidentSeverityId,
|
|
649
636
|
severityLabel: data.parsedRule.level,
|
|
650
|
-
isSevere:
|
|
637
|
+
isSevere: isSevereSigmaLevel(data.parsedRule.level),
|
|
651
638
|
});
|
|
652
639
|
}
|
|
653
|
-
|
|
654
|
-
private static isSevereLevel(level: SigmaLevel): boolean {
|
|
655
|
-
return level === SigmaLevel.Critical || level === SigmaLevel.High;
|
|
656
|
-
}
|
|
657
640
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import OcsfSeverity, {
|
|
2
|
+
OCSF_SEVERITY_ALIASES,
|
|
3
|
+
OcsfSeverityId,
|
|
4
|
+
} from "../../../Types/SecurityEvent/OcsfSeverity";
|
|
5
|
+
import {
|
|
6
|
+
DETECTION_FINDING_CLASS_UID,
|
|
7
|
+
GOOGLE_SECOPS_PRODUCT_NAME,
|
|
8
|
+
GOOGLE_SECOPS_RISK_SCORE_BANDS,
|
|
9
|
+
GOOGLE_SECOPS_VENDOR_NAME,
|
|
10
|
+
} from "../../../Utils/SecurityEvent/GoogleSecOpsAlertNormalizer";
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* Re-grades Google SecOps detections that were stored as Unknown before the
|
|
14
|
+
* normalizer learned to read a custom rule's severity.
|
|
15
|
+
*
|
|
16
|
+
* Every stored row keeps its source payload flattened into `attributes`
|
|
17
|
+
* (`detection.0.ruleLabels.2.key` = "severity", `...2.value` = "Medium"), so
|
|
18
|
+
* the grade the fixed GoogleSecOpsAlertNormalizer would give a row can be
|
|
19
|
+
* computed in SQL from the row itself. The expression below is that
|
|
20
|
+
* normalizer's resolveSeverity, written against the flattened keys:
|
|
21
|
+
*
|
|
22
|
+
* 1. detection[0].severity (Google's grade on curated rules)
|
|
23
|
+
* 2. the Collection's severity
|
|
24
|
+
* 3. the first ruleLabels "severity" that names a grade (YARA-L meta)
|
|
25
|
+
* 4. the first outcomes "risk_score" that grades, on Google's bands
|
|
26
|
+
*
|
|
27
|
+
* Its text tables are generated from OCSF_SEVERITY_ALIASES and
|
|
28
|
+
* GOOGLE_SECOPS_RISK_SCORE_BANDS, the same tables the normalizer reads, so
|
|
29
|
+
* the two cannot drift apart. It reads the list form of ruleLabels and
|
|
30
|
+
* outcomes Google returns; a label map in a hand-built webhook body is
|
|
31
|
+
* graded at ingest but not here.
|
|
32
|
+
*
|
|
33
|
+
* Only rows that are still Unknown and that the expression grades are
|
|
34
|
+
* touched, so the repair is idempotent and never overrides a grade.
|
|
35
|
+
*/
|
|
36
|
+
export default class GoogleSecOpsSeverityRepair {
|
|
37
|
+
/*
|
|
38
|
+
* The OCSF severity name a stored row's attributes grade to, or '' when
|
|
39
|
+
* nothing in them grades.
|
|
40
|
+
*/
|
|
41
|
+
public static gradeExpression(): string {
|
|
42
|
+
const detectionSeverity: string = `if(attributes['detection.0.severity'] != '', attributes['detection.0.severity'], attributes['detection.severity'])`;
|
|
43
|
+
const graded: Array<string> = [
|
|
44
|
+
GoogleSecOpsSeverityRepair.gradeText(detectionSeverity),
|
|
45
|
+
GoogleSecOpsSeverityRepair.gradeText("attributes['severity']"),
|
|
46
|
+
GoogleSecOpsSeverityRepair.firstKeyedGrade(
|
|
47
|
+
"(ruleLabels|rule_labels)",
|
|
48
|
+
"severity",
|
|
49
|
+
GoogleSecOpsSeverityRepair.gradeText,
|
|
50
|
+
),
|
|
51
|
+
GoogleSecOpsSeverityRepair.firstKeyedGrade(
|
|
52
|
+
"outcomes",
|
|
53
|
+
"risk_score",
|
|
54
|
+
GoogleSecOpsSeverityRepair.gradeRiskScore,
|
|
55
|
+
),
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
// The first of the four grades that is set, in the normalizer's order.
|
|
59
|
+
return `arrayFirst(grade -> grade != '', [${graded.join(", ")}])`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* The async ON CLUSTER mutation. `storageTable` is the local storage
|
|
64
|
+
* table and `onCluster` the cluster clause, as every data mutation on
|
|
65
|
+
* the clustered analytics schema is written.
|
|
66
|
+
*/
|
|
67
|
+
public static repairStatement(data: {
|
|
68
|
+
storageTable: string;
|
|
69
|
+
onCluster: string;
|
|
70
|
+
}): string {
|
|
71
|
+
const grade: string = GoogleSecOpsSeverityRepair.gradeExpression();
|
|
72
|
+
const names: Array<OcsfSeverity> = Object.keys(
|
|
73
|
+
OcsfSeverityId,
|
|
74
|
+
) as Array<OcsfSeverity>;
|
|
75
|
+
const severityId: string = `transform(${grade}, [${names
|
|
76
|
+
.map((name: OcsfSeverity): string => {
|
|
77
|
+
return GoogleSecOpsSeverityRepair.literal(name);
|
|
78
|
+
})
|
|
79
|
+
.join(", ")}], [${names
|
|
80
|
+
.map((name: OcsfSeverity): string => {
|
|
81
|
+
return String(OcsfSeverityId[name]);
|
|
82
|
+
})
|
|
83
|
+
.join(", ")}], ${OcsfSeverityId[OcsfSeverity.Unknown]})`;
|
|
84
|
+
|
|
85
|
+
return `ALTER TABLE ${data.storageTable}${data.onCluster} UPDATE severityName = ${grade}, severityId = ${severityId} WHERE ${GoogleSecOpsSeverityRepair.condition()}`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/*
|
|
89
|
+
* The rows the repair rewrites: Google SecOps detection findings still
|
|
90
|
+
* stored as Unknown whose attributes now grade. The cheap column checks
|
|
91
|
+
* come first so ClickHouse evaluates the attribute expression only for
|
|
92
|
+
* those rows.
|
|
93
|
+
*/
|
|
94
|
+
public static condition(): string {
|
|
95
|
+
return [
|
|
96
|
+
`vendorName = ${GoogleSecOpsSeverityRepair.literal(GOOGLE_SECOPS_VENDOR_NAME)}`,
|
|
97
|
+
`productName = ${GoogleSecOpsSeverityRepair.literal(GOOGLE_SECOPS_PRODUCT_NAME)}`,
|
|
98
|
+
`classUid = ${DETECTION_FINDING_CLASS_UID}`,
|
|
99
|
+
`severityId = ${OcsfSeverityId[OcsfSeverity.Unknown]}`,
|
|
100
|
+
`${GoogleSecOpsSeverityRepair.gradeExpression()} != ''`,
|
|
101
|
+
].join(" AND ");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// normalizeOcsfSeverity, minus Unknown: text that names no grade is ''.
|
|
105
|
+
private static gradeText(expression: string): string {
|
|
106
|
+
const graded: Array<[string, OcsfSeverity]> = Object.entries(
|
|
107
|
+
OCSF_SEVERITY_ALIASES,
|
|
108
|
+
).filter((entry: [string, OcsfSeverity]): boolean => {
|
|
109
|
+
return entry[1] !== OcsfSeverity.Unknown;
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const from: string = graded
|
|
113
|
+
.map((entry: [string, OcsfSeverity]): string => {
|
|
114
|
+
return GoogleSecOpsSeverityRepair.literal(entry[0]);
|
|
115
|
+
})
|
|
116
|
+
.join(", ");
|
|
117
|
+
const to: string = graded
|
|
118
|
+
.map((entry: [string, OcsfSeverity]): string => {
|
|
119
|
+
return GoogleSecOpsSeverityRepair.literal(entry[1]);
|
|
120
|
+
})
|
|
121
|
+
.join(", ");
|
|
122
|
+
|
|
123
|
+
return `transform(upperUTF8(${GoogleSecOpsSeverityRepair.trimmed(expression)}), [${from}], [${to}], '')`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* The normalizer's gradeRiskScore: a finite score above zero grades into
|
|
128
|
+
* the first band whose minimum it reaches.
|
|
129
|
+
*/
|
|
130
|
+
private static gradeRiskScore(expression: string): string {
|
|
131
|
+
const bands: string = GOOGLE_SECOPS_RISK_SCORE_BANDS.map(
|
|
132
|
+
(band: { minimum: number; severity: OcsfSeverity }): string => {
|
|
133
|
+
return `score >= ${band.minimum}, ${GoogleSecOpsSeverityRepair.literal(band.severity)}`;
|
|
134
|
+
},
|
|
135
|
+
).join(", ");
|
|
136
|
+
|
|
137
|
+
return `arrayMap(score -> multiIf(NOT isFinite(score) OR score <= 0, '', ${bands}, ''), [ifNull(toFloat64OrNull(${GoogleSecOpsSeverityRepair.trimmed(expression)}), 0)])[1]`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* The first grade among the entries of detection[0].<list> whose key is
|
|
142
|
+
* `key`, in list order: the normalizer's readKeyedValues + firstGrade.
|
|
143
|
+
* A flattened entry is `detection.0.<list>.<index>.key` / `.value`
|
|
144
|
+
* (`detection.<list>...` when the webhook sent detection as an object).
|
|
145
|
+
*/
|
|
146
|
+
private static firstKeyedGrade(
|
|
147
|
+
listPattern: string,
|
|
148
|
+
key: string,
|
|
149
|
+
grade: (expression: string) => string,
|
|
150
|
+
): string {
|
|
151
|
+
const keyPattern: string = `^detection[.](0[.])?${listPattern}[.][0-9]+[.]key$`;
|
|
152
|
+
const keys: string = `arraySort(entryKey -> toUInt64OrZero(extract(entryKey, '[.]([0-9]+)[.]key$')), arrayFilter(entryKey -> match(entryKey, ${GoogleSecOpsSeverityRepair.literal(keyPattern)}), mapKeys(attributes)))`;
|
|
153
|
+
const value: string =
|
|
154
|
+
"attributes[concat(substring(entryKey, 1, length(entryKey) - 3), 'value')]";
|
|
155
|
+
|
|
156
|
+
return `arrayFirst(entryGrade -> entryGrade != '', arrayMap(entryKey -> if(lowerUTF8(${GoogleSecOpsSeverityRepair.trimmed("attributes[entryKey]")}) = ${GoogleSecOpsSeverityRepair.literal(key)}, ${grade(value)}, ''), ${keys}))`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* JavaScript's String.trim strips all surrounding whitespace; ClickHouse's
|
|
161
|
+
* trim() strips spaces only.
|
|
162
|
+
*/
|
|
163
|
+
private static trimmed(expression: string): string {
|
|
164
|
+
return `replaceRegexpAll(${expression}, '^[[:space:]]+|[[:space:]]+$', '')`;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private static literal(value: string): string {
|
|
168
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
169
|
+
}
|
|
170
|
+
}
|