@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
package/Server/API/BaseAPI.ts
CHANGED
|
@@ -298,20 +298,85 @@ export default class BaseAPI<
|
|
|
298
298
|
const databaseProps: DatabaseCommonInteractionProps =
|
|
299
299
|
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
300
300
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
301
|
+
/*
|
|
302
|
+
* findBy and countBy are independent reads, so run them in parallel to
|
|
303
|
+
* cut list latency where the count is costly. The one thing that makes
|
|
304
|
+
* the sequential order load-bearing is a service-level onBeforeFind
|
|
305
|
+
* override that mutates the shared query/props objects in place (e.g.
|
|
306
|
+
* ProjectService elevates props.isRoot and pins query._id for users with
|
|
307
|
+
* no projects; the incident/alert privacy filters rewrite query keys):
|
|
308
|
+
* countBy historically ran after findBy and inherited those mutations.
|
|
309
|
+
* Services on the stock hook cannot mutate anything (and the permission
|
|
310
|
+
* pipeline copies the query before touching it, ReadPermission.ts:33),
|
|
311
|
+
* so only they run in parallel; hook-overriding services keep the
|
|
312
|
+
* sequential order and its exact semantics.
|
|
313
|
+
*/
|
|
314
|
+
const usesStockOnBeforeFindHook: boolean =
|
|
315
|
+
(this.service as unknown as { onBeforeFind: unknown }).onBeforeFind ===
|
|
316
|
+
(DatabaseService.prototype as unknown as { onBeforeFind: unknown })
|
|
317
|
+
.onBeforeFind;
|
|
318
|
+
|
|
319
|
+
let list: Array<BaseModel>;
|
|
320
|
+
let count: PositiveNumber;
|
|
321
|
+
|
|
322
|
+
if (usesStockOnBeforeFindHook) {
|
|
323
|
+
const listPromise: Promise<Array<BaseModel>> = this.service.findBy({
|
|
324
|
+
query,
|
|
325
|
+
select,
|
|
326
|
+
skip: skip,
|
|
327
|
+
limit: limit,
|
|
328
|
+
groupBy: groupBy,
|
|
329
|
+
sort: sort,
|
|
330
|
+
props: databaseProps,
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
/*
|
|
334
|
+
* Shallow copies so a countBy override that rewrites top-level query
|
|
335
|
+
* keys (the established privacy-filter pattern) can never race the
|
|
336
|
+
* concurrent findBy's reads of the shared objects.
|
|
337
|
+
*/
|
|
338
|
+
const countPromise: Promise<PositiveNumber> = this.service.countBy({
|
|
339
|
+
query: { ...query },
|
|
340
|
+
props: { ...databaseProps },
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
/*
|
|
344
|
+
* allSettled instead of Promise.all: a findBy rejection must not leave
|
|
345
|
+
* countPromise as an unhandled rejection, and findBy's error keeps
|
|
346
|
+
* priority when both fail - the same failure the sequential code
|
|
347
|
+
* surfaced.
|
|
348
|
+
*/
|
|
349
|
+
const [listResult, countResult]: [
|
|
350
|
+
PromiseSettledResult<Array<BaseModel>>,
|
|
351
|
+
PromiseSettledResult<PositiveNumber>,
|
|
352
|
+
] = await Promise.allSettled([listPromise, countPromise]);
|
|
353
|
+
|
|
354
|
+
if (listResult.status === "rejected") {
|
|
355
|
+
throw listResult.reason;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
if (countResult.status === "rejected") {
|
|
359
|
+
throw countResult.reason;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
list = listResult.value;
|
|
363
|
+
count = countResult.value;
|
|
364
|
+
} else {
|
|
365
|
+
list = await this.service.findBy({
|
|
366
|
+
query,
|
|
367
|
+
select,
|
|
368
|
+
skip: skip,
|
|
369
|
+
limit: limit,
|
|
370
|
+
groupBy: groupBy,
|
|
371
|
+
sort: sort,
|
|
372
|
+
props: databaseProps,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
count = await this.service.countBy({
|
|
376
|
+
query,
|
|
377
|
+
props: databaseProps,
|
|
378
|
+
});
|
|
379
|
+
}
|
|
315
380
|
|
|
316
381
|
return Response.sendEntityArrayResponse(
|
|
317
382
|
req,
|
|
@@ -1,22 +1,44 @@
|
|
|
1
1
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import VerificationCodeRateLimit, {
|
|
3
|
+
VerificationCodeRateLimitBucket,
|
|
4
|
+
} from "../Middleware/VerificationCodeRateLimit";
|
|
2
5
|
import UserCallService, {
|
|
3
6
|
Service as UserCallServiceType,
|
|
4
7
|
} from "../Services/UserCallService";
|
|
5
|
-
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
6
8
|
import {
|
|
7
9
|
ExpressRequest,
|
|
8
10
|
ExpressResponse,
|
|
9
11
|
NextFunction,
|
|
10
12
|
OneUptimeRequest,
|
|
11
13
|
} from "../Utils/Express";
|
|
14
|
+
import ChannelVerification, {
|
|
15
|
+
ChannelVerificationOutcome,
|
|
16
|
+
ChannelVerificationResult,
|
|
17
|
+
} from "../Utils/ChannelVerification";
|
|
12
18
|
import Response from "../Utils/Response";
|
|
13
|
-
import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
|
|
14
19
|
import BaseAPI from "./BaseAPI";
|
|
15
20
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
21
|
import ObjectID from "../../Types/ObjectID";
|
|
17
22
|
import UserCall from "../../Models/DatabaseModels/UserCall";
|
|
18
|
-
import
|
|
23
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
24
|
+
import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
|
|
19
25
|
|
|
26
|
+
/*
|
|
27
|
+
* The verify and resend routes for this notification channel.
|
|
28
|
+
*
|
|
29
|
+
* Neither the checking of a submitted code nor the issuing of a new one lives
|
|
30
|
+
* here, on purpose. The state machine is shared by all five channels
|
|
31
|
+
* (Common/Server/Utils/ChannelVerification.ts) so that a control added for one
|
|
32
|
+
* of them cannot quietly go missing on another — which is exactly what went
|
|
33
|
+
* wrong before: five hand-written copies of "compare the column, set
|
|
34
|
+
* isVerified", none of which expired the code, counted attempts, or refused a
|
|
35
|
+
* caller running the comparison a million times against somebody else's phone
|
|
36
|
+
* number.
|
|
37
|
+
*
|
|
38
|
+
* What is left here is the HTTP shape: reject malformed bodies, run the rate
|
|
39
|
+
* limiter before anything costs a database read, and turn the outcome into a
|
|
40
|
+
* response.
|
|
41
|
+
*/
|
|
20
42
|
export default class UserCallAPI extends BaseAPI<
|
|
21
43
|
UserCall,
|
|
22
44
|
UserCallServiceType
|
|
@@ -27,6 +49,9 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
27
49
|
this.router.post(
|
|
28
50
|
`/user-call/verify`,
|
|
29
51
|
UserMiddleware.getUserMiddleware,
|
|
52
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
53
|
+
VerificationCodeRateLimitBucket.Verify,
|
|
54
|
+
),
|
|
30
55
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
31
56
|
try {
|
|
32
57
|
req = req as OneUptimeRequest;
|
|
@@ -47,33 +72,10 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
47
72
|
);
|
|
48
73
|
}
|
|
49
74
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
id: req.body["itemId"],
|
|
53
|
-
props: {
|
|
54
|
-
isRoot: true,
|
|
55
|
-
},
|
|
56
|
-
select: {
|
|
57
|
-
userId: true,
|
|
58
|
-
projectId: true,
|
|
59
|
-
verificationCode: true,
|
|
60
|
-
},
|
|
61
|
-
});
|
|
75
|
+
const userId: ObjectID | undefined = (req as OneUptimeRequest)
|
|
76
|
+
?.userAuthorization?.userId;
|
|
62
77
|
|
|
63
|
-
if (!
|
|
64
|
-
return Response.sendErrorResponse(
|
|
65
|
-
req,
|
|
66
|
-
res,
|
|
67
|
-
new BadDataException("Item not found"),
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
//check user id
|
|
72
|
-
|
|
73
|
-
if (
|
|
74
|
-
item.userId?.toString() !==
|
|
75
|
-
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
76
|
-
) {
|
|
78
|
+
if (!userId) {
|
|
77
79
|
return Response.sendErrorResponse(
|
|
78
80
|
req,
|
|
79
81
|
res,
|
|
@@ -81,32 +83,30 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
81
83
|
);
|
|
82
84
|
}
|
|
83
85
|
|
|
84
|
-
|
|
86
|
+
const result: ChannelVerificationResult =
|
|
87
|
+
await ChannelVerification.verifyCode({
|
|
88
|
+
service: this.service,
|
|
89
|
+
itemId: new ObjectID(req.body["itemId"].toString()),
|
|
90
|
+
userId: userId,
|
|
91
|
+
code: req.body["code"].toString(),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (result.outcome !== ChannelVerificationOutcome.Verified) {
|
|
85
95
|
return Response.sendErrorResponse(
|
|
86
96
|
req,
|
|
87
97
|
res,
|
|
88
|
-
|
|
98
|
+
ChannelVerification.getFailureException(result.outcome),
|
|
89
99
|
);
|
|
90
100
|
}
|
|
91
101
|
|
|
92
|
-
|
|
93
|
-
id: item.id!,
|
|
94
|
-
props: {
|
|
95
|
-
isRoot: true,
|
|
96
|
-
},
|
|
97
|
-
data: {
|
|
98
|
-
isVerified: true,
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Create default notification rules for this verified call number
|
|
102
|
+
/* Create default notification rules for this verified call number */
|
|
103
103
|
try {
|
|
104
104
|
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
105
105
|
{
|
|
106
|
-
projectId: new ObjectID(
|
|
107
|
-
userId: new ObjectID(
|
|
106
|
+
projectId: new ObjectID(result.projectId!.toString()),
|
|
107
|
+
userId: new ObjectID(result.userId!.toString()),
|
|
108
108
|
notificationMethod: {
|
|
109
|
-
userCallId:
|
|
109
|
+
userCallId: result.itemId!,
|
|
110
110
|
},
|
|
111
111
|
},
|
|
112
112
|
);
|
|
@@ -127,6 +127,9 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
127
127
|
this.router.post(
|
|
128
128
|
`/user-call/resend-verification-code`,
|
|
129
129
|
UserMiddleware.getUserMiddleware,
|
|
130
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
131
|
+
VerificationCodeRateLimitBucket.Resend,
|
|
132
|
+
),
|
|
130
133
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
131
134
|
try {
|
|
132
135
|
req = req as OneUptimeRequest;
|
|
@@ -157,6 +160,11 @@ export default class UserCallAPI extends BaseAPI<
|
|
|
157
160
|
);
|
|
158
161
|
}
|
|
159
162
|
|
|
163
|
+
/*
|
|
164
|
+
* A caller may only ask for a code to be sent to a row they own.
|
|
165
|
+
* Without this the resend route is a way to make somebody else's
|
|
166
|
+
* device ring on demand.
|
|
167
|
+
*/
|
|
160
168
|
if (
|
|
161
169
|
item.userId?.toString() !==
|
|
162
170
|
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import VerificationCodeRateLimit, {
|
|
3
|
+
VerificationCodeRateLimitBucket,
|
|
4
|
+
} from "../Middleware/VerificationCodeRateLimit";
|
|
2
5
|
import UserEmailService, {
|
|
3
6
|
Service as UserEmailServiceType,
|
|
4
7
|
} from "../Services/UserEmailService";
|
|
5
|
-
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
6
8
|
import {
|
|
7
9
|
ExpressRequest,
|
|
8
10
|
ExpressResponse,
|
|
9
11
|
NextFunction,
|
|
10
12
|
OneUptimeRequest,
|
|
11
13
|
} from "../Utils/Express";
|
|
14
|
+
import ChannelVerification, {
|
|
15
|
+
ChannelVerificationOutcome,
|
|
16
|
+
ChannelVerificationResult,
|
|
17
|
+
} from "../Utils/ChannelVerification";
|
|
12
18
|
import Response from "../Utils/Response";
|
|
13
|
-
import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
|
|
14
19
|
import BaseAPI from "./BaseAPI";
|
|
15
20
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
21
|
import ObjectID from "../../Types/ObjectID";
|
|
17
22
|
import UserEmail from "../../Models/DatabaseModels/UserEmail";
|
|
23
|
+
import UserNotificationRuleService from "../Services/UserNotificationRuleService";
|
|
24
|
+
import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
|
|
18
25
|
|
|
26
|
+
/*
|
|
27
|
+
* The verify and resend routes for this notification channel.
|
|
28
|
+
*
|
|
29
|
+
* Neither the checking of a submitted code nor the issuing of a new one lives
|
|
30
|
+
* here, on purpose. The state machine is shared by all five channels
|
|
31
|
+
* (Common/Server/Utils/ChannelVerification.ts) so that a control added for one
|
|
32
|
+
* of them cannot quietly go missing on another — which is exactly what went
|
|
33
|
+
* wrong before: five hand-written copies of "compare the column, set
|
|
34
|
+
* isVerified", none of which expired the code, counted attempts, or refused a
|
|
35
|
+
* caller running the comparison a million times against somebody else's phone
|
|
36
|
+
* number.
|
|
37
|
+
*
|
|
38
|
+
* What is left here is the HTTP shape: reject malformed bodies, run the rate
|
|
39
|
+
* limiter before anything costs a database read, and turn the outcome into a
|
|
40
|
+
* response.
|
|
41
|
+
*/
|
|
19
42
|
export default class UserEmailAPI extends BaseAPI<
|
|
20
43
|
UserEmail,
|
|
21
44
|
UserEmailServiceType
|
|
@@ -26,6 +49,9 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
26
49
|
this.router.post(
|
|
27
50
|
`${new this.entityType().getCrudApiPath()?.toString()}/verify`,
|
|
28
51
|
UserMiddleware.getUserMiddleware,
|
|
52
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
53
|
+
VerificationCodeRateLimitBucket.Verify,
|
|
54
|
+
),
|
|
29
55
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
30
56
|
try {
|
|
31
57
|
req = req as OneUptimeRequest;
|
|
@@ -46,33 +72,10 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
46
72
|
);
|
|
47
73
|
}
|
|
48
74
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
id: req.body["itemId"],
|
|
52
|
-
props: {
|
|
53
|
-
isRoot: true,
|
|
54
|
-
},
|
|
55
|
-
select: {
|
|
56
|
-
userId: true,
|
|
57
|
-
projectId: true,
|
|
58
|
-
verificationCode: true,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
if (!item) {
|
|
63
|
-
return Response.sendErrorResponse(
|
|
64
|
-
req,
|
|
65
|
-
res,
|
|
66
|
-
new BadDataException("Item not found"),
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
//check user id
|
|
75
|
+
const userId: ObjectID | undefined = (req as OneUptimeRequest)
|
|
76
|
+
?.userAuthorization?.userId;
|
|
71
77
|
|
|
72
|
-
if (
|
|
73
|
-
item.userId?.toString() !==
|
|
74
|
-
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
75
|
-
) {
|
|
78
|
+
if (!userId) {
|
|
76
79
|
return Response.sendErrorResponse(
|
|
77
80
|
req,
|
|
78
81
|
res,
|
|
@@ -80,32 +83,30 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
80
83
|
);
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
const result: ChannelVerificationResult =
|
|
87
|
+
await ChannelVerification.verifyCode({
|
|
88
|
+
service: this.service,
|
|
89
|
+
itemId: new ObjectID(req.body["itemId"].toString()),
|
|
90
|
+
userId: userId,
|
|
91
|
+
code: req.body["code"].toString(),
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
if (result.outcome !== ChannelVerificationOutcome.Verified) {
|
|
84
95
|
return Response.sendErrorResponse(
|
|
85
96
|
req,
|
|
86
97
|
res,
|
|
87
|
-
|
|
98
|
+
ChannelVerification.getFailureException(result.outcome),
|
|
88
99
|
);
|
|
89
100
|
}
|
|
90
101
|
|
|
91
|
-
|
|
92
|
-
id: item.id!,
|
|
93
|
-
props: {
|
|
94
|
-
isRoot: true,
|
|
95
|
-
},
|
|
96
|
-
data: {
|
|
97
|
-
isVerified: true,
|
|
98
|
-
},
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
// Create default notification rules for this verified email
|
|
102
|
+
/* Create default notification rules for this verified email */
|
|
102
103
|
try {
|
|
103
104
|
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
104
105
|
{
|
|
105
|
-
projectId: new ObjectID(
|
|
106
|
-
userId: new ObjectID(
|
|
106
|
+
projectId: new ObjectID(result.projectId!.toString()),
|
|
107
|
+
userId: new ObjectID(result.userId!.toString()),
|
|
107
108
|
notificationMethod: {
|
|
108
|
-
userEmailId:
|
|
109
|
+
userEmailId: result.itemId!,
|
|
109
110
|
},
|
|
110
111
|
},
|
|
111
112
|
);
|
|
@@ -128,6 +129,9 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
128
129
|
.getCrudApiPath()
|
|
129
130
|
?.toString()}/resend-verification-code`,
|
|
130
131
|
UserMiddleware.getUserMiddleware,
|
|
132
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
133
|
+
VerificationCodeRateLimitBucket.Resend,
|
|
134
|
+
),
|
|
131
135
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
132
136
|
try {
|
|
133
137
|
req = req as OneUptimeRequest;
|
|
@@ -158,6 +162,11 @@ export default class UserEmailAPI extends BaseAPI<
|
|
|
158
162
|
);
|
|
159
163
|
}
|
|
160
164
|
|
|
165
|
+
/*
|
|
166
|
+
* A caller may only ask for a code to be sent to a row they own.
|
|
167
|
+
* Without this the resend route is a way to make somebody else's
|
|
168
|
+
* device ring on demand.
|
|
169
|
+
*/
|
|
161
170
|
if (
|
|
162
171
|
item.userId?.toString() !==
|
|
163
172
|
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import VerificationCodeRateLimit, {
|
|
3
|
+
VerificationCodeRateLimitBucket,
|
|
4
|
+
} from "../Middleware/VerificationCodeRateLimit";
|
|
2
5
|
import UserIncomingCallNumberService, {
|
|
3
6
|
Service as UserIncomingCallNumberServiceType,
|
|
4
7
|
} from "../Services/UserIncomingCallNumberService";
|
|
@@ -8,11 +11,32 @@ import {
|
|
|
8
11
|
NextFunction,
|
|
9
12
|
OneUptimeRequest,
|
|
10
13
|
} from "../Utils/Express";
|
|
14
|
+
import ChannelVerification, {
|
|
15
|
+
ChannelVerificationOutcome,
|
|
16
|
+
ChannelVerificationResult,
|
|
17
|
+
} from "../Utils/ChannelVerification";
|
|
11
18
|
import Response from "../Utils/Response";
|
|
12
19
|
import BaseAPI from "./BaseAPI";
|
|
13
20
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
21
|
+
import ObjectID from "../../Types/ObjectID";
|
|
14
22
|
import UserIncomingCallNumber from "../../Models/DatabaseModels/UserIncomingCallNumber";
|
|
15
23
|
|
|
24
|
+
/*
|
|
25
|
+
* The verify and resend routes for this notification channel.
|
|
26
|
+
*
|
|
27
|
+
* Neither the checking of a submitted code nor the issuing of a new one lives
|
|
28
|
+
* here, on purpose. The state machine is shared by all five channels
|
|
29
|
+
* (Common/Server/Utils/ChannelVerification.ts) so that a control added for one
|
|
30
|
+
* of them cannot quietly go missing on another — which is exactly what went
|
|
31
|
+
* wrong before: five hand-written copies of "compare the column, set
|
|
32
|
+
* isVerified", none of which expired the code, counted attempts, or refused a
|
|
33
|
+
* caller running the comparison a million times against somebody else's phone
|
|
34
|
+
* number.
|
|
35
|
+
*
|
|
36
|
+
* What is left here is the HTTP shape: reject malformed bodies, run the rate
|
|
37
|
+
* limiter before anything costs a database read, and turn the outcome into a
|
|
38
|
+
* response.
|
|
39
|
+
*/
|
|
16
40
|
export default class UserIncomingCallNumberAPI extends BaseAPI<
|
|
17
41
|
UserIncomingCallNumber,
|
|
18
42
|
UserIncomingCallNumberServiceType
|
|
@@ -23,6 +47,9 @@ export default class UserIncomingCallNumberAPI extends BaseAPI<
|
|
|
23
47
|
this.router.post(
|
|
24
48
|
`/user-incoming-call-number/verify`,
|
|
25
49
|
UserMiddleware.getUserMiddleware,
|
|
50
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
51
|
+
VerificationCodeRateLimitBucket.Verify,
|
|
52
|
+
),
|
|
26
53
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
27
54
|
try {
|
|
28
55
|
req = req as OneUptimeRequest;
|
|
@@ -43,32 +70,10 @@ export default class UserIncomingCallNumberAPI extends BaseAPI<
|
|
|
43
70
|
);
|
|
44
71
|
}
|
|
45
72
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
await this.service.findOneById({
|
|
49
|
-
id: req.body["itemId"],
|
|
50
|
-
props: {
|
|
51
|
-
isRoot: true,
|
|
52
|
-
},
|
|
53
|
-
select: {
|
|
54
|
-
userId: true,
|
|
55
|
-
verificationCode: true,
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
if (!item) {
|
|
60
|
-
return Response.sendErrorResponse(
|
|
61
|
-
req,
|
|
62
|
-
res,
|
|
63
|
-
new BadDataException("Item not found"),
|
|
64
|
-
);
|
|
65
|
-
}
|
|
73
|
+
const userId: ObjectID | undefined = (req as OneUptimeRequest)
|
|
74
|
+
?.userAuthorization?.userId;
|
|
66
75
|
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
item.userId?.toString() !==
|
|
70
|
-
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
71
|
-
) {
|
|
76
|
+
if (!userId) {
|
|
72
77
|
return Response.sendErrorResponse(
|
|
73
78
|
req,
|
|
74
79
|
res,
|
|
@@ -76,24 +81,22 @@ export default class UserIncomingCallNumberAPI extends BaseAPI<
|
|
|
76
81
|
);
|
|
77
82
|
}
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
const result: ChannelVerificationResult =
|
|
85
|
+
await ChannelVerification.verifyCode({
|
|
86
|
+
service: this.service,
|
|
87
|
+
itemId: new ObjectID(req.body["itemId"].toString()),
|
|
88
|
+
userId: userId,
|
|
89
|
+
code: req.body["code"].toString(),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (result.outcome !== ChannelVerificationOutcome.Verified) {
|
|
80
93
|
return Response.sendErrorResponse(
|
|
81
94
|
req,
|
|
82
95
|
res,
|
|
83
|
-
|
|
96
|
+
ChannelVerification.getFailureException(result.outcome),
|
|
84
97
|
);
|
|
85
98
|
}
|
|
86
99
|
|
|
87
|
-
await this.service.updateOneById({
|
|
88
|
-
id: item.id!,
|
|
89
|
-
props: {
|
|
90
|
-
isRoot: true,
|
|
91
|
-
},
|
|
92
|
-
data: {
|
|
93
|
-
isVerified: true,
|
|
94
|
-
},
|
|
95
|
-
});
|
|
96
|
-
|
|
97
100
|
return Response.sendEmptySuccessResponse(req, res);
|
|
98
101
|
} catch (err) {
|
|
99
102
|
return next(err);
|
|
@@ -104,6 +107,9 @@ export default class UserIncomingCallNumberAPI extends BaseAPI<
|
|
|
104
107
|
this.router.post(
|
|
105
108
|
`/user-incoming-call-number/resend-verification-code`,
|
|
106
109
|
UserMiddleware.getUserMiddleware,
|
|
110
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
111
|
+
VerificationCodeRateLimitBucket.Resend,
|
|
112
|
+
),
|
|
107
113
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
108
114
|
try {
|
|
109
115
|
req = req as OneUptimeRequest;
|
|
@@ -135,7 +141,11 @@ export default class UserIncomingCallNumberAPI extends BaseAPI<
|
|
|
135
141
|
);
|
|
136
142
|
}
|
|
137
143
|
|
|
138
|
-
|
|
144
|
+
/*
|
|
145
|
+
* A caller may only ask for a code to be sent to a row they own.
|
|
146
|
+
* Without this the resend route is a way to make somebody else's
|
|
147
|
+
* device ring on demand.
|
|
148
|
+
*/
|
|
139
149
|
if (
|
|
140
150
|
item.userId?.toString() !==
|
|
141
151
|
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|