@oneuptime/common 12.0.13 → 12.0.15
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/GlobalOidc.ts +20 -0
- package/Models/DatabaseModels/GlobalSso.ts +20 -0
- package/Models/DatabaseModels/MarketingConversion.ts +19 -9
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
- package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
- package/Models/DatabaseModels/StatusPage.ts +7 -4
- package/Models/DatabaseModels/UserCall.ts +94 -3
- package/Models/DatabaseModels/UserEmail.ts +94 -3
- package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
- package/Models/DatabaseModels/UserPush.ts +37 -0
- package/Models/DatabaseModels/UserSMS.ts +94 -3
- package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
- package/Server/API/BaseAPI.ts +79 -14
- package/Server/API/StatusPageAPI.ts +29 -4
- 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/EnvironmentConfig.ts +7 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/SlackAuthorization.ts +43 -6
- package/Server/Middleware/UserAuthorization.ts +236 -26
- package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
- package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
- package/Server/Services/AnalyticsDatabaseService.ts +169 -0
- package/Server/Services/DatabaseService.ts +101 -0
- package/Server/Services/GlobalOidcProjectService.ts +126 -1
- package/Server/Services/GlobalOidcService.ts +132 -0
- package/Server/Services/GlobalSsoProjectService.ts +126 -1
- package/Server/Services/GlobalSsoService.ts +132 -0
- package/Server/Services/LogAggregationService.ts +5 -0
- package/Server/Services/PushNotificationService.ts +127 -12
- package/Server/Services/TeamMemberService.ts +53 -13
- package/Server/Services/UserCallService.ts +55 -24
- package/Server/Services/UserEmailService.ts +83 -17
- package/Server/Services/UserIncomingCallNumberService.ts +49 -85
- package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
- package/Server/Services/UserNotificationRuleService.ts +26 -0
- package/Server/Services/UserPushService.ts +89 -0
- package/Server/Services/UserSmsService.ts +50 -17
- package/Server/Services/UserWhatsAppService.ts +48 -15
- package/Server/Types/Database/QueryHelper.ts +30 -0
- package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
- package/Server/Utils/ChannelVerification.ts +510 -0
- package/Server/Utils/CronTab.ts +73 -0
- package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
- package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
- package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
- package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
- package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
- package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +47 -44
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
- package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
- package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
- package/Server/Utils/Monitor/MonitorResource.ts +161 -21
- package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
- package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
- package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
- package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
- package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
- package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
- package/Server/Utils/TotpAuth.ts +137 -9
- package/Server/Utils/UserRegistrationToken.ts +182 -0
- package/Server/Utils/VerificationCode.ts +134 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
- package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
- package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
- package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
- package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
- package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
- package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
- package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
- package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
- package/Tests/Server/API/UserSmsApi.test.ts +107 -14
- package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
- package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +265 -0
- package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
- package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
- package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
- package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
- package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
- package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
- package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
- package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
- package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
- package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
- package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
- package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
- package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
- package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
- package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
- package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
- package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
- package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
- package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
- package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
- package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
- package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
- package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -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/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
- package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
- package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
- package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
- package/Tests/Server/Utils/Browser.test.ts +162 -0
- package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
- package/Tests/Server/Utils/CronTab.test.ts +116 -0
- package/Tests/Server/Utils/Express.test.ts +371 -0
- package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
- package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
- 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/EvaluateOverTime.test.ts +987 -0
- package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -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/ProfileMonitorCriteria.test.ts +382 -0
- package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
- package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
- package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
- package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
- package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
- package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
- package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
- package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
- package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
- package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
- package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
- package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
- package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
- package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
- package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
- package/Tests/Types/Call/CallRequest.test.ts +189 -0
- package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
- package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
- package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
- package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
- package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -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/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
- package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
- package/Tests/Types/TextRandomGeneration.test.ts +211 -0
- package/Tests/UI/Components/Button.test.tsx +175 -1
- package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
- package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
- package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
- package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
- package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
- package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
- package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
- package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
- package/Tests/UI/Components/List.test.tsx +9 -2
- package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
- package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
- package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
- package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
- package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
- package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
- package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
- package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
- package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
- package/Tests/UI/Components/Skeleton.test.tsx +71 -0
- package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
- package/Tests/UI/Components/Tabs.test.tsx +24 -0
- package/Tests/UI/Components/Toast.test.tsx +130 -7
- package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
- package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
- package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -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/Analytics.test.ts +187 -0
- 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 +80 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
- package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
- package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
- package/Types/Email/EmailTemplateType.ts +1 -0
- package/Types/Marketing/MarketingConversion.ts +12 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
- package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
- package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
- package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
- package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
- package/Types/Permission.ts +35 -0
- package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
- package/Types/PushNotification/PushNotificationMessage.ts +15 -0
- package/Types/PushNotification/PushNotificationRequest.ts +8 -16
- package/Types/Service/ServiceLanguage.ts +144 -0
- package/Types/Text.ts +111 -19
- package/UI/Components/Button/Button.tsx +27 -14
- package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
- package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
- package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
- package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
- package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
- package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
- package/UI/Components/CommandPalette/Types.ts +49 -0
- package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
- package/UI/Components/Dropdown/Dropdown.tsx +6 -1
- package/UI/Components/Feed/FeedItem.tsx +1 -1
- package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
- package/UI/Components/Forms/BasicForm.tsx +13 -1
- package/UI/Components/Forms/BasicModelForm.tsx +2 -1
- package/UI/Components/Forms/ModelForm.tsx +10 -1
- package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
- package/UI/Components/List/List.tsx +37 -5
- package/UI/Components/List/ListSkeleton.tsx +54 -0
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
- package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
- package/UI/Components/Modal/Modal.tsx +2 -2
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
- 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/Analytics.ts +55 -2
- package/Utils/Monitor/MonitorMetricType.ts +40 -0
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
- package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
- package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.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 +4 -4
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
- package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Server/API/BaseAPI.js +69 -13
- package/build/dist/Server/API/BaseAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +25 -4
- package/build/dist/Server/API/StatusPageAPI.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/EnvironmentConfig.js +6 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.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/SlackAuthorization.js +28 -4
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
- 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/Middleware/WhatsAppAuthorization.js +32 -2
- package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +74 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalOidcService.js +127 -0
- package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
- package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
- package/build/dist/Server/Services/GlobalSsoService.js +127 -0
- package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +5 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +69 -30
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +43 -7
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +54 -22
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +78 -17
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
- package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +77 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +50 -17
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
- package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
- package/build/dist/Server/Utils/ChannelVerification.js +348 -0
- package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
- package/build/dist/Server/Utils/CronTab.js +66 -0
- package/build/dist/Server/Utils/CronTab.js.map +1 -1
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
- package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
- package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +34 -37
- package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
- package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.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/MonitorCriteriaEvaluator.js +8 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.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 +123 -23
- 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/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/StatusPageContentSecurityPolicy.js +39 -0
- package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
- package/build/dist/Server/Utils/StatusPageCustomizationAccess.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/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
- package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
- package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
- package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
- package/build/dist/Types/Permission.js +33 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
- package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
- package/build/dist/Types/Service/ServiceLanguage.js +96 -0
- package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
- package/build/dist/Types/Text.js +82 -17
- package/build/dist/Types/Text.js.map +1 -1
- package/build/dist/UI/Components/Button/Button.js +22 -14
- package/build/dist/UI/Components/Button/Button.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
- package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
- package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
- package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
- package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
- package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
- package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
- package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
- package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
- package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
- package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
- package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
- package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
- package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
- package/build/dist/UI/Components/List/List.js +19 -5
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
- package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
- package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +2 -2
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- 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/Analytics.js +50 -2
- package/build/dist/Utils/Analytics.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
- package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
- package/jest.config.json +1 -1
- package/package.json +2 -3
- package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
- package/Tests/__mocks__/otpauth.js +0 -30
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
- package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import UserCall from "../../../../../Models/DatabaseModels/UserCall";
|
|
2
|
+
import UserEmail from "../../../../../Models/DatabaseModels/UserEmail";
|
|
3
|
+
import UserIncomingCallNumber from "../../../../../Models/DatabaseModels/UserIncomingCallNumber";
|
|
4
|
+
import UserSMS from "../../../../../Models/DatabaseModels/UserSMS";
|
|
5
|
+
import UserWhatsApp from "../../../../../Models/DatabaseModels/UserWhatsApp";
|
|
6
|
+
import BaseModel from "../../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
7
|
+
import { ColumnAccessControl } from "../../../../../Types/BaseDatabase/AccessControl";
|
|
8
|
+
import { TableColumnMetadata } from "../../../../../Types/Database/TableColumn";
|
|
9
|
+
import { describe, expect, it } from "@jest/globals";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* GHSA-5cr8-vph4-3hrf, the parts of the fix that live in model metadata
|
|
13
|
+
* rather than in code.
|
|
14
|
+
*
|
|
15
|
+
* Two properties, both of which a later well-meaning edit could remove
|
|
16
|
+
* without breaking a single functional test:
|
|
17
|
+
*
|
|
18
|
+
* 1. THE IDENTITY IS IMMUTABLE. The advisory's remediation list ends with
|
|
19
|
+
* "invalidate outstanding codes when contact details change". There is no
|
|
20
|
+
* such code path here, and that is not an oversight — the address or number
|
|
21
|
+
* on a channel row cannot be changed at all, because its column grants
|
|
22
|
+
* nobody update. A code is therefore bound to the contact detail it was
|
|
23
|
+
* sent to for the whole life of the row. Make one of these columns
|
|
24
|
+
* updatable and that stops being true: a caller verifies their own address,
|
|
25
|
+
* then rewrites the row to point at somebody else's, and arrives at a
|
|
26
|
+
* verified channel they do not own.
|
|
27
|
+
*
|
|
28
|
+
* 2. THE VERIFICATION STATE IS NOT WRITABLE BY THE CALLER. isVerified, the
|
|
29
|
+
* stored digest, its expiry and the attempt counter are all server-owned.
|
|
30
|
+
* A caller who could write any of them would not need to guess a code:
|
|
31
|
+
* they could set isVerified directly, or push the expiry out, or reset the
|
|
32
|
+
* attempt counter between guesses and never hit the limit.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
interface ChannelUnderTest {
|
|
36
|
+
name: string;
|
|
37
|
+
model: BaseModel;
|
|
38
|
+
identityColumn: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const CHANNELS: Array<ChannelUnderTest> = [
|
|
42
|
+
{ name: "UserEmail", model: new UserEmail(), identityColumn: "email" },
|
|
43
|
+
{ name: "UserSMS", model: new UserSMS(), identityColumn: "phone" },
|
|
44
|
+
{ name: "UserCall", model: new UserCall(), identityColumn: "phone" },
|
|
45
|
+
{ name: "UserWhatsApp", model: new UserWhatsApp(), identityColumn: "phone" },
|
|
46
|
+
{
|
|
47
|
+
name: "UserIncomingCallNumber",
|
|
48
|
+
model: new UserIncomingCallNumber(),
|
|
49
|
+
identityColumn: "phone",
|
|
50
|
+
},
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
/* Server-owned: writable by nobody through the API, at any point. */
|
|
54
|
+
const SERVER_OWNED_COLUMNS: Array<string> = [
|
|
55
|
+
"isVerified",
|
|
56
|
+
"verificationCode",
|
|
57
|
+
"verificationCodeExpiresAt",
|
|
58
|
+
"verificationFailedAttempts",
|
|
59
|
+
"verificationCodeSentAt",
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
describe.each(CHANNELS)(
|
|
63
|
+
"$name verification column metadata",
|
|
64
|
+
(channel: ChannelUnderTest) => {
|
|
65
|
+
const accessControlFor: (columnName: string) => ColumnAccessControl = (
|
|
66
|
+
columnName: string,
|
|
67
|
+
) => {
|
|
68
|
+
const accessControl: ColumnAccessControl | null =
|
|
69
|
+
channel.model.getColumnAccessControlFor(columnName);
|
|
70
|
+
|
|
71
|
+
expect(accessControl).not.toBeNull();
|
|
72
|
+
|
|
73
|
+
return accessControl as ColumnAccessControl;
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
it("does not let anybody change the address or number after creation", () => {
|
|
77
|
+
expect(accessControlFor(channel.identityColumn).update).toEqual([]);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it.each(SERVER_OWNED_COLUMNS)(
|
|
81
|
+
"does not let anybody create or update %s",
|
|
82
|
+
(columnName: string) => {
|
|
83
|
+
const accessControl: ColumnAccessControl = accessControlFor(columnName);
|
|
84
|
+
|
|
85
|
+
expect(accessControl.create).toEqual([]);
|
|
86
|
+
expect(accessControl.update).toEqual([]);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
it.each([
|
|
91
|
+
"verificationCode",
|
|
92
|
+
"verificationCodeExpiresAt",
|
|
93
|
+
"verificationFailedAttempts",
|
|
94
|
+
"verificationCodeSentAt",
|
|
95
|
+
])("does not expose %s to any reader", (columnName: string) => {
|
|
96
|
+
expect(accessControlFor(columnName).read).toEqual([]);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
* The row is born with a placeholder no six-digit code can hash to; the
|
|
101
|
+
* real code is issued by the service once the insert has assigned an id,
|
|
102
|
+
* because the id is part of the hashed message. A default that produced
|
|
103
|
+
* something SHORT would be a live guessable code sitting on every new row
|
|
104
|
+
* for the moment before the service overwrote it.
|
|
105
|
+
*/
|
|
106
|
+
it("defaults verificationCode to a value no code can hash to", () => {
|
|
107
|
+
const metadata: TableColumnMetadata =
|
|
108
|
+
channel.model.getTableColumnMetadata("verificationCode");
|
|
109
|
+
|
|
110
|
+
expect(metadata.forceGetDefaultValueOnCreate).toBeDefined();
|
|
111
|
+
|
|
112
|
+
const generated: string = (
|
|
113
|
+
metadata.forceGetDefaultValueOnCreate as () => string
|
|
114
|
+
)();
|
|
115
|
+
|
|
116
|
+
expect(generated).toHaveLength(64);
|
|
117
|
+
expect(generated).not.toMatch(/^[0-9]{1,10}$/);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("generates a different placeholder for every row", () => {
|
|
121
|
+
const metadata: TableColumnMetadata =
|
|
122
|
+
channel.model.getTableColumnMetadata("verificationCode");
|
|
123
|
+
|
|
124
|
+
const generated: Set<string> = new Set<string>();
|
|
125
|
+
|
|
126
|
+
for (let i: number = 0; i < 50; i++) {
|
|
127
|
+
generated.add(
|
|
128
|
+
(metadata.forceGetDefaultValueOnCreate as () => string)(),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
expect(generated.size).toBe(50);
|
|
133
|
+
});
|
|
134
|
+
},
|
|
135
|
+
);
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
import DatabaseRequestType from "../../../../../Server/Types/BaseDatabase/DatabaseRequestType";
|
|
2
|
+
import AccessControlPermission from "../../../../../Server/Types/Database/Permissions/AccessControlPermission";
|
|
3
|
+
import BasePermission from "../../../../../Server/Types/Database/Permissions/BasePermission";
|
|
4
|
+
import OwnedScopePermission from "../../../../../Server/Types/Database/Permissions/OwnedScopePermission";
|
|
5
|
+
import PublicPermission from "../../../../../Server/Types/Database/Permissions/PublicPermission";
|
|
6
|
+
import QueryPermission from "../../../../../Server/Types/Database/Permissions/QueryPermission";
|
|
7
|
+
import SelectPermission from "../../../../../Server/Types/Database/Permissions/SelectPermission";
|
|
8
|
+
import TablePermission from "../../../../../Server/Types/Database/Permissions/TablePermission";
|
|
9
|
+
import TenantPermission from "../../../../../Server/Types/Database/Permissions/TenantPermission";
|
|
10
|
+
import UserPermissions from "../../../../../Server/Types/Database/Permissions/UserPermission";
|
|
11
|
+
import Query from "../../../../../Server/Types/Database/Query";
|
|
12
|
+
import Select from "../../../../../Server/Types/Database/Select";
|
|
13
|
+
import OnCallDutyPolicyEscalationRuleSchedule from "../../../../../Models/DatabaseModels/OnCallDutyPolicyEscalationRuleSchedule";
|
|
14
|
+
import OnCallDutyPolicySchedule from "../../../../../Models/DatabaseModels/OnCallDutyPolicySchedule";
|
|
15
|
+
import BaseModel from "../../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
16
|
+
import DatabaseCommonInteractionProps from "../../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
17
|
+
import { isOwnerOnlyColumn } from "../../../../../Types/Database/AccessControl/OwnerOnlyColumn";
|
|
18
|
+
import { TableColumnMetadata } from "../../../../../Types/Database/TableColumn";
|
|
19
|
+
import TableColumnType from "../../../../../Types/Database/TableColumnType";
|
|
20
|
+
import BadDataException from "../../../../../Types/Exception/BadDataException";
|
|
21
|
+
import NotAuthorizedException from "../../../../../Types/Exception/NotAuthorizedException";
|
|
22
|
+
import ObjectID from "../../../../../Types/ObjectID";
|
|
23
|
+
import Permission from "../../../../../Types/Permission";
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
* THE BUG.
|
|
27
|
+
*
|
|
28
|
+
* Opening a policy's escalation rules failed outright with
|
|
29
|
+
*
|
|
30
|
+
* Column currentUserIdOnRoster on On-Call Policy Schedule does not
|
|
31
|
+
* support read on relation query.
|
|
32
|
+
*
|
|
33
|
+
* The escalation rule page lists the schedules attached to each rule and marks
|
|
34
|
+
* the ones that would currently page nobody. It reads that state off the join:
|
|
35
|
+
*
|
|
36
|
+
* modelType: OnCallDutyPolicyEscalationRuleSchedule
|
|
37
|
+
* select: { onCallDutyPolicySchedule: { name, currentUserIdOnRoster } }
|
|
38
|
+
*
|
|
39
|
+
* `name` carries canReadOnRelationQuery. `currentUserIdOnRoster` did not, and
|
|
40
|
+
* QueryPermission.checkRelationQueryPermission THROWS on the first unflagged
|
|
41
|
+
* inner key rather than dropping that key from the select - so the one missing
|
|
42
|
+
* flag failed the entire request, and the page rendered nothing at all. Every
|
|
43
|
+
* caller hit it, up to and including ProjectOwner, which is why deleting the
|
|
44
|
+
* schedule and re-creating it changed nothing: no row was ever the problem.
|
|
45
|
+
*
|
|
46
|
+
* WHAT THESE TESTS PIN.
|
|
47
|
+
*
|
|
48
|
+
* The two select shapes the UI actually sends, verbatim, so a select edited in
|
|
49
|
+
* the components without a matching model flag fails here (first describe).
|
|
50
|
+
* That the flag is the only thing that moved - the sibling columns on the same
|
|
51
|
+
* model, deep relations and unknown columns all still refuse, and a direct
|
|
52
|
+
* non-relation read is still governed by column permissions (third and fourth
|
|
53
|
+
* describes). And the deliberate cost of the flag, stated rather than skipped
|
|
54
|
+
* over: it bypasses the related column's own read list, exactly as `name`
|
|
55
|
+
* already did (fifth describe).
|
|
56
|
+
*/
|
|
57
|
+
|
|
58
|
+
const projectId: ObjectID = ObjectID.generate();
|
|
59
|
+
const userId: ObjectID = ObjectID.generate();
|
|
60
|
+
|
|
61
|
+
/*
|
|
62
|
+
* Fresh props per assertion: DatabaseCommonInteractionPropsUtil MUTATES what it
|
|
63
|
+
* is handed, pushing the auto-granted Public and CurrentUser onto the list, so
|
|
64
|
+
* a shared object carries state between tests.
|
|
65
|
+
*/
|
|
66
|
+
function makeProps(
|
|
67
|
+
permissions: Array<Permission>,
|
|
68
|
+
): DatabaseCommonInteractionProps {
|
|
69
|
+
return {
|
|
70
|
+
userId: userId,
|
|
71
|
+
tenantId: projectId,
|
|
72
|
+
userTenantAccessPermission: {
|
|
73
|
+
[projectId.toString()]: {
|
|
74
|
+
projectId: projectId,
|
|
75
|
+
permissions: permissions.map((permission: Permission) => {
|
|
76
|
+
return {
|
|
77
|
+
permission: permission,
|
|
78
|
+
labelIds: [],
|
|
79
|
+
isBlockPermission: false,
|
|
80
|
+
_type: "UserPermission" as const,
|
|
81
|
+
};
|
|
82
|
+
}),
|
|
83
|
+
_type: "UserTenantAccessPermission",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function checkRelationSelect(
|
|
90
|
+
select: Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
91
|
+
props: DatabaseCommonInteractionProps,
|
|
92
|
+
): void {
|
|
93
|
+
QueryPermission.checkRelationQueryPermission(
|
|
94
|
+
OnCallDutyPolicyEscalationRuleSchedule,
|
|
95
|
+
{} as Query<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
96
|
+
select,
|
|
97
|
+
props,
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/*
|
|
102
|
+
* The select copied out of
|
|
103
|
+
* App/FeatureSet/Dashboard/src/Components/OnCallPolicy/EscalationRule/EscalationRules.tsx.
|
|
104
|
+
* Kept as a literal rather than imported so that changing the component
|
|
105
|
+
* without changing the model surfaces here as a failure.
|
|
106
|
+
*/
|
|
107
|
+
const ESCALATION_RULES_SELECT: Select<OnCallDutyPolicyEscalationRuleSchedule> =
|
|
108
|
+
{
|
|
109
|
+
_id: true,
|
|
110
|
+
onCallDutyPolicyEscalationRuleId: true,
|
|
111
|
+
onCallDutyPolicySchedule: {
|
|
112
|
+
_id: true,
|
|
113
|
+
name: true,
|
|
114
|
+
currentUserIdOnRoster: true,
|
|
115
|
+
},
|
|
116
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>;
|
|
117
|
+
|
|
118
|
+
/*
|
|
119
|
+
* The select copied out of
|
|
120
|
+
* App/FeatureSet/Dashboard/src/Components/OnCallPolicy/OnCallPolicySummary.tsx.
|
|
121
|
+
*/
|
|
122
|
+
const POLICY_SUMMARY_SELECT: Select<OnCallDutyPolicyEscalationRuleSchedule> = {
|
|
123
|
+
_id: true,
|
|
124
|
+
onCallDutyPolicyEscalationRuleId: true,
|
|
125
|
+
onCallDutyPolicySchedule: {
|
|
126
|
+
_id: true,
|
|
127
|
+
name: true,
|
|
128
|
+
currentUserIdOnRoster: true,
|
|
129
|
+
},
|
|
130
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>;
|
|
131
|
+
|
|
132
|
+
describe("On-call schedule relation select - the reported failure", () => {
|
|
133
|
+
it("accepts the escalation rules page select", () => {
|
|
134
|
+
expect(() => {
|
|
135
|
+
return checkRelationSelect(
|
|
136
|
+
ESCALATION_RULES_SELECT,
|
|
137
|
+
makeProps([Permission.ProjectOwner]),
|
|
138
|
+
);
|
|
139
|
+
}).not.toThrow();
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("accepts the policy summary select", () => {
|
|
143
|
+
expect(() => {
|
|
144
|
+
return checkRelationSelect(
|
|
145
|
+
POLICY_SUMMARY_SELECT,
|
|
146
|
+
makeProps([Permission.ProjectOwner]),
|
|
147
|
+
);
|
|
148
|
+
}).not.toThrow();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("no longer raises the reported message for any caller", () => {
|
|
152
|
+
/*
|
|
153
|
+
* The reporter was a project owner and re-created the schedule twice. The
|
|
154
|
+
* throw was in the permission layer and had nothing to do with the row, so
|
|
155
|
+
* pin it across the whole read list rather than for one role.
|
|
156
|
+
*/
|
|
157
|
+
const readers: Array<Permission> = [
|
|
158
|
+
Permission.ProjectOwner,
|
|
159
|
+
Permission.ProjectAdmin,
|
|
160
|
+
Permission.ProjectMember,
|
|
161
|
+
Permission.Viewer,
|
|
162
|
+
Permission.OnCallAdmin,
|
|
163
|
+
Permission.OnCallMember,
|
|
164
|
+
Permission.OnCallViewer,
|
|
165
|
+
Permission.ReadProjectOnCallDutyPolicyEscalationRuleSchedule,
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
for (const permission of readers) {
|
|
169
|
+
expect(() => {
|
|
170
|
+
return checkRelationSelect(
|
|
171
|
+
ESCALATION_RULES_SELECT,
|
|
172
|
+
makeProps([permission]),
|
|
173
|
+
);
|
|
174
|
+
}).not.toThrow();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("accepts the roster column selected on its own", () => {
|
|
179
|
+
// Without `name` alongside it, in case the component drops the label later.
|
|
180
|
+
expect(() => {
|
|
181
|
+
return checkRelationSelect(
|
|
182
|
+
{
|
|
183
|
+
onCallDutyPolicySchedule: {
|
|
184
|
+
currentUserIdOnRoster: true,
|
|
185
|
+
},
|
|
186
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
187
|
+
makeProps([Permission.ProjectMember]),
|
|
188
|
+
);
|
|
189
|
+
}).not.toThrow();
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
describe("On-call schedule relation select - through the full permission stack", () => {
|
|
194
|
+
/*
|
|
195
|
+
* checkRelationQueryPermission is one of several gates BasePermission runs
|
|
196
|
+
* over a read, and the escalation rule page reaches it through all of them.
|
|
197
|
+
* Tenant and user scoping need a database, so they are stubbed; every
|
|
198
|
+
* permission gate on the select path is left real.
|
|
199
|
+
*/
|
|
200
|
+
beforeEach(() => {
|
|
201
|
+
jest
|
|
202
|
+
.spyOn(PublicPermission, "checkIfUserIsLoggedIn")
|
|
203
|
+
.mockImplementation(() => {});
|
|
204
|
+
jest
|
|
205
|
+
.spyOn(TenantPermission, "addTenantScopeToQuery")
|
|
206
|
+
.mockImplementation(async (_modelType: any, query: any) => {
|
|
207
|
+
return query;
|
|
208
|
+
});
|
|
209
|
+
jest
|
|
210
|
+
.spyOn(UserPermissions, "addUserScopeToQuery")
|
|
211
|
+
.mockImplementation(async (_modelType: any, query: any) => {
|
|
212
|
+
return query;
|
|
213
|
+
});
|
|
214
|
+
jest
|
|
215
|
+
.spyOn(TablePermission, "checkTableLevelPermissions")
|
|
216
|
+
.mockImplementation(() => {});
|
|
217
|
+
jest
|
|
218
|
+
.spyOn(AccessControlPermission, "addAccessControlIdsToQuery")
|
|
219
|
+
.mockImplementation(async (_modelType: any, query: any) => {
|
|
220
|
+
return query;
|
|
221
|
+
});
|
|
222
|
+
jest
|
|
223
|
+
.spyOn(OwnedScopePermission, "addOwnedScopeToQuery")
|
|
224
|
+
.mockImplementation(async (_modelType: any, query: any) => {
|
|
225
|
+
return query;
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
afterEach(() => {
|
|
230
|
+
jest.restoreAllMocks();
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("lets the escalation rule read through checkPermissions", async () => {
|
|
234
|
+
await expect(
|
|
235
|
+
BasePermission.checkPermissions(
|
|
236
|
+
OnCallDutyPolicyEscalationRuleSchedule,
|
|
237
|
+
{ onCallDutyPolicyId: ObjectID.generate() } as any,
|
|
238
|
+
ESCALATION_RULES_SELECT,
|
|
239
|
+
makeProps([Permission.ProjectOwner]),
|
|
240
|
+
DatabaseRequestType.Read,
|
|
241
|
+
),
|
|
242
|
+
).resolves.toBeDefined();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
it("actually reaches the relation gate on that path", async () => {
|
|
246
|
+
/*
|
|
247
|
+
* Guards the test above from passing because the gate was skipped rather
|
|
248
|
+
* than because it allowed the select.
|
|
249
|
+
*/
|
|
250
|
+
const spy: jest.SpyInstance = jest.spyOn(
|
|
251
|
+
QueryPermission,
|
|
252
|
+
"checkRelationQueryPermission",
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
await BasePermission.checkPermissions(
|
|
256
|
+
OnCallDutyPolicyEscalationRuleSchedule,
|
|
257
|
+
{ onCallDutyPolicyId: ObjectID.generate() } as any,
|
|
258
|
+
ESCALATION_RULES_SELECT,
|
|
259
|
+
makeProps([Permission.ProjectOwner]),
|
|
260
|
+
DatabaseRequestType.Read,
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
expect(spy).toHaveBeenCalled();
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("still runs the top-level select gate on that path", async () => {
|
|
267
|
+
const spy: jest.SpyInstance = jest.spyOn(
|
|
268
|
+
SelectPermission,
|
|
269
|
+
"checkSelectPermission",
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
await BasePermission.checkPermissions(
|
|
273
|
+
OnCallDutyPolicyEscalationRuleSchedule,
|
|
274
|
+
{ onCallDutyPolicyId: ObjectID.generate() } as any,
|
|
275
|
+
ESCALATION_RULES_SELECT,
|
|
276
|
+
makeProps([Permission.ProjectOwner]),
|
|
277
|
+
DatabaseRequestType.Read,
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
expect(spy).toHaveBeenCalled();
|
|
281
|
+
});
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
describe("On-call schedule relation select - the model flag itself", () => {
|
|
285
|
+
const schedule: BaseModel = new OnCallDutyPolicySchedule();
|
|
286
|
+
|
|
287
|
+
function metadata(columnName: string): TableColumnMetadata {
|
|
288
|
+
return schedule.getTableColumnMetadata(columnName);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
it("marks currentUserIdOnRoster readable through a relation", () => {
|
|
292
|
+
expect(metadata("currentUserIdOnRoster").canReadOnRelationQuery).toBe(true);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("keeps it an ObjectID column, not an entity", () => {
|
|
296
|
+
/*
|
|
297
|
+
* The relation traversal only recurses into Entity columns. If this column
|
|
298
|
+
* ever became one, `currentUserIdOnRoster: true` would stop being a leaf
|
|
299
|
+
* select and the flag would no longer be what is being tested.
|
|
300
|
+
*/
|
|
301
|
+
expect(metadata("currentUserIdOnRoster").type).toBe(
|
|
302
|
+
TableColumnType.ObjectID,
|
|
303
|
+
);
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
it("puts it alongside the columns the join already exposed", () => {
|
|
307
|
+
expect(metadata("name").canReadOnRelationQuery).toBe(true);
|
|
308
|
+
expect(metadata("projectId").canReadOnRelationQuery).toBe(true);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("does not mark it owner-only", () => {
|
|
312
|
+
/*
|
|
313
|
+
* canReadOnRelationQuery runs AFTER the owner-only gate in
|
|
314
|
+
* checkRelationQueryPermission and cannot override it. Marking this column
|
|
315
|
+
* @OwnerOnlyColumn later would silently re-break the page, so state the
|
|
316
|
+
* expectation here.
|
|
317
|
+
*/
|
|
318
|
+
expect(isOwnerOnlyColumn(schedule, "currentUserIdOnRoster")).toBe(false);
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it("leaves the rest of the schedule's columns alone", () => {
|
|
322
|
+
/*
|
|
323
|
+
* The fix is one flag on one column, not a widening of the model. Every
|
|
324
|
+
* column below is still unreadable through a relation.
|
|
325
|
+
*/
|
|
326
|
+
const stillClosed: Array<string> = [
|
|
327
|
+
"description",
|
|
328
|
+
"timezone",
|
|
329
|
+
"slug",
|
|
330
|
+
"nextUserIdOnRoster",
|
|
331
|
+
"rosterHandoffAt",
|
|
332
|
+
"rosterNextHandoffAt",
|
|
333
|
+
"rosterNextStartAt",
|
|
334
|
+
"rosterStartAt",
|
|
335
|
+
"createdByUserId",
|
|
336
|
+
"deletedByUserId",
|
|
337
|
+
];
|
|
338
|
+
|
|
339
|
+
for (const columnName of stillClosed) {
|
|
340
|
+
expect(metadata(columnName)).toBeTruthy();
|
|
341
|
+
expect(Boolean(metadata(columnName).canReadOnRelationQuery)).toBe(false);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
describe("On-call schedule relation select - what still refuses", () => {
|
|
347
|
+
const props: DatabaseCommonInteractionProps = makeProps([
|
|
348
|
+
Permission.ProjectOwner,
|
|
349
|
+
]);
|
|
350
|
+
|
|
351
|
+
it("refuses a sibling column that was never flagged", () => {
|
|
352
|
+
expect(() => {
|
|
353
|
+
return checkRelationSelect(
|
|
354
|
+
{
|
|
355
|
+
onCallDutyPolicySchedule: {
|
|
356
|
+
name: true,
|
|
357
|
+
timezone: true,
|
|
358
|
+
},
|
|
359
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
360
|
+
makeProps([Permission.ProjectOwner]),
|
|
361
|
+
);
|
|
362
|
+
}).toThrow(BadDataException);
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it("refuses the next-on-roster column", () => {
|
|
366
|
+
/*
|
|
367
|
+
* The neighbouring column, same shape, same model, one line away in the
|
|
368
|
+
* source. Only the column the page needs was opened.
|
|
369
|
+
*/
|
|
370
|
+
expect(() => {
|
|
371
|
+
return checkRelationSelect(
|
|
372
|
+
{
|
|
373
|
+
onCallDutyPolicySchedule: {
|
|
374
|
+
nextUserIdOnRoster: true,
|
|
375
|
+
},
|
|
376
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
377
|
+
makeProps([Permission.ProjectOwner]),
|
|
378
|
+
);
|
|
379
|
+
}).toThrow(
|
|
380
|
+
"Column nextUserIdOnRoster on On-Call Policy Schedule does not support read on relation query.",
|
|
381
|
+
);
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
it("refuses a deep relation hung off the roster user", () => {
|
|
385
|
+
/*
|
|
386
|
+
* currentUserOnRoster is the entity beside the id column. Walking into it
|
|
387
|
+
* would reach the User table; deep relations are refused before any column
|
|
388
|
+
* check happens.
|
|
389
|
+
*/
|
|
390
|
+
expect(() => {
|
|
391
|
+
return checkRelationSelect(
|
|
392
|
+
{
|
|
393
|
+
onCallDutyPolicySchedule: {
|
|
394
|
+
currentUserOnRoster: { email: true },
|
|
395
|
+
},
|
|
396
|
+
} as unknown as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
397
|
+
props,
|
|
398
|
+
);
|
|
399
|
+
}).toThrow(
|
|
400
|
+
"You cannot query deep relations. Querying deep relations is not supported.",
|
|
401
|
+
);
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
it("refuses a column that does not exist on the schedule", () => {
|
|
405
|
+
expect(() => {
|
|
406
|
+
return checkRelationSelect(
|
|
407
|
+
{
|
|
408
|
+
onCallDutyPolicySchedule: {
|
|
409
|
+
currentUserIdOnRosterr: true,
|
|
410
|
+
},
|
|
411
|
+
} as unknown as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
412
|
+
props,
|
|
413
|
+
);
|
|
414
|
+
}).toThrow(BadDataException);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
it("still refuses a direct read of the column without permission", () => {
|
|
418
|
+
/*
|
|
419
|
+
* The flag governs the relation gate only. Selecting the column at the top
|
|
420
|
+
* level of a schedule query goes through SelectPermission, which reads the
|
|
421
|
+
* column's own @ColumnAccessControl list - and a caller holding none of
|
|
422
|
+
* those permissions is refused exactly as before.
|
|
423
|
+
*/
|
|
424
|
+
expect(() => {
|
|
425
|
+
return SelectPermission.checkSelectPermission(
|
|
426
|
+
OnCallDutyPolicySchedule,
|
|
427
|
+
{ currentUserIdOnRoster: true } as Select<OnCallDutyPolicySchedule>,
|
|
428
|
+
makeProps([Permission.ProjectUser]),
|
|
429
|
+
);
|
|
430
|
+
}).toThrow(NotAuthorizedException);
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
it("allows the direct read for a caller who does hold the permission", () => {
|
|
434
|
+
expect(() => {
|
|
435
|
+
return SelectPermission.checkSelectPermission(
|
|
436
|
+
OnCallDutyPolicySchedule,
|
|
437
|
+
{ currentUserIdOnRoster: true } as Select<OnCallDutyPolicySchedule>,
|
|
438
|
+
makeProps([Permission.ReadProjectOnCallDutyPolicySchedule]),
|
|
439
|
+
);
|
|
440
|
+
}).not.toThrow();
|
|
441
|
+
});
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
describe("On-call schedule relation select - the cost of the flag", () => {
|
|
445
|
+
/*
|
|
446
|
+
* canReadOnRelationQuery short-circuits the related column's own read list -
|
|
447
|
+
* that is what the flag DOES, and it is why the model comment argues the case
|
|
448
|
+
* rather than leaving the flag bare. Pinned here so the tradeoff is visible
|
|
449
|
+
* and deliberate instead of being discovered later.
|
|
450
|
+
*/
|
|
451
|
+
|
|
452
|
+
it("exposes the roster id to a caller scoped only to the join table", () => {
|
|
453
|
+
/*
|
|
454
|
+
* ReadProjectOnCallDutyPolicyEscalationRuleSchedule is not on the schedule
|
|
455
|
+
* column's own read list. Through the join it reads anyway - as it already
|
|
456
|
+
* did for the schedule's name.
|
|
457
|
+
*/
|
|
458
|
+
const joinOnlyProps: DatabaseCommonInteractionProps = makeProps([
|
|
459
|
+
Permission.ReadProjectOnCallDutyPolicyEscalationRuleSchedule,
|
|
460
|
+
]);
|
|
461
|
+
|
|
462
|
+
expect(() => {
|
|
463
|
+
return checkRelationSelect(
|
|
464
|
+
{
|
|
465
|
+
onCallDutyPolicySchedule: {
|
|
466
|
+
name: true,
|
|
467
|
+
currentUserIdOnRoster: true,
|
|
468
|
+
},
|
|
469
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
470
|
+
joinOnlyProps,
|
|
471
|
+
);
|
|
472
|
+
}).not.toThrow();
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it("is the same route the schedule name already took", () => {
|
|
476
|
+
/*
|
|
477
|
+
* If `name` alone ever started refusing for this caller, the paragraph
|
|
478
|
+
* above stops being true and the flag would need re-arguing.
|
|
479
|
+
*/
|
|
480
|
+
expect(() => {
|
|
481
|
+
return checkRelationSelect(
|
|
482
|
+
{
|
|
483
|
+
onCallDutyPolicySchedule: { name: true },
|
|
484
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
485
|
+
makeProps([
|
|
486
|
+
Permission.ReadProjectOnCallDutyPolicyEscalationRuleSchedule,
|
|
487
|
+
]),
|
|
488
|
+
);
|
|
489
|
+
}).not.toThrow();
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it("does not let that caller reach anything else on the schedule", () => {
|
|
493
|
+
expect(() => {
|
|
494
|
+
return checkRelationSelect(
|
|
495
|
+
{
|
|
496
|
+
onCallDutyPolicySchedule: { description: true },
|
|
497
|
+
} as Select<OnCallDutyPolicyEscalationRuleSchedule>,
|
|
498
|
+
makeProps([
|
|
499
|
+
Permission.ReadProjectOnCallDutyPolicyEscalationRuleSchedule,
|
|
500
|
+
]),
|
|
501
|
+
);
|
|
502
|
+
}).toThrow(BadDataException);
|
|
503
|
+
});
|
|
504
|
+
});
|