@oneuptime/common 12.0.8 → 12.0.9
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/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +1 -1
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
- package/Models/DatabaseModels/AIConversation.ts +32 -0
- package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
- package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
- package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
- package/Models/DatabaseModels/Index.ts +12 -4
- package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +139 -9
- package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
- package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +8 -8
- package/Models/DatabaseModels/NetworkDevice.ts +141 -0
- package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
- package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
- package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
- package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
- package/Models/DatabaseModels/Project.ts +78 -0
- package/Models/DatabaseModels/UserCall.ts +42 -0
- package/Models/DatabaseModels/UserEmail.ts +44 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
- package/Models/DatabaseModels/UserPush.ts +49 -0
- package/Models/DatabaseModels/UserSMS.ts +43 -0
- package/Models/DatabaseModels/UserTelegram.ts +59 -0
- package/Models/DatabaseModels/UserWebhook.ts +52 -0
- package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
- package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
- package/Server/API/AIChatAPI.ts +315 -1
- package/Server/API/DashboardAPI.ts +217 -1
- package/Server/API/OnCallReadinessAPI.ts +841 -0
- package/Server/API/TeamComplianceAPI.ts +69 -17
- package/Server/API/TelemetryAPI.ts +220 -12
- package/Server/EnvironmentConfig.ts +52 -0
- package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Infrastructure/Queue.ts +78 -13
- package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
- package/Server/Services/AIService.ts +7 -0
- package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/AlertSeverityService.ts +63 -0
- package/Server/Services/DashboardService.ts +9 -10
- package/Server/Services/DatabaseService.ts +32 -2
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
- package/Server/Services/IncidentSeverityService.ts +76 -0
- package/Server/Services/Index.ts +12 -4
- package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
- package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +4 -4
- package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +89 -20
- package/Server/Services/LogAggregationService.ts +45 -8
- package/Server/Services/MetricAggregationService.ts +121 -0
- package/Server/Services/MetricService.ts +7 -7
- package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
- package/Server/Services/NetworkDeviceLinkService.ts +84 -0
- package/Server/Services/NetworkDeviceService.ts +140 -0
- package/Server/Services/NetworkSiteService.ts +77 -25
- package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
- package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
- package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
- package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
- package/Server/Services/OnCallReadinessService.ts +2803 -0
- package/Server/Services/OnCallSetupReminderService.ts +955 -0
- package/Server/Services/ProfileAggregationService.ts +123 -0
- package/Server/Services/StatusPageService.ts +9 -10
- package/Server/Services/TeamComplianceService.ts +429 -252
- package/Server/Services/UserCallService.ts +26 -1
- package/Server/Services/UserEmailService.ts +26 -1
- package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
- package/Server/Services/UserNotificationRuleService.ts +3812 -333
- package/Server/Services/UserOnCallLogService.ts +561 -48
- package/Server/Services/UserPushService.ts +29 -0
- package/Server/Services/UserService.ts +11 -0
- package/Server/Services/UserSmsService.ts +26 -1
- package/Server/Services/UserTelegramService.ts +24 -1
- package/Server/Services/UserWebhookService.ts +28 -1
- package/Server/Services/UserWhatsAppService.ts +24 -1
- package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
- package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
- package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
- package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
- package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
- package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
- package/Server/Types/Workflow/Components/API/Get.ts +1 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
- package/Server/Types/Workflow/Components/API/Post.ts +1 -1
- package/Server/Types/Workflow/Components/API/Put.ts +1 -1
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
- package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
- package/Server/Types/Workflow/Components/Email.ts +25 -7
- package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
- package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
- package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
- package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
- package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
- package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
- package/Server/Utils/AI/Toolbox/Index.ts +48 -0
- package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
- package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
- package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
- package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
- package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
- package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
- package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
- package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
- package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
- package/Server/Utils/ClientIp.ts +221 -0
- package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
- package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
- package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
- package/Server/Utils/Express.ts +12 -17
- package/Server/Utils/LLM/LLMService.ts +85 -8
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
- package/Server/Utils/SSRFProtection.ts +98 -23
- package/Server/Utils/StartServer.ts +12 -3
- package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +25 -25
- package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
- package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
- package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
- package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
- package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
- package/Tests/Models/InventoryItemModel.test.ts +174 -0
- package/Tests/Models/InventoryItemNaming.test.ts +302 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
- package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
- package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
- package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
- package/Tests/Server/API/Helpers.ts +24 -15
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
- package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
- package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
- package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
- package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
- package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
- package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
- package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
- package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
- package/Tests/Server/Services/{TelemetryEntityManualCreate.test.ts → InventoryItemManualCreate.test.ts} +27 -27
- package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
- package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
- package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
- package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
- package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
- package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
- package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
- package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
- package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
- package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
- package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
- package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
- package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
- package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
- package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
- package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
- package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
- package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
- package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
- package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
- package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
- package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
- package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
- package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
- package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
- package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
- package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
- package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
- package/Tests/Server/Utils/ClientIp.test.ts +438 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
- package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
- package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
- package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
- package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
- package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
- package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +15 -15
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
- package/Tests/Types/IP/IP.test.ts +263 -0
- package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
- package/Tests/Types/IP/IPv6.test.ts +12 -1
- package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
- package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
- package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
- package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +6 -6
- package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
- package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
- package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +112 -0
- package/Tests/Types/Workflow/Templates.test.ts +916 -101
- package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
- package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
- package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
- package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
- package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
- package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
- package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
- package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +72 -0
- package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +242 -7
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +15 -7
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +242 -28
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +59 -1
- package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
- package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
- package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
- package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
- package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
- package/Tests/UI/EsbuildConfig.test.ts +607 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
- package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
- package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
- package/Tests/UI/Utils/Platform.test.ts +147 -0
- package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
- package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +487 -0
- package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
- package/Tests/__mocks__/bullmq.js +55 -0
- package/Types/AI/AIChatMessageStatus.ts +8 -1
- package/Types/AI/AIChatTypes.ts +12 -0
- package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
- package/Types/Exception/ExceptionCode.ts +2 -0
- package/Types/Exception/ServiceUnavailableException.ts +8 -0
- package/Types/Exception/TooManyRequestsException.ts +8 -0
- package/Types/IP/IP.ts +93 -47
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +49 -3
- package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
- package/Types/OnCallDutyPolicy/Layer.ts +203 -149
- package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
- package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
- package/Types/Permission.ts +193 -0
- package/Types/Telemetry/EntityRelationshipType.ts +1 -1
- package/Types/Telemetry/EntitySource.ts +1 -1
- package/Types/Telemetry/EntityType.ts +1 -1
- package/Types/Telemetry/EntityTypeGroups.ts +1 -1
- package/Types/Workflow/Components/BaseModel.ts +75 -29
- package/Types/Workflow/Components/Discord.ts +1 -0
- package/Types/Workflow/Components/Email.ts +12 -3
- package/Types/Workflow/Components/JavaScript.ts +7 -0
- package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
- package/Types/Workflow/Components/Slack.ts +1 -0
- package/Types/Workflow/Components/Telegram.ts +1 -0
- package/Types/Workflow/TemplateSyntax.ts +44 -0
- package/Types/Workflow/Templates.ts +2097 -45
- package/UI/Components/Calendar/Calendar.css +43 -0
- package/UI/Components/Calendar/Calendar.tsx +8 -0
- package/UI/Components/Card/Card.tsx +2 -2
- package/UI/Components/Checkbox/Checkbox.tsx +16 -0
- package/UI/Components/Dictionary/Dictionary.tsx +48 -9
- package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
- package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
- package/UI/Components/Input/Input.tsx +1 -0
- package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
- package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
- package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
- package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
- package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
- package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
- package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
- package/UI/Components/LogsViewer/types.ts +23 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
- package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
- package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
- package/UI/Components/Table/Table.tsx +49 -16
- package/UI/Components/Table/TableBody.tsx +53 -28
- package/UI/Components/Table/TableHeader.tsx +13 -0
- package/UI/Components/Table/TableRow.tsx +58 -26
- package/UI/Components/Workflow/ArgumentsForm.tsx +155 -9
- package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +10 -1
- package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
- package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
- package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
- package/UI/Components/Workflow/GraphLint.ts +42 -5
- package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +154 -22
- package/UI/Components/Workflow/ModelSchema.ts +115 -33
- package/UI/Components/Workflow/RunStatusWatcher.ts +1 -1
- package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
- package/UI/Components/Workflow/UseRunWatch.ts +212 -0
- package/UI/Components/Workflow/VariableModal.tsx +6 -2
- package/UI/Components/Workflow/Workflow.tsx +49 -3
- package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
- package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
- package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
- package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
- package/UI/Utils/Platform.ts +149 -0
- package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
- package/UI/esbuild-config.js +22 -1
- package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +888 -164
- package/Utils/Telemetry/CrossSignalScope.ts +502 -0
- package/Utils/Telemetry/EntityKey.ts +5 -5
- package/Utils/Telemetry/EntityRelationship.ts +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
- package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
- package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
- package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
- package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +12 -4
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +167 -31
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
- package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
- package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +27 -27
- package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
- package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
- package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +80 -0
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
- package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
- package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
- package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
- package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
- package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
- package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
- package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
- package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +237 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +165 -13
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
- package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
- package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
- package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +129 -18
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +45 -0
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Queue.js +72 -13
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
- package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AIService.js +1 -0
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +54 -0
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/DashboardService.js +10 -9
- package/build/dist/Server/Services/DashboardService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +24 -2
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +12 -4
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
- package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +6 -6
- package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
- package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +68 -23
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
- package/build/dist/Server/Services/LogAggregationService.js +27 -8
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricAggregationService.js +80 -0
- package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
- package/build/dist/Server/Services/MetricService.js +6 -6
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
- package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
- package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +53 -13
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
- package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
- package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
- package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
- package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
- package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
- package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
- package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +11 -10
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceService.js +312 -160
- package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
- package/build/dist/Server/Services/UserCallService.js +24 -1
- package/build/dist/Server/Services/UserCallService.js.map +1 -1
- package/build/dist/Server/Services/UserEmailService.js +24 -1
- package/build/dist/Server/Services/UserEmailService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
- package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
- package/build/dist/Server/Services/UserPushService.js +26 -0
- package/build/dist/Server/Services/UserPushService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +10 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSmsService.js +24 -1
- package/build/dist/Server/Services/UserSmsService.js.map +1 -1
- package/build/dist/Server/Services/UserTelegramService.js +22 -1
- package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +25 -1
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
- package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
- package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
- package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
- package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
- package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
- package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
- package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
- package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
- package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
- package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
- package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
- package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
- package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
- package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
- package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
- package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
- package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
- package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
- package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
- package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
- package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
- package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
- package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
- package/build/dist/Server/Utils/ClientIp.js +137 -0
- package/build/dist/Server/Utils/ClientIp.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
- package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
- package/build/dist/Server/Utils/Express.js +12 -12
- package/build/dist/Server/Utils/Express.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +82 -21
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +12 -4
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
- package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +11 -11
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
- package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
- package/build/dist/Types/AI/AIChatTypes.js +12 -0
- package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
- package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
- package/build/dist/Types/Exception/ExceptionCode.js +2 -0
- package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
- package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
- package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
- package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
- package/build/dist/Types/IP/IP.js +87 -43
- package/build/dist/Types/IP/IP.js.map +1 -1
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
- package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
- package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
- package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
- package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
- package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
- package/build/dist/Types/Permission.js +174 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +1 -1
- package/build/dist/Types/Telemetry/EntityType.js +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +66 -28
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Discord.js +1 -0
- package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Email.js +12 -3
- package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
- package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
- package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Slack.js +1 -0
- package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
- package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
- package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
- package/build/dist/Types/Workflow/TemplateSyntax.js +12 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -1
- package/build/dist/Types/Workflow/Templates.js +1931 -38
- package/build/dist/Types/Workflow/Templates.js.map +1 -1
- package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
- package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
- package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
- package/build/dist/UI/Components/Dictionary/Dictionary.js +25 -11
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
- package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +1 -0
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
- package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
- package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
- package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
- package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
- package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
- package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
- package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +27 -15
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +24 -18
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableHeader.js +9 -1
- package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +29 -21
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +130 -12
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
- package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +4 -4
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
- package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
- package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
- package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +33 -4
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
- package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +116 -21
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ModelSchema.js +72 -34
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
- package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
- package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
- package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
- package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +41 -1
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
- package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
- package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
- package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
- package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/Platform.js +118 -0
- package/build/dist/UI/Utils/Platform.js.map +1 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
- package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
- package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +642 -136
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
- package/build/dist/Utils/Telemetry/EntityKey.js +5 -5
- package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
- package/jest.config.json +1 -0
- package/package.json +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
|
@@ -0,0 +1,858 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import DatabaseConfig from "../DatabaseConfig";
|
|
11
|
+
import BaseService from "./BaseService";
|
|
12
|
+
import MailService from "./MailService";
|
|
13
|
+
import ProjectService from "./ProjectService";
|
|
14
|
+
import TeamMemberService from "./TeamMemberService";
|
|
15
|
+
import UserCallService from "./UserCallService";
|
|
16
|
+
import UserEmailService from "./UserEmailService";
|
|
17
|
+
import UserPushService from "./UserPushService";
|
|
18
|
+
import UserService from "./UserService";
|
|
19
|
+
import UserSmsService from "./UserSmsService";
|
|
20
|
+
import UserTelegramService from "./UserTelegramService";
|
|
21
|
+
import UserWebhookService from "./UserWebhookService";
|
|
22
|
+
import UserWhatsAppService from "./UserWhatsAppService";
|
|
23
|
+
import { resolveReferenceId } from "../Utils/Database/ProjectScopedReferenceValidator";
|
|
24
|
+
import logger from "../Utils/Logger";
|
|
25
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
26
|
+
import URL from "../../Types/API/URL";
|
|
27
|
+
import AuditLogAction from "../../Types/AuditLog/AuditLogAction";
|
|
28
|
+
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
29
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
30
|
+
import ObjectID from "../../Types/ObjectID";
|
|
31
|
+
import UserNotificationRule from "../../Models/DatabaseModels/UserNotificationRule";
|
|
32
|
+
export class UserNotificationRuleAdminService extends BaseService {
|
|
33
|
+
/*
|
|
34
|
+
* Built per call, never hoisted to module scope.
|
|
35
|
+
*
|
|
36
|
+
* UserEmailService and its six siblings import UserNotificationRuleService,
|
|
37
|
+
* which imports this file — a genuine require cycle. Capturing the service
|
|
38
|
+
* objects in a module-level constant would read `default` while the sibling
|
|
39
|
+
* module is still mid-evaluation and freeze `undefined` into the table. Built
|
|
40
|
+
* inside a method, every service reference resolves at call time, long after
|
|
41
|
+
* the cycle has settled.
|
|
42
|
+
*/
|
|
43
|
+
getNotificationMethodDescriptors() {
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
idColumn: "userEmailId",
|
|
47
|
+
relationColumn: "userEmail",
|
|
48
|
+
label: "Email",
|
|
49
|
+
findOwnerUserId: async (methodId) => {
|
|
50
|
+
var _a;
|
|
51
|
+
return (_a = (await UserEmailService.findOneById({
|
|
52
|
+
id: methodId,
|
|
53
|
+
select: { _id: true, userId: true },
|
|
54
|
+
props: { isRoot: true },
|
|
55
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
idColumn: "userSmsId",
|
|
60
|
+
relationColumn: "userSms",
|
|
61
|
+
label: "SMS",
|
|
62
|
+
findOwnerUserId: async (methodId) => {
|
|
63
|
+
var _a;
|
|
64
|
+
return (_a = (await UserSmsService.findOneById({
|
|
65
|
+
id: methodId,
|
|
66
|
+
select: { _id: true, userId: true },
|
|
67
|
+
props: { isRoot: true },
|
|
68
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
idColumn: "userCallId",
|
|
73
|
+
relationColumn: "userCall",
|
|
74
|
+
label: "Call",
|
|
75
|
+
findOwnerUserId: async (methodId) => {
|
|
76
|
+
var _a;
|
|
77
|
+
return (_a = (await UserCallService.findOneById({
|
|
78
|
+
id: methodId,
|
|
79
|
+
select: { _id: true, userId: true },
|
|
80
|
+
props: { isRoot: true },
|
|
81
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
idColumn: "userWhatsAppId",
|
|
86
|
+
relationColumn: "userWhatsApp",
|
|
87
|
+
label: "WhatsApp",
|
|
88
|
+
findOwnerUserId: async (methodId) => {
|
|
89
|
+
var _a;
|
|
90
|
+
return (_a = (await UserWhatsAppService.findOneById({
|
|
91
|
+
id: methodId,
|
|
92
|
+
select: { _id: true, userId: true },
|
|
93
|
+
props: { isRoot: true },
|
|
94
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
idColumn: "userTelegramId",
|
|
99
|
+
relationColumn: "userTelegram",
|
|
100
|
+
label: "Telegram",
|
|
101
|
+
findOwnerUserId: async (methodId) => {
|
|
102
|
+
var _a;
|
|
103
|
+
return (_a = (await UserTelegramService.findOneById({
|
|
104
|
+
id: methodId,
|
|
105
|
+
select: { _id: true, userId: true },
|
|
106
|
+
props: { isRoot: true },
|
|
107
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
idColumn: "userPushId",
|
|
112
|
+
relationColumn: "userPush",
|
|
113
|
+
label: "Push",
|
|
114
|
+
findOwnerUserId: async (methodId) => {
|
|
115
|
+
var _a;
|
|
116
|
+
return (_a = (await UserPushService.findOneById({
|
|
117
|
+
id: methodId,
|
|
118
|
+
select: { _id: true, userId: true },
|
|
119
|
+
props: { isRoot: true },
|
|
120
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
idColumn: "userWebhookId",
|
|
125
|
+
relationColumn: "userWebhook",
|
|
126
|
+
label: "Webhook",
|
|
127
|
+
findOwnerUserId: async (methodId) => {
|
|
128
|
+
var _a;
|
|
129
|
+
return (_a = (await UserWebhookService.findOneById({
|
|
130
|
+
id: methodId,
|
|
131
|
+
select: { _id: true, userId: true },
|
|
132
|
+
props: { isRoot: true },
|
|
133
|
+
}))) === null || _a === void 0 ? void 0 : _a.userId;
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
];
|
|
137
|
+
}
|
|
138
|
+
/*
|
|
139
|
+
* The seven FK columns, in one place, so a future eighth channel is a single
|
|
140
|
+
* entry rather than an eighth thing to remember. A guard that covers six of
|
|
141
|
+
* seven covers none: the attacker picks the seventh.
|
|
142
|
+
*/
|
|
143
|
+
getNotificationMethodIdColumns() {
|
|
144
|
+
return this.getNotificationMethodDescriptors().map((descriptor) => {
|
|
145
|
+
return descriptor.idColumn;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/*
|
|
149
|
+
* The ownership column's two spellings, derived from the model rather than
|
|
150
|
+
* restated here as literals.
|
|
151
|
+
*
|
|
152
|
+
* `userId` is a declared @Column; `user` is a @ManyToOne whose @JoinColumn
|
|
153
|
+
* names that same physical column. Two decorated members, one join column,
|
|
154
|
+
* and a payload may carry either or both — exactly the situation that made
|
|
155
|
+
* the method FKs bypassable, reproduced on the column that decides whose
|
|
156
|
+
* pages the row selects.
|
|
157
|
+
*
|
|
158
|
+
* The derivation ("relation name is the scalar minus its `Id` suffix") is the
|
|
159
|
+
* one CreatePermission.checkCreateOwnership uses, and it is deliberate that
|
|
160
|
+
* both places derive rather than hard-code: a model that renames its
|
|
161
|
+
* ownership column must not leave a guard silently reading a property that no
|
|
162
|
+
* longer exists.
|
|
163
|
+
*/
|
|
164
|
+
getRuleOwnerColumns() {
|
|
165
|
+
const idColumn = new UserNotificationRule().getUserColumn();
|
|
166
|
+
if (!idColumn || !idColumn.endsWith("Id")) {
|
|
167
|
+
/*
|
|
168
|
+
* No user-scoped column, or one that does not follow the convention, so
|
|
169
|
+
* there is no second spelling to reconcile. Genuinely a no-op rather than
|
|
170
|
+
* a guard opening: with no ownership column there is no ownership to
|
|
171
|
+
* disagree about. Same reasoning as CreatePermission's `if (!userColumn)`.
|
|
172
|
+
*/
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
idColumn: idColumn,
|
|
177
|
+
relationColumn: idColumn.slice(0, -2),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Refuse a payload whose two spellings of the ownership column name two
|
|
182
|
+
* different users.
|
|
183
|
+
*
|
|
184
|
+
* The exact counterpart of assertOneMethodPerNotificationChannel below, on
|
|
185
|
+
* the other half of the pair this file exists to keep in agreement. A payload
|
|
186
|
+
* saying `userId: <victim>, user: { _id: <me> }` is not a client mistake — no
|
|
187
|
+
* dashboard sends both — it is a request for the guard and the ORM to read
|
|
188
|
+
* different owners, which is precisely how a validated write becomes a
|
|
189
|
+
* different persisted row.
|
|
190
|
+
*
|
|
191
|
+
* Refusing rather than silently preferring one spelling means the correctness
|
|
192
|
+
* of this file never rests on our reading of TypeORM's precedence rule. The
|
|
193
|
+
* fold below then removes the surviving redundancy, so nothing downstream —
|
|
194
|
+
* the roster check, the method-ownership check, CreatePermission, the audit
|
|
195
|
+
* line — has a precedence question left to resolve.
|
|
196
|
+
*/
|
|
197
|
+
assertOneRuleOwner(carrier) {
|
|
198
|
+
const columns = this.getRuleOwnerColumns();
|
|
199
|
+
if (!columns) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const fromIdColumn = resolveReferenceId(carrier[columns.idColumn]);
|
|
203
|
+
const fromRelation = resolveReferenceId(carrier[columns.relationColumn]);
|
|
204
|
+
if (!fromIdColumn || !fromRelation) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
/*
|
|
208
|
+
* Case-insensitively, for the reason ProjectScopedReferenceValidator
|
|
209
|
+
* normalises ids: ObjectID keeps whatever case it was handed while Postgres
|
|
210
|
+
* renders `uuid` lower case, so one id in two cases is still one id and
|
|
211
|
+
* must not read as a contradiction.
|
|
212
|
+
*/
|
|
213
|
+
if (fromIdColumn.toString().toLowerCase() ===
|
|
214
|
+
fromRelation.toString().toLowerCase()) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
throw new BadDataException(`This notification rule names two different users: ${columns.idColumn} says ${fromIdColumn.toString()} and ${columns.relationColumn} says ${fromRelation.toString()}. Send only one of them.`);
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Fold the ownership relation into the ownership scalar so exactly one
|
|
221
|
+
* spelling survives a create.
|
|
222
|
+
*
|
|
223
|
+
* This is the same reduction collapseNotificationMethodRelationsOnCreate
|
|
224
|
+
* performs for the seven method FKs, and the same one
|
|
225
|
+
* CreatePermission.checkCreateOwnership performs for this very column — it
|
|
226
|
+
* validates `user` identically to `userId` and then CLEARS it, because after
|
|
227
|
+
* clearing there is no second source of truth left to disagree with the
|
|
228
|
+
* first. What CreatePermission cannot do is cover the administrator: it
|
|
229
|
+
* returns early for a caller holding a real role permission in the model's
|
|
230
|
+
* create list, which is exactly the caller this phase introduced and exactly
|
|
231
|
+
* the caller who may legitimately name somebody else. On that path the
|
|
232
|
+
* relation reached TypeORM unreduced.
|
|
233
|
+
*
|
|
234
|
+
* The relation's id is what is kept, because that is the value TypeORM would
|
|
235
|
+
* have written: the declared @Column and the relation's @JoinColumn share one
|
|
236
|
+
* ColumnMetadata, and getEntityValue reads the relation slot first, falling
|
|
237
|
+
* back to the scalar only when the relation holds no object. A relation slot
|
|
238
|
+
* that is present but carries no id therefore resolves to nothing, and
|
|
239
|
+
* clearing the scalar alongside it reproduces the NULL the ORM would have
|
|
240
|
+
* written rather than inventing an owner the row will not have.
|
|
241
|
+
*
|
|
242
|
+
* CREATE ONLY, though for a different reason than the method columns: `user`
|
|
243
|
+
* and `userId` are `update: []` for BOTH spellings on this model, so there is
|
|
244
|
+
* no update-path fold to consider at all — an update naming either one is
|
|
245
|
+
* refused outright by ColumnPermission.
|
|
246
|
+
*/
|
|
247
|
+
collapseRuleOwnerRelationOnCreate(carrier) {
|
|
248
|
+
const columns = this.getRuleOwnerColumns();
|
|
249
|
+
if (!columns) {
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
const relationValue = carrier[columns.relationColumn];
|
|
253
|
+
if (relationValue === undefined || relationValue === null) {
|
|
254
|
+
// Nothing in this spelling; TypeORM falls through to the scalar already.
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
const resolved = resolveReferenceId(relationValue);
|
|
258
|
+
carrier[columns.idColumn] = resolved
|
|
259
|
+
? resolved instanceof ObjectID
|
|
260
|
+
? resolved
|
|
261
|
+
: new ObjectID(resolved)
|
|
262
|
+
: undefined;
|
|
263
|
+
carrier[columns.relationColumn] = undefined;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Pull EVERY notification-method reference out of a create payload or an
|
|
267
|
+
* update patch — every channel, and every spelling of every channel.
|
|
268
|
+
*
|
|
269
|
+
* THE BUG THIS SHAPE EXISTS TO PREVENT. `userWebhookId` and `userWebhook` are
|
|
270
|
+
* two decorated members over ONE physical join column, and a request may
|
|
271
|
+
* carry both. This method used to resolve them as
|
|
272
|
+
* `carrier[idColumn] || carrier[relationColumn]`, which validates the FK
|
|
273
|
+
* column and never looks at the relation when both are present. TypeORM
|
|
274
|
+
* resolves the same conflict the other way round: the declared @Column and
|
|
275
|
+
* the relation's @JoinColumn share a single ColumnMetadata, and
|
|
276
|
+
* ColumnMetadata.getEntityValue reads the RELATION first, falling back to the
|
|
277
|
+
* scalar only when the relation slot holds no object.
|
|
278
|
+
*
|
|
279
|
+
* So the id that was checked and the id that was written were different ids,
|
|
280
|
+
* and the caller chose both. Put the rule owner's own method in the FK column
|
|
281
|
+
* to satisfy the guard, and your own row in the relation slot to be
|
|
282
|
+
* persisted, and R3 — the entire anti-hijack invariant — is a formality.
|
|
283
|
+
*
|
|
284
|
+
* The rule is therefore: never short-circuit. Emit one reference per spelling
|
|
285
|
+
* actually present, so the ownership check below has to answer for all of
|
|
286
|
+
* them, and a payload can no longer be right in the half that is inspected
|
|
287
|
+
* and wrong in the half that is written.
|
|
288
|
+
*
|
|
289
|
+
* Duplicates are folded only when they are the SAME id in the same column,
|
|
290
|
+
* where the second lookup could not produce a different answer. Two spellings
|
|
291
|
+
* naming two DIFFERENT ids stay two references on purpose — that is precisely
|
|
292
|
+
* the case worth an extra query.
|
|
293
|
+
*
|
|
294
|
+
* A rule that names no method at all yields an empty array and the ownership
|
|
295
|
+
* guard becomes a no-op — correct, because an opt-out row genuinely has no
|
|
296
|
+
* address to hijack.
|
|
297
|
+
*/
|
|
298
|
+
collectNotificationMethodReferences(carrier) {
|
|
299
|
+
const references = [];
|
|
300
|
+
const seen = new Set();
|
|
301
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
302
|
+
const spellings = [
|
|
303
|
+
descriptor.idColumn,
|
|
304
|
+
descriptor.relationColumn,
|
|
305
|
+
];
|
|
306
|
+
for (const suppliedColumn of spellings) {
|
|
307
|
+
const resolved = resolveReferenceId(carrier[suppliedColumn]);
|
|
308
|
+
if (!resolved) {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
const methodId = resolved instanceof ObjectID ? resolved : new ObjectID(resolved);
|
|
312
|
+
/*
|
|
313
|
+
* Ids are compared case-insensitively for the same reason
|
|
314
|
+
* ProjectScopedReferenceValidator normalises them: ObjectID keeps
|
|
315
|
+
* whatever case it was handed, while Postgres renders `uuid` in lower
|
|
316
|
+
* case, so an uppercase spelling and a lowercase one are one id.
|
|
317
|
+
*/
|
|
318
|
+
const key = `${descriptor.idColumn}:${methodId
|
|
319
|
+
.toString()
|
|
320
|
+
.toLowerCase()}`;
|
|
321
|
+
if (seen.has(key)) {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
seen.add(key);
|
|
325
|
+
references.push({
|
|
326
|
+
idColumn: descriptor.idColumn,
|
|
327
|
+
suppliedColumn: suppliedColumn,
|
|
328
|
+
label: descriptor.label,
|
|
329
|
+
methodId: methodId,
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return references;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Refuse a payload whose two spellings of one method column name two
|
|
337
|
+
* different methods.
|
|
338
|
+
*
|
|
339
|
+
* Validating both spellings (above) closes the hijack: whichever one the ORM
|
|
340
|
+
* picks, it has been checked against the rule's owner. What it does not do is
|
|
341
|
+
* make the write PREDICTABLE — with both slots filled, which address the rule
|
|
342
|
+
* ends up delivering to is decided by a TypeORM precedence rule that no
|
|
343
|
+
* reader of this codebase should have to know, and that a TypeORM upgrade is
|
|
344
|
+
* free to change.
|
|
345
|
+
*
|
|
346
|
+
* "Both spellings, two different methods" is not something a client does by
|
|
347
|
+
* accident; the dashboard sends one. So there is no legitimate request to
|
|
348
|
+
* preserve here, and refusing is strictly better than guessing: the caller is
|
|
349
|
+
* told exactly what is contradictory, and nothing downstream has a precedence
|
|
350
|
+
* question left to resolve.
|
|
351
|
+
*
|
|
352
|
+
* Deliberately NOT run before the ownership check. A payload that is both
|
|
353
|
+
* ambiguous and a hijack attempt should be reported as the hijack — that is
|
|
354
|
+
* the finding an operator needs to see, and "you sent the same field twice"
|
|
355
|
+
* would bury it.
|
|
356
|
+
*/
|
|
357
|
+
assertOneMethodPerNotificationChannel(carrier) {
|
|
358
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
359
|
+
const fromIdColumn = resolveReferenceId(carrier[descriptor.idColumn]);
|
|
360
|
+
const fromRelation = resolveReferenceId(carrier[descriptor.relationColumn]);
|
|
361
|
+
if (!fromIdColumn || !fromRelation) {
|
|
362
|
+
continue;
|
|
363
|
+
}
|
|
364
|
+
if (fromIdColumn.toString().toLowerCase() ===
|
|
365
|
+
fromRelation.toString().toLowerCase()) {
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
throw new BadDataException(`This notification rule names two different ${descriptor.label} notification methods: ${descriptor.idColumn} says ${fromIdColumn.toString()} and ${descriptor.relationColumn} says ${fromRelation.toString()}. Send only one of them.`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Fold the relation spelling into the FK column so exactly one spelling
|
|
373
|
+
* survives — the create-path reduction, and the reason the ORM never gets to
|
|
374
|
+
* choose.
|
|
375
|
+
*
|
|
376
|
+
* This mirrors CreatePermission.checkCreateOwnership, which validates the
|
|
377
|
+
* `user` relation identically to the `userId` scalar and then CLEARS it. The
|
|
378
|
+
* point of clearing rather than merely checking is that after it there is no
|
|
379
|
+
* second source of truth left to disagree with the first.
|
|
380
|
+
*
|
|
381
|
+
* The relation's id is what is kept, because that is the value TypeORM would
|
|
382
|
+
* have written: getEntityValue reads the relation slot first. A relation slot
|
|
383
|
+
* that is present but carries no id resolves to nothing, and clearing the FK
|
|
384
|
+
* column alongside it reproduces the NULL the ORM would have written — which
|
|
385
|
+
* matters, because that NULL is what turns a rule into one that pages
|
|
386
|
+
* nowhere, and the create invariants below have to be able to see it.
|
|
387
|
+
*
|
|
388
|
+
* CREATE ONLY. On update the two spellings do not have the same access
|
|
389
|
+
* control: the relation members are `update: []` on UserNotificationRule
|
|
390
|
+
* while the `*Id` members are open to an administrator, so moving a value
|
|
391
|
+
* from the relation slot into the FK column would launder a column write that
|
|
392
|
+
* ColumnPermission (which runs after the update hook) exists to refuse. On
|
|
393
|
+
* that path ambiguity is resolved by refusal instead — see
|
|
394
|
+
* assertOneMethodPerNotificationChannel.
|
|
395
|
+
*/
|
|
396
|
+
collapseNotificationMethodRelationsOnCreate(carrier) {
|
|
397
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
398
|
+
const relationValue = carrier[descriptor.relationColumn];
|
|
399
|
+
if (relationValue === undefined || relationValue === null) {
|
|
400
|
+
/*
|
|
401
|
+
* Nothing supplied in this spelling. TypeORM falls through to the
|
|
402
|
+
* scalar in exactly this case, so there is nothing to fold and nothing
|
|
403
|
+
* to clear.
|
|
404
|
+
*/
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
407
|
+
const resolved = resolveReferenceId(relationValue);
|
|
408
|
+
carrier[descriptor.idColumn] = resolved
|
|
409
|
+
? resolved instanceof ObjectID
|
|
410
|
+
? resolved
|
|
411
|
+
: new ObjectID(resolved)
|
|
412
|
+
: undefined;
|
|
413
|
+
carrier[descriptor.relationColumn] = undefined;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Does this payload name a delivery address at all, in any channel, in either
|
|
418
|
+
* spelling?
|
|
419
|
+
*
|
|
420
|
+
* Driven off the descriptor table rather than a hand-written list of fourteen
|
|
421
|
+
* property names. A hand-written list is how an eighth channel ends up
|
|
422
|
+
* exempt from the "a rule must be able to reach somebody" invariant, and an
|
|
423
|
+
* exempt channel is a rule that silently pages nobody.
|
|
424
|
+
*/
|
|
425
|
+
carriesAnyNotificationMethod(carrier) {
|
|
426
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
427
|
+
if (carrier[descriptor.idColumn] || carrier[descriptor.relationColumn]) {
|
|
428
|
+
return true;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Does this patch MENTION a delivery address, whatever it sets it to?
|
|
435
|
+
*
|
|
436
|
+
* Distinct from carriesAnyNotificationMethod, and the difference is the whole
|
|
437
|
+
* point: `userEmailId: null` carries no method but very much mentions one. It
|
|
438
|
+
* is the write that removes a rule's only way of reaching somebody, so it is
|
|
439
|
+
* exactly the patch the coherence check must not skip.
|
|
440
|
+
*/
|
|
441
|
+
mentionsAnyNotificationMethodColumn(carrier) {
|
|
442
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
443
|
+
if (carrier[descriptor.idColumn] !== undefined ||
|
|
444
|
+
carrier[descriptor.relationColumn] !== undefined) {
|
|
445
|
+
return true;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* The row's delivery addresses as they would stand AFTER a patch is applied.
|
|
452
|
+
*
|
|
453
|
+
* The create-time invariants ("a rule that pages must name a method", "an
|
|
454
|
+
* opt-out rule must not") are properties of the ROW, and update can break
|
|
455
|
+
* both of them: flipping `isOptOut` on a rule that carries an email, or
|
|
456
|
+
* nulling the only method on a rule that is still meant to page. Neither is
|
|
457
|
+
* visible from the patch alone, so the persisted row has to be read and the
|
|
458
|
+
* two combined.
|
|
459
|
+
*
|
|
460
|
+
* Precedence between the two spellings is the ORM's, not ours: the relation
|
|
461
|
+
* slot wins when it is present, because that is what would be written. A
|
|
462
|
+
* column the patch does not mention keeps whatever the row already had.
|
|
463
|
+
*/
|
|
464
|
+
getNotificationMethodIdsAfterPatch(data) {
|
|
465
|
+
const methodIds = [];
|
|
466
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
467
|
+
let resolved = undefined;
|
|
468
|
+
if (data.patch[descriptor.relationColumn] !== undefined) {
|
|
469
|
+
resolved = resolveReferenceId(data.patch[descriptor.relationColumn]);
|
|
470
|
+
}
|
|
471
|
+
else if (data.patch[descriptor.idColumn] !== undefined) {
|
|
472
|
+
resolved = resolveReferenceId(data.patch[descriptor.idColumn]);
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
resolved = resolveReferenceId(data.currentRow[descriptor.idColumn]);
|
|
476
|
+
}
|
|
477
|
+
if (!resolved) {
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
480
|
+
methodIds.push(resolved instanceof ObjectID ? resolved : new ObjectID(resolved));
|
|
481
|
+
}
|
|
482
|
+
return methodIds;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* R1 — the target of an on-behalf-of write must belong to the project the
|
|
486
|
+
* write is scoped to.
|
|
487
|
+
*
|
|
488
|
+
* The create-path ownership gate (CreatePermission.checkCreateOwnership)
|
|
489
|
+
* deliberately steps aside for a caller who holds a real role permission in
|
|
490
|
+
* the model's create list, so that this feature can exist at all. What it
|
|
491
|
+
* hands over is a caller who may name SOME other user — it says nothing about
|
|
492
|
+
* WHICH other users are in scope, because it has no notion of a project
|
|
493
|
+
* roster. Left there, holding ProjectAdmin on one throwaway project would be
|
|
494
|
+
* a licence to write notification rules for any user id in the installation.
|
|
495
|
+
*
|
|
496
|
+
* Membership is read straight from TeamMember with isRoot props and no cache.
|
|
497
|
+
* TeamMemberService.getTeamIdsForUser would have answered the same question
|
|
498
|
+
* with one fewer query, but it memoises for 60 seconds — and a security
|
|
499
|
+
* decision that keeps saying "yes" for a minute after the user was removed
|
|
500
|
+
* from the project is not a security decision.
|
|
501
|
+
*
|
|
502
|
+
* `hasAcceptedInvitation` is part of the test because it is this codebase's
|
|
503
|
+
* own definition of membership (the Owned permission scope resolves teams the
|
|
504
|
+
* same way), and because a pending invitation is an admin-created row: any
|
|
505
|
+
* admin can create one for any email address, so treating one as membership
|
|
506
|
+
* would hand back most of what this guard just took away. Nothing legitimate
|
|
507
|
+
* is lost — a rule must carry a notification method to be created at all, and
|
|
508
|
+
* a user who has not joined the project has none.
|
|
509
|
+
*/
|
|
510
|
+
async assertTargetUserIsProjectMember(data) {
|
|
511
|
+
const projectId = data.props.tenantId;
|
|
512
|
+
if (!projectId) {
|
|
513
|
+
/*
|
|
514
|
+
* A non-root caller writing another user's rule without a tenant scope
|
|
515
|
+
* has nothing to be an admin OF. There is no roster to check them
|
|
516
|
+
* against, so there is no way to say yes.
|
|
517
|
+
*/
|
|
518
|
+
throw new BadDataException("A project is required to create a notification rule for another user.");
|
|
519
|
+
}
|
|
520
|
+
const membership = await TeamMemberService.findOneBy({
|
|
521
|
+
query: {
|
|
522
|
+
userId: data.targetUserId,
|
|
523
|
+
projectId: projectId,
|
|
524
|
+
hasAcceptedInvitation: true,
|
|
525
|
+
},
|
|
526
|
+
select: {
|
|
527
|
+
_id: true,
|
|
528
|
+
},
|
|
529
|
+
props: {
|
|
530
|
+
isRoot: true,
|
|
531
|
+
},
|
|
532
|
+
});
|
|
533
|
+
if (!membership) {
|
|
534
|
+
throw new BadDataException(`Cannot create a notification rule for user ${data.targetUserId.toString()} because they are not a member of this project.`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* R3 — the anti-hijack invariant, and the single most important guard in this
|
|
539
|
+
* phase.
|
|
540
|
+
*
|
|
541
|
+
* A rule's method FK is the address its pages are delivered to. Its userId is
|
|
542
|
+
* whose pages select it. If those two can name different people, an admin
|
|
543
|
+
* editing a colleague's rule to point at the ADMIN's own webhook silently
|
|
544
|
+
* redirects that colleague's pages, and every surface either of them can see
|
|
545
|
+
* still reports a healthy configuration.
|
|
546
|
+
*
|
|
547
|
+
* `ownerUserId` MUST be the rule's persisted owner, not a value out of the
|
|
548
|
+
* request body. On update the caller controls the body, so a body-supplied
|
|
549
|
+
* userId lets them claim the row is theirs while writing somebody else's; the
|
|
550
|
+
* callers in UserNotificationRuleService therefore re-read it from the
|
|
551
|
+
* database first, and pass what the database said.
|
|
552
|
+
*
|
|
553
|
+
* A method row that does not exist is rejected rather than ignored. "Not
|
|
554
|
+
* found" and "not yours" are the same answer here — in both cases the caller
|
|
555
|
+
* named a row they have no business naming — and a guard whose failure mode
|
|
556
|
+
* is `undefined === undefined` is a guard that opens on the one input it was
|
|
557
|
+
* written to reject.
|
|
558
|
+
*/
|
|
559
|
+
async assertNotificationMethodsBelongToUser(data) {
|
|
560
|
+
if (data.references.length === 0) {
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
if (!data.ownerUserId) {
|
|
564
|
+
/*
|
|
565
|
+
* An unowned rule is not a safe rule. Its userId decides whose pages
|
|
566
|
+
* select it, so a row that names an address but no owner is a row nobody
|
|
567
|
+
* can be shown and nobody can audit. Reject rather than skip the check.
|
|
568
|
+
*/
|
|
569
|
+
throw new BadDataException("A notification rule that names a notification method must have an owner.");
|
|
570
|
+
}
|
|
571
|
+
const descriptorsByColumn = new Map();
|
|
572
|
+
for (const descriptor of this.getNotificationMethodDescriptors()) {
|
|
573
|
+
descriptorsByColumn.set(descriptor.idColumn, descriptor);
|
|
574
|
+
}
|
|
575
|
+
for (const reference of data.references) {
|
|
576
|
+
const descriptor = descriptorsByColumn.get(reference.idColumn);
|
|
577
|
+
if (!descriptor) {
|
|
578
|
+
/*
|
|
579
|
+
* Unreachable while references only ever come from
|
|
580
|
+
* collectNotificationMethodReferences, which builds them from this same
|
|
581
|
+
* table. Refusing an unknown column rather than skipping it keeps that
|
|
582
|
+
* true if the two ever drift.
|
|
583
|
+
*/
|
|
584
|
+
throw new BadDataException(`Unknown notification method column ${reference.idColumn}.`);
|
|
585
|
+
}
|
|
586
|
+
const methodOwnerUserId = await descriptor.findOwnerUserId(reference.methodId);
|
|
587
|
+
if (!methodOwnerUserId) {
|
|
588
|
+
throw new BadDataException(`The ${descriptor.label} notification method referenced by this rule does not exist.`);
|
|
589
|
+
}
|
|
590
|
+
if (methodOwnerUserId.toString() !== data.ownerUserId.toString()) {
|
|
591
|
+
/*
|
|
592
|
+
* The spelling is named at the end rather than woven into the sentence
|
|
593
|
+
* so that the wording support runbooks and tests match on stays intact.
|
|
594
|
+
* It earns its place because the two spellings are one column: told only
|
|
595
|
+
* "your Email method is wrong", a caller looking at a payload whose
|
|
596
|
+
* `userEmailId` is perfectly correct has no way to see that the relation
|
|
597
|
+
* slot beside it is the problem.
|
|
598
|
+
*/
|
|
599
|
+
throw new BadDataException(`The ${descriptor.label} notification method referenced by this rule belongs to a different user. A notification rule can only use notification methods owned by the user the rule belongs to. The offending value was sent in ${reference.suppliedColumn}.`);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* R6 — record and announce a change one person made to another person's
|
|
605
|
+
* paging configuration.
|
|
606
|
+
*
|
|
607
|
+
* Both halves are keyed on `props.userId` — the actor the SERVER resolved
|
|
608
|
+
* from the session — versus the row's PERSISTED userId, read back after the
|
|
609
|
+
* write. Nothing here reads the request body: the body is the thing under
|
|
610
|
+
* suspicion, and an audit line that an attacker can author is worse than no
|
|
611
|
+
* audit line, because it looks like evidence.
|
|
612
|
+
*
|
|
613
|
+
* Nothing in here may break the write. The row is already committed by the
|
|
614
|
+
* time this runs; throwing now would report a failure for a change that
|
|
615
|
+
* happened, and the caller would be entitled to believe it did not. So the
|
|
616
|
+
* whole body is a try/catch, and the mail is fire-and-forget on top of that.
|
|
617
|
+
*/
|
|
618
|
+
async recordAdminRuleChange(data) {
|
|
619
|
+
var _a, _b;
|
|
620
|
+
try {
|
|
621
|
+
/*
|
|
622
|
+
* The dependable half of the trail. AuditLogService below only writes on
|
|
623
|
+
* enterprise builds with audit logs switched on for the project, which is
|
|
624
|
+
* a minority of installs — and "an admin edited somebody else's paging"
|
|
625
|
+
* is exactly the event an operator needs to be able to find on the other
|
|
626
|
+
* ones too.
|
|
627
|
+
*/
|
|
628
|
+
logger.info(`On-call notification rule ${data.action.toLowerCase()}d for user ${data.ownerUserId.toString()} by a different user ${data.actorUserId.toString()}.`, {
|
|
629
|
+
projectId: (_a = data.projectId) === null || _a === void 0 ? void 0 : _a.toString(),
|
|
630
|
+
userId: data.ownerUserId.toString(),
|
|
631
|
+
actorUserId: data.actorUserId.toString(),
|
|
632
|
+
userNotificationRuleId: (_b = data.ruleId) === null || _b === void 0 ? void 0 : _b.toString(),
|
|
633
|
+
action: data.action,
|
|
634
|
+
});
|
|
635
|
+
await this.writeAuditLog(data);
|
|
636
|
+
if (!data.notifyOwner) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
/*
|
|
640
|
+
* Fire-and-forget by construction: the owner's mail involves three more
|
|
641
|
+
* reads and an SMTP round trip, none of which the writing request should
|
|
642
|
+
* wait on and none of which may surface as a failed write.
|
|
643
|
+
*/
|
|
644
|
+
this.notifyOwnerOfAdminChange({
|
|
645
|
+
action: data.action,
|
|
646
|
+
actorUserId: data.actorUserId,
|
|
647
|
+
ownerUserId: data.ownerUserId,
|
|
648
|
+
projectId: data.projectId,
|
|
649
|
+
}).catch((error) => {
|
|
650
|
+
logger.error(`UserNotificationRuleAdminService: failed to tell user ${data.ownerUserId.toString()} that an admin changed their on-call notification rules.`);
|
|
651
|
+
logger.error(error);
|
|
652
|
+
});
|
|
653
|
+
}
|
|
654
|
+
catch (error) {
|
|
655
|
+
logger.error("UserNotificationRuleAdminService: failed to record an administrative notification rule change.");
|
|
656
|
+
logger.error(error);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
/*
|
|
660
|
+
* The AuditLog analytics row, written directly rather than through
|
|
661
|
+
* DatabaseService's own audit hook.
|
|
662
|
+
*
|
|
663
|
+
* DatabaseService writes one automatically for models decorated with
|
|
664
|
+
* @EnableAuditLog, and UserNotificationRule is not one of them — so without
|
|
665
|
+
* this call an administrative edit leaves no row at all. The decorator is
|
|
666
|
+
* checked anyway so that adding it later produces one entry rather than two:
|
|
667
|
+
* a duplicated audit record is not merely noise, it makes a reader count two
|
|
668
|
+
* changes where one happened.
|
|
669
|
+
*
|
|
670
|
+
* Required lazily for the same reason DatabaseService requires it lazily —
|
|
671
|
+
* AuditLogService depends on ProjectService and UserService, both of which
|
|
672
|
+
* extend DatabaseService, so a top-level import can leave the base class
|
|
673
|
+
* undefined at class-extension time.
|
|
674
|
+
*/
|
|
675
|
+
async writeAuditLog(data) {
|
|
676
|
+
const model = new UserNotificationRule();
|
|
677
|
+
if (model.enableAuditLogOn) {
|
|
678
|
+
// DatabaseService already writes this row; a second one would double-count.
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const auditLogService =
|
|
682
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
|
|
683
|
+
require("./AuditLogService").default;
|
|
684
|
+
if (data.action === AuditLogAction.Create && data.after) {
|
|
685
|
+
await auditLogService.recordCreate({
|
|
686
|
+
model: model,
|
|
687
|
+
createdItem: data.after,
|
|
688
|
+
props: data.props,
|
|
689
|
+
});
|
|
690
|
+
return;
|
|
691
|
+
}
|
|
692
|
+
if (data.action === AuditLogAction.Update && data.before && data.ruleId) {
|
|
693
|
+
await auditLogService.recordUpdate({
|
|
694
|
+
model: model,
|
|
695
|
+
before: data.before,
|
|
696
|
+
updatedFields: data.updatedFields || {},
|
|
697
|
+
itemId: data.ruleId,
|
|
698
|
+
props: data.props,
|
|
699
|
+
});
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
/*
|
|
703
|
+
* Delete is the one action whose audit entry cannot be reconstructed after
|
|
704
|
+
* the fact. An edited row can still be read; a deleted one cannot, so the
|
|
705
|
+
* snapshot captured before the write is the entire record of what the
|
|
706
|
+
* responder's paging used to be.
|
|
707
|
+
*/
|
|
708
|
+
if (data.action === AuditLogAction.Delete && data.before && data.ruleId) {
|
|
709
|
+
await auditLogService.recordDelete({
|
|
710
|
+
model: model,
|
|
711
|
+
deletedItem: data.before,
|
|
712
|
+
itemId: data.ruleId,
|
|
713
|
+
props: data.props,
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
/*
|
|
718
|
+
* Tell the person whose pages just changed.
|
|
719
|
+
*
|
|
720
|
+
* This is the part of the phase that makes admin repair safe to hand out
|
|
721
|
+
* rather than merely possible: an admin fixing a colleague's rules is a
|
|
722
|
+
* normal, welcome thing, and an attacker redirecting them is not, and from
|
|
723
|
+
* the server's side those two are the same request. The only reliable way to
|
|
724
|
+
* tell them apart is to ask the one person who always knows which it was.
|
|
725
|
+
*/
|
|
726
|
+
async notifyOwnerOfAdminChange(data) {
|
|
727
|
+
var _a, _b;
|
|
728
|
+
const owner = await UserService.findOneById({
|
|
729
|
+
id: data.ownerUserId,
|
|
730
|
+
select: {
|
|
731
|
+
_id: true,
|
|
732
|
+
name: true,
|
|
733
|
+
email: true,
|
|
734
|
+
},
|
|
735
|
+
props: {
|
|
736
|
+
isRoot: true,
|
|
737
|
+
},
|
|
738
|
+
});
|
|
739
|
+
if (!owner || !owner.email) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
const actor = await UserService.findOneById({
|
|
743
|
+
id: data.actorUserId,
|
|
744
|
+
select: {
|
|
745
|
+
_id: true,
|
|
746
|
+
name: true,
|
|
747
|
+
email: true,
|
|
748
|
+
},
|
|
749
|
+
props: {
|
|
750
|
+
isRoot: true,
|
|
751
|
+
},
|
|
752
|
+
});
|
|
753
|
+
/*
|
|
754
|
+
* Naming the actor by email as well as by name is deliberate. Display names
|
|
755
|
+
* are not unique and are user-editable, so "Alex changed your rules" is not
|
|
756
|
+
* something the reader can act on; an address is.
|
|
757
|
+
*/
|
|
758
|
+
const actorDescription = actor
|
|
759
|
+
? `${((_a = actor.name) === null || _a === void 0 ? void 0 : _a.toString()) || "A project administrator"} (${((_b = actor.email) === null || _b === void 0 ? void 0 : _b.toString()) || data.actorUserId.toString()})`
|
|
760
|
+
: `A project administrator (${data.actorUserId.toString()})`;
|
|
761
|
+
let projectName = "your project";
|
|
762
|
+
if (data.projectId) {
|
|
763
|
+
const project = await ProjectService.findOneById({
|
|
764
|
+
id: data.projectId,
|
|
765
|
+
select: {
|
|
766
|
+
_id: true,
|
|
767
|
+
name: true,
|
|
768
|
+
},
|
|
769
|
+
props: {
|
|
770
|
+
isRoot: true,
|
|
771
|
+
},
|
|
772
|
+
});
|
|
773
|
+
if (project === null || project === void 0 ? void 0 : project.name) {
|
|
774
|
+
projectName = project.name;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
let verb = "changed";
|
|
778
|
+
if (data.action === AuditLogAction.Create) {
|
|
779
|
+
verb = "added";
|
|
780
|
+
}
|
|
781
|
+
if (data.action === AuditLogAction.Delete) {
|
|
782
|
+
verb = "deleted";
|
|
783
|
+
}
|
|
784
|
+
const subject = `Your on-call notification rules were ${verb} by an administrator`;
|
|
785
|
+
const settingsLink = data.projectId
|
|
786
|
+
? (await this.getNotificationRulesLinkInDashboard(data.projectId)).toString()
|
|
787
|
+
: "";
|
|
788
|
+
/*
|
|
789
|
+
* Deletion gets its own sentence rather than the generic one. "Somebody
|
|
790
|
+
* changed your rules" is a prompt to go and look; "you may no longer be
|
|
791
|
+
* paged" is the consequence, and it is the only one of the three actions
|
|
792
|
+
* that can leave a responder silently unreachable — which is the failure
|
|
793
|
+
* this whole epic exists to stop happening unnoticed.
|
|
794
|
+
*/
|
|
795
|
+
const consequence = data.action === AuditLogAction.Delete
|
|
796
|
+
? "Your notification rules decide how OneUptime reaches you when you are paged. With them removed you may no longer be notified when you are on call, so add new rules if this was not what you expected, and tell your project owners."
|
|
797
|
+
: "Your notification rules decide how OneUptime reaches you when you are paged. If you were not expecting this change, review your rules now and tell your project owners.";
|
|
798
|
+
const message = `${this.escapeHtml(actorDescription)} ${verb} your on-call notification rules in ${this.escapeHtml(projectName)}.<br/><br/>${consequence}${settingsLink
|
|
799
|
+
? `<br/><br/><a href="${this.escapeHtml(settingsLink)}">Review your notification rules</a>`
|
|
800
|
+
: ""}`;
|
|
801
|
+
const vars = {
|
|
802
|
+
subject: subject,
|
|
803
|
+
message: message,
|
|
804
|
+
};
|
|
805
|
+
await MailService.sendMail({
|
|
806
|
+
toEmail: owner.email,
|
|
807
|
+
templateType: EmailTemplateType.SimpleMessage,
|
|
808
|
+
vars: vars,
|
|
809
|
+
subject: subject,
|
|
810
|
+
}, {
|
|
811
|
+
projectId: data.projectId,
|
|
812
|
+
userId: owner.id,
|
|
813
|
+
});
|
|
814
|
+
}
|
|
815
|
+
async getNotificationRulesLinkInDashboard(projectId) {
|
|
816
|
+
const dashboardUrl = await DatabaseConfig.getDashboardUrl();
|
|
817
|
+
/*
|
|
818
|
+
* Spelled out rather than imported: Common/Server cannot reach the
|
|
819
|
+
* Dashboard's RouteMap, the same reason
|
|
820
|
+
* OnCallNotificationAlertingService.getNotificationRulesLinkInDashboard
|
|
821
|
+
* duplicates its path segments.
|
|
822
|
+
*/
|
|
823
|
+
return URL.fromString(dashboardUrl.toString()).addRoute(`/${projectId.toString()}/user-settings/notification-methods`);
|
|
824
|
+
}
|
|
825
|
+
/*
|
|
826
|
+
* SimpleMessage.hbs renders `message` through a triple-stache InfoBlock
|
|
827
|
+
* partial, so nothing between here and the recipient's inbox escapes
|
|
828
|
+
* anything. Project names and user names are attacker-influenced free text.
|
|
829
|
+
*/
|
|
830
|
+
escapeHtml(value) {
|
|
831
|
+
return value
|
|
832
|
+
.replace(/&/g, "&")
|
|
833
|
+
.replace(/</g, "<")
|
|
834
|
+
.replace(/>/g, ">")
|
|
835
|
+
.replace(/"/g, """)
|
|
836
|
+
.replace(/'/g, "'");
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
__decorate([
|
|
840
|
+
CaptureSpan(),
|
|
841
|
+
__metadata("design:type", Function),
|
|
842
|
+
__metadata("design:paramtypes", [Object]),
|
|
843
|
+
__metadata("design:returntype", Promise)
|
|
844
|
+
], UserNotificationRuleAdminService.prototype, "assertTargetUserIsProjectMember", null);
|
|
845
|
+
__decorate([
|
|
846
|
+
CaptureSpan(),
|
|
847
|
+
__metadata("design:type", Function),
|
|
848
|
+
__metadata("design:paramtypes", [Object]),
|
|
849
|
+
__metadata("design:returntype", Promise)
|
|
850
|
+
], UserNotificationRuleAdminService.prototype, "assertNotificationMethodsBelongToUser", null);
|
|
851
|
+
__decorate([
|
|
852
|
+
CaptureSpan(),
|
|
853
|
+
__metadata("design:type", Function),
|
|
854
|
+
__metadata("design:paramtypes", [Object]),
|
|
855
|
+
__metadata("design:returntype", Promise)
|
|
856
|
+
], UserNotificationRuleAdminService.prototype, "recordAdminRuleChange", null);
|
|
857
|
+
export default new UserNotificationRuleAdminService();
|
|
858
|
+
//# sourceMappingURL=UserNotificationRuleAdminService.js.map
|