@oneuptime/common 13.0.8 → 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/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/Index.ts +2 -0
- package/Server/Middleware/UserAuthorization.ts +38 -16
- package/Server/Services/AuditLogService.ts +84 -1079
- 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/ProjectService.ts +284 -0
- package/Server/Services/RumSessionPinService.ts +25 -6
- 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/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 +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -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/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- 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/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/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/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/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/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/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Markdown.test.ts +181 -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/MonitorCriteriaEvaluator.test.ts +934 -96
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -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/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/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/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -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/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- 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/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- 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/Graphs/DayUptimeGraph.tsx +123 -15
- 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/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- 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/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/Index.js +2 -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/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/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/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/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 +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/MonitorCriteriaEvaluator.js +449 -261
- 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/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/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/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/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/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/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/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
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
2
|
-
import ObjectID from "../../../Types/ObjectID";
|
|
3
|
-
import EnterpriseLicenseSeatsUtil from "../../../Utils/EnterpriseLicense/EnterpriseLicenseSeats";
|
|
4
|
-
import { IsBillingEnabled, IsEnterpriseEdition } from "../../EnvironmentConfig";
|
|
5
|
-
import GlobalConfigService from "../../Services/GlobalConfigService";
|
|
6
|
-
/*
|
|
7
|
-
* Enforcement of the enterprise license seat limit on a self-hosted
|
|
8
|
-
* installation.
|
|
9
|
-
*
|
|
10
|
-
* The limit itself is set on oneuptime.com and mirrored into GlobalConfig by
|
|
11
|
-
* the daily report job (and by validating or refreshing the license by hand).
|
|
12
|
-
* This is the half that acts on it: it is the only thing standing between a
|
|
13
|
-
* customer's license terms and an unbounded User table.
|
|
14
|
-
*
|
|
15
|
-
* The seat arithmetic lives in Common/Utils/EnterpriseLicense/EnterpriseLicenseSeats
|
|
16
|
-
* as a pure function; everything here is about reading the license state and
|
|
17
|
-
* deciding whether the installation is one that enforces at all.
|
|
18
|
-
*/
|
|
19
|
-
export default class EnterpriseLicenseSeatUtil {
|
|
20
|
-
/*
|
|
21
|
-
* Whether this process is an installation whose users are governed by an
|
|
22
|
-
* enterprise license at all.
|
|
23
|
-
*
|
|
24
|
-
* Community Edition has no license and no limit. oneuptime.com runs with
|
|
25
|
-
* billing enabled and bounds seats through subscriptions instead
|
|
26
|
-
* (TeamMemberService.onBeforeCreate) — enforcing a license limit there as
|
|
27
|
-
* well would be a second, wrong answer to the same question.
|
|
28
|
-
*/
|
|
29
|
-
static isSeatLimitEnforceable() {
|
|
30
|
-
return IsEnterpriseEdition && !IsBillingEnabled;
|
|
31
|
-
}
|
|
32
|
-
/*
|
|
33
|
-
* Seat usage derived from an already-loaded GlobalConfig row. Kept separate
|
|
34
|
-
* from the loading so a caller that has the row in hand — the license
|
|
35
|
-
* endpoint, which has just read it — does not read it a second time.
|
|
36
|
-
*
|
|
37
|
-
* A null config (a fresh installation whose GlobalConfig has not been seeded
|
|
38
|
-
* yet) yields no limit, which is the same answer as a licence with no seat
|
|
39
|
-
* limit set.
|
|
40
|
-
*/
|
|
41
|
-
static getSeatUsageFromGlobalConfig(data) {
|
|
42
|
-
const config = data.config;
|
|
43
|
-
const instances = Array.isArray(config === null || config === void 0 ? void 0 : config.enterpriseLicenseInstances)
|
|
44
|
-
? config.enterpriseLicenseInstances
|
|
45
|
-
: [];
|
|
46
|
-
return EnterpriseLicenseSeatsUtil.getSeatUsage({
|
|
47
|
-
userLimit: config === null || config === void 0 ? void 0 : config.enterpriseLicenseUserLimit,
|
|
48
|
-
localUserCount: data.localUserCount,
|
|
49
|
-
aggregatedUserCount: config === null || config === void 0 ? void 0 : config.enterpriseLicenseCurrentUserCount,
|
|
50
|
-
instances: instances,
|
|
51
|
-
thisInstanceId: (config === null || config === void 0 ? void 0 : config.instanceId) ? config.instanceId.toString() : null,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
/*
|
|
55
|
-
* Seat usage for this installation right now, or null on an installation
|
|
56
|
-
* that does not enforce a seat limit.
|
|
57
|
-
*
|
|
58
|
-
* Null rather than an unenforced SeatUsage so callers cannot accidentally
|
|
59
|
-
* present Community Edition with a seat report it has no business having,
|
|
60
|
-
* and so the user count is never queried there.
|
|
61
|
-
*/
|
|
62
|
-
static async getSeatUsage(data) {
|
|
63
|
-
if (!this.isSeatLimitEnforceable()) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
const config = await GlobalConfigService.findOneById({
|
|
67
|
-
id: ObjectID.getZeroObjectID(),
|
|
68
|
-
select: {
|
|
69
|
-
enterpriseLicenseUserLimit: true,
|
|
70
|
-
enterpriseLicenseCurrentUserCount: true,
|
|
71
|
-
enterpriseLicenseInstances: true,
|
|
72
|
-
instanceId: true,
|
|
73
|
-
},
|
|
74
|
-
props: {
|
|
75
|
-
isRoot: true,
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
return this.getSeatUsageForLoadedGlobalConfig({
|
|
79
|
-
config: config,
|
|
80
|
-
getLocalUserCount: data.getLocalUserCount,
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/*
|
|
84
|
-
* The same answer as getSeatUsage, for a caller that has already loaded the
|
|
85
|
-
* GlobalConfig row (the license endpoint reads it to build its response, and
|
|
86
|
-
* reading it twice per request would be silly).
|
|
87
|
-
*
|
|
88
|
-
* The row must have been selected with enterpriseLicenseUserLimit,
|
|
89
|
-
* enterpriseLicenseCurrentUserCount, enterpriseLicenseInstances and
|
|
90
|
-
* instanceId, or the numbers here are a fiction built from missing columns.
|
|
91
|
-
*/
|
|
92
|
-
static async getSeatUsageForLoadedGlobalConfig(data) {
|
|
93
|
-
if (!this.isSeatLimitEnforceable()) {
|
|
94
|
-
return null;
|
|
95
|
-
}
|
|
96
|
-
/*
|
|
97
|
-
* The seat limit is read before the users are counted, and the count is
|
|
98
|
-
* skipped entirely when there is no limit. An unlimited licence is the
|
|
99
|
-
* common case on a large installation, and that is exactly the
|
|
100
|
-
* installation where counting the User table on every user creation would
|
|
101
|
-
* be worth avoiding.
|
|
102
|
-
*/
|
|
103
|
-
const withoutLocalUsers = this.getSeatUsageFromGlobalConfig({
|
|
104
|
-
config: data.config,
|
|
105
|
-
localUserCount: 0,
|
|
106
|
-
});
|
|
107
|
-
if (!withoutLocalUsers.isEnforced) {
|
|
108
|
-
return withoutLocalUsers;
|
|
109
|
-
}
|
|
110
|
-
return this.getSeatUsageFromGlobalConfig({
|
|
111
|
-
config: data.config,
|
|
112
|
-
localUserCount: await data.getLocalUserCount(),
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
/*
|
|
116
|
-
* Throws if this installation cannot take another user.
|
|
117
|
-
*
|
|
118
|
-
* Called from UserService.onBeforeCreate, which every path that creates a
|
|
119
|
-
* user goes through — team invitations, self-service signup, SSO and OIDC
|
|
120
|
-
* just-in-time provisioning, SCIM, and the Admin Dashboard. Enforcing on the
|
|
121
|
-
* User row rather than on the invitation is what makes that true: a seat is
|
|
122
|
-
* consumed by a person existing on the installation, not by the particular
|
|
123
|
-
* door they came through.
|
|
124
|
-
*
|
|
125
|
-
* It is also why this deliberately does NOT exempt root/internal writes.
|
|
126
|
-
* Team invitations create the invited user with `isRoot: true`, so an
|
|
127
|
-
* isRoot escape hatch here would exempt the single most important path.
|
|
128
|
-
*/
|
|
129
|
-
static async assertSeatAvailableForNewUser(data) {
|
|
130
|
-
const seatUsage = await this.getSeatUsage({
|
|
131
|
-
getLocalUserCount: data.getLocalUserCount,
|
|
132
|
-
});
|
|
133
|
-
if (!seatUsage || !seatUsage.isEnforced) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
if (seatUsage.hasSeatForNewUser) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
throw new BadDataException(EnterpriseLicenseSeatsUtil.getSeatLimitReachedMessage({
|
|
140
|
-
seatsInUse: seatUsage.seatsInUse,
|
|
141
|
-
userLimit: seatUsage.userLimit,
|
|
142
|
-
}));
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
//# sourceMappingURL=EnterpriseLicenseSeatUtil.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EnterpriseLicenseSeatUtil.js","sourceRoot":"","sources":["../../../../../Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import PostgresAppInstance from "../../Infrastructure/PostgresDatabase";
|
|
2
|
-
import logger from "../Logger";
|
|
3
|
-
/*
|
|
4
|
-
* Postgres refuses all writes once transaction-ID age reaches 2^31. Utilization
|
|
5
|
-
* is expressed against that hard ceiling rather than autovacuum_freeze_max_age,
|
|
6
|
-
* which is only the point where autovacuum is forced to intervene and is
|
|
7
|
-
* routinely exceeded on a healthy instance.
|
|
8
|
-
*/
|
|
9
|
-
export const POSTGRES_WRAPAROUND_CEILING = 2147483648;
|
|
10
|
-
const BYTES_PER_GB = 1024 * 1024 * 1024;
|
|
11
|
-
export function gigabytesToBytes(gigabytes) {
|
|
12
|
-
return gigabytes * BYTES_PER_GB;
|
|
13
|
-
}
|
|
14
|
-
function toNumberOrNull(value) {
|
|
15
|
-
if (value === null || value === undefined || value === "") {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const parsed = Number(value);
|
|
19
|
-
return Number.isFinite(parsed) ? parsed : null;
|
|
20
|
-
}
|
|
21
|
-
/*
|
|
22
|
-
* Every probe is guarded on its own so a permission error or a feature missing
|
|
23
|
-
* on this Postgres version (pg_replication_slots columns differ across major
|
|
24
|
-
* versions) leaves that one field null instead of blanking the whole snapshot.
|
|
25
|
-
* A null field means "not evaluated"; callers must not read it as healthy.
|
|
26
|
-
*/
|
|
27
|
-
export async function getPostgresHealthSnapshot() {
|
|
28
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
29
|
-
const dataSource = PostgresAppInstance.getDataSource();
|
|
30
|
-
if (!dataSource) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
const snapshot = {
|
|
34
|
-
databaseSizeInBytes: null,
|
|
35
|
-
walSizeInBytes: null,
|
|
36
|
-
maxConnections: null,
|
|
37
|
-
usableConnections: null,
|
|
38
|
-
clientBackends: null,
|
|
39
|
-
connectionUtilizationPercent: null,
|
|
40
|
-
transactionIdAge: null,
|
|
41
|
-
multiXactIdAge: null,
|
|
42
|
-
maxTransactionIdAge: null,
|
|
43
|
-
wraparoundUtilizationPercent: null,
|
|
44
|
-
replicationSlots: null,
|
|
45
|
-
isInRecovery: false,
|
|
46
|
-
};
|
|
47
|
-
try {
|
|
48
|
-
const rows = await dataSource.query("SELECT pg_is_in_recovery() AS in_recovery");
|
|
49
|
-
snapshot.isInRecovery = Boolean((_a = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _a === void 0 ? void 0 : _a.in_recovery);
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
logger.debug("InstanceHealth: postgres recovery-state probe failed");
|
|
53
|
-
logger.debug(error);
|
|
54
|
-
}
|
|
55
|
-
try {
|
|
56
|
-
const rows = await dataSource.query("SELECT pg_database_size(current_database()) AS size");
|
|
57
|
-
snapshot.databaseSizeInBytes = toNumberOrNull((_b = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _b === void 0 ? void 0 : _b.size);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
logger.debug("InstanceHealth: pg_database_size probe failed");
|
|
61
|
-
logger.debug(error);
|
|
62
|
-
}
|
|
63
|
-
/*
|
|
64
|
-
* WAL is measured separately because it lives on the same volume but outside
|
|
65
|
-
* pg_database_size, and an abandoned replication slot parks tens of gigabytes
|
|
66
|
-
* there. Without it the storage check can read comfortably under threshold
|
|
67
|
-
* while the volume is full and writes are already failing. pg_ls_waldir()
|
|
68
|
-
* needs superuser or pg_monitor, so this stays best-effort.
|
|
69
|
-
*/
|
|
70
|
-
try {
|
|
71
|
-
const rows = await dataSource.query("SELECT COALESCE(sum(size), 0) AS size FROM pg_ls_waldir()");
|
|
72
|
-
snapshot.walSizeInBytes = toNumberOrNull((_c = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _c === void 0 ? void 0 : _c.size);
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
logger.debug("InstanceHealth: pg_ls_waldir probe failed");
|
|
76
|
-
logger.debug(error);
|
|
77
|
-
}
|
|
78
|
-
/*
|
|
79
|
-
* Backends come from pg_stat_database.numbackends rather than counting
|
|
80
|
-
* pg_stat_activity rows. pg_stat_activity nulls backend_type (and state, and
|
|
81
|
-
* client_addr) for backends belonging to other roles unless the caller is a
|
|
82
|
-
* superuser or holds pg_read_all_stats/pg_monitor, so a filtered count sees
|
|
83
|
-
* only OneUptime's own connections on a managed or hardened cluster. That
|
|
84
|
-
* failure is silent — no error, no null — so it would read as healthy while
|
|
85
|
-
* another tenant exhausts the cluster, and would actively resolve an alert
|
|
86
|
-
* raised earlier from a privileged role. numbackends is not masked.
|
|
87
|
-
*
|
|
88
|
-
* The denominator subtracts the slots reserved for superusers (and, from PG
|
|
89
|
-
* 16, for pg_use_reserved_connections): ordinary clients are refused once
|
|
90
|
-
* those are all that remain, so measuring against raw max_connections
|
|
91
|
-
* understates saturation and can put the critical tier out of reach entirely
|
|
92
|
-
* on a small max_connections.
|
|
93
|
-
*/
|
|
94
|
-
try {
|
|
95
|
-
const rows = await dataSource.query(`SELECT
|
|
96
|
-
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') AS max_connections,
|
|
97
|
-
COALESCE((SELECT setting::int FROM pg_settings WHERE name = 'superuser_reserved_connections'), 0)
|
|
98
|
-
+ COALESCE((SELECT setting::int FROM pg_settings WHERE name = 'reserved_connections'), 0)
|
|
99
|
-
AS reserved_connections,
|
|
100
|
-
(SELECT COALESCE(sum(numbackends), 0) FROM pg_stat_database) AS backends`);
|
|
101
|
-
const maxConnections = toNumberOrNull((_d = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _d === void 0 ? void 0 : _d.max_connections);
|
|
102
|
-
const reservedConnections = (_f = toNumberOrNull((_e = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _e === void 0 ? void 0 : _e.reserved_connections)) !== null && _f !== void 0 ? _f : 0;
|
|
103
|
-
const clientBackends = toNumberOrNull((_g = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _g === void 0 ? void 0 : _g.backends);
|
|
104
|
-
const usableConnections = maxConnections === null
|
|
105
|
-
? null
|
|
106
|
-
: Math.max(1, maxConnections - reservedConnections);
|
|
107
|
-
snapshot.maxConnections = maxConnections;
|
|
108
|
-
snapshot.usableConnections = usableConnections;
|
|
109
|
-
snapshot.clientBackends = clientBackends;
|
|
110
|
-
snapshot.connectionUtilizationPercent =
|
|
111
|
-
usableConnections !== null && clientBackends !== null
|
|
112
|
-
? (clientBackends / usableConnections) * 100
|
|
113
|
-
: null;
|
|
114
|
-
}
|
|
115
|
-
catch (error) {
|
|
116
|
-
logger.debug("InstanceHealth: postgres connection probe failed");
|
|
117
|
-
logger.debug(error);
|
|
118
|
-
}
|
|
119
|
-
/*
|
|
120
|
-
* Multixact age is an independent counter with the same 2^31 ceiling and the
|
|
121
|
-
* same consequence — Postgres stops accepting commands to avoid wraparound
|
|
122
|
-
* data loss. An FK-heavy or SELECT ... FOR SHARE workload can exhaust it while
|
|
123
|
-
* ordinary XID age looks fine, so the check reports whichever is worse.
|
|
124
|
-
*/
|
|
125
|
-
try {
|
|
126
|
-
const rows = await dataSource.query(`SELECT
|
|
127
|
-
max(age(datfrozenxid)) AS max_xid_age,
|
|
128
|
-
max(mxid_age(datminmxid)) AS max_mxid_age
|
|
129
|
-
FROM pg_database`);
|
|
130
|
-
const transactionIdAge = toNumberOrNull((_h = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _h === void 0 ? void 0 : _h.max_xid_age);
|
|
131
|
-
const multiXactIdAge = toNumberOrNull((_j = rows === null || rows === void 0 ? void 0 : rows[0]) === null || _j === void 0 ? void 0 : _j.max_mxid_age);
|
|
132
|
-
const maxTransactionIdAge = transactionIdAge === null && multiXactIdAge === null
|
|
133
|
-
? null
|
|
134
|
-
: Math.max(transactionIdAge !== null && transactionIdAge !== void 0 ? transactionIdAge : 0, multiXactIdAge !== null && multiXactIdAge !== void 0 ? multiXactIdAge : 0);
|
|
135
|
-
snapshot.transactionIdAge = transactionIdAge;
|
|
136
|
-
snapshot.multiXactIdAge = multiXactIdAge;
|
|
137
|
-
snapshot.maxTransactionIdAge = maxTransactionIdAge;
|
|
138
|
-
snapshot.wraparoundUtilizationPercent =
|
|
139
|
-
maxTransactionIdAge !== null
|
|
140
|
-
? (maxTransactionIdAge / POSTGRES_WRAPAROUND_CEILING) * 100
|
|
141
|
-
: null;
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
logger.debug("InstanceHealth: postgres wraparound probe failed");
|
|
145
|
-
logger.debug(error);
|
|
146
|
-
}
|
|
147
|
-
/*
|
|
148
|
-
* wal_status arrived in Postgres 13. On an older external database the column
|
|
149
|
-
* simply does not exist and the whole statement errors, which would silence
|
|
150
|
-
* the slot check entirely — even though restart_lsn and pg_wal_lsn_diff are
|
|
151
|
-
* available there and the retained-WAL half of the check works fine. So the
|
|
152
|
-
* version-specific column is dropped on a retry rather than taking the rest
|
|
153
|
-
* of the probe down with it.
|
|
154
|
-
*/
|
|
155
|
-
const buildSlotQuery = (withWalStatus) => {
|
|
156
|
-
return `SELECT
|
|
157
|
-
slot_name,
|
|
158
|
-
slot_type,
|
|
159
|
-
active,
|
|
160
|
-
${withWalStatus ? "COALESCE(wal_status, 'unknown')" : "'unknown'"} AS wal_status,
|
|
161
|
-
CASE WHEN pg_is_in_recovery() THEN NULL
|
|
162
|
-
ELSE pg_wal_lsn_diff(pg_current_wal_lsn(), restart_lsn) END AS retained_bytes
|
|
163
|
-
FROM pg_replication_slots
|
|
164
|
-
ORDER BY slot_name ASC`;
|
|
165
|
-
};
|
|
166
|
-
let slotRows = null;
|
|
167
|
-
try {
|
|
168
|
-
slotRows = await dataSource.query(buildSlotQuery(true));
|
|
169
|
-
}
|
|
170
|
-
catch (error) {
|
|
171
|
-
logger.debug("InstanceHealth: pg_replication_slots probe failed, retrying without wal_status");
|
|
172
|
-
logger.debug(error);
|
|
173
|
-
try {
|
|
174
|
-
slotRows = await dataSource.query(buildSlotQuery(false));
|
|
175
|
-
}
|
|
176
|
-
catch (retryError) {
|
|
177
|
-
logger.debug("InstanceHealth: pg_replication_slots probe failed");
|
|
178
|
-
logger.debug(retryError);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (slotRows) {
|
|
182
|
-
snapshot.replicationSlots = slotRows.map((row) => {
|
|
183
|
-
return {
|
|
184
|
-
slotName: String(row.slot_name || ""),
|
|
185
|
-
slotType: String(row.slot_type || "unknown"),
|
|
186
|
-
isActive: Boolean(row.active),
|
|
187
|
-
walStatus: String(row.wal_status || "unknown"),
|
|
188
|
-
retainedWalInBytes: toNumberOrNull(row.retained_bytes),
|
|
189
|
-
};
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
return snapshot;
|
|
193
|
-
}
|
|
194
|
-
//# sourceMappingURL=PostgresHealth.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"PostgresHealth.js","sourceRoot":"","sources":["../../../../../Server/Utils/InstanceHealth/PostgresHealth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
export default class EnterpriseLicenseSeatsUtil {
|
|
2
|
-
/*
|
|
3
|
-
* How many seats are in use, and whether one more user fits.
|
|
4
|
-
*
|
|
5
|
-
* The awkward part is that a license is shared by every instance the
|
|
6
|
-
* customer runs, and only oneuptime.com can deduplicate users across them —
|
|
7
|
-
* the same person on staging and production is one seat. So this instance
|
|
8
|
-
* has two numbers and neither one is the answer on its own:
|
|
9
|
-
*
|
|
10
|
-
* localUserCount live, but blind to the customer's other instances.
|
|
11
|
-
* aggregatedUserCount complete, but up to a day old, so it does not know
|
|
12
|
-
* about anyone added since the last daily report —
|
|
13
|
-
* including the user being added right now.
|
|
14
|
-
*
|
|
15
|
-
* Combining them needs to know how much of the aggregate is NOT ours, which
|
|
16
|
-
* is what the per-instance breakdown is for: subtract our own last reported
|
|
17
|
-
* count from the aggregate and what is left is other instances. Add the live
|
|
18
|
-
* local count back and the result is current on this instance and complete
|
|
19
|
-
* on the others.
|
|
20
|
-
*
|
|
21
|
-
* When the breakdown does not say — an older license server that sends no
|
|
22
|
-
* instance list, an instance that has never registered — there is nothing to
|
|
23
|
-
* subtract, and the fallback is the larger of the two numbers on their own.
|
|
24
|
-
* That is the only case where the stale aggregate decides anything: with a
|
|
25
|
-
* usable breakdown it is deliberately NOT maxed in, because it would then
|
|
26
|
-
* outvote the live count in the one direction that hurts. Free twenty seats
|
|
27
|
-
* by deleting twenty users and a stale aggregate would go on refusing new
|
|
28
|
-
* ones until the next daily report.
|
|
29
|
-
*
|
|
30
|
-
* Which way it is allowed to be wrong: under-enforcing is recoverable (the
|
|
31
|
-
* next daily report corrects the count, and the breach emails already go
|
|
32
|
-
* out), over-enforcing locks a paying customer out of their own instance.
|
|
33
|
-
* So every "I cannot tell" branch below resolves towards under-enforcing.
|
|
34
|
-
*/
|
|
35
|
-
static getSeatUsage(input) {
|
|
36
|
-
var _a;
|
|
37
|
-
const userLimit = this.parseUserLimit(input.userLimit);
|
|
38
|
-
const localUserCount = (_a = this.parseCount(input.localUserCount)) !== null && _a !== void 0 ? _a : 0;
|
|
39
|
-
const aggregatedUserCount = this.parseCount(input.aggregatedUserCount);
|
|
40
|
-
/*
|
|
41
|
-
* Null means the report is not complete enough to attribute seats to
|
|
42
|
-
* anybody, which is a different thing from attributing zero to them.
|
|
43
|
-
*/
|
|
44
|
-
const otherInstanceSeats = this.getSeatsUsedByOtherInstances({
|
|
45
|
-
aggregatedUserCount: aggregatedUserCount,
|
|
46
|
-
instances: input.instances,
|
|
47
|
-
thisInstanceId: input.thisInstanceId,
|
|
48
|
-
});
|
|
49
|
-
const seatsUsedByOtherInstances = otherInstanceSeats !== null && otherInstanceSeats !== void 0 ? otherInstanceSeats : 0;
|
|
50
|
-
const seatsInUse = otherInstanceSeats === null
|
|
51
|
-
? Math.max(localUserCount, aggregatedUserCount !== null && aggregatedUserCount !== void 0 ? aggregatedUserCount : 0)
|
|
52
|
-
: otherInstanceSeats + localUserCount;
|
|
53
|
-
if (userLimit === null) {
|
|
54
|
-
return {
|
|
55
|
-
isEnforced: false,
|
|
56
|
-
userLimit: null,
|
|
57
|
-
seatsInUse: seatsInUse,
|
|
58
|
-
seatsRemaining: null,
|
|
59
|
-
hasSeatForNewUser: true,
|
|
60
|
-
seatsUsedByOtherInstances: seatsUsedByOtherInstances,
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
isEnforced: true,
|
|
65
|
-
userLimit: userLimit,
|
|
66
|
-
seatsInUse: seatsInUse,
|
|
67
|
-
seatsRemaining: Math.max(0, userLimit - seatsInUse),
|
|
68
|
-
hasSeatForNewUser: seatsInUse < userLimit,
|
|
69
|
-
seatsUsedByOtherInstances: seatsUsedByOtherInstances,
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
/*
|
|
73
|
-
* The message an administrator reads when a seat could not be taken. Built
|
|
74
|
-
* here rather than at each throw site so the invite form, the signup form
|
|
75
|
-
* and SSO/SCIM provisioning all explain the same thing the same way, and so
|
|
76
|
-
* the tests can assert on it without copying the wording.
|
|
77
|
-
*/
|
|
78
|
-
static getSeatLimitReachedMessage(data) {
|
|
79
|
-
return (`This OneUptime installation has reached the ${data.userLimit.toLocaleString()}-user ` +
|
|
80
|
-
`limit of its enterprise license (${data.seatsInUse.toLocaleString()} in use). New users ` +
|
|
81
|
-
`cannot be invited, signed up or provisioned until a seat is freed up or the license is ` +
|
|
82
|
-
`expanded. Contact sales@oneuptime.com to add seats, then use "Refresh license" in the ` +
|
|
83
|
-
`edition dialog to apply the new limit.`);
|
|
84
|
-
}
|
|
85
|
-
/*
|
|
86
|
-
* The part of the aggregate that belongs to instances other than this one,
|
|
87
|
-
* or null when the report does not say.
|
|
88
|
-
*
|
|
89
|
-
* Null rather than zero, because the two lead somewhere different: zero means
|
|
90
|
-
* "this installation is the only one holding seats", and null means "the
|
|
91
|
-
* report cannot be decomposed, fall back to comparing the two totals". Every
|
|
92
|
-
* missing or unusable field lands on null.
|
|
93
|
-
*
|
|
94
|
-
* In particular, an instance list that does not contain us is NOT treated as
|
|
95
|
-
* "then all of the aggregate is somebody else's". That reading is right for a
|
|
96
|
-
* genuinely unregistered instance, and catastrophic for an instance whose id
|
|
97
|
-
* changed after its users were already counted under the old one: it would
|
|
98
|
-
* count this installation's users twice and lock it out.
|
|
99
|
-
*/
|
|
100
|
-
static getSeatsUsedByOtherInstances(data) {
|
|
101
|
-
const aggregatedUserCount = data.aggregatedUserCount;
|
|
102
|
-
if (aggregatedUserCount === null) {
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
|
-
if (!Array.isArray(data.instances) || data.instances.length === 0) {
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
const thisInstanceId = typeof data.thisInstanceId === "string" ? data.thisInstanceId.trim() : "";
|
|
109
|
-
if (!thisInstanceId) {
|
|
110
|
-
return null;
|
|
111
|
-
}
|
|
112
|
-
const thisInstance = data.instances.find((instance) => {
|
|
113
|
-
return Boolean(instance) && instance.instanceId === thisInstanceId;
|
|
114
|
-
});
|
|
115
|
-
if (!thisInstance) {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
/*
|
|
119
|
-
* The active-only aggregate contains none of this installation's stale
|
|
120
|
-
* reported users. Subtracting that old count would remove users belonging
|
|
121
|
-
* to active instances and under-enforce the license. Treat the complete
|
|
122
|
-
* aggregate as other-instance usage. We also cannot add the two counts:
|
|
123
|
-
* the same users may exist on both this installation and active ones.
|
|
124
|
-
* Return null to use the existing uncertainty fallback, which takes the
|
|
125
|
-
* larger complete-or-live total without subtracting or double-counting.
|
|
126
|
-
*
|
|
127
|
-
* Undefined retains the legacy behavior for responses from older license
|
|
128
|
-
* servers that did not send activity provenance.
|
|
129
|
-
*/
|
|
130
|
-
if (thisInstance.isCountedTowardsUsage === false) {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
const ownReportedCount = this.parseCount(thisInstance.userCount);
|
|
134
|
-
if (ownReportedCount === null) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
return Math.max(0, aggregatedUserCount - ownReportedCount);
|
|
138
|
-
}
|
|
139
|
-
/*
|
|
140
|
-
* A limit is only a limit when it is a positive whole number.
|
|
141
|
-
*
|
|
142
|
-
* Zero is deliberately read as "no limit" rather than "no seats at all",
|
|
143
|
-
* matching every other place in the product that measures seat usage
|
|
144
|
-
* (the license modal, the breach notification job). A license that really
|
|
145
|
-
* grants nobody an account is not a thing OneUptime issues, and reading a
|
|
146
|
-
* stray zero the other way would leave an installation unable to create even
|
|
147
|
-
* its first user.
|
|
148
|
-
*/
|
|
149
|
-
static parseUserLimit(value) {
|
|
150
|
-
if (typeof value !== "number" ||
|
|
151
|
-
!Number.isFinite(value) ||
|
|
152
|
-
!Number.isInteger(value) ||
|
|
153
|
-
value <= 0) {
|
|
154
|
-
return null;
|
|
155
|
-
}
|
|
156
|
-
return value;
|
|
157
|
-
}
|
|
158
|
-
static parseCount(value) {
|
|
159
|
-
if (typeof value !== "number" ||
|
|
160
|
-
!Number.isFinite(value) ||
|
|
161
|
-
!Number.isInteger(value) ||
|
|
162
|
-
value < 0) {
|
|
163
|
-
return null;
|
|
164
|
-
}
|
|
165
|
-
return value;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
//# sourceMappingURL=EnterpriseLicenseSeats.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EnterpriseLicenseSeats.js","sourceRoot":"","sources":["../../../../Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts"],"names":[],"mappings":"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"}
|