@oneuptime/common 12.0.30 → 12.0.31
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/SecurityEvent.ts +48 -16
- package/Models/AnalyticsModels/ThreatIntelIndicator.ts +10 -5
- package/Models/DatabaseModels/AlertSeverity.ts +44 -0
- package/Models/DatabaseModels/DetectionRule.ts +16 -5
- package/Models/DatabaseModels/GoogleSecOpsConnection.ts +14 -5
- package/Models/DatabaseModels/IncidentSeverity.ts +44 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/NetworkDevice.ts +113 -3
- package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +88 -0
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +22 -0
- package/Models/DatabaseModels/NetworkDeviceOidTemplate.ts +499 -0
- package/Models/DatabaseModels/ThreatIntelFeed.ts +16 -5
- package/Server/API/GlobalConfigAPI.ts +362 -183
- package/Server/API/TelemetryAPI.ts +42 -4
- package/Server/EnvironmentConfig.ts +112 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790500000000-AddNetworkDeviceOidTemplate.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790600000000-AddAutoImportRuleOidTemplate.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/MultipartFormData.ts +118 -32
- package/Server/Services/AlertEpisodeLabelRuleEngineService.ts +9 -1
- package/Server/Services/AlertEpisodeOnCallRuleEngineService.ts +9 -1
- package/Server/Services/AlertEpisodeOwnerRuleEngineService.ts +9 -1
- package/Server/Services/AlertEpisodePrivacyRuleEngineService.ts +9 -1
- package/Server/Services/AlertGroupingEngineService.ts +9 -1
- package/Server/Services/AlertLabelRuleEngineService.ts +9 -1
- package/Server/Services/AlertOnCallRuleEngineService.ts +9 -1
- package/Server/Services/AlertOwnerRuleEngineService.ts +9 -1
- package/Server/Services/AlertPrivacyRuleEngineService.ts +9 -1
- package/Server/Services/AlertReminderRuleService.ts +9 -1
- package/Server/Services/AutoRemediationRuleEngineService.ts +9 -1
- package/Server/Services/CephClusterLabelRuleEngineService.ts +9 -1
- package/Server/Services/CephClusterOwnerRuleEngineService.ts +9 -1
- package/Server/Services/CloudResourceLabelRuleEngineService.ts +9 -1
- package/Server/Services/CloudResourceOwnerRuleEngineService.ts +9 -1
- package/Server/Services/DashboardLabelRuleEngineService.ts +9 -1
- package/Server/Services/DashboardOwnerRuleEngineService.ts +9 -1
- package/Server/Services/DockerHostLabelRuleEngineService.ts +9 -1
- package/Server/Services/DockerHostOwnerRuleEngineService.ts +9 -1
- package/Server/Services/DockerSwarmClusterLabelRuleEngineService.ts +9 -1
- package/Server/Services/DockerSwarmClusterOwnerRuleEngineService.ts +9 -1
- package/Server/Services/HostLabelRuleEngineService.ts +9 -1
- package/Server/Services/HostOwnerRuleEngineService.ts +9 -1
- package/Server/Services/IncidentEpisodeLabelRuleEngineService.ts +9 -1
- package/Server/Services/IncidentEpisodeOnCallRuleEngineService.ts +9 -1
- package/Server/Services/IncidentEpisodeOwnerRuleEngineService.ts +9 -1
- package/Server/Services/IncidentEpisodePrivacyRuleEngineService.ts +9 -1
- package/Server/Services/IncidentGroupingEngineService.ts +9 -1
- package/Server/Services/IncidentLabelRuleEngineService.ts +9 -1
- package/Server/Services/IncidentOnCallRuleEngineService.ts +9 -1
- package/Server/Services/IncidentOwnerRuleEngineService.ts +9 -1
- package/Server/Services/IncidentPrivacyRuleEngineService.ts +9 -1
- package/Server/Services/IncidentReminderRuleService.ts +9 -1
- package/Server/Services/IncidentSlaRuleService.ts +9 -1
- package/Server/Services/IncomingCallPolicyLabelRuleEngineService.ts +9 -1
- package/Server/Services/IncomingCallPolicyOwnerRuleEngineService.ts +9 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/IoTFleetLabelRuleEngineService.ts +9 -1
- package/Server/Services/IoTFleetOwnerRuleEngineService.ts +9 -1
- package/Server/Services/KubernetesClusterLabelRuleEngineService.ts +9 -1
- package/Server/Services/KubernetesClusterOwnerRuleEngineService.ts +9 -1
- package/Server/Services/KubernetesResourceService.ts +5 -1
- package/Server/Services/MonitorLabelRuleEngineService.ts +9 -1
- package/Server/Services/MonitorOwnerRuleEngineService.ts +9 -1
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +35 -0
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +96 -0
- package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +9 -1
- package/Server/Services/NetworkDeviceOidTemplateService.ts +201 -0
- package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +9 -1
- package/Server/Services/NetworkDeviceService.ts +209 -1
- package/Server/Services/OnCallDutyPolicyLabelRuleEngineService.ts +9 -1
- package/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.ts +9 -1
- package/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.ts +9 -1
- package/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.ts +9 -1
- package/Server/Services/PodmanHostLabelRuleEngineService.ts +9 -1
- package/Server/Services/PodmanHostOwnerRuleEngineService.ts +9 -1
- package/Server/Services/ProxmoxClusterLabelRuleEngineService.ts +9 -1
- package/Server/Services/ProxmoxClusterOwnerRuleEngineService.ts +9 -1
- package/Server/Services/RumApplicationLabelRuleEngineService.ts +9 -1
- package/Server/Services/RumApplicationOwnerRuleEngineService.ts +9 -1
- package/Server/Services/RunbookLabelRuleEngineService.ts +9 -1
- package/Server/Services/RunbookOwnerRuleEngineService.ts +9 -1
- package/Server/Services/RunbookRuleEngineService.ts +9 -1
- package/Server/Services/ScheduledMaintenanceLabelRuleEngineService.ts +9 -1
- package/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.ts +9 -1
- package/Server/Services/ScheduledMaintenanceReminderRuleService.ts +9 -1
- package/Server/Services/ServerlessFunctionLabelRuleEngineService.ts +9 -1
- package/Server/Services/ServerlessFunctionOwnerRuleEngineService.ts +9 -1
- package/Server/Services/ServiceLabelRuleEngineService.ts +9 -1
- package/Server/Services/ServiceOwnerRuleEngineService.ts +9 -1
- package/Server/Services/StatusPageLabelRuleEngineService.ts +9 -1
- package/Server/Services/StatusPageMonitorRuleEngineService.ts +7 -0
- package/Server/Services/StatusPageOwnerRuleEngineService.ts +9 -1
- package/Server/Services/TelemetrySourceMapService.ts +266 -23
- package/Server/Services/UserService.ts +27 -0
- package/Server/Services/WorkflowLabelRuleEngineService.ts +9 -1
- package/Server/Services/WorkflowOwnerRuleEngineService.ts +9 -1
- package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +186 -0
- package/Server/Utils/Monitor/CapturedMetricAttributeUtil.ts +245 -0
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +21 -2
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +55 -21
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +32 -0
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +15 -2
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +18 -1
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +10 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +34 -0
- package/Server/Utils/Rules/RuleEngineRuleRead.ts +48 -0
- package/Server/Utils/Telemetry/ExceptionSanitizer.ts +14 -1
- package/Server/Utils/Telemetry/LogExceptionExtractor.ts +14 -2
- package/Server/Utils/Telemetry/SourceMapResolver.ts +16 -5
- package/Server/Utils/Telemetry/StackTraceParser.ts +399 -0
- package/Tests/App/Dashboard/EventOverlayHook.test.tsx +125 -0
- package/Tests/App/Dashboard/HeaderImageAssets.test.tsx +93 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3 -3
- package/Tests/App/Dashboard/UserElementEmail.test.tsx +12 -4
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +1 -1
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +14 -0
- package/Tests/Models/DatabaseModels/ModelRegistryInvariants.test.ts +469 -0
- package/Tests/Models/SecurityDomainAccessControl.test.ts +429 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +657 -0
- package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +84 -6
- package/Tests/Server/API/TelemetryResolveStackTraceAPI.test.ts +805 -0
- package/Tests/Server/Infrastructure/Postgres/AddOnCallCalendarFeedsMigration.test.ts +32 -7
- package/Tests/Server/Middleware/IdentityRateLimit.test.ts +1144 -0
- package/Tests/Server/Middleware/MultipartFormData.test.ts +618 -3
- package/Tests/Server/Services/MonitorLabelRuleEngineScale.test.ts +520 -0
- package/Tests/Server/Services/NetworkDeviceOidTemplateService.test.ts +332 -0
- package/Tests/Server/Services/NetworkDeviceOidTemplateWriteGuards.test.ts +409 -0
- package/Tests/Server/Services/RuleEngineRuleFetchLimit.test.ts +239 -0
- package/Tests/Server/Services/TelemetrySourceMapService.test.ts +1210 -2
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +182 -0
- package/Tests/Server/Types/AnalyticsDatabase/SecurityEventModelPermission.test.ts +255 -0
- package/Tests/Server/Types/Database/Permissions/ReadBlockPermission.test.ts +212 -0
- package/Tests/Server/Types/Database/Permissions/SecurityRoleAccess.test.ts +413 -0
- package/Tests/Server/Utils/CodeRepository.test.ts +689 -0
- package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +495 -0
- package/Tests/Server/Utils/ExceptionSanitizer.test.ts +77 -0
- package/Tests/Server/Utils/Monitor/CapturedMetricAttributeUtil.test.ts +284 -0
- package/Tests/Server/Utils/Monitor/MonitorCustomMetricAttributes.test.ts +503 -0
- package/Tests/Server/Utils/Monitor/MonitorTemplatePrototypePollution.test.ts +106 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkLogWritePath.test.ts +33 -4
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +14 -4
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +44 -0
- package/Tests/Server/Utils/OpenAPISpec.test.ts +536 -0
- package/Tests/Server/Utils/Rules/RuleEngineRuleRead.test.ts +115 -0
- package/Tests/Server/Utils/StackTraceParser.test.ts +610 -0
- package/Tests/Server/Utils/Telemetry/LogExceptionExtractor.test.ts +0 -0
- package/Tests/Server/Utils/Telemetry/SourceMapLimits.test.ts +656 -0
- package/Tests/Server/Utils/Telemetry/SourceMapResolver.test.ts +100 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpOidListUtil.test.ts +454 -0
- package/Tests/Types/SecurityRolePermissions.test.ts +193 -0
- package/Tests/UI/Components/Charts/AnnotationLayout.test.ts +773 -0
- package/Tests/UI/Components/Charts/ChartAnnotationRail.test.tsx +789 -0
- package/Tests/UI/Components/Charts/ChartBucketIdentity.test.ts +254 -0
- package/Tests/UI/Components/Charts/TimeAnnotation.test.ts +471 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +405 -0
- package/Tests/UI/Components/ErrorMessageRefreshControl.test.tsx +83 -0
- package/Tests/UI/Components/MarkdownConverters.test.ts +686 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableDeleteAndEmptyStates.test.tsx +341 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +5 -5
- package/Tests/UI/Components/PendingProjectInvitations.test.tsx +1 -1
- package/Tests/UI/Components/TableSortAndMobileColumns.test.tsx +195 -0
- package/Tests/UI/Components/XAxis.test.ts +270 -5
- package/Tests/UI/Components/XAxisDaylightSaving.test.ts +113 -0
- package/Tests/UI/Styles/ChartFocusRing.test.ts +153 -0
- package/Tests/UI/Styles/ChartFocusRingCoverage.test.tsx +377 -0
- package/Tests/UI/Styles/ThemeStylesheet.ts +162 -0
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +507 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +951 -1
- package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +238 -0
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +1056 -0
- package/Tests/Utils/NetworkDiscovery/ReverseDnsNameUtil.test.ts +882 -0
- package/Types/Date.ts +39 -0
- package/Types/Monitor/SnmpMonitor/SnmpOidListUtil.ts +333 -0
- package/Types/Permission.ts +96 -0
- package/Types/Rum/SessionReplay.ts +21 -0
- package/Types/Telemetry/SourceMap.ts +8 -0
- package/UI/Components/Charts/ChartLibrary/Annotations/AnnotationHoverCard.tsx +176 -0
- package/UI/Components/Charts/ChartLibrary/Annotations/AnnotationLayout.ts +745 -0
- package/UI/Components/Charts/ChartLibrary/Annotations/ChartAnnotationLayer.tsx +576 -0
- package/UI/Components/Charts/ChartLibrary/Annotations/UseChartAnnotations.tsx +204 -0
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +491 -544
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +324 -372
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +487 -540
- package/UI/Components/Charts/ChartLibrary/Types/FormattedReferenceRegion.ts +7 -3
- package/UI/Components/Charts/ChartLibrary/Types/FormattedTimeReferenceLine.ts +14 -3
- package/UI/Components/Charts/Types/ChartEventKind.ts +13 -0
- package/UI/Components/Charts/Types/ReferenceRegionProps.ts +6 -0
- package/UI/Components/Charts/Types/TimeReferenceLineProps.ts +20 -3
- package/UI/Components/Charts/Utils/TimeAnnotation.ts +69 -35
- package/UI/Components/Charts/Utils/XAxis.ts +125 -18
- package/UI/Components/EditionLabel/EditionLabel.tsx +280 -26
- package/UI/Components/ErrorMessage/ErrorMessage.tsx +21 -10
- package/UI/Components/Feed/FeedItem.tsx +4 -5
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +1 -2
- package/UI/Components/Header/UserProfile/UserProfile.tsx +1 -2
- package/UI/Components/Image/Image.tsx +20 -3
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +1 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +150 -24
- package/UI/Components/Table/TableHeader.tsx +64 -48
- package/UI/Components/Table/TableRow.tsx +13 -3
- package/UI/Styles/Theme.css +38 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +271 -0
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +6 -0
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +141 -10
- package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +55 -3
- package/Utils/NetworkDiscovery/ReverseDnsNameUtil.ts +151 -0
- package/Utils/Rules/RuleEngineLimits.ts +32 -0
- package/build/dist/Models/AnalyticsModels/SecurityEvent.js +48 -16
- package/build/dist/Models/AnalyticsModels/SecurityEvent.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/ThreatIntelIndicator.js +10 -5
- package/build/dist/Models/AnalyticsModels/ThreatIntelIndicator.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertSeverity.js +46 -1
- package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DetectionRule.js +16 -5
- package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js +14 -5
- package/build/dist/Models/DatabaseModels/GoogleSecOpsConnection.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentSeverity.js +46 -1
- package/build/dist/Models/DatabaseModels/IncidentSeverity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +115 -3
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +88 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js +519 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceOidTemplate.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js +16 -5
- package/build/dist/Models/DatabaseModels/ThreatIntelFeed.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +293 -176
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +31 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +83 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790500000000-AddNetworkDeviceOidTemplate.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790500000000-AddNetworkDeviceOidTemplate.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790600000000-AddAutoImportRuleOidTemplate.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790600000000-AddAutoImportRuleOidTemplate.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MultipartFormData.js +93 -28
- package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertEpisodeOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertGroupingEngineService.js +8 -1
- package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOnCallRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AlertPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/AlertReminderRuleService.js +8 -1
- package/build/dist/Server/Services/AlertReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +8 -1
- package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/CephClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/CephClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/CloudResourceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/CloudResourceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/DashboardLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/DashboardOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/DockerHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/DockerHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/DockerSwarmClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/DockerSwarmClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/HostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/HostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentEpisodeLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentEpisodeOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentEpisodeOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentEpisodePrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentOnCallRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncidentPrivacyRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentReminderRuleService.js +8 -1
- package/build/dist/Server/Services/IncidentReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSlaRuleService.js +8 -1
- package/build/dist/Server/Services/IncidentSlaRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncomingCallPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IncomingCallPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IoTFleetLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/IoTFleetOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/KubernetesClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/KubernetesClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesResourceService.js +5 -1
- package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/MonitorLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/MonitorOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +30 -21
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +64 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceOidTemplateService.js +180 -0
- package/build/dist/Server/Services/NetworkDeviceOidTemplateService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +154 -1
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/OnCallDutyPolicyLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/OnCallDutyPolicyOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/PodmanHostLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/PodmanHostOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ProxmoxClusterLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ProxmoxClusterOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/RumApplicationLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/RumApplicationOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/RunbookLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/RunbookOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/RunbookRuleEngineService.js +8 -1
- package/build/dist/Server/Services/RunbookRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ScheduledMaintenanceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js +8 -1
- package/build/dist/Server/Services/ScheduledMaintenanceReminderRuleService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ServerlessFunctionLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ServerlessFunctionOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ServiceLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/ServiceOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/StatusPageLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +6 -0
- package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/StatusPageOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/TelemetrySourceMapService.js +213 -19
- package/build/dist/Server/Services/TelemetrySourceMapService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +25 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js +8 -1
- package/build/dist/Server/Services/WorkflowLabelRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js +8 -1
- package/build/dist/Server/Services/WorkflowOwnerRuleEngineService.js.map +1 -1
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +145 -0
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/CapturedMetricAttributeUtil.js +201 -0
- package/build/dist/Server/Utils/Monitor/CapturedMetricAttributeUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +19 -2
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +42 -23
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +29 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +11 -2
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +16 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +10 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +33 -0
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
- package/build/dist/Server/Utils/Rules/RuleEngineRuleRead.js +37 -0
- package/build/dist/Server/Utils/Rules/RuleEngineRuleRead.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ExceptionSanitizer.js +12 -1
- package/build/dist/Server/Utils/Telemetry/ExceptionSanitizer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js +14 -2
- package/build/dist/Server/Utils/Telemetry/LogExceptionExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/SourceMapResolver.js +15 -5
- package/build/dist/Server/Utils/Telemetry/SourceMapResolver.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/StackTraceParser.js +307 -0
- package/build/dist/Server/Utils/Telemetry/StackTraceParser.js.map +1 -1
- package/build/dist/Types/Date.js +27 -0
- package/build/dist/Types/Date.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpOidListUtil.js +253 -0
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpOidListUtil.js.map +1 -0
- package/build/dist/Types/Permission.js +86 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Rum/SessionReplay.js +19 -0
- package/build/dist/Types/Rum/SessionReplay.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationHoverCard.js +83 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationHoverCard.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationLayout.js +531 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/AnnotationLayout.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/ChartAnnotationLayer.js +264 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/ChartAnnotationLayer.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/UseChartAnnotations.js +122 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Annotations/UseChartAnnotations.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +213 -233
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +139 -152
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +212 -232
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Types/ChartEventKind.js +14 -0
- package/build/dist/UI/Components/Charts/Types/ChartEventKind.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js +57 -28
- package/build/dist/UI/Components/Charts/Utils/TimeAnnotation.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +103 -17
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +198 -23
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js +15 -5
- package/build/dist/UI/Components/ErrorMessage/ErrorMessage.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +4 -5
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -2
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Header/UserProfile/UserProfile.js.map +1 -1
- package/build/dist/UI/Components/Image/Image.js +6 -1
- package/build/dist/UI/Components/Image/Image.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/MemberRoleAssignment/MemberRoleAssignment.js +1 -2
- package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +104 -23
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +20 -22
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +13 -4
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +153 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +127 -7
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +50 -3
- package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/ReverseDnsNameUtil.js +132 -0
- package/build/dist/Utils/NetworkDiscovery/ReverseDnsNameUtil.js.map +1 -0
- package/build/dist/Utils/Rules/RuleEngineLimits.js +31 -0
- package/build/dist/Utils/Rules/RuleEngineLimits.js.map +1 -0
- package/jest.config.json +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
import GlobalConfigAPI from "../../../Server/API/GlobalConfigAPI";
|
|
2
|
+
import MasterAdminAuthorization from "../../../Server/Middleware/MasterAdminAuthorization";
|
|
3
|
+
import GlobalConfigService from "../../../Server/Services/GlobalConfigService";
|
|
4
|
+
import UserService from "../../../Server/Services/UserService";
|
|
5
|
+
import Response from "../../../Server/Utils/Response";
|
|
6
|
+
import GlobalConfig from "../../../Models/DatabaseModels/GlobalConfig";
|
|
7
|
+
import HTTPErrorResponse from "../../../Types/API/HTTPErrorResponse";
|
|
8
|
+
import HTTPResponse from "../../../Types/API/HTTPResponse";
|
|
9
|
+
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
10
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
11
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
12
|
+
import PositiveNumber from "../../../Types/PositiveNumber";
|
|
13
|
+
import API from "../../../Utils/API";
|
|
14
|
+
import {
|
|
15
|
+
NextFunction,
|
|
16
|
+
OneUptimeRequest,
|
|
17
|
+
OneUptimeResponse,
|
|
18
|
+
} from "../../../Server/Utils/Express";
|
|
19
|
+
import { mockRouter } from "./Helpers";
|
|
20
|
+
import { beforeEach, afterEach, describe, expect, it } from "@jest/globals";
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* The self-hosted half of the licence: activating a key, refreshing the key
|
|
24
|
+
* the installation already holds, and reporting what the seat limit means
|
|
25
|
+
* right now.
|
|
26
|
+
*
|
|
27
|
+
* Two things brought this suite into being.
|
|
28
|
+
*
|
|
29
|
+
* The seat limit is set on oneuptime.com and changes on any day — a customer
|
|
30
|
+
* buys ten more seats at noon. It reaches the installation through the daily
|
|
31
|
+
* report job, so until now the only way to apply it sooner was for somebody to
|
|
32
|
+
* re-type the licence key into a box that is HIDDEN while the licence is
|
|
33
|
+
* valid. /license/refresh is that missing button, and it exists precisely
|
|
34
|
+
* because the installation now refuses users above the limit: waiting a day to
|
|
35
|
+
* learn about seats you have already paid for is a different feature when the
|
|
36
|
+
* old number is being enforced.
|
|
37
|
+
*
|
|
38
|
+
* And both writes used to run on UserMiddleware.getUserMiddleware, which lets
|
|
39
|
+
* anonymous callers through — it has to, because the GET on the same path
|
|
40
|
+
* serves the signed-out login page. That made the route that decides this
|
|
41
|
+
* installation's seat ceiling reachable without signing in at all.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
/*
|
|
45
|
+
* PasswordHash carries a pre-existing TS diagnostic that fails any suite whose
|
|
46
|
+
* require graph reaches it, and BaseAPI's graph still reaches it. Replaced with
|
|
47
|
+
* a factory rather than automocked, because an automock still type-checks the
|
|
48
|
+
* real file.
|
|
49
|
+
*/
|
|
50
|
+
jest.mock("../../../Server/Utils/PasswordHash", () => {
|
|
51
|
+
return {
|
|
52
|
+
__esModule: true,
|
|
53
|
+
default: {
|
|
54
|
+
hash: jest.fn(),
|
|
55
|
+
verify: jest.fn(),
|
|
56
|
+
generateSalt: jest.fn(),
|
|
57
|
+
needsUpgrade: jest.fn(),
|
|
58
|
+
applyPepper: jest.fn(),
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// Same story as PasswordHash: a local-only diagnostic in a module dragged in.
|
|
64
|
+
jest.mock("../../../Server/Utils/VerificationCode", () => {
|
|
65
|
+
return {
|
|
66
|
+
__esModule: true,
|
|
67
|
+
default: {
|
|
68
|
+
generate: jest.fn(),
|
|
69
|
+
hashCode: jest.fn(),
|
|
70
|
+
isHashEqual: jest.fn(),
|
|
71
|
+
generateUnusableHash: jest.fn(),
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
jest.mock("../../../Server/Utils/Express", () => {
|
|
77
|
+
return {
|
|
78
|
+
getRouter: () => {
|
|
79
|
+
return mockRouter;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
jest.mock("../../../Server/Utils/Response", () => {
|
|
85
|
+
return {
|
|
86
|
+
sendEntityArrayResponse: jest.fn().mockImplementation((...args: []) => {
|
|
87
|
+
return args;
|
|
88
|
+
}),
|
|
89
|
+
sendJsonObjectResponse: jest.fn().mockImplementation((...args: []) => {
|
|
90
|
+
return args;
|
|
91
|
+
}),
|
|
92
|
+
sendEmptySuccessResponse: jest.fn(),
|
|
93
|
+
sendEntityResponse: jest.fn().mockImplementation((...args: []) => {
|
|
94
|
+
return args;
|
|
95
|
+
}),
|
|
96
|
+
sendErrorResponse: jest.fn().mockImplementation((...args: []) => {
|
|
97
|
+
return args;
|
|
98
|
+
}),
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
/*
|
|
103
|
+
* The deployment flags live on globalThis rather than in module-scope
|
|
104
|
+
* variables, and the getters below reference nothing but globalThis.
|
|
105
|
+
*
|
|
106
|
+
* jest hoists the mock factory above every declaration in this file, and
|
|
107
|
+
* BaseAPI's import graph reaches IncidentFeedService, which reads
|
|
108
|
+
* IsBillingEnabled at module scope. That read lands inside these getters
|
|
109
|
+
* during the import — before a `let` in this file has initialised — and a
|
|
110
|
+
* getter that closed over one would throw a temporal-dead-zone
|
|
111
|
+
* ReferenceError before a single test ran. Absent flags read as false, which
|
|
112
|
+
* is a fine thing for an unrelated service to see on its way past.
|
|
113
|
+
*
|
|
114
|
+
* They are also live accessors rather than values: the routes read the flags
|
|
115
|
+
* when they run, and object spread would flatten them at import time.
|
|
116
|
+
*/
|
|
117
|
+
const BILLING_FLAG_KEY: string = "__oneUptimeTestIsBillingEnabled";
|
|
118
|
+
const ENTERPRISE_FLAG_KEY: string = "__oneUptimeTestIsEnterpriseEdition";
|
|
119
|
+
|
|
120
|
+
type SetDeploymentFlagFunction = (key: string, value: boolean) => void;
|
|
121
|
+
|
|
122
|
+
const setDeploymentFlag: SetDeploymentFlagFunction = (
|
|
123
|
+
key: string,
|
|
124
|
+
value: boolean,
|
|
125
|
+
): void => {
|
|
126
|
+
(globalThis as unknown as Record<string, unknown>)[key] = value;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
jest.mock("../../../Server/EnvironmentConfig", () => {
|
|
130
|
+
const actual: Record<string, unknown> = jest.requireActual(
|
|
131
|
+
"../../../Server/EnvironmentConfig",
|
|
132
|
+
) as Record<string, unknown>;
|
|
133
|
+
|
|
134
|
+
const mocked: Record<string, unknown> = {
|
|
135
|
+
...actual,
|
|
136
|
+
__esModule: true,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
Object.defineProperty(mocked, "IsBillingEnabled", {
|
|
140
|
+
get: (): boolean => {
|
|
141
|
+
return (
|
|
142
|
+
(globalThis as unknown as Record<string, unknown>)[
|
|
143
|
+
"__oneUptimeTestIsBillingEnabled"
|
|
144
|
+
] === true
|
|
145
|
+
);
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
Object.defineProperty(mocked, "IsEnterpriseEdition", {
|
|
150
|
+
get: (): boolean => {
|
|
151
|
+
return (
|
|
152
|
+
(globalThis as unknown as Record<string, unknown>)[
|
|
153
|
+
"__oneUptimeTestIsEnterpriseEdition"
|
|
154
|
+
] === true
|
|
155
|
+
);
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
return mocked;
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* Factories rather than automocks. An automock still loads the real module to
|
|
164
|
+
* copy its shape, and loading UserService drags in most of the service graph -
|
|
165
|
+
* some of which reads IsBillingEnabled at module scope, before the flags above
|
|
166
|
+
* have initialised. Nothing here needs the real implementations.
|
|
167
|
+
*/
|
|
168
|
+
jest.mock("../../../Utils/API", () => {
|
|
169
|
+
return {
|
|
170
|
+
__esModule: true,
|
|
171
|
+
default: {
|
|
172
|
+
post: jest.fn(),
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
jest.mock("../../../Server/Services/GlobalConfigService", () => {
|
|
178
|
+
return {
|
|
179
|
+
__esModule: true,
|
|
180
|
+
default: {
|
|
181
|
+
findOneById: jest.fn(),
|
|
182
|
+
updateOneById: jest.fn(),
|
|
183
|
+
create: jest.fn(),
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
jest.mock("../../../Server/Services/UserService", () => {
|
|
189
|
+
return {
|
|
190
|
+
__esModule: true,
|
|
191
|
+
default: {
|
|
192
|
+
countBy: jest.fn(),
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const LICENSE_ROUTE: string = "/global-config/license";
|
|
198
|
+
const REFRESH_ROUTE: string = "/global-config/license/refresh";
|
|
199
|
+
|
|
200
|
+
const STORED_LICENSE_KEY: string = "acme-stored-license-key";
|
|
201
|
+
const INSTANCE_ID: ObjectID = ObjectID.generate();
|
|
202
|
+
|
|
203
|
+
type MakeStoredConfigFunction = (
|
|
204
|
+
overrides?: Record<string, unknown>,
|
|
205
|
+
) => GlobalConfig;
|
|
206
|
+
|
|
207
|
+
const makeStoredConfig: MakeStoredConfigFunction = (
|
|
208
|
+
overrides?: Record<string, unknown>,
|
|
209
|
+
): GlobalConfig => {
|
|
210
|
+
const config: GlobalConfig = new GlobalConfig();
|
|
211
|
+
config.id = ObjectID.getZeroObjectID();
|
|
212
|
+
config.instanceId = INSTANCE_ID;
|
|
213
|
+
config.enterpriseLicenseKey = STORED_LICENSE_KEY;
|
|
214
|
+
|
|
215
|
+
return Object.assign(config, overrides || {});
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
type LicenseServerPayloadFunction = (
|
|
219
|
+
overrides?: Record<string, unknown>,
|
|
220
|
+
) => JSONObject;
|
|
221
|
+
|
|
222
|
+
const licenseServerPayload: LicenseServerPayloadFunction = (
|
|
223
|
+
overrides?: Record<string, unknown>,
|
|
224
|
+
): JSONObject => {
|
|
225
|
+
return {
|
|
226
|
+
companyName: "Acme Inc",
|
|
227
|
+
expiresAt: "2030-01-01T00:00:00.000Z",
|
|
228
|
+
licenseKey: STORED_LICENSE_KEY,
|
|
229
|
+
token: "signed.jwt.token",
|
|
230
|
+
isEvaluationLicense: false,
|
|
231
|
+
userLimit: 150,
|
|
232
|
+
currentUserCount: 42,
|
|
233
|
+
userCountUpdatedAt: "2026-01-01T00:00:00.000Z",
|
|
234
|
+
instances: [],
|
|
235
|
+
...overrides,
|
|
236
|
+
};
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
type GetResponseBodyFunction = () => JSONObject;
|
|
240
|
+
|
|
241
|
+
const getResponseBody: GetResponseBodyFunction = (): JSONObject => {
|
|
242
|
+
const calls: Array<Array<unknown>> = (
|
|
243
|
+
Response.sendJsonObjectResponse as unknown as jest.Mock
|
|
244
|
+
).mock.calls as Array<Array<unknown>>;
|
|
245
|
+
|
|
246
|
+
expect(calls).toHaveLength(1);
|
|
247
|
+
|
|
248
|
+
return calls[0]![2] as JSONObject;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
type GetStoredUpdateFunction = () => JSONObject;
|
|
252
|
+
|
|
253
|
+
const getStoredUpdate: GetStoredUpdateFunction = (): JSONObject => {
|
|
254
|
+
const calls: Array<Array<unknown>> = (
|
|
255
|
+
GlobalConfigService.updateOneById as unknown as jest.Mock
|
|
256
|
+
).mock.calls as Array<Array<unknown>>;
|
|
257
|
+
|
|
258
|
+
expect(calls.length).toBeGreaterThan(0);
|
|
259
|
+
|
|
260
|
+
return (calls[0]![0] as Record<string, unknown>)["data"] as JSONObject;
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
describe("GlobalConfigAPI licence routes", () => {
|
|
264
|
+
let mockRequest: OneUptimeRequest;
|
|
265
|
+
let mockResponse: OneUptimeResponse;
|
|
266
|
+
let nextFunction: NextFunction;
|
|
267
|
+
|
|
268
|
+
type CallRouteFunction = (route: string) => Promise<void>;
|
|
269
|
+
|
|
270
|
+
const callRoute: CallRouteFunction = async (route: string): Promise<void> => {
|
|
271
|
+
await mockRouter
|
|
272
|
+
.match("post", route)
|
|
273
|
+
.handlerFunction(mockRequest, mockResponse, nextFunction);
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
type NextErrorFunction = () => Error;
|
|
277
|
+
|
|
278
|
+
const nextError: NextErrorFunction = (): Error => {
|
|
279
|
+
const calls: Array<Array<unknown>> = (nextFunction as unknown as jest.Mock)
|
|
280
|
+
.mock.calls as Array<Array<unknown>>;
|
|
281
|
+
|
|
282
|
+
expect(calls).toHaveLength(1);
|
|
283
|
+
|
|
284
|
+
return calls[0]![0] as Error;
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
beforeEach(() => {
|
|
288
|
+
jest.clearAllMocks();
|
|
289
|
+
mockRouter.routes = [];
|
|
290
|
+
setDeploymentFlag(BILLING_FLAG_KEY, false);
|
|
291
|
+
setDeploymentFlag(ENTERPRISE_FLAG_KEY, true);
|
|
292
|
+
|
|
293
|
+
new GlobalConfigAPI();
|
|
294
|
+
|
|
295
|
+
GlobalConfigService.findOneById = jest
|
|
296
|
+
.fn()
|
|
297
|
+
.mockResolvedValue(makeStoredConfig());
|
|
298
|
+
GlobalConfigService.updateOneById = jest.fn().mockResolvedValue(undefined);
|
|
299
|
+
GlobalConfigService.create = jest.fn().mockResolvedValue(undefined);
|
|
300
|
+
|
|
301
|
+
UserService.countBy = jest.fn().mockResolvedValue(new PositiveNumber(42));
|
|
302
|
+
|
|
303
|
+
(API.post as unknown as jest.Mock) = jest
|
|
304
|
+
.fn()
|
|
305
|
+
.mockResolvedValue(
|
|
306
|
+
new HTTPResponse<JSONObject>(200, licenseServerPayload(), {}),
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
mockRequest = {
|
|
310
|
+
body: {},
|
|
311
|
+
} as unknown as OneUptimeRequest;
|
|
312
|
+
|
|
313
|
+
mockResponse = {
|
|
314
|
+
send: jest.fn(),
|
|
315
|
+
json: jest.fn(),
|
|
316
|
+
status: jest.fn().mockReturnThis(),
|
|
317
|
+
} as unknown as OneUptimeResponse;
|
|
318
|
+
|
|
319
|
+
nextFunction = jest.fn();
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
afterEach(() => {
|
|
323
|
+
jest.restoreAllMocks();
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
describe("who is allowed to write the licence", () => {
|
|
327
|
+
/*
|
|
328
|
+
* The seat limit these routes store is the number UserService refuses new
|
|
329
|
+
* users against. UserMiddleware.getUserMiddleware — which the GET on the
|
|
330
|
+
* same path uses, and has to, because it serves the signed-out login page —
|
|
331
|
+
* lets anonymous callers straight through, so it is not a guard here.
|
|
332
|
+
*/
|
|
333
|
+
it.each([
|
|
334
|
+
["activating a licence key", LICENSE_ROUTE],
|
|
335
|
+
["refreshing the stored licence", REFRESH_ROUTE],
|
|
336
|
+
])("requires a master admin for %s", (_label: string, route: string) => {
|
|
337
|
+
expect(mockRouter.match("post", route).middlewares).toContain(
|
|
338
|
+
MasterAdminAuthorization.isAuthorizedMasterAdminMiddleware,
|
|
339
|
+
);
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it("still serves the licence GET to anyone, so the login page keeps working", () => {
|
|
343
|
+
expect(mockRouter.match("get", LICENSE_ROUTE).middlewares).not.toContain(
|
|
344
|
+
MasterAdminAuthorization.isAuthorizedMasterAdminMiddleware,
|
|
345
|
+
);
|
|
346
|
+
});
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
describe("POST /global-config/license - activating a key", () => {
|
|
350
|
+
it("rejects a request with no licence key", async () => {
|
|
351
|
+
mockRequest.body = {};
|
|
352
|
+
|
|
353
|
+
await callRoute(LICENSE_ROUTE);
|
|
354
|
+
|
|
355
|
+
expect(nextError()).toBeInstanceOf(BadDataException);
|
|
356
|
+
expect(API.post).not.toHaveBeenCalled();
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it("rejects a licence key that is only whitespace", async () => {
|
|
360
|
+
mockRequest.body = { licenseKey: " " };
|
|
361
|
+
|
|
362
|
+
await callRoute(LICENSE_ROUTE);
|
|
363
|
+
|
|
364
|
+
expect(nextError()).toBeInstanceOf(BadDataException);
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it("validates the supplied key against oneuptime.com", async () => {
|
|
368
|
+
mockRequest.body = { licenseKey: " a-new-key " };
|
|
369
|
+
|
|
370
|
+
await callRoute(LICENSE_ROUTE);
|
|
371
|
+
|
|
372
|
+
const sent: JSONObject = (
|
|
373
|
+
(API.post as unknown as jest.Mock).mock.calls[0]![0] as Record<
|
|
374
|
+
string,
|
|
375
|
+
JSONObject
|
|
376
|
+
>
|
|
377
|
+
)["data"] as JSONObject;
|
|
378
|
+
|
|
379
|
+
expect(sent["licenseKey"]).toBe("a-new-key");
|
|
380
|
+
expect(sent["instanceId"]).toBe(INSTANCE_ID.toString());
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it("stores the seat limit the licence server reported", async () => {
|
|
384
|
+
mockRequest.body = { licenseKey: STORED_LICENSE_KEY };
|
|
385
|
+
|
|
386
|
+
await callRoute(LICENSE_ROUTE);
|
|
387
|
+
|
|
388
|
+
expect(getStoredUpdate()["enterpriseLicenseUserLimit"]).toBe(150);
|
|
389
|
+
});
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
describe("POST /global-config/license/refresh", () => {
|
|
393
|
+
/*
|
|
394
|
+
* The whole point of the route: no key in the body. A refresh that
|
|
395
|
+
* accepted one would be an activation with a friendlier name, and a
|
|
396
|
+
* mistyped key would be able to replace a working licence by accident.
|
|
397
|
+
*/
|
|
398
|
+
it("refreshes using the stored key and ignores anything in the body", async () => {
|
|
399
|
+
mockRequest.body = { licenseKey: "somebody-elses-key" };
|
|
400
|
+
|
|
401
|
+
await callRoute(REFRESH_ROUTE);
|
|
402
|
+
|
|
403
|
+
const sent: JSONObject = (
|
|
404
|
+
(API.post as unknown as jest.Mock).mock.calls[0]![0] as Record<
|
|
405
|
+
string,
|
|
406
|
+
JSONObject
|
|
407
|
+
>
|
|
408
|
+
)["data"] as JSONObject;
|
|
409
|
+
|
|
410
|
+
expect(sent["licenseKey"]).toBe(STORED_LICENSE_KEY);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it("refuses to refresh an installation that has no licence key yet", async () => {
|
|
414
|
+
GlobalConfigService.findOneById = jest
|
|
415
|
+
.fn()
|
|
416
|
+
.mockResolvedValue(
|
|
417
|
+
makeStoredConfig({ enterpriseLicenseKey: undefined }),
|
|
418
|
+
);
|
|
419
|
+
|
|
420
|
+
await callRoute(REFRESH_ROUTE);
|
|
421
|
+
|
|
422
|
+
expect(nextError()).toBeInstanceOf(BadDataException);
|
|
423
|
+
expect(API.post).not.toHaveBeenCalled();
|
|
424
|
+
});
|
|
425
|
+
|
|
426
|
+
it("refuses to refresh when there is no config row at all", async () => {
|
|
427
|
+
GlobalConfigService.findOneById = jest.fn().mockResolvedValue(null);
|
|
428
|
+
|
|
429
|
+
await callRoute(REFRESH_ROUTE);
|
|
430
|
+
|
|
431
|
+
expect(nextError()).toBeInstanceOf(BadDataException);
|
|
432
|
+
expect(API.post).not.toHaveBeenCalled();
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
/*
|
|
436
|
+
* The reason the button exists. The customer raised the limit on
|
|
437
|
+
* oneuptime.com; the stored 50 is what this installation is refusing users
|
|
438
|
+
* against until something writes the new number down.
|
|
439
|
+
*/
|
|
440
|
+
it("applies a seat limit that has been raised on oneuptime.com", async () => {
|
|
441
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
442
|
+
new HTTPResponse<JSONObject>(
|
|
443
|
+
200,
|
|
444
|
+
licenseServerPayload({ userLimit: 500 }),
|
|
445
|
+
{},
|
|
446
|
+
),
|
|
447
|
+
);
|
|
448
|
+
|
|
449
|
+
await callRoute(REFRESH_ROUTE);
|
|
450
|
+
|
|
451
|
+
expect(getStoredUpdate()["enterpriseLicenseUserLimit"]).toBe(500);
|
|
452
|
+
expect(getResponseBody()["userLimit"]).toBe(500);
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
it("applies a seat limit that has been lowered on oneuptime.com", async () => {
|
|
456
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
457
|
+
new HTTPResponse<JSONObject>(
|
|
458
|
+
200,
|
|
459
|
+
licenseServerPayload({ userLimit: 5 }),
|
|
460
|
+
{},
|
|
461
|
+
),
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
await callRoute(REFRESH_ROUTE);
|
|
465
|
+
|
|
466
|
+
expect(getStoredUpdate()["enterpriseLicenseUserLimit"]).toBe(5);
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
it("clears the seat limit when the licence no longer carries one", async () => {
|
|
470
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
471
|
+
new HTTPResponse<JSONObject>(
|
|
472
|
+
200,
|
|
473
|
+
licenseServerPayload({ userLimit: null }),
|
|
474
|
+
{},
|
|
475
|
+
),
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
await callRoute(REFRESH_ROUTE);
|
|
479
|
+
|
|
480
|
+
expect(getStoredUpdate()["enterpriseLicenseUserLimit"]).toBeNull();
|
|
481
|
+
});
|
|
482
|
+
|
|
483
|
+
it("refreshes the expiry as well as the seat limit", async () => {
|
|
484
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
485
|
+
new HTTPResponse<JSONObject>(
|
|
486
|
+
200,
|
|
487
|
+
licenseServerPayload({ expiresAt: "2031-06-01T00:00:00.000Z" }),
|
|
488
|
+
{},
|
|
489
|
+
),
|
|
490
|
+
);
|
|
491
|
+
|
|
492
|
+
await callRoute(REFRESH_ROUTE);
|
|
493
|
+
|
|
494
|
+
expect(
|
|
495
|
+
(
|
|
496
|
+
getStoredUpdate()["enterpriseLicenseExpiresAt"] as unknown as Date
|
|
497
|
+
).toISOString(),
|
|
498
|
+
).toBe("2031-06-01T00:00:00.000Z");
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
/*
|
|
502
|
+
* An installation that cannot reach oneuptime.com must be told so rather
|
|
503
|
+
* than quietly keeping the old terms and reporting success — the
|
|
504
|
+
* administrator pressed this button precisely because they believe the old
|
|
505
|
+
* terms are wrong.
|
|
506
|
+
*/
|
|
507
|
+
it("surfaces a failure from the licence server instead of storing anything", async () => {
|
|
508
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
509
|
+
new HTTPErrorResponse(500, { message: "License key is invalid" }, {}),
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
await callRoute(REFRESH_ROUTE);
|
|
513
|
+
|
|
514
|
+
const error: Error = nextError();
|
|
515
|
+
|
|
516
|
+
expect(error).toBeInstanceOf(BadDataException);
|
|
517
|
+
expect(error.message).toBe("License key is invalid");
|
|
518
|
+
expect(GlobalConfigService.updateOneById).not.toHaveBeenCalled();
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it("does not store anything when the returned expiry is not a date", async () => {
|
|
522
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
523
|
+
new HTTPResponse<JSONObject>(
|
|
524
|
+
200,
|
|
525
|
+
licenseServerPayload({ expiresAt: "the-first-of-never" }),
|
|
526
|
+
{},
|
|
527
|
+
),
|
|
528
|
+
);
|
|
529
|
+
|
|
530
|
+
await callRoute(REFRESH_ROUTE);
|
|
531
|
+
|
|
532
|
+
expect(nextError()).toBeInstanceOf(BadDataException);
|
|
533
|
+
expect(GlobalConfigService.updateOneById).not.toHaveBeenCalled();
|
|
534
|
+
});
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
describe("the seat enforcement the response reports", () => {
|
|
538
|
+
it("reports the seats in use against the freshly refreshed limit", async () => {
|
|
539
|
+
UserService.countBy = jest.fn().mockResolvedValue(new PositiveNumber(42));
|
|
540
|
+
|
|
541
|
+
await callRoute(REFRESH_ROUTE);
|
|
542
|
+
|
|
543
|
+
const body: JSONObject = getResponseBody();
|
|
544
|
+
|
|
545
|
+
expect(body["isSeatLimitEnforced"]).toBe(true);
|
|
546
|
+
expect(body["seatsInUse"]).toBe(42);
|
|
547
|
+
expect(body["seatsRemaining"]).toBe(108);
|
|
548
|
+
expect(body["canAddMoreUsers"]).toBe(true);
|
|
549
|
+
});
|
|
550
|
+
|
|
551
|
+
/*
|
|
552
|
+
* The live count is what enforcement uses, and it is allowed to be higher
|
|
553
|
+
* than the licence-wide figure oneuptime.com last computed — that figure is
|
|
554
|
+
* up to a day old.
|
|
555
|
+
*/
|
|
556
|
+
it("prefers the live user count over the licence server's stale one", async () => {
|
|
557
|
+
UserService.countBy = jest
|
|
558
|
+
.fn()
|
|
559
|
+
.mockResolvedValue(new PositiveNumber(150));
|
|
560
|
+
|
|
561
|
+
await callRoute(REFRESH_ROUTE);
|
|
562
|
+
|
|
563
|
+
const body: JSONObject = getResponseBody();
|
|
564
|
+
|
|
565
|
+
expect(body["seatsInUse"]).toBe(150);
|
|
566
|
+
expect(body["seatsRemaining"]).toBe(0);
|
|
567
|
+
expect(body["canAddMoreUsers"]).toBe(false);
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it("says the limit is not enforced when the licence has none", async () => {
|
|
571
|
+
(API.post as unknown as jest.Mock).mockResolvedValue(
|
|
572
|
+
new HTTPResponse<JSONObject>(
|
|
573
|
+
200,
|
|
574
|
+
licenseServerPayload({ userLimit: null }),
|
|
575
|
+
{},
|
|
576
|
+
),
|
|
577
|
+
);
|
|
578
|
+
|
|
579
|
+
await callRoute(REFRESH_ROUTE);
|
|
580
|
+
|
|
581
|
+
const body: JSONObject = getResponseBody();
|
|
582
|
+
|
|
583
|
+
expect(body["isSeatLimitEnforced"]).toBe(false);
|
|
584
|
+
expect(body["seatsInUse"]).toBeNull();
|
|
585
|
+
expect(body["canAddMoreUsers"]).toBe(true);
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
it("says the limit is not enforced on Community Edition", async () => {
|
|
589
|
+
setDeploymentFlag(ENTERPRISE_FLAG_KEY, false);
|
|
590
|
+
|
|
591
|
+
await callRoute(REFRESH_ROUTE);
|
|
592
|
+
|
|
593
|
+
const body: JSONObject = getResponseBody();
|
|
594
|
+
|
|
595
|
+
expect(body["isSeatLimitEnforced"]).toBe(false);
|
|
596
|
+
expect(body["canAddMoreUsers"]).toBe(true);
|
|
597
|
+
expect(UserService.countBy).not.toHaveBeenCalled();
|
|
598
|
+
});
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
describe("GET /global-config/license", () => {
|
|
602
|
+
type CallGetFunction = () => Promise<void>;
|
|
603
|
+
|
|
604
|
+
const callGet: CallGetFunction = async (): Promise<void> => {
|
|
605
|
+
await mockRouter
|
|
606
|
+
.match("get", LICENSE_ROUTE)
|
|
607
|
+
.handlerFunction(mockRequest, mockResponse, nextFunction);
|
|
608
|
+
};
|
|
609
|
+
|
|
610
|
+
beforeEach(() => {
|
|
611
|
+
GlobalConfigService.findOneById = jest.fn().mockResolvedValue(
|
|
612
|
+
makeStoredConfig({
|
|
613
|
+
enterpriseLicenseUserLimit: 150,
|
|
614
|
+
enterpriseLicenseCurrentUserCount: 42,
|
|
615
|
+
enterpriseLicenseInstances: [],
|
|
616
|
+
}),
|
|
617
|
+
);
|
|
618
|
+
});
|
|
619
|
+
|
|
620
|
+
it("tells a signed-in administrator how close the installation is to refusing users", async () => {
|
|
621
|
+
(mockRequest as unknown as Record<string, unknown>)["userAuthorization"] =
|
|
622
|
+
{
|
|
623
|
+
userId: ObjectID.generate(),
|
|
624
|
+
};
|
|
625
|
+
UserService.countBy = jest
|
|
626
|
+
.fn()
|
|
627
|
+
.mockResolvedValue(new PositiveNumber(149));
|
|
628
|
+
|
|
629
|
+
await callGet();
|
|
630
|
+
|
|
631
|
+
const body: JSONObject = getResponseBody();
|
|
632
|
+
|
|
633
|
+
expect(body["isSeatLimitEnforced"]).toBe(true);
|
|
634
|
+
expect(body["seatsInUse"]).toBe(149);
|
|
635
|
+
expect(body["seatsRemaining"]).toBe(1);
|
|
636
|
+
expect(body["canAddMoreUsers"]).toBe(true);
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
/*
|
|
640
|
+
* The same route serves the signed-out login page. How near this server is
|
|
641
|
+
* to refusing new accounts is operational detail, and counting its users
|
|
642
|
+
* for an anonymous visitor would be a free query on an unauthenticated
|
|
643
|
+
* endpoint besides.
|
|
644
|
+
*/
|
|
645
|
+
it("tells an anonymous visitor nothing about seat enforcement", async () => {
|
|
646
|
+
await callGet();
|
|
647
|
+
|
|
648
|
+
const body: JSONObject = getResponseBody();
|
|
649
|
+
|
|
650
|
+
expect(body["isSeatLimitEnforced"]).toBe(false);
|
|
651
|
+
expect(body["seatsInUse"]).toBeNull();
|
|
652
|
+
expect(body["seatsRemaining"]).toBeNull();
|
|
653
|
+
expect(body["canAddMoreUsers"]).toBe(true);
|
|
654
|
+
expect(UserService.countBy).not.toHaveBeenCalled();
|
|
655
|
+
});
|
|
656
|
+
});
|
|
657
|
+
});
|