@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,593 @@
|
|
|
1
|
+
import Redis, { ClientType } from "../Infrastructure/Redis";
|
|
2
|
+
import {
|
|
3
|
+
ExpressRequest,
|
|
4
|
+
ExpressResponse,
|
|
5
|
+
NextFunction,
|
|
6
|
+
OneUptimeRequest,
|
|
7
|
+
} from "../Utils/Express";
|
|
8
|
+
import logger, { getLogAttributesFromRequest } from "../Utils/Logger";
|
|
9
|
+
import resolveTrustedClientIp, { ClientIpRequestLike } from "../Utils/ClientIp";
|
|
10
|
+
import Response from "../Utils/Response";
|
|
11
|
+
import ObjectID from "../../Types/ObjectID";
|
|
12
|
+
import ServiceUnavailableException from "../../Types/Exception/ServiceUnavailableException";
|
|
13
|
+
import TooManyRequestsException from "../../Types/Exception/TooManyRequestsException";
|
|
14
|
+
|
|
15
|
+
/*
|
|
16
|
+
* Rate limiting for the anonymous public dashboard surface — every route
|
|
17
|
+
* Nginx exposes under /public-dashboard-api (rewritten to /api/dashboard
|
|
18
|
+
* before it reaches this process, so the prefix is not visible here; the
|
|
19
|
+
* routes themselves are the surface).
|
|
20
|
+
*
|
|
21
|
+
* Why this exists: holding a public dashboard id was previously enough to
|
|
22
|
+
* drive unbounded ClickHouse and Postgres work — a 400-day SLO-style
|
|
23
|
+
* aggregation, or a metrics aggregation at the finest bucket interval,
|
|
24
|
+
* issued in a loop. /master-password was worse still: it verifies a bcrypt
|
|
25
|
+
* hash per request, so with no attempt limit it is an online
|
|
26
|
+
* password-guessing oracle that also burns a CPU-bound hash per guess.
|
|
27
|
+
*
|
|
28
|
+
* One limiter covers the whole surface rather than per-route budgets. The
|
|
29
|
+
* routes differ enormously in cost, but the thing being bounded is request
|
|
30
|
+
* volume from a single origin, and a uniform ceiling is the one an operator
|
|
31
|
+
* can reason about. Only /master-password gets its own, much tighter bucket,
|
|
32
|
+
* because it is the one route where the abuse is guessing rather than load.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
* Every request consumes TWO counters, and either one can reject it:
|
|
37
|
+
*
|
|
38
|
+
* - the dashboard counter, keyed on dashboard id + client IP. This is the
|
|
39
|
+
* budget an individual viewer of an individual dashboard gets.
|
|
40
|
+
*
|
|
41
|
+
* - the IP counter, keyed on client IP alone. Without this the dashboard
|
|
42
|
+
* counter is trivially bypassed: an attacker rotates the dashboard id on
|
|
43
|
+
* every request, lands in a fresh bucket every time, and still costs us a
|
|
44
|
+
* Postgres lookup per request even when every id is a 404. The IP counter
|
|
45
|
+
* is the ceiling that survives id rotation.
|
|
46
|
+
*
|
|
47
|
+
* Both are incremented on every request including a rejected one. That is
|
|
48
|
+
* standard fixed-window behaviour and it is deliberate: a client that keeps
|
|
49
|
+
* hammering keeps its window pinned rather than being handed a fresh
|
|
50
|
+
* allowance for free.
|
|
51
|
+
*/
|
|
52
|
+
export enum PublicDashboardRateLimitScope {
|
|
53
|
+
Dashboard = "dashboard",
|
|
54
|
+
Ip = "ip",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export enum PublicDashboardRateLimitBucket {
|
|
58
|
+
/* Every public dashboard read route. */
|
|
59
|
+
Read = "read",
|
|
60
|
+
|
|
61
|
+
/* /master-password only. Tighter, because each request costs a bcrypt. */
|
|
62
|
+
MasterPassword = "master-password",
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export enum PublicDashboardRateLimitOutcome {
|
|
66
|
+
Allowed = "allowed",
|
|
67
|
+
RateLimited = "rate-limited",
|
|
68
|
+
|
|
69
|
+
/* Redis is unreachable, so no limit can be honoured either way. */
|
|
70
|
+
CounterUnavailable = "counter-unavailable",
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface PublicDashboardRateLimitDecision {
|
|
74
|
+
outcome: PublicDashboardRateLimitOutcome;
|
|
75
|
+
retryAfterSeconds?: number | undefined;
|
|
76
|
+
|
|
77
|
+
/* Which of the two counters rejected, for logs. Unset unless rejected. */
|
|
78
|
+
scope?: PublicDashboardRateLimitScope | undefined;
|
|
79
|
+
|
|
80
|
+
/*
|
|
81
|
+
* True only on the request that first crossed the line in this window.
|
|
82
|
+
*
|
|
83
|
+
* The point of a limiter is that the caller keeps knocking, so logging
|
|
84
|
+
* every refusal turns a flood into a second flood in the log pipeline —
|
|
85
|
+
* the tool an operator needs to see the first one. Logging only the
|
|
86
|
+
* crossing gives exactly one line per key per window.
|
|
87
|
+
*/
|
|
88
|
+
isFirstRejectionInWindow?: boolean | undefined;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const parsePositiveIntFromEnv: (envKey: string, fallback: number) => number = (
|
|
92
|
+
envKey: string,
|
|
93
|
+
fallback: number,
|
|
94
|
+
): number => {
|
|
95
|
+
const rawValue: string | undefined = process.env[envKey];
|
|
96
|
+
|
|
97
|
+
if (!rawValue) {
|
|
98
|
+
return fallback;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const parsedValue: number = parseInt(rawValue, 10);
|
|
102
|
+
|
|
103
|
+
if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
|
|
104
|
+
return fallback;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return parsedValue;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
interface BucketConfig {
|
|
111
|
+
windowSeconds: number;
|
|
112
|
+
perDashboardLimit: number;
|
|
113
|
+
perIpLimit: number;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/*
|
|
117
|
+
* Read budget.
|
|
118
|
+
*
|
|
119
|
+
* Sized against the worst LEGITIMATE case rather than the typical one,
|
|
120
|
+
* because the key is dashboard + address and a great many viewers share one
|
|
121
|
+
* address. A public dashboard is often left open on office wall displays that
|
|
122
|
+
* auto-refresh: 40 widgets refreshing every 30s is ~80 requests/minute per
|
|
123
|
+
* display, and several displays plus ordinary viewers behind one corporate
|
|
124
|
+
* NAT all land in the same bucket. 600/minute covers roughly seven such
|
|
125
|
+
* displays at once.
|
|
126
|
+
*
|
|
127
|
+
* A limiter that fires on real viewers is worse than a slightly generous one,
|
|
128
|
+
* because the operator's fix is to turn it off. The number that matters is
|
|
129
|
+
* that "as fast as the attacker's loop runs" becomes a fixed ceiling at all —
|
|
130
|
+
* 600 versus the tens of thousands a loop manages — and operators who want it
|
|
131
|
+
* tighter have the environment variables below.
|
|
132
|
+
*/
|
|
133
|
+
const READ_BUCKET: BucketConfig = {
|
|
134
|
+
windowSeconds: parsePositiveIntFromEnv(
|
|
135
|
+
"PUBLIC_DASHBOARD_RATE_LIMIT_WINDOW_SECONDS",
|
|
136
|
+
60,
|
|
137
|
+
),
|
|
138
|
+
perDashboardLimit: parsePositiveIntFromEnv(
|
|
139
|
+
"PUBLIC_DASHBOARD_RATE_LIMIT_PER_DASHBOARD_PER_WINDOW",
|
|
140
|
+
600,
|
|
141
|
+
),
|
|
142
|
+
perIpLimit: parsePositiveIntFromEnv(
|
|
143
|
+
"PUBLIC_DASHBOARD_RATE_LIMIT_PER_IP_PER_WINDOW",
|
|
144
|
+
1800,
|
|
145
|
+
),
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
/*
|
|
149
|
+
* Master password budget. This is an authentication attempt counter, not a
|
|
150
|
+
* load control, so it is sized for humans rather than for load: 15 tries per
|
|
151
|
+
* 15 minutes covers a team behind one office address each mistyping a shared
|
|
152
|
+
* password, and still takes guessing from roughly 600 attempts a minute (what
|
|
153
|
+
* a bcrypt verify allows unthrottled) down to one a minute.
|
|
154
|
+
*/
|
|
155
|
+
const MASTER_PASSWORD_BUCKET: BucketConfig = {
|
|
156
|
+
windowSeconds: parsePositiveIntFromEnv(
|
|
157
|
+
"PUBLIC_DASHBOARD_MASTER_PASSWORD_RATE_LIMIT_WINDOW_SECONDS",
|
|
158
|
+
15 * 60,
|
|
159
|
+
),
|
|
160
|
+
perDashboardLimit: parsePositiveIntFromEnv(
|
|
161
|
+
"PUBLIC_DASHBOARD_MASTER_PASSWORD_RATE_LIMIT_PER_DASHBOARD_PER_WINDOW",
|
|
162
|
+
15,
|
|
163
|
+
),
|
|
164
|
+
perIpLimit: parsePositiveIntFromEnv(
|
|
165
|
+
"PUBLIC_DASHBOARD_MASTER_PASSWORD_RATE_LIMIT_PER_IP_PER_WINDOW",
|
|
166
|
+
45,
|
|
167
|
+
),
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
const KEY_PREFIX: string = "pdash:rl:";
|
|
171
|
+
|
|
172
|
+
/*
|
|
173
|
+
* Counter keys outlive their window by one full window, so a request landing
|
|
174
|
+
* on a boundary cannot read a key that was reclaimed mid-window.
|
|
175
|
+
*/
|
|
176
|
+
const TTL_MULTIPLIER: number = 2;
|
|
177
|
+
|
|
178
|
+
/* Bounds a Redis key built from attacker-supplied path segments. */
|
|
179
|
+
const MAX_KEY_SEGMENT_LENGTH: number = 64;
|
|
180
|
+
|
|
181
|
+
/* How often the "counter unavailable" condition may be logged, per bucket. */
|
|
182
|
+
const COUNTER_UNAVAILABLE_LOG_INTERVAL_MS: number = 60 * 1000;
|
|
183
|
+
|
|
184
|
+
const DOMAIN_PATTERN: RegExp =
|
|
185
|
+
/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)+$/i;
|
|
186
|
+
|
|
187
|
+
const MAX_DOMAIN_LENGTH: number = 253;
|
|
188
|
+
|
|
189
|
+
export default class PublicDashboardRateLimit {
|
|
190
|
+
/*
|
|
191
|
+
* The client address to bill this request to.
|
|
192
|
+
*
|
|
193
|
+
* Delegates to the shared ClientIp helper, which reads X-Forwarded-For from
|
|
194
|
+
* the trusted (right-hand) end under the instance-wide TRUSTED_PROXY_HOPS
|
|
195
|
+
* setting. Deliberately NOT Express.getClientIp: that one takes the LEFTMOST
|
|
196
|
+
* entry, which any caller can set by sending its own X-Forwarded-For header,
|
|
197
|
+
* and for a rate limiter that is fatal — a fresh spoofed value per request
|
|
198
|
+
* means a fresh bucket per request and no limit at all.
|
|
199
|
+
*
|
|
200
|
+
* Sharing the helper matters beyond deduplication. This limiter and the
|
|
201
|
+
* dashboard/status page IP allowlists must agree on who the caller is: a
|
|
202
|
+
* deployment behind an extra load balancer sets TRUSTED_PROXY_HOPS once, and
|
|
203
|
+
* if this middleware kept its own knob an operator who set the shared one
|
|
204
|
+
* would silently leave the limiter reading the balancer's address instead of
|
|
205
|
+
* the viewer's — collapsing every viewer behind that balancer into a single
|
|
206
|
+
* bucket and refusing them all.
|
|
207
|
+
*
|
|
208
|
+
* The helper also normalizes ports, brackets and IPv4-mapped IPv6, so the
|
|
209
|
+
* same viewer cannot land in two different buckets depending on the form
|
|
210
|
+
* their address arrives in.
|
|
211
|
+
*/
|
|
212
|
+
public static resolveClientIp(req: ExpressRequest): string {
|
|
213
|
+
const clientIp: string | undefined = resolveTrustedClientIp(
|
|
214
|
+
req as unknown as ClientIpRequestLike,
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
if (clientIp) {
|
|
218
|
+
return PublicDashboardRateLimit.sanitizeKeySegment(clientIp);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/*
|
|
222
|
+
* No address at all. Everything in this state shares one bucket, which
|
|
223
|
+
* is the conservative direction — an unidentifiable caller should not
|
|
224
|
+
* get its own private allowance.
|
|
225
|
+
*/
|
|
226
|
+
return "unknown";
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/*
|
|
230
|
+
* The dashboard this request is about, as a key segment.
|
|
231
|
+
*
|
|
232
|
+
* Routes name the parameter differently (:dashboardId on most,
|
|
233
|
+
* :dashboardIdOrDomain on /overview and /seo) and /domain carries it in the
|
|
234
|
+
* body instead, so all three are checked.
|
|
235
|
+
*
|
|
236
|
+
* Anything that is neither a valid id nor a plausible domain collapses to
|
|
237
|
+
* a single "invalid" bucket. That bounds Redis memory against a caller
|
|
238
|
+
* feeding junk path segments, and it is the right grouping anyway: those
|
|
239
|
+
* requests cannot correspond to a real dashboard, so sharing one small
|
|
240
|
+
* allowance between all of them is exactly what we want.
|
|
241
|
+
*
|
|
242
|
+
* Known and accepted: a dashboard reachable both by id and by custom domain
|
|
243
|
+
* has two keys, so a caller alternating the two forms gets twice the
|
|
244
|
+
* per-dashboard allowance. Resolving the domain to its id here would mean a
|
|
245
|
+
* database lookup on every request — the exact cost this middleware exists
|
|
246
|
+
* to avoid paying before the limit is checked — and the per-address ceiling
|
|
247
|
+
* below already bounds the total either way.
|
|
248
|
+
*/
|
|
249
|
+
public static resolveDashboardKey(req: ExpressRequest): string {
|
|
250
|
+
const candidates: Array<unknown> = [
|
|
251
|
+
req.params?.["dashboardId"],
|
|
252
|
+
req.params?.["dashboardIdOrDomain"],
|
|
253
|
+
(req.body as Record<string, unknown> | undefined)?.["domain"],
|
|
254
|
+
];
|
|
255
|
+
|
|
256
|
+
const raw: string | undefined = candidates.find(
|
|
257
|
+
(candidate: unknown): candidate is string => {
|
|
258
|
+
return typeof candidate === "string" && candidate.trim().length > 0;
|
|
259
|
+
},
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
if (!raw) {
|
|
263
|
+
return "none";
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const value: string = raw.trim();
|
|
267
|
+
|
|
268
|
+
if (ObjectID.isValidUUID(value)) {
|
|
269
|
+
return `id:${value.toLowerCase()}`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (value.length <= MAX_DOMAIN_LENGTH && DOMAIN_PATTERN.test(value)) {
|
|
273
|
+
return `dom:${value.toLowerCase()}`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return "invalid";
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private static sanitizeKeySegment(value: string): string {
|
|
280
|
+
return (
|
|
281
|
+
value
|
|
282
|
+
.slice(0, MAX_KEY_SEGMENT_LENGTH)
|
|
283
|
+
/*
|
|
284
|
+
* Redis keys are binary safe, but a predictable charset keeps
|
|
285
|
+
* operational tooling (KEYS/SCAN patterns, dashboards) sane.
|
|
286
|
+
*/
|
|
287
|
+
.replace(/[^a-zA-Z0-9._:%\-[\]]/g, "_")
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
private static getBucketConfig(
|
|
292
|
+
bucket: PublicDashboardRateLimitBucket,
|
|
293
|
+
): BucketConfig {
|
|
294
|
+
return bucket === PublicDashboardRateLimitBucket.MasterPassword
|
|
295
|
+
? MASTER_PASSWORD_BUCKET
|
|
296
|
+
: READ_BUCKET;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/*
|
|
300
|
+
* Increment both counters for this request and decide.
|
|
301
|
+
*
|
|
302
|
+
* Both INCRs go out in one pipeline so the common path costs a single
|
|
303
|
+
* round trip; the EXPIRE follow-ups only happen on the request that
|
|
304
|
+
* created a key.
|
|
305
|
+
*/
|
|
306
|
+
public static async consume(data: {
|
|
307
|
+
dashboardKey: string;
|
|
308
|
+
clientIp: string;
|
|
309
|
+
bucket: PublicDashboardRateLimitBucket;
|
|
310
|
+
}): Promise<PublicDashboardRateLimitDecision> {
|
|
311
|
+
const client: ClientType | null = Redis.getClient();
|
|
312
|
+
|
|
313
|
+
if (!client || !Redis.isConnected()) {
|
|
314
|
+
return { outcome: PublicDashboardRateLimitOutcome.CounterUnavailable };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const config: BucketConfig = PublicDashboardRateLimit.getBucketConfig(
|
|
318
|
+
data.bucket,
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
const windowMs: number = config.windowSeconds * 1000;
|
|
322
|
+
const windowIndex: number = Math.floor(Date.now() / windowMs);
|
|
323
|
+
|
|
324
|
+
const dashboardCounterKey: string = `${KEY_PREFIX}${data.bucket}:d:${data.dashboardKey}:${data.clientIp}:${windowIndex}`;
|
|
325
|
+
const ipCounterKey: string = `${KEY_PREFIX}${data.bucket}:i:${data.clientIp}:${windowIndex}`;
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
const pipelineResults: Array<[Error | null, unknown]> | null =
|
|
329
|
+
(await client
|
|
330
|
+
.pipeline()
|
|
331
|
+
.incr(dashboardCounterKey)
|
|
332
|
+
.incr(ipCounterKey)
|
|
333
|
+
.exec()) as Array<[Error | null, unknown]> | null;
|
|
334
|
+
|
|
335
|
+
if (!pipelineResults || pipelineResults.length < 2) {
|
|
336
|
+
throw new Error("Rate limit pipeline returned no result");
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
const dashboardCount: number = PublicDashboardRateLimit.readCounterResult(
|
|
340
|
+
pipelineResults[0],
|
|
341
|
+
);
|
|
342
|
+
const ipCount: number = PublicDashboardRateLimit.readCounterResult(
|
|
343
|
+
pipelineResults[1],
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
/*
|
|
347
|
+
* Set the expiry only on the write that created the key. Re-issuing
|
|
348
|
+
* EXPIRE on every increment would slide the window forward for as long
|
|
349
|
+
* as the load continues, so the counter would never reset and a client
|
|
350
|
+
* that tripped the limit once could never recover.
|
|
351
|
+
*/
|
|
352
|
+
const ttlSeconds: number = config.windowSeconds * TTL_MULTIPLIER;
|
|
353
|
+
const keysToExpire: Array<string> = [];
|
|
354
|
+
|
|
355
|
+
if (dashboardCount === 1) {
|
|
356
|
+
keysToExpire.push(dashboardCounterKey);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
if (ipCount === 1) {
|
|
360
|
+
keysToExpire.push(ipCounterKey);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
if (keysToExpire.length > 0) {
|
|
364
|
+
const expirePipeline: ReturnType<ClientType["pipeline"]> =
|
|
365
|
+
client.pipeline();
|
|
366
|
+
|
|
367
|
+
for (const key of keysToExpire) {
|
|
368
|
+
expirePipeline.expire(key, ttlSeconds);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
await expirePipeline.exec();
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const retryAfterSeconds: number =
|
|
375
|
+
PublicDashboardRateLimit.getSecondsUntilWindowEnd(config.windowSeconds);
|
|
376
|
+
|
|
377
|
+
/*
|
|
378
|
+
* Dashboard counter is reported first when both are over, because it is
|
|
379
|
+
* the more specific of the two and the more useful thing to see in a log
|
|
380
|
+
* line.
|
|
381
|
+
*/
|
|
382
|
+
if (dashboardCount > config.perDashboardLimit) {
|
|
383
|
+
return {
|
|
384
|
+
outcome: PublicDashboardRateLimitOutcome.RateLimited,
|
|
385
|
+
retryAfterSeconds,
|
|
386
|
+
scope: PublicDashboardRateLimitScope.Dashboard,
|
|
387
|
+
isFirstRejectionInWindow:
|
|
388
|
+
dashboardCount === config.perDashboardLimit + 1,
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (ipCount > config.perIpLimit) {
|
|
393
|
+
return {
|
|
394
|
+
outcome: PublicDashboardRateLimitOutcome.RateLimited,
|
|
395
|
+
retryAfterSeconds,
|
|
396
|
+
scope: PublicDashboardRateLimitScope.Ip,
|
|
397
|
+
isFirstRejectionInWindow: ipCount === config.perIpLimit + 1,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return { outcome: PublicDashboardRateLimitOutcome.Allowed };
|
|
402
|
+
} catch (err) {
|
|
403
|
+
/*
|
|
404
|
+
* Throttled for the same reason as the middleware's unavailable branch:
|
|
405
|
+
* whatever broke Redis is unlikely to break it for one request only, and
|
|
406
|
+
* a per-request log line buries the incident it is reporting.
|
|
407
|
+
*/
|
|
408
|
+
if (PublicDashboardRateLimit.shouldLogCounterUnavailable(data.bucket)) {
|
|
409
|
+
logger.warn(
|
|
410
|
+
`PublicDashboardRateLimit: counter failed for ${data.dashboardKey}`,
|
|
411
|
+
);
|
|
412
|
+
logger.warn(err);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return { outcome: PublicDashboardRateLimitOutcome.CounterUnavailable };
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
private static readCounterResult(
|
|
420
|
+
result: [Error | null, unknown] | undefined,
|
|
421
|
+
): number {
|
|
422
|
+
if (!result) {
|
|
423
|
+
throw new Error("Rate limit counter returned no result");
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const [error, value] = result;
|
|
427
|
+
|
|
428
|
+
if (error) {
|
|
429
|
+
throw error;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (typeof value !== "number") {
|
|
433
|
+
throw new Error("Rate limit counter returned a non-numeric value");
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return value;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/*
|
|
440
|
+
* Remaining seconds in the current fixed window, so every rejected caller
|
|
441
|
+
* is told to come back when the window actually rolls rather than all
|
|
442
|
+
* backing off by the same constant and re-colliding.
|
|
443
|
+
*/
|
|
444
|
+
private static getSecondsUntilWindowEnd(windowSeconds: number): number {
|
|
445
|
+
const windowMs: number = windowSeconds * 1000;
|
|
446
|
+
const msIntoWindow: number = Date.now() % windowMs;
|
|
447
|
+
|
|
448
|
+
return Math.max(1, Math.ceil((windowMs - msIntoWindow) / 1000));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/*
|
|
452
|
+
* Express middleware. Registered ahead of UserMiddleware on every public
|
|
453
|
+
* dashboard route so a flood is rejected before it costs a session lookup,
|
|
454
|
+
* let alone a database read.
|
|
455
|
+
*/
|
|
456
|
+
public static getMiddleware(
|
|
457
|
+
bucket: PublicDashboardRateLimitBucket = PublicDashboardRateLimitBucket.Read,
|
|
458
|
+
): (
|
|
459
|
+
req: ExpressRequest,
|
|
460
|
+
res: ExpressResponse,
|
|
461
|
+
next: NextFunction,
|
|
462
|
+
) => Promise<void> {
|
|
463
|
+
return async (
|
|
464
|
+
req: ExpressRequest,
|
|
465
|
+
res: ExpressResponse,
|
|
466
|
+
next: NextFunction,
|
|
467
|
+
): Promise<void> => {
|
|
468
|
+
const dashboardKey: string =
|
|
469
|
+
PublicDashboardRateLimit.resolveDashboardKey(req);
|
|
470
|
+
const clientIp: string = PublicDashboardRateLimit.resolveClientIp(req);
|
|
471
|
+
|
|
472
|
+
const decision: PublicDashboardRateLimitDecision =
|
|
473
|
+
await PublicDashboardRateLimit.consume({
|
|
474
|
+
dashboardKey,
|
|
475
|
+
clientIp,
|
|
476
|
+
bucket,
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
if (decision.outcome === PublicDashboardRateLimitOutcome.RateLimited) {
|
|
480
|
+
if (decision.retryAfterSeconds) {
|
|
481
|
+
PublicDashboardRateLimit.setRetryAfterHeader(
|
|
482
|
+
res,
|
|
483
|
+
decision.retryAfterSeconds,
|
|
484
|
+
);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (decision.isFirstRejectionInWindow) {
|
|
488
|
+
logger.warn(
|
|
489
|
+
`PublicDashboardRateLimit: rejected ${bucket} request for ${dashboardKey} from ${clientIp} (${decision.scope} limit)`,
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
return Response.sendErrorResponse(
|
|
494
|
+
req,
|
|
495
|
+
res,
|
|
496
|
+
new TooManyRequestsException(
|
|
497
|
+
bucket === PublicDashboardRateLimitBucket.MasterPassword
|
|
498
|
+
? "Too many password attempts. Please try again later."
|
|
499
|
+
: "Too many requests. Please try again later.",
|
|
500
|
+
),
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (
|
|
505
|
+
decision.outcome === PublicDashboardRateLimitOutcome.CounterUnavailable
|
|
506
|
+
) {
|
|
507
|
+
/*
|
|
508
|
+
* The two buckets fail in opposite directions, on purpose.
|
|
509
|
+
*
|
|
510
|
+
* Reads fail OPEN. These are unauthenticated read-only endpoints and
|
|
511
|
+
* the counter is a load control; blacking out every customer's public
|
|
512
|
+
* dashboard because Redis blipped is a worse outcome than an
|
|
513
|
+
* unbounded window for the duration of that blip, which is itself
|
|
514
|
+
* alarmed on.
|
|
515
|
+
*
|
|
516
|
+
* /master-password fails CLOSED. There the counter is not a load
|
|
517
|
+
* control, it is the only thing bounding password guesses. Serving
|
|
518
|
+
* the endpoint without it means serving an unlimited guessing oracle,
|
|
519
|
+
* so we answer 503 and let the viewer retry when Redis is back.
|
|
520
|
+
*/
|
|
521
|
+
if (bucket === PublicDashboardRateLimitBucket.MasterPassword) {
|
|
522
|
+
if (PublicDashboardRateLimit.shouldLogCounterUnavailable(bucket)) {
|
|
523
|
+
logger.error(
|
|
524
|
+
`PublicDashboardRateLimit: rate limit counter unavailable, refusing master password attempts for ${dashboardKey}`,
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
return Response.sendErrorResponse(
|
|
529
|
+
req,
|
|
530
|
+
res,
|
|
531
|
+
new ServiceUnavailableException(
|
|
532
|
+
"Unable to verify the password right now. Please try again shortly.",
|
|
533
|
+
),
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
if (PublicDashboardRateLimit.shouldLogCounterUnavailable(bucket)) {
|
|
538
|
+
logger.warn(
|
|
539
|
+
"PublicDashboardRateLimit: rate limit counter unavailable, allowing public dashboard reads unthrottled",
|
|
540
|
+
);
|
|
541
|
+
logger.warn(getLogAttributesFromRequest(req as OneUptimeRequest));
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return next();
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/*
|
|
550
|
+
* A Redis outage means EVERY request takes the unavailable path, so an
|
|
551
|
+
* unguarded log line there is one per request for as long as the outage
|
|
552
|
+
* lasts — the same log-flooding problem the crossing-only rejection log
|
|
553
|
+
* avoids, but continuous. One line per bucket per interval is enough to
|
|
554
|
+
* make the condition visible without burying everything else.
|
|
555
|
+
*/
|
|
556
|
+
private static shouldLogCounterUnavailable(
|
|
557
|
+
bucket: PublicDashboardRateLimitBucket,
|
|
558
|
+
): boolean {
|
|
559
|
+
const now: number = Date.now();
|
|
560
|
+
const lastLoggedAt: number =
|
|
561
|
+
PublicDashboardRateLimit.counterUnavailableLastLoggedAt.get(bucket) || 0;
|
|
562
|
+
|
|
563
|
+
if (now - lastLoggedAt < COUNTER_UNAVAILABLE_LOG_INTERVAL_MS) {
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
PublicDashboardRateLimit.counterUnavailableLastLoggedAt.set(bucket, now);
|
|
568
|
+
|
|
569
|
+
return true;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
private static counterUnavailableLastLoggedAt: Map<
|
|
573
|
+
PublicDashboardRateLimitBucket,
|
|
574
|
+
number
|
|
575
|
+
> = new Map();
|
|
576
|
+
|
|
577
|
+
private static setRetryAfterHeader(
|
|
578
|
+
res: ExpressResponse,
|
|
579
|
+
retryAfterSeconds: number,
|
|
580
|
+
): void {
|
|
581
|
+
const setHeader: unknown = (res as unknown as Record<string, unknown>)[
|
|
582
|
+
"setHeader"
|
|
583
|
+
];
|
|
584
|
+
|
|
585
|
+
if (typeof setHeader === "function") {
|
|
586
|
+
(setHeader as (name: string, value: string) => void).call(
|
|
587
|
+
res,
|
|
588
|
+
"Retry-After",
|
|
589
|
+
String(retryAfterSeconds),
|
|
590
|
+
);
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
}
|
|
@@ -323,6 +323,12 @@ export interface AILogRequest {
|
|
|
323
323
|
export interface AILogResponse {
|
|
324
324
|
content: string;
|
|
325
325
|
toolCalls?: Array<LLMToolCall> | undefined;
|
|
326
|
+
/*
|
|
327
|
+
* Why generation stopped, straight from the provider: "length" means the
|
|
328
|
+
* output hit the token cap, so callers can surface truncation instead of
|
|
329
|
+
* presenting a cut-off answer as complete.
|
|
330
|
+
*/
|
|
331
|
+
stopReason?: LLMCompletionResponse["stopReason"];
|
|
326
332
|
llmLog: LlmLog;
|
|
327
333
|
}
|
|
328
334
|
|
|
@@ -705,6 +711,7 @@ export class Service extends BaseService {
|
|
|
705
711
|
return {
|
|
706
712
|
content: response.content,
|
|
707
713
|
toolCalls: response.toolCalls,
|
|
714
|
+
stopReason: response.stopReason,
|
|
708
715
|
llmLog: savedLog,
|
|
709
716
|
};
|
|
710
717
|
} catch (error) {
|
|
@@ -20,6 +20,9 @@ import AlertEpisodeFeedService from "./AlertEpisodeFeedService";
|
|
|
20
20
|
import { AlertEpisodeFeedEventType } from "../../Models/DatabaseModels/AlertEpisodeFeed";
|
|
21
21
|
import Semaphore, { SemaphoreMutex } from "../Infrastructure/Semaphore";
|
|
22
22
|
import AlertEpisodeService from "./AlertEpisodeService";
|
|
23
|
+
import AlertEpisodeInternalNote from "../../Models/DatabaseModels/AlertEpisodeInternalNote";
|
|
24
|
+
import AlertEpisodeInternalNoteService from "./AlertEpisodeInternalNoteService";
|
|
25
|
+
import { JSONObject } from "../../Types/JSON";
|
|
23
26
|
|
|
24
27
|
export class Service extends DatabaseService<AlertEpisodeStateTimeline> {
|
|
25
28
|
public constructor() {
|
|
@@ -182,11 +185,21 @@ export class Service extends DatabaseService<AlertEpisodeStateTimeline> {
|
|
|
182
185
|
alertEpisodeId: createBy.data.alertEpisodeId?.toString(),
|
|
183
186
|
} as LogAttributes);
|
|
184
187
|
|
|
188
|
+
/*
|
|
189
|
+
* The note a user writes when they change the state. It is not a column
|
|
190
|
+
* on this model, so it travels alongside the create and becomes an
|
|
191
|
+
* internal note on the episode once the timeline row exists.
|
|
192
|
+
*/
|
|
193
|
+
const privateNote: string | undefined = (
|
|
194
|
+
createBy.miscDataProps as JSONObject | undefined
|
|
195
|
+
)?.["privateNote"] as string | undefined;
|
|
196
|
+
|
|
185
197
|
return {
|
|
186
198
|
createBy,
|
|
187
199
|
carryForward: {
|
|
188
200
|
statusTimelineBeforeThisStatus: stateBeforeThis || null,
|
|
189
201
|
statusTimelineAfterThisStatus: stateAfterThis || null,
|
|
202
|
+
privateNote: privateNote,
|
|
190
203
|
mutex: mutex,
|
|
191
204
|
},
|
|
192
205
|
};
|
|
@@ -433,6 +446,22 @@ export class Service extends DatabaseService<AlertEpisodeStateTimeline> {
|
|
|
433
446
|
},
|
|
434
447
|
});
|
|
435
448
|
|
|
449
|
+
if (onCreate.carryForward.privateNote) {
|
|
450
|
+
const privateNote: string = onCreate.carryForward.privateNote;
|
|
451
|
+
|
|
452
|
+
const episodeInternalNote: AlertEpisodeInternalNote =
|
|
453
|
+
new AlertEpisodeInternalNote();
|
|
454
|
+
episodeInternalNote.alertEpisodeId = createdItem.alertEpisodeId;
|
|
455
|
+
episodeInternalNote.note = privateNote;
|
|
456
|
+
episodeInternalNote.createdAt = createdItem.startsAt!;
|
|
457
|
+
episodeInternalNote.projectId = createdItem.projectId!;
|
|
458
|
+
|
|
459
|
+
await AlertEpisodeInternalNoteService.create({
|
|
460
|
+
data: episodeInternalNote,
|
|
461
|
+
props: onCreate.createBy.props,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
|
|
436
465
|
return createdItem;
|
|
437
466
|
}
|
|
438
467
|
|