@oneuptime/common 13.0.8 → 14.0.1
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/Index.ts +4 -0
- package/Models/DatabaseModels/Monitor.ts +3 -2
- package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
- package/Models/DatabaseModels/ServiceLevelObjectiveFeed.ts +2 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.ts +522 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.ts +38 -4
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.ts +603 -0
- package/Scripts/generate-service-worker.js +65 -4
- package/Server/API/BaseAPI.ts +26 -5
- package/Server/API/GlobalConfigAPI.ts +228 -462
- package/Server/API/ProjectOIDC.ts +25 -16
- package/Server/API/ProjectSSO.ts +24 -16
- package/Server/API/StatusPageAPI.ts +100 -42
- package/Server/API/TeamMemberAPI.ts +10 -1
- 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/1794100000000-AddSloLabelAndOwnerRules.ts +248 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/UserAuthorization.ts +38 -16
- package/Server/Services/AuditLogService.ts +84 -1079
- package/Server/Services/DatabaseService.ts +10 -0
- package/Server/Services/EnterpriseLicenseService.ts +38 -0
- package/Server/Services/GlobalConfigService.ts +80 -1
- package/Server/Services/Index.ts +4 -0
- package/Server/Services/MonitorProbeService.ts +116 -20
- package/Server/Services/MonitorService.ts +59 -6
- package/Server/Services/MonitorStatusTimelineService.ts +284 -0
- package/Server/Services/MonitorTemplateService.ts +26 -0
- package/Server/Services/ProjectService.ts +284 -0
- package/Server/Services/RumSessionPinService.ts +25 -6
- package/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.ts +385 -0
- package/Server/Services/ServiceLevelObjectiveLabelRuleService.ts +51 -0
- package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +92 -16
- package/Server/Services/ServiceLevelObjectiveMonitorRuleService.ts +36 -1
- package/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.ts +521 -0
- package/Server/Services/ServiceLevelObjectiveOwnerRuleService.ts +51 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +28 -0
- package/Server/Services/StatusPagePrivateUserService.ts +7 -3
- package/Server/Services/StatusPageService.ts +78 -1
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TeamService.ts +10 -0
- package/Server/Services/UserService.ts +10 -17
- package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
- package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
- package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
- package/Server/Types/Markdown.ts +41 -0
- package/Server/Types/Workflow/Components/Telegram/SendMessageToChat.ts +27 -1
- package/Server/Utils/AI/Toolbox/SloTools.ts +1 -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/Monitor/AffectedResourceList.ts +148 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +1 -1
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/Criteria/MetricMonitorCriteria.ts +1 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +720 -465
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
- package/Server/Utils/Monitor/RootCauseList.ts +139 -0
- package/Server/Utils/Rules/RuleRun/RuleRunRegistry.ts +28 -0
- package/Server/Utils/Slo/SloRulePatternValidator.ts +42 -0
- 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/AuditLogsAndComplianceShells.test.tsx +572 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
- package/Tests/App/Dashboard/FeedFilterSortIntegration.test.tsx +1632 -0
- package/Tests/App/Dashboard/FeedOptionsLocales.test.ts +250 -0
- package/Tests/App/Dashboard/FeedOrdering.test.ts +279 -9
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +60 -1
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +594 -3
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- package/Tests/App/Dashboard/ProductOrientation.test.tsx +646 -0
- package/Tests/App/Dashboard/ResourceFeed.test.tsx +612 -2
- package/Tests/App/Dashboard/ResourceFeedPageWiring.test.ts +30 -0
- package/Tests/App/Dashboard/ResourceFeedPagesFilterSort.test.tsx +1202 -0
- package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +52 -1
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
- package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
- package/Tests/App/Dashboard/SloFeed.test.tsx +106 -1
- package/Tests/App/Dashboard/SloMonitorRuleCriteria.test.tsx +566 -0
- package/Tests/App/Dashboard/SloNavigationWiring.test.tsx +6 -4
- package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +186 -0
- package/Tests/App/Dashboard/SloOverviewKpiStrip.test.tsx +388 -44
- package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +613 -0
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
- 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/DatabaseModels/ResourceFeedModels.test.ts +0 -8
- package/Tests/Models/DatabaseModels/SloLabelAndOwnerRuleModels.test.ts +404 -0
- package/Tests/Models/DatabaseModels/SloOverhaulModels.test.ts +17 -1
- package/Tests/Models/DatabaseModels/StaticRuleCriteriaInheritance.test.ts +4 -2
- package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
- package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
- package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
- package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
- 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/Infrastructure/Postgres/AddConfigurableRuleCriteriaMigration.test.ts +3 -0
- package/Tests/Server/Infrastructure/Postgres/AddSloLabelAndOwnerRulesMigration.test.ts +407 -0
- package/Tests/Server/Infrastructure/Postgres/AddSloMonitorRuleMonitorTypeMigration.test.ts +171 -0
- package/Tests/Server/Infrastructure/Postgres/SloProductOverhaulMigration.test.ts +88 -4
- package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
- package/Tests/Server/Services/AuditLogService.test.ts +460 -990
- package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
- package/Tests/Server/Services/DatabaseServiceRuleCriteriaValidation.test.ts +104 -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/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
- package/Tests/Server/Services/RuleRun/LabelRuleEnginesGroupBRun.test.ts +48 -1
- package/Tests/Server/Services/RuleRun/OwnerRuleEnginesGroupBRun.test.ts +30 -0
- package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleEngines.test.ts +1170 -0
- package/Tests/Server/Services/ServiceLevelObjectiveLabelAndOwnerRuleServices.test.ts +172 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +323 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleService.test.ts +115 -0
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleTriggers.test.ts +21 -2
- package/Tests/Server/Services/ServiceLevelObjectiveMonitorTypePostgres.test.ts +480 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +162 -0
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
- package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +45 -6
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/FeedEventTypeFilterQuery.test.ts +745 -0
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Markdown.test.ts +183 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +49 -0
- package/Tests/Server/Types/Workflow/Components/TelegramSendMessageToChat.test.ts +331 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +10 -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/Monitor/AffectedResourceList.test.ts +518 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
- package/Tests/Server/Utils/Monitor/Criteria/MetricMonitorCriteriaAnomalyUnits.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +1339 -96
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorBreachingSamples.test.ts +1101 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorMetricUnits.test.ts +106 -80
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
- package/Tests/Server/Utils/Monitor/RootCauseList.test.ts +252 -0
- package/Tests/Server/Utils/Rules/RuleRun/RuleRunPermission.test.ts +154 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +111 -0
- package/Tests/Server/Utils/Slo/SloRulePatternValidator.test.ts +67 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +213 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
- package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
- package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
- package/Tests/Types/API/Route.test.ts +56 -0
- package/Tests/Types/API/URLSchemeLikePath.test.ts +304 -0
- package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -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 +84 -178
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
- package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
- package/Tests/UI/Components/FeedOptions.test.ts +1404 -0
- package/Tests/UI/Components/FeedOptionsButton.test.tsx +2603 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
- package/Tests/UI/Components/Icon.test.tsx +26 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
- package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
- package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +3 -3
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/Components/useFeedItemsViewKey.test.tsx +1017 -0
- package/Tests/UI/Components/useFeedOptions.test.tsx +1107 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
- package/Tests/Utils/HostAddressUtil.test.ts +138 -0
- package/Tests/Utils/LabelRuleImportExport.test.ts +102 -0
- package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
- package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
- package/Tests/Utils/Slo/SloDuration.test.ts +115 -24
- package/Tests/Utils/Slo/SloHealth.test.ts +93 -10
- package/Tests/Utils/Slo/SloMonitorRuleCriteria.test.ts +109 -0
- package/Tests/Utils/Slo/SloOverviewText.test.ts +64 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- package/Types/API/Route.ts +19 -2
- package/Types/API/URL.ts +26 -2
- 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/MetricMonitor/MetricCriteriaContext.ts +6 -5
- package/Types/Monitor/MetricMonitor/MetricMonitorResponse.ts +9 -0
- package/Types/Monitor/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- package/Types/Permission.ts +90 -0
- package/Types/Rules/RuleCriteriaFieldRegistry.ts +11 -0
- package/Types/Rules/RuleRun.ts +4 -0
- package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
- package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
- package/UI/Components/Feed/FeedOptions.ts +427 -0
- package/UI/Components/Feed/FeedOptionsButton.tsx +692 -0
- package/UI/Components/Feed/useFeedItems.ts +28 -9
- package/UI/Components/Feed/useFeedOptions.ts +225 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
- package/UI/Components/Icon/Icon.tsx +1 -1
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/ModelList/ModelList.tsx +11 -1
- package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
- package/UI/esbuild-enterprise.js +263 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
- package/Utils/HostAddressUtil.ts +94 -0
- package/Utils/LabelRuleImportExport.ts +27 -9
- package/Utils/Monitor/MetricValueFormatter.ts +2 -2
- package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- package/Utils/Rules/MonitorTypeRuleCriteria.ts +31 -0
- package/Utils/Slo/SloDuration.ts +22 -6
- package/Utils/Slo/SloHealth.ts +8 -7
- package/Utils/Slo/SloMonitorRuleCriteria.ts +33 -1
- package/Utils/Slo/SloOverviewText.ts +33 -0
- package/Utils/Slo/SloProjection.ts +4 -3
- 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/Index.js +4 -0
- package/build/dist/Models/DatabaseModels/Index.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/ServiceLevelObjectiveFeed.js +2 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js +530 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveLabelRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js +39 -4
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveMonitorRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js +612 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerRule.js.map +1 -0
- package/build/dist/Server/API/BaseAPI.js +26 -5
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
- package/build/dist/Server/API/GlobalConfigAPI.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/StatusPageAPI.js +93 -43
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +8 -1
- package/build/dist/Server/API/TeamMemberAPI.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/1794100000000-AddSloLabelAndOwnerRules.js +93 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794100000000-AddSloLabelAndOwnerRules.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1794200000000-AddSloMonitorRuleMonitorType.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
- package/build/dist/Server/Middleware/UserAuthorization.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 +7 -0
- package/build/dist/Server/Services/DatabaseService.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/Index.js +4 -0
- package/build/dist/Server/Services/Index.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 +48 -6
- 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/ProjectService.js +214 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +24 -6
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js +295 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js +56 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveLabelRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +59 -14
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js +22 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js +400 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleEngineService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js +56 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +21 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.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/TeamService.js +9 -0
- package/build/dist/Server/Services/TeamService.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/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/TablePermission.js +10 -3
- 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/Types/Workflow/Components/Telegram/SendMessageToChat.js +20 -1
- package/build/dist/Server/Types/Workflow/Components/Telegram/SendMessageToChat.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.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/Monitor/AffectedResourceList.js +67 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +1 -1
- 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/Criteria/MetricMonitorCriteria.js +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +585 -367
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.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/Monitor/RootCauseList.js +101 -0
- package/build/dist/Server/Utils/Monitor/RootCauseList.js.map +1 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js +28 -0
- package/build/dist/Server/Utils/Rules/RuleRun/RuleRunRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js +28 -0
- package/build/dist/Server/Utils/Slo/SloRulePatternValidator.js.map +1 -0
- 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/API/Route.js +18 -2
- package/build/dist/Types/API/Route.js.map +1 -1
- package/build/dist/Types/API/URL.js +23 -2
- package/build/dist/Types/API/URL.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/Permission.js +84 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js +11 -0
- package/build/dist/Types/Rules/RuleCriteriaFieldRegistry.js.map +1 -1
- package/build/dist/Types/Rules/RuleRun.js +4 -0
- package/build/dist/Types/Rules/RuleRun.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/EditionLabel/EditionLabel.js +414 -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/Feed/FeedOptions.js +235 -0
- package/build/dist/UI/Components/Feed/FeedOptions.js.map +1 -0
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js +346 -0
- package/build/dist/UI/Components/Feed/FeedOptionsButton.js.map +1 -0
- package/build/dist/UI/Components/Feed/useFeedItems.js +17 -7
- package/build/dist/UI/Components/Feed/useFeedItems.js.map +1 -1
- package/build/dist/UI/Components/Feed/useFeedOptions.js +130 -0
- package/build/dist/UI/Components/Feed/useFeedOptions.js.map +1 -0
- 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/Icon/Icon.js +1 -1
- package/build/dist/UI/Components/Icon/Icon.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/ModelList/ModelList.js +4 -1
- package/build/dist/UI/Components/ModelList/ModelList.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/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/LabelRuleImportExport.js +22 -6
- package/build/dist/Utils/LabelRuleImportExport.js.map +1 -1
- package/build/dist/Utils/Monitor/MetricValueFormatter.js +2 -2
- 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/Rules/MonitorTypeRuleCriteria.js +18 -0
- package/build/dist/Utils/Rules/MonitorTypeRuleCriteria.js.map +1 -0
- package/build/dist/Utils/Slo/SloDuration.js +13 -5
- package/build/dist/Utils/Slo/SloDuration.js.map +1 -1
- package/build/dist/Utils/Slo/SloHealth.js +8 -7
- package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
- package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js +16 -1
- package/build/dist/Utils/Slo/SloMonitorRuleCriteria.js.map +1 -1
- package/build/dist/Utils/Slo/SloOverviewText.js +16 -0
- package/build/dist/Utils/Slo/SloOverviewText.js.map +1 -1
- package/build/dist/Utils/Slo/SloProjection.js.map +1 -1
- 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/SecurityEventsExplorer.test.tsx +0 -761
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
- package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
- 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
package/Server/Types/Markdown.ts
CHANGED
|
@@ -207,6 +207,47 @@ export default class Markdown {
|
|
|
207
207
|
);
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
+
/*
|
|
211
|
+
* Lists. A platform monitor's root cause lists its affected resources
|
|
212
|
+
* as a numbered list with a bullet list of details nested under each
|
|
213
|
+
* item, and the cluster and metric details above it are bullets too.
|
|
214
|
+
*
|
|
215
|
+
* Left to the client, Gmail and Apple Mail indent every list level by
|
|
216
|
+
* 40px — close to a tenth of the card, twice over for a nested list —
|
|
217
|
+
* and Outlook's Word engine ignores padding on <ul>/<ol> and picks its
|
|
218
|
+
* own margins. So the indent is a margin-left, which Outlook honours,
|
|
219
|
+
* with padding zeroed: 24px holds a bullet, and 32px holds a numbered
|
|
220
|
+
* marker up to three digits ("100."). The vertical margins give each
|
|
221
|
+
* item's nested details a little air above and a gap below that
|
|
222
|
+
* separates it from the next item.
|
|
223
|
+
*
|
|
224
|
+
* margin-left is a physical side, so it is followed by the logical
|
|
225
|
+
* margin-inline-start / -end: a client that understands them moves
|
|
226
|
+
* the indent to the marker side in right-to-left text, and one that
|
|
227
|
+
* does not keeps the margin-left.
|
|
228
|
+
*/
|
|
229
|
+
renderer.list = function (
|
|
230
|
+
body: string,
|
|
231
|
+
ordered: boolean,
|
|
232
|
+
start: number | "",
|
|
233
|
+
): string {
|
|
234
|
+
const tag: string = ordered ? "ol" : "ul";
|
|
235
|
+
const startAttribute: string =
|
|
236
|
+
ordered && start !== "" && start !== 1 ? ` start="${start}"` : "";
|
|
237
|
+
const indent: string = ordered ? "32px" : "24px";
|
|
238
|
+
|
|
239
|
+
return (
|
|
240
|
+
`<${tag}${startAttribute} style="margin:6px 0 12px 0;` +
|
|
241
|
+
`margin-left:${indent};margin-inline-start:${indent};` +
|
|
242
|
+
`margin-inline-end:0;padding:0;">` +
|
|
243
|
+
`${body}</${tag}>`
|
|
244
|
+
);
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
renderer.listitem = function (text: string): string {
|
|
248
|
+
return `<li style="margin:0 0 4px;padding:0;">${text}</li>`;
|
|
249
|
+
};
|
|
250
|
+
|
|
210
251
|
/*
|
|
211
252
|
* The root cause backticks metric names, aliases and timestamps. Left
|
|
212
253
|
* bare they were indistinguishable from the prose around them.
|
|
@@ -13,7 +13,17 @@ import TelegramComponents from "../../../../../Types/Workflow/Components/Telegra
|
|
|
13
13
|
import API from "../../../../../Utils/API";
|
|
14
14
|
import CaptureSpan from "../../../../Utils/Telemetry/CaptureSpan";
|
|
15
15
|
|
|
16
|
+
/*
|
|
17
|
+
* https://core.telegram.org/bots/api#authorizing-your-bot — a numeric bot id,
|
|
18
|
+
* a ":", then the secret, e.g. "123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11".
|
|
19
|
+
*/
|
|
20
|
+
const TELEGRAM_BOT_TOKEN_REGEX: RegExp = /^\d+:[A-Za-z0-9_-]+$/;
|
|
21
|
+
|
|
16
22
|
export default class SendMessageToChat extends ComponentCode {
|
|
23
|
+
public static isValidBotToken(botToken: string): boolean {
|
|
24
|
+
return TELEGRAM_BOT_TOKEN_REGEX.test(botToken);
|
|
25
|
+
}
|
|
26
|
+
|
|
17
27
|
public constructor() {
|
|
18
28
|
super();
|
|
19
29
|
|
|
@@ -69,10 +79,26 @@ export default class SendMessageToChat extends ComponentCode {
|
|
|
69
79
|
throw options.onError(new BadDataException("Telegram message not found"));
|
|
70
80
|
}
|
|
71
81
|
|
|
72
|
-
|
|
82
|
+
// A token pasted or stored with a trailing newline is still the token.
|
|
83
|
+
const botToken: string = (args["bot-token"]?.toString() || "").trim();
|
|
73
84
|
const chatId: string = args["chat-id"]?.toString() as string;
|
|
74
85
|
const text: string = args["text"]?.toString() as string;
|
|
75
86
|
|
|
87
|
+
/*
|
|
88
|
+
* The token becomes a path segment of the request URL, so anything other
|
|
89
|
+
* than Telegram's "<bot id>:<secret>" shape is refused before it gets
|
|
90
|
+
* there. The message deliberately does not quote the value: the step's
|
|
91
|
+
* error is written to the run log, and the token is a credential. Before
|
|
92
|
+
* this check, a URL parse failure put the whole token into the log.
|
|
93
|
+
*/
|
|
94
|
+
if (!SendMessageToChat.isValidBotToken(botToken)) {
|
|
95
|
+
throw options.onError(
|
|
96
|
+
new BadDataException(
|
|
97
|
+
"Telegram Bot Token is not in a valid format. It should look like 123456789:ABCdefGhIJKlmnoPQRstuVWxyz, exactly as BotFather issued it.",
|
|
98
|
+
),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
76
102
|
const telegramApiUrl: URL = URL.fromString(
|
|
77
103
|
`https://api.telegram.org/bot${botToken}/sendMessage`,
|
|
78
104
|
);
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import EnterpriseEdition, {
|
|
2
|
+
EnterpriseFeatureStateChange,
|
|
3
|
+
} from "../Enterprise/EnterpriseEdition";
|
|
4
|
+
import EnterpriseFeature from "../Enterprise/EnterpriseFeature";
|
|
5
|
+
import {
|
|
6
|
+
ENTERPRISE_LICENSE_GRACE_PERIOD_IN_DAYS,
|
|
7
|
+
ENTERPRISE_LICENSE_TRIAL_PERIOD_IN_DAYS,
|
|
8
|
+
} from "../Enterprise/EnterpriseLicenseSnapshot";
|
|
9
|
+
import GlobalConfigService from "../Services/GlobalConfigService";
|
|
10
|
+
import ProjectSCIMService from "../Services/ProjectSCIMService";
|
|
11
|
+
import ProjectService from "../Services/ProjectService";
|
|
12
|
+
import StatusPageService from "../Services/StatusPageService";
|
|
13
|
+
import logger from "./Logger";
|
|
14
|
+
import PositiveNumber from "../../Types/PositiveNumber";
|
|
15
|
+
import Project from "../../Models/DatabaseModels/Project";
|
|
16
|
+
import ProjectSCIM from "../../Models/DatabaseModels/ProjectSCIM";
|
|
17
|
+
import StatusPage from "../../Models/DatabaseModels/StatusPage";
|
|
18
|
+
|
|
19
|
+
// How many ids of each kind the log line names; the counts are always exact.
|
|
20
|
+
export const MAX_IDS_LISTED_PER_KIND: number = 20;
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* The SSO requirements and SCIM team locks that are configured but not
|
|
24
|
+
* enforced (see EditionEnforcement): left over from an Enterprise Edition
|
|
25
|
+
* install on a Community Edition process, or configured on an Enterprise
|
|
26
|
+
* install whose license has lapsed.
|
|
27
|
+
*/
|
|
28
|
+
export interface RelaxedEnforcementSummary {
|
|
29
|
+
instanceRequiresSso: boolean;
|
|
30
|
+
projectsRequiringSso: number;
|
|
31
|
+
projectIdsRequiringSso: Array<string>;
|
|
32
|
+
statusPagesRequiringSso: number;
|
|
33
|
+
statusPageIdsRequiringSso: Array<string>;
|
|
34
|
+
scimConfigurationsWithPushGroups: number;
|
|
35
|
+
projectIdsWithScimPushGroups: Array<string>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/*
|
|
39
|
+
* Why the settings in a report are not enforced:
|
|
40
|
+
*
|
|
41
|
+
* community a Community Edition process, which has no SSO login and
|
|
42
|
+
* no SCIM endpoint at all;
|
|
43
|
+
* lapsed-license an Enterprise install whose license no longer covers SSO
|
|
44
|
+
* and/or SCIM (EnterpriseEdition.isFeatureActive). Only the
|
|
45
|
+
* relaxed half is reported.
|
|
46
|
+
*/
|
|
47
|
+
export type RelaxedEnforcementContext =
|
|
48
|
+
| { reason: "community" }
|
|
49
|
+
| { reason: "lapsed-license"; isSsoRelaxed: boolean; isScimRelaxed: boolean };
|
|
50
|
+
|
|
51
|
+
const COMMUNITY_CONTEXT: RelaxedEnforcementContext = { reason: "community" };
|
|
52
|
+
|
|
53
|
+
/*
|
|
54
|
+
* Tells the operator which configured security settings this server is not
|
|
55
|
+
* enforcing, so that never happens silently:
|
|
56
|
+
*
|
|
57
|
+
* - Community Edition: moving from the Enterprise image to the Community
|
|
58
|
+
* one keeps the database as it is, so a project that required SSO still
|
|
59
|
+
* says so - but the SSO login routes are part of the Enterprise Edition,
|
|
60
|
+
* so the requirement is relaxed rather than locking everyone out. Logged
|
|
61
|
+
* once per process at boot.
|
|
62
|
+
* - Enterprise Edition: when the license lapses, SSO and SCIM stop and the
|
|
63
|
+
* same settings are relaxed until a license is activated. Logged each time
|
|
64
|
+
* SSO or SCIM stops (EnterpriseEdition reports each change once),
|
|
65
|
+
* including a license that has already lapsed at boot.
|
|
66
|
+
*/
|
|
67
|
+
export default class CommunityEditionSsoReport {
|
|
68
|
+
private static hasRun: boolean = false;
|
|
69
|
+
|
|
70
|
+
private static stopWatchingLicense: (() => void) | null = null;
|
|
71
|
+
|
|
72
|
+
/*
|
|
73
|
+
* Called once at boot, after the enterprise loader. On the Community
|
|
74
|
+
* Edition it logs the relaxed settings once per process. On the Enterprise
|
|
75
|
+
* Edition it starts watching the license (once per process) and reports
|
|
76
|
+
* whenever SSO or SCIM stops. Never throws: a failed check is logged and
|
|
77
|
+
* boot carries on. Returns what the Community Edition report found (null
|
|
78
|
+
* when it did not run or the check failed).
|
|
79
|
+
*/
|
|
80
|
+
public static async logRelaxedEnforcementOnce(): Promise<RelaxedEnforcementSummary | null> {
|
|
81
|
+
if (EnterpriseEdition.isLoaded()) {
|
|
82
|
+
CommunityEditionSsoReport.watchLicenseOnce();
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (CommunityEditionSsoReport.hasRun) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
CommunityEditionSsoReport.hasRun = true;
|
|
91
|
+
|
|
92
|
+
return await CommunityEditionSsoReport.report(COMMUNITY_CONTEXT);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/*
|
|
96
|
+
* Collects and logs the relaxed settings. Never throws. Returns what it
|
|
97
|
+
* found (null when the check failed).
|
|
98
|
+
*/
|
|
99
|
+
public static async report(
|
|
100
|
+
context: RelaxedEnforcementContext,
|
|
101
|
+
): Promise<RelaxedEnforcementSummary | null> {
|
|
102
|
+
try {
|
|
103
|
+
const summary: RelaxedEnforcementSummary =
|
|
104
|
+
await CommunityEditionSsoReport.collect();
|
|
105
|
+
|
|
106
|
+
const message: string | null = CommunityEditionSsoReport.describe(
|
|
107
|
+
summary,
|
|
108
|
+
context,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (message) {
|
|
112
|
+
logger.warn(message);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return summary;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
logger.error(
|
|
118
|
+
context.reason === "community"
|
|
119
|
+
? "Community Edition: could not check for SSO requirements and SCIM team locks left over from an Enterprise Edition install."
|
|
120
|
+
: "OneUptime Enterprise license lapsed: could not check which SSO requirements and SCIM team locks are no longer enforced.",
|
|
121
|
+
);
|
|
122
|
+
logger.error(err);
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/*
|
|
128
|
+
* Watches the Enterprise license for SSO or SCIM stopping, once per
|
|
129
|
+
* process. The first look happens here, so a license that has already
|
|
130
|
+
* lapsed at boot is reported like a lapse at runtime.
|
|
131
|
+
*/
|
|
132
|
+
private static watchLicenseOnce(): void {
|
|
133
|
+
if (CommunityEditionSsoReport.stopWatchingLicense) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
CommunityEditionSsoReport.stopWatchingLicense =
|
|
138
|
+
EnterpriseEdition.onFeatureStateChange(
|
|
139
|
+
(change: EnterpriseFeatureStateChange): void => {
|
|
140
|
+
CommunityEditionSsoReport.onFeatureStateChange(change);
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
try {
|
|
145
|
+
EnterpriseEdition.isFeatureActive(EnterpriseFeature.SSO);
|
|
146
|
+
EnterpriseEdition.isFeatureActive(EnterpriseFeature.SCIM);
|
|
147
|
+
} catch (err) {
|
|
148
|
+
logger.error(err);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private static onFeatureStateChange(
|
|
153
|
+
change: EnterpriseFeatureStateChange,
|
|
154
|
+
): void {
|
|
155
|
+
const isSsoRelaxed: boolean = change.stopped.includes(
|
|
156
|
+
EnterpriseFeature.SSO,
|
|
157
|
+
);
|
|
158
|
+
const isScimRelaxed: boolean = change.stopped.includes(
|
|
159
|
+
EnterpriseFeature.SCIM,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
if (!isSsoRelaxed && !isScimRelaxed) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
void CommunityEditionSsoReport.report({
|
|
167
|
+
reason: "lapsed-license",
|
|
168
|
+
isSsoRelaxed,
|
|
169
|
+
isScimRelaxed,
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Reads the stored (not the masked) settings. Root reads are never masked.
|
|
174
|
+
public static async collect(): Promise<RelaxedEnforcementSummary> {
|
|
175
|
+
const [
|
|
176
|
+
instanceRequiresSso,
|
|
177
|
+
projectCount,
|
|
178
|
+
projects,
|
|
179
|
+
statusPageCount,
|
|
180
|
+
statusPages,
|
|
181
|
+
scimCount,
|
|
182
|
+
scimConfigurations,
|
|
183
|
+
]: [
|
|
184
|
+
boolean,
|
|
185
|
+
PositiveNumber,
|
|
186
|
+
Array<Project>,
|
|
187
|
+
PositiveNumber,
|
|
188
|
+
Array<StatusPage>,
|
|
189
|
+
PositiveNumber,
|
|
190
|
+
Array<ProjectSCIM>,
|
|
191
|
+
] = await Promise.all([
|
|
192
|
+
GlobalConfigService.getRequireSsoForLogin(),
|
|
193
|
+
ProjectService.countBy({
|
|
194
|
+
query: { requireSsoForLogin: true },
|
|
195
|
+
props: { isRoot: true },
|
|
196
|
+
}),
|
|
197
|
+
ProjectService.findBy({
|
|
198
|
+
query: { requireSsoForLogin: true },
|
|
199
|
+
select: { _id: true },
|
|
200
|
+
limit: MAX_IDS_LISTED_PER_KIND,
|
|
201
|
+
skip: 0,
|
|
202
|
+
props: { isRoot: true },
|
|
203
|
+
}),
|
|
204
|
+
StatusPageService.countBy({
|
|
205
|
+
query: { requireSsoForLogin: true },
|
|
206
|
+
props: { isRoot: true },
|
|
207
|
+
}),
|
|
208
|
+
StatusPageService.findBy({
|
|
209
|
+
query: { requireSsoForLogin: true },
|
|
210
|
+
select: { _id: true },
|
|
211
|
+
limit: MAX_IDS_LISTED_PER_KIND,
|
|
212
|
+
skip: 0,
|
|
213
|
+
props: { isRoot: true },
|
|
214
|
+
}),
|
|
215
|
+
ProjectSCIMService.countBy({
|
|
216
|
+
query: { enablePushGroups: true },
|
|
217
|
+
props: { isRoot: true },
|
|
218
|
+
}),
|
|
219
|
+
ProjectSCIMService.findBy({
|
|
220
|
+
query: { enablePushGroups: true },
|
|
221
|
+
select: { projectId: true },
|
|
222
|
+
limit: MAX_IDS_LISTED_PER_KIND,
|
|
223
|
+
skip: 0,
|
|
224
|
+
props: { isRoot: true },
|
|
225
|
+
}),
|
|
226
|
+
]);
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
instanceRequiresSso: Boolean(instanceRequiresSso),
|
|
230
|
+
projectsRequiringSso: projectCount.toNumber(),
|
|
231
|
+
projectIdsRequiringSso: CommunityEditionSsoReport.toIds(
|
|
232
|
+
projects.map((project: Project) => {
|
|
233
|
+
return project.id?.toString() || project._id?.toString();
|
|
234
|
+
}),
|
|
235
|
+
),
|
|
236
|
+
statusPagesRequiringSso: statusPageCount.toNumber(),
|
|
237
|
+
statusPageIdsRequiringSso: CommunityEditionSsoReport.toIds(
|
|
238
|
+
statusPages.map((statusPage: StatusPage) => {
|
|
239
|
+
return statusPage.id?.toString() || statusPage._id?.toString();
|
|
240
|
+
}),
|
|
241
|
+
),
|
|
242
|
+
scimConfigurationsWithPushGroups: scimCount.toNumber(),
|
|
243
|
+
projectIdsWithScimPushGroups: CommunityEditionSsoReport.toIds(
|
|
244
|
+
scimConfigurations.map((scim: ProjectSCIM) => {
|
|
245
|
+
return scim.projectId?.toString();
|
|
246
|
+
}),
|
|
247
|
+
),
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// The log line, or null when nothing is relaxed.
|
|
252
|
+
public static describe(
|
|
253
|
+
summary: RelaxedEnforcementSummary,
|
|
254
|
+
context: RelaxedEnforcementContext = COMMUNITY_CONTEXT,
|
|
255
|
+
): string | null {
|
|
256
|
+
const isSsoRelaxed: boolean =
|
|
257
|
+
context.reason === "community" || context.isSsoRelaxed;
|
|
258
|
+
const isScimRelaxed: boolean =
|
|
259
|
+
context.reason === "community" || context.isScimRelaxed;
|
|
260
|
+
|
|
261
|
+
const relaxed: Array<string> = [];
|
|
262
|
+
|
|
263
|
+
if (isSsoRelaxed && summary.instanceRequiresSso) {
|
|
264
|
+
relaxed.push(
|
|
265
|
+
'the instance-wide "Require SSO for Login" setting (Admin Dashboard > Settings > Authentication)',
|
|
266
|
+
);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
if (isSsoRelaxed && summary.projectsRequiringSso > 0) {
|
|
270
|
+
relaxed.push(
|
|
271
|
+
`${summary.projectsRequiringSso} project(s) that require SSO for login${CommunityEditionSsoReport.describeIds(
|
|
272
|
+
summary.projectIdsRequiringSso,
|
|
273
|
+
summary.projectsRequiringSso,
|
|
274
|
+
)}`,
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
if (isSsoRelaxed && summary.statusPagesRequiringSso > 0) {
|
|
279
|
+
relaxed.push(
|
|
280
|
+
`${summary.statusPagesRequiringSso} private status page(s) that require SSO for login${CommunityEditionSsoReport.describeIds(
|
|
281
|
+
summary.statusPageIdsRequiringSso,
|
|
282
|
+
summary.statusPagesRequiringSso,
|
|
283
|
+
)}`,
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (isScimRelaxed && summary.scimConfigurationsWithPushGroups > 0) {
|
|
288
|
+
relaxed.push(
|
|
289
|
+
`${summary.scimConfigurationsWithPushGroups} SCIM configuration(s) with Push Groups on, whose teams can be edited in OneUptime again${CommunityEditionSsoReport.describeIds(
|
|
290
|
+
summary.projectIdsWithScimPushGroups,
|
|
291
|
+
summary.scimConfigurationsWithPushGroups,
|
|
292
|
+
"project ids",
|
|
293
|
+
)}`,
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
if (relaxed.length === 0) {
|
|
298
|
+
return null;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (context.reason === "lapsed-license") {
|
|
302
|
+
const stopped: string =
|
|
303
|
+
isSsoRelaxed && isScimRelaxed
|
|
304
|
+
? "SSO login and SCIM provisioning have"
|
|
305
|
+
: isSsoRelaxed
|
|
306
|
+
? "SSO login has"
|
|
307
|
+
: "SCIM provisioning has";
|
|
308
|
+
|
|
309
|
+
return (
|
|
310
|
+
"OneUptime Enterprise license lapsed: this server has security settings that it no longer enforces, " +
|
|
311
|
+
`because ${stopped} stopped until a license that includes ${isSsoRelaxed && isScimRelaxed ? "them" : "it"} is activated. ` +
|
|
312
|
+
(isSsoRelaxed
|
|
313
|
+
? "Users of these projects and status pages sign in with email and password instead (users who only ever signed in with SSO can reset their password). "
|
|
314
|
+
: "") +
|
|
315
|
+
`Not enforced: ${relaxed.join("; ")}. ` +
|
|
316
|
+
"The settings are kept unchanged and are enforced again as soon as a license is activated, without a restart."
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return (
|
|
321
|
+
"Community Edition: this server has security settings from an Enterprise Edition install that it does not enforce, " +
|
|
322
|
+
"because SSO login and SCIM provisioning are part of the OneUptime Enterprise Edition. " +
|
|
323
|
+
"Users of these projects and status pages sign in with email and password instead. " +
|
|
324
|
+
`Not enforced: ${relaxed.join("; ")}. ` +
|
|
325
|
+
`The settings are kept unchanged and are enforced again when this server runs the Enterprise Edition image with a valid license (or during its ${ENTERPRISE_LICENSE_TRIAL_PERIOD_IN_DAYS}-day trial, or the ${ENTERPRISE_LICENSE_GRACE_PERIOD_IN_DAYS}-day grace period after a license expires).`
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// Test suites only: allow the next call to run again and stop watching.
|
|
330
|
+
public static resetForTests(): void {
|
|
331
|
+
CommunityEditionSsoReport.hasRun = false;
|
|
332
|
+
|
|
333
|
+
if (CommunityEditionSsoReport.stopWatchingLicense) {
|
|
334
|
+
CommunityEditionSsoReport.stopWatchingLicense();
|
|
335
|
+
CommunityEditionSsoReport.stopWatchingLicense = null;
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
private static toIds(values: Array<string | undefined>): Array<string> {
|
|
340
|
+
return values
|
|
341
|
+
.filter((value: string | undefined): value is string => {
|
|
342
|
+
return Boolean(value);
|
|
343
|
+
})
|
|
344
|
+
.slice(0, MAX_IDS_LISTED_PER_KIND);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
private static describeIds(
|
|
348
|
+
ids: Array<string>,
|
|
349
|
+
total: number,
|
|
350
|
+
label: string = "ids",
|
|
351
|
+
): string {
|
|
352
|
+
if (ids.length === 0) {
|
|
353
|
+
return "";
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
const more: string =
|
|
357
|
+
total > ids.length ? ` and ${total - ids.length} more` : "";
|
|
358
|
+
|
|
359
|
+
return ` (${label}: ${ids.join(", ")}${more})`;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import EnterpriseEdition from "../Enterprise/EnterpriseEdition";
|
|
2
|
+
import EnterpriseFeature from "../Enterprise/EnterpriseFeature";
|
|
3
|
+
import {
|
|
4
|
+
ENTERPRISE_LICENSE_GRACE_PERIOD_IN_DAYS,
|
|
5
|
+
ENTERPRISE_LICENSE_TRIAL_PERIOD_IN_DAYS,
|
|
6
|
+
} from "../Enterprise/EnterpriseLicenseSnapshot";
|
|
7
|
+
import logger from "./Logger";
|
|
8
|
+
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
9
|
+
import PaymentRequiredException from "../../Types/Exception/PaymentRequiredException";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* Which enterprise identity controls are live in this process.
|
|
13
|
+
*
|
|
14
|
+
* Every answer here follows the RUNTIME state of the feature behind it
|
|
15
|
+
* (EnterpriseEdition.isFeatureActive): SSO for the SSO requirements, the
|
|
16
|
+
* SAML/OIDC sign-in routes and the provider listings, SCIM for the SCIM Push
|
|
17
|
+
* Groups team locks. A feature is active when the Enterprise Edition is loaded
|
|
18
|
+
* and, with billing off, its license covers the feature (valid, in the grace
|
|
19
|
+
* period after it expired, or - with no license - inside the trial).
|
|
20
|
+
*
|
|
21
|
+
* The controls are relaxed where they cannot work:
|
|
22
|
+
* - on the Community Edition, which has no SAML/OIDC sign-in routes and no
|
|
23
|
+
* SCIM endpoints;
|
|
24
|
+
* - on an Enterprise install whose license has lapsed, where those routes
|
|
25
|
+
* refuse (ee/Server/Identity).
|
|
26
|
+
* Enforcing a leftover "Require SSO for login" there would lock every user
|
|
27
|
+
* out, and a leftover SCIM Push Groups lock would leave teams nobody can
|
|
28
|
+
* manage. Users sign in with their password instead (users who only ever used
|
|
29
|
+
* SSO reset it). The configuration itself is kept untouched - reads made for
|
|
30
|
+
* a caller report the requirement as off, and a caller's write can neither
|
|
31
|
+
* switch it off nor set it meanwhile (guardSsoRequirementWrite) - so running
|
|
32
|
+
* the Enterprise Edition again (with a valid license, or during its trial or
|
|
33
|
+
* grace period), or renewing the license, restores enforcement without a
|
|
34
|
+
* restart.
|
|
35
|
+
*
|
|
36
|
+
* Failure direction: an error while deciding answers "enforce", and an
|
|
37
|
+
* unknown license state counts as active (see isFeatureActive), so a read
|
|
38
|
+
* error never switches a control off.
|
|
39
|
+
*/
|
|
40
|
+
export default class EditionEnforcement {
|
|
41
|
+
// Why guardSsoRequirementWrite refuses a write, on the Community Edition.
|
|
42
|
+
public static readonly SSO_REQUIREMENT_UNCHANGEABLE_COMMUNITY_MESSAGE: string =
|
|
43
|
+
'Single sign-on is part of the OneUptime Enterprise Edition and this server runs the Community Edition, so "Require SSO for login" shows as off, is not enforced and cannot be changed here. ' +
|
|
44
|
+
`A setting saved earlier is kept, and it is enforced again when this server runs the Enterprise Edition image with a valid license (or during its ${ENTERPRISE_LICENSE_TRIAL_PERIOD_IN_DAYS}-day trial, or the ${ENTERPRISE_LICENSE_GRACE_PERIOD_IN_DAYS}-day grace period after a license expires).`;
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* Why guardSsoRequirementWrite refuses a write, on an Enterprise install
|
|
48
|
+
* whose license does not cover SSO right now.
|
|
49
|
+
*/
|
|
50
|
+
public static readonly SSO_REQUIREMENT_UNCHANGEABLE_LICENSE_MESSAGE: string =
|
|
51
|
+
'Single sign-on has stopped because the OneUptime Enterprise license is missing, expired or does not include SSO, so "Require SSO for login" shows as off, is not enforced and cannot be changed. ' +
|
|
52
|
+
"The saved setting is kept, and it is enforced again as soon as a master admin activates or renews the license from the edition label in the Admin Dashboard header.";
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
* Whether configured SSO requirements - a project's requireSsoForLogin (and
|
|
56
|
+
* its required provider), the instance-wide requireSsoForLogin and a status
|
|
57
|
+
* page's requireSsoForLogin - are enforced.
|
|
58
|
+
*/
|
|
59
|
+
public static isSsoEnforced(): boolean {
|
|
60
|
+
try {
|
|
61
|
+
return EnterpriseEdition.isFeatureActive(EnterpriseFeature.SSO);
|
|
62
|
+
} catch (err) {
|
|
63
|
+
logger.error(
|
|
64
|
+
"EditionEnforcement: could not tell whether SSO is enforced; enforcing it.",
|
|
65
|
+
);
|
|
66
|
+
logger.error(err);
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// A configured SSO requirement that is also enforced in this process.
|
|
72
|
+
public static isSsoRequired(
|
|
73
|
+
configuredRequirement: boolean | null | undefined,
|
|
74
|
+
): boolean {
|
|
75
|
+
if (!configuredRequirement) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return EditionEnforcement.isSsoEnforced();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* Whether SCIM Push Groups owns team membership: while a project's SCIM
|
|
84
|
+
* configuration has Push Groups on, teams and team members can only be
|
|
85
|
+
* changed by the identity provider. Relaxed on the Community Edition, and
|
|
86
|
+
* while the license does not cover SCIM, because then no SCIM endpoint
|
|
87
|
+
* answers the identity provider and nobody else could manage those teams.
|
|
88
|
+
*/
|
|
89
|
+
public static areScimTeamLocksEnforced(): boolean {
|
|
90
|
+
try {
|
|
91
|
+
return EnterpriseEdition.isFeatureActive(EnterpriseFeature.SCIM);
|
|
92
|
+
} catch (err) {
|
|
93
|
+
logger.error(
|
|
94
|
+
"EditionEnforcement: could not tell whether SCIM team locks apply; applying them.",
|
|
95
|
+
);
|
|
96
|
+
logger.error(err);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* Whether the SAML/OIDC sign-in routes answer right now. Provider listings
|
|
103
|
+
* (the lists a sign-in page offers) are empty when they do not, so no client
|
|
104
|
+
* sends a user into a route that answers 404 (Community Edition) or refuses
|
|
105
|
+
* because the license lapsed (Enterprise Edition).
|
|
106
|
+
*/
|
|
107
|
+
public static areSsoRoutesServed(): boolean {
|
|
108
|
+
try {
|
|
109
|
+
return EnterpriseEdition.isFeatureActive(EnterpriseFeature.SSO);
|
|
110
|
+
} catch (err) {
|
|
111
|
+
logger.error(
|
|
112
|
+
"EditionEnforcement: could not tell whether the SSO routes are served; serving them.",
|
|
113
|
+
);
|
|
114
|
+
logger.error(err);
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*
|
|
120
|
+
* Whether a read should report the EFFECTIVE SSO requirement (false)
|
|
121
|
+
* instead of the stored one. Clients - the mobile app in particular, whose
|
|
122
|
+
* store builds cannot be patched - decide from these columns whether to
|
|
123
|
+
* start an SSO flow, and while SSO is not active that flow does not exist
|
|
124
|
+
* (Community Edition) or refuses (lapsed license).
|
|
125
|
+
*
|
|
126
|
+
* Only reads made for a caller are masked. Internal (root) reads see the
|
|
127
|
+
* stored value, and a read never writes, so the configuration is intact
|
|
128
|
+
* when SSO is active again. The write half is guardSsoRequirementWrite.
|
|
129
|
+
*/
|
|
130
|
+
public static shouldMaskSsoRequirementOnRead(
|
|
131
|
+
props: DatabaseCommonInteractionProps | null | undefined,
|
|
132
|
+
): boolean {
|
|
133
|
+
if (!props || props.isRoot) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return !EditionEnforcement.isSsoEnforced();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/*
|
|
141
|
+
* The write half of shouldMaskSsoRequirementOnRead, for the services'
|
|
142
|
+
* onBeforeUpdate. A caller whose reads are masked has only ever seen the
|
|
143
|
+
* requirement as off (no required provider), so what it writes to those
|
|
144
|
+
* columns cannot be taken at face value: a settings form, or an API client
|
|
145
|
+
* doing a read-modify-write, sends back the masked value it read. Saving it
|
|
146
|
+
* would switch a configured requirement off without anybody deciding to,
|
|
147
|
+
* and it would stay off once SSO is active again.
|
|
148
|
+
*
|
|
149
|
+
* So while this caller's reads are masked:
|
|
150
|
+
* - a write of the masked value (false, or no provider) is dropped from
|
|
151
|
+
* `data`, and the stored requirement is kept;
|
|
152
|
+
* - a write that would set a requirement (true, or a provider) is
|
|
153
|
+
* refused: it could neither be seen nor enforced until SSO is active;
|
|
154
|
+
* - a write that is left with nothing else to save is refused with the
|
|
155
|
+
* same explanation, rather than reporting a save that did not happen.
|
|
156
|
+
*
|
|
157
|
+
* Root writes, and every write while SSO is active, are left alone.
|
|
158
|
+
* Mutates `data`. Throws PaymentRequiredException.
|
|
159
|
+
*/
|
|
160
|
+
public static guardSsoRequirementWrite(input: {
|
|
161
|
+
props: DatabaseCommonInteractionProps | null | undefined;
|
|
162
|
+
data: Record<string, unknown>;
|
|
163
|
+
// The requirement columns of the model being written.
|
|
164
|
+
columns: ReadonlyArray<string>;
|
|
165
|
+
}): void {
|
|
166
|
+
if (!EditionEnforcement.shouldMaskSsoRequirementOnRead(input.props)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const writtenColumns: Array<string> = input.columns.filter(
|
|
171
|
+
(column: string): boolean => {
|
|
172
|
+
return input.data[column] !== undefined;
|
|
173
|
+
},
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
if (writtenColumns.length === 0) {
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const setsRequirement: boolean = writtenColumns.some(
|
|
181
|
+
(column: string): boolean => {
|
|
182
|
+
return !EditionEnforcement.isMaskedSsoRequirementValue(
|
|
183
|
+
input.data[column],
|
|
184
|
+
);
|
|
185
|
+
},
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
if (setsRequirement) {
|
|
189
|
+
throw EditionEnforcement.createSsoRequirementUnchangeableException();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
for (const column of writtenColumns) {
|
|
193
|
+
delete input.data[column];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/*
|
|
197
|
+
* `data` is the plain update onBeforeUpdate receives (a model instance
|
|
198
|
+
* has already been reduced to its set columns by
|
|
199
|
+
* DatabaseService.sanitizeUpdateData); a key left undefined writes
|
|
200
|
+
* nothing, so it does not count.
|
|
201
|
+
*/
|
|
202
|
+
const hasOtherColumns: boolean = Object.keys(input.data).some(
|
|
203
|
+
(key: string): boolean => {
|
|
204
|
+
return input.data[key] !== undefined;
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
if (!hasOtherColumns) {
|
|
209
|
+
throw EditionEnforcement.createSsoRequirementUnchangeableException();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// What a masked read reports for a requirement column: false or null.
|
|
214
|
+
private static isMaskedSsoRequirementValue(value: unknown): boolean {
|
|
215
|
+
return value === false || value === null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private static createSsoRequirementUnchangeableException(): PaymentRequiredException {
|
|
219
|
+
let isEnterpriseEditionLoaded: boolean = true;
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
isEnterpriseEditionLoaded = EnterpriseEdition.isLoaded();
|
|
223
|
+
} catch (err) {
|
|
224
|
+
logger.error(err);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return new PaymentRequiredException(
|
|
228
|
+
isEnterpriseEditionLoaded
|
|
229
|
+
? EditionEnforcement.SSO_REQUIREMENT_UNCHANGEABLE_LICENSE_MESSAGE
|
|
230
|
+
: EditionEnforcement.SSO_REQUIREMENT_UNCHANGEABLE_COMMUNITY_MESSAGE,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
}
|