@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
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import { jest } from "@jest/globals";
|
|
2
|
+
import EnterpriseEdition from "../../../Server/Enterprise/EnterpriseEdition";
|
|
3
|
+
import EnterpriseFeature from "../../../Server/Enterprise/EnterpriseFeature";
|
|
4
|
+
import {
|
|
5
|
+
EnterpriseLicenseSnapshot,
|
|
6
|
+
EnterpriseLicenseStatus,
|
|
7
|
+
SeatUsage,
|
|
8
|
+
} from "../../../Server/Enterprise/EnterpriseLicenseSnapshot";
|
|
9
|
+
import EnterpriseServerModule, {
|
|
10
|
+
AuditLogRecorder,
|
|
11
|
+
ENTERPRISE_SERVER_MODULE_NAME,
|
|
12
|
+
EnterpriseLicensingProvider,
|
|
13
|
+
} from "../../../Server/Enterprise/EnterpriseServerModule";
|
|
14
|
+
import type { ExpressRouter } from "../../../Server/Utils/Express";
|
|
15
|
+
import { setTestBillingEnabled } from "./TestBillingFlag";
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* Test kit for anything that behaves differently per edition.
|
|
19
|
+
*
|
|
20
|
+
* Every suite that touches gated code pins BOTH halves of the state:
|
|
21
|
+
* - billing, with TestBillingFlag (CI's config.env sets BILLING_ENABLED=true)
|
|
22
|
+
* - the edition, with installFakeEnterpriseModule(...) for "EE loaded" or
|
|
23
|
+
* uninstallEnterpriseModule() for "Community Edition"
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
const DAY_IN_MS: number = 24 * 60 * 60 * 1000;
|
|
27
|
+
|
|
28
|
+
// A current, fully entitled, verified license. Override what the test is about.
|
|
29
|
+
export const createLicenseSnapshot: (
|
|
30
|
+
overrides?: Partial<EnterpriseLicenseSnapshot>,
|
|
31
|
+
) => EnterpriseLicenseSnapshot = (
|
|
32
|
+
overrides?: Partial<EnterpriseLicenseSnapshot>,
|
|
33
|
+
): EnterpriseLicenseSnapshot => {
|
|
34
|
+
return {
|
|
35
|
+
status: "valid",
|
|
36
|
+
verification: "verified",
|
|
37
|
+
companyName: "Acme Inc",
|
|
38
|
+
expiresAt: new Date(Date.now() + 365 * DAY_IN_MS),
|
|
39
|
+
userLimit: null,
|
|
40
|
+
isEvaluation: false,
|
|
41
|
+
features: "all",
|
|
42
|
+
...(overrides || {}),
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/*
|
|
47
|
+
* A snapshot in the given status, with the fields that status normally
|
|
48
|
+
* carries. "missing" is an install whose trial ended a day ago (graceEndsAt
|
|
49
|
+
* in the past): a known lapse. Pass graceEndsAt: undefined for "the trial
|
|
50
|
+
* start is not known", which isFeatureActive treats as an unknown state.
|
|
51
|
+
*/
|
|
52
|
+
export const createLicenseSnapshotWithStatus: (
|
|
53
|
+
status: EnterpriseLicenseStatus,
|
|
54
|
+
overrides?: Partial<EnterpriseLicenseSnapshot>,
|
|
55
|
+
) => EnterpriseLicenseSnapshot = (
|
|
56
|
+
status: EnterpriseLicenseStatus,
|
|
57
|
+
overrides?: Partial<EnterpriseLicenseSnapshot>,
|
|
58
|
+
): EnterpriseLicenseSnapshot => {
|
|
59
|
+
const now: number = Date.now();
|
|
60
|
+
|
|
61
|
+
switch (status) {
|
|
62
|
+
case "missing":
|
|
63
|
+
return createLicenseSnapshot({
|
|
64
|
+
status,
|
|
65
|
+
verification: "none",
|
|
66
|
+
companyName: undefined,
|
|
67
|
+
expiresAt: undefined,
|
|
68
|
+
graceEndsAt: new Date(now - DAY_IN_MS),
|
|
69
|
+
features: [],
|
|
70
|
+
...(overrides || {}),
|
|
71
|
+
});
|
|
72
|
+
case "grace":
|
|
73
|
+
return createLicenseSnapshot({
|
|
74
|
+
status,
|
|
75
|
+
graceReason: "expired",
|
|
76
|
+
// Two days into the 30-day grace period.
|
|
77
|
+
expiresAt: new Date(now - 2 * DAY_IN_MS),
|
|
78
|
+
graceEndsAt: new Date(now + 28 * DAY_IN_MS),
|
|
79
|
+
...(overrides || {}),
|
|
80
|
+
});
|
|
81
|
+
case "expired":
|
|
82
|
+
return createLicenseSnapshot({
|
|
83
|
+
status,
|
|
84
|
+
// Past the 30-day grace period.
|
|
85
|
+
expiresAt: new Date(now - 45 * DAY_IN_MS),
|
|
86
|
+
...(overrides || {}),
|
|
87
|
+
});
|
|
88
|
+
case "invalid":
|
|
89
|
+
return createLicenseSnapshot({
|
|
90
|
+
status,
|
|
91
|
+
message: "The license token signature does not verify.",
|
|
92
|
+
...(overrides || {}),
|
|
93
|
+
});
|
|
94
|
+
case "valid":
|
|
95
|
+
default:
|
|
96
|
+
return createLicenseSnapshot({ status, ...(overrides || {}) });
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* Each method is both the recorder method and a jest spy, so a test can assert
|
|
102
|
+
* on calls (toHaveBeenCalledWith) without casting.
|
|
103
|
+
*/
|
|
104
|
+
export type MockedAuditLogRecorder = {
|
|
105
|
+
[K in keyof AuditLogRecorder]: AuditLogRecorder[K] & jest.Mock;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// An audit-log recorder whose four methods are jest spies that do nothing.
|
|
109
|
+
export const createAuditLogRecorderSpy: () => MockedAuditLogRecorder =
|
|
110
|
+
(): MockedAuditLogRecorder => {
|
|
111
|
+
return {
|
|
112
|
+
recordCreate: jest.fn(async (): Promise<void> => {
|
|
113
|
+
return undefined;
|
|
114
|
+
}) as unknown as MockedAuditLogRecorder["recordCreate"],
|
|
115
|
+
recordUpdate: jest.fn(async (): Promise<void> => {
|
|
116
|
+
return undefined;
|
|
117
|
+
}) as unknown as MockedAuditLogRecorder["recordUpdate"],
|
|
118
|
+
recordDelete: jest.fn(async (): Promise<void> => {
|
|
119
|
+
return undefined;
|
|
120
|
+
}) as unknown as MockedAuditLogRecorder["recordDelete"],
|
|
121
|
+
invalidateProjectSettings: jest.fn((): void => {
|
|
122
|
+
return undefined;
|
|
123
|
+
}) as unknown as MockedAuditLogRecorder["invalidateProjectSettings"],
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
export interface FakeEnterpriseModuleOptions {
|
|
128
|
+
/*
|
|
129
|
+
* What getCachedSnapshot() and getSnapshot() return. Defaults to a valid,
|
|
130
|
+
* fully entitled license. Null models "the first load has not finished".
|
|
131
|
+
*/
|
|
132
|
+
snapshot?: EnterpriseLicenseSnapshot | null | undefined;
|
|
133
|
+
/*
|
|
134
|
+
* What getSnapshot() returns when it should differ from the cached one (for
|
|
135
|
+
* example a fresher read). Defaults to `snapshot`.
|
|
136
|
+
*/
|
|
137
|
+
asyncSnapshot?: EnterpriseLicenseSnapshot | null | undefined;
|
|
138
|
+
seatUsage?: SeatUsage | null | undefined;
|
|
139
|
+
// When set, assertSeatAvailableForNewUser rejects with it.
|
|
140
|
+
seatError?: Error | undefined;
|
|
141
|
+
identityRouters?: Array<ExpressRouter> | undefined;
|
|
142
|
+
apiRouters?: Array<ExpressRouter> | undefined;
|
|
143
|
+
adminHealthRouter?: ExpressRouter | null | undefined;
|
|
144
|
+
// Defaults to a fresh spy recorder; pass null for "ee without a recorder".
|
|
145
|
+
auditLogRecorder?: AuditLogRecorder | null | undefined;
|
|
146
|
+
version?: string | undefined;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
class FakeLicensingProvider implements EnterpriseLicensingProvider {
|
|
150
|
+
public cachedSnapshot: EnterpriseLicenseSnapshot | null;
|
|
151
|
+
public asyncSnapshot: EnterpriseLicenseSnapshot | null;
|
|
152
|
+
public seatUsage: SeatUsage | null;
|
|
153
|
+
public seatError: Error | undefined;
|
|
154
|
+
public getCachedSnapshotError: Error | undefined = undefined;
|
|
155
|
+
public getSnapshotError: Error | undefined = undefined;
|
|
156
|
+
public refreshCount: number = 0;
|
|
157
|
+
public invalidateCount: number = 0;
|
|
158
|
+
public seatChecks: number = 0;
|
|
159
|
+
|
|
160
|
+
public constructor(options: FakeEnterpriseModuleOptions) {
|
|
161
|
+
this.cachedSnapshot =
|
|
162
|
+
options.snapshot === undefined
|
|
163
|
+
? createLicenseSnapshot()
|
|
164
|
+
: options.snapshot;
|
|
165
|
+
this.asyncSnapshot =
|
|
166
|
+
options.asyncSnapshot === undefined
|
|
167
|
+
? this.cachedSnapshot
|
|
168
|
+
: options.asyncSnapshot;
|
|
169
|
+
this.seatUsage = options.seatUsage === undefined ? null : options.seatUsage;
|
|
170
|
+
this.seatError = options.seatError;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public async getSnapshot(): Promise<EnterpriseLicenseSnapshot> {
|
|
174
|
+
if (this.getSnapshotError) {
|
|
175
|
+
throw this.getSnapshotError;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (!this.asyncSnapshot) {
|
|
179
|
+
throw new Error("FakeLicensingProvider: no snapshot configured");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return this.asyncSnapshot;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public getCachedSnapshot(): EnterpriseLicenseSnapshot | null {
|
|
186
|
+
if (this.getCachedSnapshotError) {
|
|
187
|
+
throw this.getCachedSnapshotError;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return this.cachedSnapshot;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
public async refresh(): Promise<void> {
|
|
194
|
+
this.refreshCount++;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
public invalidate(): void {
|
|
198
|
+
this.invalidateCount++;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
public async getSeatUsage(): Promise<SeatUsage | null> {
|
|
202
|
+
return this.seatUsage;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public async assertSeatAvailableForNewUser(): Promise<void> {
|
|
206
|
+
this.seatChecks++;
|
|
207
|
+
|
|
208
|
+
if (this.seatError) {
|
|
209
|
+
throw this.seatError;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
export default class FakeEnterpriseModule implements EnterpriseServerModule {
|
|
215
|
+
public readonly name: typeof ENTERPRISE_SERVER_MODULE_NAME =
|
|
216
|
+
ENTERPRISE_SERVER_MODULE_NAME;
|
|
217
|
+
public readonly version: string;
|
|
218
|
+
public readonly licensing: FakeLicensingProvider;
|
|
219
|
+
public identityRouters: Array<ExpressRouter>;
|
|
220
|
+
public apiRouters: Array<ExpressRouter>;
|
|
221
|
+
public adminHealthRouter: ExpressRouter | null;
|
|
222
|
+
public auditLogRecorder: AuditLogRecorder | null;
|
|
223
|
+
public initCount: number = 0;
|
|
224
|
+
public registerWorkerJobsCount: number = 0;
|
|
225
|
+
|
|
226
|
+
public constructor(options: FakeEnterpriseModuleOptions = {}) {
|
|
227
|
+
this.version = options.version || "0.0.0-test";
|
|
228
|
+
this.licensing = new FakeLicensingProvider(options);
|
|
229
|
+
this.identityRouters = options.identityRouters || [];
|
|
230
|
+
this.apiRouters = options.apiRouters || [];
|
|
231
|
+
this.adminHealthRouter = options.adminHealthRouter || null;
|
|
232
|
+
this.auditLogRecorder =
|
|
233
|
+
options.auditLogRecorder === undefined
|
|
234
|
+
? createAuditLogRecorderSpy()
|
|
235
|
+
: options.auditLogRecorder;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
public async init(): Promise<void> {
|
|
239
|
+
this.initCount++;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
public getIdentityRouters(): Array<ExpressRouter> {
|
|
243
|
+
return this.identityRouters;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public getApiRouters(): Array<ExpressRouter> {
|
|
247
|
+
return this.apiRouters;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
public getAdminHealthRouter(): ExpressRouter | null {
|
|
251
|
+
return this.adminHealthRouter;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public async registerWorkerJobs(): Promise<void> {
|
|
255
|
+
this.registerWorkerJobsCount++;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
public getAuditLogRecorder(): AuditLogRecorder | null {
|
|
259
|
+
return this.auditLogRecorder;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Replaces both the cached and the async snapshot.
|
|
263
|
+
public setSnapshot(snapshot: EnterpriseLicenseSnapshot | null): void {
|
|
264
|
+
this.licensing.cachedSnapshot = snapshot;
|
|
265
|
+
this.licensing.asyncSnapshot = snapshot;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/*
|
|
270
|
+
* "EE is loaded" with the given license state: forgets any earlier module and
|
|
271
|
+
* registers a fresh fake. Returns it so the test can inspect or change it.
|
|
272
|
+
*/
|
|
273
|
+
export const installFakeEnterpriseModule: (
|
|
274
|
+
options?: FakeEnterpriseModuleOptions,
|
|
275
|
+
) => FakeEnterpriseModule = (
|
|
276
|
+
options?: FakeEnterpriseModuleOptions,
|
|
277
|
+
): FakeEnterpriseModule => {
|
|
278
|
+
const fake: FakeEnterpriseModule = new FakeEnterpriseModule(options || {});
|
|
279
|
+
EnterpriseEdition.resetForTests();
|
|
280
|
+
EnterpriseEdition.register(fake);
|
|
281
|
+
return fake;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// A fake whose license entitles exactly `features` (valid, verified).
|
|
285
|
+
export const installFakeEnterpriseModuleWithFeatures: (
|
|
286
|
+
features: Array<EnterpriseFeature>,
|
|
287
|
+
) => FakeEnterpriseModule = (
|
|
288
|
+
features: Array<EnterpriseFeature>,
|
|
289
|
+
): FakeEnterpriseModule => {
|
|
290
|
+
return installFakeEnterpriseModule({
|
|
291
|
+
snapshot: createLicenseSnapshot({ features }),
|
|
292
|
+
});
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
// "Community Edition": no enterprise module in the process.
|
|
296
|
+
export const uninstallEnterpriseModule: () => void = (): void => {
|
|
297
|
+
EnterpriseEdition.resetForTests();
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
/*
|
|
301
|
+
* ---------------------------------------------------------------------------
|
|
302
|
+
* License states for the RUNTIME features (SSO, SCIM, audit logging), which
|
|
303
|
+
* follow EnterpriseEdition.isFeatureActive: with billing off they run while
|
|
304
|
+
* the license covers them and stop when it lapses; an UNKNOWN license state
|
|
305
|
+
* (not read yet, or unreadable) counts as active.
|
|
306
|
+
* ---------------------------------------------------------------------------
|
|
307
|
+
*/
|
|
308
|
+
export interface LicenseStateCase {
|
|
309
|
+
label: string;
|
|
310
|
+
// Registers a fresh fake enterprise module in this license state.
|
|
311
|
+
install: () => FakeEnterpriseModule;
|
|
312
|
+
// Whether SSO, SCIM and audit logging run in this state with billing off.
|
|
313
|
+
isActiveWithoutBilling: boolean;
|
|
314
|
+
/*
|
|
315
|
+
* The unknown states: active for runtime checks, but unavailable for
|
|
316
|
+
* configuration checks (isFeatureAvailableSync fails closed).
|
|
317
|
+
*/
|
|
318
|
+
isUnknown: boolean;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// A license that entitles everything except the three runtime features.
|
|
322
|
+
export const FEATURES_WITHOUT_RUNTIME_FEATURES: Array<EnterpriseFeature> = [
|
|
323
|
+
EnterpriseFeature.TeamCompliance,
|
|
324
|
+
EnterpriseFeature.InstanceHealth,
|
|
325
|
+
];
|
|
326
|
+
|
|
327
|
+
export const LICENSE_STATE_CASES: ReadonlyArray<LicenseStateCase> = [
|
|
328
|
+
{
|
|
329
|
+
label: "valid license",
|
|
330
|
+
install: (): FakeEnterpriseModule => {
|
|
331
|
+
return installFakeEnterpriseModule({
|
|
332
|
+
snapshot: createLicenseSnapshotWithStatus("valid"),
|
|
333
|
+
});
|
|
334
|
+
},
|
|
335
|
+
isActiveWithoutBilling: true,
|
|
336
|
+
isUnknown: false,
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
label: "license expired less than 30 days ago (grace)",
|
|
340
|
+
install: (): FakeEnterpriseModule => {
|
|
341
|
+
return installFakeEnterpriseModule({
|
|
342
|
+
snapshot: createLicenseSnapshotWithStatus("grace"),
|
|
343
|
+
});
|
|
344
|
+
},
|
|
345
|
+
isActiveWithoutBilling: true,
|
|
346
|
+
isUnknown: false,
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
label: "no license, inside the 14-day trial",
|
|
350
|
+
install: (): FakeEnterpriseModule => {
|
|
351
|
+
return installFakeEnterpriseModule({
|
|
352
|
+
snapshot: createLicenseSnapshotWithStatus("grace", {
|
|
353
|
+
graceReason: "unlicensed",
|
|
354
|
+
verification: "none",
|
|
355
|
+
companyName: undefined,
|
|
356
|
+
expiresAt: undefined,
|
|
357
|
+
graceEndsAt: new Date(Date.now() + 5 * DAY_IN_MS),
|
|
358
|
+
features: "all",
|
|
359
|
+
}),
|
|
360
|
+
});
|
|
361
|
+
},
|
|
362
|
+
isActiveWithoutBilling: true,
|
|
363
|
+
isUnknown: false,
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
label: "unverified legacy license, accepted",
|
|
367
|
+
install: (): FakeEnterpriseModule => {
|
|
368
|
+
return installFakeEnterpriseModule({
|
|
369
|
+
snapshot: createLicenseSnapshotWithStatus("valid", {
|
|
370
|
+
verification: "unverified",
|
|
371
|
+
}),
|
|
372
|
+
});
|
|
373
|
+
},
|
|
374
|
+
isActiveWithoutBilling: true,
|
|
375
|
+
isUnknown: false,
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
label: "license expired more than 30 days ago",
|
|
379
|
+
install: (): FakeEnterpriseModule => {
|
|
380
|
+
return installFakeEnterpriseModule({
|
|
381
|
+
snapshot: createLicenseSnapshotWithStatus("expired"),
|
|
382
|
+
});
|
|
383
|
+
},
|
|
384
|
+
isActiveWithoutBilling: false,
|
|
385
|
+
isUnknown: false,
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
label: "no license after the trial",
|
|
389
|
+
install: (): FakeEnterpriseModule => {
|
|
390
|
+
return installFakeEnterpriseModule({
|
|
391
|
+
snapshot: createLicenseSnapshotWithStatus("missing", {
|
|
392
|
+
graceEndsAt: new Date(Date.now() - DAY_IN_MS),
|
|
393
|
+
}),
|
|
394
|
+
});
|
|
395
|
+
},
|
|
396
|
+
isActiveWithoutBilling: false,
|
|
397
|
+
isUnknown: false,
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
label: "invalid license",
|
|
401
|
+
install: (): FakeEnterpriseModule => {
|
|
402
|
+
return installFakeEnterpriseModule({
|
|
403
|
+
snapshot: createLicenseSnapshotWithStatus("invalid"),
|
|
404
|
+
});
|
|
405
|
+
},
|
|
406
|
+
isActiveWithoutBilling: false,
|
|
407
|
+
isUnknown: false,
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
label: "valid license without SSO, SCIM or audit logs",
|
|
411
|
+
install: (): FakeEnterpriseModule => {
|
|
412
|
+
return installFakeEnterpriseModule({
|
|
413
|
+
snapshot: createLicenseSnapshotWithStatus("valid", {
|
|
414
|
+
features: [...FEATURES_WITHOUT_RUNTIME_FEATURES],
|
|
415
|
+
}),
|
|
416
|
+
});
|
|
417
|
+
},
|
|
418
|
+
isActiveWithoutBilling: false,
|
|
419
|
+
isUnknown: false,
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
label: "license not read yet (unknown)",
|
|
423
|
+
install: (): FakeEnterpriseModule => {
|
|
424
|
+
return installFakeEnterpriseModule({ snapshot: null });
|
|
425
|
+
},
|
|
426
|
+
isActiveWithoutBilling: true,
|
|
427
|
+
isUnknown: true,
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
label: "no license, trial start not recorded yet (unknown)",
|
|
431
|
+
install: (): FakeEnterpriseModule => {
|
|
432
|
+
return installFakeEnterpriseModule({
|
|
433
|
+
snapshot: createLicenseSnapshotWithStatus("missing", {
|
|
434
|
+
graceEndsAt: undefined,
|
|
435
|
+
}),
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
isActiveWithoutBilling: true,
|
|
439
|
+
isUnknown: true,
|
|
440
|
+
},
|
|
441
|
+
{
|
|
442
|
+
label: "license snapshot unreadable (unknown)",
|
|
443
|
+
install: (): FakeEnterpriseModule => {
|
|
444
|
+
const fake: FakeEnterpriseModule = installFakeEnterpriseModule();
|
|
445
|
+
fake.licensing.getCachedSnapshotError = new Error(
|
|
446
|
+
"the cached snapshot cannot be read",
|
|
447
|
+
);
|
|
448
|
+
return fake;
|
|
449
|
+
},
|
|
450
|
+
isActiveWithoutBilling: true,
|
|
451
|
+
isUnknown: true,
|
|
452
|
+
},
|
|
453
|
+
];
|
|
454
|
+
|
|
455
|
+
/*
|
|
456
|
+
* One deployment state: billing, edition and license together, with whether
|
|
457
|
+
* the runtime features run in it. apply() pins BOTH billing and the edition,
|
|
458
|
+
* so a suite that loops over these needs nothing else (it must still mock
|
|
459
|
+
* EnvironmentConfig with TestBillingFlag.withLiveBillingFlag).
|
|
460
|
+
*/
|
|
461
|
+
export interface EditionStateCase {
|
|
462
|
+
label: string;
|
|
463
|
+
billing: boolean;
|
|
464
|
+
isLoaded: boolean;
|
|
465
|
+
// Whether SSO, SCIM and audit logging run in this state.
|
|
466
|
+
isActive: boolean;
|
|
467
|
+
apply: () => FakeEnterpriseModule | null;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
export const createEditionStateCases: () => Array<EditionStateCase> =
|
|
471
|
+
(): Array<EditionStateCase> => {
|
|
472
|
+
const cases: Array<EditionStateCase> = [];
|
|
473
|
+
|
|
474
|
+
for (const billing of [false, true]) {
|
|
475
|
+
cases.push({
|
|
476
|
+
label: `billing=${billing}, Community Edition`,
|
|
477
|
+
billing,
|
|
478
|
+
isLoaded: false,
|
|
479
|
+
isActive: false,
|
|
480
|
+
apply: (): null => {
|
|
481
|
+
setTestBillingEnabled(billing);
|
|
482
|
+
uninstallEnterpriseModule();
|
|
483
|
+
return null;
|
|
484
|
+
},
|
|
485
|
+
});
|
|
486
|
+
|
|
487
|
+
for (const licenseState of LICENSE_STATE_CASES) {
|
|
488
|
+
cases.push({
|
|
489
|
+
label: `billing=${billing}, Enterprise Edition, ${licenseState.label}`,
|
|
490
|
+
billing,
|
|
491
|
+
isLoaded: true,
|
|
492
|
+
isActive: billing || licenseState.isActiveWithoutBilling,
|
|
493
|
+
apply: (): FakeEnterpriseModule => {
|
|
494
|
+
setTestBillingEnabled(billing);
|
|
495
|
+
return licenseState.install();
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
return cases;
|
|
502
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* A live, per-test billing switch for suites that touch edition gating.
|
|
3
|
+
*
|
|
4
|
+
* CI's config.env sets BILLING_ENABLED=true, so a suite that does not pin
|
|
5
|
+
* billing silently tests the SaaS path in CI and the self-hosted path locally.
|
|
6
|
+
* Every suite that exercises EnterpriseEdition (directly or through a gate)
|
|
7
|
+
* must pin BOTH billing and the registered module.
|
|
8
|
+
*
|
|
9
|
+
* This file deliberately imports nothing: it is loaded from inside a hoisted
|
|
10
|
+
* jest.mock factory, before any of the test file's own imports exist.
|
|
11
|
+
*
|
|
12
|
+
* jest.mock("<path>/Server/EnvironmentConfig", () => {
|
|
13
|
+
* const flag: typeof import("<path>/Tests/Server/Enterprise/TestBillingFlag") =
|
|
14
|
+
* jest.requireActual("<path>/Tests/Server/Enterprise/TestBillingFlag") as
|
|
15
|
+
* typeof import("<path>/Tests/Server/Enterprise/TestBillingFlag");
|
|
16
|
+
* return flag.withLiveBillingFlag(
|
|
17
|
+
* jest.requireActual("<path>/Server/EnvironmentConfig") as
|
|
18
|
+
* Record<string, unknown>,
|
|
19
|
+
* );
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* setTestBillingEnabled(false); // in beforeEach, or per test
|
|
23
|
+
*
|
|
24
|
+
* The flag lives on globalThis and the getter reads nothing else, so a module
|
|
25
|
+
* that reads IsBillingEnabled while the mock is being built (some services do,
|
|
26
|
+
* at module scope) sees `false` instead of hitting a temporal-dead-zone error.
|
|
27
|
+
*/
|
|
28
|
+
export const TEST_BILLING_FLAG_KEY: string =
|
|
29
|
+
"__oneUptimeEnterpriseTestIsBillingEnabled";
|
|
30
|
+
|
|
31
|
+
type GlobalFlags = Record<string, unknown>;
|
|
32
|
+
|
|
33
|
+
export const setTestBillingEnabled: (value: boolean) => void = (
|
|
34
|
+
value: boolean,
|
|
35
|
+
): void => {
|
|
36
|
+
(globalThis as unknown as GlobalFlags)[TEST_BILLING_FLAG_KEY] = value;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export const isTestBillingEnabled: () => boolean = (): boolean => {
|
|
40
|
+
return (globalThis as unknown as GlobalFlags)[TEST_BILLING_FLAG_KEY] === true;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/*
|
|
44
|
+
* A copy of the real EnvironmentConfig exports whose IsBillingEnabled is a live
|
|
45
|
+
* getter over the flag above. A getter rather than a value, because object
|
|
46
|
+
* spread would freeze it at import time.
|
|
47
|
+
*/
|
|
48
|
+
export const withLiveBillingFlag: (
|
|
49
|
+
actualEnvironmentConfig: Record<string, unknown>,
|
|
50
|
+
) => Record<string, unknown> = (
|
|
51
|
+
actualEnvironmentConfig: Record<string, unknown>,
|
|
52
|
+
): Record<string, unknown> => {
|
|
53
|
+
const mocked: Record<string, unknown> = {
|
|
54
|
+
...actualEnvironmentConfig,
|
|
55
|
+
__esModule: true,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
Object.defineProperty(mocked, "IsBillingEnabled", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
get: (): boolean => {
|
|
61
|
+
return (
|
|
62
|
+
(globalThis as unknown as GlobalFlags)[
|
|
63
|
+
"__oneUptimeEnterpriseTestIsBillingEnabled"
|
|
64
|
+
] === true
|
|
65
|
+
);
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return mocked;
|
|
70
|
+
};
|