@oneuptime/common 13.0.8 → 14.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/AnalyticsModels/AuditLog.ts +23 -15
- package/Models/DatabaseModels/GlobalConfig.ts +24 -0
- package/Models/DatabaseModels/Monitor.ts +3 -2
- package/Models/DatabaseModels/MonitorTemplate.ts +2 -1
- package/Scripts/generate-service-worker.js +65 -4
- package/Server/API/BaseAPI.ts +26 -5
- package/Server/API/GlobalConfigAPI.ts +228 -462
- package/Server/API/ProjectOIDC.ts +25 -16
- package/Server/API/ProjectSSO.ts +24 -16
- package/Server/API/StatusPageAPI.ts +100 -42
- package/Server/API/TeamMemberAPI.ts +10 -1
- package/Server/Enterprise/EnterpriseEdition.ts +649 -0
- package/Server/Enterprise/EnterpriseFeature.ts +48 -0
- package/Server/Enterprise/EnterpriseLicenseSnapshot.ts +192 -0
- package/Server/Enterprise/EnterpriseServerModule.ts +233 -0
- package/Server/EnvironmentConfig.ts +147 -2
- package/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.ts +25 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Server/Middleware/UserAuthorization.ts +38 -16
- package/Server/Services/AuditLogService.ts +84 -1079
- package/Server/Services/EnterpriseLicenseService.ts +38 -0
- package/Server/Services/GlobalConfigService.ts +80 -1
- package/Server/Services/MonitorProbeService.ts +116 -20
- package/Server/Services/MonitorService.ts +56 -4
- package/Server/Services/MonitorStatusTimelineService.ts +284 -0
- package/Server/Services/MonitorTemplateService.ts +26 -0
- package/Server/Services/ProjectService.ts +284 -0
- package/Server/Services/RumSessionPinService.ts +25 -6
- package/Server/Services/StatusPagePrivateUserService.ts +7 -3
- package/Server/Services/StatusPageService.ts +78 -1
- package/Server/Services/TeamMemberService.ts +11 -0
- package/Server/Services/TeamService.ts +10 -0
- package/Server/Services/UserService.ts +10 -17
- package/Server/Types/Database/Permissions/CreatePermission.ts +15 -0
- package/Server/Types/Database/Permissions/EditionPermission.ts +208 -18
- package/Server/Types/Database/Permissions/TablePermission.ts +10 -3
- package/Server/Types/Database/Permissions/UpdatePermission.ts +29 -0
- package/Server/Types/Markdown.ts +41 -0
- package/Server/Utils/CommunityEditionSsoReport.ts +361 -0
- package/Server/Utils/EditionEnforcement.ts +233 -0
- package/Server/Utils/FrontendEnvironment.ts +41 -2
- package/Server/Utils/InstanceHealth/RedisHealth.ts +12 -277
- package/Server/Utils/Monitor/AffectedResourceList.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +10 -1
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +543 -333
- package/Server/Utils/Monitor/MonitoringIntervalValidator.ts +116 -0
- package/Server/Utils/Workspace/Slack/Slack.ts +423 -10
- package/Tests/App/Accounts/LoginPasskey.test.tsx +18 -0
- package/Tests/App/Accounts/LoginSsoEdition.test.tsx +616 -0
- package/Tests/App/AdminDashboard/AdminAuthenticationSsoEdition.test.tsx +217 -0
- package/Tests/App/AdminDashboard/AdminEnterprisePluginPage.test.tsx +357 -0
- package/Tests/App/AdminDashboard/EnterpriseLicensesShell.test.tsx +214 -0
- package/Tests/App/AdminDashboard/GlobalSSOEnterpriseShells.test.tsx +271 -0
- package/Tests/App/AdminDashboard/HealthShells.test.tsx +659 -0
- package/Tests/App/Dashboard/AuditLogsAndComplianceShells.test.tsx +572 -0
- package/Tests/App/Dashboard/EnterpriseFeatureUpgrade.test.tsx +547 -0
- package/Tests/App/Dashboard/EnterprisePluginPage.test.tsx +667 -0
- package/Tests/App/Dashboard/IdentityEnterpriseShells.test.tsx +319 -0
- package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +185 -0
- package/Tests/App/Dashboard/SecurityEventConnectionDiagnostics.test.tsx +45 -9
- package/Tests/App/Dashboard/SecurityEventDetailPanel.test.tsx +399 -0
- package/Tests/App/Dashboard/SecurityEventListRow.test.tsx +214 -0
- package/Tests/App/Dashboard/SecurityEventsEmptyState.test.tsx +1 -83
- package/Tests/App/Dashboard/SecurityEventsNavTabs.test.tsx +248 -0
- package/Tests/App/Dashboard/SecurityEventsViewer.test.tsx +1203 -0
- package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +11 -91
- package/Tests/App/StatusPage/StatusPageSsoEmptyState.test.tsx +319 -0
- package/Tests/Helpers/RefreshAwareApiScan.ts +757 -0
- package/Tests/Helpers/TenantScopedRequestScan.ts +515 -0
- package/Tests/Scripts/GenerateServiceWorker.test.ts +931 -0
- package/Tests/Server/API/BaseAPICreateItemDoesNotMutateModel.test.ts +130 -0
- package/Tests/Server/API/GlobalConfigLicense.test.ts +742 -497
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +35 -909
- package/Tests/Server/API/SsoProviderListingsEdition.test.ts +432 -0
- package/Tests/Server/API/TeamMemberLeaveScimLockEdition.test.ts +252 -0
- package/Tests/Server/Enterprise/EnterpriseEdition.test.ts +824 -0
- package/Tests/Server/Enterprise/EnterpriseFeatureActive.test.ts +643 -0
- package/Tests/Server/Enterprise/EnterpriseLicenseSnapshot.test.ts +294 -0
- package/Tests/Server/Enterprise/EnterpriseModelFeatureMap.test.ts +93 -0
- package/Tests/Server/Enterprise/EnterpriseOnlyModulesLiveInEe.test.ts +582 -0
- package/Tests/Server/Enterprise/EnterpriseServerModule.test.ts +247 -0
- package/Tests/Server/Enterprise/FakeEnterpriseModule.ts +502 -0
- package/Tests/Server/Enterprise/TestBillingFlag.ts +70 -0
- package/Tests/Server/EnvironmentConfigEnterpriseEdition.test.ts +314 -0
- package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +289 -0
- package/Tests/Server/Infrastructure/E2EClickHouseFixtureAccess.test.ts +5 -1
- package/Tests/Server/Middleware/UserAuthorization.test.ts +37 -2
- package/Tests/Server/Middleware/UserAuthorizationEditionEnforcement.test.ts +516 -0
- package/Tests/Server/Services/AuditLogService.test.ts +460 -990
- package/Tests/Server/Services/CreateAndReadResponsesKeepIds.test.ts +263 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceKeyGeneration.test.ts +151 -0
- package/Tests/Server/Services/GlobalConfigServiceLicenseColumns.test.ts +357 -0
- package/Tests/Server/Services/MonitorDestinationInfoIPv6.test.ts +101 -0
- package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +333 -0
- package/Tests/Server/Services/MonitorStatusTimelineDailyAggregates.test.ts +303 -0
- package/Tests/Server/Services/ProjectServiceAuditLogLicense.test.ts +701 -0
- package/Tests/Server/Services/ProjectServiceAuditLogSettingsCache.test.ts +31 -35
- package/Tests/Server/Services/ScimPushGroupsTeamLocksEdition.test.ts +431 -0
- package/Tests/Server/Services/SsoRequirementReadMasking.test.ts +419 -0
- package/Tests/Server/Services/SsoRequirementWriteGuard.test.ts +769 -0
- package/Tests/Server/Services/StatusPagePrivateUserInvitationPolicy.test.ts +94 -0
- package/Tests/Server/Services/UserAuthenticationService.test.ts +35 -0
- package/Tests/Server/Services/UserServiceSeatLimit.test.ts +94 -56
- package/Tests/Server/Types/Database/Permissions/EditionPermission.test.ts +1823 -0
- package/Tests/Server/Types/Markdown.test.ts +181 -0
- package/Tests/Server/Utils/CommunityEditionSsoReport.test.ts +565 -0
- package/Tests/Server/Utils/EditionEnforcement.test.ts +303 -0
- package/Tests/Server/Utils/FrontendEnvironment.test.ts +367 -0
- package/Tests/Server/Utils/InstanceHealth/RedisHealth.test.ts +38 -418
- package/Tests/Server/Utils/Monitor/AffectedResourceList.test.ts +518 -0
- package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +24 -4
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluator.test.ts +934 -96
- package/Tests/Server/Utils/Monitor/MonitoringIntervalValidator.test.ts +188 -0
- package/Tests/Server/Utils/Workspace/Slack/SlackMarkdownSectionSplit.test.ts +1209 -0
- package/Tests/Types/API/HostnameFromAuthority.test.ts +20 -10
- package/Tests/Types/API/HostnameIPv6.test.ts +149 -0
- package/Tests/Types/Database/CanonicalModelInstance.test.ts +190 -0
- package/Tests/UI/Components/EditionLabelLapseCopy.ts +104 -0
- package/Tests/UI/Components/EditionLabelLicenseManagerWiring.test.tsx +254 -0
- package/Tests/UI/Components/EditionLabelLicenseRefresh.test.tsx +84 -178
- package/Tests/UI/Components/EditionLabelLicenseStatus.test.tsx +1586 -0
- package/Tests/UI/Components/EditionLabelLicenseWritesGuard.test.tsx +157 -0
- package/Tests/UI/Components/Graphs/DayUptimeGraph.test.tsx +49 -2
- package/Tests/UI/Components/MarkdownConverters.test.ts +684 -0
- package/Tests/UI/Components/ModelListEmptyState.test.tsx +289 -0
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerEmptyContent.test.tsx +131 -0
- package/Tests/UI/EsbuildEnterpriseAlias.test.ts +1127 -0
- package/Tests/Utils/HostAddressUtil.test.ts +138 -0
- package/Tests/Utils/Monitor/MonitorDestinationUtil.test.ts +313 -0
- package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +304 -0
- package/Tests/Utils/StatusPage/UptimeDailyAggregateUtil.test.ts +248 -0
- package/Types/API/Hostname.ts +63 -16
- package/Types/Database/AccessControl/ColumnAccessControl.ts +19 -7
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +19 -7
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +15 -6
- package/Types/Database/CanonicalModelInstance.ts +102 -0
- package/Types/Database/TableColumn.ts +20 -6
- package/Types/EnterpriseLicense/EnterpriseLicensePeriods.ts +29 -0
- package/Types/IP/IPv6.ts +6 -1
- package/Types/Monitor/MonitorStep.ts +6 -1
- package/Types/Monitor/ProxmoxAlertTemplates.ts +1 -1
- package/Types/StatusPage/UptimeDailyAggregate.ts +110 -0
- package/UI/Components/EditionLabel/EditionLabel.tsx +796 -1195
- package/UI/Components/EditionLabel/LicenseManager.ts +119 -0
- package/UI/Components/Graphs/DayUptimeGraph.tsx +123 -15
- package/UI/Components/Markdown.tsx/MarkdownConverters.ts +0 -0
- package/UI/Components/ModelList/ModelList.tsx +11 -1
- package/UI/Components/MonitorGraphs/Uptime.tsx +69 -0
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +28 -12
- package/UI/esbuild-enterprise.js +263 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +7 -2
- package/Utils/HostAddressUtil.ts +94 -0
- package/Utils/Monitor/MonitorDestinationUtil.ts +157 -0
- package/Utils/Monitor/MonitoringIntervalUtil.ts +436 -0
- package/Utils/StatusPage/UptimeDailyAggregateUtil.ts +192 -0
- package/build/dist/Models/AnalyticsModels/AuditLog.js +23 -15
- package/build/dist/Models/AnalyticsModels/AuditLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalConfig.js +25 -0
- package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +2 -2
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js +2 -1
- package/build/dist/Models/DatabaseModels/MonitorTemplate.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +26 -5
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/GlobalConfigAPI.js +148 -344
- package/build/dist/Server/API/GlobalConfigAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectOIDC.js +24 -16
- package/build/dist/Server/API/ProjectOIDC.js.map +1 -1
- package/build/dist/Server/API/ProjectSSO.js +24 -16
- package/build/dist/Server/API/ProjectSSO.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +93 -43
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TeamMemberAPI.js +8 -1
- package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
- package/build/dist/Server/Enterprise/EnterpriseEdition.js +466 -0
- package/build/dist/Server/Enterprise/EnterpriseEdition.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js +39 -0
- package/build/dist/Server/Enterprise/EnterpriseFeature.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js +70 -0
- package/build/dist/Server/Enterprise/EnterpriseLicenseSnapshot.js.map +1 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js +84 -0
- package/build/dist/Server/Enterprise/EnterpriseServerModule.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +84 -2
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1793900000000-AddEnterpriseEditionFirstSeenAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +30 -11
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AuditLogService.js +71 -740
- package/build/dist/Server/Services/AuditLogService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +34 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalConfigService.js +63 -0
- package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
- package/build/dist/Server/Services/MonitorProbeService.js +90 -17
- package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +45 -4
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +242 -0
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +16 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +214 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/RumSessionPinService.js +24 -6
- package/build/dist/Server/Services/RumSessionPinService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +7 -3
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +71 -0
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +10 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TeamService.js +9 -0
- package/build/dist/Server/Services/TeamService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -16
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +10 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js +154 -14
- package/build/dist/Server/Types/Database/Permissions/EditionPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js +10 -3
- package/build/dist/Server/Types/Database/Permissions/TablePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js +17 -0
- package/build/dist/Server/Types/Database/Permissions/UpdatePermission.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +31 -0
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js +223 -0
- package/build/dist/Server/Utils/CommunityEditionSsoReport.js.map +1 -0
- package/build/dist/Server/Utils/EditionEnforcement.js +187 -0
- package/build/dist/Server/Utils/EditionEnforcement.js.map +1 -0
- package/build/dist/Server/Utils/FrontendEnvironment.js +31 -2
- package/build/dist/Server/Utils/FrontendEnvironment.js.map +1 -1
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js +6 -193
- package/build/dist/Server/Utils/InstanceHealth/RedisHealth.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js +96 -0
- package/build/dist/Server/Utils/Monitor/AffectedResourceList.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +8 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +449 -261
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js +88 -0
- package/build/dist/Server/Utils/Monitor/MonitoringIntervalValidator.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +331 -11
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +59 -11
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +19 -7
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +13 -6
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -1
- package/build/dist/Types/Database/CanonicalModelInstance.js +88 -0
- package/build/dist/Types/Database/CanonicalModelInstance.js.map +1 -0
- package/build/dist/Types/Database/TableColumn.js +19 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js +28 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicensePeriods.js.map +1 -0
- package/build/dist/Types/IP/IPv6.js +6 -1
- package/build/dist/Types/IP/IPv6.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +1 -1
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js +32 -0
- package/build/dist/Types/StatusPage/UptimeDailyAggregate.js.map +1 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +414 -585
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js +2 -0
- package/build/dist/UI/Components/EditionLabel/LicenseManager.js.map +1 -0
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js +90 -17
- package/build/dist/UI/Components/Graphs/DayUptimeGraph.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js +0 -0
- package/build/dist/UI/Components/Markdown.tsx/MarkdownConverters.js.map +1 -1
- package/build/dist/UI/Components/ModelList/ModelList.js +4 -1
- package/build/dist/UI/Components/ModelList/ModelList.js.map +1 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js +42 -1
- package/build/dist/UI/Components/MonitorGraphs/Uptime.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +2 -2
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +6 -2
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/HostAddressUtil.js +80 -0
- package/build/dist/Utils/HostAddressUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js +127 -0
- package/build/dist/Utils/Monitor/MonitorDestinationUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js +374 -0
- package/build/dist/Utils/Monitor/MonitoringIntervalUtil.js.map +1 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js +148 -0
- package/build/dist/Utils/StatusPage/UptimeDailyAggregateUtil.js.map +1 -0
- package/jest.config.json +3 -1
- package/package.json +1 -1
- package/test-setup.sh +103 -34
- package/tsconfig.json +13 -0
- package/Server/API/EnterpriseLicenseAPI.ts +0 -925
- package/Server/API/TeamComplianceAPI.ts +0 -158
- package/Server/Middleware/SCIMAuthorization.ts +0 -141
- package/Server/Services/TeamComplianceService.ts +0 -733
- package/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.ts +0 -186
- package/Server/Utils/InstanceHealth/PostgresHealth.ts +0 -286
- package/Tests/App/AdminDashboard/EnterpriseLicenseInstanceActivity.test.tsx +0 -451
- package/Tests/App/Dashboard/AuditLogsTable.test.tsx +0 -598
- package/Tests/App/Dashboard/SecurityEventsExplorer.test.tsx +0 -761
- package/Tests/App/Dashboard/SecurityEventsSideMenu.test.tsx +0 -247
- package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +0 -382
- package/Tests/App/Dashboard/SecurityEventsVolumeChart.test.tsx +0 -321
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +0 -1851
- package/Tests/Server/Middleware/SCIMAuthorization.test.ts +0 -525
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +0 -1845
- package/Tests/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.test.ts +0 -495
- package/Tests/Server/Utils/InstanceHealth/PostgresHealth.test.ts +0 -337
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +0 -576
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +0 -568
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +0 -287
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +0 -244
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +0 -646
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +0 -1
- package/build/dist/Server/API/TeamComplianceAPI.js +0 -111
- package/build/dist/Server/API/TeamComplianceAPI.js.map +0 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +0 -124
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +0 -1
- package/build/dist/Server/Services/TeamComplianceService.js +0 -537
- package/build/dist/Server/Services/TeamComplianceService.js.map +0 -1
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js +0 -145
- package/build/dist/Server/Utils/EnterpriseLicense/EnterpriseLicenseSeatUtil.js.map +0 -1
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js +0 -194
- package/build/dist/Server/Utils/InstanceHealth/PostgresHealth.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +0 -168
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +0 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +0 -174
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +0 -1
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import GlobalConfig from "../../../Models/DatabaseModels/GlobalConfig";
|
|
2
|
+
import GlobalConfigService, {
|
|
3
|
+
ROOT_ONLY_LICENSE_COLUMNS,
|
|
4
|
+
} from "../../../Server/Services/GlobalConfigService";
|
|
5
|
+
import CreateBy from "../../../Server/Types/Database/CreateBy";
|
|
6
|
+
import { OnCreate, OnUpdate } from "../../../Server/Types/Database/Hooks";
|
|
7
|
+
import UpdateBy from "../../../Server/Types/Database/UpdateBy";
|
|
8
|
+
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
9
|
+
import NotAuthorizedException from "../../../Types/Exception/NotAuthorizedException";
|
|
10
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
11
|
+
import { afterEach, describe, expect, test } from "@jest/globals";
|
|
12
|
+
|
|
13
|
+
/*
|
|
14
|
+
* A12: forging a license through GlobalConfig CRUD.
|
|
15
|
+
*
|
|
16
|
+
* GlobalConfig's column ACLs are empty, and master admins bypass ACLs, so the
|
|
17
|
+
* generic PUT /api/global-config/<zero id> let a master admin write any column
|
|
18
|
+
* - including the stored license token, its expiry, the seat limit, the
|
|
19
|
+
* instance id an instance-bound license is checked against, and the moment
|
|
20
|
+
* the Enterprise Edition was first seen (which starts the unlicensed grace).
|
|
21
|
+
* One request was enough to turn an unlicensed installation into a licensed
|
|
22
|
+
* one, or to restart the trial forever.
|
|
23
|
+
*
|
|
24
|
+
* Those columns are now written by OneUptime itself only (props.isRoot): the
|
|
25
|
+
* license client, the first-boot stamp and the data migrations. Everybody
|
|
26
|
+
* else is refused, including master admins, and including writes of null.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
type GlobalConfigServiceWithHooks = {
|
|
30
|
+
onBeforeCreate(
|
|
31
|
+
createBy: CreateBy<GlobalConfig>,
|
|
32
|
+
): Promise<OnCreate<GlobalConfig>>;
|
|
33
|
+
onBeforeUpdate(
|
|
34
|
+
updateBy: UpdateBy<GlobalConfig>,
|
|
35
|
+
): Promise<OnUpdate<GlobalConfig>>;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const hooks: GlobalConfigServiceWithHooks =
|
|
39
|
+
GlobalConfigService as unknown as GlobalConfigServiceWithHooks;
|
|
40
|
+
|
|
41
|
+
const EXPECTED_ROOT_ONLY_COLUMNS: Array<string> = [
|
|
42
|
+
"instanceId",
|
|
43
|
+
"enterpriseCompanyName",
|
|
44
|
+
"enterpriseLicenseKey",
|
|
45
|
+
"enterpriseLicenseExpiresAt",
|
|
46
|
+
"enterpriseLicenseToken",
|
|
47
|
+
"enterpriseLicenseIsEvaluation",
|
|
48
|
+
"enterpriseLicenseUserLimit",
|
|
49
|
+
"enterpriseLicenseCurrentUserCount",
|
|
50
|
+
"enterpriseLicenseUserCountUpdatedAt",
|
|
51
|
+
"enterpriseLicenseInstances",
|
|
52
|
+
"enterpriseEditionFirstSeenAt",
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
// A plausible forged value for each column.
|
|
56
|
+
const FORGED_VALUES: Record<string, unknown> = {
|
|
57
|
+
instanceId: ObjectID.generate(),
|
|
58
|
+
enterpriseCompanyName: "Forged Inc",
|
|
59
|
+
enterpriseLicenseKey: "forged-key",
|
|
60
|
+
enterpriseLicenseExpiresAt: new Date("2099-01-01T00:00:00.000Z"),
|
|
61
|
+
enterpriseLicenseToken: "forged.license.token",
|
|
62
|
+
enterpriseLicenseIsEvaluation: false,
|
|
63
|
+
enterpriseLicenseUserLimit: 1_000_000,
|
|
64
|
+
enterpriseLicenseCurrentUserCount: 0,
|
|
65
|
+
enterpriseLicenseUserCountUpdatedAt: new Date(),
|
|
66
|
+
enterpriseLicenseInstances: [],
|
|
67
|
+
enterpriseEditionFirstSeenAt: new Date(),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const MASTER_ADMIN_PROPS: DatabaseCommonInteractionProps = {
|
|
71
|
+
userId: ObjectID.generate(),
|
|
72
|
+
isMasterAdmin: true,
|
|
73
|
+
} as DatabaseCommonInteractionProps;
|
|
74
|
+
|
|
75
|
+
const ROOT_PROPS: DatabaseCommonInteractionProps = {
|
|
76
|
+
isRoot: true,
|
|
77
|
+
} as DatabaseCommonInteractionProps;
|
|
78
|
+
|
|
79
|
+
const makeUpdateBy: (
|
|
80
|
+
data: Record<string, unknown>,
|
|
81
|
+
props: DatabaseCommonInteractionProps,
|
|
82
|
+
) => UpdateBy<GlobalConfig> = (
|
|
83
|
+
data: Record<string, unknown>,
|
|
84
|
+
props: DatabaseCommonInteractionProps,
|
|
85
|
+
): UpdateBy<GlobalConfig> => {
|
|
86
|
+
return {
|
|
87
|
+
query: { _id: ObjectID.getZeroObjectID().toString() },
|
|
88
|
+
data,
|
|
89
|
+
limit: 1,
|
|
90
|
+
skip: 0,
|
|
91
|
+
props,
|
|
92
|
+
} as unknown as UpdateBy<GlobalConfig>;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const makeCreateBy: (
|
|
96
|
+
data: Record<string, unknown>,
|
|
97
|
+
props: DatabaseCommonInteractionProps,
|
|
98
|
+
) => CreateBy<GlobalConfig> = (
|
|
99
|
+
data: Record<string, unknown>,
|
|
100
|
+
props: DatabaseCommonInteractionProps,
|
|
101
|
+
): CreateBy<GlobalConfig> => {
|
|
102
|
+
const model: GlobalConfig = new GlobalConfig();
|
|
103
|
+
model.id = ObjectID.getZeroObjectID();
|
|
104
|
+
Object.assign(model, data);
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
data: model,
|
|
108
|
+
props,
|
|
109
|
+
} as unknown as CreateBy<GlobalConfig>;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
afterEach(() => {
|
|
113
|
+
jest.restoreAllMocks();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe("GlobalConfigService - which columns are root-only", () => {
|
|
117
|
+
test("covers exactly the license and identity columns", () => {
|
|
118
|
+
expect([...ROOT_ONLY_LICENSE_COLUMNS].sort()).toEqual(
|
|
119
|
+
[...EXPECTED_ROOT_ONLY_COLUMNS].sort(),
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("every root-only column is a real GlobalConfig column", () => {
|
|
124
|
+
const model: GlobalConfig = new GlobalConfig();
|
|
125
|
+
|
|
126
|
+
for (const column of ROOT_ONLY_LICENSE_COLUMNS) {
|
|
127
|
+
expect({
|
|
128
|
+
column,
|
|
129
|
+
isColumn: model.isTableColumn(column as string),
|
|
130
|
+
}).toEqual({ column, isColumn: true });
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
/*
|
|
135
|
+
* These two are settings the oneuptime.com admin edits from the Admin
|
|
136
|
+
* Dashboard; locking them would break that page.
|
|
137
|
+
*/
|
|
138
|
+
test.each([
|
|
139
|
+
"enterpriseLicenseNotificationEmail",
|
|
140
|
+
"enterpriseLicenseExpiryReminderDays",
|
|
141
|
+
])("leaves %s editable by master admins", (column: string) => {
|
|
142
|
+
expect(ROOT_ONLY_LICENSE_COLUMNS as ReadonlyArray<string>).not.toContain(
|
|
143
|
+
column,
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
describe("GlobalConfigService - a master admin forging the license (update)", () => {
|
|
149
|
+
test.each(EXPECTED_ROOT_ONLY_COLUMNS)(
|
|
150
|
+
"refuses a master admin writing %s",
|
|
151
|
+
async (column: string) => {
|
|
152
|
+
await expect(
|
|
153
|
+
hooks.onBeforeUpdate(
|
|
154
|
+
makeUpdateBy({ [column]: FORGED_VALUES[column] }, MASTER_ADMIN_PROPS),
|
|
155
|
+
),
|
|
156
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
157
|
+
},
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
test.each(EXPECTED_ROOT_ONLY_COLUMNS)(
|
|
161
|
+
"refuses a master admin clearing %s with null",
|
|
162
|
+
async (column: string) => {
|
|
163
|
+
await expect(
|
|
164
|
+
hooks.onBeforeUpdate(
|
|
165
|
+
makeUpdateBy({ [column]: null }, MASTER_ADMIN_PROPS),
|
|
166
|
+
),
|
|
167
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
168
|
+
},
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
test("refuses an ordinary signed-in user too", async () => {
|
|
172
|
+
await expect(
|
|
173
|
+
hooks.onBeforeUpdate(
|
|
174
|
+
makeUpdateBy({ enterpriseLicenseToken: "forged.license.token" }, {
|
|
175
|
+
userId: ObjectID.generate(),
|
|
176
|
+
} as DatabaseCommonInteractionProps),
|
|
177
|
+
),
|
|
178
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
test("refuses a request with no props flags at all", async () => {
|
|
182
|
+
await expect(
|
|
183
|
+
hooks.onBeforeUpdate(
|
|
184
|
+
makeUpdateBy(
|
|
185
|
+
{ enterpriseLicenseExpiresAt: new Date("2099-01-01") },
|
|
186
|
+
{} as DatabaseCommonInteractionProps,
|
|
187
|
+
),
|
|
188
|
+
),
|
|
189
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
/*
|
|
193
|
+
* The exact request from the review: the token and a far-future expiry in
|
|
194
|
+
* one PUT, which used to turn an unlicensed installation into a licensed one.
|
|
195
|
+
*/
|
|
196
|
+
test("refuses the token-plus-expiry forgery and names both columns", async () => {
|
|
197
|
+
let caught: unknown = null;
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
await hooks.onBeforeUpdate(
|
|
201
|
+
makeUpdateBy(
|
|
202
|
+
{
|
|
203
|
+
enterpriseLicenseToken: "x",
|
|
204
|
+
enterpriseLicenseExpiresAt: new Date("2099-01-01T00:00:00.000Z"),
|
|
205
|
+
},
|
|
206
|
+
MASTER_ADMIN_PROPS,
|
|
207
|
+
),
|
|
208
|
+
);
|
|
209
|
+
} catch (err) {
|
|
210
|
+
caught = err;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
expect(caught).toBeInstanceOf(NotAuthorizedException);
|
|
214
|
+
expect((caught as Error).message).toContain("enterpriseLicenseToken");
|
|
215
|
+
expect((caught as Error).message).toContain("enterpriseLicenseExpiresAt");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
test("refuses a forged column hidden among legitimate settings", async () => {
|
|
219
|
+
await expect(
|
|
220
|
+
hooks.onBeforeUpdate(
|
|
221
|
+
makeUpdateBy(
|
|
222
|
+
{
|
|
223
|
+
disableSignup: true,
|
|
224
|
+
enterpriseLicenseUserLimit: 1_000_000,
|
|
225
|
+
},
|
|
226
|
+
MASTER_ADMIN_PROPS,
|
|
227
|
+
),
|
|
228
|
+
),
|
|
229
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
test("lets a master admin change ordinary settings", async () => {
|
|
233
|
+
const result: OnUpdate<GlobalConfig> = await hooks.onBeforeUpdate(
|
|
234
|
+
makeUpdateBy({ disableSignup: true }, MASTER_ADMIN_PROPS),
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
expect(result.updateBy.data).toEqual({ disableSignup: true });
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test.each([
|
|
241
|
+
["enterpriseLicenseNotificationEmail", "licenses@oneuptime.com"],
|
|
242
|
+
["enterpriseLicenseExpiryReminderDays", 30],
|
|
243
|
+
])(
|
|
244
|
+
"lets a master admin change %s",
|
|
245
|
+
async (column: string, value: unknown) => {
|
|
246
|
+
await expect(
|
|
247
|
+
hooks.onBeforeUpdate(
|
|
248
|
+
makeUpdateBy({ [column]: value }, MASTER_ADMIN_PROPS),
|
|
249
|
+
),
|
|
250
|
+
).resolves.toBeDefined();
|
|
251
|
+
},
|
|
252
|
+
);
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
describe("GlobalConfigService - OneUptime's own license writes (update)", () => {
|
|
256
|
+
test.each(EXPECTED_ROOT_ONLY_COLUMNS)(
|
|
257
|
+
"lets a root write set %s",
|
|
258
|
+
async (column: string) => {
|
|
259
|
+
const result: OnUpdate<GlobalConfig> = await hooks.onBeforeUpdate(
|
|
260
|
+
makeUpdateBy({ [column]: FORGED_VALUES[column] }, ROOT_PROPS),
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
expect((result.updateBy.data as Record<string, unknown>)[column]).toEqual(
|
|
264
|
+
FORGED_VALUES[column],
|
|
265
|
+
);
|
|
266
|
+
},
|
|
267
|
+
);
|
|
268
|
+
|
|
269
|
+
test("lets a root write clear the token", async () => {
|
|
270
|
+
await expect(
|
|
271
|
+
hooks.onBeforeUpdate(
|
|
272
|
+
makeUpdateBy({ enterpriseLicenseToken: null }, ROOT_PROPS),
|
|
273
|
+
),
|
|
274
|
+
).resolves.toBeDefined();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
describe("GlobalConfigService - a master admin forging the license (create)", () => {
|
|
279
|
+
test.each(EXPECTED_ROOT_ONLY_COLUMNS)(
|
|
280
|
+
"refuses a master admin creating the row with %s",
|
|
281
|
+
async (column: string) => {
|
|
282
|
+
await expect(
|
|
283
|
+
hooks.onBeforeCreate(
|
|
284
|
+
makeCreateBy({ [column]: FORGED_VALUES[column] }, MASTER_ADMIN_PROPS),
|
|
285
|
+
),
|
|
286
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
287
|
+
},
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
test("lets a master admin create a row without license columns", async () => {
|
|
291
|
+
await expect(
|
|
292
|
+
hooks.onBeforeCreate(
|
|
293
|
+
makeCreateBy({ disableSignup: true }, MASTER_ADMIN_PROPS),
|
|
294
|
+
),
|
|
295
|
+
).resolves.toBeDefined();
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
/*
|
|
299
|
+
* AddDefaultGlobalConfig seeds the row with a fresh instanceId as root; it
|
|
300
|
+
* must keep working.
|
|
301
|
+
*/
|
|
302
|
+
test("lets the default-config data migration create the row with an instance id", async () => {
|
|
303
|
+
await expect(
|
|
304
|
+
hooks.onBeforeCreate(
|
|
305
|
+
makeCreateBy({ instanceId: ObjectID.generate() }, ROOT_PROPS),
|
|
306
|
+
),
|
|
307
|
+
).resolves.toBeDefined();
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
describe("GlobalConfigService - through the public write methods", () => {
|
|
312
|
+
/*
|
|
313
|
+
* The hook is what the generic CRUD API reaches. Driving the public methods
|
|
314
|
+
* proves the refusal happens before any database work: nothing here has a
|
|
315
|
+
* database, so reaching one would fail differently.
|
|
316
|
+
*/
|
|
317
|
+
test("updateOneBy refuses a master admin's forged token", async () => {
|
|
318
|
+
await expect(
|
|
319
|
+
GlobalConfigService.updateOneBy({
|
|
320
|
+
query: { _id: ObjectID.getZeroObjectID().toString() },
|
|
321
|
+
data: { enterpriseLicenseToken: "forged.license.token" },
|
|
322
|
+
props: MASTER_ADMIN_PROPS,
|
|
323
|
+
}),
|
|
324
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
test("create refuses a master admin's forged first-seen stamp", async () => {
|
|
328
|
+
const model: GlobalConfig = new GlobalConfig();
|
|
329
|
+
model.enterpriseEditionFirstSeenAt = new Date();
|
|
330
|
+
|
|
331
|
+
await expect(
|
|
332
|
+
GlobalConfigService.create({
|
|
333
|
+
data: model,
|
|
334
|
+
props: MASTER_ADMIN_PROPS,
|
|
335
|
+
}),
|
|
336
|
+
).rejects.toBeInstanceOf(NotAuthorizedException);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test("the guard lets a root write through whatever else its props say", () => {
|
|
340
|
+
expect(() => {
|
|
341
|
+
GlobalConfigService.assertLicenseColumnsWrittenByRootOnly(
|
|
342
|
+
{ enterpriseLicenseToken: "x" },
|
|
343
|
+
{ isRoot: true, ignoreHooks: true } as DatabaseCommonInteractionProps,
|
|
344
|
+
);
|
|
345
|
+
}).not.toThrow();
|
|
346
|
+
expect(() => {
|
|
347
|
+
GlobalConfigService.assertLicenseColumnsWrittenByRootOnly(
|
|
348
|
+
{ enterpriseLicenseToken: "x" },
|
|
349
|
+
{
|
|
350
|
+
isRoot: false,
|
|
351
|
+
isMasterAdmin: true,
|
|
352
|
+
ignoreHooks: true,
|
|
353
|
+
} as DatabaseCommonInteractionProps,
|
|
354
|
+
);
|
|
355
|
+
}).toThrow(NotAuthorizedException);
|
|
356
|
+
});
|
|
357
|
+
});
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
2
|
+
import MonitorService from "../../../Server/Services/MonitorService";
|
|
3
|
+
import IP from "../../../Types/IP/IP";
|
|
4
|
+
import MonitorStep from "../../../Types/Monitor/MonitorStep";
|
|
5
|
+
import MonitorSteps from "../../../Types/Monitor/MonitorSteps";
|
|
6
|
+
import MonitorType from "../../../Types/Monitor/MonitorType";
|
|
7
|
+
import Port from "../../../Types/Port";
|
|
8
|
+
import { describe, expect, test } from "@jest/globals";
|
|
9
|
+
import net from "net";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* The destination string that goes into owner notifications — the "monitor X
|
|
13
|
+
* is down, here is what it was checking" line somebody reads on their phone
|
|
14
|
+
* at 3am and then acts on.
|
|
15
|
+
*
|
|
16
|
+
* For a Port monitor it is host + ":" + port. For IPv4 that is unambiguous.
|
|
17
|
+
* For IPv6 it is not, and the failure is not that it looks odd: appending
|
|
18
|
+
* ":179" to "2001:518:2800:9::2" produces "2001:518:2800:9::2:179", which
|
|
19
|
+
* net.isIP() accepts as a valid IPv6 address — a DIFFERENT host from the one
|
|
20
|
+
* being monitored. The alert named the wrong machine.
|
|
21
|
+
*
|
|
22
|
+
* Pure in-memory models; no database anywhere.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const CUSTOMER_ADDRESS: string = "2001:518:2800:9::2";
|
|
26
|
+
const BGP_PORT: number = 179;
|
|
27
|
+
|
|
28
|
+
function monitorWithDestination(data: {
|
|
29
|
+
monitorType: MonitorType;
|
|
30
|
+
destination: string;
|
|
31
|
+
port?: number | undefined;
|
|
32
|
+
}): Monitor {
|
|
33
|
+
const step: MonitorStep = new MonitorStep();
|
|
34
|
+
|
|
35
|
+
step.setMonitorDestination(IP.fromString(data.destination));
|
|
36
|
+
|
|
37
|
+
if (data.port !== undefined) {
|
|
38
|
+
step.setPort(new Port(data.port));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const steps: MonitorSteps = new MonitorSteps();
|
|
42
|
+
steps.data = {
|
|
43
|
+
monitorStepsInstanceArray: [step],
|
|
44
|
+
defaultMonitorStatusId: undefined,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const monitor: Monitor = new Monitor();
|
|
48
|
+
monitor.monitorType = data.monitorType;
|
|
49
|
+
monitor.monitorSteps = steps;
|
|
50
|
+
|
|
51
|
+
return monitor;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function portMonitor(destination: string, port: number): Monitor {
|
|
55
|
+
return monitorWithDestination({
|
|
56
|
+
monitorType: MonitorType.Port,
|
|
57
|
+
destination: destination,
|
|
58
|
+
port: port,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
describe("MonitorService.getMonitorDestinationInfo — IPv6 host and port", () => {
|
|
63
|
+
test("brackets an IPv6 host so the port cannot be read as part of the address", () => {
|
|
64
|
+
expect(
|
|
65
|
+
MonitorService.getMonitorDestinationInfo(
|
|
66
|
+
portMonitor(CUSTOMER_ADDRESS, BGP_PORT),
|
|
67
|
+
).monitorDestination,
|
|
68
|
+
).toBe(`[${CUSTOMER_ADDRESS}]:${BGP_PORT}`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("the unbracketed form it used to produce is a different, valid host", () => {
|
|
72
|
+
const wrong: string = `${CUSTOMER_ADDRESS}:${BGP_PORT}`;
|
|
73
|
+
|
|
74
|
+
// Not malformed — which is exactly why nobody noticed.
|
|
75
|
+
expect(net.isIP(wrong)).toBe(6);
|
|
76
|
+
expect(
|
|
77
|
+
MonitorService.getMonitorDestinationInfo(
|
|
78
|
+
portMonitor(CUSTOMER_ADDRESS, BGP_PORT),
|
|
79
|
+
).monitorDestination,
|
|
80
|
+
).not.toBe(wrong);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("an IPv4 Port monitor keeps the conventional spelling", () => {
|
|
84
|
+
expect(
|
|
85
|
+
MonitorService.getMonitorDestinationInfo(
|
|
86
|
+
portMonitor("192.0.2.1", BGP_PORT),
|
|
87
|
+
).monitorDestination,
|
|
88
|
+
).toBe(`192.0.2.1:${BGP_PORT}`);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("an IPv6 Ping monitor with no port is reported as the bare address", () => {
|
|
92
|
+
expect(
|
|
93
|
+
MonitorService.getMonitorDestinationInfo(
|
|
94
|
+
monitorWithDestination({
|
|
95
|
+
monitorType: MonitorType.Ping,
|
|
96
|
+
destination: CUSTOMER_ADDRESS,
|
|
97
|
+
}),
|
|
98
|
+
).monitorDestination,
|
|
99
|
+
).toBe(CUSTOMER_ADDRESS);
|
|
100
|
+
});
|
|
101
|
+
});
|