@oneuptime/common 12.0.12 → 12.0.14
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/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
- package/Models/DatabaseModels/NetworkDevice.ts +64 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/StatusPage.ts +59 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
- package/Server/API/AIChatAPI.ts +55 -56
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/CommonAPI.ts +89 -0
- package/Server/API/MicrosoftTeamsAPI.ts +20 -9
- package/Server/API/SlackAPI.ts +13 -10
- package/Server/API/StatusPageAPI.ts +2197 -2128
- package/Server/API/TelemetryAPI.ts +72 -3
- package/Server/API/UserCallAPI.ts +53 -45
- package/Server/API/UserEmailAPI.ts +53 -44
- package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
- package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
- package/Server/API/UserPushAPI.ts +126 -2
- package/Server/API/UserSmsAPI.ts +53 -44
- package/Server/API/UserWhatsAppAPI.ts +53 -50
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/UserAuthorization.ts +11 -2
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/ApiKeyPermissionService.ts +116 -2
- package/Server/Services/DatabaseService.ts +118 -6
- package/Server/Services/LogAggregationService.ts +39 -0
- package/Server/Services/LogService.ts +21 -0
- package/Server/Services/NetworkSiteService.ts +12 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/SpanService.ts +21 -0
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/TraceAggregationService.ts +15 -0
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/APIKey/AccessPermission.ts +16 -40
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/LogRedaction.ts +576 -0
- package/Server/Utils/Logger.ts +123 -46
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResource.ts +29 -9
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
- package/Server/Utils/StartServer.ts +30 -9
- package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +328 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
- package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
- package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
- package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
- package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +280 -0
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
- package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
- package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
- package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
- package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
- package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
- package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
- package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
- package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/MasterPage.test.tsx +36 -1
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/Dropdown.test.ts +423 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
- package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
- package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
- package/Tests/Utils/API.test.ts +16 -2
- package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
- package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/API/Hostname.ts +79 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
- package/Types/Database/DatabaseProperty.ts +38 -0
- package/Types/Database/TableColumn.ts +34 -7
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Events/Recurring.ts +16 -1
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/MonitorStep.ts +13 -1
- package/Types/Monitor/MonitorType.ts +345 -40
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CardSelect/CardSelect.tsx +714 -105
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/EmptyState/EmptyState.tsx +8 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/Footer/Footer.tsx +32 -6
- package/UI/Components/Forms/Fields/FormField.tsx +3 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Loader/PageLoader.tsx +29 -8
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +23 -2
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/MasterPage/MasterPage.tsx +24 -11
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
- package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
- package/UI/Components/Navbar/NavBar.tsx +14 -1
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
- package/UI/Components/SideOver/SideOver.tsx +37 -2
- package/UI/Components/Skeleton/Skeleton.tsx +53 -0
- package/UI/Components/Table/Table.tsx +74 -44
- package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
- package/UI/Components/Tabs/Tab.tsx +1 -1
- package/UI/Components/Toast/Toast.tsx +118 -53
- package/UI/Components/Toast/ToastInit.tsx +82 -32
- package/UI/Styles/Theme.css +40 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
- package/UI/Utils/ModelListCache.ts +188 -0
- package/UI/Utils/Project.ts +29 -0
- package/Utils/API.ts +6 -1
- package/Utils/Monitor/MonitorMetricType.ts +16 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
- package/Utils/Telemetry/CrossSignalScope.ts +75 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +48 -35
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +59 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +13 -10
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +745 -673
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +34 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +42 -38
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +42 -38
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
- package/build/dist/Server/API/UserPushAPI.js +95 -2
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +42 -38
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +89 -6
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +7 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogService.js +16 -0
- package/build/dist/Server/Services/LogService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +12 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +16 -0
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +449 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Logger.js +98 -45
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -7
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
- package/build/dist/Server/Utils/TotpAuth.js +127 -8
- package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
- package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
- package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
- package/build/dist/Server/Utils/VerificationCode.js +120 -0
- package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +63 -0
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +38 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js +24 -6
- package/build/dist/Types/Database/TableColumn.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/Events/Recurring.js +13 -1
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +9 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +330 -31
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/Footer/Footer.js +7 -4
- package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
- package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
- package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +35 -24
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
- package/build/dist/UI/Components/Tabs/Tab.js +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Toast/Toast.js +77 -23
- package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
- package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelListCache.js +126 -0
- package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +24 -1
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/Utils/API.js +6 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
|
@@ -6,6 +6,11 @@ import SiteStatusRollupUtil, {
|
|
|
6
6
|
/*
|
|
7
7
|
* MonitorStatus priority is HIGHER = WORSE (seeded: Operational 1,
|
|
8
8
|
* Degraded 2, Offline 3).
|
|
9
|
+
*
|
|
10
|
+
* The SNMP half of this rollup now asks DeviceReachabilityUtil — "did the
|
|
11
|
+
* last poll succeed" — rather than "was the last success recent". That is
|
|
12
|
+
* what stops a site card going red because its probe is behind on a large
|
|
13
|
+
* fleet while every device under it is answering (issue #3220).
|
|
9
14
|
*/
|
|
10
15
|
const OPERATIONAL: RollupStatusOption = {
|
|
11
16
|
monitorStatusId: "status-operational",
|
|
@@ -26,12 +31,31 @@ function minutesAgo(minutes: number): Date {
|
|
|
26
31
|
return new Date(NOW.getTime() - minutes * 60 * 1000);
|
|
27
32
|
}
|
|
28
33
|
|
|
34
|
+
// A device whose last poll succeeded `minutes` ago.
|
|
35
|
+
function answered(minutes: number): DeviceHealthState {
|
|
36
|
+
return {
|
|
37
|
+
isReachable: true,
|
|
38
|
+
lastPolledAt: minutesAgo(minutes),
|
|
39
|
+
lastSeenAt: minutesAgo(minutes),
|
|
40
|
+
pollingIntervalInMinutes: 5,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// A device whose last poll failed `minutes` ago.
|
|
45
|
+
function failed(minutes: number): DeviceHealthState {
|
|
46
|
+
return {
|
|
47
|
+
isReachable: false,
|
|
48
|
+
lastPolledAt: minutesAgo(minutes),
|
|
49
|
+
lastSeenAt: minutesAgo(minutes + 60),
|
|
50
|
+
pollingIntervalInMinutes: 5,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
29
54
|
function worst(
|
|
30
55
|
deviceStates: Array<DeviceHealthState>,
|
|
31
56
|
overrides?: {
|
|
32
57
|
operationalStatus?: RollupStatusOption | null;
|
|
33
58
|
offlineStatus?: RollupStatusOption | null;
|
|
34
|
-
freshnessWindowInMinutes?: number;
|
|
35
59
|
},
|
|
36
60
|
): string | null {
|
|
37
61
|
return SiteStatusRollupUtil.worstStatus({
|
|
@@ -45,7 +69,6 @@ function worst(
|
|
|
45
69
|
? overrides.offlineStatus
|
|
46
70
|
: OFFLINE,
|
|
47
71
|
now: NOW,
|
|
48
|
-
freshnessWindowInMinutes: overrides?.freshnessWindowInMinutes,
|
|
49
72
|
});
|
|
50
73
|
}
|
|
51
74
|
|
|
@@ -84,65 +107,103 @@ describe("SiteStatusRollupUtil.worstStatus", () => {
|
|
|
84
107
|
).toBe(OFFLINE.monitorStatusId);
|
|
85
108
|
});
|
|
86
109
|
|
|
87
|
-
it("a
|
|
88
|
-
expect(worst([
|
|
110
|
+
it("a device whose last poll succeeded maps to the operational equivalent", () => {
|
|
111
|
+
expect(worst([answered(5)])).toBe(OPERATIONAL.monitorStatusId);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("a device whose last poll failed maps to the offline equivalent", () => {
|
|
115
|
+
expect(worst([failed(2)])).toBe(OFFLINE.monitorStatusId);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
* The rollup half of issue #3220. 21 minutes was the reported lag on a
|
|
120
|
+
* fleet the probe could not get round in 15, and every device under the
|
|
121
|
+
* site was answering.
|
|
122
|
+
*/
|
|
123
|
+
it("issue #3220: a site whose devices are all answering, 21 minutes behind, is operational", () => {
|
|
124
|
+
expect(worst([answered(21), answered(19), answered(25)])).toBe(
|
|
89
125
|
OPERATIONAL.monitorStatusId,
|
|
90
126
|
);
|
|
91
127
|
});
|
|
92
128
|
|
|
93
|
-
it("a
|
|
94
|
-
expect(
|
|
95
|
-
|
|
96
|
-
|
|
129
|
+
it("a slow-polled device is operational right up to its next poll", () => {
|
|
130
|
+
expect(
|
|
131
|
+
worst([
|
|
132
|
+
{
|
|
133
|
+
isReachable: true,
|
|
134
|
+
lastPolledAt: minutesAgo(29),
|
|
135
|
+
lastSeenAt: minutesAgo(29),
|
|
136
|
+
pollingIntervalInMinutes: 30,
|
|
137
|
+
},
|
|
138
|
+
]),
|
|
139
|
+
).toBe(OPERATIONAL.monitorStatusId);
|
|
97
140
|
});
|
|
98
141
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
142
|
+
/*
|
|
143
|
+
* A site nothing has polled for hours keeps its last known status rather
|
|
144
|
+
* than flipping offline. Turning "nobody has checked lately" into a red
|
|
145
|
+
* site card is the same inference this change removed from the device
|
|
146
|
+
* pill — and doing it here alone would put the site card at odds with
|
|
147
|
+
* every device under it, which is the inconsistency issue #3220 reported.
|
|
148
|
+
*/
|
|
149
|
+
it("a device out of contact past its stale window keeps its last verdict", () => {
|
|
150
|
+
expect(worst([answered(61)])).toBe(OPERATIONAL.monitorStatusId);
|
|
151
|
+
expect(worst([answered(60 * 24)])).toBe(OPERATIONAL.monitorStatusId);
|
|
102
152
|
});
|
|
103
153
|
|
|
104
|
-
it("
|
|
105
|
-
expect(worst([
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
154
|
+
it("...but a device that actually failed its last poll still rolls up offline", () => {
|
|
155
|
+
expect(worst([failed(60 * 24)])).toBe(OFFLINE.monitorStatusId);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
/*
|
|
159
|
+
* Changed deliberately: a never-polled device used to be counted as
|
|
160
|
+
* offline, which pinned a brand-new site red until its first walk landed
|
|
161
|
+
* — while the device list showed the very same device as a gray
|
|
162
|
+
* "Pending". It now contributes nothing, and the caller reads null as
|
|
163
|
+
* "leave the site's status alone".
|
|
164
|
+
*/
|
|
165
|
+
it("a never-polled device contributes nothing at all", () => {
|
|
166
|
+
expect(worst([{}])).toBeNull();
|
|
167
|
+
expect(worst([{ isReachable: null, lastSeenAt: null }])).toBeNull();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it("a never-polled device does not drag down a site with healthy devices", () => {
|
|
171
|
+
expect(worst([answered(1), {}])).toBe(OPERATIONAL.monitorStatusId);
|
|
111
172
|
});
|
|
112
173
|
|
|
113
|
-
it("mix: a
|
|
174
|
+
it("mix: a failing device outranks a monitored operational one", () => {
|
|
114
175
|
expect(
|
|
115
176
|
worst([
|
|
116
177
|
{
|
|
117
178
|
currentMonitorStatusId: OPERATIONAL.monitorStatusId,
|
|
118
179
|
monitorStatusPriority: OPERATIONAL.priority,
|
|
119
180
|
},
|
|
120
|
-
|
|
181
|
+
failed(1),
|
|
121
182
|
]),
|
|
122
183
|
).toBe(OFFLINE.monitorStatusId);
|
|
123
184
|
});
|
|
124
185
|
|
|
125
|
-
it("mix: a monitored offline device outranks
|
|
186
|
+
it("mix: a monitored offline device outranks answering ones", () => {
|
|
126
187
|
expect(
|
|
127
188
|
worst([
|
|
128
|
-
|
|
189
|
+
answered(1),
|
|
129
190
|
{
|
|
130
191
|
currentMonitorStatusId: OFFLINE.monitorStatusId,
|
|
131
192
|
monitorStatusPriority: OFFLINE.priority,
|
|
132
193
|
},
|
|
133
|
-
|
|
194
|
+
answered(2),
|
|
134
195
|
]),
|
|
135
196
|
).toBe(OFFLINE.monitorStatusId);
|
|
136
197
|
});
|
|
137
198
|
|
|
138
|
-
it("a stamped status whose priority is unknown falls back to
|
|
139
|
-
// The MonitorStatus row was deleted: treat the device by
|
|
199
|
+
it("a stamped status whose priority is unknown falls back to reachability", () => {
|
|
200
|
+
// The MonitorStatus row was deleted: treat the device by its last poll.
|
|
140
201
|
expect(
|
|
141
202
|
worst([
|
|
142
203
|
{
|
|
143
204
|
currentMonitorStatusId: "deleted-status",
|
|
144
205
|
monitorStatusPriority: undefined,
|
|
145
|
-
|
|
206
|
+
...answered(1),
|
|
146
207
|
},
|
|
147
208
|
]),
|
|
148
209
|
).toBe(OPERATIONAL.monitorStatusId);
|
|
@@ -151,7 +212,7 @@ describe("SiteStatusRollupUtil.worstStatus", () => {
|
|
|
151
212
|
{
|
|
152
213
|
currentMonitorStatusId: "deleted-status",
|
|
153
214
|
monitorStatusPriority: null,
|
|
154
|
-
|
|
215
|
+
...failed(1),
|
|
155
216
|
},
|
|
156
217
|
]),
|
|
157
218
|
).toBe(OFFLINE.monitorStatusId);
|
|
@@ -172,9 +233,9 @@ describe("SiteStatusRollupUtil.worstStatus", () => {
|
|
|
172
233
|
).toBe("status-a");
|
|
173
234
|
});
|
|
174
235
|
|
|
175
|
-
it("returns null when only
|
|
236
|
+
it("returns null when only SNMP fallbacks apply but the project has no flagged rows", () => {
|
|
176
237
|
expect(
|
|
177
|
-
worst([
|
|
238
|
+
worst([answered(1), failed(1)], {
|
|
178
239
|
operationalStatus: null,
|
|
179
240
|
offlineStatus: null,
|
|
180
241
|
}),
|
|
@@ -185,7 +246,7 @@ describe("SiteStatusRollupUtil.worstStatus", () => {
|
|
|
185
246
|
expect(
|
|
186
247
|
worst(
|
|
187
248
|
[
|
|
188
|
-
|
|
249
|
+
failed(1), // offline equivalent missing -> skipped
|
|
189
250
|
{
|
|
190
251
|
currentMonitorStatusId: DEGRADED.monitorStatusId,
|
|
191
252
|
monitorStatusPriority: DEGRADED.priority,
|
|
@@ -196,26 +257,34 @@ describe("SiteStatusRollupUtil.worstStatus", () => {
|
|
|
196
257
|
).toBe(DEGRADED.monitorStatusId);
|
|
197
258
|
});
|
|
198
259
|
|
|
199
|
-
it("
|
|
260
|
+
it("a lastPolledAt in the future counts as fresh, not an error", () => {
|
|
200
261
|
expect(
|
|
201
|
-
worst([
|
|
202
|
-
|
|
203
|
-
|
|
262
|
+
worst([
|
|
263
|
+
{
|
|
264
|
+
isReachable: true,
|
|
265
|
+
lastPolledAt: minutesAgo(-5),
|
|
266
|
+
lastSeenAt: minutesAgo(-5),
|
|
267
|
+
},
|
|
268
|
+
]),
|
|
204
269
|
).toBe(OPERATIONAL.monitorStatusId);
|
|
205
|
-
expect(
|
|
206
|
-
worst([{ lastSeenAt: minutesAgo(20) }], {
|
|
207
|
-
freshnessWindowInMinutes: 10,
|
|
208
|
-
}),
|
|
209
|
-
).toBe(OFFLINE.monitorStatusId);
|
|
210
270
|
});
|
|
211
271
|
|
|
212
|
-
|
|
213
|
-
|
|
272
|
+
/*
|
|
273
|
+
* Rows written before the reachability columns existed carry only
|
|
274
|
+
* lastSeenAt. They must keep rolling up sensibly until the upgrade
|
|
275
|
+
* migration (or their next walk) fills the rest in.
|
|
276
|
+
*/
|
|
277
|
+
it("legacy rows with only lastSeenAt still roll up by freshness", () => {
|
|
278
|
+
/*
|
|
279
|
+
* The one place freshness survives: a row written before isReachable
|
|
280
|
+
* existed has nothing else to go on. The upgrade migration backfills
|
|
281
|
+
* these, so it is a short-lived path.
|
|
282
|
+
*/
|
|
283
|
+
expect(worst([{ lastSeenAt: minutesAgo(5) }])).toBe(
|
|
214
284
|
OPERATIONAL.monitorStatusId,
|
|
215
285
|
);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
expect(SiteStatusRollupUtil.DEFAULT_FRESHNESS_WINDOW_IN_MINUTES).toBe(15);
|
|
286
|
+
expect(worst([{ lastSeenAt: minutesAgo(600) }])).toBe(
|
|
287
|
+
OFFLINE.monitorStatusId,
|
|
288
|
+
);
|
|
220
289
|
});
|
|
221
290
|
});
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { describe, expect, it } from "@jest/globals";
|
|
2
|
+
import UrlScrubber from "../../../Utils/Rum/UrlScrubber";
|
|
3
|
+
|
|
4
|
+
/*
|
|
5
|
+
* The parent UrlScrubber.test.ts drives the whole pipeline through the
|
|
6
|
+
* public scrub()/getScrubbedPathname() facade. This suite pins the two
|
|
7
|
+
* segment-level primitives directly — scrubPath() and scrubQuery() — so
|
|
8
|
+
* that the branch behaviour each one owns (every redaction pattern and its
|
|
9
|
+
* length boundary, the decode-before-match step, the empty/"/" short
|
|
10
|
+
* circuits, and the allowlist rules) is exercised in isolation rather than
|
|
11
|
+
* only as an emergent property of a full URL round-trip.
|
|
12
|
+
*
|
|
13
|
+
* Everything here is a pure function of its arguments: no network, no clock,
|
|
14
|
+
* no randomness. scrubQuery takes a plain URLSearchParams built inline.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const REDACTED: string = "[redacted]";
|
|
18
|
+
|
|
19
|
+
describe("UrlScrubber segment primitives", () => {
|
|
20
|
+
describe("scrubPath", () => {
|
|
21
|
+
describe("empty and boundary inputs", () => {
|
|
22
|
+
it("normalises an empty path to a single slash", () => {
|
|
23
|
+
/*
|
|
24
|
+
* The `pathname || "/"` fallback: an empty string is not passed
|
|
25
|
+
* through as-is, it is turned into the root path.
|
|
26
|
+
*/
|
|
27
|
+
expect(UrlScrubber.scrubPath("")).toBe("/");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("returns the root path unchanged", () => {
|
|
31
|
+
expect(UrlScrubber.scrubPath("/")).toBe("/");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("keeps a path whose segments are all ordinary route words", () => {
|
|
35
|
+
expect(UrlScrubber.scrubPath("/blog/how-we-scaled-clickhouse")).toBe(
|
|
36
|
+
"/blog/how-we-scaled-clickhouse",
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("preserves the leading empty segment produced by the leading slash", () => {
|
|
41
|
+
/*
|
|
42
|
+
* "/orders/2".split("/") is ["", "orders", "2"]; the empty first
|
|
43
|
+
* element must survive the map so the result stays absolute.
|
|
44
|
+
*/
|
|
45
|
+
const scrubbed: string = UrlScrubber.scrubPath("/orders/2");
|
|
46
|
+
|
|
47
|
+
expect(scrubbed).toBe("/orders/2");
|
|
48
|
+
expect(scrubbed.startsWith("/")).toBe(true);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("preserves a trailing slash and collapsed empty segments", () => {
|
|
52
|
+
expect(UrlScrubber.scrubPath("/a//b/")).toBe("/a//b/");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("handles a path that is a single identifier segment", () => {
|
|
56
|
+
expect(
|
|
57
|
+
UrlScrubber.scrubPath("/3f1a9c7e-5b2d-4801-96a3-c9e7b1d5028f"),
|
|
58
|
+
).toBe(`/${REDACTED}`);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("uuid segments", () => {
|
|
63
|
+
it("redacts a canonical lowercase uuid while keeping the route shape", () => {
|
|
64
|
+
expect(
|
|
65
|
+
UrlScrubber.scrubPath(
|
|
66
|
+
"/orders/3f1a9c7e-5b2d-4801-96a3-c9e7b1d5028f/items",
|
|
67
|
+
),
|
|
68
|
+
).toBe(`/orders/${REDACTED}/items`);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it("redacts a uuid case-insensitively", () => {
|
|
72
|
+
expect(
|
|
73
|
+
UrlScrubber.scrubPath("/orders/3F1A9C7E-5B2D-4801-96A3-C9E7B1D5028F"),
|
|
74
|
+
).toBe(`/orders/${REDACTED}`);
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it("does not treat a uuid-shaped-but-wrong-length string as a uuid", () => {
|
|
78
|
+
/*
|
|
79
|
+
* A truncated uuid (30 chars): it fails the anchored uuid pattern
|
|
80
|
+
* and, being under the 32-char opaque-token threshold, escapes that
|
|
81
|
+
* rule too, so it survives as ordinary route structure.
|
|
82
|
+
*/
|
|
83
|
+
const almost: string = "3f1a9c7e-5b2d-4801-96a3-c9e7b1";
|
|
84
|
+
|
|
85
|
+
expect(almost.length).toBeLessThan(32);
|
|
86
|
+
expect(UrlScrubber.scrubPath(`/x/${almost}`)).toBe(`/x/${almost}`);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("object id segments", () => {
|
|
91
|
+
it("redacts a 24-character Mongo/BSON object id", () => {
|
|
92
|
+
expect(UrlScrubber.scrubPath("/users/6512f3a9b7c4d2e108f5a3b9")).toBe(
|
|
93
|
+
`/users/${REDACTED}`,
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("keeps a 23-character hex string, one short of an object id", () => {
|
|
98
|
+
const shortHex: string = "6512f3a9b7c4d2e108f5a3b";
|
|
99
|
+
|
|
100
|
+
expect(UrlScrubber.scrubPath(`/users/${shortHex}`)).toBe(
|
|
101
|
+
`/users/${shortHex}`,
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe("email segments", () => {
|
|
107
|
+
it("redacts a plain email segment", () => {
|
|
108
|
+
expect(UrlScrubber.scrubPath("/u/someone@example.com/profile")).toBe(
|
|
109
|
+
`/u/${REDACTED}/profile`,
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("redacts a percent-encoded email by decoding before matching", () => {
|
|
114
|
+
/*
|
|
115
|
+
* name%40example.com decodes to name@example.com; the decode step
|
|
116
|
+
* is what lets the email pattern see it.
|
|
117
|
+
*/
|
|
118
|
+
const scrubbed: string = UrlScrubber.scrubPath(
|
|
119
|
+
"/u/someone%40example.com",
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
expect(scrubbed).toBe(`/u/${REDACTED}`);
|
|
123
|
+
expect(scrubbed).not.toContain("%40");
|
|
124
|
+
expect(scrubbed).not.toContain("someone");
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("keeps a segment that merely contains an at-sign but is not an address", () => {
|
|
128
|
+
/*
|
|
129
|
+
* A handle like "@acme" has no domain part, so the anchored email
|
|
130
|
+
* pattern rejects it and it is treated as route structure.
|
|
131
|
+
*/
|
|
132
|
+
expect(UrlScrubber.scrubPath("/team/@acme")).toBe("/team/@acme");
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe("long digit-run segments", () => {
|
|
137
|
+
it("redacts a run of 9 or more digits (card / phone / SSN shaped)", () => {
|
|
138
|
+
expect(UrlScrubber.scrubPath("/account/4111111111111111")).toBe(
|
|
139
|
+
`/account/${REDACTED}`,
|
|
140
|
+
);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("redacts at the 9-digit boundary", () => {
|
|
144
|
+
expect(UrlScrubber.scrubPath("/n/123456789")).toBe(`/n/${REDACTED}`);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("keeps an 8-digit run just under the boundary", () => {
|
|
148
|
+
expect(UrlScrubber.scrubPath("/n/12345678")).toBe("/n/12345678");
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("keeps a short numeric id, which is route structure not PII", () => {
|
|
152
|
+
expect(UrlScrubber.scrubPath("/page/2")).toBe("/page/2");
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe("opaque token segments", () => {
|
|
157
|
+
it("redacts a 32-or-longer high-entropy token", () => {
|
|
158
|
+
expect(
|
|
159
|
+
UrlScrubber.scrubPath(
|
|
160
|
+
"/s/aVeryLongOpaqueSessionTokenValue1234567890",
|
|
161
|
+
),
|
|
162
|
+
).toBe(`/s/${REDACTED}`);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it("redacts exactly at the 32-character boundary", () => {
|
|
166
|
+
const token: string = "a".repeat(32);
|
|
167
|
+
|
|
168
|
+
expect(UrlScrubber.scrubPath(`/s/${token}`)).toBe(`/s/${REDACTED}`);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("keeps a 31-character string just under the boundary", () => {
|
|
172
|
+
const slug: string = "a".repeat(31);
|
|
173
|
+
|
|
174
|
+
expect(UrlScrubber.scrubPath(`/s/${slug}`)).toBe(`/s/${slug}`);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it("keeps a long slug that carries a dot outside the token charset", () => {
|
|
178
|
+
/*
|
|
179
|
+
* The opaque-token charset is [A-Za-z0-9_-]; a dot disqualifies the
|
|
180
|
+
* whole segment even when it is well over 32 characters, so a
|
|
181
|
+
* dotted asset name survives.
|
|
182
|
+
*/
|
|
183
|
+
const dotted: string = "this-is-a-fairly-long-report-name.2024.final";
|
|
184
|
+
|
|
185
|
+
expect(UrlScrubber.scrubPath(`/files/${dotted}`)).toBe(
|
|
186
|
+
`/files/${dotted}`,
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe("decode fallback and structure preservation", () => {
|
|
192
|
+
it("never throws and leaves a malformed percent-escape segment intact", () => {
|
|
193
|
+
/*
|
|
194
|
+
* decodeURIComponent("%E0%A4%A") throws; the catch falls back to
|
|
195
|
+
* matching the raw segment, which matches nothing, so the segment
|
|
196
|
+
* is returned exactly as given rather than crashing the mapper.
|
|
197
|
+
*/
|
|
198
|
+
const malformed: string = "%E0%A4%A";
|
|
199
|
+
|
|
200
|
+
let scrubbed: string = "";
|
|
201
|
+
|
|
202
|
+
expect((): void => {
|
|
203
|
+
scrubbed = UrlScrubber.scrubPath(`/x/${malformed}`);
|
|
204
|
+
}).not.toThrow();
|
|
205
|
+
|
|
206
|
+
expect(scrubbed).toBe(`/x/${malformed}`);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
it("returns the raw (still-encoded) form for a non-PII encoded segment", () => {
|
|
210
|
+
/*
|
|
211
|
+
* A kept segment is returned in its original encoded form, not the
|
|
212
|
+
* decoded one: "caf%C3%A9" decodes to "café", matches no pattern,
|
|
213
|
+
* and comes back byte-for-byte as it went in.
|
|
214
|
+
*/
|
|
215
|
+
expect(UrlScrubber.scrubPath("/menu/caf%C3%A9")).toBe(
|
|
216
|
+
"/menu/caf%C3%A9",
|
|
217
|
+
);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
it("redacts only the identifier segments in a mixed path", () => {
|
|
221
|
+
const mixed: string =
|
|
222
|
+
"/org/acme/users/6512f3a9b7c4d2e108f5a3b9/orders/2/token/" +
|
|
223
|
+
"aVeryLongOpaqueSessionTokenValue1234567890";
|
|
224
|
+
|
|
225
|
+
expect(UrlScrubber.scrubPath(mixed)).toBe(
|
|
226
|
+
`/org/acme/users/${REDACTED}/orders/2/token/${REDACTED}`,
|
|
227
|
+
);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it("redacts every identifier segment when a path is nothing but ids", () => {
|
|
231
|
+
expect(
|
|
232
|
+
UrlScrubber.scrubPath(
|
|
233
|
+
"/6512f3a9b7c4d2e108f5a3b9/someone@example.com/123456789",
|
|
234
|
+
),
|
|
235
|
+
).toBe(`/${REDACTED}/${REDACTED}/${REDACTED}`);
|
|
236
|
+
});
|
|
237
|
+
});
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
describe("scrubQuery", () => {
|
|
241
|
+
describe("empty / missing allowlist drops everything", () => {
|
|
242
|
+
it("returns an empty string when the allowlist is undefined", () => {
|
|
243
|
+
const params: URLSearchParams = new URLSearchParams(
|
|
244
|
+
"plan=growth&coupon=SECRET50",
|
|
245
|
+
);
|
|
246
|
+
|
|
247
|
+
expect(UrlScrubber.scrubQuery(params)).toBe("");
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it("returns an empty string when the allowlist is empty", () => {
|
|
251
|
+
const params: URLSearchParams = new URLSearchParams("plan=growth");
|
|
252
|
+
|
|
253
|
+
expect(UrlScrubber.scrubQuery(params, [])).toBe("");
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("returns an empty string when no parameter matches the allowlist", () => {
|
|
257
|
+
const params: URLSearchParams = new URLSearchParams(
|
|
258
|
+
"coupon=SECRET50&ref=twitter",
|
|
259
|
+
);
|
|
260
|
+
|
|
261
|
+
expect(UrlScrubber.scrubQuery(params, ["plan"])).toBe("");
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it("returns an empty string for a query with no parameters at all", () => {
|
|
265
|
+
expect(UrlScrubber.scrubQuery(new URLSearchParams(""), ["plan"])).toBe(
|
|
266
|
+
"",
|
|
267
|
+
);
|
|
268
|
+
});
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
describe("allowlisted names are kept with redacted values", () => {
|
|
272
|
+
it("keeps the name and redacts the value of an allowlisted parameter", () => {
|
|
273
|
+
const params: URLSearchParams = new URLSearchParams(
|
|
274
|
+
"plan=growth&coupon=SECRET50",
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
const scrubbed: string = UrlScrubber.scrubQuery(params, ["plan"]);
|
|
278
|
+
|
|
279
|
+
expect(scrubbed).toBe(`plan=${REDACTED}`);
|
|
280
|
+
expect(scrubbed).not.toContain("growth");
|
|
281
|
+
expect(scrubbed).not.toContain("SECRET50");
|
|
282
|
+
expect(scrubbed).not.toContain("coupon");
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
it("redacts the value regardless of how sensitive it looks", () => {
|
|
286
|
+
const params: URLSearchParams = new URLSearchParams();
|
|
287
|
+
params.append("token", "eyJhbGciOiJIUzI1NiJ9.payload.signature");
|
|
288
|
+
|
|
289
|
+
const scrubbed: string = UrlScrubber.scrubQuery(params, ["token"]);
|
|
290
|
+
|
|
291
|
+
expect(scrubbed).toBe(`token=${REDACTED}`);
|
|
292
|
+
expect(scrubbed).not.toContain("eyJ");
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("keeps several allowlisted parameters joined by ampersands", () => {
|
|
296
|
+
const params: URLSearchParams = new URLSearchParams(
|
|
297
|
+
"plan=growth&ref=twitter&step=2",
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
expect(UrlScrubber.scrubQuery(params, ["plan", "step"])).toBe(
|
|
301
|
+
`plan=${REDACTED}&step=${REDACTED}`,
|
|
302
|
+
);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it("preserves the original query order of the kept parameters", () => {
|
|
306
|
+
const params: URLSearchParams = new URLSearchParams(
|
|
307
|
+
"step=2&plan=growth",
|
|
308
|
+
);
|
|
309
|
+
|
|
310
|
+
expect(UrlScrubber.scrubQuery(params, ["plan", "step"])).toBe(
|
|
311
|
+
`step=${REDACTED}&plan=${REDACTED}`,
|
|
312
|
+
);
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
describe("case-insensitive matching", () => {
|
|
317
|
+
it("matches an allowlist entry against a differently-cased parameter name", () => {
|
|
318
|
+
const params: URLSearchParams = new URLSearchParams("Plan=growth");
|
|
319
|
+
|
|
320
|
+
/*
|
|
321
|
+
* The comparison lowercases both sides, but the emitted name keeps
|
|
322
|
+
* the parameter's original casing.
|
|
323
|
+
*/
|
|
324
|
+
expect(UrlScrubber.scrubQuery(params, ["plan"])).toBe(
|
|
325
|
+
`Plan=${REDACTED}`,
|
|
326
|
+
);
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it("matches when the allowlist entry itself is upper-cased", () => {
|
|
330
|
+
const params: URLSearchParams = new URLSearchParams("plan=growth");
|
|
331
|
+
|
|
332
|
+
expect(UrlScrubber.scrubQuery(params, ["PLAN"])).toBe(
|
|
333
|
+
`plan=${REDACTED}`,
|
|
334
|
+
);
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
describe("edge cases in parameter names", () => {
|
|
339
|
+
it("emits one redacted entry per repeated occurrence of a key", () => {
|
|
340
|
+
/*
|
|
341
|
+
* URLSearchParams keeps duplicate keys, so forEach visits each one;
|
|
342
|
+
* both are kept, and because the value is redacted the two entries
|
|
343
|
+
* are identical.
|
|
344
|
+
*/
|
|
345
|
+
const params: URLSearchParams = new URLSearchParams("a=1&a=2&b=3");
|
|
346
|
+
|
|
347
|
+
expect(UrlScrubber.scrubQuery(params, ["a"])).toBe(
|
|
348
|
+
`a=${REDACTED}&a=${REDACTED}`,
|
|
349
|
+
);
|
|
350
|
+
});
|
|
351
|
+
|
|
352
|
+
it("percent-encodes an allowlisted key that contains a space", () => {
|
|
353
|
+
const params: URLSearchParams = new URLSearchParams();
|
|
354
|
+
params.append("user name", "jane");
|
|
355
|
+
|
|
356
|
+
expect(UrlScrubber.scrubQuery(params, ["user name"])).toBe(
|
|
357
|
+
`user%20name=${REDACTED}`,
|
|
358
|
+
);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
362
|
+
});
|