@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
|
@@ -12,8 +12,10 @@ import { describe, expect, test } from "@jest/globals";
|
|
|
12
12
|
* consumer, which is why a monitor on a non-443 port could never connect —
|
|
13
13
|
* see https://github.com/OneUptime/oneuptime/issues/3225.
|
|
14
14
|
*
|
|
15
|
-
* fromString()
|
|
16
|
-
*
|
|
15
|
+
* fromString() used not to be a substitute: it split on the FIRST colon,
|
|
16
|
+
* which mangled every IPv6 literal. It now delegates IPv6 authorities here
|
|
17
|
+
* instead, so the two agree on addresses; they still differ on a DNS host,
|
|
18
|
+
* where fromString keeps its own splitting and its own userinfo handling.
|
|
17
19
|
*/
|
|
18
20
|
describe("Hostname.fromAuthority", () => {
|
|
19
21
|
describe("host and port", () => {
|
|
@@ -141,18 +143,26 @@ describe("Hostname.fromAuthority", () => {
|
|
|
141
143
|
});
|
|
142
144
|
|
|
143
145
|
describe("contrast with fromString", () => {
|
|
144
|
-
test("fromString
|
|
146
|
+
test("fromString now agrees with fromAuthority on an IPv6 literal", () => {
|
|
145
147
|
/*
|
|
146
|
-
*
|
|
147
|
-
*
|
|
148
|
+
* This case used to be pinned the other way round: fromString split on
|
|
149
|
+
* the FIRST colon, so "[::1]:8443" became a host of "[" and the setter
|
|
150
|
+
* threw. Worse, the unbracketed spelling did NOT throw -- it returned
|
|
151
|
+
* host "2001" / port 518 for "2001:518:2800:9::2" and a monitor was
|
|
152
|
+
* saved pointing at a host nobody typed.
|
|
148
153
|
*
|
|
149
|
-
* fromString
|
|
150
|
-
*
|
|
154
|
+
* fromString delegates IPv6 authorities to fromAuthority now, so the
|
|
155
|
+
* two agree. Kept as a contrast test so a future 'simplification' that
|
|
156
|
+
* reintroduces the split fails here.
|
|
151
157
|
*/
|
|
152
158
|
expect(Hostname.fromAuthority("[::1]:8443").hostname).toBe("[::1]");
|
|
153
|
-
expect(()
|
|
154
|
-
|
|
155
|
-
|
|
159
|
+
expect(Hostname.fromString("[::1]:8443").hostname).toBe("[::1]");
|
|
160
|
+
expect(Hostname.fromString("[::1]:8443").port?.toNumber()).toBe(8443);
|
|
161
|
+
|
|
162
|
+
expect(Hostname.fromString("2001:518:2800:9::2").hostname).toBe(
|
|
163
|
+
"2001:518:2800:9::2",
|
|
164
|
+
);
|
|
165
|
+
expect(Hostname.fromString("2001:518:2800:9::2").port).toBeUndefined();
|
|
156
166
|
});
|
|
157
167
|
|
|
158
168
|
test("both agree on the simple host:port case", () => {
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import Hostname from "../../../Types/API/Hostname";
|
|
2
|
+
import URL from "../../../Types/API/URL";
|
|
3
|
+
import { describe, expect, test } from "@jest/globals";
|
|
4
|
+
import net from "net";
|
|
5
|
+
|
|
6
|
+
/*
|
|
7
|
+
* Hostname's handling of IPv6 literals.
|
|
8
|
+
*
|
|
9
|
+
* fromString used to split on the FIRST colon, which is meaningless for an
|
|
10
|
+
* address made of colons. The damage was silent rather than loud: for the
|
|
11
|
+
* customer address reported below it
|
|
12
|
+
* returned host "2001" with port 518 — both legal — so nothing threw and the
|
|
13
|
+
* value the operator typed was simply gone.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const CUSTOMER_ADDRESS: string = "2001:518:2800:9::2";
|
|
17
|
+
|
|
18
|
+
describe("Hostname.fromString with an IPv6 literal", () => {
|
|
19
|
+
test("keeps the whole address instead of its first two groups", () => {
|
|
20
|
+
const hostname: Hostname = Hostname.fromString(CUSTOMER_ADDRESS);
|
|
21
|
+
|
|
22
|
+
expect(hostname.hostname).toBe(CUSTOMER_ADDRESS);
|
|
23
|
+
expect(hostname.port).toBeUndefined();
|
|
24
|
+
expect(hostname.toString()).toBe(CUSTOMER_ADDRESS);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("specifically, it is not 2001 port 518", () => {
|
|
28
|
+
const hostname: Hostname = Hostname.fromString(CUSTOMER_ADDRESS);
|
|
29
|
+
|
|
30
|
+
expect(hostname.hostname).not.toBe("2001");
|
|
31
|
+
expect(hostname.port?.toNumber()).not.toBe(518);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("trims, so a pasted address keeps working", () => {
|
|
35
|
+
expect(Hostname.fromString(` ${CUSTOMER_ADDRESS}\n`).hostname).toBe(
|
|
36
|
+
CUSTOMER_ADDRESS,
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test.each([
|
|
41
|
+
"::1",
|
|
42
|
+
"::",
|
|
43
|
+
"2001:db8::",
|
|
44
|
+
"::ffff:192.0.2.1",
|
|
45
|
+
"2001:0db8:85a3:0000:0000:8a2e:0370:7334",
|
|
46
|
+
])("survives the compressed form %s", (address: string) => {
|
|
47
|
+
expect(Hostname.fromString(address).hostname).toBe(address);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test("a bracketed literal keeps its brackets and gives up its port", () => {
|
|
51
|
+
const hostname: Hostname = Hostname.fromString(`[${CUSTOMER_ADDRESS}]:179`);
|
|
52
|
+
|
|
53
|
+
expect(hostname.hostname).toBe(`[${CUSTOMER_ADDRESS}]`);
|
|
54
|
+
expect(hostname.port?.toNumber()).toBe(179);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("a value with two colons that is NOT an address is rejected rather than silently split", () => {
|
|
58
|
+
expect(() => {
|
|
59
|
+
return Hostname.fromString("example.com:80:90");
|
|
60
|
+
}).toThrow();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("Hostname.fromString — IPv4 and DNS are unchanged", () => {
|
|
65
|
+
test.each([
|
|
66
|
+
["example.com", "example.com", undefined],
|
|
67
|
+
["example.com:8443", "example.com", 8443],
|
|
68
|
+
["192.0.2.1", "192.0.2.1", undefined],
|
|
69
|
+
["192.0.2.1:179", "192.0.2.1", 179],
|
|
70
|
+
["localhost:3000", "localhost", 3000],
|
|
71
|
+
])(
|
|
72
|
+
"%s parses to host %s",
|
|
73
|
+
(value: string, expectedHost: string, expectedPort?: number) => {
|
|
74
|
+
const hostname: Hostname = Hostname.fromString(value);
|
|
75
|
+
|
|
76
|
+
expect(hostname.hostname).toBe(expectedHost);
|
|
77
|
+
expect(hostname.port?.toNumber()).toBe(expectedPort);
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("Hostname.toString with a port", () => {
|
|
83
|
+
test("brackets an IPv6 host, because the unbracketed form is a different address", () => {
|
|
84
|
+
const hostname: Hostname = new Hostname(CUSTOMER_ADDRESS, 179);
|
|
85
|
+
|
|
86
|
+
expect(hostname.toString()).toBe(`[${CUSTOMER_ADDRESS}]:179`);
|
|
87
|
+
|
|
88
|
+
// What it used to produce, and why that was not merely ugly:
|
|
89
|
+
expect(net.isIP(`${CUSTOMER_ADDRESS}:179`)).toBe(6);
|
|
90
|
+
expect(hostname.toString()).not.toBe(`${CUSTOMER_ADDRESS}:179`);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
test("the bracketed form re-parses to the same host and port", () => {
|
|
94
|
+
const roundTripped: Hostname = Hostname.fromString(
|
|
95
|
+
new Hostname(CUSTOMER_ADDRESS, 179).toString(),
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
expect(roundTripped.hostname).toBe(`[${CUSTOMER_ADDRESS}]`);
|
|
99
|
+
expect(roundTripped.port?.toNumber()).toBe(179);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("an IPv4 or DNS host keeps the conventional spelling", () => {
|
|
103
|
+
expect(new Hostname("192.0.2.1", 179).toString()).toBe("192.0.2.1:179");
|
|
104
|
+
expect(new Hostname("example.com", 8443).toString()).toBe(
|
|
105
|
+
"example.com:8443",
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("without a port the host is returned exactly as held", () => {
|
|
110
|
+
expect(new Hostname(CUSTOMER_ADDRESS).toString()).toBe(CUSTOMER_ADDRESS);
|
|
111
|
+
expect(Hostname.fromAuthority("[::1]").toString()).toBe("[::1]");
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("Hostname.isValid validates the address, not just its characters", () => {
|
|
116
|
+
test.each([CUSTOMER_ADDRESS, "::1", "[::1]", "[::1]:8080", "2001:db8::"])(
|
|
117
|
+
"accepts %s",
|
|
118
|
+
(value: string) => {
|
|
119
|
+
expect(Hostname.isValid(value)).toBe(true);
|
|
120
|
+
},
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
test.each([
|
|
124
|
+
"::::",
|
|
125
|
+
"2001:db8:::1",
|
|
126
|
+
"[not-an-address]",
|
|
127
|
+
"gggg::1",
|
|
128
|
+
"2001:db8::1::2",
|
|
129
|
+
])(
|
|
130
|
+
"rejects %s, which the old character allowlist let through",
|
|
131
|
+
(value: string) => {
|
|
132
|
+
expect(Hostname.isValid(value)).toBe(false);
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
describe("URL.toString still emits a valid authority for an IPv6 host", () => {
|
|
138
|
+
test("brackets survive a round trip", () => {
|
|
139
|
+
expect(
|
|
140
|
+
URL.fromString(`https://[${CUSTOMER_ADDRESS}]/health`).toString(),
|
|
141
|
+
).toBe(`https://[${CUSTOMER_ADDRESS}]/health`);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
test("a bracketed host with a port survives a round trip", () => {
|
|
145
|
+
expect(
|
|
146
|
+
URL.fromString(`https://[${CUSTOMER_ADDRESS}]:8443/x`).toString(),
|
|
147
|
+
).toBe(`https://[${CUSTOMER_ADDRESS}]:8443/x`);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import AllModelTypes from "../../../Models/DatabaseModels/Index";
|
|
2
|
+
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
3
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
4
|
+
import ProjectSCIM from "../../../Models/DatabaseModels/ProjectSCIM";
|
|
5
|
+
import StatusPage from "../../../Models/DatabaseModels/StatusPage";
|
|
6
|
+
import UserEmail from "../../../Models/DatabaseModels/UserEmail";
|
|
7
|
+
import { ColumnAccessControl } from "../../../Types/BaseDatabase/AccessControl";
|
|
8
|
+
import ColumnBillingAccessControl from "../../../Types/BaseDatabase/ColumnBillingAccessControl";
|
|
9
|
+
import { getColumnAccessControlForAllColumns } from "../../../Types/Database/AccessControl/ColumnAccessControl";
|
|
10
|
+
import { getColumnBillingAccessControlForAllColumns } from "../../../Types/Database/AccessControl/ColumnBillingAccessControl";
|
|
11
|
+
import { getOwnerOnlyColumns } from "../../../Types/Database/AccessControl/OwnerOnlyColumn";
|
|
12
|
+
import Dictionary from "../../../Types/Dictionary";
|
|
13
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
14
|
+
import { describe, expect, test } from "@jest/globals";
|
|
15
|
+
import { getMetadataArgsStorage } from "typeorm";
|
|
16
|
+
|
|
17
|
+
/*
|
|
18
|
+
* WHY THIS FILE EXISTS - do not delete these as "obvious" assertions.
|
|
19
|
+
*
|
|
20
|
+
* Every "which columns does this model have" lookup answers the question by
|
|
21
|
+
* enumerating an INSTANCE's own keys, and caches the answer per CLASS, for the
|
|
22
|
+
* whole process. So the FIRST instance to ask used to define what the class is
|
|
23
|
+
* for everybody after it.
|
|
24
|
+
*
|
|
25
|
+
* BaseAPI.createItem deleted `_id` off the live model instance it handed to
|
|
26
|
+
* the service, and DatabaseService.create asks that instance for its columns
|
|
27
|
+
* (generateDefaultValues) before any permission check runs. One POST - even a
|
|
28
|
+
* POST that was refused - could therefore teach the process that a model has
|
|
29
|
+
* no `_id` column, and DatabaseBaseModel.toJSONObject serializes a row by
|
|
30
|
+
* iterating exactly that cached list, so every response for that model lost
|
|
31
|
+
* its id from then on. To any caller, on any route, including plain reads as
|
|
32
|
+
* root: the row still carried its real `_id` in memory and the SQL projection
|
|
33
|
+
* still selected it. The id was dropped on the way out, and it stayed a 200
|
|
34
|
+
* because `_id` is in ColumnPermissions.getExcludedColumnNames().
|
|
35
|
+
*
|
|
36
|
+
* The tests below do the mutation on purpose. No caller in the tree does it
|
|
37
|
+
* any more, and that is not what is being protected: the invariant is that it
|
|
38
|
+
* CANNOT MATTER who asks first or what they did to their own instance. Each
|
|
39
|
+
* test uses a different model class, because these caches are per class and
|
|
40
|
+
* per process - a class another test has already asked about has a warm cache
|
|
41
|
+
* and would pass vacuously.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
describe("column metadata does not depend on which instance asked first", () => {
|
|
45
|
+
test("getTableColumns: a mutilated instance asking first cannot strip _id from the class", () => {
|
|
46
|
+
const mutilated: ProjectSCIM = new ProjectSCIM();
|
|
47
|
+
|
|
48
|
+
// exactly what BaseAPI.createItem used to do before calling the service
|
|
49
|
+
delete (mutilated as unknown as Record<string, unknown>)["_id"];
|
|
50
|
+
expect(Object.keys(mutilated)).not.toContain("_id");
|
|
51
|
+
|
|
52
|
+
// the mutilated instance is the FIRST to ask, on a cold cache
|
|
53
|
+
expect(mutilated.getTableColumns().columns).toContain("_id");
|
|
54
|
+
|
|
55
|
+
// ...and a fresh instance of the same class is unharmed
|
|
56
|
+
expect(new ProjectSCIM().getTableColumns().columns).toContain("_id");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("getTableColumns: a row still serializes with its _id after such a create", () => {
|
|
60
|
+
/*
|
|
61
|
+
* The assertion that matches the reported symptom: POST /api/project-scim
|
|
62
|
+
* answered 200 with every column except "_id", and a get-list selecting
|
|
63
|
+
* {_id, name} came back as {name} alone.
|
|
64
|
+
*/
|
|
65
|
+
const mutilated: Monitor = new Monitor();
|
|
66
|
+
delete (mutilated as unknown as Record<string, unknown>)["_id"];
|
|
67
|
+
mutilated.getTableColumns();
|
|
68
|
+
|
|
69
|
+
const row: Monitor = new Monitor();
|
|
70
|
+
row._id = "22222222-2222-4222-8222-222222222222";
|
|
71
|
+
row.name = "a monitor";
|
|
72
|
+
|
|
73
|
+
const json: JSONObject = BaseModel.toJSONObject(row, Monitor);
|
|
74
|
+
|
|
75
|
+
expect(json["_id"]).toBe("22222222-2222-4222-8222-222222222222");
|
|
76
|
+
expect(json["name"]).toBe("a monitor");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("getColumnAccessControlForAllColumns is instance-independent", () => {
|
|
80
|
+
const mutilated: StatusPage = new StatusPage();
|
|
81
|
+
delete (mutilated as unknown as Record<string, unknown>)["name"];
|
|
82
|
+
|
|
83
|
+
const fromMutilated: Dictionary<ColumnAccessControl> =
|
|
84
|
+
getColumnAccessControlForAllColumns(mutilated);
|
|
85
|
+
|
|
86
|
+
expect(fromMutilated["name"]).toBeDefined();
|
|
87
|
+
expect(
|
|
88
|
+
getColumnAccessControlForAllColumns(new StatusPage())["name"],
|
|
89
|
+
).toBeDefined();
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("getColumnBillingAccessControlForAllColumns is instance-independent", () => {
|
|
93
|
+
const mutilated: StatusPage = new StatusPage();
|
|
94
|
+
delete (mutilated as unknown as Record<string, unknown>)["customCSS"];
|
|
95
|
+
|
|
96
|
+
const fromMutilated: Dictionary<ColumnBillingAccessControl> =
|
|
97
|
+
getColumnBillingAccessControlForAllColumns(mutilated);
|
|
98
|
+
|
|
99
|
+
expect(fromMutilated["customCSS"]).toBeDefined();
|
|
100
|
+
expect(
|
|
101
|
+
getColumnBillingAccessControlForAllColumns(new StatusPage())["customCSS"],
|
|
102
|
+
).toBeDefined();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("getOwnerOnlyColumns is instance-independent", () => {
|
|
106
|
+
/*
|
|
107
|
+
* This one is a permission list, not a projection: a marked column that
|
|
108
|
+
* goes unreported is a column OwnerOnlyColumnPermission stops protecting.
|
|
109
|
+
*/
|
|
110
|
+
const mutilated: UserEmail = new UserEmail();
|
|
111
|
+
delete (mutilated as unknown as Record<string, unknown>)["email"];
|
|
112
|
+
|
|
113
|
+
expect(getOwnerOnlyColumns(mutilated)).toContain("email");
|
|
114
|
+
expect(getOwnerOnlyColumns(new UserEmail())).toContain("email");
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("mutating an instance after the class has been read changes nothing either", () => {
|
|
118
|
+
const first: UserEmail = new UserEmail();
|
|
119
|
+
expect(first.getTableColumns().columns).toContain("_id");
|
|
120
|
+
|
|
121
|
+
delete (first as unknown as Record<string, unknown>)["_id"];
|
|
122
|
+
|
|
123
|
+
expect(first.getTableColumns().columns).toContain("_id");
|
|
124
|
+
expect(new UserEmail().getTableColumns().columns).toContain("_id");
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
/*
|
|
129
|
+
* The premise of the fix: metadata enumeration reads a freshly constructed
|
|
130
|
+
* instance of the caller's class, so every model must be no-arg constructible
|
|
131
|
+
* and must expose every column it declares on a fresh instance (the class
|
|
132
|
+
* bodies do that with `= undefined` initializers). If a model is ever added
|
|
133
|
+
* that breaks either half, it would silently lose columns everywhere -
|
|
134
|
+
* responses, selects, permissions - so assert it for all of them at once.
|
|
135
|
+
*/
|
|
136
|
+
describe("every database model supports canonical-instance enumeration", () => {
|
|
137
|
+
test("all models are no-arg constructible and declare no column that a fresh instance lacks", () => {
|
|
138
|
+
const columnsByTarget: Map<unknown, Array<string>> = new Map();
|
|
139
|
+
|
|
140
|
+
const record: (target: unknown, propertyName: string) => void = (
|
|
141
|
+
target: unknown,
|
|
142
|
+
propertyName: string,
|
|
143
|
+
): void => {
|
|
144
|
+
const list: Array<string> = columnsByTarget.get(target) || [];
|
|
145
|
+
list.push(propertyName);
|
|
146
|
+
columnsByTarget.set(target, list);
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
for (const column of getMetadataArgsStorage().columns) {
|
|
150
|
+
record(column.target, column.propertyName);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
for (const relation of getMetadataArgsStorage().relations) {
|
|
154
|
+
record(relation.target, relation.propertyName);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const constructFailures: Array<string> = [];
|
|
158
|
+
const missingKeys: Array<string> = [];
|
|
159
|
+
|
|
160
|
+
for (const modelType of AllModelTypes) {
|
|
161
|
+
let instance: BaseModel | null = null;
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
instance = new modelType();
|
|
165
|
+
} catch (err) {
|
|
166
|
+
constructFailures.push(`${modelType.name}: ${(err as Error).message}`);
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const ownKeys: Set<string> = new Set(Object.keys(instance));
|
|
171
|
+
|
|
172
|
+
// inherited columns count too, so walk the constructor chain
|
|
173
|
+
let ctor: unknown = modelType;
|
|
174
|
+
|
|
175
|
+
while (ctor && ctor !== Function.prototype) {
|
|
176
|
+
for (const propertyName of columnsByTarget.get(ctor) || []) {
|
|
177
|
+
if (!ownKeys.has(propertyName)) {
|
|
178
|
+
missingKeys.push(`${modelType.name}.${propertyName}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
ctor = Object.getPrototypeOf(ctor);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
expect(constructFailures).toEqual([]);
|
|
187
|
+
expect(missingKeys).toEqual([]);
|
|
188
|
+
expect(AllModelTypes.length).toBeGreaterThan(400);
|
|
189
|
+
});
|
|
190
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* What the edition dialog must say about an Enterprise license lapse. Shared
|
|
3
|
+
* by the core EditionLabel suite and ee/Tests/UI/License, which renders the
|
|
4
|
+
* same dialog with the Enterprise license manager.
|
|
5
|
+
*
|
|
6
|
+
* When the license lapses (after the trial or the grace period), single
|
|
7
|
+
* sign-on (SAML and OIDC), SCIM provisioning and audit logging stop - the
|
|
8
|
+
* Community Edition's behaviour - and "Require SSO" stops being enforced at
|
|
9
|
+
* the same moment, so nobody is locked out: users sign in with their
|
|
10
|
+
* password. Everything resumes as soon as a license is activated. The trial
|
|
11
|
+
* and grace notices must say so BEFORE it happens, and the lapsed notice must
|
|
12
|
+
* say what is off.
|
|
13
|
+
*
|
|
14
|
+
* The dialog used to promise the opposite ("SSO, SCIM and audit logging never
|
|
15
|
+
* stop"), so the checks reject that copy too. Plain functions over text, with
|
|
16
|
+
* no jest dependency, so a test can prove each check fails on the wrong copy.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Before the lapse: the trial and grace notices, after "Without a valid license (...), ".
|
|
20
|
+
export const LAPSE_WARNING_PHRASES: ReadonlyArray<string> = [
|
|
21
|
+
"single sign-on (SAML and OIDC) stops",
|
|
22
|
+
'"Require SSO" is no longer enforced, so users sign in with their password',
|
|
23
|
+
"SCIM provisioning stops",
|
|
24
|
+
"audit logging stops recording",
|
|
25
|
+
"enterprise configuration becomes read-only",
|
|
26
|
+
"the enterprise admin dashboards are locked",
|
|
27
|
+
"Everything resumes as soon as a license is activated",
|
|
28
|
+
"core monitoring is never affected",
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
// After the lapse: the license-required notice (expired, missing, invalid).
|
|
32
|
+
export const LAPSED_STATE_PHRASES: ReadonlyArray<string> = [
|
|
33
|
+
"Single sign-on (SAML and OIDC) and SCIM provisioning are off",
|
|
34
|
+
'"Require SSO" is not enforced, so users sign in with their password',
|
|
35
|
+
"SCIM requests are refused",
|
|
36
|
+
"Audit logging is not recording",
|
|
37
|
+
"Enterprise configuration is read-only",
|
|
38
|
+
"Everything resumes, without a restart, as soon as a valid license is added",
|
|
39
|
+
"core monitoring is never affected",
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
// The soft-enforcement promises the dialog made before. None may come back.
|
|
43
|
+
export const RETIRED_SOFT_ENFORCEMENT_COPY: ReadonlyArray<RegExp> = [
|
|
44
|
+
/never stop/i,
|
|
45
|
+
/already configured keeps working/i,
|
|
46
|
+
/configured stops working/i,
|
|
47
|
+
/keeps? working as configured/i,
|
|
48
|
+
/never (?:silently )?weakens?/i,
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
// The copy the dialog shipped before the owner's decision, verbatim.
|
|
52
|
+
export const RETIRED_NOTICE_EXAMPLES: ReadonlyArray<string> = [
|
|
53
|
+
"Without a valid license (after the 14-day grace period), enterprise configuration becomes read-only and the enterprise admin dashboards are locked. Everything you already configured keeps working — SSO, SCIM and audit logging never stop — and core monitoring is never affected.",
|
|
54
|
+
"Without a valid license (after the 14-day trial), enterprise configuration becomes read-only and the enterprise admin dashboards are locked. Everything you already configured keeps working — SSO, SCIM and audit logging never stop — and core monitoring is never affected.",
|
|
55
|
+
"The Enterprise license expired and its grace period is over. Enterprise configuration is read-only and the enterprise admin dashboards are locked until a valid license is added. Everything you already configured keeps working — SSO, SCIM and audit logging never stop — and core monitoring is never affected.",
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
type CopyCheck = (text: string | null | undefined) => Array<string>;
|
|
59
|
+
|
|
60
|
+
// Whitespace-normalized, so a check does not depend on how JSX wraps a line.
|
|
61
|
+
const normalize: (text: string | null | undefined) => string = (
|
|
62
|
+
text: string | null | undefined,
|
|
63
|
+
): string => {
|
|
64
|
+
return (text || "").replace(/\s+/g, " ").trim();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const copyProblems: (
|
|
68
|
+
text: string | null | undefined,
|
|
69
|
+
requiredPhrases: ReadonlyArray<string>,
|
|
70
|
+
) => Array<string> = (
|
|
71
|
+
text: string | null | undefined,
|
|
72
|
+
requiredPhrases: ReadonlyArray<string>,
|
|
73
|
+
): Array<string> => {
|
|
74
|
+
const flat: string = normalize(text);
|
|
75
|
+
const problems: Array<string> = [];
|
|
76
|
+
|
|
77
|
+
for (const phrase of requiredPhrases) {
|
|
78
|
+
if (!flat.includes(phrase)) {
|
|
79
|
+
problems.push(`missing: ${phrase}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for (const retired of RETIRED_SOFT_ENFORCEMENT_COPY) {
|
|
84
|
+
if (retired.test(flat)) {
|
|
85
|
+
problems.push(`retired: ${retired.source}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return problems;
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// What is wrong with a trial or grace notice (empty when it is right).
|
|
93
|
+
export const lapseWarningProblems: CopyCheck = (
|
|
94
|
+
text: string | null | undefined,
|
|
95
|
+
): Array<string> => {
|
|
96
|
+
return copyProblems(text, LAPSE_WARNING_PHRASES);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// What is wrong with the notice shown once the license has lapsed.
|
|
100
|
+
export const lapsedStateProblems: CopyCheck = (
|
|
101
|
+
text: string | null | undefined,
|
|
102
|
+
): Array<string> => {
|
|
103
|
+
return copyProblems(text, LAPSED_STATE_PHRASES);
|
|
104
|
+
};
|