@oneuptime/common 12.0.32 → 12.0.33
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/Span.ts +14 -0
- package/Models/DatabaseModels/EnterpriseLicense.ts +56 -0
- package/Models/DatabaseModels/Index.ts +10 -0
- package/Models/DatabaseModels/Monitor.ts +76 -0
- package/Models/DatabaseModels/NetworkAlertPolicy.ts +690 -0
- package/Models/DatabaseModels/NetworkDevice.ts +176 -1
- package/Models/DatabaseModels/NetworkSite.ts +201 -2
- package/Models/DatabaseModels/NetworkSiteType.ts +102 -3
- package/Models/DatabaseModels/NetworkSnmpCredentialProfile.ts +841 -0
- package/Models/DatabaseModels/TelemetryException.ts +119 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupBatch.ts +334 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupItem.ts +370 -0
- package/Models/DatabaseModels/UserNotificationEmailRollupSetting.ts +282 -0
- package/Server/API/EnterpriseLicenseAPI.ts +391 -64
- package/Server/API/LlmProviderAPI.ts +137 -22
- package/Server/EnvironmentConfig.ts +14 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.ts +55 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.ts +31 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.ts +124 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.ts +132 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.ts +191 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
- package/Server/Infrastructure/QueueWorker.ts +38 -8
- package/Server/Middleware/BearerTokenAuthorization.ts +12 -0
- package/Server/Middleware/ProjectAuthorization.ts +11 -0
- package/Server/Middleware/SCIMAuthorization.ts +12 -0
- package/Server/Middleware/TelemetryIngest.ts +11 -0
- package/Server/Services/AIBillingService.ts +101 -27
- package/Server/Services/EnterpriseLicenseInstanceService.ts +197 -0
- package/Server/Services/EnterpriseLicenseService.ts +55 -0
- package/Server/Services/Index.ts +10 -0
- package/Server/Services/MonitorService.ts +143 -21
- package/Server/Services/MonitorStatusTimelineService.ts +150 -8
- package/Server/Services/MonitorTemplateService.ts +217 -1
- package/Server/Services/NetworkAlertPolicyEngineService.ts +2159 -0
- package/Server/Services/NetworkAlertPolicyService.ts +944 -0
- package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +9 -10
- package/Server/Services/NetworkDeviceAutoImportRuleService.ts +60 -15
- package/Server/Services/NetworkDeviceService.ts +1032 -73
- package/Server/Services/NetworkSiteService.ts +1502 -129
- package/Server/Services/NetworkSiteTypeService.ts +1216 -0
- package/Server/Services/NetworkSnmpCredentialProfileService.ts +238 -0
- package/Server/Services/NotificationService.ts +118 -28
- package/Server/Services/ProjectService.ts +105 -48
- package/Server/Services/StatusPagePrivateUserService.ts +103 -3
- package/Server/Services/UserNotificationEmailRollupBatchService.ts +78 -0
- package/Server/Services/UserNotificationEmailRollupItemService.ts +79 -0
- package/Server/Services/UserNotificationEmailRollupSettingService.ts +113 -0
- package/Server/Services/UserNotificationSettingService.ts +62 -25
- package/Server/Services/UserService.ts +95 -0
- package/Server/Types/Database/QueryHelper.ts +2 -2
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +14 -3
- package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +10 -0
- package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +62 -1
- package/Server/Utils/AI/Toolbox/AlertTools.ts +15 -1
- package/Server/Utils/Billing/BillingFailureNoticeThrottle.ts +80 -0
- package/Server/Utils/DataSource/HttpFetch.ts +9 -2
- package/Server/Utils/EmailRollup/EmailRollupConstants.ts +98 -0
- package/Server/Utils/EmailRollup/EmailRollupFlushRunner.ts +872 -0
- package/Server/Utils/EmailRollup/EmailRollupRenderer.ts +781 -0
- package/Server/Utils/EmailRollup/EmailRollupWriter.ts +368 -0
- package/Server/Utils/LLM/LLMService.ts +78 -0
- package/Server/Utils/LogRedaction.ts +8 -0
- package/Server/Utils/Logger.ts +79 -1
- package/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.ts +190 -0
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +9 -2
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +61 -1
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +14 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +49 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +255 -4
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +41 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +43 -0
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +499 -19
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +66 -10
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +238 -44
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +146 -39
- package/Server/Utils/NetworkDevice/DeviceHealthAggregation.ts +31 -18
- package/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.ts +213 -0
- package/Server/Utils/OutboundUserAgent.ts +152 -0
- package/Server/Utils/StartServer.ts +51 -19
- package/Server/Utils/Telemetry/CaptureSpan.ts +32 -8
- package/Server/Utils/Telemetry/ErrorClassResolver.ts +120 -0
- package/Server/Utils/Telemetry/SpanUtil.ts +33 -0
- package/Server/Utils/Telemetry.ts +198 -51
- package/Server/Views/Partials/SensitiveUrlToken.ejs +140 -0
- package/Tests/App/Dashboard/AddNeighborToMonitoringModal.test.tsx +134 -33
- package/Tests/App/Dashboard/AskAiSuggestedPrompts.test.ts +279 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +517 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +26 -0
- package/Tests/App/Dashboard/DeviceStatusHero.test.tsx +588 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +18 -9
- package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +632 -0
- package/Tests/App/Dashboard/MonitorRecommendationCreateProgress.test.tsx +682 -0
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +4 -2
- package/Tests/App/Dashboard/NetworkDeviceCreateFormMonitorBinding.test.tsx +676 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormPingMonitor.test.tsx +791 -0
- package/Tests/App/Dashboard/NetworkDeviceCreateFormProbeAndSnmp.test.tsx +833 -0
- package/Tests/App/Dashboard/NetworkDeviceCriteriaFilter.test.ts +161 -0
- package/Tests/App/Dashboard/NetworkDeviceSettingsMonitoringSection.test.tsx +458 -0
- package/Tests/App/Dashboard/NetworkSideMenu.test.tsx +41 -5
- package/Tests/App/Dashboard/PingMonitorProvisioning.test.ts +368 -0
- package/Tests/App/Dashboard/RecommendationCard.test.tsx +796 -0
- package/Tests/App/Dashboard/RecommendationToolbar.test.tsx +519 -0
- package/Tests/App/Dashboard/RecommendationsList.test.tsx +661 -0
- package/Tests/App/Dashboard/UseBulkCreatePingMonitors.test.tsx +899 -0
- package/Tests/App/Dashboard/UseBulkSnmpCredentialProfileActions.test.tsx +732 -0
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +256 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +11 -1
- package/Tests/App/StatusPage/StatusPageLoginCodeBootstrap.test.ts +9 -4
- package/Tests/Models/NetworkSiteHierarchy.test.ts +41 -4
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +951 -7
- package/Tests/Server/API/LlmProviderConnectionTest.test.ts +522 -0
- package/Tests/Server/Infrastructure/Postgres/NetworkSnmpCredentialProfilesAndAlertPoliciesMigration.test.ts +854 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +18 -0
- package/Tests/Server/Infrastructure/Postgres/UserNotificationEmailRollupTableMigration.test.ts +535 -0
- package/Tests/Server/Services/AIChatPrivacyPin.test.ts +560 -0
- package/Tests/Server/Services/BillingRechargeOwnerEmailGuards.test.ts +783 -0
- package/Tests/Server/Services/EnterpriseLicenseInstanceServiceDeletionUsage.test.ts +707 -0
- package/Tests/Server/Services/EnterpriseLicenseServiceUsageAggregationLock.test.ts +329 -0
- package/Tests/Server/Services/MonitorServiceDeleteNetworkDeviceCleanup.test.ts +294 -0
- package/Tests/Server/Services/MonitorStatusBridgeProbePath.test.ts +802 -0
- package/Tests/Server/Services/MonitorStatusTimelineService.test.ts +72 -2
- package/Tests/Server/Services/NetworkAlertPolicyEngineHooks.test.ts +752 -0
- package/Tests/Server/Services/NetworkAlertPolicyEngineService.test.ts +1849 -0
- package/Tests/Server/Services/NetworkAlertPolicyModel.test.ts +1793 -0
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +47 -4
- package/Tests/Server/Services/NetworkDeviceAutoImportRuleService.test.ts +97 -12
- package/Tests/Server/Services/NetworkDeviceAutoMonitorLifecycle.test.ts +148 -3
- package/Tests/Server/Services/NetworkDeviceMonitorBindingUpdateGuard.test.ts +514 -0
- package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +447 -58
- package/Tests/Server/Services/NetworkDeviceMonitoringMethodTransition.test.ts +739 -0
- package/Tests/Server/Services/NetworkDevicePollingTenancy.test.ts +501 -0
- package/Tests/Server/Services/NetworkDeviceSiteDefaultProbe.test.ts +432 -0
- package/Tests/Server/Services/NetworkSiteMonitoringDefaults.test.ts +498 -0
- package/Tests/Server/Services/NetworkSiteRollupPolicyAndMaintenance.test.ts +337 -55
- package/Tests/Server/Services/NetworkSiteService.test.ts +1868 -131
- package/Tests/Server/Services/NetworkSiteTypeService.test.ts +1109 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileModel.test.ts +926 -0
- package/Tests/Server/Services/NetworkSnmpCredentialProfileService.test.ts +796 -0
- package/Tests/Server/Services/ProjectServiceNetworkSiteTypeDefaults.test.ts +214 -0
- package/Tests/Server/Services/StatusPagePrivateUserEmailChangePasswordResetExpiry.test.ts +269 -0
- package/Tests/Server/Services/UserEmailChangePasswordResetExpiry.test.ts +472 -0
- package/Tests/Server/Services/UserNotificationEmailRollupModels.test.ts +569 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingModel.test.ts +314 -0
- package/Tests/Server/Services/UserNotificationEmailRollupSettingService.test.ts +409 -0
- package/Tests/Server/Services/UserNotificationSettingRollupRouting.test.ts +856 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +102 -1
- package/Tests/Server/Types/Database/Permissions/DashboardAccessPermission.test.ts +321 -0
- package/Tests/Server/Types/Database/QueryHelperOperators.test.ts +17 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +124 -0
- package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +208 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +235 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +253 -0
- package/Tests/Server/Utils/Captcha.test.ts +422 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +96 -2
- package/Tests/Server/Utils/Database/MigrationFailureLog.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerBehaviour.test.ts +1096 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupFlushRunnerClaim.test.ts +466 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupRenderer.test.ts +1428 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupTestHarness.ts +752 -0
- package/Tests/Server/Utils/EmailRollup/EmailRollupWriter.test.ts +864 -0
- package/Tests/Server/Utils/LoggerFaultDemotion.test.ts +346 -0
- package/Tests/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.test.ts +633 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +196 -0
- package/Tests/Server/Utils/Monitor/DatabaseMetricWrite.test.ts +367 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +100 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +5 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +512 -31
- package/Tests/Server/Utils/Monitor/NetworkDeviceMetricUtil.test.ts +252 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +479 -42
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +351 -5
- package/Tests/Server/Utils/NetworkDevice/DeviceHealthAggregation.test.ts +136 -12
- package/Tests/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.test.ts +306 -0
- package/Tests/Server/Utils/OutboundUserAgent.test.ts +266 -0
- package/Tests/Server/Utils/SecurityEvent/ThreatIntel/TaxiiClientUserAgent.test.ts +141 -0
- package/Tests/Server/Utils/Telemetry/ErrorClassResolver.test.ts +298 -0
- package/Tests/Server/Utils/Telemetry.test.ts +456 -66
- package/Tests/Types/Monitor/DatabaseMetricCatalog.test.ts +388 -0
- package/Tests/Types/Monitor/MonitorStepDatabaseMonitor.test.ts +243 -0
- package/Tests/Types/Monitor/MonitorStepDefaultTelemetryConfig.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorType.test.ts +1 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +16 -7
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +60 -0
- package/Tests/Types/NetworkDevice/NetworkAlertPolicyScope.test.ts +655 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +115 -26
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +39 -0
- package/Tests/Types/NotificationSetting/NotificationEmailRollupPolicy.test.ts +299 -0
- package/Tests/Types/Telemetry/ErrorClass.test.ts +483 -0
- package/Tests/UI/Components/BasicRadioButtons.test.tsx +336 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +15 -0
- package/Tests/UI/Components/ProgressBar.test.tsx +38 -2
- package/Tests/UI/Components/SideMenuItem.test.tsx +226 -4
- package/Tests/UI/Components/SideMenuSection.test.tsx +310 -0
- package/Tests/UI/Components/SideOverSubmitState.test.tsx +335 -0
- package/Tests/UI/Utils/PageScrollLock.test.tsx +377 -0
- package/Tests/UI/Utils/PermissionGate.test.ts +78 -0
- package/Tests/UI/Utils/SensitiveUrlToken.test.ts +140 -0
- package/Tests/Utils/EnterpriseLicenseSeats.test.ts +69 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +7 -1
- package/Tests/Utils/EnterpriseLicenseUsage.test.ts +433 -2
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +280 -1
- package/Tests/Utils/Monitor/MonitorSummarySnapshotUtil.test.ts +1 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +38 -0
- package/Tests/Utils/NetworkDevice/DeviceHealthStateUtil.test.ts +284 -23
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +177 -0
- package/Tests/Utils/NetworkDevice/MonitoringMethodThreadedClassifiers.test.ts +992 -0
- package/Tests/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.test.ts +427 -0
- package/Tests/Utils/NetworkDevice/ReachabilityStampConsistency.test.ts +185 -0
- package/Tests/Utils/NetworkDevice/SnmpCredentialUtil.test.ts +268 -0
- package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +55 -5
- package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +98 -21
- package/Tests/Utils/NetworkDiscovery/DiscoveryImportEligibility.test.ts +98 -20
- package/Tests/Utils/NetworkDiscovery/DiscoveryReverseDnsChain.test.ts +8 -7
- package/Tests/Utils/NetworkDiscovery/PingMonitorBuilderForAddress.test.ts +274 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +230 -51
- package/Tests/Utils/NetworkSite/TypeHierarchyUtil.test.ts +209 -0
- package/Tests/Utils/Telemetry/CaptureSpanExportGating.test.ts +145 -0
- package/Types/AI/ExceptionAIClassification.ts +10 -24
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary.ts +5 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.ts +13 -0
- package/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.ts +6 -0
- package/Types/Exception/ApiException.ts +10 -0
- package/Types/Exception/BadDataException.ts +11 -0
- package/Types/Exception/BadRequestException.ts +11 -0
- package/Types/Exception/Exception.ts +65 -0
- package/Types/Exception/ForbiddenException.ts +10 -0
- package/Types/Exception/NotAuthenticatedException.ts +10 -0
- package/Types/Exception/NotAuthorizedException.ts +10 -0
- package/Types/Exception/NotFoundException.ts +11 -0
- package/Types/Exception/PayloadTooLargeException.ts +11 -0
- package/Types/Exception/PaymentRequiredException.ts +10 -0
- package/Types/Exception/ServiceUnavailableException.ts +10 -0
- package/Types/Exception/SsoAuthorizationException.ts +10 -0
- package/Types/Exception/TenantNotFoundException.ts +11 -0
- package/Types/Exception/TimeoutException.ts +10 -0
- package/Types/Exception/TooManyRequestsException.ts +10 -0
- package/Types/Exception/UnableToReachServer.ts +10 -0
- package/Types/Exception/WebsiteRequestException.ts +10 -0
- package/Types/Monitor/CriteriaFilter.ts +60 -2
- package/Types/Monitor/DatabaseMetricCatalog.ts +693 -0
- package/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.ts +83 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +76 -0
- package/Types/Monitor/MonitorMetricType.ts +71 -0
- package/Types/Monitor/MonitorStep.ts +76 -0
- package/Types/Monitor/MonitorStepDatabaseMonitor.ts +171 -0
- package/Types/Monitor/MonitorStepSqlMonitor.ts +2 -20
- package/Types/Monitor/MonitorType.ts +47 -1
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +22 -1
- package/Types/Monitor/SqlConnectionConfig.ts +31 -0
- package/Types/NetworkDevice/NetworkAlertPolicyScope.ts +343 -0
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +42 -22
- package/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.ts +30 -0
- package/Types/NotificationSetting/NotificationEmailRollupCategory.ts +255 -0
- package/Types/NotificationSetting/NotificationEmailRollupPolicy.ts +104 -0
- package/Types/Permission.ts +90 -0
- package/Types/Probe/ProbeMonitorResponse.ts +16 -0
- package/Types/Telemetry/ErrorClass.ts +274 -0
- package/Types/Telemetry/UnitOfWork.ts +59 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +2 -8
- package/UI/Components/EditionLabel/EditionLabel.tsx +4 -0
- package/UI/Components/Modal/Modal.tsx +2 -8
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +44 -0
- package/UI/Components/ProgressBar/ProgressBar.tsx +12 -1
- package/UI/Components/RadioButtons/BasicRadioButtons.tsx +37 -7
- package/UI/Components/SideMenu/SideMenu.tsx +123 -5
- package/UI/Components/SideMenu/SideMenuItem.tsx +76 -84
- package/UI/Components/SideMenu/SideMenuSection.tsx +55 -23
- package/UI/Components/SideOver/SideOver.tsx +21 -20
- package/UI/Utils/PageScrollLock.ts +79 -3
- package/UI/Utils/PermissionGate.ts +61 -0
- package/UI/Utils/SensitiveUrlToken.ts +112 -0
- package/UI/Utils/TestLLMProvider.ts +11 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSeats.ts +16 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseUsage.ts +191 -11
- package/Utils/Monitor/MonitorMetricType.ts +153 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +23 -3
- package/Utils/NetworkDevice/DeviceHealthStateUtil.ts +65 -14
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +43 -14
- package/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.ts +247 -0
- package/Utils/NetworkDevice/SnmpCredentialUtil.ts +68 -0
- package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +15 -7
- package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +52 -17
- package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +55 -23
- package/Utils/NetworkDiscovery/PingMonitorBuilder.ts +115 -13
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +66 -20
- package/Utils/NetworkSite/TypeHierarchyUtil.ts +313 -0
- package/build/dist/Models/AnalyticsModels/Span.js +14 -0
- package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +59 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +10 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +75 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js +713 -0
- package/build/dist/Models/DatabaseModels/NetworkAlertPolicy.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +180 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSite.js +200 -2
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +102 -3
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js +878 -0
- package/build/dist/Models/DatabaseModels/NetworkSnmpCredentialProfile.js.map +1 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js +123 -0
- package/build/dist/Models/DatabaseModels/TelemetryException.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js +363 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupBatch.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js +402 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js +296 -0
- package/build/dist/Models/DatabaseModels/UserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/API/EnterpriseLicenseAPI.js +273 -60
- package/build/dist/Server/API/EnterpriseLicenseAPI.js.map +1 -1
- package/build/dist/Server/API/LlmProviderAPI.js +108 -13
- package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +12 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js +24 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790700000000-AddNetworkSiteTypeParentHierarchy.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddEnterpriseLicenseUsageProvenance.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js +111 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1790900000000-AddTelemetryExceptionErrorClass.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js +77 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791000000000-AddUserNotificationEmailRollup.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791100000000-AddUserNotificationEmailRollupSetting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js +83 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1791200000000-AddNetworkSnmpCredentialProfilesAndAlertPolicies.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/QueueWorker.js +33 -5
- package/build/dist/Server/Infrastructure/QueueWorker.js.map +1 -1
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js +12 -0
- package/build/dist/Server/Middleware/BearerTokenAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +11 -0
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/SCIMAuthorization.js +12 -0
- package/build/dist/Server/Middleware/SCIMAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +11 -0
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIBillingService.js +70 -16
- package/build/dist/Server/Services/AIBillingService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js +167 -0
- package/build/dist/Server/Services/EnterpriseLicenseInstanceService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +39 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +10 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +119 -21
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +127 -8
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorTemplateService.js +162 -0
- package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js +1683 -0
- package/build/dist/Server/Services/NetworkAlertPolicyEngineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js +732 -0
- package/build/dist/Server/Services/NetworkAlertPolicyService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +10 -9
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +54 -11
- package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +841 -70
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +1145 -107
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteTypeService.js +863 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js +217 -0
- package/build/dist/Server/Services/NetworkSnmpCredentialProfileService.js.map +1 -0
- package/build/dist/Server/Services/NotificationService.js +80 -17
- package/build/dist/Server/Services/NotificationService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +66 -30
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +92 -2
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js +76 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupBatchService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js +77 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupItemService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js +111 -0
- package/build/dist/Server/Services/UserNotificationEmailRollupSettingService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +46 -20
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +90 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +14 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +10 -0
- package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +54 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +18 -4
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js +59 -0
- package/build/dist/Server/Utils/Billing/BillingFailureNoticeThrottle.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +2 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js +91 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupConstants.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js +691 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupFlushRunner.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js +497 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupRenderer.js.map +1 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js +257 -0
- package/build/dist/Server/Utils/EmailRollup/EmailRollupWriter.js.map +1 -0
- package/build/dist/Server/Utils/LLM/LLMService.js +64 -1
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +8 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -1
- package/build/dist/Server/Utils/Logger.js +63 -1
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.js +141 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DatabaseMonitorCriteria.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/Criteria/SnmpMonitorCriteria.js +51 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +7 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +37 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +158 -6
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +330 -21
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +55 -10
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +178 -49
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +119 -29
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js +30 -17
- package/build/dist/Server/Utils/NetworkDevice/DeviceHealthAggregation.js.map +1 -1
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js +158 -0
- package/build/dist/Server/Utils/NetworkSite/NetworkSiteHierarchyLock.js.map +1 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js +123 -0
- package/build/dist/Server/Utils/OutboundUserAgent.js.map +1 -0
- package/build/dist/Server/Utils/StartServer.js +38 -14
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js +28 -8
- package/build/dist/Server/Utils/Telemetry/CaptureSpan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js +95 -0
- package/build/dist/Server/Utils/Telemetry/ErrorClassResolver.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js +29 -0
- package/build/dist/Server/Utils/Telemetry/SpanUtil.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +162 -46
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/AI/ExceptionAIClassification.js +10 -24
- package/build/dist/Types/AI/ExceptionAIClassification.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js +2 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUsageSnapshot.js.map +1 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js +7 -0
- package/build/dist/Types/EnterpriseLicense/EnterpriseLicenseUserCountSource.js.map +1 -0
- package/build/dist/Types/Exception/ApiException.js +9 -0
- package/build/dist/Types/Exception/ApiException.js.map +1 -1
- package/build/dist/Types/Exception/BadDataException.js +10 -0
- package/build/dist/Types/Exception/BadDataException.js.map +1 -1
- package/build/dist/Types/Exception/BadRequestException.js +10 -0
- package/build/dist/Types/Exception/BadRequestException.js.map +1 -1
- package/build/dist/Types/Exception/Exception.js +56 -0
- package/build/dist/Types/Exception/Exception.js.map +1 -1
- package/build/dist/Types/Exception/ForbiddenException.js +9 -0
- package/build/dist/Types/Exception/ForbiddenException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthenticatedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthenticatedException.js.map +1 -1
- package/build/dist/Types/Exception/NotAuthorizedException.js +9 -0
- package/build/dist/Types/Exception/NotAuthorizedException.js.map +1 -1
- package/build/dist/Types/Exception/NotFoundException.js +10 -0
- package/build/dist/Types/Exception/NotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/PayloadTooLargeException.js +10 -0
- package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -1
- package/build/dist/Types/Exception/PaymentRequiredException.js +9 -0
- package/build/dist/Types/Exception/PaymentRequiredException.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +9 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -1
- package/build/dist/Types/Exception/SsoAuthorizationException.js +9 -0
- package/build/dist/Types/Exception/SsoAuthorizationException.js.map +1 -1
- package/build/dist/Types/Exception/TenantNotFoundException.js +10 -0
- package/build/dist/Types/Exception/TenantNotFoundException.js.map +1 -1
- package/build/dist/Types/Exception/TimeoutException.js +9 -0
- package/build/dist/Types/Exception/TimeoutException.js.map +1 -1
- package/build/dist/Types/Exception/TooManyRequestsException.js +9 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -1
- package/build/dist/Types/Exception/UnableToReachServer.js +9 -0
- package/build/dist/Types/Exception/UnableToReachServer.js.map +1 -1
- package/build/dist/Types/Exception/WebsiteRequestException.js +9 -0
- package/build/dist/Types/Exception/WebsiteRequestException.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +45 -2
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js +594 -0
- package/build/dist/Types/Monitor/DatabaseMetricCatalog.js.map +1 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js +21 -0
- package/build/dist/Types/Monitor/DatabaseMonitor/DatabaseMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +70 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +61 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +54 -0
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js +122 -0
- package/build/dist/Types/Monitor/MonitorStepDatabaseMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +45 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +21 -1
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SqlConnectionConfig.js +2 -0
- package/build/dist/Types/Monitor/SqlConnectionConfig.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js +172 -0
- package/build/dist/Types/NetworkDevice/NetworkAlertPolicyScope.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +40 -22
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js +26 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteTypeHierarchy.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js +186 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupCategory.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js +87 -0
- package/build/dist/Types/NotificationSetting/NotificationEmailRollupPolicy.js.map +1 -0
- package/build/dist/Types/Permission.js +80 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/ErrorClass.js +216 -0
- package/build/dist/Types/Telemetry/ErrorClass.js.map +1 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js +59 -0
- package/build/dist/Types/Telemetry/UnitOfWork.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +2 -7
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js +3 -0
- package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -7
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +39 -0
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js +12 -1
- package/build/dist/UI/Components/ProgressBar/ProgressBar.js.map +1 -1
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +6 -6
- package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenu.js +67 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js +49 -53
- package/build/dist/UI/Components/SideMenu/SideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js +25 -7
- package/build/dist/UI/Components/SideMenu/SideMenuSection.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +5 -20
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +31 -3
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +42 -1
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +97 -0
- package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -0
- package/build/dist/UI/Utils/TestLLMProvider.js +4 -5
- package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js +15 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSeats.js.map +1 -1
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js +111 -9
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseUsage.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +109 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +8 -3
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js +27 -7
- package/build/dist/Utils/NetworkDevice/DeviceHealthStateUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +7 -5
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js +180 -0
- package/build/dist/Utils/NetworkDevice/NetworkAlertPolicyBootstrapUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js +12 -0
- package/build/dist/Utils/NetworkDevice/SnmpCredentialUtil.js.map +1 -0
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +15 -5
- package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +44 -15
- package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +52 -23
- package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js +85 -13
- package/build/dist/Utils/NetworkDiscovery/PingMonitorBuilder.js.map +1 -1
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +30 -15
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js +191 -0
- package/build/dist/Utils/NetworkSite/TypeHierarchyUtil.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
import UserService from "../../../Server/Services/UserService";
|
|
2
|
+
import { OnUpdate } from "../../../Server/Types/Database/Hooks";
|
|
3
|
+
import UpdateBy from "../../../Server/Types/Database/UpdateBy";
|
|
4
|
+
import User from "../../../Models/DatabaseModels/User";
|
|
5
|
+
import DatabaseCommonInteractionProps from "../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
6
|
+
import Email from "../../../Types/Email";
|
|
7
|
+
import Name from "../../../Types/Name";
|
|
8
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
9
|
+
import HashedString from "../../../Types/HashedString";
|
|
10
|
+
import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
|
|
11
|
+
|
|
12
|
+
/*
|
|
13
|
+
* ---------------------------------------------------------------------------
|
|
14
|
+
* A PASSWORD RESET LINK MUST NOT SURVIVE THE ADDRESS IT WAS MAILED TO.
|
|
15
|
+
*
|
|
16
|
+
* The bug this file pins down, reported against oneuptime.com as "Broken
|
|
17
|
+
* Authentication Leads To Account Takeover":
|
|
18
|
+
*
|
|
19
|
+
* 1. Somebody who can read the victim's mailbox requests a password reset
|
|
20
|
+
* and DOES NOT click the link. The account is untouched, so nothing looks
|
|
21
|
+
* wrong to the victim -- this is the step that makes the whole thing
|
|
22
|
+
* work.
|
|
23
|
+
* 2. The victim realises the mailbox is compromised and moves the account to
|
|
24
|
+
* an address the attacker cannot read. This is the standard remedy, and
|
|
25
|
+
* the product's own "You have changed your email" mail implies it worked.
|
|
26
|
+
* 3. The attacker spends the link from step 1. `POST /reset-password` finds
|
|
27
|
+
* the account BY TOKEN HASH ALONE -- it never looks at the email address
|
|
28
|
+
* on the row -- so it sets a new password on the account at its NEW
|
|
29
|
+
* address, and the victim loses the account they had just rescued.
|
|
30
|
+
*
|
|
31
|
+
* The fix is one invariant, enforced in `UserService.onBeforeUpdate`: writing a
|
|
32
|
+
* DIFFERENT email address to a user row clears `resetPasswordToken` and
|
|
33
|
+
* `resetPasswordExpires` on that row first. Every test below is about some way
|
|
34
|
+
* that invariant can be broken while the product still appears to work:
|
|
35
|
+
*
|
|
36
|
+
* - clearing AFTER the email write (in `onUpdateSuccess`) leaves a window in
|
|
37
|
+
* which the new address is committed and the old link still redeemable, so
|
|
38
|
+
* the assertions below are about the state of the row when `onBeforeUpdate`
|
|
39
|
+
* RETURNS, before the caller's UPDATE has run at all;
|
|
40
|
+
* - clearing by adding the two columns to `updateBy.data` would look correct
|
|
41
|
+
* and pass a naive test, but `resetPasswordToken` is declared `update: []`,
|
|
42
|
+
* so the permission check that runs after this hook would reject the whole
|
|
43
|
+
* write and no user could change their own email again. Hence the explicit
|
|
44
|
+
* test that `updateBy.data` is left alone;
|
|
45
|
+
* - clearing on EVERY email write, rather than on a change, would let a SCIM
|
|
46
|
+
* directory sync -- which rewrites `email` with the value it already has on
|
|
47
|
+
* every push -- silently invalidate a reset link a user is part-way through
|
|
48
|
+
* using.
|
|
49
|
+
*
|
|
50
|
+
* No database is involved. `findBy` and `updateOneById` on the UserService
|
|
51
|
+
* singleton are jest.spyOn stubs, and the hook -- protected, but an ordinary
|
|
52
|
+
* prototype method at runtime -- is reached through a structural cast.
|
|
53
|
+
* ---------------------------------------------------------------------------
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
const USER_ID: ObjectID = new ObjectID("11111111-1111-4111-8111-111111111111");
|
|
57
|
+
const OTHER_USER_ID: ObjectID = new ObjectID(
|
|
58
|
+
"22222222-2222-4222-8222-222222222222",
|
|
59
|
+
);
|
|
60
|
+
const THIRD_USER_ID: ObjectID = new ObjectID(
|
|
61
|
+
"33333333-3333-4333-8333-333333333333",
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const OLD_EMAIL: string = "victim@compromised-mailbox.example.com";
|
|
65
|
+
const NEW_EMAIL: string = "victim@rescued-mailbox.example.com";
|
|
66
|
+
|
|
67
|
+
// The digest a live reset link would have left on the row.
|
|
68
|
+
const PENDING_TOKEN_HASH: string = "a-live-reset-token-digest";
|
|
69
|
+
|
|
70
|
+
interface UserServiceInternals {
|
|
71
|
+
onBeforeUpdate: (updateBy: UpdateBy<User>) => Promise<OnUpdate<User>>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function userService(): UserServiceInternals {
|
|
75
|
+
return UserService as unknown as UserServiceInternals;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
type PersistedUserData = {
|
|
79
|
+
id?: ObjectID | undefined;
|
|
80
|
+
email?: string | undefined;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/*
|
|
84
|
+
* A row as `onBeforeUpdate`'s own `findBy` returns it: `_id` and `email` only,
|
|
85
|
+
* because that is precisely what the hook selects. `email` is omitted when the
|
|
86
|
+
* caller asks for it, which is the shape a column the caller may not read
|
|
87
|
+
* comes back as.
|
|
88
|
+
*/
|
|
89
|
+
function persistedUser(data: PersistedUserData = {}): User {
|
|
90
|
+
const user: User = new User();
|
|
91
|
+
|
|
92
|
+
if (data.id !== undefined) {
|
|
93
|
+
user.id = data.id;
|
|
94
|
+
user._id = data.id.toString();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (data.email !== undefined) {
|
|
98
|
+
user.email = new Email(data.email);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return user;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
type UpdatePayloadData = {
|
|
105
|
+
patch: Record<string, unknown>;
|
|
106
|
+
query?: Record<string, unknown> | undefined;
|
|
107
|
+
props?: DatabaseCommonInteractionProps | undefined;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
/* An ordinary signed-in user editing their own profile: no root, no role. */
|
|
111
|
+
function currentUserProps(): DatabaseCommonInteractionProps {
|
|
112
|
+
return {
|
|
113
|
+
userId: USER_ID,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function updatePayload(data: UpdatePayloadData): UpdateBy<User> {
|
|
118
|
+
return {
|
|
119
|
+
query: (data.query || {
|
|
120
|
+
_id: USER_ID.toString(),
|
|
121
|
+
}) as unknown as UpdateBy<User>["query"],
|
|
122
|
+
data: data.patch as unknown as UpdateBy<User>["data"],
|
|
123
|
+
props: data.props || currentUserProps(),
|
|
124
|
+
limit: 10,
|
|
125
|
+
skip: 0,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
type Stubs = {
|
|
130
|
+
findBy: jest.SpyInstance;
|
|
131
|
+
updateOneById: jest.SpyInstance;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
let stubs: Stubs;
|
|
135
|
+
|
|
136
|
+
describe("UserService.onBeforeUpdate — a password reset link dies with the address it was mailed to", () => {
|
|
137
|
+
beforeEach(() => {
|
|
138
|
+
stubs = {
|
|
139
|
+
findBy: jest
|
|
140
|
+
.spyOn(UserService, "findBy")
|
|
141
|
+
.mockResolvedValue([
|
|
142
|
+
persistedUser({ id: USER_ID, email: OLD_EMAIL }),
|
|
143
|
+
] as never),
|
|
144
|
+
updateOneById: jest
|
|
145
|
+
.spyOn(UserService, "updateOneById")
|
|
146
|
+
.mockResolvedValue(undefined as never),
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
afterEach(() => {
|
|
151
|
+
jest.restoreAllMocks();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe("the reported attack", () => {
|
|
155
|
+
test("a link minted before the address change is gone once the address changes", async () => {
|
|
156
|
+
/*
|
|
157
|
+
* The end-to-end shape of the report, with the row standing in for the
|
|
158
|
+
* database. What matters is the LAST line: after the victim moves the
|
|
159
|
+
* account, `/reset-password`'s lookup -- `findOneBy({ resetPasswordToken:
|
|
160
|
+
* <hash> })` -- has nothing left to match, so the link the attacker is
|
|
161
|
+
* holding resolves to no user and the endpoint answers "Invalid link".
|
|
162
|
+
*/
|
|
163
|
+
const row: {
|
|
164
|
+
email: string;
|
|
165
|
+
resetPasswordToken: string | null;
|
|
166
|
+
resetPasswordExpires: Date | null;
|
|
167
|
+
} = {
|
|
168
|
+
email: OLD_EMAIL,
|
|
169
|
+
// Step 1: the attacker requested a reset and never spent the link.
|
|
170
|
+
resetPasswordToken: PENDING_TOKEN_HASH,
|
|
171
|
+
resetPasswordExpires: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
stubs.findBy.mockResolvedValue([
|
|
175
|
+
persistedUser({ id: USER_ID, email: row.email }),
|
|
176
|
+
] as never);
|
|
177
|
+
|
|
178
|
+
stubs.updateOneById.mockImplementation(
|
|
179
|
+
(updateBy: { data: Record<string, unknown> }): Promise<number> => {
|
|
180
|
+
if ("resetPasswordToken" in updateBy.data) {
|
|
181
|
+
row.resetPasswordToken = updateBy.data["resetPasswordToken"] as
|
|
182
|
+
| string
|
|
183
|
+
| null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if ("resetPasswordExpires" in updateBy.data) {
|
|
187
|
+
row.resetPasswordExpires = updateBy.data[
|
|
188
|
+
"resetPasswordExpires"
|
|
189
|
+
] as Date | null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return Promise.resolve(1);
|
|
193
|
+
},
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
// Step 2: the victim moves the account to a mailbox the attacker cannot read.
|
|
197
|
+
await userService().onBeforeUpdate(
|
|
198
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
// Step 3: there is no longer anything for the attacker's link to match.
|
|
202
|
+
expect(row.resetPasswordToken).toBeNull();
|
|
203
|
+
expect(row.resetPasswordExpires).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test("the link is dead BEFORE the new address is written, not after", async () => {
|
|
207
|
+
/*
|
|
208
|
+
* The ordering is the security property, not an implementation detail.
|
|
209
|
+
* Clearing in `onUpdateSuccess` would also make the test above pass while
|
|
210
|
+
* leaving an interval -- however short -- in which the account answers to
|
|
211
|
+
* the new address and the old link still works. `onBeforeUpdate` returns
|
|
212
|
+
* to the caller BEFORE the caller's UPDATE runs, so asserting the write
|
|
213
|
+
* has already happened by the time it returns is asserting that no such
|
|
214
|
+
* interval exists.
|
|
215
|
+
*/
|
|
216
|
+
await userService().onBeforeUpdate(
|
|
217
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
expect(stubs.updateOneById).toHaveBeenCalledTimes(1);
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe("what the clearing write looks like", () => {
|
|
225
|
+
test("it nulls both the token and its expiry, and touches nothing else", async () => {
|
|
226
|
+
await userService().onBeforeUpdate(
|
|
227
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
const write: Record<string, unknown> = (
|
|
231
|
+
stubs.updateOneById.mock.calls[0]![0] as unknown as {
|
|
232
|
+
data: Record<string, unknown>;
|
|
233
|
+
}
|
|
234
|
+
).data;
|
|
235
|
+
|
|
236
|
+
expect(write).toEqual({
|
|
237
|
+
resetPasswordToken: null,
|
|
238
|
+
resetPasswordExpires: null,
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
test("it is aimed at the row whose address is changing", async () => {
|
|
243
|
+
await userService().onBeforeUpdate(
|
|
244
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
const write: { id: ObjectID } = stubs.updateOneById.mock
|
|
248
|
+
.calls[0]![0] as unknown as { id: ObjectID };
|
|
249
|
+
|
|
250
|
+
expect(write.id.toString()).toBe(USER_ID.toString());
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("it is a root, hook-free write", async () => {
|
|
254
|
+
/*
|
|
255
|
+
* Root because `resetPasswordToken` carries `update: []` -- there is no
|
|
256
|
+
* permission that can write it, so the ordinary caller's props would be
|
|
257
|
+
* refused. Hook-free because this IS the update hook: re-entering it
|
|
258
|
+
* would send this write looking for an email change of its own.
|
|
259
|
+
*/
|
|
260
|
+
await userService().onBeforeUpdate(
|
|
261
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
262
|
+
);
|
|
263
|
+
|
|
264
|
+
const write: { props: DatabaseCommonInteractionProps } = stubs
|
|
265
|
+
.updateOneById.mock.calls[0]![0] as unknown as {
|
|
266
|
+
props: DatabaseCommonInteractionProps;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
expect(write.props.isRoot).toBe(true);
|
|
270
|
+
expect(write.props.ignoreHooks).toBe(true);
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test("the caller's own update is left exactly as it was", async () => {
|
|
274
|
+
/*
|
|
275
|
+
* The tempting one-line fix is to fold the two nulls into `updateBy.data`
|
|
276
|
+
* so they ride along on the caller's UPDATE. It cannot be done here:
|
|
277
|
+
* `ModelPermission.checkUpdateQueryPermissions` runs AFTER this hook and
|
|
278
|
+
* refuses any column whose `update` list is empty, so a user changing
|
|
279
|
+
* their own email would get a permission error instead of an email
|
|
280
|
+
* change -- a regression that no test about tokens would catch.
|
|
281
|
+
*/
|
|
282
|
+
const payload: UpdateBy<User> = updatePayload({
|
|
283
|
+
patch: { email: new Email(NEW_EMAIL) },
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
await userService().onBeforeUpdate(payload);
|
|
287
|
+
|
|
288
|
+
expect(Object.keys(payload.data)).toEqual(["email"]);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
test("an ordinary user changing their own address still gets the token cleared", async () => {
|
|
292
|
+
/*
|
|
293
|
+
* The victim in the report is not an admin. The clearing write must not
|
|
294
|
+
* inherit the caller's props, or it would be refused for exactly the
|
|
295
|
+
* person the fix exists to protect.
|
|
296
|
+
*/
|
|
297
|
+
await userService().onBeforeUpdate(
|
|
298
|
+
updatePayload({
|
|
299
|
+
patch: { email: new Email(NEW_EMAIL) },
|
|
300
|
+
props: currentUserProps(),
|
|
301
|
+
}),
|
|
302
|
+
);
|
|
303
|
+
|
|
304
|
+
expect(stubs.updateOneById).toHaveBeenCalledTimes(1);
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
describe("writes that must NOT invalidate a pending link", () => {
|
|
309
|
+
test("re-writing the address the account already has", async () => {
|
|
310
|
+
/*
|
|
311
|
+
* SCIM pushes `email` on every sync whether or not it changed (see
|
|
312
|
+
* App/FeatureSet/Identity/API/SCIM.ts, which updates whenever the email
|
|
313
|
+
* OR the name is present). If those cleared tokens, a directory sync
|
|
314
|
+
* firing between "send me a reset link" and "here is my new password"
|
|
315
|
+
* would break the reset for no reason at all.
|
|
316
|
+
*/
|
|
317
|
+
await userService().onBeforeUpdate(
|
|
318
|
+
updatePayload({ patch: { email: new Email(OLD_EMAIL) } }),
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
expect(stubs.updateOneById).not.toHaveBeenCalled();
|
|
322
|
+
});
|
|
323
|
+
|
|
324
|
+
test("re-writing the same address in different case", async () => {
|
|
325
|
+
/*
|
|
326
|
+
* The address the user types is not necessarily the one on the row,
|
|
327
|
+
* character for character. Today `Email` lowercases on construction so
|
|
328
|
+
* the two agree by the time they get here; the comparison lowercases as
|
|
329
|
+
* well, so this keeps holding if a raw string ever reaches `data.email`.
|
|
330
|
+
*/
|
|
331
|
+
stubs.findBy.mockResolvedValue([
|
|
332
|
+
persistedUser({ id: USER_ID, email: "Victim@Example.com" }),
|
|
333
|
+
] as never);
|
|
334
|
+
|
|
335
|
+
await userService().onBeforeUpdate(
|
|
336
|
+
updatePayload({ patch: { email: new Email("victim@example.com") } }),
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
expect(stubs.updateOneById).not.toHaveBeenCalled();
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
test("a password change, which has its own session revocation", async () => {
|
|
343
|
+
await userService().onBeforeUpdate(
|
|
344
|
+
updatePayload({
|
|
345
|
+
patch: { password: new HashedString("a-new-password") },
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
expect(stubs.updateOneById).not.toHaveBeenCalled();
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
test("a profile edit that does not touch the address at all", async () => {
|
|
353
|
+
await userService().onBeforeUpdate(
|
|
354
|
+
updatePayload({ patch: { name: new Name("Victim") } }),
|
|
355
|
+
);
|
|
356
|
+
|
|
357
|
+
expect(stubs.findBy).not.toHaveBeenCalled();
|
|
358
|
+
expect(stubs.updateOneById).not.toHaveBeenCalled();
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
describe("updates that match more than one row", () => {
|
|
363
|
+
test("every row whose address changes is cleared, and only those", async () => {
|
|
364
|
+
/*
|
|
365
|
+
* `updateBy.query` is a query, not an id, so one call can carry the same
|
|
366
|
+
* new address onto several rows -- and the ones already at that address
|
|
367
|
+
* are not changing. A fix written against `updateOneById` alone would
|
|
368
|
+
* quietly clear only the first.
|
|
369
|
+
*/
|
|
370
|
+
stubs.findBy.mockResolvedValue([
|
|
371
|
+
persistedUser({ id: USER_ID, email: OLD_EMAIL }),
|
|
372
|
+
persistedUser({ id: OTHER_USER_ID, email: NEW_EMAIL }),
|
|
373
|
+
persistedUser({ id: THIRD_USER_ID, email: "third@example.com" }),
|
|
374
|
+
] as never);
|
|
375
|
+
|
|
376
|
+
await userService().onBeforeUpdate(
|
|
377
|
+
updatePayload({
|
|
378
|
+
patch: { email: new Email(NEW_EMAIL) },
|
|
379
|
+
query: { isEmailVerified: true },
|
|
380
|
+
}),
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
const clearedIds: Array<string> = stubs.updateOneById.mock.calls.map(
|
|
384
|
+
(call: Array<unknown>) => {
|
|
385
|
+
return (call[0] as { id: ObjectID }).id.toString();
|
|
386
|
+
},
|
|
387
|
+
);
|
|
388
|
+
|
|
389
|
+
expect(clearedIds).toEqual([
|
|
390
|
+
USER_ID.toString(),
|
|
391
|
+
THIRD_USER_ID.toString(),
|
|
392
|
+
]);
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
test("a row that came back without an id is skipped rather than throwing", async () => {
|
|
396
|
+
stubs.findBy.mockResolvedValue([
|
|
397
|
+
persistedUser({ email: OLD_EMAIL }),
|
|
398
|
+
persistedUser({ id: USER_ID, email: OLD_EMAIL }),
|
|
399
|
+
] as never);
|
|
400
|
+
|
|
401
|
+
await expect(
|
|
402
|
+
userService().onBeforeUpdate(
|
|
403
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
404
|
+
),
|
|
405
|
+
).resolves.toBeDefined();
|
|
406
|
+
|
|
407
|
+
expect(stubs.updateOneById).toHaveBeenCalledTimes(1);
|
|
408
|
+
});
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
describe("fail-closed behaviour", () => {
|
|
412
|
+
test("a row whose address could not be read is treated as changed", async () => {
|
|
413
|
+
/*
|
|
414
|
+
* `email` comes back absent only when the caller could not read the
|
|
415
|
+
* column. There is then no way to tell whether the address is changing,
|
|
416
|
+
* and the two answers are not equally bad: guessing "unchanged" leaves a
|
|
417
|
+
* live reset link on an account that may have just moved, while guessing
|
|
418
|
+
* "changed" costs the user one more trip to the forgot-password page.
|
|
419
|
+
*/
|
|
420
|
+
stubs.findBy.mockResolvedValue([persistedUser({ id: USER_ID })] as never);
|
|
421
|
+
|
|
422
|
+
await userService().onBeforeUpdate(
|
|
423
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
expect(stubs.updateOneById).toHaveBeenCalledTimes(1);
|
|
427
|
+
});
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
describe("the rest of the hook still works", () => {
|
|
431
|
+
test("carryForward still holds the rows as they were before the write", async () => {
|
|
432
|
+
/*
|
|
433
|
+
* `onUpdateSuccess` diffs `carryForward` against the re-read rows to
|
|
434
|
+
* decide whether to send the "please verify your new address" mail and
|
|
435
|
+
* clear `isEmailVerified`. Clearing tokens must not disturb that: if
|
|
436
|
+
* carryForward came back empty, an email change would silently stop
|
|
437
|
+
* requiring re-verification.
|
|
438
|
+
*/
|
|
439
|
+
const result: OnUpdate<User> = await userService().onBeforeUpdate(
|
|
440
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
expect(result.carryForward).toHaveLength(1);
|
|
444
|
+
expect((result.carryForward as Array<User>)[0]!.email!.toString()).toBe(
|
|
445
|
+
OLD_EMAIL,
|
|
446
|
+
);
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
test("the rows are loaded once, not once per concern", async () => {
|
|
450
|
+
await userService().onBeforeUpdate(
|
|
451
|
+
updatePayload({ patch: { email: new Email(NEW_EMAIL) } }),
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
expect(stubs.findBy).toHaveBeenCalledTimes(1);
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
test("turning off two factor auth as a non-root caller is still refused", async () => {
|
|
458
|
+
/*
|
|
459
|
+
* The guard that lives immediately after the new code in the same hook.
|
|
460
|
+
* Cheap to assert here, and it is the thing an edit to this method is
|
|
461
|
+
* most likely to displace.
|
|
462
|
+
*/
|
|
463
|
+
await expect(
|
|
464
|
+
userService().onBeforeUpdate(
|
|
465
|
+
updatePayload({ patch: { enableTwoFactorAuth: false } }),
|
|
466
|
+
),
|
|
467
|
+
).rejects.toThrow(
|
|
468
|
+
"Only an administrator can turn off two factor authentication for this account.",
|
|
469
|
+
);
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
});
|