@oneuptime/common 12.0.6 → 12.0.8

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 (594) hide show
  1. package/Models/DatabaseModels/AIInsight.ts +1 -1
  2. package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
  3. package/Models/DatabaseModels/DeletedProject.ts +595 -0
  4. package/Models/DatabaseModels/Index.ts +2 -0
  5. package/Models/DatabaseModels/Monitor.ts +111 -0
  6. package/Models/DatabaseModels/Project.ts +3 -3
  7. package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
  8. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
  9. package/Models/DatabaseModels/WorkflowLog.ts +38 -0
  10. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
  11. package/Server/API/FileAPI.ts +15 -2
  12. package/Server/API/MicrosoftTeamsAPI.ts +6 -1
  13. package/Server/API/ProjectAPI.ts +214 -0
  14. package/Server/API/StatusPageAPI.ts +39 -6
  15. package/Server/API/UserAPI.ts +16 -1
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  22. package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
  23. package/Server/Services/AIAgentService.ts +20 -0
  24. package/Server/Services/DashboardDomainService.ts +73 -28
  25. package/Server/Services/DatabaseService.ts +1 -0
  26. package/Server/Services/DeletedProjectService.ts +138 -0
  27. package/Server/Services/FileService.ts +61 -0
  28. package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
  29. package/Server/Services/IncidentPublicNoteService.ts +18 -0
  30. package/Server/Services/Index.ts +2 -0
  31. package/Server/Services/MonitorService.ts +311 -0
  32. package/Server/Services/ProbeService.ts +20 -0
  33. package/Server/Services/ProjectService.ts +297 -1
  34. package/Server/Services/PushNotificationService.ts +71 -0
  35. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
  36. package/Server/Services/StatusPageAnnouncementService.ts +53 -0
  37. package/Server/Services/StatusPageDomainService.ts +73 -28
  38. package/Server/Services/TeamMemberService.ts +117 -12
  39. package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
  40. package/Server/Services/TelemetryEntityService.ts +114 -1
  41. package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
  42. package/Server/Services/UserWebhookService.ts +34 -109
  43. package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
  44. package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
  45. package/Server/Types/Database/DeleteById.ts +2 -0
  46. package/Server/Types/Database/DeleteOneBy.ts +6 -0
  47. package/Server/Types/Domain.ts +41 -0
  48. package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
  49. package/Server/Types/Workflow/Components/API/Get.ts +2 -1
  50. package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
  51. package/Server/Types/Workflow/Components/API/Post.ts +2 -1
  52. package/Server/Types/Workflow/Components/API/Put.ts +2 -1
  53. package/Server/Types/Workflow/Components/API/Utils.ts +85 -3
  54. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
  55. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
  56. package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
  57. package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
  58. package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
  59. package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
  60. package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
  61. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
  62. package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
  63. package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
  64. package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
  65. package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
  66. package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
  67. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
  68. package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
  69. package/Server/Types/Workflow/TriggerCode.ts +12 -0
  70. package/Server/Types/Workflow/Workflow.ts +5 -0
  71. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  72. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
  73. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
  74. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
  75. package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
  76. package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
  77. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
  78. package/Server/Utils/DataSource/EgressGuard.ts +176 -16
  79. package/Server/Utils/DataSource/HttpFetch.ts +6 -45
  80. package/Server/Utils/Execute.ts +8 -0
  81. package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
  82. package/Server/Utils/LLM/LLMService.ts +57 -12
  83. package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
  84. package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
  85. package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
  86. package/Server/Utils/Monitor/MonitorResource.ts +36 -0
  87. package/Server/Utils/Response.ts +142 -6
  88. package/Server/Utils/SSRFProtection.ts +273 -60
  89. package/Server/Utils/StartServer.ts +8 -0
  90. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
  91. package/Server/Utils/VM/VMAPI.ts +56 -8
  92. package/Server/Utils/VM/VMRunner.ts +88 -1
  93. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
  94. package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
  95. package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
  96. package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
  97. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
  98. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
  99. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
  100. package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
  101. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
  102. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
  103. package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
  104. package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
  105. package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
  106. package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
  107. package/Tests/Server/API/ProjectAPI.test.ts +299 -1
  108. package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
  109. package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
  110. package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
  111. package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
  112. package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
  113. package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
  114. package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
  115. package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
  116. package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
  117. package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
  118. package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
  119. package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
  120. package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
  121. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
  122. package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
  123. package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
  124. package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
  125. package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
  126. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
  127. package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
  128. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
  129. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
  130. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
  131. package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
  132. package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
  133. package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
  134. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
  135. package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
  136. package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
  137. package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
  138. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
  139. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
  140. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
  141. package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
  142. package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
  143. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
  144. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
  145. package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
  146. package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
  147. package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
  148. package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
  149. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
  150. package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
  151. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
  152. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
  153. package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
  154. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
  155. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
  156. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
  157. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
  158. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
  159. package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
  160. package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
  161. package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
  162. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
  163. package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
  164. package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
  165. package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
  166. package/Tests/Types/JSONFunctions.test.ts +252 -1
  167. package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
  168. package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
  169. package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
  170. package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
  171. package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
  172. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
  173. package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
  174. package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
  175. package/Tests/Types/Workflow/Templates.test.ts +403 -0
  176. package/Tests/UI/Components/404.test.tsx +1 -1
  177. package/Tests/UI/Components/Alert.test.tsx +1 -1
  178. package/Tests/UI/Components/Badge.test.tsx +1 -1
  179. package/Tests/UI/Components/BasicForm.test.tsx +39 -10
  180. package/Tests/UI/Components/Button.test.tsx +1 -1
  181. package/Tests/UI/Components/Card.test.tsx +1 -1
  182. package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
  183. package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
  184. package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
  185. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
  186. package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
  187. package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
  188. package/Tests/UI/Components/Dropdown.test.tsx +1 -1
  189. package/Tests/UI/Components/FilePicker.test.tsx +1 -1
  190. package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
  191. package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
  192. package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
  193. package/Tests/UI/Components/HiddenText.test.tsx +1 -1
  194. package/Tests/UI/Components/Input.test.tsx +1 -1
  195. package/Tests/UI/Components/Loader.test.tsx +1 -1
  196. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +43 -1
  197. package/Tests/UI/Components/MasterPage.test.tsx +1 -1
  198. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +579 -0
  199. package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
  200. package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
  201. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
  202. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
  203. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
  204. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
  205. package/Tests/UI/Components/NavBar.test.tsx +1 -1
  206. package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
  207. package/Tests/UI/Components/Pagination.test.tsx +1 -1
  208. package/Tests/UI/Components/Pill.test.tsx +1 -1
  209. package/Tests/UI/Components/Probe.test.tsx +1 -1
  210. package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
  211. package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
  212. package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
  213. package/Tests/UI/Components/SideOver.test.tsx +500 -6
  214. package/Tests/UI/Components/Tabs.test.tsx +1 -1
  215. package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
  216. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +50 -8
  217. package/Tests/UI/Components/TextArea.test.tsx +1 -1
  218. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
  219. package/Tests/UI/Components/Toast.test.tsx +1 -1
  220. package/Tests/UI/Components/Toggle.test.tsx +1 -1
  221. package/Tests/UI/Components/TopSection.test.tsx +1 -1
  222. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
  223. package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
  224. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
  225. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
  226. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
  227. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
  228. package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
  229. package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
  230. package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
  231. package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
  232. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
  233. package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
  234. package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
  235. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
  236. package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
  237. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
  238. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
  239. package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
  240. package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
  241. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
  242. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
  243. package/Tests/Utils/Realtime.test.ts +78 -0
  244. package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
  245. package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
  246. package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
  247. package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
  248. package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
  249. package/Types/AI/FixPullRequestCiStatus.ts +1 -1
  250. package/Types/AI/FixVerificationStatus.ts +2 -2
  251. package/Types/API/Hostname.ts +92 -4
  252. package/Types/API/URL.ts +43 -25
  253. package/Types/Billing/BalanceAdjustmentType.ts +14 -0
  254. package/Types/Billing/ProjectBalanceType.ts +13 -0
  255. package/Types/Domain.ts +26 -0
  256. package/Types/File/MimeType.ts +11 -0
  257. package/Types/JSONFunctions.ts +15 -0
  258. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
  259. package/Types/SerializableObjectDictionary.ts +133 -39
  260. package/Types/Telemetry/EntitySource.ts +40 -0
  261. package/Types/Telemetry/EntityType.ts +27 -0
  262. package/Types/Telemetry/EntityTypeGroups.ts +65 -0
  263. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
  264. package/Types/Workflow/Component.ts +29 -0
  265. package/Types/Workflow/Components/API.ts +35 -0
  266. package/Types/Workflow/Components/BaseModel.ts +96 -28
  267. package/Types/Workflow/StepTrace.ts +181 -0
  268. package/Types/Workflow/TemplateSyntax.ts +499 -0
  269. package/Types/Workflow/Templates.ts +316 -0
  270. package/Typings/Index.d.ts +12 -0
  271. package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
  272. package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
  273. package/UI/Components/Dictionary/Dictionary.tsx +23 -6
  274. package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
  275. package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
  276. package/UI/Components/Forms/Types/Field.ts +7 -0
  277. package/UI/Components/Forms/Validation.ts +63 -1
  278. package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
  279. package/UI/Components/Input/Input.tsx +31 -3
  280. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
  281. package/UI/Components/Modal/ConfirmModal.tsx +10 -5
  282. package/UI/Components/Modal/Modal.tsx +64 -51
  283. package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
  284. package/UI/Components/SideOver/SideOver.tsx +195 -68
  285. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
  286. package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
  287. package/UI/Components/Workflow/Component.tsx +28 -26
  288. package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
  289. package/UI/Components/Workflow/GraphLint.ts +591 -0
  290. package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
  291. package/UI/Components/Workflow/ModelSchema.ts +196 -0
  292. package/UI/Components/Workflow/RunForm.tsx +41 -7
  293. package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
  294. package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
  295. package/UI/Components/Workflow/Utils.ts +93 -1
  296. package/UI/Components/Workflow/Workflow.tsx +77 -4
  297. package/UI/Types/LayeredDismissal.ts +31 -0
  298. package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
  299. package/UI/Utils/PageScrollLock.ts +66 -0
  300. package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
  301. package/Utils/Dashboard/VariableInterpolation.ts +19 -1
  302. package/Utils/LegacySerializedArray.ts +60 -0
  303. package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
  304. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
  305. package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
  306. package/Utils/Telemetry/EntityKey.ts +66 -0
  307. package/Utils/Telemetry/SavedViewFilters.ts +88 -0
  308. package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
  309. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
  311. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
  313. package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
  314. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  315. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  316. package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
  317. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  318. package/build/dist/Models/DatabaseModels/Project.js +3 -3
  319. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  320. package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
  321. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
  322. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
  323. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
  324. package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
  325. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  326. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  327. package/build/dist/Server/API/FileAPI.js +14 -2
  328. package/build/dist/Server/API/FileAPI.js.map +1 -1
  329. package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
  330. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  331. package/build/dist/Server/API/ProjectAPI.js +157 -4
  332. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  333. package/build/dist/Server/API/StatusPageAPI.js +27 -3
  334. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  335. package/build/dist/Server/API/UserAPI.js +16 -1
  336. package/build/dist/Server/API/UserAPI.js.map +1 -1
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  349. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
  350. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  351. package/build/dist/Server/Services/AIAgentService.js +17 -0
  352. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  353. package/build/dist/Server/Services/DashboardDomainService.js +55 -18
  354. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  355. package/build/dist/Server/Services/DatabaseService.js +1 -0
  356. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  357. package/build/dist/Server/Services/DeletedProjectService.js +124 -0
  358. package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
  359. package/build/dist/Server/Services/FileService.js +52 -0
  360. package/build/dist/Server/Services/FileService.js.map +1 -1
  361. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
  362. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  363. package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
  364. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  365. package/build/dist/Server/Services/Index.js +2 -0
  366. package/build/dist/Server/Services/Index.js.map +1 -1
  367. package/build/dist/Server/Services/MonitorService.js +232 -0
  368. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  369. package/build/dist/Server/Services/ProbeService.js +17 -0
  370. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  371. package/build/dist/Server/Services/ProjectService.js +228 -6
  372. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  373. package/build/dist/Server/Services/PushNotificationService.js +56 -0
  374. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  375. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
  376. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  377. package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
  378. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  379. package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
  380. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  381. package/build/dist/Server/Services/TeamMemberService.js +97 -6
  382. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  383. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
  384. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  385. package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
  386. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  387. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
  388. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  389. package/build/dist/Server/Services/UserWebhookService.js +31 -87
  390. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  391. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
  392. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  393. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
  394. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  395. package/build/dist/Server/Types/Domain.js +37 -0
  396. package/build/dist/Server/Types/Domain.js.map +1 -1
  397. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
  398. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  399. package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
  400. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  401. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
  402. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  403. package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
  404. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  405. package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
  406. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  407. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +63 -2
  408. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  409. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
  410. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  411. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
  412. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  413. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
  414. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
  415. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
  416. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
  417. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
  418. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
  419. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
  420. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
  421. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
  422. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
  423. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
  424. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
  425. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
  426. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
  427. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
  428. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
  429. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
  430. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
  431. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
  432. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
  433. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
  434. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
  435. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
  436. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  437. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
  438. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
  439. package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
  440. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  441. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
  442. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
  443. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
  444. package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
  445. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
  446. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
  447. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
  448. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  449. package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
  450. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  451. package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
  452. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  453. package/build/dist/Server/Utils/Execute.js +2 -2
  454. package/build/dist/Server/Utils/Execute.js.map +1 -1
  455. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
  456. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
  457. package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
  458. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
  460. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  461. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
  462. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
  464. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  465. package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
  466. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  467. package/build/dist/Server/Utils/Response.js +112 -5
  468. package/build/dist/Server/Utils/Response.js.map +1 -1
  469. package/build/dist/Server/Utils/SSRFProtection.js +219 -53
  470. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  471. package/build/dist/Server/Utils/StartServer.js +7 -0
  472. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  473. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
  474. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
  475. package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
  476. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  477. package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
  478. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  479. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
  480. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  481. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
  482. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  483. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  484. package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
  485. package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
  486. package/build/dist/Types/API/Hostname.js +73 -4
  487. package/build/dist/Types/API/Hostname.js.map +1 -1
  488. package/build/dist/Types/API/URL.js +42 -24
  489. package/build/dist/Types/API/URL.js.map +1 -1
  490. package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
  491. package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
  492. package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
  493. package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
  494. package/build/dist/Types/Domain.js +22 -0
  495. package/build/dist/Types/Domain.js.map +1 -1
  496. package/build/dist/Types/File/MimeType.js +11 -0
  497. package/build/dist/Types/File/MimeType.js.map +1 -1
  498. package/build/dist/Types/JSONFunctions.js +14 -0
  499. package/build/dist/Types/JSONFunctions.js.map +1 -1
  500. package/build/dist/Types/SerializableObjectDictionary.js +133 -39
  501. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  502. package/build/dist/Types/Telemetry/EntitySource.js +39 -0
  503. package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
  504. package/build/dist/Types/Telemetry/EntityType.js +27 -0
  505. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  506. package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
  507. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
  508. package/build/dist/Types/Workflow/Component.js +21 -0
  509. package/build/dist/Types/Workflow/Component.js.map +1 -1
  510. package/build/dist/Types/Workflow/Components/API.js +35 -0
  511. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  512. package/build/dist/Types/Workflow/Components/BaseModel.js +87 -28
  513. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  514. package/build/dist/Types/Workflow/StepTrace.js +104 -0
  515. package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
  516. package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
  517. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
  518. package/build/dist/Types/Workflow/Templates.js +218 -0
  519. package/build/dist/Types/Workflow/Templates.js.map +1 -0
  520. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
  521. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
  522. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
  523. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
  524. package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
  525. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  526. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
  527. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  528. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
  529. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  530. package/build/dist/UI/Components/Forms/Validation.js +44 -0
  531. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  532. package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
  533. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
  534. package/build/dist/UI/Components/Input/Input.js +12 -4
  535. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  536. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
  537. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  538. package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
  539. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  540. package/build/dist/UI/Components/Modal/Modal.js +55 -39
  541. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  542. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
  543. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  544. package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
  545. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  546. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
  547. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  548. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
  549. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  550. package/build/dist/UI/Components/Workflow/Component.js +20 -19
  551. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  552. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
  553. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  554. package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
  555. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
  556. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
  557. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
  558. package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
  559. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
  560. package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
  561. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  562. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
  563. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
  564. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
  565. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
  566. package/build/dist/UI/Components/Workflow/Utils.js +73 -1
  567. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  568. package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
  569. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  570. package/build/dist/UI/Types/LayeredDismissal.js +21 -0
  571. package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
  572. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
  573. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  574. package/build/dist/UI/Utils/PageScrollLock.js +52 -0
  575. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
  576. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
  577. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
  578. package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
  579. package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
  580. package/build/dist/Utils/LegacySerializedArray.js +51 -0
  581. package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
  582. package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
  583. package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
  584. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
  585. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
  586. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
  587. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  588. package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
  589. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  590. package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
  591. package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
  592. package/jest.config.json +3 -0
  593. package/package.json +1 -1
  594. package/tsconfig.json +3 -1
@@ -1,18 +1,17 @@
1
1
  import CreateBy from "../Types/Database/CreateBy";
2
2
  import DeleteBy from "../Types/Database/DeleteBy";
3
- import { OnCreate, OnDelete } from "../Types/Database/Hooks";
3
+ import UpdateBy from "../Types/Database/UpdateBy";
4
+ import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
4
5
  import GreenlockUtil from "../Utils/Greenlock/Greenlock";
5
6
  import logger, { LogAttributes } from "../Utils/Logger";
6
7
  import DatabaseService from "./DatabaseService";
7
8
  import DomainService from "./DomainService";
8
9
  import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
9
10
  import HTTPResponse from "../../Types/API/HTTPResponse";
10
- import URL from "../../Types/API/URL";
11
11
  import LIMIT_MAX from "../../Types/Database/LimitMax";
12
12
  import BadDataException from "../../Types/Exception/BadDataException";
13
13
  import { JSONObject } from "../../Types/JSON";
14
14
  import ObjectID from "../../Types/ObjectID";
15
- import API from "../../Utils/API";
16
15
  import AcmeCertificate from "../../Models/DatabaseModels/AcmeCertificate";
17
16
  import DomainModel from "../../Models/DatabaseModels/Domain";
18
17
  import StatusPageDomain from "../../Models/DatabaseModels/StatusPageDomain";
@@ -22,11 +21,60 @@ import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
22
21
  import { StatusPageCNameRecord } from "../EnvironmentConfig";
23
22
  import Domain from "../Types/Domain";
24
23
 
24
+ const STATUS_PAGE_DOMAIN_EGRESS_LABEL: string = "Status page domain";
25
+
25
26
  export class Service extends DatabaseService<StatusPageDomain> {
26
27
  public constructor() {
27
28
  super(StatusPageDomain);
28
29
  }
29
30
 
31
+ /*
32
+ * Normalize a submitted subdomain and reject anything that is not a plain
33
+ * DNS label chain.
34
+ *
35
+ * fullDomain is built as `${subdomain}.${baseDomain}` and then interpolated
36
+ * into "https://" + fullDomain + "/status-page-api/..." — and URL parsing
37
+ * treats everything before the first "/" as the host. Without this check a
38
+ * subdomain of "169.254.169.254/latest/meta-data/#" hands an attacker the
39
+ * host, the port and the path of a request the certificate cron then makes
40
+ * unattended, every 15 minutes, from inside the cluster.
41
+ */
42
+ private static normalizeAndValidateSubdomain(
43
+ subdomain: string | undefined,
44
+ ): string {
45
+ const normalized: string = subdomain?.trim().toLowerCase() || "";
46
+
47
+ // "@" is the documented way to ask for the root domain.
48
+ if (normalized === "" || normalized === "@") {
49
+ return "";
50
+ }
51
+
52
+ if (!Domain.isValidSubdomain(normalized)) {
53
+ throw new BadDataException(
54
+ `Subdomain ${normalized} is not valid. Use a plain subdomain such as "status" — schemes, ports, paths and "/" are not allowed.`,
55
+ );
56
+ }
57
+
58
+ return normalized;
59
+ }
60
+
61
+ @CaptureSpan()
62
+ protected override async onBeforeUpdate(
63
+ updateBy: UpdateBy<StatusPageDomain>,
64
+ ): Promise<OnUpdate<StatusPageDomain>> {
65
+ /*
66
+ * Create-time validation alone leaves the value editable afterwards —
67
+ * subdomain is ProjectMember-updatable.
68
+ */
69
+ if (updateBy.data.subdomain !== undefined) {
70
+ updateBy.data.subdomain = Service.normalizeAndValidateSubdomain(
71
+ updateBy.data.subdomain as string,
72
+ );
73
+ }
74
+
75
+ return { updateBy, carryForward: null };
76
+ }
77
+
30
78
  @CaptureSpan()
31
79
  protected override async onBeforeCreate(
32
80
  createBy: CreateBy<StatusPageDomain>,
@@ -48,14 +96,11 @@ export class Service extends DatabaseService<StatusPageDomain> {
48
96
  );
49
97
  }
50
98
 
51
- let normalizedSubdomain: string =
52
- createBy.data.subdomain?.trim().toLowerCase() || "";
53
-
54
- if (normalizedSubdomain === "@") {
55
- normalizedSubdomain = "";
56
- }
99
+ createBy.data.subdomain = Service.normalizeAndValidateSubdomain(
100
+ createBy.data.subdomain,
101
+ );
57
102
 
58
- createBy.data.subdomain = normalizedSubdomain;
103
+ const normalizedSubdomain: string = createBy.data.subdomain;
59
104
 
60
105
  if (domain) {
61
106
  const baseDomain: string =
@@ -231,13 +276,13 @@ export class Service extends DatabaseService<StatusPageDomain> {
231
276
  ): Promise<boolean> {
232
277
  try {
233
278
  const result: HTTPErrorResponse | HTTPResponse<JSONObject> =
234
- await API.get({
235
- url: URL.fromString(
279
+ await Domain.getForDomainVerification({
280
+ url:
236
281
  "https://" +
237
- fulldomain +
238
- "/status-page-api/cname-verification/" +
239
- token,
240
- ),
282
+ fulldomain +
283
+ "/status-page-api/cname-verification/" +
284
+ token,
285
+ targetLabel: STATUS_PAGE_DOMAIN_EGRESS_LABEL,
241
286
  });
242
287
 
243
288
  if (result.isFailure()) {
@@ -320,13 +365,13 @@ export class Service extends DatabaseService<StatusPageDomain> {
320
365
 
321
366
  try {
322
367
  const result: HTTPErrorResponse | HTTPResponse<JSONObject> =
323
- await API.get({
324
- url: URL.fromString(
368
+ await Domain.getForDomainVerification({
369
+ url:
325
370
  "http://" +
326
- fullDomain +
327
- "/status-page-api/cname-verification/" +
328
- token,
329
- ),
371
+ fullDomain +
372
+ "/status-page-api/cname-verification/" +
373
+ token,
374
+ targetLabel: STATUS_PAGE_DOMAIN_EGRESS_LABEL,
330
375
  });
331
376
 
332
377
  logger.debug("CNAME verification result", {
@@ -353,13 +398,13 @@ export class Service extends DatabaseService<StatusPageDomain> {
353
398
 
354
399
  try {
355
400
  const resultHttps: HTTPErrorResponse | HTTPResponse<JSONObject> =
356
- await API.get({
357
- url: URL.fromString(
401
+ await Domain.getForDomainVerification({
402
+ url:
358
403
  "https://" +
359
- fullDomain +
360
- "/status-page-api/cname-verification/" +
361
- token,
362
- ),
404
+ fullDomain +
405
+ "/status-page-api/cname-verification/" +
406
+ token,
407
+ targetLabel: STATUS_PAGE_DOMAIN_EGRESS_LABEL,
363
408
  });
364
409
 
365
410
  logger.debug("CNAME verification result for https", {
@@ -120,10 +120,40 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
120
120
  }
121
121
  }
122
122
 
123
- if (!createBy.props.isRoot) {
123
+ /*
124
+ * Only internal writes (isRoot) and a master admin acting from the Admin
125
+ * Dashboard may create a membership that is already accepted - that is the
126
+ * "accept the invitation automatically" checkbox on the admin invite forms.
127
+ *
128
+ * Everyone else invites, and the invited person accepts for themselves. A
129
+ * project admin who could accept on someone's behalf would be able to pull
130
+ * an account into their project - and into whatever the team's permissions
131
+ * grant - without that person ever agreeing to it.
132
+ */
133
+ const canCreateAcceptedInvitation: boolean = Boolean(
134
+ createBy.props.isRoot || createBy.props.isMasterAdmin,
135
+ );
136
+
137
+ if (!canCreateAcceptedInvitation) {
124
138
  createBy.data.hasAcceptedInvitation = false;
125
139
  }
126
140
 
141
+ const isInvitationAcceptedOnCreate: boolean = Boolean(
142
+ createBy.data.hasAcceptedInvitation,
143
+ );
144
+
145
+ /*
146
+ * The acceptance timestamp is stamped here rather than taken from the
147
+ * request, so it can never disagree with hasAcceptedInvitation - a row that
148
+ * says "Member" with no accepted-at date, or an accepted-at date on a row
149
+ * that is still only invited.
150
+ */
151
+ if (isInvitationAcceptedOnCreate) {
152
+ createBy.data.invitationAcceptedAt = OneUptimeDate.getCurrentDate();
153
+ } else {
154
+ delete createBy.data.invitationAcceptedAt;
155
+ }
156
+
127
157
  if (createBy.miscDataProps && createBy.miscDataProps["email"]) {
128
158
  const email: Email = new Email(createBy.miscDataProps["email"] as string);
129
159
 
@@ -221,10 +251,18 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
221
251
  .addQueryParam("email", email.toString(), true)
222
252
  .toString(),
223
253
  isNewUser: isNewUser.toString(),
254
+ /*
255
+ * An auto-accepted member has nothing left to accept, so the
256
+ * template drops the "sign in to accept your invitation" framing
257
+ * and tells them they are already in.
258
+ */
259
+ isInvitationAccepted: isInvitationAcceptedOnCreate.toString(),
224
260
  projectName: project.name!,
225
261
  homeUrl: new URL(httpProtocol, host).toString(),
226
262
  },
227
- subject: "You have been invited to " + project.name,
263
+ subject: isInvitationAcceptedOnCreate
264
+ ? "You have been added to " + project.name
265
+ : "You have been invited to " + project.name,
228
266
  },
229
267
  {
230
268
  projectId: createBy.data.projectId!,
@@ -283,6 +321,65 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
283
321
  );
284
322
  }
285
323
 
324
+ /*
325
+ * The per-project notification defaults a member gets the moment their
326
+ * membership becomes accepted, whether that happened by them accepting the
327
+ * invitation or by a master admin accepting it for them on create. Without
328
+ * these, an auto-accepted member is a member who is never notified about
329
+ * anything.
330
+ *
331
+ * Skipped for an unverified email: UserService adds the defaults for every
332
+ * accepted membership once the address is verified.
333
+ *
334
+ * Best effort. Both helpers below are idempotent, and by the time either
335
+ * caller runs, the membership row is already committed - failing the write
336
+ * that created it would report "invite failed" for a member who exists.
337
+ */
338
+ @CaptureSpan()
339
+ private async addDefaultNotificationSettingsAndRules(data: {
340
+ userId: ObjectID;
341
+ projectId: ObjectID;
342
+ user?: User | undefined;
343
+ }): Promise<void> {
344
+ try {
345
+ const user: User | null =
346
+ data.user ||
347
+ (await UserService.findOneById({
348
+ id: data.userId,
349
+ select: {
350
+ email: true,
351
+ isEmailVerified: true,
352
+ },
353
+ props: {
354
+ isRoot: true,
355
+ },
356
+ }));
357
+
358
+ if (!user || !user.isEmailVerified || !user.email) {
359
+ return;
360
+ }
361
+
362
+ await UserNotificationSettingService.addDefaultNotificationSettingsForUser(
363
+ data.userId,
364
+ data.projectId,
365
+ );
366
+
367
+ await UserNotificationRuleService.addDefaultNotificationRuleForUser(
368
+ data.projectId,
369
+ data.userId,
370
+ user.email,
371
+ );
372
+ } catch (err) {
373
+ logger.error(
374
+ err as Error,
375
+ {
376
+ projectId: data.projectId.toString(),
377
+ userId: data.userId.toString(),
378
+ } as LogAttributes,
379
+ );
380
+ }
381
+ }
382
+
286
383
  @CaptureSpan()
287
384
  protected override async onCreateSuccess(
288
385
  onCreate: OnCreate<TeamMember>,
@@ -297,6 +394,18 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
297
394
  onCreate.createBy.data.projectId!,
298
395
  );
299
396
 
397
+ /*
398
+ * A membership created already accepted never goes through the
399
+ * accept-invitation update, so it would otherwise miss the defaults that
400
+ * hook adds.
401
+ */
402
+ if (createdItem.hasAcceptedInvitation) {
403
+ await this.addDefaultNotificationSettingsAndRules({
404
+ userId: onCreate.createBy.data.userId!,
405
+ projectId: onCreate.createBy.data.projectId!,
406
+ });
407
+ }
408
+
300
409
  // Activation event for marketing funnels, attributed to the inviter.
301
410
  ProductAnalytics.captureForUser({
302
411
  userId: onCreate.createBy.props.userId,
@@ -339,16 +448,12 @@ export class TeamMemberService extends DatabaseService<TeamMember> {
339
448
  for (const item of items) {
340
449
  await this.refreshTokens(item.userId!, item.projectId!);
341
450
 
342
- if (updateBy.data.hasAcceptedInvitation && item.user?.isEmailVerified) {
343
- await UserNotificationSettingService.addDefaultNotificationSettingsForUser(
344
- item.userId!,
345
- item.projectId!,
346
- );
347
- await UserNotificationRuleService.addDefaultNotificationRuleForUser(
348
- item.projectId!,
349
- item.userId!,
350
- item.user?.email as Email,
351
- );
451
+ if (updateBy.data.hasAcceptedInvitation) {
452
+ await this.addDefaultNotificationSettingsAndRules({
453
+ userId: item.userId!,
454
+ projectId: item.projectId!,
455
+ user: item.user,
456
+ });
352
457
  }
353
458
  }
354
459
 
@@ -5,6 +5,7 @@ import OneUptimeDate from "../../Types/Date";
5
5
  import logger from "../Utils/Logger";
6
6
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
7
7
  import { EntityRelationshipEdge } from "../../Utils/Telemetry/EntityRelationship";
8
+ import EntitySource from "../../Types/Telemetry/EntitySource";
8
9
  import { reconcileByNaturalKey } from "../Utils/Telemetry/EntityRegistry";
9
10
  import QueryDeepPartialEntity from "../../Types/Database/PartialEntity";
10
11
 
@@ -62,6 +63,8 @@ export class TelemetryEntityRelationshipService extends DatabaseService<Model> {
62
63
  model.fromEntityKey = edge.fromEntityKey;
63
64
  model.toEntityKey = edge.toEntityKey;
64
65
  model.relationshipType = edge.relationshipType;
66
+ // Explicit: this is what makes the edge eligible for stale pruning.
67
+ model.source = EntitySource.Discovered;
65
68
  model.firstSeenAt = now;
66
69
  model.lastSeenAt = now;
67
70
  if (edge.metrics) {
@@ -8,8 +8,19 @@ import ObjectID from "../../Types/ObjectID";
8
8
  import OneUptimeDate from "../../Types/Date";
9
9
  import ColumnLength from "../../Types/Database/ColumnLength";
10
10
  import QueryDeepPartialEntity from "../../Types/Database/PartialEntity";
11
+ import CreateBy from "../Types/Database/CreateBy";
12
+ import { OnCreate } from "../Types/Database/Hooks";
13
+ import BadDataException from "../../Types/Exception/BadDataException";
14
+ import Dictionary from "../../Types/Dictionary";
11
15
  import { JSONObject } from "../../Types/JSON";
16
+ import EntitySource from "../../Types/Telemetry/EntitySource";
12
17
  import EntityType from "../../Types/Telemetry/EntityType";
18
+ import { MANUAL_ENTITY_TYPES } from "../../Types/Telemetry/EntityTypeGroups";
19
+ import {
20
+ canonicalizeEntityValue,
21
+ computeEntityKey,
22
+ MANUAL_ENTITY_IDENTITY_ATTRIBUTE,
23
+ } from "../../Utils/Telemetry/EntityKey";
13
24
  import logger from "../Utils/Logger";
14
25
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
15
26
  import { ExtractedEntity } from "../Utils/Telemetry/TelemetryEntity";
@@ -25,6 +36,91 @@ export class TelemetryEntityService extends DatabaseService<Model> {
25
36
  super(Model);
26
37
  }
27
38
 
39
+ /**
40
+ * Completes a manually created CI.
41
+ *
42
+ * Every machine writer — the ingest reconciler and the inventory mirror —
43
+ * computes `entityKey` itself and passes an explicit `source`, because
44
+ * both derive identity from something the user never sees (a canonicalized
45
+ * semconv attribute set, or the owning row's id). A create arriving
46
+ * WITHOUT a key is therefore a user create by construction, and this hook
47
+ * is what turns the two fields a human can reasonably supply (type and
48
+ * name) into the identity the registry needs.
49
+ *
50
+ * Deriving the key here rather than in the dashboard keeps it enforced for
51
+ * API clients too, and keeps the one identity rule — canonicalize, then
52
+ * hash — in the module that owns it.
53
+ */
54
+ @CaptureSpan()
55
+ protected override async onBeforeCreate(
56
+ createBy: CreateBy<Model>,
57
+ ): Promise<OnCreate<Model>> {
58
+ const data: Model = createBy.data;
59
+
60
+ if (!data.entityKey) {
61
+ data.source = EntitySource.Manual;
62
+ }
63
+
64
+ if (data.source !== EntitySource.Manual) {
65
+ return { createBy, carryForward: null };
66
+ }
67
+
68
+ if (!data.projectId) {
69
+ throw new BadDataException("Project ID is required.");
70
+ }
71
+
72
+ if (!data.entityType) {
73
+ throw new BadDataException("Entity Type is required.");
74
+ }
75
+
76
+ /*
77
+ * Confined to the manual-only vocabulary. A hand-made row of an
78
+ * observable type would key off the manual identity attribute and so
79
+ * could never converge with the row ingest derives for the same thing —
80
+ * it would just sit beside it forever. See MANUAL_ENTITY_TYPES.
81
+ */
82
+ if (!MANUAL_ENTITY_TYPES.has(data.entityType)) {
83
+ throw new BadDataException(
84
+ `Entities of type ${data.entityType} are discovered automatically and cannot be created manually. Manually creatable types are: ${Array.from(
85
+ MANUAL_ENTITY_TYPES,
86
+ ).join(", ")}.`,
87
+ );
88
+ }
89
+
90
+ const displayName: string = (data.displayName || "").trim();
91
+
92
+ if (!displayName) {
93
+ throw new BadDataException(
94
+ "Name is required for a manually created entity.",
95
+ );
96
+ }
97
+
98
+ data.displayName = displayName.substring(0, ColumnLength.ShortText);
99
+
100
+ const identifyingAttributes: Dictionary<string> = {
101
+ [MANUAL_ENTITY_IDENTITY_ATTRIBUTE]: canonicalizeEntityValue(displayName),
102
+ };
103
+ data.identifyingAttributes = identifyingAttributes as JSONObject;
104
+
105
+ data.entityKey = computeEntityKey({
106
+ projectId: data.projectId.toString(),
107
+ entityType: data.entityType,
108
+ identifyingAttributes,
109
+ });
110
+
111
+ /*
112
+ * Stamped so the explorer can sort manual CIs alongside discovered ones
113
+ * on the same columns. `lastSeenAt` never moves again for these rows —
114
+ * it means "created", not "observed" — which is exactly why the prune
115
+ * sweep excludes them.
116
+ */
117
+ const now: Date = OneUptimeDate.getCurrentDate();
118
+ data.firstSeenAt = data.firstSeenAt || now;
119
+ data.lastSeenAt = data.lastSeenAt || now;
120
+
121
+ return { createBy, carryForward: null };
122
+ }
123
+
28
124
  /**
29
125
  * Forward-only registry reconciliation: upsert a catalog row per
30
126
  * discovered entity, bump `lastSeenAt`, merge descriptive attributes
@@ -169,7 +265,18 @@ export class TelemetryEntityService extends DatabaseService<Model> {
169
265
  if (count === undefined) {
170
266
  count = (
171
267
  await this.countBy({
172
- query: { projectId, entityType: entity.entityType },
268
+ query: {
269
+ projectId,
270
+ entityType: entity.entityType,
271
+ /*
272
+ * The budget exists to bound rows minted by ingest, so it
273
+ * counts only those. Manual CIs and inventory mirrors are
274
+ * bounded by their own creators and must not consume it —
275
+ * otherwise registering enough devices could stop new
276
+ * telemetry entities being recorded at all.
277
+ */
278
+ source: EntitySource.Discovered,
279
+ },
173
280
  props: { isRoot: true },
174
281
  })
175
282
  ).toNumber();
@@ -198,6 +305,12 @@ export class TelemetryEntityService extends DatabaseService<Model> {
198
305
  model.projectId = projectId;
199
306
  model.entityType = entity.entityType;
200
307
  model.entityKey = entity.entityKey;
308
+ /*
309
+ * Explicit rather than leaning on the column default: this is the
310
+ * flag that makes the row eligible for stale-entity pruning, and a
311
+ * silently-defaulted value is a poor way to carry that.
312
+ */
313
+ model.source = EntitySource.Discovered;
201
314
  model.identifyingAttributes = entity.identifyingAttributes;
202
315
  if (
203
316
  entity.descriptiveAttributes &&
@@ -85,6 +85,7 @@ export class Service extends DatabaseService<Model> {
85
85
 
86
86
  let secretKeyObjectId: ObjectID;
87
87
  try {
88
+ ObjectID.validateUUID(secretKey);
88
89
  secretKeyObjectId = new ObjectID(secretKey);
89
90
  } catch {
90
91
  this.projectIdCache.set(cacheKey, null, NEGATIVE_TTL_MS);
@@ -1,6 +1,7 @@
1
1
  import CreateBy from "../Types/Database/CreateBy";
2
2
  import DeleteBy from "../Types/Database/DeleteBy";
3
- import { OnCreate, OnDelete } from "../Types/Database/Hooks";
3
+ import UpdateBy from "../Types/Database/UpdateBy";
4
+ import { OnCreate, OnDelete, OnUpdate } from "../Types/Database/Hooks";
4
5
  import DatabaseService from "./DatabaseService";
5
6
  import UserNotificationRuleService from "./UserNotificationRuleService";
6
7
  import LIMIT_MAX from "../../Types/Database/LimitMax";
@@ -8,8 +9,19 @@ import BadDataException from "../../Types/Exception/BadDataException";
8
9
  import Model from "../../Models/DatabaseModels/UserWebhook";
9
10
  import URL from "../../Types/API/URL";
10
11
  import logger from "../Utils/Logger";
12
+ import SSRFProtection from "../Utils/SSRFProtection";
11
13
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
12
14
 
15
+ /*
16
+ * URL validation here used to be a hand-rolled copy of the SSRF blocklist that
17
+ * had drifted weaker than the original (it compared the host with the port
18
+ * still attached, and never resolved DNS). Everything that actually sends one
19
+ * of these webhooks goes through WebhookService, which calls
20
+ * SSRFProtection.validateWebhookTargetIsSafe — so the copy bought nothing and
21
+ * would have been read as "this is checked". Both hooks now call the same
22
+ * guard the sender does, which fails the write early instead of at delivery.
23
+ */
24
+
13
25
  export class Service extends DatabaseService<Model> {
14
26
  public constructor() {
15
27
  super(Model);
@@ -27,7 +39,7 @@ export class Service extends DatabaseService<Model> {
27
39
  throw new BadDataException("Webhook name is required");
28
40
  }
29
41
 
30
- this.validateWebhookUrl(createBy.data.webhookUrl);
42
+ await SSRFProtection.validateWebhookTargetIsSafe(createBy.data.webhookUrl);
31
43
 
32
44
  return {
33
45
  createBy,
@@ -35,6 +47,26 @@ export class Service extends DatabaseService<Model> {
35
47
  };
36
48
  }
37
49
 
50
+ @CaptureSpan()
51
+ protected override async onBeforeUpdate(
52
+ updateBy: UpdateBy<Model>,
53
+ ): Promise<OnUpdate<Model>> {
54
+ /*
55
+ * Create-time validation on its own is not a control: the URL is
56
+ * editable afterwards.
57
+ */
58
+ const webhookUrl: unknown = updateBy.data.webhookUrl;
59
+
60
+ if (typeof webhookUrl === "string" || webhookUrl instanceof URL) {
61
+ await SSRFProtection.validateWebhookTargetIsSafe(webhookUrl);
62
+ }
63
+
64
+ return {
65
+ updateBy,
66
+ carryForward: null,
67
+ };
68
+ }
69
+
38
70
  @CaptureSpan()
39
71
  protected override async onCreateSuccess(
40
72
  _onCreate: OnCreate<Model>,
@@ -96,113 +128,6 @@ export class Service extends DatabaseService<Model> {
96
128
  carryForward: null,
97
129
  };
98
130
  }
99
-
100
- private validateWebhookUrl(rawUrl: string): void {
101
- let parsed: URL;
102
- try {
103
- parsed = URL.fromString(rawUrl);
104
- } catch {
105
- throw new BadDataException("Webhook URL is not a valid URL");
106
- }
107
-
108
- const protocolValue: string = parsed.protocol.toString().toLowerCase();
109
- if (protocolValue !== "http://" && protocolValue !== "https://") {
110
- throw new BadDataException(
111
- "Webhook URL must use http or https protocol.",
112
- );
113
- }
114
-
115
- const hostname: string = parsed.hostname.hostname.toLowerCase();
116
-
117
- if (!hostname) {
118
- throw new BadDataException("Webhook URL must include a host.");
119
- }
120
-
121
- if (isBlockedHostnameLiteral(hostname)) {
122
- throw new BadDataException(
123
- "Webhook URL points to a private, loopback, or link-local address and is not allowed.",
124
- );
125
- }
126
- }
127
- }
128
-
129
- function isBlockedHostnameLiteral(hostname: string): boolean {
130
- if (
131
- hostname === "localhost" ||
132
- hostname.endsWith(".localhost") ||
133
- hostname === "metadata.google.internal"
134
- ) {
135
- return true;
136
- }
137
-
138
- // IPv4 literal check
139
- const ipv4Match: RegExpMatchArray | null = hostname.match(
140
- /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/,
141
- );
142
- if (ipv4Match) {
143
- const octets: Array<number> = [
144
- Number(ipv4Match[1]),
145
- Number(ipv4Match[2]),
146
- Number(ipv4Match[3]),
147
- Number(ipv4Match[4]),
148
- ];
149
-
150
- if (
151
- octets.some((o: number) => {
152
- return o < 0 || o > 255;
153
- })
154
- ) {
155
- return true;
156
- }
157
-
158
- // 0.0.0.0/8
159
- if (octets[0] === 0) {
160
- return true;
161
- }
162
- // 127.0.0.0/8 loopback
163
- if (octets[0] === 127) {
164
- return true;
165
- }
166
- // 10.0.0.0/8
167
- if (octets[0] === 10) {
168
- return true;
169
- }
170
- // 172.16.0.0/12
171
- if (octets[0] === 172 && (octets[1]! & 0xf0) === 16) {
172
- return true;
173
- }
174
- // 192.168.0.0/16
175
- if (octets[0] === 192 && octets[1] === 168) {
176
- return true;
177
- }
178
- // 169.254.0.0/16 link-local (incl. cloud metadata)
179
- if (octets[0] === 169 && octets[1] === 254) {
180
- return true;
181
- }
182
- // 100.64.0.0/10 carrier-grade NAT
183
- if (octets[0] === 100 && (octets[1]! & 0xc0) === 64) {
184
- return true;
185
- }
186
- return false;
187
- }
188
-
189
- // IPv6 literal — block loopback, link-local, unique-local
190
- if (hostname.includes(":")) {
191
- const stripped: string = hostname.replace(/^\[|\]$/g, "");
192
- if (stripped === "::1" || stripped === "::") {
193
- return true;
194
- }
195
- if (stripped.startsWith("fe80:") || stripped.startsWith("fe80::")) {
196
- return true;
197
- }
198
- if (IPV6_UNIQUE_LOCAL_REGEX.test(stripped)) {
199
- return true;
200
- }
201
- }
202
-
203
- return false;
204
131
  }
205
132
 
206
- const IPV6_UNIQUE_LOCAL_REGEX: RegExp = /^f[cd][0-9a-f]{2}:/;
207
-
208
133
  export default new Service();