@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/UserSmsAPI.ts
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import VerificationCodeRateLimit, {
|
|
3
|
+
VerificationCodeRateLimitBucket,
|
|
4
|
+
} from "../Middleware/VerificationCodeRateLimit";
|
|
2
5
|
import UserSMSService, {
|
|
3
6
|
Service as UserSMSServiceType,
|
|
4
7
|
} from "../Services/UserSmsService";
|
|
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 UserSMS from "../../Models/DatabaseModels/UserSMS";
|
|
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 UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
20
43
|
public constructor() {
|
|
21
44
|
super(UserSMS, UserSMSService);
|
|
@@ -23,6 +46,9 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
23
46
|
this.router.post(
|
|
24
47
|
`/user-sms/verify`,
|
|
25
48
|
UserMiddleware.getUserMiddleware,
|
|
49
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
50
|
+
VerificationCodeRateLimitBucket.Verify,
|
|
51
|
+
),
|
|
26
52
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
27
53
|
try {
|
|
28
54
|
req = req as OneUptimeRequest;
|
|
@@ -43,33 +69,10 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
43
69
|
);
|
|
44
70
|
}
|
|
45
71
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
id: req.body["itemId"],
|
|
49
|
-
props: {
|
|
50
|
-
isRoot: true,
|
|
51
|
-
},
|
|
52
|
-
select: {
|
|
53
|
-
userId: true,
|
|
54
|
-
projectId: 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
|
-
}
|
|
66
|
-
|
|
67
|
-
//check user id
|
|
72
|
+
const userId: ObjectID | undefined = (req as OneUptimeRequest)
|
|
73
|
+
?.userAuthorization?.userId;
|
|
68
74
|
|
|
69
|
-
if (
|
|
70
|
-
item.userId?.toString() !==
|
|
71
|
-
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
72
|
-
) {
|
|
75
|
+
if (!userId) {
|
|
73
76
|
return Response.sendErrorResponse(
|
|
74
77
|
req,
|
|
75
78
|
res,
|
|
@@ -77,32 +80,30 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
77
80
|
);
|
|
78
81
|
}
|
|
79
82
|
|
|
80
|
-
|
|
83
|
+
const result: ChannelVerificationResult =
|
|
84
|
+
await ChannelVerification.verifyCode({
|
|
85
|
+
service: this.service,
|
|
86
|
+
itemId: new ObjectID(req.body["itemId"].toString()),
|
|
87
|
+
userId: userId,
|
|
88
|
+
code: req.body["code"].toString(),
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (result.outcome !== ChannelVerificationOutcome.Verified) {
|
|
81
92
|
return Response.sendErrorResponse(
|
|
82
93
|
req,
|
|
83
94
|
res,
|
|
84
|
-
|
|
95
|
+
ChannelVerification.getFailureException(result.outcome),
|
|
85
96
|
);
|
|
86
97
|
}
|
|
87
98
|
|
|
88
|
-
|
|
89
|
-
id: item.id!,
|
|
90
|
-
props: {
|
|
91
|
-
isRoot: true,
|
|
92
|
-
},
|
|
93
|
-
data: {
|
|
94
|
-
isVerified: true,
|
|
95
|
-
},
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
// Create default notification rules for this verified SMS
|
|
99
|
+
/* Create default notification rules for this verified SMS number */
|
|
99
100
|
try {
|
|
100
101
|
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
101
102
|
{
|
|
102
|
-
projectId: new ObjectID(
|
|
103
|
-
userId: new ObjectID(
|
|
103
|
+
projectId: new ObjectID(result.projectId!.toString()),
|
|
104
|
+
userId: new ObjectID(result.userId!.toString()),
|
|
104
105
|
notificationMethod: {
|
|
105
|
-
userSmsId:
|
|
106
|
+
userSmsId: result.itemId!,
|
|
106
107
|
},
|
|
107
108
|
},
|
|
108
109
|
);
|
|
@@ -123,6 +124,9 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
123
124
|
this.router.post(
|
|
124
125
|
`/user-sms/resend-verification-code`,
|
|
125
126
|
UserMiddleware.getUserMiddleware,
|
|
127
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
128
|
+
VerificationCodeRateLimitBucket.Resend,
|
|
129
|
+
),
|
|
126
130
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
127
131
|
try {
|
|
128
132
|
req = req as OneUptimeRequest;
|
|
@@ -153,6 +157,11 @@ export default class UserSMSAPI extends BaseAPI<UserSMS, UserSMSServiceType> {
|
|
|
153
157
|
);
|
|
154
158
|
}
|
|
155
159
|
|
|
160
|
+
/*
|
|
161
|
+
* A caller may only ask for a code to be sent to a row they own.
|
|
162
|
+
* Without this the resend route is a way to make somebody else's
|
|
163
|
+
* device ring on demand.
|
|
164
|
+
*/
|
|
156
165
|
if (
|
|
157
166
|
item.userId?.toString() !==
|
|
158
167
|
(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 UserWhatsAppService, {
|
|
3
6
|
Service as UserWhatsAppServiceType,
|
|
4
7
|
} from "../Services/UserWhatsAppService";
|
|
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 UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
|
|
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 UserWhatsAppAPI extends BaseAPI<
|
|
20
43
|
UserWhatsApp,
|
|
21
44
|
UserWhatsAppServiceType
|
|
@@ -26,6 +49,9 @@ export default class UserWhatsAppAPI 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,39 +72,10 @@ export default class UserWhatsAppAPI extends BaseAPI<
|
|
|
46
72
|
);
|
|
47
73
|
}
|
|
48
74
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
props: {
|
|
52
|
-
isRoot: true,
|
|
53
|
-
},
|
|
54
|
-
select: {
|
|
55
|
-
userId: true,
|
|
56
|
-
projectId: true,
|
|
57
|
-
verificationCode: true,
|
|
58
|
-
isVerified: true,
|
|
59
|
-
},
|
|
60
|
-
});
|
|
75
|
+
const userId: ObjectID | undefined = (req as OneUptimeRequest)
|
|
76
|
+
?.userAuthorization?.userId;
|
|
61
77
|
|
|
62
|
-
if (!
|
|
63
|
-
return Response.sendErrorResponse(
|
|
64
|
-
req,
|
|
65
|
-
res,
|
|
66
|
-
new BadDataException("Item not found"),
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (item.isVerified) {
|
|
71
|
-
return Response.sendErrorResponse(
|
|
72
|
-
req,
|
|
73
|
-
res,
|
|
74
|
-
new BadDataException("WhatsApp number already verified"),
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
if (
|
|
79
|
-
item.userId?.toString() !==
|
|
80
|
-
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
81
|
-
) {
|
|
78
|
+
if (!userId) {
|
|
82
79
|
return Response.sendErrorResponse(
|
|
83
80
|
req,
|
|
84
81
|
res,
|
|
@@ -86,32 +83,30 @@ export default class UserWhatsAppAPI extends BaseAPI<
|
|
|
86
83
|
);
|
|
87
84
|
}
|
|
88
85
|
|
|
89
|
-
|
|
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) {
|
|
90
95
|
return Response.sendErrorResponse(
|
|
91
96
|
req,
|
|
92
97
|
res,
|
|
93
|
-
|
|
98
|
+
ChannelVerification.getFailureException(result.outcome),
|
|
94
99
|
);
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
|
|
98
|
-
id: item.id!,
|
|
99
|
-
props: {
|
|
100
|
-
isRoot: true,
|
|
101
|
-
},
|
|
102
|
-
data: {
|
|
103
|
-
isVerified: true,
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
// Create default notification rules for this verified WhatsApp number
|
|
102
|
+
/* Create default notification rules for this verified WhatsApp number */
|
|
108
103
|
try {
|
|
109
104
|
await UserNotificationRuleService.addDefaultNotificationRulesForVerifiedMethod(
|
|
110
105
|
{
|
|
111
|
-
projectId: new ObjectID(
|
|
112
|
-
userId: new ObjectID(
|
|
106
|
+
projectId: new ObjectID(result.projectId!.toString()),
|
|
107
|
+
userId: new ObjectID(result.userId!.toString()),
|
|
113
108
|
notificationMethod: {
|
|
114
|
-
userWhatsAppId:
|
|
109
|
+
userWhatsAppId: result.itemId!,
|
|
115
110
|
},
|
|
116
111
|
},
|
|
117
112
|
);
|
|
@@ -134,6 +129,9 @@ export default class UserWhatsAppAPI extends BaseAPI<
|
|
|
134
129
|
.getCrudApiPath()
|
|
135
130
|
?.toString()}/resend-verification-code`,
|
|
136
131
|
UserMiddleware.getUserMiddleware,
|
|
132
|
+
VerificationCodeRateLimit.getMiddleware(
|
|
133
|
+
VerificationCodeRateLimitBucket.Resend,
|
|
134
|
+
),
|
|
137
135
|
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
138
136
|
try {
|
|
139
137
|
req = req as OneUptimeRequest;
|
|
@@ -164,6 +162,11 @@ export default class UserWhatsAppAPI extends BaseAPI<
|
|
|
164
162
|
);
|
|
165
163
|
}
|
|
166
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
|
+
*/
|
|
167
170
|
if (
|
|
168
171
|
item.userId?.toString() !==
|
|
169
172
|
(req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* GHSA-5cr8-vph4-3hrf: expiry, attempt counting and resend throttling for the
|
|
5
|
+
* notification-channel verification codes.
|
|
6
|
+
*
|
|
7
|
+
* Three columns per channel table:
|
|
8
|
+
*
|
|
9
|
+
* verificationCodeExpiresAt NULL means there is no live code. Every row
|
|
10
|
+
* that exists when this runs gets NULL, which
|
|
11
|
+
* is read as expired — so the plaintext codes
|
|
12
|
+
* those rows are carrying stop being accepted
|
|
13
|
+
* the moment this lands, and their owners
|
|
14
|
+
* press "resend" once. That is the intended
|
|
15
|
+
* behaviour, not a side effect: those codes
|
|
16
|
+
* never expired and were never attempt-limited.
|
|
17
|
+
*
|
|
18
|
+
* verificationFailedAttempts The counter that bounds guessing. NOT NULL
|
|
19
|
+
* DEFAULT 0 so the atomic increment never has
|
|
20
|
+
* to deal with a NULL.
|
|
21
|
+
*
|
|
22
|
+
* verificationCodeSentAt Drives the resend cooldown. NULL on existing
|
|
23
|
+
* rows, which allows one immediate resend —
|
|
24
|
+
* correct, since the code they hold has just
|
|
25
|
+
* been invalidated above.
|
|
26
|
+
*
|
|
27
|
+
* The up() also SCRUBS the plaintext codes those rows are still carrying.
|
|
28
|
+
* They are already unusable by the time the scrub runs, but they are live
|
|
29
|
+
* six-digit secrets sitting in a table, its replicas and every backup taken
|
|
30
|
+
* while they were there, and the whole point of the change this migration
|
|
31
|
+
* supports is that the column holds a keyed digest and never the code.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
export class MigrationName1787142779538 implements MigrationInterface {
|
|
35
|
+
public name: string = "MigrationName1787142779538";
|
|
36
|
+
|
|
37
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
38
|
+
await queryRunner.query(
|
|
39
|
+
`ALTER TABLE "UserCall" ADD "verificationCodeExpiresAt" TIMESTAMP WITH TIME ZONE`,
|
|
40
|
+
);
|
|
41
|
+
await queryRunner.query(
|
|
42
|
+
`ALTER TABLE "UserCall" ADD "verificationFailedAttempts" integer NOT NULL DEFAULT '0'`,
|
|
43
|
+
);
|
|
44
|
+
await queryRunner.query(
|
|
45
|
+
`ALTER TABLE "UserCall" ADD "verificationCodeSentAt" TIMESTAMP WITH TIME ZONE`,
|
|
46
|
+
);
|
|
47
|
+
await queryRunner.query(
|
|
48
|
+
`ALTER TABLE "UserEmail" ADD "verificationCodeExpiresAt" TIMESTAMP WITH TIME ZONE`,
|
|
49
|
+
);
|
|
50
|
+
await queryRunner.query(
|
|
51
|
+
`ALTER TABLE "UserEmail" ADD "verificationFailedAttempts" integer NOT NULL DEFAULT '0'`,
|
|
52
|
+
);
|
|
53
|
+
await queryRunner.query(
|
|
54
|
+
`ALTER TABLE "UserEmail" ADD "verificationCodeSentAt" TIMESTAMP WITH TIME ZONE`,
|
|
55
|
+
);
|
|
56
|
+
await queryRunner.query(
|
|
57
|
+
`ALTER TABLE "UserSMS" ADD "verificationCodeExpiresAt" TIMESTAMP WITH TIME ZONE`,
|
|
58
|
+
);
|
|
59
|
+
await queryRunner.query(
|
|
60
|
+
`ALTER TABLE "UserSMS" ADD "verificationFailedAttempts" integer NOT NULL DEFAULT '0'`,
|
|
61
|
+
);
|
|
62
|
+
await queryRunner.query(
|
|
63
|
+
`ALTER TABLE "UserSMS" ADD "verificationCodeSentAt" TIMESTAMP WITH TIME ZONE`,
|
|
64
|
+
);
|
|
65
|
+
await queryRunner.query(
|
|
66
|
+
`ALTER TABLE "UserWhatsApp" ADD "verificationCodeExpiresAt" TIMESTAMP WITH TIME ZONE`,
|
|
67
|
+
);
|
|
68
|
+
await queryRunner.query(
|
|
69
|
+
`ALTER TABLE "UserWhatsApp" ADD "verificationFailedAttempts" integer NOT NULL DEFAULT '0'`,
|
|
70
|
+
);
|
|
71
|
+
await queryRunner.query(
|
|
72
|
+
`ALTER TABLE "UserWhatsApp" ADD "verificationCodeSentAt" TIMESTAMP WITH TIME ZONE`,
|
|
73
|
+
);
|
|
74
|
+
await queryRunner.query(
|
|
75
|
+
`ALTER TABLE "UserIncomingCallNumber" ADD "verificationCodeExpiresAt" TIMESTAMP WITH TIME ZONE`,
|
|
76
|
+
);
|
|
77
|
+
await queryRunner.query(
|
|
78
|
+
`ALTER TABLE "UserIncomingCallNumber" ADD "verificationFailedAttempts" integer NOT NULL DEFAULT '0'`,
|
|
79
|
+
);
|
|
80
|
+
await queryRunner.query(
|
|
81
|
+
`ALTER TABLE "UserIncomingCallNumber" ADD "verificationCodeSentAt" TIMESTAMP WITH TIME ZONE`,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
/*
|
|
85
|
+
* Replace every stored plaintext code with a value nothing can hash
|
|
86
|
+
* to. Two md5s give the 64 hex characters a real digest has, using
|
|
87
|
+
* only functions core Postgres always has — gen_random_bytes would
|
|
88
|
+
* need pgcrypto, which is not a dependency this schema otherwise has.
|
|
89
|
+
*
|
|
90
|
+
* Restricted to values that look like a code rather than applied
|
|
91
|
+
* blindly, so re-running against a database that has already moved on
|
|
92
|
+
* cannot damage a real digest.
|
|
93
|
+
*/
|
|
94
|
+
for (const tableName of [
|
|
95
|
+
"UserEmail",
|
|
96
|
+
"UserSMS",
|
|
97
|
+
"UserCall",
|
|
98
|
+
"UserWhatsApp",
|
|
99
|
+
"UserIncomingCallNumber",
|
|
100
|
+
]) {
|
|
101
|
+
await queryRunner.query(
|
|
102
|
+
`UPDATE "${tableName}" SET "verificationCode" = md5(random()::text || clock_timestamp()::text) || md5(random()::text || clock_timestamp()::text) WHERE "verificationCode" ~ '^[0-9]{1,10}$'`,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
108
|
+
await queryRunner.query(
|
|
109
|
+
`ALTER TABLE "UserIncomingCallNumber" DROP COLUMN "verificationCodeSentAt"`,
|
|
110
|
+
);
|
|
111
|
+
await queryRunner.query(
|
|
112
|
+
`ALTER TABLE "UserIncomingCallNumber" DROP COLUMN "verificationFailedAttempts"`,
|
|
113
|
+
);
|
|
114
|
+
await queryRunner.query(
|
|
115
|
+
`ALTER TABLE "UserIncomingCallNumber" DROP COLUMN "verificationCodeExpiresAt"`,
|
|
116
|
+
);
|
|
117
|
+
await queryRunner.query(
|
|
118
|
+
`ALTER TABLE "UserWhatsApp" DROP COLUMN "verificationCodeSentAt"`,
|
|
119
|
+
);
|
|
120
|
+
await queryRunner.query(
|
|
121
|
+
`ALTER TABLE "UserWhatsApp" DROP COLUMN "verificationFailedAttempts"`,
|
|
122
|
+
);
|
|
123
|
+
await queryRunner.query(
|
|
124
|
+
`ALTER TABLE "UserWhatsApp" DROP COLUMN "verificationCodeExpiresAt"`,
|
|
125
|
+
);
|
|
126
|
+
await queryRunner.query(
|
|
127
|
+
`ALTER TABLE "UserSMS" DROP COLUMN "verificationCodeSentAt"`,
|
|
128
|
+
);
|
|
129
|
+
await queryRunner.query(
|
|
130
|
+
`ALTER TABLE "UserSMS" DROP COLUMN "verificationFailedAttempts"`,
|
|
131
|
+
);
|
|
132
|
+
await queryRunner.query(
|
|
133
|
+
`ALTER TABLE "UserSMS" DROP COLUMN "verificationCodeExpiresAt"`,
|
|
134
|
+
);
|
|
135
|
+
await queryRunner.query(
|
|
136
|
+
`ALTER TABLE "UserEmail" DROP COLUMN "verificationCodeSentAt"`,
|
|
137
|
+
);
|
|
138
|
+
await queryRunner.query(
|
|
139
|
+
`ALTER TABLE "UserEmail" DROP COLUMN "verificationFailedAttempts"`,
|
|
140
|
+
);
|
|
141
|
+
await queryRunner.query(
|
|
142
|
+
`ALTER TABLE "UserEmail" DROP COLUMN "verificationCodeExpiresAt"`,
|
|
143
|
+
);
|
|
144
|
+
await queryRunner.query(
|
|
145
|
+
`ALTER TABLE "UserCall" DROP COLUMN "verificationCodeSentAt"`,
|
|
146
|
+
);
|
|
147
|
+
await queryRunner.query(
|
|
148
|
+
`ALTER TABLE "UserCall" DROP COLUMN "verificationFailedAttempts"`,
|
|
149
|
+
);
|
|
150
|
+
await queryRunner.query(
|
|
151
|
+
`ALTER TABLE "UserCall" DROP COLUMN "verificationCodeExpiresAt"`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1787156982416 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1787156982416";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "UserPush" ADD "isCriticalAlertEnabled" boolean NOT NULL DEFAULT false`,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "UserPush" DROP COLUMN "isCriticalAlertEnabled"`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Corrects the otpauth:// URLs behind every un-scanned 2FA QR code.
|
|
5
|
+
*
|
|
6
|
+
* OneUptime used to build those URLs with `algorithm=SHA256`. Google
|
|
7
|
+
* Authenticator and Microsoft Authenticator parse the URL, ignore that
|
|
8
|
+
* parameter, and compute SHA1 — so the app displayed six digits the server
|
|
9
|
+
* could never agree with and enrolment failed with "Invalid code" forever, no
|
|
10
|
+
* matter how many fresh codes the user tried.
|
|
11
|
+
*
|
|
12
|
+
* This migration is NOT what unsticks those users. The code fix already does:
|
|
13
|
+
* verification tries SHA1 first, which is what those apps were emitting all
|
|
14
|
+
* along, so a pending enrolment starts working the moment the new build ships
|
|
15
|
+
* and the stored URL is never consulted during verification. What this fixes
|
|
16
|
+
* is the URL still claiming something untrue, which matters for the apps that
|
|
17
|
+
* DO honour the parameter and do not implement SHA256 — some hardware tokens,
|
|
18
|
+
* older FreeOTP builds — and which would otherwise keep minting new rows that
|
|
19
|
+
* depend on the SHA256 fallback long after the fallback should have gone.
|
|
20
|
+
*
|
|
21
|
+
* Only the algorithm label changes; the secret is untouched, so an app that
|
|
22
|
+
* already scanned the old QR keeps working. Verification accepts SHA1 and
|
|
23
|
+
* legacy SHA256 either way (see Common/Server/Utils/TotpAuth.ts), which is
|
|
24
|
+
* what makes rewriting the label safe rather than a second lockout.
|
|
25
|
+
*
|
|
26
|
+
* Verified rows are deliberately left alone. Their QR code is never shown
|
|
27
|
+
* again — the Verify action only exists for unverified entries — so the stored
|
|
28
|
+
* URL is a record of what the user's authenticator actually holds, and that
|
|
29
|
+
* record should stay accurate.
|
|
30
|
+
*/
|
|
31
|
+
export class FixTotpOtpUrlAlgorithm1787700000000 implements MigrationInterface {
|
|
32
|
+
public name = "FixTotpOtpUrlAlgorithm1787700000000";
|
|
33
|
+
|
|
34
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
35
|
+
await queryRunner.query(
|
|
36
|
+
`UPDATE "UserTotpAuth" SET "twoFactorOtpUrl" = REPLACE("twoFactorOtpUrl", 'algorithm=SHA256', 'algorithm=SHA1') WHERE "isVerified" = false AND "twoFactorOtpUrl" LIKE '%algorithm=SHA256%'`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
41
|
+
await queryRunner.query(
|
|
42
|
+
`UPDATE "UserTotpAuth" SET "twoFactorOtpUrl" = REPLACE("twoFactorOtpUrl", 'algorithm=SHA1', 'algorithm=SHA256') WHERE "isVerified" = false AND "twoFactorOtpUrl" LIKE '%algorithm=SHA1%'`,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -530,6 +530,9 @@ import { AddEpisodeMemberNotifyIndexes1787300000000 } from "./1787300000000-AddE
|
|
|
530
530
|
import { AddDeviceRoleAndDeclaredLinkParent1787400000000 } from "./1787400000000-AddDeviceRoleAndDeclaredLinkParent";
|
|
531
531
|
import { AddEnableSearchEngineIndexingToStatusPage1787500000000 } from "./1787500000000-AddEnableSearchEngineIndexingToStatusPage";
|
|
532
532
|
import { AddNetworkDeviceReachabilityColumns1787600000000 } from "./1787600000000-AddNetworkDeviceReachabilityColumns";
|
|
533
|
+
import { FixTotpOtpUrlAlgorithm1787700000000 } from "./1787700000000-FixTotpOtpUrlAlgorithm";
|
|
534
|
+
import { MigrationName1787142779538 } from "./1787142779538-MigrationName";
|
|
535
|
+
import { MigrationName1787156982416 } from "./1787156982416-MigrationName";
|
|
533
536
|
|
|
534
537
|
export default [
|
|
535
538
|
InitialMigration,
|
|
@@ -1059,9 +1062,12 @@ export default [
|
|
|
1059
1062
|
AddInventoryItemArchiveAndCustomFields1786900000000,
|
|
1060
1063
|
AddOnCallNotificationFallbackColumns1787000000000,
|
|
1061
1064
|
AddAIConversationPageContext1787100000000,
|
|
1065
|
+
MigrationName1787142779538,
|
|
1066
|
+
MigrationName1787156982416,
|
|
1062
1067
|
AddAIChatMessageFeedback1787200000000,
|
|
1063
1068
|
AddEpisodeMemberNotifyIndexes1787300000000,
|
|
1064
1069
|
AddDeviceRoleAndDeclaredLinkParent1787400000000,
|
|
1065
1070
|
AddEnableSearchEngineIndexingToStatusPage1787500000000,
|
|
1066
1071
|
AddNetworkDeviceReachabilityColumns1787600000000,
|
|
1072
|
+
FixTotpOtpUrlAlgorithm1787700000000,
|
|
1067
1073
|
];
|