@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,319 @@
|
|
|
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 { cleanup, render, screen } from "@testing-library/react";
|
|
11
|
+
import React, { FunctionComponent, ReactElement } from "react";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* The six identity pages the Dashboard routes to - Settings > SSO / OIDC /
|
|
15
|
+
* SCIM and Status page > SSO / OIDC / SCIM - are Enterprise Edition screens
|
|
16
|
+
* (ee/Dashboard/SSO). Core keeps a shell at each page's original path, so the
|
|
17
|
+
* route files and the lazy page map never changed: the shell renders the
|
|
18
|
+
* Enterprise screen when the project may use the feature AND the bundle
|
|
19
|
+
* includes it, and the upsell card the page used to show otherwise.
|
|
20
|
+
*
|
|
21
|
+
* "@oneuptime/ee-dashboard" is replaced by a plugin object the tests fill in,
|
|
22
|
+
* standing in for the Enterprise bundle; left empty it is the Community
|
|
23
|
+
* bundle. Billing, the edition and the plan are pinned in every test: CI's
|
|
24
|
+
* config.env sets BILLING_ENABLED=true.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
let billingEnabledForTest: boolean = false;
|
|
28
|
+
let enterpriseEditionForTest: boolean = false;
|
|
29
|
+
let currentPlanForTest: string | null = null;
|
|
30
|
+
|
|
31
|
+
const CLOUD_PLAN_ENV: Record<string, string> = {
|
|
32
|
+
SUBSCRIPTION_PLAN_BASIC: "Free,priceMonthlyId1,priceYearlyId1,0,0,1,0",
|
|
33
|
+
SUBSCRIPTION_PLAN_GROWTH: "Growth,priceMonthlyId2,priceYearlyId2,0,0,2,14",
|
|
34
|
+
SUBSCRIPTION_PLAN_SCALE: "Scale,priceMonthlyId3,priceYearlyId3,0,0,3,0",
|
|
35
|
+
SUBSCRIPTION_PLAN_ENTERPRISE:
|
|
36
|
+
"Enterprise,priceMonthlyId4,priceYearlyId4,-1,-1,4,14",
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
jest.mock("../../../UI/Config", () => {
|
|
40
|
+
const actual: Record<string, unknown> = jest.requireActual(
|
|
41
|
+
"../../../UI/Config",
|
|
42
|
+
) as Record<string, unknown>;
|
|
43
|
+
|
|
44
|
+
const mocked: Record<string, unknown> = { ...actual };
|
|
45
|
+
|
|
46
|
+
Object.defineProperty(mocked, "BILLING_ENABLED", {
|
|
47
|
+
get: (): boolean => {
|
|
48
|
+
return billingEnabledForTest;
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
Object.defineProperty(mocked, "IS_ENTERPRISE_EDITION", {
|
|
53
|
+
get: (): boolean => {
|
|
54
|
+
return enterpriseEditionForTest;
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
mocked["getAllEnvVars"] = (): Record<string, string> => {
|
|
59
|
+
return CLOUD_PLAN_ENV;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
return mocked;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
jest.mock("../../../UI/Utils/Project", () => {
|
|
66
|
+
const actual: Record<string, any> = jest.requireActual(
|
|
67
|
+
"../../../UI/Utils/Project",
|
|
68
|
+
) as Record<string, any>;
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
__esModule: true,
|
|
72
|
+
...actual,
|
|
73
|
+
default: {
|
|
74
|
+
...actual["default"],
|
|
75
|
+
getCurrentPlan: (): string | null => {
|
|
76
|
+
return currentPlanForTest;
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/*
|
|
83
|
+
* What getDashboardPlugins() returns in this suite. The shells read it on
|
|
84
|
+
* every render, so each test fills it in after the shells were imported.
|
|
85
|
+
*/
|
|
86
|
+
const mockEnterprisePlugins: Record<string, unknown> = {};
|
|
87
|
+
|
|
88
|
+
jest.mock("@oneuptime/ee-dashboard", () => {
|
|
89
|
+
return { __esModule: true, default: mockEnterprisePlugins };
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
import SettingsOIDC from "../../../../App/FeatureSet/Dashboard/src/Pages/Settings/OIDC";
|
|
93
|
+
import SettingsSCIM from "../../../../App/FeatureSet/Dashboard/src/Pages/Settings/SCIM";
|
|
94
|
+
import SettingsSSO from "../../../../App/FeatureSet/Dashboard/src/Pages/Settings/SSO";
|
|
95
|
+
import StatusPageViewOIDC from "../../../../App/FeatureSet/Dashboard/src/Pages/StatusPages/View/OIDC";
|
|
96
|
+
import StatusPageViewSCIM from "../../../../App/FeatureSet/Dashboard/src/Pages/StatusPages/View/SCIM";
|
|
97
|
+
import StatusPageViewSSO from "../../../../App/FeatureSet/Dashboard/src/Pages/StatusPages/View/SSO";
|
|
98
|
+
import PageComponentProps from "../../../../App/FeatureSet/Dashboard/src/Pages/PageComponentProps";
|
|
99
|
+
import { DashboardEnterprisePluginKey } from "../../../../App/FeatureSet/Dashboard/src/Enterprise/EnterprisePlugins";
|
|
100
|
+
import Route from "../../../Types/API/Route";
|
|
101
|
+
import { PlanType } from "../../../Types/Billing/SubscriptionPlan";
|
|
102
|
+
|
|
103
|
+
interface ShellCase {
|
|
104
|
+
name: string;
|
|
105
|
+
Shell: FunctionComponent<PageComponentProps>;
|
|
106
|
+
pluginKey: DashboardEnterprisePluginKey;
|
|
107
|
+
// The upsell copy the page showed before it moved to ee/.
|
|
108
|
+
upsellTitle: string;
|
|
109
|
+
featureName: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const SHELLS: Array<ShellCase> = [
|
|
113
|
+
{
|
|
114
|
+
name: "Settings > SSO",
|
|
115
|
+
Shell: SettingsSSO,
|
|
116
|
+
pluginKey: "SettingsSSO",
|
|
117
|
+
upsellTitle: "Single Sign On (SSO)",
|
|
118
|
+
featureName: "SAML Single Sign On",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Settings > OIDC",
|
|
122
|
+
Shell: SettingsOIDC,
|
|
123
|
+
pluginKey: "SettingsOIDC",
|
|
124
|
+
upsellTitle: "OpenID Connect (OIDC)",
|
|
125
|
+
featureName: "OIDC Single Sign On",
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: "Settings > SCIM",
|
|
129
|
+
Shell: SettingsSCIM,
|
|
130
|
+
pluginKey: "SettingsSCIM",
|
|
131
|
+
upsellTitle: "SCIM User Provisioning",
|
|
132
|
+
featureName: "SCIM User Provisioning",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: "Status page > SSO",
|
|
136
|
+
Shell: StatusPageViewSSO,
|
|
137
|
+
pluginKey: "StatusPageSSO",
|
|
138
|
+
upsellTitle: "Status Page SSO",
|
|
139
|
+
featureName: "Status Page SAML SSO",
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: "Status page > OIDC",
|
|
143
|
+
Shell: StatusPageViewOIDC,
|
|
144
|
+
pluginKey: "StatusPageOIDC",
|
|
145
|
+
upsellTitle: "Status Page OIDC",
|
|
146
|
+
featureName: "Status Page OIDC SSO",
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
name: "Status page > SCIM",
|
|
150
|
+
Shell: StatusPageViewSCIM,
|
|
151
|
+
pluginKey: "StatusPageSCIM",
|
|
152
|
+
upsellTitle: "Status Page SCIM",
|
|
153
|
+
featureName: "Status Page SCIM Provisioning",
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
const PAGE_PROPS: PageComponentProps = {
|
|
158
|
+
pageRoute: new Route("/dashboard/project-id/settings/identity"),
|
|
159
|
+
currentProject: null,
|
|
160
|
+
hasPaymentMethod: true,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
* Stands in for an Enterprise screen: says which plugin key it is and echoes
|
|
165
|
+
* the props the shell handed it.
|
|
166
|
+
*/
|
|
167
|
+
const makeFakeScreen: (
|
|
168
|
+
pluginKey: string,
|
|
169
|
+
) => FunctionComponent<PageComponentProps> = (
|
|
170
|
+
pluginKey: string,
|
|
171
|
+
): FunctionComponent<PageComponentProps> => {
|
|
172
|
+
const FakeScreen: FunctionComponent<PageComponentProps> = (
|
|
173
|
+
props: PageComponentProps,
|
|
174
|
+
): ReactElement => {
|
|
175
|
+
return (
|
|
176
|
+
<div data-testid="enterprise-screen">
|
|
177
|
+
{pluginKey}|{props.pageRoute.toString()}|
|
|
178
|
+
{String(props.hasPaymentMethod)}
|
|
179
|
+
</div>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
return FakeScreen;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
const installPlugins: (keys: Array<DashboardEnterprisePluginKey>) => void = (
|
|
187
|
+
keys: Array<DashboardEnterprisePluginKey>,
|
|
188
|
+
): void => {
|
|
189
|
+
for (const key of keys) {
|
|
190
|
+
mockEnterprisePlugins[key] = makeFakeScreen(key);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const clearPlugins: () => void = (): void => {
|
|
195
|
+
for (const key of Object.keys(mockEnterprisePlugins)) {
|
|
196
|
+
delete mockEnterprisePlugins[key];
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
beforeEach(() => {
|
|
201
|
+
billingEnabledForTest = false;
|
|
202
|
+
enterpriseEditionForTest = false;
|
|
203
|
+
currentPlanForTest = null;
|
|
204
|
+
clearPlugins();
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
afterEach(() => {
|
|
208
|
+
cleanup();
|
|
209
|
+
clearPlugins();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
describe.each(SHELLS)("$name shell", (shell: ShellCase) => {
|
|
213
|
+
test("Community Edition: the upsell card, even when a plugin is present", () => {
|
|
214
|
+
installPlugins([shell.pluginKey]);
|
|
215
|
+
|
|
216
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
217
|
+
|
|
218
|
+
expect(screen.getAllByText(shell.featureName).length).toBeGreaterThan(0);
|
|
219
|
+
expect(screen.getAllByText(shell.upsellTitle).length).toBeGreaterThan(0);
|
|
220
|
+
expect(
|
|
221
|
+
screen.getAllByText("Learn about Enterprise Edition").length,
|
|
222
|
+
).toBeGreaterThan(0);
|
|
223
|
+
expect(screen.queryByTestId("enterprise-screen")).not.toBeInTheDocument();
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test("Enterprise Edition: the Enterprise screen, with the page props", () => {
|
|
227
|
+
enterpriseEditionForTest = true;
|
|
228
|
+
installPlugins([shell.pluginKey]);
|
|
229
|
+
|
|
230
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
231
|
+
|
|
232
|
+
expect(screen.getByTestId("enterprise-screen")).toHaveTextContent(
|
|
233
|
+
`${shell.pluginKey}|/dashboard/project-id/settings/identity|true`,
|
|
234
|
+
);
|
|
235
|
+
expect(screen.queryByText(shell.featureName)).not.toBeInTheDocument();
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
test("Enterprise Edition on a Community bundle: the upsell, pointing at the edition", () => {
|
|
239
|
+
enterpriseEditionForTest = true;
|
|
240
|
+
|
|
241
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
242
|
+
|
|
243
|
+
expect(screen.getAllByText(shell.featureName).length).toBeGreaterThan(0);
|
|
244
|
+
expect(
|
|
245
|
+
screen.getAllByText("Learn about Enterprise Edition").length,
|
|
246
|
+
).toBeGreaterThan(0);
|
|
247
|
+
expect(screen.queryByText("Upgrade to Scale")).not.toBeInTheDocument();
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
test("OneUptime Cloud below Scale: the plan upsell, never the screen", () => {
|
|
251
|
+
billingEnabledForTest = true;
|
|
252
|
+
enterpriseEditionForTest = true;
|
|
253
|
+
currentPlanForTest = PlanType.Growth;
|
|
254
|
+
installPlugins([shell.pluginKey]);
|
|
255
|
+
|
|
256
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
257
|
+
|
|
258
|
+
expect(screen.getAllByText("Upgrade to Scale").length).toBeGreaterThan(0);
|
|
259
|
+
expect(screen.getAllByText(shell.featureName).length).toBeGreaterThan(0);
|
|
260
|
+
expect(screen.queryByTestId("enterprise-screen")).not.toBeInTheDocument();
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test.each([PlanType.Scale, PlanType.Enterprise])(
|
|
264
|
+
"OneUptime Cloud on %s: the Enterprise screen",
|
|
265
|
+
(plan: PlanType) => {
|
|
266
|
+
billingEnabledForTest = true;
|
|
267
|
+
enterpriseEditionForTest = true;
|
|
268
|
+
currentPlanForTest = plan;
|
|
269
|
+
installPlugins([shell.pluginKey]);
|
|
270
|
+
|
|
271
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
272
|
+
|
|
273
|
+
expect(screen.getByTestId("enterprise-screen")).toHaveTextContent(
|
|
274
|
+
shell.pluginKey,
|
|
275
|
+
);
|
|
276
|
+
},
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
test("renders its own plugin key when every identity screen is present", () => {
|
|
280
|
+
enterpriseEditionForTest = true;
|
|
281
|
+
installPlugins(
|
|
282
|
+
SHELLS.map((each: ShellCase) => {
|
|
283
|
+
return each.pluginKey;
|
|
284
|
+
}),
|
|
285
|
+
);
|
|
286
|
+
|
|
287
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
288
|
+
|
|
289
|
+
expect(screen.getByTestId("enterprise-screen")).toHaveTextContent(
|
|
290
|
+
`${shell.pluginKey}|`,
|
|
291
|
+
);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
test("ignores other features' screens", () => {
|
|
295
|
+
enterpriseEditionForTest = true;
|
|
296
|
+
installPlugins(
|
|
297
|
+
SHELLS.map((each: ShellCase) => {
|
|
298
|
+
return each.pluginKey;
|
|
299
|
+
}).filter((key: DashboardEnterprisePluginKey) => {
|
|
300
|
+
return key !== shell.pluginKey;
|
|
301
|
+
}),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
render(<shell.Shell {...PAGE_PROPS} />);
|
|
305
|
+
|
|
306
|
+
expect(screen.queryByTestId("enterprise-screen")).not.toBeInTheDocument();
|
|
307
|
+
expect(screen.getAllByText(shell.featureName).length).toBeGreaterThan(0);
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
describe("identity shells", () => {
|
|
312
|
+
test("each reads a different plugin key", () => {
|
|
313
|
+
const keys: Array<string> = SHELLS.map((shell: ShellCase) => {
|
|
314
|
+
return shell.pluginKey;
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
expect(new Set(keys).size).toBe(SHELLS.length);
|
|
318
|
+
});
|
|
319
|
+
});
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import {
|
|
3
|
+
act,
|
|
4
|
+
cleanup,
|
|
5
|
+
fireEvent,
|
|
6
|
+
render,
|
|
7
|
+
screen,
|
|
8
|
+
} from "@testing-library/react";
|
|
9
|
+
import React, { ReactElement, useEffect } from "react";
|
|
10
|
+
import {
|
|
11
|
+
afterEach,
|
|
12
|
+
beforeEach,
|
|
13
|
+
describe,
|
|
14
|
+
expect,
|
|
15
|
+
jest,
|
|
16
|
+
test,
|
|
17
|
+
} from "@jest/globals";
|
|
18
|
+
import ProjectUtil from "../../../UI/Utils/Project";
|
|
19
|
+
import Navigation from "../../../UI/Utils/Navigation";
|
|
20
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
21
|
+
import Route from "../../../Types/API/Route";
|
|
22
|
+
import URL from "../../../Types/API/URL";
|
|
23
|
+
import OnboardingSsoPage from "../../../../App/FeatureSet/Dashboard/src/Pages/Onboarding/SSO";
|
|
24
|
+
import PageMap from "../../../../App/FeatureSet/Dashboard/src/Utils/PageMap";
|
|
25
|
+
import RouteMap from "../../../../App/FeatureSet/Dashboard/src/Utils/RouteMap";
|
|
26
|
+
import { getJestSpyOn } from "../../Spy";
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Dashboard > project SSO sign-in (Onboarding/SSO): where a user lands when a
|
|
30
|
+
* project requires SSO. It lists the project's providers from
|
|
31
|
+
* /project-sso/:projectId/sso-list.
|
|
32
|
+
*
|
|
33
|
+
* That list is empty when the project has no enabled provider - and always on
|
|
34
|
+
* the Community Edition, where SSO login is part of the Enterprise Edition and
|
|
35
|
+
* the server lists no providers. The page must then explain why and offer a
|
|
36
|
+
* way back to sign-in, rather than a dead end.
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
type ProviderRow = { _id: string; name: string };
|
|
40
|
+
|
|
41
|
+
interface ProviderListProps {
|
|
42
|
+
id: string;
|
|
43
|
+
overrideFetchApiUrl: URL;
|
|
44
|
+
noItemsMessage: string;
|
|
45
|
+
onListLoaded?: (list: Array<ProviderRow>) => void;
|
|
46
|
+
onSelectChange?: (list: Array<ProviderRow>) => void;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let providersForTest: Array<ProviderRow> = [];
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* The real ModelList fetches over HTTP; this stand-in "loads" the configured
|
|
53
|
+
* providers the same way (onListLoaded after mount) and renders them.
|
|
54
|
+
*/
|
|
55
|
+
jest.mock("../../../UI/Components/ModelList/ModelList", () => {
|
|
56
|
+
return {
|
|
57
|
+
__esModule: true,
|
|
58
|
+
default: (props: ProviderListProps): ReactElement => {
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
props.onListLoaded?.(providersForTest);
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
data-testid={props.id}
|
|
66
|
+
data-fetch-url={props.overrideFetchApiUrl.toString()}
|
|
67
|
+
>
|
|
68
|
+
{providersForTest.length === 0 ? (
|
|
69
|
+
<p>{props.noItemsMessage}</p>
|
|
70
|
+
) : (
|
|
71
|
+
providersForTest.map((provider: ProviderRow) => {
|
|
72
|
+
return (
|
|
73
|
+
<button
|
|
74
|
+
key={provider._id}
|
|
75
|
+
onClick={() => {
|
|
76
|
+
props.onSelectChange?.([provider]);
|
|
77
|
+
}}
|
|
78
|
+
>
|
|
79
|
+
{provider.name}
|
|
80
|
+
</button>
|
|
81
|
+
);
|
|
82
|
+
})
|
|
83
|
+
)}
|
|
84
|
+
</div>
|
|
85
|
+
);
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
jest.mock("../../../UI/Components/Page/Page", () => {
|
|
91
|
+
const react: typeof React = jest.requireActual("react") as typeof React;
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
__esModule: true,
|
|
95
|
+
default: (props: { children?: React.ReactNode }) => {
|
|
96
|
+
return react.createElement("div", null, props.children);
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const PROJECT_ID: ObjectID = new ObjectID(
|
|
102
|
+
"11111111-1111-4111-8111-111111111111",
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
const renderPage: () => Promise<void> = async (): Promise<void> => {
|
|
106
|
+
await act(async () => {
|
|
107
|
+
render(
|
|
108
|
+
<OnboardingSsoPage
|
|
109
|
+
pageRoute={new Route("/dashboard/project/sso")}
|
|
110
|
+
currentProject={null}
|
|
111
|
+
hasPaymentMethod={false}
|
|
112
|
+
/>,
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
describe("Dashboard project SSO sign-in page", () => {
|
|
118
|
+
beforeEach(() => {
|
|
119
|
+
providersForTest = [];
|
|
120
|
+
getJestSpyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(
|
|
121
|
+
PROJECT_ID,
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
afterEach(() => {
|
|
126
|
+
cleanup();
|
|
127
|
+
jest.restoreAllMocks();
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("with no provider (always the case on the Community Edition) it explains why and links back to sign-in", async () => {
|
|
131
|
+
await renderPage();
|
|
132
|
+
|
|
133
|
+
const help: HTMLElement = await screen.findByTestId(
|
|
134
|
+
"sso-no-providers-help",
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
expect(help).toHaveTextContent(
|
|
138
|
+
"This project has no single sign-on provider you can use to log in.",
|
|
139
|
+
);
|
|
140
|
+
expect(help).toHaveTextContent(
|
|
141
|
+
"Single sign-on is part of the OneUptime Enterprise Edition",
|
|
142
|
+
);
|
|
143
|
+
expect(help).toHaveTextContent(
|
|
144
|
+
"sign in with your email and password instead",
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const backToSignIn: HTMLElement = screen.getByText("Back to sign in");
|
|
148
|
+
|
|
149
|
+
expect(backToSignIn.closest("a")).toHaveAttribute(
|
|
150
|
+
"href",
|
|
151
|
+
RouteMap[PageMap.LOGOUT]!.toString(),
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("with providers it lists them, shows no help text, and signs in with the chosen one", async () => {
|
|
156
|
+
providersForTest = [
|
|
157
|
+
{ _id: "22222222-2222-4222-8222-222222222222", name: "Okta" },
|
|
158
|
+
];
|
|
159
|
+
const navigate: ReturnType<typeof getJestSpyOn> = getJestSpyOn(
|
|
160
|
+
Navigation,
|
|
161
|
+
"navigate",
|
|
162
|
+
).mockImplementation(() => {});
|
|
163
|
+
|
|
164
|
+
await renderPage();
|
|
165
|
+
|
|
166
|
+
expect(
|
|
167
|
+
screen.queryByTestId("sso-no-providers-help"),
|
|
168
|
+
).not.toBeInTheDocument();
|
|
169
|
+
|
|
170
|
+
fireEvent.click(screen.getByText("Okta"));
|
|
171
|
+
|
|
172
|
+
expect(navigate).toHaveBeenCalledTimes(1);
|
|
173
|
+
expect(String(navigate.mock.calls[0]![0])).toContain(
|
|
174
|
+
`/sso/${PROJECT_ID.toString()}/22222222-2222-4222-8222-222222222222`,
|
|
175
|
+
);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("lists providers from the project's sso-list endpoint", async () => {
|
|
179
|
+
await renderPage();
|
|
180
|
+
|
|
181
|
+
expect(
|
|
182
|
+
screen.getByTestId("sso-list").getAttribute("data-fetch-url"),
|
|
183
|
+
).toContain(`/project-sso/${PROJECT_ID.toString()}/sso-list`);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -48,7 +48,6 @@ import ListResult from "../../../Types/BaseDatabase/ListResult";
|
|
|
48
48
|
import RangeStartAndEndDateTime from "../../../Types/Time/RangeStartAndEndDateTime";
|
|
49
49
|
import TimeRange from "../../../Types/Time/TimeRange";
|
|
50
50
|
import { JSONObject } from "../../../Types/JSON";
|
|
51
|
-
import JSONFunctions from "../../../Types/JSONFunctions";
|
|
52
51
|
import ObjectID from "../../../Types/ObjectID";
|
|
53
52
|
import {
|
|
54
53
|
SecurityConnectorSample,
|
|
@@ -269,12 +268,36 @@ function eventsParams(route: Route): URLSearchParams {
|
|
|
269
268
|
return new URLSearchParams(text.slice(text.indexOf("?")));
|
|
270
269
|
}
|
|
271
270
|
|
|
272
|
-
|
|
271
|
+
/*
|
|
272
|
+
* The chips the link opens the events explorer with, re-shaped as
|
|
273
|
+
* `{ attributes: { key: value } }` — the reading these assertions have always
|
|
274
|
+
* used.
|
|
275
|
+
*
|
|
276
|
+
* The link's grammar is the explorers' own `filters` param
|
|
277
|
+
* (`[["attributes.<key>", "<value>"], ...]`); it used to be the model
|
|
278
|
+
* table's serialized column filter, which went away with the table. Anything
|
|
279
|
+
* the explorer does not express as an attribute chip is left out, so an
|
|
280
|
+
* assertion that a key is absent still means "the link does not filter on
|
|
281
|
+
* it".
|
|
282
|
+
*/
|
|
273
283
|
function eventsFilter(route: Route): JSONObject {
|
|
274
|
-
const raw: string | null = eventsParams(route).get(
|
|
275
|
-
|
|
276
|
-
)
|
|
277
|
-
|
|
284
|
+
const raw: string | null = eventsParams(route).get("filters");
|
|
285
|
+
|
|
286
|
+
if (!raw) {
|
|
287
|
+
return {};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const attributes: JSONObject = {};
|
|
291
|
+
|
|
292
|
+
for (const pair of JSON.parse(raw) as Array<[string, string]>) {
|
|
293
|
+
if (!Array.isArray(pair) || !pair[0]?.startsWith("attributes.")) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
attributes[pair[0].substring("attributes.".length)] = pair[1];
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return Object.keys(attributes).length > 0 ? { attributes } : {};
|
|
278
301
|
}
|
|
279
302
|
|
|
280
303
|
/*
|
|
@@ -1481,25 +1504,38 @@ describe("View events for a connection run", () => {
|
|
|
1481
1504
|
expect(eventsFilter(route)["attributes"]).toBeUndefined();
|
|
1482
1505
|
});
|
|
1483
1506
|
|
|
1484
|
-
test("the window is the page's time range, not a
|
|
1507
|
+
test("the window is the page's time range, not a chip", (): void => {
|
|
1485
1508
|
const route: Route = connectionEventsRoute(result(), CONNECTION_ID);
|
|
1486
1509
|
const params: URLSearchParams = eventsParams(route);
|
|
1487
1510
|
|
|
1488
1511
|
expect(params.get("range")).toBe(TimeRange.CUSTOM);
|
|
1489
1512
|
expect(params.get("start")).toBe("2026-09-09T01:30:29.000Z");
|
|
1490
1513
|
expect(params.get("end")).toBe("2026-09-09T01:30:31.000Z");
|
|
1491
|
-
// The
|
|
1514
|
+
// The window is the explorer's own range, never one of its chips.
|
|
1492
1515
|
expect(eventsFilter(route)["time"]).toBeUndefined();
|
|
1493
1516
|
expect(eventsFilter(route)["attributes"]).toEqual({
|
|
1494
1517
|
[SECURITY_CONNECTION_ID_ATTRIBUTE]: CONNECTION_ID,
|
|
1495
1518
|
});
|
|
1496
1519
|
});
|
|
1497
1520
|
|
|
1498
|
-
test("
|
|
1521
|
+
test("the connection chip is written in the explorer's filters grammar", (): void => {
|
|
1522
|
+
const raw: string | null = eventsParams(
|
|
1523
|
+
connectionEventsRoute(result(), CONNECTION_ID),
|
|
1524
|
+
).get("filters");
|
|
1525
|
+
|
|
1526
|
+
expect(raw).not.toBeNull();
|
|
1527
|
+
expect(JSON.parse(raw as string)).toEqual([
|
|
1528
|
+
[`attributes.${SECURITY_CONNECTION_ID_ATTRIBUTE}`, CONNECTION_ID],
|
|
1529
|
+
]);
|
|
1530
|
+
});
|
|
1531
|
+
|
|
1532
|
+
test("a link with nothing to filter on sets no chips at all", (): void => {
|
|
1499
1533
|
const params: URLSearchParams = eventsParams(
|
|
1500
1534
|
connectionEventsRoute(result()),
|
|
1501
1535
|
);
|
|
1502
1536
|
|
|
1537
|
+
expect(params.get("filters")).toBeNull();
|
|
1538
|
+
// The retired model table's own filter param is gone for good.
|
|
1503
1539
|
expect(params.get("security-events-table-filter")).toBeNull();
|
|
1504
1540
|
expect(params.get("range")).toBe(TimeRange.CUSTOM);
|
|
1505
1541
|
});
|