@oneuptime/common 12.0.7 → 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.
Files changed (873) hide show
  1. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +1 -1
  2. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
  3. package/Models/DatabaseModels/AIConversation.ts +32 -0
  4. package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
  5. package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
  6. package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
  7. package/Models/DatabaseModels/Index.ts +12 -4
  8. package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +184 -9
  9. package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
  10. package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +33 -7
  11. package/Models/DatabaseModels/NetworkDevice.ts +141 -0
  12. package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
  13. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
  14. package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
  15. package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
  16. package/Models/DatabaseModels/Project.ts +78 -0
  17. package/Models/DatabaseModels/UserCall.ts +42 -0
  18. package/Models/DatabaseModels/UserEmail.ts +44 -0
  19. package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
  20. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
  21. package/Models/DatabaseModels/UserPush.ts +49 -0
  22. package/Models/DatabaseModels/UserSMS.ts +43 -0
  23. package/Models/DatabaseModels/UserTelegram.ts +59 -0
  24. package/Models/DatabaseModels/UserWebhook.ts +52 -0
  25. package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
  26. package/Models/DatabaseModels/WorkflowLog.ts +38 -0
  27. package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
  28. package/Server/API/AIChatAPI.ts +315 -1
  29. package/Server/API/DashboardAPI.ts +217 -1
  30. package/Server/API/OnCallReadinessAPI.ts +841 -0
  31. package/Server/API/TeamComplianceAPI.ts +69 -17
  32. package/Server/API/TelemetryAPI.ts +220 -12
  33. package/Server/API/UserAPI.ts +16 -1
  34. package/Server/EnvironmentConfig.ts +52 -0
  35. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +24 -0
  51. package/Server/Infrastructure/Queue.ts +78 -13
  52. package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
  53. package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
  54. package/Server/Services/AIService.ts +7 -0
  55. package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
  56. package/Server/Services/AlertSeverityService.ts +63 -0
  57. package/Server/Services/DashboardService.ts +9 -10
  58. package/Server/Services/DatabaseService.ts +32 -2
  59. package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
  60. package/Server/Services/IncidentSeverityService.ts +76 -0
  61. package/Server/Services/Index.ts +12 -4
  62. package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
  63. package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +7 -4
  64. package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +203 -21
  65. package/Server/Services/LogAggregationService.ts +45 -8
  66. package/Server/Services/MetricAggregationService.ts +121 -0
  67. package/Server/Services/MetricService.ts +7 -7
  68. package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
  69. package/Server/Services/NetworkDeviceLinkService.ts +84 -0
  70. package/Server/Services/NetworkDeviceService.ts +140 -0
  71. package/Server/Services/NetworkSiteService.ts +77 -25
  72. package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
  73. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
  74. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
  75. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
  76. package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
  77. package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
  78. package/Server/Services/OnCallReadinessService.ts +2803 -0
  79. package/Server/Services/OnCallSetupReminderService.ts +955 -0
  80. package/Server/Services/ProfileAggregationService.ts +123 -0
  81. package/Server/Services/StatusPageService.ts +9 -10
  82. package/Server/Services/TeamComplianceService.ts +429 -252
  83. package/Server/Services/UserCallService.ts +26 -1
  84. package/Server/Services/UserEmailService.ts +26 -1
  85. package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
  86. package/Server/Services/UserNotificationRuleService.ts +3812 -333
  87. package/Server/Services/UserOnCallLogService.ts +561 -48
  88. package/Server/Services/UserPushService.ts +29 -0
  89. package/Server/Services/UserService.ts +11 -0
  90. package/Server/Services/UserSmsService.ts +26 -1
  91. package/Server/Services/UserTelegramService.ts +24 -1
  92. package/Server/Services/UserWebhookService.ts +28 -1
  93. package/Server/Services/UserWhatsAppService.ts +24 -1
  94. package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
  95. package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
  96. package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
  97. package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
  98. package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
  99. package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
  100. package/Server/Types/Workflow/Components/API/Get.ts +1 -1
  101. package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
  102. package/Server/Types/Workflow/Components/API/Post.ts +1 -1
  103. package/Server/Types/Workflow/Components/API/Put.ts +1 -1
  104. package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
  105. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
  106. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
  107. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
  108. package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
  109. package/Server/Types/Workflow/Components/Email.ts +25 -7
  110. package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
  111. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
  112. package/Server/Types/Workflow/TriggerCode.ts +12 -0
  113. package/Server/Types/Workflow/Workflow.ts +5 -0
  114. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
  115. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
  116. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
  117. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
  118. package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
  119. package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
  120. package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
  121. package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
  122. package/Server/Utils/AI/Toolbox/Index.ts +48 -0
  123. package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
  124. package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
  125. package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
  126. package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
  127. package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
  128. package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
  129. package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
  130. package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
  131. package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
  132. package/Server/Utils/ClientIp.ts +221 -0
  133. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
  134. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
  135. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
  136. package/Server/Utils/Express.ts +12 -17
  137. package/Server/Utils/LLM/LLMService.ts +85 -8
  138. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
  139. package/Server/Utils/SSRFProtection.ts +98 -23
  140. package/Server/Utils/StartServer.ts +12 -3
  141. package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
  142. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
  143. package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
  144. package/Server/Utils/VM/VMAPI.ts +56 -8
  145. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
  146. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
  147. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
  148. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
  149. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
  150. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
  151. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
  152. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
  153. package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
  154. package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
  155. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
  156. package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
  157. package/Tests/Models/InventoryItemModel.test.ts +174 -0
  158. package/Tests/Models/InventoryItemNaming.test.ts +302 -0
  159. package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
  160. package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
  161. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
  162. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
  163. package/Tests/Server/API/Helpers.ts +24 -15
  164. package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
  165. package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
  166. package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
  167. package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
  168. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
  169. package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
  170. package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
  171. package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
  172. package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
  173. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
  174. package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
  175. package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
  176. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
  177. package/Tests/Server/Services/InventoryItemManualCreate.test.ts +248 -0
  178. package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
  179. package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
  180. package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
  181. package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
  182. package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
  183. package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
  184. package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
  185. package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
  186. package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
  187. package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
  188. package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
  189. package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
  190. package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
  191. package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
  192. package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
  193. package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
  194. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
  195. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
  196. package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
  197. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
  198. package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
  199. package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
  200. package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
  201. package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
  202. package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
  203. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
  204. package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
  205. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
  206. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
  207. package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
  208. package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
  209. package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
  210. package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
  211. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
  212. package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
  213. package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
  214. package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
  215. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
  216. package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
  217. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
  218. package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
  219. package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
  220. package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
  221. package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
  222. package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
  223. package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
  224. package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
  225. package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
  226. package/Tests/Server/Utils/ClientIp.test.ts +438 -0
  227. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
  228. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
  229. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
  230. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
  231. package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
  232. package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
  233. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
  234. package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
  235. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
  236. package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
  237. package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
  238. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
  239. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
  240. package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
  241. package/Tests/Types/IP/IP.test.ts +263 -0
  242. package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
  243. package/Tests/Types/IP/IPv6.test.ts +12 -1
  244. package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
  245. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
  246. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
  247. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
  248. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
  249. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
  250. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
  251. package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
  252. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
  253. package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
  254. package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
  255. package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
  256. package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
  257. package/Tests/Types/Workflow/TemplateSyntax.test.ts +491 -0
  258. package/Tests/Types/Workflow/Templates.test.ts +1218 -0
  259. package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
  260. package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
  261. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
  262. package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
  263. package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
  264. package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
  265. package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
  266. package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
  267. package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
  268. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
  269. package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
  270. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
  271. package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
  272. package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
  273. package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
  274. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
  275. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
  276. package/Tests/UI/Components/Workflow/GraphLint.test.ts +893 -0
  277. package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
  278. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +522 -0
  279. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +193 -0
  280. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +388 -0
  281. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +210 -0
  282. package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
  283. package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
  284. package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
  285. package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
  286. package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
  287. package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
  288. package/Tests/UI/EsbuildConfig.test.ts +607 -0
  289. package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
  290. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
  291. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
  292. package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
  293. package/Tests/UI/Utils/Platform.test.ts +147 -0
  294. package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
  295. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
  296. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
  297. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +727 -0
  298. package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
  299. package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
  300. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
  301. package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
  302. package/Tests/__mocks__/bullmq.js +55 -0
  303. package/Types/AI/AIChatMessageStatus.ts +8 -1
  304. package/Types/AI/AIChatTypes.ts +12 -0
  305. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
  306. package/Types/Exception/ExceptionCode.ts +2 -0
  307. package/Types/Exception/ServiceUnavailableException.ts +8 -0
  308. package/Types/Exception/TooManyRequestsException.ts +8 -0
  309. package/Types/IP/IP.ts +93 -47
  310. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +80 -3
  311. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
  312. package/Types/OnCallDutyPolicy/Layer.ts +203 -149
  313. package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
  314. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
  315. package/Types/Permission.ts +193 -0
  316. package/Types/SerializableObjectDictionary.ts +133 -39
  317. package/Types/Telemetry/EntityRelationshipType.ts +1 -1
  318. package/Types/Telemetry/EntitySource.ts +40 -0
  319. package/Types/Telemetry/EntityType.ts +28 -1
  320. package/Types/Telemetry/EntityTypeGroups.ts +65 -0
  321. package/Types/Workflow/Component.ts +29 -0
  322. package/Types/Workflow/Components/API.ts +35 -0
  323. package/Types/Workflow/Components/BaseModel.ts +77 -27
  324. package/Types/Workflow/Components/Discord.ts +1 -0
  325. package/Types/Workflow/Components/Email.ts +12 -3
  326. package/Types/Workflow/Components/JavaScript.ts +7 -0
  327. package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
  328. package/Types/Workflow/Components/Slack.ts +1 -0
  329. package/Types/Workflow/Components/Telegram.ts +1 -0
  330. package/Types/Workflow/StepTrace.ts +181 -0
  331. package/Types/Workflow/TemplateSyntax.ts +543 -0
  332. package/Types/Workflow/Templates.ts +2368 -0
  333. package/UI/Components/Calendar/Calendar.css +43 -0
  334. package/UI/Components/Calendar/Calendar.tsx +8 -0
  335. package/UI/Components/Card/Card.tsx +2 -2
  336. package/UI/Components/Checkbox/Checkbox.tsx +16 -0
  337. package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
  338. package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
  339. package/UI/Components/Dictionary/Dictionary.tsx +71 -15
  340. package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
  341. package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
  342. package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
  343. package/UI/Components/Forms/Types/Field.ts +7 -0
  344. package/UI/Components/Forms/Validation.ts +63 -1
  345. package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
  346. package/UI/Components/Input/Input.tsx +32 -3
  347. package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
  348. package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
  349. package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
  350. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
  351. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
  352. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
  353. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
  354. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
  355. package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
  356. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
  357. package/UI/Components/LogsViewer/types.ts +23 -0
  358. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
  359. package/UI/Components/Modal/Modal.tsx +37 -4
  360. package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
  361. package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
  362. package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
  363. package/UI/Components/Table/Table.tsx +49 -16
  364. package/UI/Components/Table/TableBody.tsx +53 -28
  365. package/UI/Components/Table/TableHeader.tsx +13 -0
  366. package/UI/Components/Table/TableRow.tsx +58 -26
  367. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
  368. package/UI/Components/Workflow/ArgumentsForm.tsx +341 -8
  369. package/UI/Components/Workflow/Component.tsx +28 -26
  370. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
  371. package/UI/Components/Workflow/ComponentSettingsModal.tsx +79 -9
  372. package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
  373. package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
  374. package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
  375. package/UI/Components/Workflow/GraphLint.ts +628 -0
  376. package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
  377. package/UI/Components/Workflow/ModelColumnEditor.tsx +528 -0
  378. package/UI/Components/Workflow/ModelSchema.ts +278 -0
  379. package/UI/Components/Workflow/RunForm.tsx +41 -7
  380. package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
  381. package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
  382. package/UI/Components/Workflow/UseRunWatch.ts +212 -0
  383. package/UI/Components/Workflow/Utils.ts +93 -1
  384. package/UI/Components/Workflow/VariableModal.tsx +6 -2
  385. package/UI/Components/Workflow/Workflow.tsx +126 -7
  386. package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
  387. package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
  388. package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
  389. package/UI/Types/LayeredDismissal.ts +31 -0
  390. package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
  391. package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
  392. package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
  393. package/UI/Utils/Platform.ts +149 -0
  394. package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
  395. package/UI/esbuild-config.js +22 -1
  396. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
  397. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
  398. package/Utils/Monitor/NetworkTopologyUtil.ts +917 -155
  399. package/Utils/Telemetry/CrossSignalScope.ts +502 -0
  400. package/Utils/Telemetry/EntityKey.ts +71 -5
  401. package/Utils/Telemetry/EntityRelationship.ts +1 -1
  402. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
  403. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
  404. package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
  405. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
  406. package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
  407. package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
  408. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
  409. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
  410. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
  411. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
  412. package/build/dist/Models/DatabaseModels/Index.js +12 -4
  413. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  414. package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +212 -29
  415. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
  416. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
  417. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
  418. package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +52 -25
  419. package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
  420. package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
  421. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  422. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
  423. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
  424. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
  425. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
  426. package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
  427. package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
  428. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
  429. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
  430. package/build/dist/Models/DatabaseModels/Project.js +80 -0
  431. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  432. package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
  433. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  434. package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
  435. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  436. package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
  437. package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
  438. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
  439. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  440. package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
  441. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  442. package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
  443. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  444. package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
  445. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  446. package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
  447. package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
  448. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
  449. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  450. package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
  451. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  452. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
  453. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  454. package/build/dist/Server/API/AIChatAPI.js +237 -1
  455. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  456. package/build/dist/Server/API/DashboardAPI.js +165 -13
  457. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  458. package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
  459. package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
  460. package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
  461. package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
  462. package/build/dist/Server/API/TelemetryAPI.js +129 -18
  463. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  464. package/build/dist/Server/API/UserAPI.js +16 -1
  465. package/build/dist/Server/API/UserAPI.js.map +1 -1
  466. package/build/dist/Server/EnvironmentConfig.js +45 -0
  467. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  468. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
  469. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  470. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
  471. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
  472. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
  473. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
  474. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
  475. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
  476. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
  477. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
  478. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
  479. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
  480. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
  481. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
  482. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
  483. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
  484. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
  485. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
  486. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
  487. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
  488. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
  489. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
  490. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
  491. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
  492. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
  493. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
  494. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
  495. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +24 -0
  496. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  497. package/build/dist/Server/Infrastructure/Queue.js +72 -13
  498. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  499. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
  500. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  501. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
  502. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
  503. package/build/dist/Server/Services/AIService.js +1 -0
  504. package/build/dist/Server/Services/AIService.js.map +1 -1
  505. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
  506. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  507. package/build/dist/Server/Services/AlertSeverityService.js +54 -0
  508. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  509. package/build/dist/Server/Services/DashboardService.js +10 -9
  510. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  511. package/build/dist/Server/Services/DatabaseService.js +24 -2
  512. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  513. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
  514. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  515. package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
  516. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  517. package/build/dist/Server/Services/Index.js +12 -4
  518. package/build/dist/Server/Services/Index.js.map +1 -1
  519. package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
  520. package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
  521. package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +9 -6
  522. package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
  523. package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +158 -23
  524. package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
  525. package/build/dist/Server/Services/LogAggregationService.js +27 -8
  526. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  527. package/build/dist/Server/Services/MetricAggregationService.js +80 -0
  528. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  529. package/build/dist/Server/Services/MetricService.js +6 -6
  530. package/build/dist/Server/Services/MetricService.js.map +1 -1
  531. package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
  532. package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
  533. package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
  534. package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
  535. package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
  536. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  537. package/build/dist/Server/Services/NetworkSiteService.js +53 -13
  538. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  539. package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
  540. package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
  541. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
  542. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  543. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
  544. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  545. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
  546. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  547. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
  548. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  549. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
  550. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
  551. package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
  552. package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
  553. package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
  554. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
  555. package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
  556. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
  557. package/build/dist/Server/Services/StatusPageService.js +11 -10
  558. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  559. package/build/dist/Server/Services/TeamComplianceService.js +312 -160
  560. package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
  561. package/build/dist/Server/Services/UserCallService.js +24 -1
  562. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  563. package/build/dist/Server/Services/UserEmailService.js +24 -1
  564. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  565. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
  566. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
  567. package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
  568. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  569. package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
  570. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  571. package/build/dist/Server/Services/UserPushService.js +26 -0
  572. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  573. package/build/dist/Server/Services/UserService.js +10 -0
  574. package/build/dist/Server/Services/UserService.js.map +1 -1
  575. package/build/dist/Server/Services/UserSmsService.js +24 -1
  576. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  577. package/build/dist/Server/Services/UserTelegramService.js +22 -1
  578. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  579. package/build/dist/Server/Services/UserWebhookService.js +25 -1
  580. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  581. package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
  582. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  583. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
  584. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  585. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
  586. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  587. package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
  588. package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
  589. package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
  590. package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
  591. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
  592. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  593. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
  594. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  595. package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
  596. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  597. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
  598. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  599. package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
  600. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  601. package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
  602. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  603. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
  604. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  605. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
  606. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  607. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
  608. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  609. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
  610. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
  611. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
  612. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
  613. package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
  614. package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
  615. package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
  616. package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
  617. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
  618. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  619. package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
  620. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
  621. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  622. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
  623. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  624. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
  625. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  626. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
  627. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  628. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
  629. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  630. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
  631. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
  632. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
  633. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  634. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
  635. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  636. package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
  637. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  638. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
  639. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
  640. package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
  641. package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
  642. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
  643. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
  644. package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
  645. package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
  646. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
  647. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
  648. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
  649. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
  650. package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
  651. package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
  652. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
  653. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
  654. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
  655. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
  656. package/build/dist/Server/Utils/ClientIp.js +137 -0
  657. package/build/dist/Server/Utils/ClientIp.js.map +1 -0
  658. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
  659. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  660. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
  661. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
  662. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
  663. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
  664. package/build/dist/Server/Utils/Express.js +12 -12
  665. package/build/dist/Server/Utils/Express.js.map +1 -1
  666. package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
  667. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  668. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
  669. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  670. package/build/dist/Server/Utils/SSRFProtection.js +82 -21
  671. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  672. package/build/dist/Server/Utils/StartServer.js +12 -4
  673. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  674. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
  675. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  676. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
  677. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
  678. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
  679. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  680. package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
  681. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  682. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
  683. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  684. package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
  685. package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
  686. package/build/dist/Types/AI/AIChatTypes.js +12 -0
  687. package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
  688. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
  689. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
  690. package/build/dist/Types/Exception/ExceptionCode.js +2 -0
  691. package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
  692. package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
  693. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
  694. package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
  695. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
  696. package/build/dist/Types/IP/IP.js +87 -43
  697. package/build/dist/Types/IP/IP.js.map +1 -1
  698. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
  699. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
  700. package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
  701. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  702. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
  703. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
  704. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
  705. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
  706. package/build/dist/Types/Permission.js +174 -0
  707. package/build/dist/Types/Permission.js.map +1 -1
  708. package/build/dist/Types/SerializableObjectDictionary.js +133 -39
  709. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  710. package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
  711. package/build/dist/Types/Telemetry/EntitySource.js +39 -0
  712. package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
  713. package/build/dist/Types/Telemetry/EntityType.js +28 -1
  714. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  715. package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
  716. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
  717. package/build/dist/Types/Workflow/Component.js +21 -0
  718. package/build/dist/Types/Workflow/Component.js.map +1 -1
  719. package/build/dist/Types/Workflow/Components/API.js +35 -0
  720. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  721. package/build/dist/Types/Workflow/Components/BaseModel.js +68 -26
  722. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  723. package/build/dist/Types/Workflow/Components/Discord.js +1 -0
  724. package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
  725. package/build/dist/Types/Workflow/Components/Email.js +12 -3
  726. package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
  727. package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
  728. package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
  729. package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
  730. package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
  731. package/build/dist/Types/Workflow/Components/Slack.js +1 -0
  732. package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
  733. package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
  734. package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
  735. package/build/dist/Types/Workflow/StepTrace.js +104 -0
  736. package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
  737. package/build/dist/Types/Workflow/TemplateSyntax.js +338 -0
  738. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
  739. package/build/dist/Types/Workflow/Templates.js +2111 -0
  740. package/build/dist/Types/Workflow/Templates.js.map +1 -0
  741. package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
  742. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  743. package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
  744. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  745. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
  746. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
  747. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
  748. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
  749. package/build/dist/UI/Components/Dictionary/Dictionary.js +47 -17
  750. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  751. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  752. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
  753. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  754. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
  755. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  756. package/build/dist/UI/Components/Forms/Validation.js +44 -0
  757. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  758. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
  759. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  760. package/build/dist/UI/Components/Input/Input.js +13 -4
  761. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  762. package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
  763. package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
  764. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
  765. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
  766. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
  767. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  768. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
  769. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  770. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
  771. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
  772. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
  773. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  774. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
  775. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  776. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
  777. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  778. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
  779. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  780. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
  781. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  782. package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
  783. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
  784. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  785. package/build/dist/UI/Components/Modal/Modal.js +31 -5
  786. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  787. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
  788. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  789. package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
  790. package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
  791. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
  792. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
  793. package/build/dist/UI/Components/Table/Table.js +27 -15
  794. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  795. package/build/dist/UI/Components/Table/TableBody.js +24 -18
  796. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  797. package/build/dist/UI/Components/Table/TableHeader.js +9 -1
  798. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  799. package/build/dist/UI/Components/Table/TableRow.js +29 -21
  800. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  801. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
  802. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  803. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +261 -14
  804. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  805. package/build/dist/UI/Components/Workflow/Component.js +20 -19
  806. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  807. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
  808. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  809. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +35 -7
  810. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  811. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
  812. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
  813. package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
  814. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  815. package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
  816. package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
  817. package/build/dist/UI/Components/Workflow/GraphLint.js +425 -0
  818. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
  819. package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
  820. package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
  821. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +320 -0
  822. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
  823. package/build/dist/UI/Components/Workflow/ModelSchema.js +156 -0
  824. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
  825. package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
  826. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  827. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
  828. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
  829. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
  830. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
  831. package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
  832. package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
  833. package/build/dist/UI/Components/Workflow/Utils.js +73 -1
  834. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  835. package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
  836. package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
  837. package/build/dist/UI/Components/Workflow/Workflow.js +92 -7
  838. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  839. package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
  840. package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
  841. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
  842. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
  843. package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
  844. package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
  845. package/build/dist/UI/Types/LayeredDismissal.js +21 -0
  846. package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
  847. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
  848. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  849. package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
  850. package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
  851. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
  852. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  853. package/build/dist/UI/Utils/Platform.js +118 -0
  854. package/build/dist/UI/Utils/Platform.js.map +1 -0
  855. package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
  856. package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
  857. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
  858. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
  859. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
  860. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
  861. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +661 -126
  862. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  863. package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
  864. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
  865. package/build/dist/Utils/Telemetry/EntityKey.js +57 -5
  866. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  867. package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
  868. package/jest.config.json +1 -0
  869. package/package.json +1 -1
  870. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
  871. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
  872. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
  873. package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
@@ -0,0 +1,1089 @@
1
+ import TeamMember from "../../../../../Models/DatabaseModels/TeamMember";
2
+ import UserCall from "../../../../../Models/DatabaseModels/UserCall";
3
+ import UserEmail from "../../../../../Models/DatabaseModels/UserEmail";
4
+ import UserNotificationRule from "../../../../../Models/DatabaseModels/UserNotificationRule";
5
+ import UserPush from "../../../../../Models/DatabaseModels/UserPush";
6
+ import UserSMS from "../../../../../Models/DatabaseModels/UserSMS";
7
+ import UserTelegram from "../../../../../Models/DatabaseModels/UserTelegram";
8
+ import UserWebhook from "../../../../../Models/DatabaseModels/UserWebhook";
9
+ import UserWhatsApp from "../../../../../Models/DatabaseModels/UserWhatsApp";
10
+ import BaseModel from "../../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
11
+ import DatabaseRequestType from "../../../../../Server/Types/BaseDatabase/DatabaseRequestType";
12
+ import TenantPermission from "../../../../../Server/Types/Database/Permissions/TenantPermission";
13
+ import Query from "../../../../../Server/Types/Database/Query";
14
+ import NotEqual from "../../../../../Types/BaseDatabase/NotEqual";
15
+ import DatabaseCommonInteractionProps from "../../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
16
+ import ColumnAccessControl from "../../../../../Types/Database/AccessControl/ColumnAccessControl";
17
+ import TableAccessControl from "../../../../../Types/Database/AccessControl/TableAccessControl";
18
+ import CurrentUserCanAccessRecordBy from "../../../../../Types/Database/CurrentUserCanAccessRecordBy";
19
+ import TableColumn from "../../../../../Types/Database/TableColumn";
20
+ import TableColumnType from "../../../../../Types/Database/TableColumnType";
21
+ import TenantColumn from "../../../../../Types/Database/TenantColumn";
22
+ import NotAuthorizedException from "../../../../../Types/Exception/NotAuthorizedException";
23
+ import ObjectID from "../../../../../Types/ObjectID";
24
+ import Permission from "../../../../../Types/Permission";
25
+
26
+ /*
27
+ * WHAT THIS FILE PINS
28
+ *
29
+ * On-call notification configuration - the rules themselves plus every channel
30
+ * they can fire through (email, SMS, call, push, WhatsApp, Telegram, webhook) -
31
+ * is row-scoped to its owner by one mechanism:
32
+ *
33
+ * @TableAccessControl({ ... [Permission.CurrentUser] ... })
34
+ * @CurrentUserCanAccessRecordBy("userId")
35
+ *
36
+ * TenantPermission.isAccessGrantedOnlyByCurrentUser() returns true whenever
37
+ * Permission.CurrentUser is the ONLY permission the caller holds that also
38
+ * appears in the model's table access control list. When it does,
39
+ * addCurrentUserScopeToQuery() rewrites the query to `userId = me`, and throws
40
+ * NotAuthorizedException outright if the caller had explicitly named somebody
41
+ * else. The FIRST group below is the standing proof that this still holds for a
42
+ * plain member on all eight models.
43
+ *
44
+ * GAP D in Internal/Roadmap/OnCallNotificationReadiness.md was the consequence
45
+ * for everybody else: a Project ADMIN was treated identically to a plain member
46
+ * on these tables, because ProjectAdmin appeared in none of these lists and so
47
+ * never landed in the intersection. There was no query an admin could issue
48
+ * that returned another user's notification configuration - not to audit it,
49
+ * not to repair it, not to see why a page went unanswered.
50
+ *
51
+ * IT WAS CLOSED ON THE RULE TABLE AND ONLY THERE. That boundary is the whole
52
+ * design and this file exists to keep it from being erased in either direction:
53
+ *
54
+ * - UserNotificationRule widens on ALL FOUR verbs. An administrator may read
55
+ * a member's rules, repair them, delete them, and provision one for a
56
+ * member who has none.
57
+ *
58
+ * - The SEVEN METHOD MODELS widen on NOTHING. All four lists are
59
+ * [CurrentUser], so an administrator is force-scoped onto their own rows
60
+ * there and is rejected outright for naming somebody else, on every verb -
61
+ * indistinguishable from a plain member.
62
+ *
63
+ * The read half of those seven WAS widened at one point, and reverting it is
64
+ * the most load-bearing fact in this file. The table scope is not one gate
65
+ * among several on these models; it is the only one. Every column on them
66
+ * declares `read: [Permission.CurrentUser]`, and that list is intersected by
67
+ * NAME against a permission set that always contains the auto-granted
68
+ * CurrentUser, so on its own it admits every authenticated caller. What made it
69
+ * mean "owner only" was the ownership predicate this file is about. Widening
70
+ * the table read deleted the predicate and with it the only row scope in the
71
+ * path; the column-level guard written to contain that was then walked past by
72
+ * nested relation selects, by `query` filters it never inspected, and by sort
73
+ * columns appended to the select after it had run.
74
+ *
75
+ * The administrator did not lose the diagnosis. OnCallReadinessService answers
76
+ * "can this colleague be paged" as root and returns ReadinessMethod
77
+ * { methodId, methodType, maskedIdentifier, isVerified }, masked server-side by
78
+ * the one code path that holds the raw value. methodId is a foreign key rather
79
+ * than a secret, so a rule can be pointed at a method without the method's row
80
+ * ever being read - which is exactly the capability the widening was reaching
81
+ * for.
82
+ *
83
+ * Row scoping is only half of what the rule-table widening moved, and the half
84
+ * this file does NOT cover. A nested relation select issued against an
85
+ * admin-wide read of UserNotificationRule reaches the method row without
86
+ * passing through the method table's list at all. That path is asserted
87
+ * end-to-end in AdminNotificationRuleAccess.test.ts; the column-list assertions
88
+ * at the bottom of this file are necessary but nowhere near sufficient on their
89
+ * own.
90
+ *
91
+ * Two further groups exist to keep the MECHANISM legible independently of the
92
+ * production decorators, so a future change cannot make the two agree by
93
+ * accident:
94
+ *
95
+ * - TeamMember carries the very same @CurrentUserCanAccessRecordBy("userId")
96
+ * decorator and has always listed ProjectOwner/ProjectAdmin in its read
97
+ * list. It is force-scoped for a member and unscoped for an admin. The
98
+ * ownership decorator was therefore never the thing scoping admins out -
99
+ * the absent permission entry was, which is why the rule table's fix is an
100
+ * entry in a list rather than a new gate, and why the seven methods stay
101
+ * scoped purely by having no such entry.
102
+ *
103
+ * - AdminReadableNotificationRuleModel below isolates the same shape on a
104
+ * throwaway class, with read and update widened and create and delete left
105
+ * alone. It demonstrates that the lift is granted PER OPERATION on a class
106
+ * whose lists match no shipping model, so the framework guarantee survives
107
+ * any future edit to a production one.
108
+ */
109
+
110
+ /*
111
+ * A throwaway stand-in for a user-scoped model, carrying ProjectAdmin on read
112
+ * and update only: same tenant column and same ownership column as the
113
+ * production models, but a combination of verbs that none of them use.
114
+ *
115
+ * It is deliberately not a copy of any shipping model - not of the rule table,
116
+ * whose four lists are all widened, and not of the seven methods, whose four
117
+ * lists are all closed. Its job is to pin the mechanism - the scope lifts for
118
+ * the operations whose list names a real permission and holds for the ones
119
+ * whose list does not - so that the production assertions above it are testing
120
+ * the models rather than re-testing the framework.
121
+ */
122
+ @TenantColumn("projectId")
123
+ @TableAccessControl({
124
+ create: [Permission.CurrentUser],
125
+ read: [Permission.CurrentUser, Permission.ProjectAdmin],
126
+ update: [Permission.CurrentUser, Permission.ProjectAdmin],
127
+ delete: [Permission.CurrentUser],
128
+ })
129
+ @CurrentUserCanAccessRecordBy("userId")
130
+ class AdminReadableNotificationRuleModel extends BaseModel {
131
+ @ColumnAccessControl({
132
+ create: [Permission.CurrentUser],
133
+ read: [Permission.CurrentUser, Permission.ProjectAdmin],
134
+ update: [],
135
+ })
136
+ @TableColumn({
137
+ type: TableColumnType.ObjectID,
138
+ title: "Project ID",
139
+ })
140
+ public projectId?: ObjectID = undefined;
141
+
142
+ @ColumnAccessControl({
143
+ create: [Permission.CurrentUser],
144
+ read: [Permission.CurrentUser, Permission.ProjectAdmin],
145
+ update: [],
146
+ })
147
+ @TableColumn({
148
+ type: TableColumnType.ObjectID,
149
+ title: "User ID",
150
+ })
151
+ public userId?: ObjectID = undefined;
152
+ }
153
+
154
+ type ModelTypeUnderTest = { new (): BaseModel };
155
+
156
+ /*
157
+ * The seven channels a rule can fire through. They are seven copies of one
158
+ * decorator shape, so every method assertion runs against all seven rather than
159
+ * against a representative one - a widening applied to one of them is exactly
160
+ * the kind of thing that survives review.
161
+ */
162
+ const NOTIFICATION_METHOD_MODELS: Array<ModelTypeUnderTest> = [
163
+ UserEmail,
164
+ UserSMS,
165
+ UserCall,
166
+ UserPush,
167
+ UserWhatsApp,
168
+ UserTelegram,
169
+ UserWebhook,
170
+ ];
171
+
172
+ /*
173
+ * Every model that makes up a user's on-call notification configuration.
174
+ *
175
+ * All eight behave identically for a plain member, which is what the first
176
+ * group asserts over this list. They diverge only in what an ADMINISTRATOR
177
+ * sees, so the admin-facing groups below name UserNotificationRule separately
178
+ * and iterate NOTIFICATION_METHOD_MODELS for the seven that stay closed.
179
+ */
180
+ const NOTIFICATION_CONFIG_MODELS: Array<ModelTypeUnderTest> = [
181
+ UserNotificationRule,
182
+ ...NOTIFICATION_METHOD_MODELS,
183
+ ];
184
+
185
+ const ROW_SCOPED_REQUEST_TYPES: Array<DatabaseRequestType> = [
186
+ DatabaseRequestType.Read,
187
+ DatabaseRequestType.Update,
188
+ DatabaseRequestType.Delete,
189
+ ];
190
+
191
+ /*
192
+ * The permissions the rule table gained, spelled out here rather than imported
193
+ * from the model. A test that reads the model's own constant would assert that
194
+ * the model equals itself; naming them independently means a change to a
195
+ * shipping list has to be re-stated deliberately in a test.
196
+ *
197
+ * On the seven method models these names appear only inside a `not.toContain`.
198
+ */
199
+ const ADMIN_READ_GRANTS: Array<Permission> = [
200
+ Permission.ProjectOwner,
201
+ Permission.ProjectAdmin,
202
+ Permission.ReadProjectUserNotificationRule,
203
+ ];
204
+
205
+ const ADMIN_WRITE_GRANTS: Array<Permission> = [
206
+ Permission.ProjectOwner,
207
+ Permission.ProjectAdmin,
208
+ Permission.EditProjectUserNotificationRule,
209
+ ];
210
+
211
+ const projectId: ObjectID = ObjectID.generate();
212
+ const callerUserId: ObjectID = ObjectID.generate();
213
+ const otherUserId: ObjectID = ObjectID.generate();
214
+
215
+ /*
216
+ * A plain project member. No tenant role at all - the permission machinery
217
+ * auto-grants Public and CurrentUser to any request that carries a userId.
218
+ */
219
+ function makeMemberProps(): DatabaseCommonInteractionProps {
220
+ return {
221
+ userId: callerUserId,
222
+ tenantId: projectId,
223
+ };
224
+ }
225
+
226
+ /*
227
+ * A caller holding Permission.ProjectAdmin for this tenant. This is the highest
228
+ * ordinary role in a project short of ProjectOwner.
229
+ */
230
+ function makeAdminProps(): DatabaseCommonInteractionProps {
231
+ return {
232
+ userId: callerUserId,
233
+ tenantId: projectId,
234
+ userTenantAccessPermission: {
235
+ [projectId.toString()]: {
236
+ projectId: projectId,
237
+ permissions: [
238
+ {
239
+ permission: Permission.ProjectAdmin,
240
+ labelIds: [],
241
+ isBlockPermission: false,
242
+ _type: "UserPermission",
243
+ },
244
+ ],
245
+ _type: "UserTenantAccessPermission",
246
+ },
247
+ },
248
+ };
249
+ }
250
+
251
+ describe("notification config models are row-scoped to their owner", () => {
252
+ it.each(NOTIFICATION_CONFIG_MODELS)(
253
+ "forces %p reads, updates and deletes onto the member's own rows",
254
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
255
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
256
+ const query: Query<BaseModel> =
257
+ await TenantPermission.addTenantScopeToQuery(
258
+ modelType,
259
+ {},
260
+ null,
261
+ makeMemberProps(),
262
+ requestType,
263
+ );
264
+
265
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
266
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
267
+ }
268
+ },
269
+ );
270
+
271
+ it.each(NOTIFICATION_CONFIG_MODELS)(
272
+ "rejects a member who explicitly names another user in a %p query",
273
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
274
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
275
+ await expect(
276
+ TenantPermission.addTenantScopeToQuery(
277
+ modelType,
278
+ { userId: otherUserId } as any,
279
+ null,
280
+ makeMemberProps(),
281
+ requestType,
282
+ ),
283
+ ).rejects.toThrow(NotAuthorizedException);
284
+ }
285
+ },
286
+ );
287
+
288
+ it.each(NOTIFICATION_CONFIG_MODELS)(
289
+ "leaves a member's own-userId %p filter intact rather than rejecting it",
290
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
291
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
292
+ const query: Query<BaseModel> =
293
+ await TenantPermission.addTenantScopeToQuery(
294
+ modelType,
295
+ { userId: callerUserId } as any,
296
+ null,
297
+ makeMemberProps(),
298
+ requestType,
299
+ );
300
+
301
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
302
+ }
303
+ },
304
+ );
305
+
306
+ it.each(NOTIFICATION_CONFIG_MODELS)(
307
+ "rejects a %p ownership filter disguised as a query operator",
308
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
309
+ /*
310
+ * NotEqual stringifies to the id it wraps, so a string comparison alone
311
+ * would let `userId != me` masquerade as the exact ownership predicate
312
+ * and widen the query to every other row in the project.
313
+ */
314
+ await expect(
315
+ TenantPermission.addTenantScopeToQuery(
316
+ modelType,
317
+ { userId: new NotEqual<string>(callerUserId.toString()) } as any,
318
+ null,
319
+ makeMemberProps(),
320
+ DatabaseRequestType.Read,
321
+ ),
322
+ ).rejects.toThrow(NotAuthorizedException);
323
+ },
324
+ );
325
+
326
+ it.each(NOTIFICATION_CONFIG_MODELS)(
327
+ "refuses a %p query when the caller has no user session at all",
328
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
329
+ /*
330
+ * An API key can carry the auto-granted CurrentUser permission without a
331
+ * userId. There is no id to convert into an ownership predicate, so the
332
+ * request must fail closed rather than run unscoped.
333
+ */
334
+ await expect(
335
+ TenantPermission.addTenantScopeToQuery(
336
+ modelType,
337
+ {},
338
+ null,
339
+ {
340
+ tenantId: projectId,
341
+ userGlobalAccessPermission: {
342
+ projectIds: [projectId],
343
+ globalPermissions: [Permission.Public, Permission.CurrentUser],
344
+ _type: "UserGlobalAccessPermission",
345
+ },
346
+ },
347
+ DatabaseRequestType.Read,
348
+ ),
349
+ ).rejects.toThrow(NotAuthorizedException);
350
+ },
351
+ );
352
+ });
353
+
354
+ /*
355
+ * A fan-out query comes back with its predicates already serialized. Each
356
+ * project is re-checked through BasePermission.checkPermissions, which runs
357
+ * QueryUtil.serializeQuery, and that rewrites an ObjectID-valued predicate into
358
+ * QueryHelper.equalTo() - a TypeORM Raw() FindOperator whose uuid does NOT live
359
+ * on `.value` (that slot holds the SQL-generator function) but in
360
+ * `.objectLiteralParameters` under a per-call random key (QueryUtil.ts:222-230,
361
+ * QueryHelper.ts:501-511). The id is therefore the sole VALUE in that bag
362
+ * rather than a value at a known key.
363
+ */
364
+ function boundIdOf(predicate: unknown): string | undefined {
365
+ const rawOperator:
366
+ | {
367
+ type?: string | undefined;
368
+ objectLiteralParameters?: Record<string, unknown> | undefined;
369
+ }
370
+ | undefined = predicate as
371
+ | {
372
+ type?: string | undefined;
373
+ objectLiteralParameters?: Record<string, unknown> | undefined;
374
+ }
375
+ | undefined;
376
+
377
+ if (!rawOperator || rawOperator.type !== "raw") {
378
+ return undefined;
379
+ }
380
+
381
+ const boundValues: Array<unknown> = Object.values(
382
+ rawOperator.objectLiteralParameters || {},
383
+ );
384
+
385
+ if (boundValues.length !== 1) {
386
+ return undefined;
387
+ }
388
+
389
+ return String(boundValues[0]);
390
+ }
391
+
392
+ describe("GAP D closed - the rule table opens to a ProjectAdmin on every verb", () => {
393
+ it("lifts the ownership scope on a ProjectAdmin's read, update and delete", async () => {
394
+ /*
395
+ * The inversion of the original GAP D assertion, and the reason the phase
396
+ * exists. Permission.ProjectAdmin now appears in UserNotificationRule's
397
+ * read, update and delete lists, so the intersection between what the admin
398
+ * holds and what the model accepts contains a real role rather than the
399
+ * auto-granted CurrentUser alone. isAccessGrantedOnlyByCurrentUser()
400
+ * returns false, no ownership predicate is stamped on, and the query comes
401
+ * back scoped to the PROJECT rather than to the caller - which is what lets
402
+ * an administrator list every member's rules and notice the member who has
403
+ * none.
404
+ *
405
+ * Delete is in this list on purpose rather than by inheritance. Removing a
406
+ * rule is how an administrator repairs a member whose paging is being
407
+ * swallowed by a stale opt-out row, and it is the only supported way to move
408
+ * a rule between owners now that the ownership column is frozen.
409
+ */
410
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
411
+ const query: Query<BaseModel> =
412
+ await TenantPermission.addTenantScopeToQuery(
413
+ UserNotificationRule,
414
+ {},
415
+ null,
416
+ makeAdminProps(),
417
+ requestType,
418
+ );
419
+
420
+ expect((query as any).userId).toBeUndefined();
421
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
422
+ }
423
+ });
424
+
425
+ it("lets a ProjectAdmin name another user on read, update and delete", async () => {
426
+ /*
427
+ * The other half of the same claim, and the half that used to throw. An
428
+ * unscoped query only proves the predicate is no longer stamped on; a query
429
+ * that NAMES the other user proves addCurrentUserScopeToQuery is no longer
430
+ * rejecting the attempt outright, which is what "there is no API by which an
431
+ * admin can read another user's rules" actually meant.
432
+ */
433
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
434
+ const query: Query<BaseModel> =
435
+ await TenantPermission.addTenantScopeToQuery(
436
+ UserNotificationRule,
437
+ { userId: otherUserId } as any,
438
+ null,
439
+ makeAdminProps(),
440
+ requestType,
441
+ );
442
+
443
+ expect((query as any).userId?.toString()).toBe(otherUserId.toString());
444
+ }
445
+ });
446
+
447
+ it("does not stamp a ProjectAdmin's UserNotificationRule create with their own userId", async () => {
448
+ /*
449
+ * Create widened too, which had to be decided rather than inherited. An
450
+ * administrator provisioning a rule for a member who has none is the single
451
+ * repair that matters most, and it is impossible if the framework stamps the
452
+ * administrator's own id onto the row.
453
+ *
454
+ * The framework deliberately says nothing about WHICH user may be named
455
+ * here - it only stops enforcing "you, and nobody else". The membership
456
+ * question (is this userId even in props.tenantId?) is answered in
457
+ * UserNotificationRuleService, not in this layer, and a passing assertion
458
+ * here must not be read as "on-behalf-of creation is safe".
459
+ */
460
+ const query: Query<UserNotificationRule> =
461
+ await TenantPermission.addTenantScopeToQuery(
462
+ UserNotificationRule,
463
+ {},
464
+ null,
465
+ makeAdminProps(),
466
+ DatabaseRequestType.Create,
467
+ );
468
+
469
+ expect((query as any).userId).toBeUndefined();
470
+ });
471
+
472
+ it("lifts the scope in the project where the caller is an admin and nowhere else", async () => {
473
+ /*
474
+ * When no single tenantId is supplied the permission layer fans the query
475
+ * out across every project the caller can see and re-checks each one
476
+ * independently. That per-project re-entry is the point: the lift follows
477
+ * the grant, so the project where the caller is merely a member still comes
478
+ * back carrying their own userId while the project where they are a full
479
+ * ProjectAdmin comes back with no ownership predicate at all.
480
+ *
481
+ * Asserted per-project rather than uniformly, because a single loop over
482
+ * both queries is how a fan-out bug that widens the WRONG project would go
483
+ * unnoticed.
484
+ */
485
+ const memberProjectId: ObjectID = ObjectID.generate();
486
+ const adminProjectId: ObjectID = ObjectID.generate();
487
+
488
+ const queries: Array<Record<string, unknown>> =
489
+ (await TenantPermission.addTenantScopeToQuery(
490
+ UserNotificationRule,
491
+ {},
492
+ null,
493
+ {
494
+ userId: callerUserId,
495
+ userGlobalAccessPermission: {
496
+ projectIds: [memberProjectId, adminProjectId],
497
+ globalPermissions: [Permission.Public, Permission.CurrentUser],
498
+ _type: "UserGlobalAccessPermission",
499
+ },
500
+ userTenantAccessPermission: {
501
+ [adminProjectId.toString()]: {
502
+ projectId: adminProjectId,
503
+ permissions: [
504
+ {
505
+ permission: Permission.ProjectAdmin,
506
+ labelIds: [],
507
+ isBlockPermission: false,
508
+ _type: "UserPermission",
509
+ },
510
+ ],
511
+ _type: "UserTenantAccessPermission",
512
+ },
513
+ },
514
+ },
515
+ DatabaseRequestType.Read,
516
+ )) as unknown as Array<Record<string, unknown>>;
517
+
518
+ expect(queries).toHaveLength(2);
519
+
520
+ const queryByProject: Record<string, Record<string, unknown>> = {};
521
+
522
+ for (const query of queries) {
523
+ const boundProjectId: string | undefined = boundIdOf(query["projectId"]);
524
+
525
+ expect(boundProjectId).toBeDefined();
526
+ queryByProject[boundProjectId as string] = query;
527
+ }
528
+
529
+ const memberProjectQuery: Record<string, unknown> | undefined =
530
+ queryByProject[memberProjectId.toString()];
531
+ const adminProjectQuery: Record<string, unknown> | undefined =
532
+ queryByProject[adminProjectId.toString()];
533
+
534
+ expect(memberProjectQuery).toBeDefined();
535
+ expect(adminProjectQuery).toBeDefined();
536
+
537
+ /*
538
+ * The member project keeps its ownership predicate - and keeps it in the
539
+ * serialized form, which matters beyond shape. TenantPermission
540
+ * .isExactUserScope() accepts only `string | ObjectID`, so a fan-out query
541
+ * fed back into addTenantScopeToQuery would be rejected as a disguised
542
+ * broad filter rather than recognised as the caller's own ownership
543
+ * predicate. The two paths are not round-trippable and no caller may assume
544
+ * they are.
545
+ */
546
+ expect(memberProjectQuery!["userId"]).toBeDefined();
547
+ expect(memberProjectQuery!["userId"]).not.toBeInstanceOf(ObjectID);
548
+ expect(boundIdOf(memberProjectQuery!["userId"])).toBe(
549
+ callerUserId.toString(),
550
+ );
551
+
552
+ // The admin project carries no ownership predicate in any form.
553
+ expect(adminProjectQuery!["userId"]).toBeUndefined();
554
+ });
555
+ });
556
+
557
+ describe("GAP D closed on the rule table alone - the seven methods open to nobody", () => {
558
+ /*
559
+ * THE BOUNDARY OF THE PHASE, AND THE PART MOST LIKELY TO BE "TIDIED UP"
560
+ * LATER, because seven models that differ from their sibling in all four
561
+ * lists look like an oversight rather than a decision.
562
+ *
563
+ * Two independent reasons keep them closed, and both have to be understood or
564
+ * one of them will be argued away.
565
+ *
566
+ * READ, because the table scope is the only row scope these models have. Each
567
+ * column on them declares `read: [Permission.CurrentUser]`, which is
568
+ * intersected by NAME against a permission set that always contains the
569
+ * auto-granted CurrentUser - so the column lists admit every authenticated
570
+ * caller on their own, and the ownership predicate stamped by this very
571
+ * mechanism is what makes them mean "owner only". Widen the table read and
572
+ * every column on every member's row in the project becomes readable: the
573
+ * webhook URL and its signing secret, the push device token, the Telegram
574
+ * chat id and its verification code. That shipped once and the column-level
575
+ * guard written to contain it did not hold.
576
+ *
577
+ * WRITE, because a rule is a pair - the ownership column decides whose pages
578
+ * select the row, the method relation decides where those pages are
579
+ * delivered. An administrator who could CREATE or EDIT a method on somebody
580
+ * else's account would hold a one-step paging hijack: register a phone or
581
+ * webhook you control on the victim, point their rules at it, and their pages
582
+ * arrive on your device.
583
+ *
584
+ * Neither restriction costs the administrator anything they actually need. A
585
+ * member with no methods must verify a device THEY own, which nobody can do
586
+ * for them, and "does this colleague have a verified method" is answered by
587
+ * OnCallReadinessService's masked payload without this table being read.
588
+ */
589
+
590
+ it.each(NOTIFICATION_METHOD_MODELS)(
591
+ "still stamps the ownership predicate on a ProjectAdmin's %p READ",
592
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
593
+ /*
594
+ * The inversion of the assertion this group used to open with. The read
595
+ * list is [CurrentUser], so a ProjectAdmin's intersection contains
596
+ * nothing but the auto-granted permission and the predicate is written
597
+ * onto their query exactly as onto a plain member's.
598
+ *
599
+ * This is the shape a leak arrives through rather than the named-target
600
+ * one below: an admin listing page asks for a project's methods rather
601
+ * than one member's, so it issues no userId at all and cannot be refused
602
+ * for naming the wrong one. The stamp is what makes that request
603
+ * harmless.
604
+ */
605
+ const query: Query<BaseModel> =
606
+ await TenantPermission.addTenantScopeToQuery(
607
+ modelType,
608
+ {},
609
+ null,
610
+ makeAdminProps(),
611
+ DatabaseRequestType.Read,
612
+ );
613
+
614
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
615
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
616
+ },
617
+ );
618
+
619
+ it.each(NOTIFICATION_METHOD_MODELS)(
620
+ "still rejects a ProjectAdmin who names another user's %p rows for read",
621
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
622
+ /*
623
+ * A hard NotAuthorizedException rather than a quiet redirect onto the
624
+ * admin's own rows. The refusal, not the redirect, is what makes "an
625
+ * administrator cannot see a colleague's notification methods" a
626
+ * statement about the API rather than about the UI that happens not to
627
+ * ask.
628
+ */
629
+ await expect(
630
+ TenantPermission.addTenantScopeToQuery(
631
+ modelType,
632
+ { userId: otherUserId } as any,
633
+ null,
634
+ makeAdminProps(),
635
+ DatabaseRequestType.Read,
636
+ ),
637
+ ).rejects.toThrow(NotAuthorizedException);
638
+ },
639
+ );
640
+
641
+ it.each(NOTIFICATION_METHOD_MODELS)(
642
+ "leaves a ProjectAdmin's own-userId %p filter intact on every verb",
643
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
644
+ /*
645
+ * The companion every refusal above needs, and the constraint a
646
+ * heavy-handed fix breaks. An administrator is a member too: they own
647
+ * notification methods, they manage them through these same endpoints,
648
+ * and a change that withheld these rows whenever the caller holds an
649
+ * administrator permission would satisfy every refusal in this group and
650
+ * break the administrator's own settings page.
651
+ *
652
+ * The claim is precisely that ProjectAdmin buys nothing here - not that
653
+ * it costs anything either.
654
+ */
655
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
656
+ const query: Query<BaseModel> =
657
+ await TenantPermission.addTenantScopeToQuery(
658
+ modelType,
659
+ { userId: callerUserId } as any,
660
+ null,
661
+ makeAdminProps(),
662
+ requestType,
663
+ );
664
+
665
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
666
+ }
667
+ },
668
+ );
669
+
670
+ it.each(NOTIFICATION_METHOD_MODELS)(
671
+ "still forces a ProjectAdmin's %p create, update and delete onto their own rows",
672
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
673
+ /*
674
+ * These three lists were never widened, and this is the assertion that
675
+ * says so. A ProjectAdmin's intersection here contains nothing but the
676
+ * auto-granted permission and they are scoped exactly like the plain
677
+ * member in the first group. An admin permission arriving in any of these
678
+ * three lists breaks this test, which is the entire point of keeping it.
679
+ */
680
+ for (const requestType of [
681
+ DatabaseRequestType.Create,
682
+ DatabaseRequestType.Update,
683
+ DatabaseRequestType.Delete,
684
+ ]) {
685
+ const query: Query<BaseModel> =
686
+ await TenantPermission.addTenantScopeToQuery(
687
+ modelType,
688
+ {},
689
+ null,
690
+ makeAdminProps(),
691
+ requestType,
692
+ );
693
+
694
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
695
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
696
+ }
697
+ },
698
+ );
699
+
700
+ it.each(NOTIFICATION_METHOD_MODELS)(
701
+ "still rejects a ProjectAdmin who explicitly targets another user's %p rows for write",
702
+ async (modelType: ModelTypeUnderTest): Promise<void> => {
703
+ /*
704
+ * A hard NotAuthorizedException rather than a quiet redirect, and here the
705
+ * difference is load-bearing beyond legibility: service hooks run before
706
+ * the final permission check, so silently rewriting the target would let a
707
+ * hook inspect one row while the database operation mutated a different
708
+ * one.
709
+ */
710
+ for (const requestType of [
711
+ DatabaseRequestType.Update,
712
+ DatabaseRequestType.Delete,
713
+ ]) {
714
+ await expect(
715
+ TenantPermission.addTenantScopeToQuery(
716
+ modelType,
717
+ { userId: otherUserId } as any,
718
+ null,
719
+ makeAdminProps(),
720
+ requestType,
721
+ ),
722
+ ).rejects.toThrow(NotAuthorizedException);
723
+ }
724
+ },
725
+ );
726
+ });
727
+
728
+ describe("TeamMember proves the mechanism - a listed admin permission lifts the scope", () => {
729
+ it("does not scope a ProjectAdmin's TeamMember read to their own userId", async () => {
730
+ /*
731
+ * TeamMember carries the identical @CurrentUserCanAccessRecordBy("userId")
732
+ * decorator as the notification models, and yet the admin walks away
733
+ * unscoped. The difference is one entry: ProjectAdmin appears in
734
+ * TeamMember's read list, so the intersection contains a real role and
735
+ * isAccessGrantedOnlyByCurrentUser() returns false.
736
+ *
737
+ * That is the whole of what the rule table gained, on a model that has
738
+ * always shipped it - which is why the fix there was an entry in a list
739
+ * rather than a new gate, and equally why the seven method models stay
740
+ * closed by simply having no such entry. Nothing guards them beyond the
741
+ * absence, so this group stays here as the independent statement of what
742
+ * the absence is doing.
743
+ */
744
+ const query: Query<TeamMember> =
745
+ await TenantPermission.addTenantScopeToQuery(
746
+ TeamMember,
747
+ {},
748
+ null,
749
+ makeAdminProps(),
750
+ DatabaseRequestType.Read,
751
+ );
752
+
753
+ expect((query as any).userId).toBeUndefined();
754
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
755
+ });
756
+
757
+ it("scopes a plain member's TeamMember read to their own userId", async () => {
758
+ const query: Query<TeamMember> =
759
+ await TenantPermission.addTenantScopeToQuery(
760
+ TeamMember,
761
+ {},
762
+ null,
763
+ makeMemberProps(),
764
+ DatabaseRequestType.Read,
765
+ );
766
+
767
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
768
+ });
769
+
770
+ it("lets a ProjectAdmin read another user's TeamMember rows without throwing", async () => {
771
+ const query: Query<TeamMember> =
772
+ await TenantPermission.addTenantScopeToQuery(
773
+ TeamMember,
774
+ { userId: otherUserId } as any,
775
+ null,
776
+ makeAdminProps(),
777
+ DatabaseRequestType.Read,
778
+ );
779
+
780
+ expect((query as any).userId?.toString()).toBe(otherUserId.toString());
781
+ });
782
+
783
+ it("rejects a plain member reading another user's TeamMember rows", async () => {
784
+ await expect(
785
+ TenantPermission.addTenantScopeToQuery(
786
+ TeamMember,
787
+ { userId: otherUserId } as any,
788
+ null,
789
+ makeMemberProps(),
790
+ DatabaseRequestType.Read,
791
+ ),
792
+ ).rejects.toThrow(NotAuthorizedException);
793
+ });
794
+
795
+ it("still scopes a ProjectAdmin's TeamMember UPDATE, because ProjectAdmin is not in the update list", async () => {
796
+ /*
797
+ * The exemption is granted per-operation, not per-model, and TeamMember
798
+ * demonstrates it on a shipping model. That is what makes the rule table's
799
+ * asymmetry expressible at all - read widened for one set of permissions,
800
+ * write for another - and what would let a future method model be opened on
801
+ * one verb without being opened on the rest, should anyone ever find a
802
+ * verb that is safe to open.
803
+ *
804
+ * TeamMember's update list is
805
+ * [ProjectOwner, InviteProjectTeamMembers, EditProjectTeam, CurrentUser] -
806
+ * ProjectAdmin is absent - so a caller holding ONLY ProjectAdmin is
807
+ * force-scoped on update even though they were unscoped on read.
808
+ */
809
+ const query: Query<TeamMember> =
810
+ await TenantPermission.addTenantScopeToQuery(
811
+ TeamMember,
812
+ {},
813
+ null,
814
+ makeAdminProps(),
815
+ DatabaseRequestType.Update,
816
+ );
817
+
818
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
819
+ });
820
+
821
+ it("does not row-scope a TeamMember delete at all, because CurrentUser is not in the delete list", async () => {
822
+ /*
823
+ * TeamMember's delete list omits CurrentUser entirely, so
824
+ * isAccessGrantedOnlyByCurrentUser() short-circuits to false before any
825
+ * ownership predicate is considered. Nothing is added to the query here -
826
+ * it is the separate table-level permission check that stops a plain
827
+ * member from deleting memberships.
828
+ */
829
+ const query: Query<TeamMember> =
830
+ await TenantPermission.addTenantScopeToQuery(
831
+ TeamMember,
832
+ {},
833
+ null,
834
+ makeMemberProps(),
835
+ DatabaseRequestType.Delete,
836
+ );
837
+
838
+ expect((query as any).userId).toBeUndefined();
839
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
840
+ });
841
+ });
842
+
843
+ describe("the lift mechanism in isolation, on a throwaway model", () => {
844
+ /*
845
+ * The production groups above assert what UserNotificationRule and the seven
846
+ * methods DO; this group asserts what the framework does with any user-scoped
847
+ * model, on a class whose lists match neither of them - all four widened on
848
+ * the rule table, all four closed on the methods, two-of-four here.
849
+ *
850
+ * That mismatch is the point. If a future change to TenantPermission alters
851
+ * the rule, this group fails on its own terms and says so, instead of the
852
+ * failure arriving disguised as eight models having drifted.
853
+ */
854
+
855
+ it("lifts the ownership scope for a ProjectAdmin on read and update", async () => {
856
+ for (const requestType of [
857
+ DatabaseRequestType.Read,
858
+ DatabaseRequestType.Update,
859
+ ]) {
860
+ const query: Query<BaseModel> =
861
+ await TenantPermission.addTenantScopeToQuery(
862
+ AdminReadableNotificationRuleModel,
863
+ {},
864
+ null,
865
+ makeAdminProps(),
866
+ requestType,
867
+ );
868
+
869
+ expect((query as any).userId).toBeUndefined();
870
+ expect((query as any).projectId?.toString()).toBe(projectId.toString());
871
+ }
872
+ });
873
+
874
+ it("lets a ProjectAdmin target another user's rows once the permission is listed", async () => {
875
+ const query: Query<BaseModel> =
876
+ await TenantPermission.addTenantScopeToQuery(
877
+ AdminReadableNotificationRuleModel,
878
+ { userId: otherUserId } as any,
879
+ null,
880
+ makeAdminProps(),
881
+ DatabaseRequestType.Read,
882
+ );
883
+
884
+ expect((query as any).userId?.toString()).toBe(otherUserId.toString());
885
+ });
886
+
887
+ it("keeps the ownership scope on a plain member for read, update and delete", async () => {
888
+ for (const requestType of ROW_SCOPED_REQUEST_TYPES) {
889
+ const query: Query<BaseModel> =
890
+ await TenantPermission.addTenantScopeToQuery(
891
+ AdminReadableNotificationRuleModel,
892
+ {},
893
+ null,
894
+ makeMemberProps(),
895
+ requestType,
896
+ );
897
+
898
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
899
+ }
900
+ });
901
+
902
+ it("still rejects a plain member targeting another user once admins are exempt", async () => {
903
+ await expect(
904
+ TenantPermission.addTenantScopeToQuery(
905
+ AdminReadableNotificationRuleModel,
906
+ { userId: otherUserId } as any,
907
+ null,
908
+ makeMemberProps(),
909
+ DatabaseRequestType.Read,
910
+ ),
911
+ ).rejects.toThrow(NotAuthorizedException);
912
+ });
913
+
914
+ it("keeps the delete scope on a ProjectAdmin, since delete was left CurrentUser-only", async () => {
915
+ /*
916
+ * The exemption is granted per-operation: adding ProjectAdmin to read and
917
+ * update alone leaves delete untouched. Proved here on a class whose lists
918
+ * nothing else depends on, so the guarantee survives any future edit to a
919
+ * production model - including the edit that would widen a notification
920
+ * method on one verb while believing the rest stay closed.
921
+ */
922
+ const query: Query<BaseModel> =
923
+ await TenantPermission.addTenantScopeToQuery(
924
+ AdminReadableNotificationRuleModel,
925
+ {},
926
+ null,
927
+ makeAdminProps(),
928
+ DatabaseRequestType.Delete,
929
+ );
930
+
931
+ expect((query as any).userId?.toString()).toBe(callerUserId.toString());
932
+ });
933
+ });
934
+
935
+ describe("notification config model decorators", () => {
936
+ it.each(NOTIFICATION_CONFIG_MODELS)(
937
+ "declares userId as %p's ownership column and projectId as its tenant column",
938
+ (modelType: ModelTypeUnderTest): void => {
939
+ const model: BaseModel = new modelType();
940
+
941
+ expect(model.getUserColumn()).toBe("userId");
942
+ expect(model.getTenantColumn()).toBe("projectId");
943
+ },
944
+ );
945
+
946
+ it("grants UserNotificationRule table access to CurrentUser plus the administrator grants, on all four verbs", () => {
947
+ /*
948
+ * Pinned literally rather than with `toContain`, and the direction matters:
949
+ * the failure mode worth catching on a widened list is an entry ARRIVING,
950
+ * not one going missing, and a containment check passes straight through the
951
+ * change it exists to catch.
952
+ *
953
+ * CurrentUser stays FIRST and stays present in every list. It is what keeps
954
+ * a plain member scoped to their own rows; drop it and the first group in
955
+ * this file - the one that proves members are still confined - stops being
956
+ * about anything.
957
+ */
958
+ const model: UserNotificationRule = new UserNotificationRule();
959
+
960
+ expect(model.getReadPermissions()).toEqual([
961
+ Permission.CurrentUser,
962
+ ...ADMIN_READ_GRANTS,
963
+ ]);
964
+ expect(model.getCreatePermissions()).toEqual([
965
+ Permission.CurrentUser,
966
+ ...ADMIN_WRITE_GRANTS,
967
+ ]);
968
+ expect(model.getUpdatePermissions()).toEqual([
969
+ Permission.CurrentUser,
970
+ ...ADMIN_WRITE_GRANTS,
971
+ ]);
972
+ expect(model.getDeletePermissions()).toEqual([
973
+ Permission.CurrentUser,
974
+ ...ADMIN_WRITE_GRANTS,
975
+ ]);
976
+ });
977
+
978
+ it.each(NOTIFICATION_METHOD_MODELS)(
979
+ "keeps all four of %p's table lists CurrentUser-only",
980
+ (modelType: ModelTypeUnderTest): void => {
981
+ /*
982
+ * The decorator-level statement of what the behavioural group above
983
+ * asserts. Both are needed: the behaviour is what actually protects a
984
+ * member, but a list can be widened by a refactor months before anybody
985
+ * writes a query that notices, and this fails on the commit that does it.
986
+ *
987
+ * READ IS THE ENTRY TO WATCH. It is the one that shipped widened and was
988
+ * reverted, so it is the one a later commit is most likely to re-add
989
+ * while "restoring the admin feature" - and re-adding it silently removes
990
+ * the row scope that every column on the model depends on. Neither
991
+ * ADMIN_READ_GRANTS nor ADMIN_WRITE_GRANTS belongs in any list on these
992
+ * seven; there is no verb on a notification method that an administrator
993
+ * may perform on somebody else's row.
994
+ */
995
+ const model: BaseModel = new modelType();
996
+
997
+ for (const list of [
998
+ model.getReadPermissions(),
999
+ model.getCreatePermissions(),
1000
+ model.getUpdatePermissions(),
1001
+ model.getDeletePermissions(),
1002
+ ]) {
1003
+ expect(list).toEqual([Permission.CurrentUser]);
1004
+ }
1005
+ },
1006
+ );
1007
+
1008
+ it.each(NOTIFICATION_CONFIG_MODELS)(
1009
+ "does not let %p be queried across tenants",
1010
+ (modelType: ModelTypeUnderTest): void => {
1011
+ /*
1012
+ * canQueryMultiTenant() is what would let a caller ask for rows without
1013
+ * naming a project. These models say no, so the fan-out path is the only
1014
+ * multi-project route and it re-checks permissions per project.
1015
+ */
1016
+ const model: BaseModel = new modelType();
1017
+
1018
+ expect(model.canQueryMultiTenant()).toBe(false);
1019
+ },
1020
+ );
1021
+
1022
+ it("keeps the UserNotificationRule ownership column unwritable after creation", () => {
1023
+ const model: UserNotificationRule = new UserNotificationRule();
1024
+
1025
+ expect(model.getColumnAccessControlFor("userId")?.update).toEqual([]);
1026
+ expect(model.getColumnAccessControlFor("user")?.update).toEqual([]);
1027
+ expect(model.getColumnAccessControlFor("projectId")?.update).toEqual([]);
1028
+ });
1029
+
1030
+ it("names no administrator permission on the webhook URL's read list", () => {
1031
+ /*
1032
+ * A webhook URL frequently carries its own bearer token in the path or
1033
+ * query string, so it is the most sensitive column in this group and no
1034
+ * admin permission may ever appear on its read list.
1035
+ *
1036
+ * NECESSARY, NOT SUFFICIENT - and the gap between the two is the trap the
1037
+ * reverted widening walked into. `read: [CurrentUser]` does not mean
1038
+ * "readable only on my own row": Permission.CurrentUser is auto-granted to
1039
+ * every authenticated caller and ColumnPermissions intersects by NAME
1040
+ * without ever seeing the query, so this list alone says nothing more than
1041
+ * "readable by anyone logged in". It is equivalent to owner-only only
1042
+ * because the TABLE list pins the row scope to the caller - which is why the
1043
+ * table assertions above are the ones doing the work, and why this one only
1044
+ * catches the cruder mistake of pasting the admin grants in here too.
1045
+ */
1046
+ const model: UserWebhook = new UserWebhook();
1047
+
1048
+ expect(model.getColumnAccessControlFor("webhookUrl")?.read).toEqual([
1049
+ Permission.CurrentUser,
1050
+ ]);
1051
+
1052
+ for (const grant of [...ADMIN_READ_GRANTS, ...ADMIN_WRITE_GRANTS]) {
1053
+ expect(model.getColumnAccessControlFor("webhookUrl")?.read).not.toContain(
1054
+ grant,
1055
+ );
1056
+ }
1057
+
1058
+ expect(model.getColumnAccessControlFor("webhookUrl")?.read).not.toContain(
1059
+ Permission.ProjectMember,
1060
+ );
1061
+ });
1062
+
1063
+ it("keeps UserWebhook's ownership column CurrentUser-only on read and unwritable on update", () => {
1064
+ /*
1065
+ * Widened on the read side once and reverted, so both halves are pinned
1066
+ * here for different reasons.
1067
+ *
1068
+ * READ went back to CurrentUser because there is no longer any question an
1069
+ * administrator can ask of this table. "Whose row is this" is only worth
1070
+ * answering to a caller who can reach somebody else's row, and none can;
1071
+ * leaving the ownership column widened would be a standing invitation to
1072
+ * re-widen the table so that the column meant something again.
1073
+ *
1074
+ * UPDATE stays empty for everybody, which is the more important half and was
1075
+ * never in question. A writable ownership column would let an administrator
1076
+ * RE-POINT an existing row at a different owner: take a webhook that already
1077
+ * points at an endpoint you control, move its userId to a colleague, and
1078
+ * their pages arrive at your endpoint. That is the create-side ownership
1079
+ * gate reopened through a different verb, and nothing at the row level
1080
+ * distinguishes it from a legitimate edit.
1081
+ */
1082
+ const model: UserWebhook = new UserWebhook();
1083
+
1084
+ expect(model.getColumnAccessControlFor("userId")?.read).toEqual([
1085
+ Permission.CurrentUser,
1086
+ ]);
1087
+ expect(model.getColumnAccessControlFor("userId")?.update).toEqual([]);
1088
+ });
1089
+ });