@oneuptime/common 12.0.13 → 12.0.15
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/GlobalOidc.ts +20 -0
- package/Models/DatabaseModels/GlobalSso.ts +20 -0
- package/Models/DatabaseModels/MarketingConversion.ts +19 -9
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/StatusPage.ts +7 -4
- 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/Server/API/BaseAPI.ts +79 -14
- package/Server/API/StatusPageAPI.ts +29 -4
- 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/EnvironmentConfig.ts +7 -0
- 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/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/SlackAuthorization.ts +43 -6
- package/Server/Middleware/UserAuthorization.ts +236 -26
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/DatabaseService.ts +101 -0
- package/Server/Services/GlobalOidcProjectService.ts +126 -1
- package/Server/Services/GlobalOidcService.ts +132 -0
- package/Server/Services/GlobalSsoProjectService.ts +126 -1
- package/Server/Services/GlobalSsoService.ts +132 -0
- package/Server/Services/LogAggregationService.ts +5 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/TeamMemberService.ts +53 -13
- 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/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/CronTab.ts +73 -0
- package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
- package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
- package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
- package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +47 -44
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResource.ts +161 -21
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
- package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- 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 +28 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -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/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +265 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
- package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -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/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
- package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
- 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/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/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -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/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
- package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -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/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/CronTab.test.ts +116 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
- package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
- 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/EvaluateOverTime.test.ts +987 -0
- package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -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/ProfileMonitorCriteria.test.ts +382 -0
- package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
- 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 +86 -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/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
- package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -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/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/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/MonitorStepConfigHelpers.test.ts +165 -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/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- 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/FormSubmitAnalytics.test.tsx +206 -0
- 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/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/AIChatExport/ConversationMarkdown.test.ts +774 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -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/Analytics.test.ts +187 -0
- 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 +80 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
- package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Marketing/MarketingConversion.ts +12 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -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/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- 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/Feed/FeedItem.tsx +1 -1
- package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
- package/UI/Components/Forms/BasicForm.tsx +13 -1
- package/UI/Components/Forms/BasicModelForm.tsx +2 -1
- package/UI/Components/Forms/ModelForm.tsx +10 -1
- package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
- 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/Analytics.ts +55 -2
- package/Utils/Monitor/MonitorMetricType.ts +40 -0
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
- package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.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 +4 -4
- package/build/dist/Models/DatabaseModels/StatusPage.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/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +25 -4
- package/build/dist/Server/API/StatusPageAPI.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/EnvironmentConfig.js +6 -0
- package/build/dist/Server/EnvironmentConfig.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/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/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.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/SlackAuthorization.js +28 -4
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
- 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/Middleware/WhatsAppAuthorization.js +32 -2
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +74 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcService.js +127 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoService.js +127 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +5 -0
- package/build/dist/Server/Services/LogAggregationService.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/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.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/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.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/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/CronTab.js +66 -0
- package/build/dist/Server/Utils/CronTab.js.map +1 -1
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +34 -37
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.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/MonitorCriteriaEvaluator.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.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 +123 -23
- 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/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/StatusPageContentSecurityPolicy.js +39 -0
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.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/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.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/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/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.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/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/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/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
- 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/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/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- 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/Analytics.js +50 -2
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
- 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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MAX_SCAN_STATUS_MESSAGE_LENGTH,
|
|
3
|
+
UNCLAIMED_PENDING_MINUTES,
|
|
4
|
+
UnclaimedScanProbeState,
|
|
5
|
+
buildUnclaimedScanDiagnosis,
|
|
6
|
+
} from "../../../Utils/NetworkDiscovery/UnclaimedScanDiagnosis";
|
|
7
|
+
import OneUptimeDate from "../../../Types/Date";
|
|
8
|
+
import { describe, expect, test } from "@jest/globals";
|
|
9
|
+
|
|
10
|
+
/*
|
|
11
|
+
* The sentence a stuck discovery scan gets to say for itself.
|
|
12
|
+
*
|
|
13
|
+
* A scan leaves "Pending" only when a probe asks for it. When no probe ever
|
|
14
|
+
* does, nothing times out and nothing fails — the row simply never moves, and
|
|
15
|
+
* before this existed the product said nothing at all about it. OneUptime
|
|
16
|
+
* issue #3287 is that silence: four scans submitted over an hour, all
|
|
17
|
+
* "Pending", an em-dash where the result goes, and no way to tell a scan
|
|
18
|
+
* queued a second ago from one no probe will ever pick up.
|
|
19
|
+
*
|
|
20
|
+
* So these tests are about the WORDS, not a state machine: whether an operator
|
|
21
|
+
* reading the row learns which of the two very different problems they have,
|
|
22
|
+
* and whether the sentence survives the varchar(500) column it is written to.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const disconnectedProbe: UnclaimedScanProbeState = {
|
|
26
|
+
probeName: "Datacentre Probe",
|
|
27
|
+
isProbeConnected: false,
|
|
28
|
+
lastAliveAt: OneUptimeDate.getSomeHoursAgo(6),
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const connectedProbe: UnclaimedScanProbeState = {
|
|
32
|
+
probeName: "Datacentre Probe",
|
|
33
|
+
isProbeConnected: true,
|
|
34
|
+
lastAliveAt: OneUptimeDate.getCurrentDate(),
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
describe("buildUnclaimedScanDiagnosis — the probe is not connected", () => {
|
|
38
|
+
test("names the probe the operator chose", () => {
|
|
39
|
+
expect(buildUnclaimedScanDiagnosis(disconnectedProbe)).toContain(
|
|
40
|
+
'Probe "Datacentre Probe"',
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("says the probe is not connected, which is the actual fault", () => {
|
|
45
|
+
expect(buildUnclaimedScanDiagnosis(disconnectedProbe)).toContain(
|
|
46
|
+
"is not connected to OneUptime",
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
* "Last seen 6 hours ago" is the difference between "my probe just
|
|
52
|
+
* restarted" and "that probe has been gone since the upgrade".
|
|
53
|
+
*/
|
|
54
|
+
test("says when the probe was last seen", () => {
|
|
55
|
+
expect(buildUnclaimedScanDiagnosis(disconnectedProbe)).toContain(
|
|
56
|
+
"It was last seen",
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("a probe that has never connected says exactly that, not 'last seen never'", () => {
|
|
61
|
+
const message: string = buildUnclaimedScanDiagnosis({
|
|
62
|
+
probeName: "Brand New Probe",
|
|
63
|
+
isProbeConnected: false,
|
|
64
|
+
lastAliveAt: null,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
expect(message).toContain("It has never connected.");
|
|
68
|
+
expect(message).not.toContain("last seen");
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test("a missing lastAlive is treated the same as never connecting", () => {
|
|
72
|
+
expect(
|
|
73
|
+
buildUnclaimedScanDiagnosis({
|
|
74
|
+
isProbeConnected: false,
|
|
75
|
+
}),
|
|
76
|
+
).toContain("It has never connected.");
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
/*
|
|
80
|
+
* The scan is annotated, not failed, so the operator needs to know they do
|
|
81
|
+
* not have to re-create it.
|
|
82
|
+
*/
|
|
83
|
+
test("promises the scan still runs once the probe returns", () => {
|
|
84
|
+
expect(buildUnclaimedScanDiagnosis(disconnectedProbe)).toContain(
|
|
85
|
+
"as soon as the probe reconnects",
|
|
86
|
+
);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("buildUnclaimedScanDiagnosis — the probe IS connected", () => {
|
|
91
|
+
/*
|
|
92
|
+
* A completely different problem with a completely different fix: the probe
|
|
93
|
+
* is running and authenticating, but its discovery job is not claiming
|
|
94
|
+
* scans — an old image, a wedged sweep, or a probe that can reach the
|
|
95
|
+
* heartbeat route but not the probe-ingest one.
|
|
96
|
+
*/
|
|
97
|
+
test("does not blame the connection", () => {
|
|
98
|
+
const message: string = buildUnclaimedScanDiagnosis(connectedProbe);
|
|
99
|
+
|
|
100
|
+
expect(message).toContain("is connected but has not picked this scan up");
|
|
101
|
+
expect(message).not.toContain("is not connected");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test("names the two things worth checking", () => {
|
|
105
|
+
const message: string = buildUnclaimedScanDiagnosis(connectedProbe);
|
|
106
|
+
|
|
107
|
+
expect(message).toContain("version that supports");
|
|
108
|
+
expect(message).toContain("probe-ingest");
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
test("quotes the threshold it actually waited for", () => {
|
|
112
|
+
expect(buildUnclaimedScanDiagnosis(connectedProbe)).toContain(
|
|
113
|
+
`${UNCLAIMED_PENDING_MINUTES} minutes`,
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("the two branches are genuinely different sentences", () => {
|
|
118
|
+
expect(buildUnclaimedScanDiagnosis(connectedProbe)).not.toBe(
|
|
119
|
+
buildUnclaimedScanDiagnosis(disconnectedProbe),
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
describe("buildUnclaimedScanDiagnosis — a probe with no readable name", () => {
|
|
125
|
+
test("falls back to a phrase that still reads as a sentence", () => {
|
|
126
|
+
const message: string = buildUnclaimedScanDiagnosis({
|
|
127
|
+
isProbeConnected: false,
|
|
128
|
+
lastAliveAt: null,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(message).toContain("The assigned probe is not connected");
|
|
132
|
+
expect(message).not.toContain('Probe ""');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("an empty-string name is treated as no name", () => {
|
|
136
|
+
expect(
|
|
137
|
+
buildUnclaimedScanDiagnosis({
|
|
138
|
+
probeName: "",
|
|
139
|
+
isProbeConnected: true,
|
|
140
|
+
}),
|
|
141
|
+
).toContain("The assigned probe");
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
describe("buildUnclaimedScanDiagnosis — it has to fit the column", () => {
|
|
146
|
+
/*
|
|
147
|
+
* statusMessage is a varchar(500) and this message is written through the
|
|
148
|
+
* full update pipeline, which does NOT clamp. An over-long value throws, and
|
|
149
|
+
* the diagnosis is lost precisely when it is most needed.
|
|
150
|
+
*/
|
|
151
|
+
test("the column ceiling is the one the model declares", () => {
|
|
152
|
+
expect(MAX_SCAN_STATUS_MESSAGE_LENGTH).toBe(500);
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test("every message fits, for both branches", () => {
|
|
156
|
+
for (const probeState of [disconnectedProbe, connectedProbe]) {
|
|
157
|
+
expect(
|
|
158
|
+
buildUnclaimedScanDiagnosis(probeState).length,
|
|
159
|
+
).toBeLessThanOrEqual(MAX_SCAN_STATUS_MESSAGE_LENGTH);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
/*
|
|
164
|
+
* A probe name is a ShortText column, so 100 characters is the real worst
|
|
165
|
+
* case. Feeding well past it proves the truncation is what bounds the
|
|
166
|
+
* message rather than the caller's good manners.
|
|
167
|
+
*/
|
|
168
|
+
test("an absurdly long probe name cannot overflow the column", () => {
|
|
169
|
+
const longName: string = "N".repeat(400);
|
|
170
|
+
|
|
171
|
+
for (const isProbeConnected of [true, false]) {
|
|
172
|
+
const message: string = buildUnclaimedScanDiagnosis({
|
|
173
|
+
probeName: longName,
|
|
174
|
+
isProbeConnected: isProbeConnected,
|
|
175
|
+
lastAliveAt: OneUptimeDate.getSomeHoursAgo(200),
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
expect(message.length).toBeLessThanOrEqual(
|
|
179
|
+
MAX_SCAN_STATUS_MESSAGE_LENGTH,
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test("a long name is cut with an ellipsis rather than silently dropped", () => {
|
|
185
|
+
const message: string = buildUnclaimedScanDiagnosis({
|
|
186
|
+
probeName: "N".repeat(400),
|
|
187
|
+
isProbeConnected: false,
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(message).toContain("NNN");
|
|
191
|
+
expect(message).toContain("…");
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("a name that fits is left exactly as the operator typed it", () => {
|
|
195
|
+
expect(
|
|
196
|
+
buildUnclaimedScanDiagnosis({
|
|
197
|
+
probeName: "core-sw-probe-01",
|
|
198
|
+
isProbeConnected: false,
|
|
199
|
+
}),
|
|
200
|
+
).toContain('Probe "core-sw-probe-01"');
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
describe("the grace period", () => {
|
|
205
|
+
/*
|
|
206
|
+
* The probe polls every minute, so this is a count of consecutive failed
|
|
207
|
+
* polls. Too short and a probe redeploy annotates every queued scan; too
|
|
208
|
+
* long and the operator has given up before the product says anything.
|
|
209
|
+
*/
|
|
210
|
+
test("is long enough to ride out a probe restart and short enough to be useful", () => {
|
|
211
|
+
expect(UNCLAIMED_PENDING_MINUTES).toBeGreaterThanOrEqual(5);
|
|
212
|
+
expect(UNCLAIMED_PENDING_MINUTES).toBeLessThanOrEqual(60);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
@@ -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
|
+
});
|
|
@@ -3,6 +3,7 @@ enum EmailTemplateType {
|
|
|
3
3
|
ForgotPassword = "ForgotPassword.hbs",
|
|
4
4
|
ProbeOffline = "ProbeOffline.hbs",
|
|
5
5
|
SignupWelcomeEmail = "SignupWelcomeEmail.hbs",
|
|
6
|
+
CompleteRegistration = "CompleteRegistration.hbs",
|
|
6
7
|
ProbeConnectionStatusChange = "ProbeConnectionStatusChange.hbs",
|
|
7
8
|
AIAgentConnectionStatusChange = "AIAgentConnectionStatusChange.hbs",
|
|
8
9
|
AIAgentOwnerAdded = "AIAgentOwnerAdded.hbs",
|
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
export enum MarketingConversionType {
|
|
2
2
|
SignUp = "SignUp",
|
|
3
|
+
// A verified Cal.com booking. See Docs/analytics/enterprise-conversion-tracking.md.
|
|
4
|
+
MeetingBooked = "MeetingBooked",
|
|
3
5
|
PaidSubscription = "PaidSubscription",
|
|
4
6
|
}
|
|
5
7
|
|
|
8
|
+
/*
|
|
9
|
+
* Conversion types that ad platforms have an explicit conversion-action
|
|
10
|
+
* mapping for. Every provider picks its platform conversion action by
|
|
11
|
+
* branching on SignUp vs not-SignUp, so a type that is not listed here would
|
|
12
|
+
* be uploaded as a purchase — add a type only once every provider has a
|
|
13
|
+
* mapping for it. Types left out stay ledger-only and are recorded as Skipped.
|
|
14
|
+
*/
|
|
15
|
+
export const AdUploadableMarketingConversionTypes: Array<MarketingConversionType> =
|
|
16
|
+
[MarketingConversionType.SignUp, MarketingConversionType.PaidSubscription];
|
|
17
|
+
|
|
6
18
|
export enum MarketingConversionUploadStatus {
|
|
7
19
|
Uploaded = "Uploaded",
|
|
8
20
|
Failed = "Failed",
|
|
@@ -224,6 +224,14 @@ export enum EvaluateOverTimeMinutes {
|
|
|
224
224
|
export interface EvaluateOverTimeOptions {
|
|
225
225
|
timeValueInMinutes: number | undefined;
|
|
226
226
|
evaluateOverTimeType: EvaluateOverTimeType | undefined;
|
|
227
|
+
/*
|
|
228
|
+
* Governs what happens when the evaluation window cannot back the filter -
|
|
229
|
+
* either nothing was recorded in it, or the monitor has not been running
|
|
230
|
+
* long enough to cover it yet. Defaults to Ignore when unset, so a filter
|
|
231
|
+
* asked to look at the last N minutes waits for N minutes of data instead
|
|
232
|
+
* of firing off the reading that happens to have just arrived.
|
|
233
|
+
*/
|
|
234
|
+
onNoDataPolicy?: NoDataPolicy | undefined;
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
export interface CriteriaFilter {
|
|
@@ -449,5 +457,6 @@ export const CriteriaFilterSchema: ZodSchema = Zod.object({
|
|
|
449
457
|
evaluateOverTimeOptions: Zod.object({
|
|
450
458
|
timeValueInMinutes: Zod.number().optional(),
|
|
451
459
|
evaluateOverTimeType: Zod.string().optional(),
|
|
460
|
+
onNoDataPolicy: Zod.string().optional(),
|
|
452
461
|
}).optional(),
|
|
453
462
|
});
|