@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
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The <meta name="robots"> half of the status page indexing opt-out, rendered
|
|
3
|
+
* from the real template.
|
|
4
|
+
*
|
|
5
|
+
* This is the channel that matters most: it is in the server-rendered HTML
|
|
6
|
+
* before the JS bundle loads, so it is what a crawler that does not run
|
|
7
|
+
* JavaScript sees. The X-Robots-Tag header that backs it up is asserted in
|
|
8
|
+
* App/Tests/StatusPage/SearchEngineIndexingResponses.test.ts.
|
|
9
|
+
*
|
|
10
|
+
* The template is read off disk rather than reproduced here, because the
|
|
11
|
+
* failure this guards against is someone editing index.ejs - a copy of the
|
|
12
|
+
* markup would keep passing while the shipped page lost its tag. It lives
|
|
13
|
+
* under Common/Tests because that is where the ejs types are installed;
|
|
14
|
+
* Common/Tests/App is the established home for tests that reach into App.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { JSONObject } from "../../../Types/JSON";
|
|
18
|
+
import { describe, expect, it } from "@jest/globals";
|
|
19
|
+
import ejs from "ejs";
|
|
20
|
+
import fs from "fs";
|
|
21
|
+
import path from "path";
|
|
22
|
+
|
|
23
|
+
const INDEX_TEMPLATE: string = path.join(
|
|
24
|
+
__dirname,
|
|
25
|
+
"..",
|
|
26
|
+
"..",
|
|
27
|
+
"..",
|
|
28
|
+
"..",
|
|
29
|
+
"App",
|
|
30
|
+
"FeatureSet",
|
|
31
|
+
"StatusPage",
|
|
32
|
+
"views",
|
|
33
|
+
"index.ejs",
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const NOINDEX_META: RegExp =
|
|
37
|
+
/<meta\s+name="robots"\s+content="noindex,\s*nofollow">/;
|
|
38
|
+
|
|
39
|
+
function renderIndexPage(variables: JSONObject): string {
|
|
40
|
+
return ejs.render(fs.readFileSync(INDEX_TEMPLATE, "utf8"), variables);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
describe("the status page index template", () => {
|
|
44
|
+
it("tells crawlers not to index when the owner turned indexing off", () => {
|
|
45
|
+
const html: string = renderIndexPage({
|
|
46
|
+
title: "Acme Status",
|
|
47
|
+
description: "How Acme is doing.",
|
|
48
|
+
isSearchEngineIndexingEnabled: false,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
expect(html).toMatch(NOINDEX_META);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("keeps the noindex tag inside <head>, where crawlers read it", () => {
|
|
55
|
+
const html: string = renderIndexPage({
|
|
56
|
+
title: "Acme Status",
|
|
57
|
+
isSearchEngineIndexingEnabled: false,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
const head: string = html.split("</head>")[0] || "";
|
|
61
|
+
expect(head).toMatch(NOINDEX_META);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("says nothing about robots when indexing is on", () => {
|
|
65
|
+
/*
|
|
66
|
+
* Not "emits index, follow". A crawler already assumes that, and emitting
|
|
67
|
+
* it would override a noindex an operator set on a proxy in front of
|
|
68
|
+
* OneUptime - the last robots instruction a crawler reads is the one that
|
|
69
|
+
* counts.
|
|
70
|
+
*/
|
|
71
|
+
const html: string = renderIndexPage({
|
|
72
|
+
title: "Acme Status",
|
|
73
|
+
description: "How Acme is doing.",
|
|
74
|
+
isSearchEngineIndexingEnabled: true,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
expect(html).not.toContain('name="robots"');
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it("says nothing about robots when the variable was never passed", () => {
|
|
81
|
+
/*
|
|
82
|
+
* The fallback render - a host that resolves to no status page - passes
|
|
83
|
+
* no flag at all, and must not throw on the missing variable either.
|
|
84
|
+
* That page is the generic placeholder and stays indexable, which is what
|
|
85
|
+
* shipped before this feature.
|
|
86
|
+
*/
|
|
87
|
+
const html: string = renderIndexPage({ title: "Status Page" });
|
|
88
|
+
|
|
89
|
+
expect(html).not.toContain('name="robots"');
|
|
90
|
+
expect(html).toContain("<title>Status Page</title>");
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it.each([
|
|
94
|
+
["a truthy non-boolean", "no"],
|
|
95
|
+
["null", null],
|
|
96
|
+
["zero", 0],
|
|
97
|
+
])(
|
|
98
|
+
"only an explicit false suppresses indexing, not %s",
|
|
99
|
+
(_label: string, value: unknown) => {
|
|
100
|
+
/*
|
|
101
|
+
* The template compares against false rather than testing falsiness, so
|
|
102
|
+
* a value arriving in an unexpected shape leaves the page indexable
|
|
103
|
+
* instead of silently de-indexing it.
|
|
104
|
+
*/
|
|
105
|
+
const html: string = renderIndexPage({
|
|
106
|
+
title: "Acme Status",
|
|
107
|
+
isSearchEngineIndexingEnabled: value,
|
|
108
|
+
} as JSONObject);
|
|
109
|
+
|
|
110
|
+
expect(html).not.toContain('name="robots"');
|
|
111
|
+
},
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
it("still renders the rest of the head when indexing is off", () => {
|
|
115
|
+
/*
|
|
116
|
+
* The opt-out must not cost the page its title, description or favicon -
|
|
117
|
+
* a page kept out of search results is still a page people read.
|
|
118
|
+
*/
|
|
119
|
+
const html: string = renderIndexPage({
|
|
120
|
+
title: "Acme Status",
|
|
121
|
+
description: "How Acme is doing.",
|
|
122
|
+
faviconUrl: "/status-page-api/favicon/acme",
|
|
123
|
+
isSearchEngineIndexingEnabled: false,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
expect(html).toContain("<title>Acme Status</title>");
|
|
127
|
+
expect(html).toContain('content="How Acme is doing."');
|
|
128
|
+
expect(html).toContain('href="/status-page-api/favicon/acme"');
|
|
129
|
+
});
|
|
130
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
2
|
+
import Incident from "../../../Models/DatabaseModels/Incident";
|
|
3
|
+
import IncidentSeverity from "../../../Models/DatabaseModels/IncidentSeverity";
|
|
4
|
+
import Label from "../../../Models/DatabaseModels/Label";
|
|
5
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
6
|
+
import Color from "../../../Types/Color";
|
|
7
|
+
import { JSONArray, JSONObject } from "../../../Types/JSON";
|
|
8
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
9
|
+
import { describe, expect, it } from "@jest/globals";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* toJSONObject reads table-column metadata off a cached, frozen, per-class
|
|
13
|
+
* vanilla instance instead of constructing one per row. These tests pin the
|
|
14
|
+
* contract that makes the cache safe: output is identical to a fresh
|
|
15
|
+
* construction, no state bleeds between rows or tenants, the cache is keyed
|
|
16
|
+
* on the declared modelType (not the instance's runtime class), and fromJSON
|
|
17
|
+
* still hands out a fresh mutable instance every call.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
describe("DatabaseBaseModel.toJSONObject with cached vanilla model", () => {
|
|
21
|
+
it("serializes a populated model with nested Entity and EntityArray columns", () => {
|
|
22
|
+
const severity: IncidentSeverity = new IncidentSeverity();
|
|
23
|
+
severity._id = "severity-id";
|
|
24
|
+
severity.name = "Critical";
|
|
25
|
+
|
|
26
|
+
const monitorOne: Monitor = new Monitor();
|
|
27
|
+
monitorOne._id = "monitor-one-id";
|
|
28
|
+
monitorOne.name = "Monitor One";
|
|
29
|
+
|
|
30
|
+
const monitorTwo: Monitor = new Monitor();
|
|
31
|
+
monitorTwo._id = "monitor-two-id";
|
|
32
|
+
monitorTwo.name = "Monitor Two";
|
|
33
|
+
|
|
34
|
+
const incident: Incident = new Incident();
|
|
35
|
+
incident._id = "incident-id";
|
|
36
|
+
incident.title = "Database is down";
|
|
37
|
+
incident.projectId = new ObjectID("project-one");
|
|
38
|
+
incident.incidentSeverity = severity;
|
|
39
|
+
incident.monitors = [monitorOne, monitorTwo];
|
|
40
|
+
|
|
41
|
+
const json: JSONObject = BaseModel.toJSONObject(incident, Incident);
|
|
42
|
+
|
|
43
|
+
expect(json["_id"]).toBe("incident-id");
|
|
44
|
+
expect(json["title"]).toBe("Database is down");
|
|
45
|
+
expect(json["projectId"]).toBe(incident.projectId);
|
|
46
|
+
|
|
47
|
+
// Nested Entity column is recursively serialized to a plain object.
|
|
48
|
+
const severityJson: JSONObject = json["incidentSeverity"] as JSONObject;
|
|
49
|
+
expect(severityJson).not.toBeInstanceOf(BaseModel);
|
|
50
|
+
expect(severityJson["_id"]).toBe("severity-id");
|
|
51
|
+
expect(severityJson["name"]).toBe("Critical");
|
|
52
|
+
|
|
53
|
+
// Nested EntityArray column is serialized item by item, order preserved.
|
|
54
|
+
const monitorsJson: JSONArray = json["monitors"] as JSONArray;
|
|
55
|
+
expect(Array.isArray(monitorsJson)).toBe(true);
|
|
56
|
+
expect(
|
|
57
|
+
monitorsJson.map((monitor: JSONObject | unknown) => {
|
|
58
|
+
expect(monitor).not.toBeInstanceOf(BaseModel);
|
|
59
|
+
return (monitor as JSONObject)["name"];
|
|
60
|
+
}),
|
|
61
|
+
).toEqual(["Monitor One", "Monitor Two"]);
|
|
62
|
+
|
|
63
|
+
// Unset columns are skipped entirely.
|
|
64
|
+
expect("description" in json).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("keeps each row's JSON isolated across repeated calls for the same class", () => {
|
|
68
|
+
const tenantOneProjectId: ObjectID = ObjectID.generate();
|
|
69
|
+
const tenantTwoProjectId: ObjectID = ObjectID.generate();
|
|
70
|
+
|
|
71
|
+
const tenantOneLabel: Label = new Label();
|
|
72
|
+
tenantOneLabel._id = "label-tenant-one";
|
|
73
|
+
tenantOneLabel.name = "Tenant One Label";
|
|
74
|
+
tenantOneLabel.projectId = tenantOneProjectId;
|
|
75
|
+
|
|
76
|
+
const tenantTwoLabel: Label = new Label();
|
|
77
|
+
tenantTwoLabel._id = "label-tenant-two";
|
|
78
|
+
tenantTwoLabel.name = "Tenant Two Label";
|
|
79
|
+
tenantTwoLabel.projectId = tenantTwoProjectId;
|
|
80
|
+
|
|
81
|
+
const jsonOne: JSONObject = BaseModel.toJSONObject(tenantOneLabel, Label);
|
|
82
|
+
const jsonTwo: JSONObject = BaseModel.toJSONObject(tenantTwoLabel, Label);
|
|
83
|
+
|
|
84
|
+
// Second serialization must not disturb the first result.
|
|
85
|
+
expect(jsonOne["_id"]).toBe("label-tenant-one");
|
|
86
|
+
expect(jsonOne["name"]).toBe("Tenant One Label");
|
|
87
|
+
expect(jsonOne["projectId"]).toBe(tenantOneProjectId);
|
|
88
|
+
|
|
89
|
+
expect(jsonTwo["_id"]).toBe("label-tenant-two");
|
|
90
|
+
expect(jsonTwo["name"]).toBe("Tenant Two Label");
|
|
91
|
+
expect(jsonTwo["projectId"]).toBe(tenantTwoProjectId);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("does not leak a key set on an earlier row into a later row without it", () => {
|
|
95
|
+
const labelWithColor: Label = new Label();
|
|
96
|
+
labelWithColor.name = "Colored";
|
|
97
|
+
labelWithColor.color = new Color("#112233");
|
|
98
|
+
|
|
99
|
+
const labelWithoutColor: Label = new Label();
|
|
100
|
+
labelWithoutColor.name = "Plain";
|
|
101
|
+
|
|
102
|
+
const jsonWithColor: JSONObject = BaseModel.toJSONObject(
|
|
103
|
+
labelWithColor,
|
|
104
|
+
Label,
|
|
105
|
+
);
|
|
106
|
+
const jsonWithoutColor: JSONObject = BaseModel.toJSONObject(
|
|
107
|
+
labelWithoutColor,
|
|
108
|
+
Label,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
expect(jsonWithColor["color"]).toBe(labelWithColor.color);
|
|
112
|
+
expect("color" in jsonWithoutColor).toBe(false);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it("serializes by the declared modelType, not the instance's runtime class", () => {
|
|
116
|
+
const label: Label = new Label();
|
|
117
|
+
label._id = "declared-type-label";
|
|
118
|
+
label.name = "Declared Type";
|
|
119
|
+
label.color = new Color("#445566");
|
|
120
|
+
label.projectId = ObjectID.generate();
|
|
121
|
+
|
|
122
|
+
/*
|
|
123
|
+
* Warm the subclass cache first so a cache wrongly keyed on
|
|
124
|
+
* model.constructor would surface Label columns below.
|
|
125
|
+
*/
|
|
126
|
+
BaseModel.toJSONObject(label, Label);
|
|
127
|
+
|
|
128
|
+
const baseJson: JSONObject = BaseModel.toJSONObject(label, BaseModel);
|
|
129
|
+
|
|
130
|
+
const baseColumns: Array<string> = new BaseModel().getTableColumns()
|
|
131
|
+
.columns;
|
|
132
|
+
for (const key of Object.keys(baseJson)) {
|
|
133
|
+
expect(baseColumns).toContain(key);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
expect(baseJson["_id"]).toBe("declared-type-label");
|
|
137
|
+
expect("color" in baseJson).toBe(false);
|
|
138
|
+
expect("projectId" in baseJson).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("toJSONObject on a fresh base model returns an empty object", () => {
|
|
142
|
+
const json: JSONObject = BaseModel.toJSONObject(new BaseModel(), BaseModel);
|
|
143
|
+
expect(json).toEqual({});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("fromJSON returns a fresh mutable instance on every call", () => {
|
|
147
|
+
const json: JSONObject = {
|
|
148
|
+
name: "oneuptime",
|
|
149
|
+
description: "a label",
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const first: Label = BaseModel.fromJSON(json, Label) as Label;
|
|
153
|
+
const second: Label = BaseModel.fromJSON(json, Label) as Label;
|
|
154
|
+
|
|
155
|
+
expect(first).toBeInstanceOf(Label);
|
|
156
|
+
expect(second).toBeInstanceOf(Label);
|
|
157
|
+
expect(first).not.toBe(second);
|
|
158
|
+
|
|
159
|
+
first.name = "mutated";
|
|
160
|
+
expect(second.name).toBe("oneuptime");
|
|
161
|
+
expect(second.description).toBe("a label");
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("toJSONObjectArray serializes every item correctly on the cache-hit path", () => {
|
|
165
|
+
const labels: Array<Label> = [1, 2, 3, 4].map((index: number) => {
|
|
166
|
+
const label: Label = new Label();
|
|
167
|
+
label._id = `label-${index}`;
|
|
168
|
+
label.name = `Label ${index}`;
|
|
169
|
+
return label;
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
const jsonArray: JSONArray = BaseModel.toJSONObjectArray(labels, Label);
|
|
173
|
+
|
|
174
|
+
expect(jsonArray).toHaveLength(4);
|
|
175
|
+
jsonArray.forEach((item: JSONObject | unknown, index: number) => {
|
|
176
|
+
expect((item as JSONObject)["_id"]).toBe(`label-${index + 1}`);
|
|
177
|
+
expect((item as JSONObject)["name"]).toBe(`Label ${index + 1}`);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StatusPage.enableSearchEngineIndexing column contract.
|
|
3
|
+
*
|
|
4
|
+
* The promise is "status pages stay indexable unless the owner turns indexing
|
|
5
|
+
* off". Three separate mechanisms carry that promise, and they are easy to
|
|
6
|
+
* confuse:
|
|
7
|
+
* - NEW rows get true from the Postgres column default, declared by
|
|
8
|
+
* @Column({ default: true }) and stored in TypeORM's metadata
|
|
9
|
+
* - EXISTING rows got true from the migration's NOT NULL DEFAULT true
|
|
10
|
+
* - @TableColumn({ defaultValue: true }) is documentation only - it feeds the
|
|
11
|
+
* generated API schema and form metadata, and defaults nothing at runtime
|
|
12
|
+
*
|
|
13
|
+
* All three are pinned below, because a one-word edit to any of them silently
|
|
14
|
+
* flips the default for everyone - and this is a default nobody notices going
|
|
15
|
+
* wrong until their status page has dropped out of Google.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import StatusPage from "../../Models/DatabaseModels/StatusPage";
|
|
19
|
+
import { TableColumnMetadata } from "../../Types/Database/TableColumn";
|
|
20
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
21
|
+
import Permission from "../../Types/Permission";
|
|
22
|
+
import { SEARCH_ENGINE_INDEXING_FLAG_NAME } from "../../Types/StatusPage/SearchEngineIndexing";
|
|
23
|
+
import { describe, expect, test } from "@jest/globals";
|
|
24
|
+
import { getMetadataArgsStorage } from "typeorm";
|
|
25
|
+
import { ColumnMetadataArgs } from "typeorm/metadata-args/ColumnMetadataArgs";
|
|
26
|
+
import fs from "fs";
|
|
27
|
+
import path from "path";
|
|
28
|
+
|
|
29
|
+
const COLUMN: string = "enableSearchEngineIndexing";
|
|
30
|
+
|
|
31
|
+
const MIGRATIONS_DIR: string = path.join(
|
|
32
|
+
__dirname,
|
|
33
|
+
"..",
|
|
34
|
+
"..",
|
|
35
|
+
"Server",
|
|
36
|
+
"Infrastructure",
|
|
37
|
+
"Postgres",
|
|
38
|
+
"SchemaMigrations",
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const MIGRATION_PATH: string = path.join(
|
|
42
|
+
MIGRATIONS_DIR,
|
|
43
|
+
"1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts",
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
function metadata(): TableColumnMetadata {
|
|
47
|
+
return new StatusPage().getTableColumnMetadata(COLUMN);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function typeOrmColumn(): ColumnMetadataArgs | undefined {
|
|
51
|
+
return getMetadataArgsStorage().columns.find((column: ColumnMetadataArgs) => {
|
|
52
|
+
return column.target === StatusPage && column.propertyName === COLUMN;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe("StatusPage.enableSearchEngineIndexing", () => {
|
|
57
|
+
test("exists as a boolean column", () => {
|
|
58
|
+
expect(metadata()).toBeDefined();
|
|
59
|
+
expect(metadata().type).toBe(TableColumnType.Boolean);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("is named exactly what the API and the template look for", () => {
|
|
63
|
+
expect(COLUMN).toBe(SEARCH_ENGINE_INDEXING_FLAG_NAME);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("a newly created status page is indexable", () => {
|
|
67
|
+
/*
|
|
68
|
+
* This is the assertion that actually protects new status pages: the
|
|
69
|
+
* Postgres column default. Nothing else populates the column when a
|
|
70
|
+
* create omits it, and every create in the product omits it.
|
|
71
|
+
*/
|
|
72
|
+
expect(typeOrmColumn()).toBeDefined();
|
|
73
|
+
expect(typeOrmColumn()?.options.default).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("the column is NOT NULL, so no row can be ambiguous", () => {
|
|
77
|
+
expect(typeOrmColumn()?.options.nullable).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("every pre-existing status page was backfilled as indexable", () => {
|
|
81
|
+
/*
|
|
82
|
+
* The migration is the only thing that decided the value for status pages
|
|
83
|
+
* that existed before this feature shipped. DEFAULT true in the same
|
|
84
|
+
* statement fills every existing row, so no page silently loses its search
|
|
85
|
+
* traffic on upgrade.
|
|
86
|
+
*/
|
|
87
|
+
const migration: string = fs.readFileSync(MIGRATION_PATH, "utf8");
|
|
88
|
+
|
|
89
|
+
expect(migration).toContain('ALTER TABLE "StatusPage"');
|
|
90
|
+
expect(migration).toContain(
|
|
91
|
+
`ADD "${COLUMN}" boolean NOT NULL DEFAULT true`,
|
|
92
|
+
);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test("the migration is registered, so it actually runs on boot", () => {
|
|
96
|
+
/*
|
|
97
|
+
* A migration file that is not in Index.ts is dead code: the column never
|
|
98
|
+
* appears in Postgres, and every read of it fails at runtime rather than
|
|
99
|
+
* at compile time.
|
|
100
|
+
*/
|
|
101
|
+
const index: string = fs.readFileSync(
|
|
102
|
+
path.join(MIGRATIONS_DIR, "Index.ts"),
|
|
103
|
+
"utf8",
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
expect(index).toContain(
|
|
107
|
+
"AddEnableSearchEngineIndexingToStatusPage1787500000000",
|
|
108
|
+
);
|
|
109
|
+
/* Imported AND listed in the exported array - the import alone does nothing. */
|
|
110
|
+
expect(
|
|
111
|
+
index.match(/AddEnableSearchEngineIndexingToStatusPage1787500000000/g)
|
|
112
|
+
?.length,
|
|
113
|
+
).toBeGreaterThanOrEqual(2);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test("is documented as defaulting to enabled", () => {
|
|
117
|
+
/*
|
|
118
|
+
* Feeds the generated API schema and the dashboard form metadata.
|
|
119
|
+
* Documentation only - see the tests above for the defaults that actually
|
|
120
|
+
* apply.
|
|
121
|
+
*/
|
|
122
|
+
expect(metadata().defaultValue).toBe(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("is a default-value column, so create may omit it", () => {
|
|
126
|
+
expect(new StatusPage().isDefaultValueColumn(COLUMN)).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("is not required, so existing create calls keep working", () => {
|
|
130
|
+
expect(metadata().required).toBeFalsy();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("is readable by status page viewers", () => {
|
|
134
|
+
const accessControl: Array<Permission> | undefined =
|
|
135
|
+
new StatusPage().getColumnAccessControlFor(COLUMN)?.read;
|
|
136
|
+
|
|
137
|
+
expect(accessControl).toContain(Permission.ProjectMember);
|
|
138
|
+
expect(accessControl).toContain(Permission.StatusPageAdmin);
|
|
139
|
+
expect(accessControl).toContain(Permission.ReadProjectStatusPage);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("is editable by status page editors", () => {
|
|
143
|
+
const accessControl: Array<Permission> | undefined =
|
|
144
|
+
new StatusPage().getColumnAccessControlFor(COLUMN)?.update;
|
|
145
|
+
|
|
146
|
+
expect(accessControl).toContain(Permission.EditProjectStatusPage);
|
|
147
|
+
expect(accessControl).toContain(Permission.StatusPageAdmin);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("is not editable by a read-only viewer", () => {
|
|
151
|
+
const accessControl: Array<Permission> | undefined =
|
|
152
|
+
new StatusPage().getColumnAccessControlFor(COLUMN)?.update;
|
|
153
|
+
|
|
154
|
+
expect(accessControl).not.toContain(Permission.Viewer);
|
|
155
|
+
expect(accessControl).not.toContain(Permission.StatusPageViewer);
|
|
156
|
+
});
|
|
157
|
+
});
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UserPush.isCriticalAlertEnabled column contract.
|
|
3
|
+
*
|
|
4
|
+
* This is the one stored preference in the product whose purpose is to DEFEAT
|
|
5
|
+
* a choice the user made with a physical switch on their phone. Everything
|
|
6
|
+
* below pins a property that, quietly changed, either wakes people who did not
|
|
7
|
+
* ask to be woken or - far worse for an on-call product - stops waking people
|
|
8
|
+
* who did.
|
|
9
|
+
*
|
|
10
|
+
* The three "default" mechanisms are separate and easy to confuse:
|
|
11
|
+
* - NEW rows get false from the Postgres column default (@Column default)
|
|
12
|
+
* - EXISTING rows got false from the migration's NOT NULL DEFAULT false
|
|
13
|
+
* - @TableColumn defaultValue is documentation for the generated API schema
|
|
14
|
+
* and forms; it defaults nothing at runtime
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
18
|
+
import { TableColumnMetadata } from "../../Types/Database/TableColumn";
|
|
19
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
20
|
+
import Permission from "../../Types/Permission";
|
|
21
|
+
import { describe, expect, test } from "@jest/globals";
|
|
22
|
+
import { getMetadataArgsStorage } from "typeorm";
|
|
23
|
+
import { ColumnMetadataArgs } from "typeorm/metadata-args/ColumnMetadataArgs";
|
|
24
|
+
import fs from "fs";
|
|
25
|
+
import path from "path";
|
|
26
|
+
|
|
27
|
+
const COLUMN: string = "isCriticalAlertEnabled";
|
|
28
|
+
|
|
29
|
+
const MIGRATIONS_DIR: string = path.join(
|
|
30
|
+
__dirname,
|
|
31
|
+
"..",
|
|
32
|
+
"..",
|
|
33
|
+
"Server",
|
|
34
|
+
"Infrastructure",
|
|
35
|
+
"Postgres",
|
|
36
|
+
"SchemaMigrations",
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const MIGRATION_CLASS: string = "MigrationName1787156982416";
|
|
40
|
+
|
|
41
|
+
const MIGRATION_PATH: string = path.join(
|
|
42
|
+
MIGRATIONS_DIR,
|
|
43
|
+
"1787156982416-MigrationName.ts",
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
function metadata(): TableColumnMetadata {
|
|
47
|
+
return new UserPush().getTableColumnMetadata(COLUMN);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function typeOrmColumn(): ColumnMetadataArgs | undefined {
|
|
51
|
+
return getMetadataArgsStorage().columns.find((column: ColumnMetadataArgs) => {
|
|
52
|
+
return column.target === UserPush && column.propertyName === COLUMN;
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe("UserPush.isCriticalAlertEnabled", () => {
|
|
57
|
+
test("exists as a boolean column", () => {
|
|
58
|
+
expect(metadata()).toBeDefined();
|
|
59
|
+
expect(metadata().type).toBe(TableColumnType.Boolean);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("a newly registered device does NOT override silent mode", () => {
|
|
63
|
+
/*
|
|
64
|
+
* The single most important assertion in this file. Overriding a silenced
|
|
65
|
+
* phone is opted into, never inherited: a responder who installs the app
|
|
66
|
+
* has not asked to be woken by it, and a default of true would make every
|
|
67
|
+
* existing user's phone start ringing through Do Not Disturb on upgrade.
|
|
68
|
+
*/
|
|
69
|
+
expect(typeOrmColumn()).toBeDefined();
|
|
70
|
+
expect(typeOrmColumn()?.options.default).toBe(false);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("every device that existed before this feature was backfilled as off", () => {
|
|
74
|
+
const migration: string = fs.readFileSync(MIGRATION_PATH, "utf8");
|
|
75
|
+
|
|
76
|
+
expect(migration).toContain('ALTER TABLE "UserPush"');
|
|
77
|
+
expect(migration).toContain(
|
|
78
|
+
`ADD "${COLUMN}" boolean NOT NULL DEFAULT false`,
|
|
79
|
+
);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test("the migration is registered, so the column actually exists at runtime", () => {
|
|
83
|
+
/*
|
|
84
|
+
* A migration file missing from Index.ts never runs. The column would then
|
|
85
|
+
* be absent from Postgres while every select in the paging path asks for
|
|
86
|
+
* it, which fails the query that sends the page.
|
|
87
|
+
*/
|
|
88
|
+
const index: string = fs.readFileSync(
|
|
89
|
+
path.join(MIGRATIONS_DIR, "Index.ts"),
|
|
90
|
+
"utf8",
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
// Imported AND listed in the exported array - the import alone does nothing.
|
|
94
|
+
expect(index.match(new RegExp(MIGRATION_CLASS, "g"))?.length).toBe(2);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("the migration's down() removes the column", () => {
|
|
98
|
+
const migration: string = fs.readFileSync(MIGRATION_PATH, "utf8");
|
|
99
|
+
|
|
100
|
+
expect(migration).toContain(
|
|
101
|
+
`ALTER TABLE "UserPush" DROP COLUMN "${COLUMN}"`,
|
|
102
|
+
);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("is a default-value column, so existing create calls keep working", () => {
|
|
106
|
+
expect(new UserPush().isDefaultValueColumn(COLUMN)).toBe(true);
|
|
107
|
+
expect(metadata().required).toBeFalsy();
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("is documented as defaulting to off", () => {
|
|
111
|
+
expect(metadata().defaultValue).toBe(false);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe("UserPush.isCriticalAlertEnabled access control", () => {
|
|
116
|
+
/*
|
|
117
|
+
* UserPush is an owner-only table: its table-level `read` names
|
|
118
|
+
* Permission.CurrentUser and nothing else, which is what scopes every read
|
|
119
|
+
* to the caller's own rows. A new column has to keep that shape or it
|
|
120
|
+
* becomes the exception that widens the table.
|
|
121
|
+
*/
|
|
122
|
+
test("is readable only by the responder it belongs to", () => {
|
|
123
|
+
const read: Array<Permission> | undefined =
|
|
124
|
+
new UserPush().getColumnAccessControlFor(COLUMN)?.read;
|
|
125
|
+
|
|
126
|
+
expect(read).toEqual([Permission.CurrentUser]);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("is settable at registration by the responder", () => {
|
|
130
|
+
const create: Array<Permission> | undefined =
|
|
131
|
+
new UserPush().getColumnAccessControlFor(COLUMN)?.create;
|
|
132
|
+
|
|
133
|
+
expect(create).toEqual([Permission.CurrentUser]);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
test("cannot be written through the generic CRUD update surface", () => {
|
|
137
|
+
/*
|
|
138
|
+
* Every column on this model has an empty update list; writes go through
|
|
139
|
+
* the dedicated routes that check row ownership first and then act as
|
|
140
|
+
* root. Granting update here would let the flag be flipped by any path
|
|
141
|
+
* that can PUT the model, which is a wider surface than "the phone that
|
|
142
|
+
* owns this row".
|
|
143
|
+
*/
|
|
144
|
+
const update: Array<Permission> | undefined =
|
|
145
|
+
new UserPush().getColumnAccessControlFor(COLUMN)?.update;
|
|
146
|
+
|
|
147
|
+
expect(update).toEqual([]);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
test("does not widen the table's owner-only read scope", () => {
|
|
151
|
+
/*
|
|
152
|
+
* isAccessGrantedOnlyByCurrentUser is true exactly while the TABLE read
|
|
153
|
+
* list holds nothing but CurrentUser, and that is what stamps
|
|
154
|
+
* `userId = me` onto every read of this table. Adding a column must not
|
|
155
|
+
* disturb it.
|
|
156
|
+
*/
|
|
157
|
+
expect(new UserPush().getReadPermissions()).toEqual([
|
|
158
|
+
Permission.CurrentUser,
|
|
159
|
+
]);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("is not marked readable through relation queries", () => {
|
|
163
|
+
/*
|
|
164
|
+
* canReadOnRelationQuery makes a column readable from a nested select on a
|
|
165
|
+
* model whose own read is admin-wide, skipping this table's column check
|
|
166
|
+
* entirely. isVerified - the column this one sits beside and is read
|
|
167
|
+
* alongside - does not set it, and neither does this: the paging path
|
|
168
|
+
* reads both as root, so nothing needs the flag.
|
|
169
|
+
*/
|
|
170
|
+
expect(metadata().canReadOnRelationQuery).toBeFalsy();
|
|
171
|
+
});
|
|
172
|
+
});
|
|
@@ -26,6 +26,7 @@ import AIRunStatus from "../../../Types/AI/AIRunStatus";
|
|
|
26
26
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
27
27
|
import { JSONObject } from "../../../Types/JSON";
|
|
28
28
|
import ObjectID from "../../../Types/ObjectID";
|
|
29
|
+
import Permission from "../../../Types/Permission";
|
|
29
30
|
import {
|
|
30
31
|
afterEach,
|
|
31
32
|
beforeEach,
|
|
@@ -61,10 +62,31 @@ const MESSAGE_ID: ObjectID = new ObjectID(
|
|
|
61
62
|
"eeeeeeee-eeee-4eee-8eee-eeeeeeeeeeee",
|
|
62
63
|
);
|
|
63
64
|
|
|
65
|
+
/*
|
|
66
|
+
* A real member of PROJECT_ID. The tenant access permission entry is not
|
|
67
|
+
* decoration: every AI chat route asserts membership of the project named in
|
|
68
|
+
* the `tenantid` header (CommonAPI.assertAuthenticatedProjectMember), so props
|
|
69
|
+
* carrying only a user id and a tenant id are exactly what an outsider sends
|
|
70
|
+
* and are refused before the handler does anything. AIChatRouteAuthorization
|
|
71
|
+
* covers that refusal; these tests are about what a legitimate member gets.
|
|
72
|
+
*/
|
|
64
73
|
const props: DatabaseCommonInteractionProps = {
|
|
65
74
|
userId: USER_ID,
|
|
66
75
|
tenantId: PROJECT_ID,
|
|
67
|
-
|
|
76
|
+
userTenantAccessPermission: {
|
|
77
|
+
[PROJECT_ID.toString()]: {
|
|
78
|
+
_type: "UserTenantAccessPermission",
|
|
79
|
+
projectId: PROJECT_ID,
|
|
80
|
+
permissions: [
|
|
81
|
+
{
|
|
82
|
+
_type: "UserPermission",
|
|
83
|
+
permission: Permission.ProjectMember,
|
|
84
|
+
labelIds: [],
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
} as unknown as DatabaseCommonInteractionProps;
|
|
68
90
|
|
|
69
91
|
function requestFor(body: JSONObject): ExpressRequest {
|
|
70
92
|
return {
|