@oneuptime/common 12.0.12 → 12.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
- package/Models/DatabaseModels/NetworkDevice.ts +64 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/StatusPage.ts +59 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
- package/Server/API/AIChatAPI.ts +55 -56
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/CommonAPI.ts +89 -0
- package/Server/API/MicrosoftTeamsAPI.ts +20 -9
- package/Server/API/SlackAPI.ts +13 -10
- package/Server/API/StatusPageAPI.ts +2197 -2128
- package/Server/API/TelemetryAPI.ts +72 -3
- package/Server/API/UserCallAPI.ts +53 -45
- package/Server/API/UserEmailAPI.ts +53 -44
- package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
- package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
- package/Server/API/UserPushAPI.ts +126 -2
- package/Server/API/UserSmsAPI.ts +53 -44
- package/Server/API/UserWhatsAppAPI.ts +53 -50
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/UserAuthorization.ts +11 -2
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/ApiKeyPermissionService.ts +116 -2
- package/Server/Services/DatabaseService.ts +118 -6
- package/Server/Services/LogAggregationService.ts +39 -0
- package/Server/Services/LogService.ts +21 -0
- package/Server/Services/NetworkSiteService.ts +12 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/SpanService.ts +21 -0
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/TraceAggregationService.ts +15 -0
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/APIKey/AccessPermission.ts +16 -40
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/LogRedaction.ts +576 -0
- package/Server/Utils/Logger.ts +123 -46
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResource.ts +29 -9
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
- package/Server/Utils/StartServer.ts +30 -9
- package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +328 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
- package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
- package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
- package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
- package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +280 -0
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
- package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
- package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
- package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
- package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
- package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
- package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
- package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
- package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
- package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
- package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
- package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
- package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/MasterPage.test.tsx +36 -1
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/Dropdown.test.ts +423 -0
- package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
- package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
- package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
- package/Tests/Utils/API.test.ts +16 -2
- package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
- package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
- package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/API/Hostname.ts +79 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
- package/Types/Database/DatabaseProperty.ts +38 -0
- package/Types/Database/TableColumn.ts +34 -7
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Events/Recurring.ts +16 -1
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/MonitorStep.ts +13 -1
- package/Types/Monitor/MonitorType.ts +345 -40
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CardSelect/CardSelect.tsx +714 -105
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/EmptyState/EmptyState.tsx +8 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/Footer/Footer.tsx +32 -6
- package/UI/Components/Forms/Fields/FormField.tsx +3 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Loader/PageLoader.tsx +29 -8
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +23 -2
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/MasterPage/MasterPage.tsx +24 -11
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
- package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
- package/UI/Components/Navbar/NavBar.tsx +14 -1
- package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
- package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
- package/UI/Components/SideOver/SideOver.tsx +37 -2
- package/UI/Components/Skeleton/Skeleton.tsx +53 -0
- package/UI/Components/Table/Table.tsx +74 -44
- package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
- package/UI/Components/Tabs/Tab.tsx +1 -1
- package/UI/Components/Toast/Toast.tsx +118 -53
- package/UI/Components/Toast/ToastInit.tsx +82 -32
- package/UI/Styles/Theme.css +40 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
- package/UI/Utils/ModelListCache.ts +188 -0
- package/UI/Utils/Project.ts +29 -0
- package/Utils/API.ts +6 -1
- package/Utils/Monitor/MonitorMetricType.ts +16 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
- package/Utils/Telemetry/CrossSignalScope.ts +75 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +48 -35
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +59 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +13 -10
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +745 -673
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +34 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/API/UserCallAPI.js +42 -38
- package/build/dist/Server/API/UserCallAPI.js.map +1 -1
- package/build/dist/Server/API/UserEmailAPI.js +42 -38
- package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
- package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
- package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
- package/build/dist/Server/API/UserPushAPI.js +95 -2
- package/build/dist/Server/API/UserPushAPI.js.map +1 -1
- package/build/dist/Server/API/UserSmsAPI.js +42 -38
- package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
- package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
- package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
- package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +89 -6
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +7 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogService.js +16 -0
- package/build/dist/Server/Services/LogService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +12 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +16 -0
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/LogRedaction.js +449 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Logger.js +98 -45
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
- package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
- package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
- package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -7
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
- package/build/dist/Server/Utils/TotpAuth.js +127 -8
- package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
- package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
- package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
- package/build/dist/Server/Utils/VerificationCode.js +120 -0
- package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +63 -0
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +38 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js +24 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +13 -1
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +9 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +330 -31
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/Footer/Footer.js +7 -4
- package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
- package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
- package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
- package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
- package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
- package/build/dist/UI/Components/Table/Table.js +35 -24
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
- package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
- package/build/dist/UI/Components/Tabs/Tab.js +1 -1
- package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
- package/build/dist/UI/Components/Toast/Toast.js +77 -23
- package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
- package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
- package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelListCache.js +126 -0
- package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +24 -1
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/Utils/API.js +6 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
|
@@ -26,6 +26,7 @@ import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
|
26
26
|
import PushNotificationLog from "../../Models/DatabaseModels/PushNotificationLog";
|
|
27
27
|
import PushNotificationLogService from "./PushNotificationLogService";
|
|
28
28
|
import PushStatus from "../../Types/PushNotification/PushStatus";
|
|
29
|
+
import AndroidNotificationChannel from "../../Types/PushNotification/AndroidNotificationChannel";
|
|
29
30
|
|
|
30
31
|
/*
|
|
31
32
|
* The push services the browsers actually use. A Web Push subscription is a
|
|
@@ -67,6 +68,43 @@ export interface PushNotificationOptions {
|
|
|
67
68
|
teamId?: ObjectID | undefined;
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/*
|
|
72
|
+
* What Expo needs to be told for a notification to ring through a silenced
|
|
73
|
+
* handset. The two platforms disagree about where the answer lives, so this is
|
|
74
|
+
* computed once and reused by both the direct-SDK and relay send paths.
|
|
75
|
+
*
|
|
76
|
+
* iOS reads the payload: a `sound` object with `critical: true` plus
|
|
77
|
+
* `interruptionLevel: "critical"` is what makes APNs ignore the ringer switch
|
|
78
|
+
* and Focus, and it is refused unless the app carries Apple's critical-alert
|
|
79
|
+
* entitlement.
|
|
80
|
+
*
|
|
81
|
+
* Android ignores all of that and reads the CHANNEL. Sound, importance and Do
|
|
82
|
+
* Not Disturb bypass are baked into the channel when the app creates it and
|
|
83
|
+
* cannot be raised by a payload, so the only lever the server has is which
|
|
84
|
+
* channel id it names.
|
|
85
|
+
*/
|
|
86
|
+
export type ExpoPushSound =
|
|
87
|
+
| string
|
|
88
|
+
| null
|
|
89
|
+
| {
|
|
90
|
+
critical?: boolean;
|
|
91
|
+
name?: string | null;
|
|
92
|
+
volume?: number;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type ExpoInterruptionLevel =
|
|
96
|
+
| "active"
|
|
97
|
+
| "critical"
|
|
98
|
+
| "passive"
|
|
99
|
+
| "time-sensitive";
|
|
100
|
+
|
|
101
|
+
export interface ExpoDeliveryOptions {
|
|
102
|
+
channelId: string;
|
|
103
|
+
sound: ExpoPushSound;
|
|
104
|
+
priority: "high";
|
|
105
|
+
interruptionLevel?: ExpoInterruptionLevel;
|
|
106
|
+
}
|
|
107
|
+
|
|
70
108
|
export default class PushNotificationService {
|
|
71
109
|
public static isWebPushInitialized = false;
|
|
72
110
|
private static expoClient: Expo = new Expo(
|
|
@@ -408,6 +446,57 @@ export default class PushNotificationService {
|
|
|
408
446
|
}
|
|
409
447
|
}
|
|
410
448
|
|
|
449
|
+
/*
|
|
450
|
+
* Volume is pinned rather than exposed as a setting. A critical alert exists
|
|
451
|
+
* to wake somebody, and a responder who has already opted this device in and
|
|
452
|
+
* granted the OS permission has not asked to be woken quietly.
|
|
453
|
+
*/
|
|
454
|
+
public static readonly CRITICAL_ALERT_VOLUME: number = 1;
|
|
455
|
+
|
|
456
|
+
public static getExpoDeliveryOptions(
|
|
457
|
+
message: PushNotificationMessage,
|
|
458
|
+
deviceType: PushDeviceType,
|
|
459
|
+
): ExpoDeliveryOptions {
|
|
460
|
+
const isAndroid: boolean = deviceType === PushDeviceType.Android;
|
|
461
|
+
const isCritical: boolean = Boolean(message.isCriticalAlert);
|
|
462
|
+
|
|
463
|
+
/*
|
|
464
|
+
* iOS has no channels, so "default" here is the payload's own sound rather
|
|
465
|
+
* than a channel id. Android without the critical flag stays on
|
|
466
|
+
* oncall_high, which is what every push has used until now.
|
|
467
|
+
*/
|
|
468
|
+
const channelId: string = isAndroid
|
|
469
|
+
? isCritical
|
|
470
|
+
? AndroidNotificationChannel.Critical
|
|
471
|
+
: AndroidNotificationChannel.High
|
|
472
|
+
: "default";
|
|
473
|
+
|
|
474
|
+
if (!isCritical) {
|
|
475
|
+
return {
|
|
476
|
+
channelId: channelId,
|
|
477
|
+
sound: "default",
|
|
478
|
+
priority: "high",
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
return {
|
|
483
|
+
channelId: channelId,
|
|
484
|
+
/*
|
|
485
|
+
* Sent to Android too, and harmlessly ignored there. Expo forwards it to
|
|
486
|
+
* APNs where it is the whole mechanism, and to FCM where the channel has
|
|
487
|
+
* already decided the sound; keeping one shape avoids a per-platform
|
|
488
|
+
* branch that could silently drop the iOS half.
|
|
489
|
+
*/
|
|
490
|
+
sound: {
|
|
491
|
+
critical: true,
|
|
492
|
+
name: "default",
|
|
493
|
+
volume: PushNotificationService.CRITICAL_ALERT_VOLUME,
|
|
494
|
+
},
|
|
495
|
+
priority: "high",
|
|
496
|
+
interruptionLevel: "critical",
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
|
|
411
500
|
private static async sendExpoPushNotification(
|
|
412
501
|
expoPushToken: string,
|
|
413
502
|
message: PushNotificationMessage,
|
|
@@ -430,8 +519,10 @@ export default class PushNotificationService {
|
|
|
430
519
|
dataPayload["url"] = message.url || message.clickAction || "";
|
|
431
520
|
}
|
|
432
521
|
|
|
433
|
-
const
|
|
434
|
-
|
|
522
|
+
const delivery: ExpoDeliveryOptions = this.getExpoDeliveryOptions(
|
|
523
|
+
message,
|
|
524
|
+
deviceType,
|
|
525
|
+
);
|
|
435
526
|
|
|
436
527
|
// If EXPO_ACCESS_TOKEN is not set, relay through the push notification gateway
|
|
437
528
|
if (!ExpoAccessToken) {
|
|
@@ -439,7 +530,7 @@ export default class PushNotificationService {
|
|
|
439
530
|
expoPushToken,
|
|
440
531
|
message,
|
|
441
532
|
dataPayload,
|
|
442
|
-
|
|
533
|
+
delivery,
|
|
443
534
|
deviceType,
|
|
444
535
|
);
|
|
445
536
|
return;
|
|
@@ -452,9 +543,12 @@ export default class PushNotificationService {
|
|
|
452
543
|
title: message.title,
|
|
453
544
|
body: message.body,
|
|
454
545
|
data: dataPayload,
|
|
455
|
-
sound:
|
|
456
|
-
priority:
|
|
457
|
-
channelId: channelId,
|
|
546
|
+
sound: delivery.sound,
|
|
547
|
+
priority: delivery.priority,
|
|
548
|
+
channelId: delivery.channelId,
|
|
549
|
+
...(delivery.interruptionLevel
|
|
550
|
+
? { interruptionLevel: delivery.interruptionLevel }
|
|
551
|
+
: {}),
|
|
458
552
|
};
|
|
459
553
|
|
|
460
554
|
const tickets: ExpoPushTicket[] =
|
|
@@ -500,7 +594,7 @@ export default class PushNotificationService {
|
|
|
500
594
|
expoPushToken: string,
|
|
501
595
|
message: PushNotificationMessage,
|
|
502
596
|
dataPayload: { [key: string]: string },
|
|
503
|
-
|
|
597
|
+
delivery: ExpoDeliveryOptions,
|
|
504
598
|
deviceType: PushDeviceType,
|
|
505
599
|
): Promise<void> {
|
|
506
600
|
logger.info(
|
|
@@ -516,9 +610,19 @@ export default class PushNotificationService {
|
|
|
516
610
|
title: message.title || "",
|
|
517
611
|
body: message.body || "",
|
|
518
612
|
data: dataPayload,
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
613
|
+
/*
|
|
614
|
+
* The relay re-sends exactly what it is given, so a critical page
|
|
615
|
+
* that loses its sound object here arrives on the responder's
|
|
616
|
+
* phone as an ordinary silent notification. That is the failure
|
|
617
|
+
* this feature exists to prevent, so the whole delivery shape
|
|
618
|
+
* crosses the wire rather than the channel id alone.
|
|
619
|
+
*/
|
|
620
|
+
sound: delivery.sound,
|
|
621
|
+
priority: delivery.priority,
|
|
622
|
+
channelId: delivery.channelId,
|
|
623
|
+
...(delivery.interruptionLevel
|
|
624
|
+
? { interruptionLevel: delivery.interruptionLevel }
|
|
625
|
+
: {}),
|
|
522
626
|
},
|
|
523
627
|
});
|
|
524
628
|
|
|
@@ -552,9 +656,10 @@ export default class PushNotificationService {
|
|
|
552
656
|
title?: string;
|
|
553
657
|
body?: string;
|
|
554
658
|
data?: { [key: string]: string };
|
|
555
|
-
sound?:
|
|
659
|
+
sound?: ExpoPushSound;
|
|
556
660
|
priority?: string;
|
|
557
661
|
channelId?: string;
|
|
662
|
+
interruptionLevel?: ExpoInterruptionLevel;
|
|
558
663
|
}): Promise<void> {
|
|
559
664
|
if (!ExpoAccessToken) {
|
|
560
665
|
throw new Error(
|
|
@@ -562,14 +667,24 @@ export default class PushNotificationService {
|
|
|
562
667
|
);
|
|
563
668
|
}
|
|
564
669
|
|
|
670
|
+
/*
|
|
671
|
+
* `sound: null` is a caller asking for a silent notification and has to
|
|
672
|
+
* survive, so the fallback tests for undefined rather than falsiness.
|
|
673
|
+
*/
|
|
674
|
+
const sound: ExpoPushSound =
|
|
675
|
+
data.sound === undefined ? "default" : data.sound;
|
|
676
|
+
|
|
565
677
|
const expoPushMessage: ExpoPushMessage = {
|
|
566
678
|
to: data.to,
|
|
567
679
|
title: data.title || "",
|
|
568
680
|
body: data.body || "",
|
|
569
681
|
data: data.data || {},
|
|
570
|
-
sound:
|
|
682
|
+
sound: sound,
|
|
571
683
|
priority: (data.priority as "default" | "normal" | "high") || "high",
|
|
572
684
|
channelId: data.channelId || "default",
|
|
685
|
+
...(data.interruptionLevel
|
|
686
|
+
? { interruptionLevel: data.interruptionLevel }
|
|
687
|
+
: {}),
|
|
573
688
|
};
|
|
574
689
|
|
|
575
690
|
const tickets: ExpoPushTicket[] =
|
|
@@ -14,6 +14,9 @@ import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
|
14
14
|
import InBetween from "../../Types/BaseDatabase/InBetween";
|
|
15
15
|
import Includes from "../../Types/BaseDatabase/Includes";
|
|
16
16
|
import ObjectID from "../../Types/ObjectID";
|
|
17
|
+
import FindBy from "../Types/AnalyticsDatabase/FindBy";
|
|
18
|
+
import { OnFind } from "../Types/AnalyticsDatabase/Hooks";
|
|
19
|
+
import ResourceEntityFilter from "../Utils/Telemetry/ResourceEntityFilter";
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* Columns the proj_hist_by_minute projection can answer with. If a count
|
|
@@ -35,6 +38,24 @@ export class SpanService extends AnalyticsDatabaseService<Span> {
|
|
|
35
38
|
super({ modelType: Span, database: clickhouseDatabase });
|
|
36
39
|
}
|
|
37
40
|
|
|
41
|
+
/*
|
|
42
|
+
* Resolve the traces explorer's resource-facet selections (a Kubernetes
|
|
43
|
+
* cluster, a host, ...) before the query is compiled. They arrive as
|
|
44
|
+
* Postgres ids under `resourceFilters`; matching them needs the
|
|
45
|
+
* resource's entity key, which only Postgres can supply. See
|
|
46
|
+
* ResourceEntityFilter.
|
|
47
|
+
*/
|
|
48
|
+
protected override async onBeforeFind(
|
|
49
|
+
findBy: FindBy<Span>,
|
|
50
|
+
): Promise<OnFind<Span>> {
|
|
51
|
+
await ResourceEntityFilter.rewriteAnalyticsQuery({
|
|
52
|
+
query: findBy.query as unknown as Record<string, unknown>,
|
|
53
|
+
projectId: findBy.props?.tenantId,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return { findBy, carryForward: null };
|
|
57
|
+
}
|
|
58
|
+
|
|
38
59
|
/**
|
|
39
60
|
* Normalize a JSON-deserialized date value to a Date instance. When a query
|
|
40
61
|
* crosses the API boundary, InBetween's startValue/endValue come back as ISO
|
|
@@ -10,6 +10,7 @@ import UpdateBy from "../Types/Database/UpdateBy";
|
|
|
10
10
|
import Errors from "../Utils/Errors";
|
|
11
11
|
import logger, { LogAttributes } from "../Utils/Logger";
|
|
12
12
|
import ProductAnalytics from "../Utils/ProductAnalytics";
|
|
13
|
+
import UserRegistrationToken from "../Utils/UserRegistrationToken";
|
|
13
14
|
import AccessTokenService from "./AccessTokenService";
|
|
14
15
|
import BillingService from "./BillingService";
|
|
15
16
|
import DatabaseService from "./DatabaseService";
|
|
@@ -166,8 +167,23 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
|
166
167
|
? (createBy.miscDataProps["name"] as string).trim()
|
|
167
168
|
: undefined;
|
|
168
169
|
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
/*
|
|
171
|
+
* `password` comes back too, because whether this person has finished
|
|
172
|
+
* registering decides both which link the invitation carries and whether
|
|
173
|
+
* that link needs a registration token. UserService.findByEmail selects
|
|
174
|
+
* only the id, so it cannot answer that.
|
|
175
|
+
*/
|
|
176
|
+
let user: User | null = await UserService.findOneBy({
|
|
177
|
+
query: {
|
|
178
|
+
email: email,
|
|
179
|
+
},
|
|
180
|
+
select: {
|
|
181
|
+
_id: true,
|
|
182
|
+
password: true,
|
|
183
|
+
},
|
|
184
|
+
props: {
|
|
185
|
+
isRoot: true,
|
|
186
|
+
},
|
|
171
187
|
});
|
|
172
188
|
|
|
173
189
|
let isNewUser: boolean = false;
|
|
@@ -228,6 +244,39 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
|
228
244
|
const host: Hostname = await DatabaseConfig.getHost();
|
|
229
245
|
const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
|
|
230
246
|
|
|
247
|
+
/*
|
|
248
|
+
* "Still has to register", not "we just created the row". Someone
|
|
249
|
+
* invited to a second project before they ever signed up already has a
|
|
250
|
+
* user row and still has no password, and used to be sent the sign-in
|
|
251
|
+
* link — which they could not use, having no password to sign in with.
|
|
252
|
+
*/
|
|
253
|
+
const needsRegistration: boolean = isNewUser || !user.password;
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
* The token is what lets the recipient claim this account, so it exists
|
|
257
|
+
* only on the link inside this email and only for someone who has not
|
|
258
|
+
* registered yet. An already-registered invitee gets the plain link;
|
|
259
|
+
* they sign in instead, and minting a claim token for an account that
|
|
260
|
+
* cannot be claimed would just be a spare key lying around.
|
|
261
|
+
*/
|
|
262
|
+
const registerLink: string = needsRegistration
|
|
263
|
+
? (
|
|
264
|
+
await UserRegistrationToken.generateRegistrationLink({
|
|
265
|
+
userId: user.id!,
|
|
266
|
+
email: email,
|
|
267
|
+
})
|
|
268
|
+
).toString()
|
|
269
|
+
: URL.fromString(
|
|
270
|
+
new URL(
|
|
271
|
+
httpProtocol,
|
|
272
|
+
host,
|
|
273
|
+
new Route(AccountsRoute.toString()),
|
|
274
|
+
).toString(),
|
|
275
|
+
)
|
|
276
|
+
.addRoute("/register")
|
|
277
|
+
.addQueryParam("email", email.toString(), true)
|
|
278
|
+
.toString();
|
|
279
|
+
|
|
231
280
|
MailService.sendMail(
|
|
232
281
|
{
|
|
233
282
|
toEmail: email,
|
|
@@ -240,17 +289,8 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
|
|
|
240
289
|
new Route(AccountsRoute.toString()),
|
|
241
290
|
).toString(),
|
|
242
291
|
).toString(),
|
|
243
|
-
registerLink:
|
|
244
|
-
|
|
245
|
-
httpProtocol,
|
|
246
|
-
host,
|
|
247
|
-
new Route(AccountsRoute.toString()),
|
|
248
|
-
).toString(),
|
|
249
|
-
)
|
|
250
|
-
.addRoute("/register")
|
|
251
|
-
.addQueryParam("email", email.toString(), true)
|
|
252
|
-
.toString(),
|
|
253
|
-
isNewUser: isNewUser.toString(),
|
|
292
|
+
registerLink: registerLink,
|
|
293
|
+
isNewUser: needsRegistration.toString(),
|
|
254
294
|
/*
|
|
255
295
|
* An auto-accepted member has nothing left to accept, so the
|
|
256
296
|
* template drops the "sign in to accept your invitation" framing
|
|
@@ -11,6 +11,10 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
|
11
11
|
import { DbJSONResponse, Results } from "./AnalyticsDatabaseService";
|
|
12
12
|
import logger from "../Utils/Logger";
|
|
13
13
|
import ServiceType from "../../Types/Telemetry/ServiceType";
|
|
14
|
+
import {
|
|
15
|
+
appendResourceScopeFilters,
|
|
16
|
+
ResourceEntityScope,
|
|
17
|
+
} from "../Utils/Telemetry/ResourceEntityFilter";
|
|
14
18
|
import ResourceFacetResolver, {
|
|
15
19
|
ResolvedFacetValue,
|
|
16
20
|
ResourceFacetSpec,
|
|
@@ -33,6 +37,15 @@ export type TraceAttributeFilters = Record<string, TraceAttributeFilterValue>;
|
|
|
33
37
|
export interface TraceFilters {
|
|
34
38
|
serviceIds?: Array<ObjectID> | undefined;
|
|
35
39
|
entityKeys?: Array<string> | undefined;
|
|
40
|
+
/*
|
|
41
|
+
* Resource-facet selections (Kubernetes cluster / host / docker host /
|
|
42
|
+
* podman host) already resolved to their entity keys. One scope per
|
|
43
|
+
* facet: the branches inside a scope OR (a span proves membership either
|
|
44
|
+
* by being primary-keyed on the resource or by carrying its entity key),
|
|
45
|
+
* and the scopes AND with each other so two facets intersect. See
|
|
46
|
+
* ResourceEntityFilter.
|
|
47
|
+
*/
|
|
48
|
+
resourceScopes?: Array<ResourceEntityScope> | undefined;
|
|
36
49
|
statusCodes?: Array<number> | undefined;
|
|
37
50
|
spanKinds?: Array<string> | undefined;
|
|
38
51
|
spanNames?: Array<string> | undefined;
|
|
@@ -1008,6 +1021,8 @@ export class TraceAggregationService {
|
|
|
1008
1021
|
);
|
|
1009
1022
|
}
|
|
1010
1023
|
|
|
1024
|
+
appendResourceScopeFilters(statement, request.resourceScopes);
|
|
1025
|
+
|
|
1011
1026
|
if (request.statusCodes && request.statusCodes.length > 0) {
|
|
1012
1027
|
statement.append(
|
|
1013
1028
|
SQL` AND statusCode IN (${{
|
|
@@ -16,7 +16,8 @@ import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
|
16
16
|
import TwilioConfig from "../../Types/CallAndSMS/TwilioConfig";
|
|
17
17
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
18
18
|
import ObjectID from "../../Types/ObjectID";
|
|
19
|
-
import
|
|
19
|
+
import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
|
|
20
|
+
import ChannelVerification from "../Utils/ChannelVerification";
|
|
20
21
|
import Project from "../../Models/DatabaseModels/Project";
|
|
21
22
|
import Model from "../../Models/DatabaseModels/UserCall";
|
|
22
23
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
@@ -144,7 +145,8 @@ export class Service extends DatabaseService<Model> {
|
|
|
144
145
|
createdItem: Model,
|
|
145
146
|
): Promise<Model> {
|
|
146
147
|
if (!createdItem.isVerified) {
|
|
147
|
-
|
|
148
|
+
// issue and send the first verification code
|
|
149
|
+
await this.issueAndSendVerificationCode(createdItem);
|
|
148
150
|
}
|
|
149
151
|
return createdItem;
|
|
150
152
|
}
|
|
@@ -158,9 +160,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
158
160
|
},
|
|
159
161
|
select: {
|
|
160
162
|
phone: true,
|
|
161
|
-
verificationCode: true,
|
|
162
163
|
isVerified: true,
|
|
163
164
|
projectId: true,
|
|
165
|
+
userId: true,
|
|
166
|
+
verificationCodeSentAt: true,
|
|
164
167
|
},
|
|
165
168
|
});
|
|
166
169
|
|
|
@@ -215,23 +218,57 @@ export class Service extends DatabaseService<Model> {
|
|
|
215
218
|
);
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
|
|
219
|
-
|
|
221
|
+
/*
|
|
222
|
+
* Resend cooldown.
|
|
223
|
+
*
|
|
224
|
+
* Without it, spending the attempt budget on a code and asking for
|
|
225
|
+
* another one is free, which turns the attempt limit into a speed bump
|
|
226
|
+
* rather than a wall — and the resend control doubles as a way to send
|
|
227
|
+
* somebody unsolicited messages as fast as the network allows, at the
|
|
228
|
+
* project's expense.
|
|
229
|
+
*/
|
|
230
|
+
const retryAfterSeconds: number =
|
|
231
|
+
ChannelVerification.getResendRetryAfterSeconds({
|
|
232
|
+
lastSentAt: item.verificationCodeSentAt,
|
|
233
|
+
});
|
|
220
234
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
235
|
+
if (retryAfterSeconds > 0) {
|
|
236
|
+
throw new TooManyRequestsException(
|
|
237
|
+
`Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
await this.issueAndSendVerificationCode(item);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/*
|
|
245
|
+
* Mint a fresh code for this row, store only its digest, and send the
|
|
246
|
+
* plaintext to the channel.
|
|
247
|
+
*
|
|
248
|
+
* The plaintext exists in memory for exactly as long as it takes to hand it
|
|
249
|
+
* to the notification service and is never written anywhere. Everything
|
|
250
|
+
* about why — expiry, the attempt counter, rotation, the resend cooldown —
|
|
251
|
+
* is in Common/Server/Utils/ChannelVerification.ts.
|
|
252
|
+
*
|
|
253
|
+
* This does NOT check whether a send is allowed. Callers decide that:
|
|
254
|
+
* onCreateSuccess because a brand new row has never been sent to, and
|
|
255
|
+
* resendVerificationCode after the cooldown and the channel's own
|
|
256
|
+
* preconditions have passed.
|
|
257
|
+
*/
|
|
258
|
+
@CaptureSpan()
|
|
259
|
+
public async issueAndSendVerificationCode(item: Model): Promise<void> {
|
|
260
|
+
const plainCode: string = await ChannelVerification.issueCodeOnItem({
|
|
261
|
+
service: this,
|
|
262
|
+
itemId: item.id!,
|
|
229
263
|
});
|
|
230
264
|
|
|
231
|
-
this.sendVerificationCode(item);
|
|
265
|
+
this.sendVerificationCode(item, plainCode);
|
|
232
266
|
}
|
|
233
267
|
|
|
234
|
-
public sendVerificationCode(item: Model): void {
|
|
268
|
+
public sendVerificationCode(item: Model, code: string): void {
|
|
269
|
+
// add space to make it more clear and slow down the message
|
|
270
|
+
const spokenCode: string = code.split("").join(" ");
|
|
271
|
+
|
|
235
272
|
const callRequest: CallRequest = {
|
|
236
273
|
to: item.phone!,
|
|
237
274
|
data: [
|
|
@@ -239,19 +276,13 @@ export class Service extends DatabaseService<Model> {
|
|
|
239
276
|
sayMessage: "This call is from One Uptime.",
|
|
240
277
|
},
|
|
241
278
|
{
|
|
242
|
-
sayMessage:
|
|
243
|
-
"Your verification code is " +
|
|
244
|
-
item.verificationCode?.split("").join(" "), // add space to make it more clear and slow down the message
|
|
279
|
+
sayMessage: "Your verification code is " + spokenCode,
|
|
245
280
|
},
|
|
246
281
|
{
|
|
247
|
-
sayMessage:
|
|
248
|
-
"Your verification code is " +
|
|
249
|
-
item.verificationCode?.split("").join(" "), // add space to make it more clear and slow down the message
|
|
282
|
+
sayMessage: "Your verification code is " + spokenCode,
|
|
250
283
|
},
|
|
251
284
|
{
|
|
252
|
-
sayMessage:
|
|
253
|
-
"Your verification code is " +
|
|
254
|
-
item.verificationCode?.split("").join(" "), // add space to make it more clear and slow down the message
|
|
285
|
+
sayMessage: "Your verification code is " + spokenCode,
|
|
255
286
|
},
|
|
256
287
|
{
|
|
257
288
|
sayMessage: "Thank you for using One Uptime. Goodbye.",
|
|
@@ -12,7 +12,8 @@ import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
|
12
12
|
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
13
13
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
14
14
|
import ObjectID from "../../Types/ObjectID";
|
|
15
|
-
import
|
|
15
|
+
import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
|
|
16
|
+
import ChannelVerification from "../Utils/ChannelVerification";
|
|
16
17
|
import Model from "../../Models/DatabaseModels/UserEmail";
|
|
17
18
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
18
19
|
|
|
@@ -100,8 +101,33 @@ export class Service extends DatabaseService<Model> {
|
|
|
100
101
|
createdItem: Model,
|
|
101
102
|
): Promise<Model> {
|
|
102
103
|
if (!createdItem.isVerified) {
|
|
103
|
-
// send verification code
|
|
104
|
-
|
|
104
|
+
// issue and send the first verification code
|
|
105
|
+
const plainCode: string =
|
|
106
|
+
await this.issueAndSendVerificationCode(createdItem);
|
|
107
|
+
|
|
108
|
+
/*
|
|
109
|
+
* TEST-ONLY seam, OFF unless explicitly switched on.
|
|
110
|
+
*
|
|
111
|
+
* The plaintext code is otherwise only ever emailed - never returned by
|
|
112
|
+
* the API - which is deliberate: returning it would let a caller add
|
|
113
|
+
* anybody's address and confirm it instantly, the exact takeover the
|
|
114
|
+
* hashing/expiry/attempt controls exist to stop (see ChannelVerification
|
|
115
|
+
* and VerificationCode). The end-to-end stack has no mailbox to read the
|
|
116
|
+
* emailed code from, so this narrow hatch hands the code back on the
|
|
117
|
+
* create response for it to confirm the address the way a user would.
|
|
118
|
+
*
|
|
119
|
+
* It is gated on an environment variable that is unset in every shipped
|
|
120
|
+
* config and set true ONLY in the CI e2e job (docker-compose passes it
|
|
121
|
+
* through, .github/workflows/test-release.yaml sets it for the SaaS run).
|
|
122
|
+
* In production the flag is absent, this branch never runs, and the code
|
|
123
|
+
* never leaves the mail path.
|
|
124
|
+
*/
|
|
125
|
+
if (
|
|
126
|
+
process.env["EXPOSE_VERIFICATION_CODE_IN_API_RESPONSE_FOR_E2E"] ===
|
|
127
|
+
"true"
|
|
128
|
+
) {
|
|
129
|
+
createdItem.verificationCode = plainCode;
|
|
130
|
+
}
|
|
105
131
|
}
|
|
106
132
|
|
|
107
133
|
return createdItem;
|
|
@@ -116,9 +142,10 @@ export class Service extends DatabaseService<Model> {
|
|
|
116
142
|
},
|
|
117
143
|
select: {
|
|
118
144
|
email: true,
|
|
119
|
-
verificationCode: true,
|
|
120
145
|
isVerified: true,
|
|
121
146
|
projectId: true,
|
|
147
|
+
userId: true,
|
|
148
|
+
verificationCodeSentAt: true,
|
|
122
149
|
},
|
|
123
150
|
});
|
|
124
151
|
|
|
@@ -132,29 +159,68 @@ export class Service extends DatabaseService<Model> {
|
|
|
132
159
|
throw new BadDataException("Email already verified");
|
|
133
160
|
}
|
|
134
161
|
|
|
135
|
-
|
|
136
|
-
|
|
162
|
+
/*
|
|
163
|
+
* Resend cooldown.
|
|
164
|
+
*
|
|
165
|
+
* Without it, spending the attempt budget on a code and asking for
|
|
166
|
+
* another one is free, which turns the attempt limit into a speed bump
|
|
167
|
+
* rather than a wall — and the resend control doubles as a way to send
|
|
168
|
+
* somebody unsolicited messages as fast as the network allows, at the
|
|
169
|
+
* project's expense.
|
|
170
|
+
*/
|
|
171
|
+
const retryAfterSeconds: number =
|
|
172
|
+
ChannelVerification.getResendRetryAfterSeconds({
|
|
173
|
+
lastSentAt: item.verificationCodeSentAt,
|
|
174
|
+
});
|
|
137
175
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
176
|
+
if (retryAfterSeconds > 0) {
|
|
177
|
+
throw new TooManyRequestsException(
|
|
178
|
+
`Please wait ${retryAfterSeconds} seconds before requesting another verification code.`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
await this.issueAndSendVerificationCode(item);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* Mint a fresh code for this row, store only its digest, and send the
|
|
187
|
+
* plaintext to the channel.
|
|
188
|
+
*
|
|
189
|
+
* The plaintext exists in memory for exactly as long as it takes to hand it
|
|
190
|
+
* to the notification service and is never written anywhere. Everything
|
|
191
|
+
* about why — expiry, the attempt counter, rotation, the resend cooldown —
|
|
192
|
+
* is in Common/Server/Utils/ChannelVerification.ts.
|
|
193
|
+
*
|
|
194
|
+
* This does NOT check whether a send is allowed. Callers decide that:
|
|
195
|
+
* onCreateSuccess because a brand new row has never been sent to, and
|
|
196
|
+
* resendVerificationCode after the cooldown and the channel's own
|
|
197
|
+
* preconditions have passed.
|
|
198
|
+
*/
|
|
199
|
+
@CaptureSpan()
|
|
200
|
+
public async issueAndSendVerificationCode(item: Model): Promise<string> {
|
|
201
|
+
const plainCode: string = await ChannelVerification.issueCodeOnItem({
|
|
202
|
+
service: this,
|
|
203
|
+
itemId: item.id!,
|
|
146
204
|
});
|
|
147
205
|
|
|
148
|
-
this.sendVerificationCode(item);
|
|
206
|
+
this.sendVerificationCode(item, plainCode);
|
|
207
|
+
|
|
208
|
+
/*
|
|
209
|
+
* The plaintext exists here for exactly as long as it takes to hand it to
|
|
210
|
+
* the mailer, and is returned so a caller that has a legitimate reason to
|
|
211
|
+
* see it can - see onCreateSuccess for the one place that does, and the
|
|
212
|
+
* hard gate around it.
|
|
213
|
+
*/
|
|
214
|
+
return plainCode;
|
|
149
215
|
}
|
|
150
216
|
|
|
151
|
-
public sendVerificationCode(item: Model): void {
|
|
217
|
+
public sendVerificationCode(item: Model, code: string): void {
|
|
152
218
|
MailService.sendMail(
|
|
153
219
|
{
|
|
154
220
|
toEmail: item.email!,
|
|
155
221
|
templateType: EmailTemplateType.VerificationCode,
|
|
156
222
|
vars: {
|
|
157
|
-
code:
|
|
223
|
+
code: code,
|
|
158
224
|
subject: "Verify this email address",
|
|
159
225
|
},
|
|
160
226
|
subject: "Verify this email address",
|