@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,254 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import {
|
|
3
|
+
afterEach,
|
|
4
|
+
beforeEach,
|
|
5
|
+
describe,
|
|
6
|
+
expect,
|
|
7
|
+
jest,
|
|
8
|
+
test,
|
|
9
|
+
} from "@jest/globals";
|
|
10
|
+
import { act, cleanup, render } from "@testing-library/react";
|
|
11
|
+
import React, { ReactElement } from "react";
|
|
12
|
+
import fs from "fs";
|
|
13
|
+
import path from "path";
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* The core Header (Admin Dashboard) and Footer (Dashboard) hand their edition
|
|
17
|
+
* pill the Enterprise plugin's LicenseManager, read from the plugin door
|
|
18
|
+
* inside render. With the Community stub - which is what this jest config
|
|
19
|
+
* resolves the plugin specifiers to - they hand it nothing, and the pill
|
|
20
|
+
* shows the license status only.
|
|
21
|
+
*
|
|
22
|
+
* EditionLabel is replaced with a probe that records the prop, and each door
|
|
23
|
+
* with one that returns whatever the test sets (the real Community stub by
|
|
24
|
+
* default). This is core, and must pass with ee/ deleted.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
const receivedManagers: Array<unknown> = [];
|
|
28
|
+
|
|
29
|
+
jest.mock("../../../UI/Components/EditionLabel/EditionLabel", () => {
|
|
30
|
+
return {
|
|
31
|
+
__esModule: true,
|
|
32
|
+
default: (props: { licenseManager?: unknown }): ReactElement => {
|
|
33
|
+
receivedManagers.push(props.licenseManager);
|
|
34
|
+
|
|
35
|
+
return <span data-testid="edition-label" />;
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
jest.mock("../../../UI/Images/logos/OneUptimeSVG/3-transparent.svg", () => {
|
|
41
|
+
return "data:image/svg+xml;base64,bG9nbw==";
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
jest.mock("react-i18next", () => {
|
|
45
|
+
return {
|
|
46
|
+
useTranslation: () => {
|
|
47
|
+
return {
|
|
48
|
+
t: (key: string): string => {
|
|
49
|
+
return key;
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
jest.mock("../../../UI/Utils/User", () => {
|
|
57
|
+
return {
|
|
58
|
+
__esModule: true,
|
|
59
|
+
default: {
|
|
60
|
+
isMasterAdmin: (): boolean => {
|
|
61
|
+
return true;
|
|
62
|
+
},
|
|
63
|
+
isLoggedIn: (): boolean => {
|
|
64
|
+
return true;
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
jest.mock(
|
|
71
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/LanguageSwitcher/LanguageSwitcher",
|
|
72
|
+
() => {
|
|
73
|
+
return {
|
|
74
|
+
__esModule: true,
|
|
75
|
+
default: (): ReactElement => {
|
|
76
|
+
return <span data-testid="language-switcher" />;
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
let mockAdminPlugins: Record<string, unknown> = {};
|
|
83
|
+
let mockDashboardPlugins: Record<string, unknown> = {};
|
|
84
|
+
let adminDoorReads: number = 0;
|
|
85
|
+
let dashboardDoorReads: number = 0;
|
|
86
|
+
|
|
87
|
+
jest.mock(
|
|
88
|
+
"../../../../App/FeatureSet/AdminDashboard/src/Enterprise/Plugins",
|
|
89
|
+
() => {
|
|
90
|
+
return {
|
|
91
|
+
getAdminDashboardPlugins: (): Record<string, unknown> => {
|
|
92
|
+
adminDoorReads += 1;
|
|
93
|
+
return mockAdminPlugins;
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
jest.mock("../../../../App/FeatureSet/Dashboard/src/Enterprise/Plugins", () => {
|
|
100
|
+
return {
|
|
101
|
+
getDashboardPlugins: (): Record<string, unknown> => {
|
|
102
|
+
dashboardDoorReads += 1;
|
|
103
|
+
return mockDashboardPlugins;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
import AdminCommunityPlugins from "../../../../App/FeatureSet/AdminDashboard/src/Enterprise/CommunityPlugins";
|
|
109
|
+
import DashboardCommunityPlugins from "../../../../App/FeatureSet/Dashboard/src/Enterprise/CommunityPlugins";
|
|
110
|
+
import AdminDashboardHeader from "../../../../App/FeatureSet/AdminDashboard/src/Components/Header/Header";
|
|
111
|
+
import DashboardFooter from "../../../../App/FeatureSet/Dashboard/src/Components/Footer/Footer";
|
|
112
|
+
import { ADMIN_DASHBOARD_ENTERPRISE_PLUGIN_KEYS } from "../../../../App/FeatureSet/AdminDashboard/src/Enterprise/EnterprisePlugins";
|
|
113
|
+
import { DASHBOARD_ENTERPRISE_PLUGIN_KEYS } from "../../../../App/FeatureSet/Dashboard/src/Enterprise/EnterprisePlugins";
|
|
114
|
+
|
|
115
|
+
const FakeAdminLicenseManager: () => ReactElement = (): ReactElement => {
|
|
116
|
+
return <span />;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const FakeDashboardLicenseManager: () => ReactElement = (): ReactElement => {
|
|
120
|
+
return <span />;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const APP_DIR: string = path.resolve(__dirname, "..", "..", "..", "..", "App");
|
|
124
|
+
|
|
125
|
+
interface Caller {
|
|
126
|
+
name: string;
|
|
127
|
+
file: string;
|
|
128
|
+
render: () => void;
|
|
129
|
+
setPlugins: (plugins: Record<string, unknown>) => void;
|
|
130
|
+
communityStub: Record<string, unknown>;
|
|
131
|
+
fake: () => ReactElement;
|
|
132
|
+
doorReads: () => number;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const CALLERS: Array<Caller> = [
|
|
136
|
+
{
|
|
137
|
+
name: "the Admin Dashboard header",
|
|
138
|
+
file: path.join(
|
|
139
|
+
APP_DIR,
|
|
140
|
+
"FeatureSet/AdminDashboard/src/Components/Header/Header.tsx",
|
|
141
|
+
),
|
|
142
|
+
render: (): void => {
|
|
143
|
+
render(<AdminDashboardHeader />);
|
|
144
|
+
},
|
|
145
|
+
setPlugins: (plugins: Record<string, unknown>): void => {
|
|
146
|
+
mockAdminPlugins = plugins;
|
|
147
|
+
},
|
|
148
|
+
communityStub: AdminCommunityPlugins as Record<string, unknown>,
|
|
149
|
+
fake: FakeAdminLicenseManager,
|
|
150
|
+
doorReads: (): number => {
|
|
151
|
+
return adminDoorReads;
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "the Dashboard footer",
|
|
156
|
+
file: path.join(
|
|
157
|
+
APP_DIR,
|
|
158
|
+
"FeatureSet/Dashboard/src/Components/Footer/Footer.tsx",
|
|
159
|
+
),
|
|
160
|
+
render: (): void => {
|
|
161
|
+
render(<DashboardFooter />);
|
|
162
|
+
},
|
|
163
|
+
setPlugins: (plugins: Record<string, unknown>): void => {
|
|
164
|
+
mockDashboardPlugins = plugins;
|
|
165
|
+
},
|
|
166
|
+
communityStub: DashboardCommunityPlugins as Record<string, unknown>,
|
|
167
|
+
fake: FakeDashboardLicenseManager,
|
|
168
|
+
doorReads: (): number => {
|
|
169
|
+
return dashboardDoorReads;
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
|
|
174
|
+
beforeEach(() => {
|
|
175
|
+
receivedManagers.length = 0;
|
|
176
|
+
adminDoorReads = 0;
|
|
177
|
+
dashboardDoorReads = 0;
|
|
178
|
+
mockAdminPlugins = AdminCommunityPlugins as Record<string, unknown>;
|
|
179
|
+
mockDashboardPlugins = DashboardCommunityPlugins as Record<string, unknown>;
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
afterEach(() => {
|
|
183
|
+
cleanup();
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
describe("LicenseManager is a key of both plugin contracts", () => {
|
|
187
|
+
test("the Admin Dashboard's", () => {
|
|
188
|
+
expect(ADMIN_DASHBOARD_ENTERPRISE_PLUGIN_KEYS).toContain("LicenseManager");
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
test("the Dashboard's", () => {
|
|
192
|
+
expect(DASHBOARD_ENTERPRISE_PLUGIN_KEYS).toContain("LicenseManager");
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test("and neither Community stub provides it", () => {
|
|
196
|
+
expect(
|
|
197
|
+
(AdminCommunityPlugins as Record<string, unknown>)["LicenseManager"],
|
|
198
|
+
).toBeUndefined();
|
|
199
|
+
expect(
|
|
200
|
+
(DashboardCommunityPlugins as Record<string, unknown>)["LicenseManager"],
|
|
201
|
+
).toBeUndefined();
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
describe.each(CALLERS)("$name", (caller: Caller) => {
|
|
206
|
+
test("passes the plugin's LicenseManager to the edition pill", async () => {
|
|
207
|
+
caller.setPlugins({ LicenseManager: caller.fake });
|
|
208
|
+
|
|
209
|
+
await act(async () => {
|
|
210
|
+
caller.render();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
expect(receivedManagers).toContain(caller.fake);
|
|
214
|
+
expect(
|
|
215
|
+
receivedManagers.every((value: unknown): boolean => {
|
|
216
|
+
return value === caller.fake;
|
|
217
|
+
}),
|
|
218
|
+
).toBe(true);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
test("passes nothing with the Community stub (negative control)", async () => {
|
|
222
|
+
caller.setPlugins(caller.communityStub);
|
|
223
|
+
|
|
224
|
+
await act(async () => {
|
|
225
|
+
caller.render();
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
expect(receivedManagers.length).toBeGreaterThan(0);
|
|
229
|
+
expect(
|
|
230
|
+
receivedManagers.every((value: unknown): boolean => {
|
|
231
|
+
return value === undefined;
|
|
232
|
+
}),
|
|
233
|
+
).toBe(true);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
test("reads the door while rendering, not when the module loads", async () => {
|
|
237
|
+
// The module was imported above; no render has happened yet.
|
|
238
|
+
expect(caller.doorReads()).toBe(0);
|
|
239
|
+
|
|
240
|
+
await act(async () => {
|
|
241
|
+
caller.render();
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
expect(caller.doorReads()).toBeGreaterThan(0);
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
test("names the prop in its source, so the wiring is not a coincidence", () => {
|
|
248
|
+
const source: string = fs.readFileSync(caller.file, "utf8");
|
|
249
|
+
|
|
250
|
+
expect(source).toMatch(
|
|
251
|
+
/licenseManager=\{get(AdminDashboard|Dashboard)Plugins\(\)\.LicenseManager\}/,
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
@@ -14,23 +14,22 @@ import React from "react";
|
|
|
14
14
|
import { beforeEach, describe, expect, it } from "@jest/globals";
|
|
15
15
|
|
|
16
16
|
/*
|
|
17
|
-
*
|
|
17
|
+
* What EditionLabel on its own still does around the license GET and the seat
|
|
18
|
+
* figures, with no license manager (the login page, a build without the
|
|
19
|
+
* Enterprise plugin). This suite must pass with ee/ deleted.
|
|
18
20
|
*
|
|
19
|
-
* The
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* valid. This button is the answer, so these tests pin that it:
|
|
21
|
+
* The "Refresh license" button this suite used to cover - offered only to a
|
|
22
|
+
* master admin, sending no key, showing the new limit, reporting a failure -
|
|
23
|
+
* is the Enterprise plugin's license manager now, together with the seat
|
|
24
|
+
* card. ee/Tests/UI/License/LicenseManagerRefresh.test.tsx runs every one of
|
|
25
|
+
* this suite's original tests against EditionLabel with that manager. What
|
|
26
|
+
* stays here:
|
|
26
27
|
*
|
|
27
|
-
* -
|
|
28
|
-
*
|
|
29
|
-
* -
|
|
30
|
-
*
|
|
31
|
-
* -
|
|
32
|
-
* - says so when it fails, rather than looking like it worked. The whole
|
|
33
|
-
* reason it was pressed is a belief that the stored terms are stale.
|
|
28
|
+
* - the signedIn flag on the license GET;
|
|
29
|
+
* - a non-admin is told who can activate the license;
|
|
30
|
+
* - EditionLabel never offers a refresh, a key change or the seat card by
|
|
31
|
+
* itself, and writes nothing;
|
|
32
|
+
* - the pill still reads the seat figures, enforced usage first.
|
|
34
33
|
*/
|
|
35
34
|
|
|
36
35
|
let isEnterpriseEdition: boolean = true;
|
|
@@ -137,7 +136,14 @@ const licensePayload: LicensePayloadFunction = (
|
|
|
137
136
|
expiresAt: EXPIRES_AT,
|
|
138
137
|
licenseKey: "acme-license-key",
|
|
139
138
|
token: "signed.jwt.token",
|
|
139
|
+
edition: "enterprise",
|
|
140
|
+
status: "valid",
|
|
141
|
+
verification: "verified",
|
|
142
|
+
graceReason: null,
|
|
143
|
+
graceEndsAt: null,
|
|
144
|
+
activationMode: "online",
|
|
140
145
|
licenseValid: true,
|
|
146
|
+
isEvaluation: false,
|
|
141
147
|
isEvaluationLicense: false,
|
|
142
148
|
userLimit: 50,
|
|
143
149
|
currentUserCount: 50,
|
|
@@ -245,7 +251,14 @@ describe("EditionLabel - telling the license route we expect to be signed in", (
|
|
|
245
251
|
});
|
|
246
252
|
});
|
|
247
253
|
|
|
248
|
-
|
|
254
|
+
/*
|
|
255
|
+
* Refreshing the license, changing its key and the seat card are the
|
|
256
|
+
* Enterprise plugin's license manager now (ee/Tests/UI/License runs this
|
|
257
|
+
* suite's original refresh and seat tests against it). What EditionLabel
|
|
258
|
+
* still owns is below: telling a non-admin who can act, reading the seat
|
|
259
|
+
* figures for the pill, and never writing the license itself.
|
|
260
|
+
*/
|
|
261
|
+
describe("EditionLabel - the license, read-only", () => {
|
|
249
262
|
beforeEach(() => {
|
|
250
263
|
fetchCalls.length = 0;
|
|
251
264
|
isEnterpriseEdition = true;
|
|
@@ -257,39 +270,12 @@ describe("EditionLabel - refreshing the license", () => {
|
|
|
257
270
|
};
|
|
258
271
|
});
|
|
259
272
|
|
|
260
|
-
it("offers the button to a master admin once the license is valid", async () => {
|
|
261
|
-
await openDialog();
|
|
262
|
-
|
|
263
|
-
expect(
|
|
264
|
-
await screen.findByTestId("refresh-enterprise-license"),
|
|
265
|
-
).toBeInTheDocument();
|
|
266
|
-
});
|
|
267
|
-
|
|
268
|
-
/*
|
|
269
|
-
* The server requires a master admin on both license writes, so offering the
|
|
270
|
-
* button to anyone else would only ever produce a permission error.
|
|
271
|
-
*/
|
|
272
|
-
it("does not offer the button to a user who is not a master admin", async () => {
|
|
273
|
-
isMasterAdmin = false;
|
|
274
|
-
|
|
275
|
-
await openDialog();
|
|
276
|
-
|
|
277
|
-
await waitFor(() => {
|
|
278
|
-
expect(screen.getByText("Licensed seats")).toBeInTheDocument();
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
expect(
|
|
282
|
-
screen.queryByTestId("refresh-enterprise-license"),
|
|
283
|
-
).not.toBeInTheDocument();
|
|
284
|
-
expect(screen.queryByText("Change license key")).not.toBeInTheDocument();
|
|
285
|
-
});
|
|
286
|
-
|
|
287
273
|
it("asks a non-admin to find one when the license needs activating", async () => {
|
|
288
274
|
isMasterAdmin = false;
|
|
289
275
|
respond = (): HTTPResponse<JSONObject> => {
|
|
290
276
|
return new HTTPResponse<JSONObject>(
|
|
291
277
|
200,
|
|
292
|
-
licensePayload({ licenseValid: false, token: null }),
|
|
278
|
+
licensePayload({ licenseValid: false, token: null, status: "missing" }),
|
|
293
279
|
{},
|
|
294
280
|
);
|
|
295
281
|
};
|
|
@@ -304,95 +290,28 @@ describe("EditionLabel - refreshing the license", () => {
|
|
|
304
290
|
).not.toBeInTheDocument();
|
|
305
291
|
});
|
|
306
292
|
|
|
307
|
-
|
|
308
|
-
* No license key in the body. A refresh that carried one would be an
|
|
309
|
-
* activation with a friendlier name.
|
|
310
|
-
*/
|
|
311
|
-
it("refreshes the stored license without sending a key", async () => {
|
|
312
|
-
await openDialog();
|
|
313
|
-
|
|
314
|
-
fireEvent.click(await screen.findByTestId("refresh-enterprise-license"));
|
|
315
|
-
|
|
316
|
-
await waitFor(() => {
|
|
317
|
-
expect(
|
|
318
|
-
fetchCalls.some((call: FetchCall): boolean => {
|
|
319
|
-
return call.url.includes("/global-config/license/refresh");
|
|
320
|
-
}),
|
|
321
|
-
).toBe(true);
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
const refreshCall: FetchCall = fetchCalls.find(
|
|
325
|
-
(call: FetchCall): boolean => {
|
|
326
|
-
return call.url.includes("/global-config/license/refresh");
|
|
327
|
-
},
|
|
328
|
-
) as FetchCall;
|
|
329
|
-
|
|
330
|
-
expect(refreshCall.method).toBe("POST");
|
|
331
|
-
expect(refreshCall.data).toBeUndefined();
|
|
332
|
-
});
|
|
333
|
-
|
|
334
|
-
it("shows the new seat limit after a refresh", async () => {
|
|
293
|
+
it("offers no refresh, key change or seat card on its own, even to a master admin", async () => {
|
|
335
294
|
await openDialog();
|
|
336
295
|
|
|
337
|
-
await screen.
|
|
338
|
-
|
|
339
|
-
// Ten more seats bought on oneuptime.com since the page loaded.
|
|
340
|
-
respond = (): HTTPResponse<JSONObject> => {
|
|
341
|
-
return new HTTPResponse<JSONObject>(
|
|
342
|
-
200,
|
|
343
|
-
licensePayload({
|
|
344
|
-
userLimit: 60,
|
|
345
|
-
seatsRemaining: 10,
|
|
346
|
-
canAddMoreUsers: true,
|
|
347
|
-
}),
|
|
348
|
-
{},
|
|
349
|
-
);
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
fireEvent.click(screen.getByTestId("refresh-enterprise-license"));
|
|
353
|
-
|
|
354
|
-
expect(
|
|
355
|
-
await screen.findByText(/License refreshed from OneUptime/),
|
|
356
|
-
).toBeInTheDocument();
|
|
357
|
-
expect(await screen.findByText(/60 seats/)).toBeInTheDocument();
|
|
358
|
-
});
|
|
359
|
-
|
|
360
|
-
/*
|
|
361
|
-
* A refresh that quietly kept the old terms and said nothing would be worse
|
|
362
|
-
* than no button at all: the administrator pressed it precisely because they
|
|
363
|
-
* think the stored terms are wrong.
|
|
364
|
-
*/
|
|
365
|
-
it("reports a failed refresh instead of looking like it worked", async () => {
|
|
366
|
-
await openDialog();
|
|
367
|
-
|
|
368
|
-
await screen.findByTestId("refresh-enterprise-license");
|
|
369
|
-
|
|
370
|
-
respond = (
|
|
371
|
-
call: FetchCall,
|
|
372
|
-
): HTTPResponse<JSONObject> | HTTPErrorResponse => {
|
|
373
|
-
if (call.url.includes("/refresh")) {
|
|
374
|
-
return new HTTPErrorResponse(
|
|
375
|
-
500,
|
|
376
|
-
{ message: "Could not reach OneUptime." },
|
|
377
|
-
{},
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return new HTTPResponse<JSONObject>(200, licensePayload(), {});
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
fireEvent.click(screen.getByTestId("refresh-enterprise-license"));
|
|
385
|
-
|
|
386
|
-
expect(
|
|
387
|
-
await screen.findByText(/Could not reach OneUptime/),
|
|
388
|
-
).toBeInTheDocument();
|
|
296
|
+
expect(await screen.findByText("Licensed to")).toBeInTheDocument();
|
|
389
297
|
expect(
|
|
390
|
-
screen.
|
|
298
|
+
screen.queryByTestId("refresh-enterprise-license"),
|
|
391
299
|
).not.toBeInTheDocument();
|
|
300
|
+
expect(screen.queryByText("Change license key")).not.toBeInTheDocument();
|
|
301
|
+
expect(screen.queryByText("Licensed seats")).not.toBeInTheDocument();
|
|
302
|
+
expect(
|
|
303
|
+
fetchCalls.filter((call: FetchCall): boolean => {
|
|
304
|
+
return call.method !== "GET" || call.url.includes("/refresh");
|
|
305
|
+
}),
|
|
306
|
+
).toEqual([]);
|
|
392
307
|
});
|
|
393
308
|
});
|
|
394
309
|
|
|
395
|
-
|
|
310
|
+
/*
|
|
311
|
+
* The pill still reads the seat figures: an exhausted limit is what a master
|
|
312
|
+
* admin has to see on every page, not only inside the dialog.
|
|
313
|
+
*/
|
|
314
|
+
describe("EditionLabel - what an exhausted seat limit looks like on the pill", () => {
|
|
396
315
|
beforeEach(() => {
|
|
397
316
|
fetchCalls.length = 0;
|
|
398
317
|
isEnterpriseEdition = true;
|
|
@@ -404,64 +323,62 @@ describe("EditionLabel - what an exhausted seat limit looks like", () => {
|
|
|
404
323
|
};
|
|
405
324
|
});
|
|
406
325
|
|
|
326
|
+
const pillNamed: (name: string) => Promise<void> = async (
|
|
327
|
+
name: string,
|
|
328
|
+
): Promise<void> => {
|
|
329
|
+
render(<EditionLabel />);
|
|
330
|
+
|
|
331
|
+
await waitFor(() => {
|
|
332
|
+
expect(
|
|
333
|
+
screen.getByRole("button", { name: /Enterprise Edition/ }),
|
|
334
|
+
).toHaveAccessibleName(name);
|
|
335
|
+
});
|
|
336
|
+
};
|
|
337
|
+
|
|
407
338
|
/*
|
|
408
|
-
* 50 of 50 is not over the limit,
|
|
409
|
-
*
|
|
410
|
-
* limit is enforced, being exactly on it is the thing the administrator has
|
|
411
|
-
* to act on.
|
|
339
|
+
* 50 of 50 is not over the limit, but once the limit is enforced nobody
|
|
340
|
+
* else gets in: a breach, not an amber nudge.
|
|
412
341
|
*/
|
|
413
|
-
it("treats a full license as a breach
|
|
414
|
-
await
|
|
342
|
+
it("treats a full enforced license as a breach, on the pill and the dialog badge", async () => {
|
|
343
|
+
await pillNamed("Enterprise Edition, User limit exceeded");
|
|
415
344
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
).toBeInTheDocument();
|
|
419
|
-
expect(screen.getByText("Limit exceeded")).toBeInTheDocument();
|
|
345
|
+
fireEvent.click(screen.getByRole("button", { name: /Enterprise Edition/ }));
|
|
346
|
+
|
|
347
|
+
expect(await screen.findByText("Seat limit exceeded")).toBeInTheDocument();
|
|
420
348
|
});
|
|
421
349
|
|
|
422
|
-
it("
|
|
423
|
-
|
|
350
|
+
it("measures against the live enforced usage rather than the last reported count", async () => {
|
|
351
|
+
respond = (): HTTPResponse<JSONObject> => {
|
|
352
|
+
return new HTTPResponse<JSONObject>(
|
|
353
|
+
200,
|
|
354
|
+
licensePayload({ currentUserCount: 40, seatsInUse: 50 }),
|
|
355
|
+
{},
|
|
356
|
+
);
|
|
357
|
+
};
|
|
424
358
|
|
|
425
|
-
|
|
426
|
-
await screen.findByText(
|
|
427
|
-
/New users cannot be invited, signed up or provisioned/,
|
|
428
|
-
),
|
|
429
|
-
).toBeInTheDocument();
|
|
359
|
+
await pillNamed("Enterprise Edition, User limit exceeded");
|
|
430
360
|
});
|
|
431
361
|
|
|
432
|
-
|
|
433
|
-
* seatsInUse is computed from the live User table; currentUserCount is the
|
|
434
|
-
* licence-wide figure oneuptime.com last computed, up to a day ago. The card
|
|
435
|
-
* has to show the one enforcement uses, or it contradicts the invitation that
|
|
436
|
-
* just bounced.
|
|
437
|
-
*/
|
|
438
|
-
it("shows the live enforced usage rather than the last reported count", async () => {
|
|
362
|
+
it("says nothing is wrong when the server reports no enforcement and seats are free", async () => {
|
|
439
363
|
respond = (): HTTPResponse<JSONObject> => {
|
|
440
364
|
return new HTTPResponse<JSONObject>(
|
|
441
365
|
200,
|
|
442
366
|
licensePayload({
|
|
443
|
-
|
|
444
|
-
seatsInUse:
|
|
367
|
+
isSeatLimitEnforced: false,
|
|
368
|
+
seatsInUse: null,
|
|
369
|
+
seatsRemaining: null,
|
|
370
|
+
canAddMoreUsers: true,
|
|
371
|
+
currentUserCount: 10,
|
|
372
|
+
userLimit: 50,
|
|
445
373
|
}),
|
|
446
374
|
{},
|
|
447
375
|
);
|
|
448
376
|
};
|
|
449
377
|
|
|
450
|
-
await
|
|
451
|
-
|
|
452
|
-
await waitFor(() => {
|
|
453
|
-
expect(screen.getByText("Licensed seats")).toBeInTheDocument();
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
expect(screen.getByText("50")).toBeInTheDocument();
|
|
457
|
-
expect(screen.queryByText("40")).not.toBeInTheDocument();
|
|
378
|
+
await pillNamed("Enterprise Edition, View details");
|
|
458
379
|
});
|
|
459
380
|
|
|
460
|
-
|
|
461
|
-
* A build or a deployment that reports no enforcement must not be rendered as
|
|
462
|
-
* one that is refusing users.
|
|
463
|
-
*/
|
|
464
|
-
it("says nothing about enforcement when the server reports none", async () => {
|
|
381
|
+
it("nudges when seats are nearly full", async () => {
|
|
465
382
|
respond = (): HTTPResponse<JSONObject> => {
|
|
466
383
|
return new HTTPResponse<JSONObject>(
|
|
467
384
|
200,
|
|
@@ -470,24 +387,13 @@ describe("EditionLabel - what an exhausted seat limit looks like", () => {
|
|
|
470
387
|
seatsInUse: null,
|
|
471
388
|
seatsRemaining: null,
|
|
472
389
|
canAddMoreUsers: true,
|
|
473
|
-
currentUserCount:
|
|
390
|
+
currentUserCount: 46,
|
|
474
391
|
userLimit: 50,
|
|
475
392
|
}),
|
|
476
393
|
{},
|
|
477
394
|
);
|
|
478
395
|
};
|
|
479
396
|
|
|
480
|
-
await
|
|
481
|
-
|
|
482
|
-
await waitFor(() => {
|
|
483
|
-
expect(screen.getByText("Licensed seats")).toBeInTheDocument();
|
|
484
|
-
});
|
|
485
|
-
|
|
486
|
-
expect(
|
|
487
|
-
screen.queryByText(/New users cannot be invited/),
|
|
488
|
-
).not.toBeInTheDocument();
|
|
489
|
-
expect(
|
|
490
|
-
screen.queryByText(/This installation enforces the seat limit/),
|
|
491
|
-
).not.toBeInTheDocument();
|
|
397
|
+
await pillNamed("Enterprise Edition, Seats nearly full");
|
|
492
398
|
});
|
|
493
399
|
});
|