@oneuptime/common 12.0.13 → 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/OnCallDutyPolicySchedule.ts +14 -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/Server/API/BaseAPI.ts +79 -14
- 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/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/DatabaseService.ts +101 -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/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- 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/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/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 +315 -0
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -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/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -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/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/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/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/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/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/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/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/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/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/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/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/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/Email/EmailTemplateType.ts +1 -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/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/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/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/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.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/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/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 +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.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/DatabaseService.js +74 -0
- package/build/dist/Server/Services/DatabaseService.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/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.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/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/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/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/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/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/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/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
|
@@ -644,6 +644,14 @@ export class Service extends DatabaseService<Model> {
|
|
|
644
644
|
deviceType: true,
|
|
645
645
|
isVerified: true,
|
|
646
646
|
userId: true,
|
|
647
|
+
/*
|
|
648
|
+
* Whether this handset asked to be rung through silent mode. Unselected
|
|
649
|
+
* it reads as undefined, which Boolean()s to false further down - the
|
|
650
|
+
* page still goes out, just quietly, which is the wrong outcome for the
|
|
651
|
+
* one channel a sleeping responder relies on. It is selected here so
|
|
652
|
+
* that cannot happen.
|
|
653
|
+
*/
|
|
654
|
+
isCriticalAlertEnabled: true,
|
|
647
655
|
},
|
|
648
656
|
},
|
|
649
657
|
props: {
|
|
@@ -2419,6 +2427,16 @@ export class Service extends DatabaseService<Model> {
|
|
|
2419
2427
|
notificationRuleItem.userPush?.deviceToken &&
|
|
2420
2428
|
notificationRuleItem.userPush?.isVerified
|
|
2421
2429
|
) {
|
|
2430
|
+
/*
|
|
2431
|
+
* This is the on-call paging path - the notification that exists to wake
|
|
2432
|
+
* somebody at 3am - so it is the only push in the product allowed to
|
|
2433
|
+
* override the ringer switch, and then only for a device whose owner
|
|
2434
|
+
* turned the option on. Owner subscriptions and note-posted notifications
|
|
2435
|
+
* go out through UserNotificationSettingService and never set this.
|
|
2436
|
+
*/
|
|
2437
|
+
const isCriticalAlert: boolean = Boolean(
|
|
2438
|
+
notificationRuleItem.userPush.isCriticalAlertEnabled,
|
|
2439
|
+
);
|
|
2422
2440
|
// send push notification for alert
|
|
2423
2441
|
if (
|
|
2424
2442
|
options.userNotificationEventType ===
|
|
@@ -2459,6 +2477,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
2459
2477
|
projectId: alert.projectId!.toString(),
|
|
2460
2478
|
});
|
|
2461
2479
|
|
|
2480
|
+
pushMessage.isCriticalAlert = isCriticalAlert;
|
|
2481
|
+
|
|
2462
2482
|
// send push notification.
|
|
2463
2483
|
PushNotificationService.sendPushNotification(
|
|
2464
2484
|
{
|
|
@@ -2540,6 +2560,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
2540
2560
|
projectId: incident.projectId!.toString(),
|
|
2541
2561
|
});
|
|
2542
2562
|
|
|
2563
|
+
pushMessage.isCriticalAlert = isCriticalAlert;
|
|
2564
|
+
|
|
2543
2565
|
// send push notification.
|
|
2544
2566
|
PushNotificationService.sendPushNotification(
|
|
2545
2567
|
{
|
|
@@ -2620,6 +2642,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
2620
2642
|
projectId: alertEpisode.projectId!.toString(),
|
|
2621
2643
|
});
|
|
2622
2644
|
|
|
2645
|
+
pushMessage.isCriticalAlert = isCriticalAlert;
|
|
2646
|
+
|
|
2623
2647
|
PushNotificationService.sendPushNotification(
|
|
2624
2648
|
{
|
|
2625
2649
|
devices: [
|
|
@@ -2699,6 +2723,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
2699
2723
|
projectId: incidentEpisode.projectId!.toString(),
|
|
2700
2724
|
});
|
|
2701
2725
|
|
|
2726
|
+
pushMessage.isCriticalAlert = isCriticalAlert;
|
|
2727
|
+
|
|
2702
2728
|
PushNotificationService.sendPushNotification(
|
|
2703
2729
|
{
|
|
2704
2730
|
devices: [
|
|
@@ -12,6 +12,7 @@ import PositiveNumber from "../../Types/PositiveNumber";
|
|
|
12
12
|
import PushDeviceType from "../../Types/PushNotification/PushDeviceType";
|
|
13
13
|
import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
14
14
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
15
|
+
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
15
16
|
|
|
16
17
|
export class Service extends DatabaseService<UserPush> {
|
|
17
18
|
public constructor() {
|
|
@@ -120,6 +121,94 @@ export class Service extends DatabaseService<UserPush> {
|
|
|
120
121
|
},
|
|
121
122
|
});
|
|
122
123
|
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Turn on-call critical alerts on or off for a handset.
|
|
127
|
+
*
|
|
128
|
+
* Keyed on the device TOKEN rather than a row id, because one phone owns one
|
|
129
|
+
* row per project it is registered against, and "ring me through silent
|
|
130
|
+
* mode" is a property of the phone. Toggling it per row would leave a
|
|
131
|
+
* responder loud for one project and silent for the next - a distinction
|
|
132
|
+
* nothing in the app offers to make and nobody would think to check.
|
|
133
|
+
* Deletion already works this way for the same reason (see the unregister
|
|
134
|
+
* route).
|
|
135
|
+
*
|
|
136
|
+
* Scoped to `userId` so a token cannot be used to reconfigure somebody
|
|
137
|
+
* else's device, and to the two mobile platforms because no browser can
|
|
138
|
+
* override a device's ringer: storing the preference on a web row would
|
|
139
|
+
* read back as though it did something.
|
|
140
|
+
*
|
|
141
|
+
* Returns how many rows were updated, so the caller can tell a real toggle
|
|
142
|
+
* apart from one that matched no device at all.
|
|
143
|
+
*/
|
|
144
|
+
@CaptureSpan()
|
|
145
|
+
public async setCriticalAlertEnabledForDeviceToken(data: {
|
|
146
|
+
userId: ObjectID;
|
|
147
|
+
deviceToken: string;
|
|
148
|
+
isEnabled: boolean;
|
|
149
|
+
}): Promise<number> {
|
|
150
|
+
const devices: Array<UserPush> = await this.findBy({
|
|
151
|
+
query: {
|
|
152
|
+
userId: data.userId,
|
|
153
|
+
deviceToken: data.deviceToken,
|
|
154
|
+
},
|
|
155
|
+
select: {
|
|
156
|
+
_id: true,
|
|
157
|
+
deviceType: true,
|
|
158
|
+
},
|
|
159
|
+
limit: LIMIT_PER_PROJECT,
|
|
160
|
+
skip: 0,
|
|
161
|
+
props: {
|
|
162
|
+
isRoot: true,
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
if (devices.length === 0) {
|
|
167
|
+
throw new BadDataException(
|
|
168
|
+
"No registered device was found for this device token.",
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const mobileDeviceIds: Array<string> = devices
|
|
173
|
+
.filter((device: UserPush) => {
|
|
174
|
+
return (
|
|
175
|
+
device.deviceType === PushDeviceType.iOS ||
|
|
176
|
+
device.deviceType === PushDeviceType.Android
|
|
177
|
+
);
|
|
178
|
+
})
|
|
179
|
+
.map((device: UserPush) => {
|
|
180
|
+
return device._id!.toString();
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
if (mobileDeviceIds.length === 0) {
|
|
184
|
+
throw new BadDataException(
|
|
185
|
+
"Critical alerts are only available on iOS and Android devices.",
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
let updatedCount: number = 0;
|
|
190
|
+
|
|
191
|
+
/*
|
|
192
|
+
* One update per row rather than an `_id: In([...])` query: the query
|
|
193
|
+
* builder used here takes a single value per column, and the count of
|
|
194
|
+
* projects a responder belongs to is small.
|
|
195
|
+
*/
|
|
196
|
+
for (const deviceId of mobileDeviceIds) {
|
|
197
|
+
updatedCount += await this.updateOneBy({
|
|
198
|
+
query: {
|
|
199
|
+
_id: deviceId,
|
|
200
|
+
},
|
|
201
|
+
data: {
|
|
202
|
+
isCriticalAlertEnabled: data.isEnabled,
|
|
203
|
+
},
|
|
204
|
+
props: {
|
|
205
|
+
isRoot: true,
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return updatedCount;
|
|
211
|
+
}
|
|
123
212
|
}
|
|
124
213
|
|
|
125
214
|
export default new Service();
|
|
@@ -15,7 +15,8 @@ import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
|
15
15
|
import TwilioConfig from "../../Types/CallAndSMS/TwilioConfig";
|
|
16
16
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
17
17
|
import ObjectID from "../../Types/ObjectID";
|
|
18
|
-
import
|
|
18
|
+
import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
|
|
19
|
+
import ChannelVerification from "../Utils/ChannelVerification";
|
|
19
20
|
import Project from "../../Models/DatabaseModels/Project";
|
|
20
21
|
import Model from "../../Models/DatabaseModels/UserSMS";
|
|
21
22
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
@@ -143,7 +144,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
143
144
|
createdItem: Model,
|
|
144
145
|
): Promise<Model> {
|
|
145
146
|
if (!createdItem.isVerified) {
|
|
146
|
-
|
|
147
|
+
// issue and send the first verification code
|
|
148
|
+
await this.issueAndSendVerificationCode(createdItem);
|
|
147
149
|
}
|
|
148
150
|
|
|
149
151
|
return createdItem;
|
|
@@ -158,9 +160,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
158
160
|
},
|
|
159
161
|
select: {
|
|
160
162
|
phone: true,
|
|
161
|
-
verificationCode: true,
|
|
162
163
|
isVerified: true,
|
|
163
164
|
projectId: true,
|
|
165
|
+
userId: true,
|
|
166
|
+
verificationCodeSentAt: true,
|
|
164
167
|
},
|
|
165
168
|
});
|
|
166
169
|
|
|
@@ -215,23 +218,54 @@ export class Service extends DatabaseService<Model> {
|
|
|
215
218
|
);
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
|
|
219
|
-
|
|
221
|
+
/*
|
|
222
|
+
* Resend cooldown.
|
|
223
|
+
*
|
|
224
|
+
* Without it, spending the attempt budget on a code and asking for
|
|
225
|
+
* another one is free, which turns the attempt limit into a speed bump
|
|
226
|
+
* rather than a wall — and the resend control doubles as a way to send
|
|
227
|
+
* somebody unsolicited messages as fast as the network allows, at the
|
|
228
|
+
* project's expense.
|
|
229
|
+
*/
|
|
230
|
+
const retryAfterSeconds: number =
|
|
231
|
+
ChannelVerification.getResendRetryAfterSeconds({
|
|
232
|
+
lastSentAt: item.verificationCodeSentAt,
|
|
233
|
+
});
|
|
220
234
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
235
|
+
if (retryAfterSeconds > 0) {
|
|
236
|
+
throw new TooManyRequestsException(
|
|
237
|
+
`Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
await this.issueAndSendVerificationCode(item);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* Mint a fresh code for this row, store only its digest, and send the
|
|
246
|
+
* plaintext to the channel.
|
|
247
|
+
*
|
|
248
|
+
* The plaintext exists in memory for exactly as long as it takes to hand it
|
|
249
|
+
* to the notification service and is never written anywhere. Everything
|
|
250
|
+
* about why — expiry, the attempt counter, rotation, the resend cooldown —
|
|
251
|
+
* is in Common/Server/Utils/ChannelVerification.ts.
|
|
252
|
+
*
|
|
253
|
+
* This does NOT check whether a send is allowed. Callers decide that:
|
|
254
|
+
* onCreateSuccess because a brand new row has never been sent to, and
|
|
255
|
+
* resendVerificationCode after the cooldown and the channel's own
|
|
256
|
+
* preconditions have passed.
|
|
257
|
+
*/
|
|
258
|
+
@CaptureSpan()
|
|
259
|
+
public async issueAndSendVerificationCode(item: Model): Promise<void> {
|
|
260
|
+
const plainCode: string = await ChannelVerification.issueCodeOnItem({
|
|
261
|
+
service: this,
|
|
262
|
+
itemId: item.id!,
|
|
229
263
|
});
|
|
230
264
|
|
|
231
|
-
this.sendVerificationCode(item);
|
|
265
|
+
this.sendVerificationCode(item, plainCode);
|
|
232
266
|
}
|
|
233
267
|
|
|
234
|
-
public sendVerificationCode(item: Model): void {
|
|
268
|
+
public sendVerificationCode(item: Model, code: string): void {
|
|
235
269
|
(async () => {
|
|
236
270
|
const projectTwilioConfig: TwilioConfig | undefined =
|
|
237
271
|
await ProjectCallSMSConfigService.getProjectDefaultTwilioConfig(
|
|
@@ -242,8 +276,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
242
276
|
{
|
|
243
277
|
to: item.phone!,
|
|
244
278
|
message:
|
|
245
|
-
"This message is from OneUptime. Your verification code is " +
|
|
246
|
-
item.verificationCode,
|
|
279
|
+
"This message is from OneUptime. Your verification code is " + code,
|
|
247
280
|
},
|
|
248
281
|
{
|
|
249
282
|
projectId: item.projectId,
|
|
@@ -13,7 +13,8 @@ import WhatsAppService from "./WhatsAppService";
|
|
|
13
13
|
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
14
14
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
15
15
|
import ObjectID from "../../Types/ObjectID";
|
|
16
|
-
import
|
|
16
|
+
import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
|
|
17
|
+
import ChannelVerification from "../Utils/ChannelVerification";
|
|
17
18
|
import Project from "../../Models/DatabaseModels/Project";
|
|
18
19
|
import Model from "../../Models/DatabaseModels/UserWhatsApp";
|
|
19
20
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
@@ -139,7 +140,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
139
140
|
createdItem: Model,
|
|
140
141
|
): Promise<Model> {
|
|
141
142
|
if (!createdItem.isVerified) {
|
|
142
|
-
this.
|
|
143
|
+
this.issueAndSendVerificationCode(createdItem).catch((error: Error) => {
|
|
143
144
|
logger.error(error, {
|
|
144
145
|
projectId: createdItem.projectId?.toString(),
|
|
145
146
|
userId: createdItem.userId?.toString(),
|
|
@@ -159,10 +160,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
159
160
|
},
|
|
160
161
|
select: {
|
|
161
162
|
phone: true,
|
|
162
|
-
verificationCode: true,
|
|
163
163
|
isVerified: true,
|
|
164
164
|
projectId: true,
|
|
165
165
|
userId: true,
|
|
166
|
+
verificationCodeSentAt: true,
|
|
166
167
|
},
|
|
167
168
|
});
|
|
168
169
|
|
|
@@ -176,22 +177,54 @@ export class Service extends DatabaseService<Model> {
|
|
|
176
177
|
throw new BadDataException("WhatsApp number already verified");
|
|
177
178
|
}
|
|
178
179
|
|
|
179
|
-
|
|
180
|
+
/*
|
|
181
|
+
* Resend cooldown.
|
|
182
|
+
*
|
|
183
|
+
* Without it, spending the attempt budget on a code and asking for
|
|
184
|
+
* another one is free, which turns the attempt limit into a speed bump
|
|
185
|
+
* rather than a wall — and the resend control doubles as a way to send
|
|
186
|
+
* somebody unsolicited messages as fast as the network allows, at the
|
|
187
|
+
* project's expense.
|
|
188
|
+
*/
|
|
189
|
+
const retryAfterSeconds: number =
|
|
190
|
+
ChannelVerification.getResendRetryAfterSeconds({
|
|
191
|
+
lastSentAt: item.verificationCodeSentAt,
|
|
192
|
+
});
|
|
180
193
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
if (retryAfterSeconds > 0) {
|
|
195
|
+
throw new TooManyRequestsException(
|
|
196
|
+
`Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
await this.issueAndSendVerificationCode(item);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/*
|
|
204
|
+
* Mint a fresh code for this row, store only its digest, and send the
|
|
205
|
+
* plaintext to the channel.
|
|
206
|
+
*
|
|
207
|
+
* The plaintext exists in memory for exactly as long as it takes to hand it
|
|
208
|
+
* to the notification service and is never written anywhere. Everything
|
|
209
|
+
* about why — expiry, the attempt counter, rotation, the resend cooldown —
|
|
210
|
+
* is in Common/Server/Utils/ChannelVerification.ts.
|
|
211
|
+
*
|
|
212
|
+
* This does NOT check whether a send is allowed. Callers decide that:
|
|
213
|
+
* onCreateSuccess because a brand new row has never been sent to, and
|
|
214
|
+
* resendVerificationCode after the cooldown and the channel's own
|
|
215
|
+
* preconditions have passed.
|
|
216
|
+
*/
|
|
217
|
+
@CaptureSpan()
|
|
218
|
+
public async issueAndSendVerificationCode(item: Model): Promise<void> {
|
|
219
|
+
const plainCode: string = await ChannelVerification.issueCodeOnItem({
|
|
220
|
+
service: this,
|
|
221
|
+
itemId: item.id!,
|
|
189
222
|
});
|
|
190
223
|
|
|
191
|
-
await this.sendVerificationCode(item);
|
|
224
|
+
await this.sendVerificationCode(item, plainCode);
|
|
192
225
|
}
|
|
193
226
|
|
|
194
|
-
public async sendVerificationCode(item: Model): Promise<void> {
|
|
227
|
+
public async sendVerificationCode(item: Model, code: string): Promise<void> {
|
|
195
228
|
if (!item.projectId || !item.userId || !item.phone) {
|
|
196
229
|
logger.warn("Cannot send WhatsApp verification code. Missing data.", {
|
|
197
230
|
projectId: item.projectId?.toString(),
|
|
@@ -205,7 +238,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
205
238
|
const templateKey: WhatsAppTemplateId =
|
|
206
239
|
WhatsAppTemplateIds.VerificationCode;
|
|
207
240
|
const templateVariables: Record<string, string> = {
|
|
208
|
-
"1":
|
|
241
|
+
"1": code,
|
|
209
242
|
};
|
|
210
243
|
|
|
211
244
|
const whatsAppMessage: WhatsAppMessage = {
|
|
@@ -51,6 +51,36 @@ export default class QueryHelper {
|
|
|
51
51
|
);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/*
|
|
55
|
+
* Case-insensitive `IN (...)` — the multi-value twin of
|
|
56
|
+
* findWithSameText. Used where a user-typed identifier has to match an
|
|
57
|
+
* ingest-stamped name that may differ only by case (monitor step
|
|
58
|
+
* configs vs. the resource rows discovered from telemetry), and where
|
|
59
|
+
* issuing one findOneBy per identifier would cost a round-trip each.
|
|
60
|
+
*
|
|
61
|
+
* An empty list would compile to `IN ()`, which is a syntax error, so
|
|
62
|
+
* callers must not pass one; they have nothing to look up anyway.
|
|
63
|
+
*/
|
|
64
|
+
@CaptureSpan()
|
|
65
|
+
public static findWithSameTextAnyOf(
|
|
66
|
+
texts: Array<string>,
|
|
67
|
+
): FindWhereProperty<any> {
|
|
68
|
+
const rid: string = Text.generateRandomText(10);
|
|
69
|
+
|
|
70
|
+
const normalizedTexts: Array<string> = texts.map((text: string): string => {
|
|
71
|
+
return text.toLowerCase().trim();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return Raw(
|
|
75
|
+
(alias: string) => {
|
|
76
|
+
return `(LOWER(${alias}) IN (:...${rid}))`;
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
[rid]: normalizedTexts,
|
|
80
|
+
},
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
54
84
|
@CaptureSpan()
|
|
55
85
|
public static isNull(): any {
|
|
56
86
|
return Raw((alias: string) => {
|
|
@@ -25,6 +25,46 @@ export const DEFAULT_MAX_BYTES_BEFORE_EXTERNAL_GROUP_BY_IN_BYTES: number = 16106
|
|
|
25
25
|
// 1.5 GiB.
|
|
26
26
|
export const DEFAULT_MAX_BYTES_BEFORE_EXTERNAL_SORT_IN_BYTES: number = 1610612736;
|
|
27
27
|
|
|
28
|
+
/*
|
|
29
|
+
* Scan-side memory bound for wide-window aggregations.
|
|
30
|
+
*
|
|
31
|
+
* A GROUP BY over a log window has to visit every matching row, so unlike a
|
|
32
|
+
* paginated list it cannot be made to read less. What it CAN be stopped from
|
|
33
|
+
* doing is holding a huge amount of that data in flight at once: peak memory
|
|
34
|
+
* is roughly (threads x block rows x bytes per row), and a row carrying the
|
|
35
|
+
* fat `attributes` Map(String, String) is expensive. Reading the default
|
|
36
|
+
* 65536 rows per block per thread is what pushes a filtered facet or a
|
|
37
|
+
* projection-fallback histogram past max_memory_usage and into Code 241.
|
|
38
|
+
*
|
|
39
|
+
* These are execution-strategy settings only — ClickHouse returns the same
|
|
40
|
+
* rows either way (asserted in QuerySettingsHelper.test.ts and verified
|
|
41
|
+
* against a real server).
|
|
42
|
+
*
|
|
43
|
+
* Measured on ClickHouse 26.7, 3M rows shaped like LogItemV3, one facet
|
|
44
|
+
* query filtered on an attribute:
|
|
45
|
+
*
|
|
46
|
+
* default 695 MiB peak
|
|
47
|
+
* max_block_size alone 88 MiB peak (and faster)
|
|
48
|
+
* + preferred_block_size_bytes, threads 40 MiB peak
|
|
49
|
+
*
|
|
50
|
+
* NOTE: this bounds SCAN memory, not aggregation state. A facet on a
|
|
51
|
+
* genuinely high-cardinality attribute builds a large hash table regardless;
|
|
52
|
+
* that case is covered by max_bytes_before_external_group_by spilling to
|
|
53
|
+
* disk, which is already applied to every read here.
|
|
54
|
+
*/
|
|
55
|
+
export const AGGREGATION_SCAN_MAX_BLOCK_SIZE: number = 8192;
|
|
56
|
+
|
|
57
|
+
// 1 MiB — caps a block by bytes when rows are unusually wide.
|
|
58
|
+
export const AGGREGATION_SCAN_PREFERRED_BLOCK_SIZE_IN_BYTES: number = 1048576;
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* The Logs sidebar fans out one aggregation per facet key concurrently, so
|
|
62
|
+
* per-query thread caps also bound how much of the server a single page load
|
|
63
|
+
* can claim. Latency is barely affected — these queries are already bounded
|
|
64
|
+
* by max_execution_time with 'break'.
|
|
65
|
+
*/
|
|
66
|
+
export const AGGREGATION_SCAN_MAX_THREADS: number = 4;
|
|
67
|
+
|
|
28
68
|
export interface QuerySettingsOptions {
|
|
29
69
|
/**
|
|
30
70
|
* Wall-clock cap in seconds (max_execution_time). Omitted from the
|
|
@@ -40,6 +80,13 @@ export interface QuerySettingsOptions {
|
|
|
40
80
|
maxMemoryUsageInBytes?: number | undefined;
|
|
41
81
|
maxBytesBeforeExternalGroupByInBytes?: number | undefined;
|
|
42
82
|
maxBytesBeforeExternalSortInBytes?: number | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Bounds how much data a scan holds in flight, for aggregations that must
|
|
85
|
+
* visit every row in a wide window. Emits max_block_size,
|
|
86
|
+
* preferred_block_size_bytes and max_threads. Execution strategy only —
|
|
87
|
+
* the result set is unchanged. See AGGREGATION_SCAN_MAX_BLOCK_SIZE.
|
|
88
|
+
*/
|
|
89
|
+
boundScanMemory?: boolean | undefined;
|
|
43
90
|
/**
|
|
44
91
|
* Site-specific passthrough settings (e.g. optimize_use_projections,
|
|
45
92
|
* optimize_aggregation_in_order, max_threads). Keys and values are
|
|
@@ -77,6 +124,18 @@ export function getQuerySettings(options?: QuerySettingsOptions): string {
|
|
|
77
124
|
}`,
|
|
78
125
|
);
|
|
79
126
|
|
|
127
|
+
/*
|
|
128
|
+
* Emitted before additionalSettings so a call site can still override any
|
|
129
|
+
* one of these explicitly if it has a reason to.
|
|
130
|
+
*/
|
|
131
|
+
if (options?.boundScanMemory) {
|
|
132
|
+
parts.push(`max_block_size = ${AGGREGATION_SCAN_MAX_BLOCK_SIZE}`);
|
|
133
|
+
parts.push(
|
|
134
|
+
`preferred_block_size_bytes = ${AGGREGATION_SCAN_PREFERRED_BLOCK_SIZE_IN_BYTES}`,
|
|
135
|
+
);
|
|
136
|
+
parts.push(`max_threads = ${AGGREGATION_SCAN_MAX_THREADS}`);
|
|
137
|
+
}
|
|
138
|
+
|
|
80
139
|
if (options?.additionalSettings) {
|
|
81
140
|
for (const [key, value] of Object.entries(options.additionalSettings)) {
|
|
82
141
|
parts.push(
|