@oneuptime/common 12.0.6 → 12.0.7

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 (424) 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/WorkspaceProjectAuthToken.ts +19 -1
  8. package/Server/API/FileAPI.ts +15 -2
  9. package/Server/API/MicrosoftTeamsAPI.ts +6 -1
  10. package/Server/API/ProjectAPI.ts +214 -0
  11. package/Server/API/StatusPageAPI.ts +39 -6
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  16. package/Server/Services/AIAgentService.ts +20 -0
  17. package/Server/Services/DashboardDomainService.ts +73 -28
  18. package/Server/Services/DatabaseService.ts +1 -0
  19. package/Server/Services/DeletedProjectService.ts +138 -0
  20. package/Server/Services/FileService.ts +61 -0
  21. package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
  22. package/Server/Services/IncidentPublicNoteService.ts +18 -0
  23. package/Server/Services/Index.ts +2 -0
  24. package/Server/Services/MonitorService.ts +311 -0
  25. package/Server/Services/ProbeService.ts +20 -0
  26. package/Server/Services/ProjectService.ts +297 -1
  27. package/Server/Services/PushNotificationService.ts +71 -0
  28. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
  29. package/Server/Services/StatusPageAnnouncementService.ts +53 -0
  30. package/Server/Services/StatusPageDomainService.ts +73 -28
  31. package/Server/Services/TeamMemberService.ts +117 -12
  32. package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
  33. package/Server/Services/UserWebhookService.ts +34 -109
  34. package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
  35. package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
  36. package/Server/Types/Database/DeleteById.ts +2 -0
  37. package/Server/Types/Database/DeleteOneBy.ts +6 -0
  38. package/Server/Types/Domain.ts +41 -0
  39. package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
  40. package/Server/Types/Workflow/Components/API/Get.ts +2 -1
  41. package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
  42. package/Server/Types/Workflow/Components/API/Post.ts +2 -1
  43. package/Server/Types/Workflow/Components/API/Put.ts +2 -1
  44. package/Server/Types/Workflow/Components/API/Utils.ts +41 -2
  45. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
  46. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
  47. package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
  48. package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
  49. package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
  50. package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
  51. package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
  52. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
  53. package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
  54. package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
  55. package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
  56. package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
  57. package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
  58. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
  59. package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
  60. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  61. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
  62. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
  63. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
  64. package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
  65. package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
  66. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
  67. package/Server/Utils/DataSource/EgressGuard.ts +176 -16
  68. package/Server/Utils/DataSource/HttpFetch.ts +6 -45
  69. package/Server/Utils/Execute.ts +8 -0
  70. package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
  71. package/Server/Utils/LLM/LLMService.ts +57 -12
  72. package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
  73. package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
  74. package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
  75. package/Server/Utils/Monitor/MonitorResource.ts +36 -0
  76. package/Server/Utils/Response.ts +142 -6
  77. package/Server/Utils/SSRFProtection.ts +273 -60
  78. package/Server/Utils/StartServer.ts +8 -0
  79. package/Server/Utils/VM/VMRunner.ts +88 -1
  80. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
  81. package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
  82. package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
  83. package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
  84. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
  85. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
  86. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
  87. package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
  88. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
  89. package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
  90. package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
  91. package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
  92. package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
  93. package/Tests/Server/API/ProjectAPI.test.ts +299 -1
  94. package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
  95. package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
  96. package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
  97. package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
  98. package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
  99. package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
  100. package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
  101. package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
  102. package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
  103. package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
  104. package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
  105. package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
  106. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
  107. package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
  108. package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
  109. package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
  110. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
  111. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
  112. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
  113. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
  114. package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
  115. package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
  116. package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
  117. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
  118. package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
  119. package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
  120. package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
  121. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
  122. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
  123. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
  124. package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
  125. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
  126. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
  127. package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
  128. package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
  129. package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
  130. package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
  131. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
  132. package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
  133. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
  134. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
  135. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
  137. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
  138. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
  139. package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
  140. package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
  141. package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
  142. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
  143. package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
  144. package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
  145. package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
  146. package/Tests/Types/JSONFunctions.test.ts +252 -1
  147. package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
  148. package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
  149. package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
  150. package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
  151. package/Tests/UI/Components/404.test.tsx +1 -1
  152. package/Tests/UI/Components/Alert.test.tsx +1 -1
  153. package/Tests/UI/Components/Badge.test.tsx +1 -1
  154. package/Tests/UI/Components/BasicForm.test.tsx +39 -10
  155. package/Tests/UI/Components/Button.test.tsx +1 -1
  156. package/Tests/UI/Components/Card.test.tsx +1 -1
  157. package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
  158. package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
  159. package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
  160. package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
  161. package/Tests/UI/Components/Dropdown.test.tsx +1 -1
  162. package/Tests/UI/Components/FilePicker.test.tsx +1 -1
  163. package/Tests/UI/Components/HiddenText.test.tsx +1 -1
  164. package/Tests/UI/Components/Input.test.tsx +1 -1
  165. package/Tests/UI/Components/Loader.test.tsx +1 -1
  166. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +1 -1
  167. package/Tests/UI/Components/MasterPage.test.tsx +1 -1
  168. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +489 -0
  169. package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
  170. package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
  171. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
  172. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
  173. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
  174. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
  175. package/Tests/UI/Components/NavBar.test.tsx +1 -1
  176. package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
  177. package/Tests/UI/Components/Pagination.test.tsx +1 -1
  178. package/Tests/UI/Components/Pill.test.tsx +1 -1
  179. package/Tests/UI/Components/Probe.test.tsx +1 -1
  180. package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
  181. package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
  182. package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
  183. package/Tests/UI/Components/SideOver.test.tsx +500 -6
  184. package/Tests/UI/Components/Tabs.test.tsx +1 -1
  185. package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
  186. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +1 -1
  187. package/Tests/UI/Components/TextArea.test.tsx +1 -1
  188. package/Tests/UI/Components/Toast.test.tsx +1 -1
  189. package/Tests/UI/Components/Toggle.test.tsx +1 -1
  190. package/Tests/UI/Components/TopSection.test.tsx +1 -1
  191. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
  192. package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
  193. package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
  194. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
  195. package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
  196. package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
  197. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
  198. package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
  199. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
  200. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
  201. package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
  202. package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
  203. package/Tests/Utils/Realtime.test.ts +78 -0
  204. package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
  205. package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
  206. package/Types/AI/FixPullRequestCiStatus.ts +1 -1
  207. package/Types/AI/FixVerificationStatus.ts +2 -2
  208. package/Types/API/Hostname.ts +92 -4
  209. package/Types/API/URL.ts +43 -25
  210. package/Types/Billing/BalanceAdjustmentType.ts +14 -0
  211. package/Types/Billing/ProjectBalanceType.ts +13 -0
  212. package/Types/Domain.ts +26 -0
  213. package/Types/File/MimeType.ts +11 -0
  214. package/Types/JSONFunctions.ts +15 -0
  215. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
  216. package/Types/Workflow/Components/BaseModel.ts +92 -28
  217. package/Typings/Index.d.ts +12 -0
  218. package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
  219. package/UI/Components/Modal/ConfirmModal.tsx +10 -5
  220. package/UI/Components/Modal/Modal.tsx +27 -47
  221. package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
  222. package/UI/Components/SideOver/SideOver.tsx +195 -68
  223. package/UI/Utils/PageScrollLock.ts +66 -0
  224. package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
  225. package/Utils/Dashboard/VariableInterpolation.ts +19 -1
  226. package/Utils/LegacySerializedArray.ts +60 -0
  227. package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
  228. package/Utils/Telemetry/SavedViewFilters.ts +88 -0
  229. package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
  230. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
  231. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
  232. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
  233. package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
  234. package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
  235. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  236. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  237. package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
  238. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  239. package/build/dist/Models/DatabaseModels/Project.js +3 -3
  240. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  241. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  242. package/build/dist/Server/API/FileAPI.js +14 -2
  243. package/build/dist/Server/API/FileAPI.js.map +1 -1
  244. package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
  245. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  246. package/build/dist/Server/API/ProjectAPI.js +157 -4
  247. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  248. package/build/dist/Server/API/StatusPageAPI.js +27 -3
  249. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
  253. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
  254. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
  255. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
  256. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  257. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  258. package/build/dist/Server/Services/AIAgentService.js +17 -0
  259. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  260. package/build/dist/Server/Services/DashboardDomainService.js +55 -18
  261. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  262. package/build/dist/Server/Services/DatabaseService.js +1 -0
  263. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  264. package/build/dist/Server/Services/DeletedProjectService.js +124 -0
  265. package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
  266. package/build/dist/Server/Services/FileService.js +52 -0
  267. package/build/dist/Server/Services/FileService.js.map +1 -1
  268. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
  269. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  270. package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
  271. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  272. package/build/dist/Server/Services/Index.js +2 -0
  273. package/build/dist/Server/Services/Index.js.map +1 -1
  274. package/build/dist/Server/Services/MonitorService.js +232 -0
  275. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  276. package/build/dist/Server/Services/ProbeService.js +17 -0
  277. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  278. package/build/dist/Server/Services/ProjectService.js +228 -6
  279. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  280. package/build/dist/Server/Services/PushNotificationService.js +56 -0
  281. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  282. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
  283. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  284. package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
  285. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  286. package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
  287. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  288. package/build/dist/Server/Services/TeamMemberService.js +97 -6
  289. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  290. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
  291. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  292. package/build/dist/Server/Services/UserWebhookService.js +31 -87
  293. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  294. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
  295. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  296. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
  297. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  298. package/build/dist/Server/Types/Domain.js +37 -0
  299. package/build/dist/Server/Types/Domain.js.map +1 -1
  300. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
  301. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  302. package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
  303. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  304. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
  305. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  306. package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
  307. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  308. package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
  309. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  310. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +35 -2
  311. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  312. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
  313. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  314. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
  315. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  316. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
  317. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
  318. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
  319. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
  320. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
  321. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
  322. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
  323. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
  324. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
  325. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
  326. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
  327. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
  328. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
  329. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
  330. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
  331. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
  332. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
  333. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
  334. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
  335. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
  336. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
  337. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
  338. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
  339. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  340. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
  341. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
  342. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  343. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
  344. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
  345. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
  346. package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
  347. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
  348. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
  349. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
  350. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  351. package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
  352. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  353. package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
  354. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  355. package/build/dist/Server/Utils/Execute.js +2 -2
  356. package/build/dist/Server/Utils/Execute.js.map +1 -1
  357. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
  358. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
  359. package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
  360. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  361. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
  362. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  363. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
  364. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
  365. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
  366. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  367. package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
  368. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  369. package/build/dist/Server/Utils/Response.js +112 -5
  370. package/build/dist/Server/Utils/Response.js.map +1 -1
  371. package/build/dist/Server/Utils/SSRFProtection.js +219 -53
  372. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  373. package/build/dist/Server/Utils/StartServer.js +7 -0
  374. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  375. package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
  376. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  377. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
  378. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  379. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
  380. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  381. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  382. package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
  383. package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
  384. package/build/dist/Types/API/Hostname.js +73 -4
  385. package/build/dist/Types/API/Hostname.js.map +1 -1
  386. package/build/dist/Types/API/URL.js +42 -24
  387. package/build/dist/Types/API/URL.js.map +1 -1
  388. package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
  389. package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
  390. package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
  391. package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
  392. package/build/dist/Types/Domain.js +22 -0
  393. package/build/dist/Types/Domain.js.map +1 -1
  394. package/build/dist/Types/File/MimeType.js +11 -0
  395. package/build/dist/Types/File/MimeType.js.map +1 -1
  396. package/build/dist/Types/JSONFunctions.js +14 -0
  397. package/build/dist/Types/JSONFunctions.js.map +1 -1
  398. package/build/dist/Types/Workflow/Components/BaseModel.js +83 -28
  399. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  400. package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
  401. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
  402. package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
  403. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  404. package/build/dist/UI/Components/Modal/Modal.js +24 -34
  405. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  406. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
  407. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  408. package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
  409. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  410. package/build/dist/UI/Utils/PageScrollLock.js +52 -0
  411. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
  412. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
  413. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
  414. package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
  415. package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
  416. package/build/dist/Utils/LegacySerializedArray.js +51 -0
  417. package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
  418. package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
  419. package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
  420. package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
  421. package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
  422. package/jest.config.json +3 -0
  423. package/package.json +1 -1
  424. package/tsconfig.json +3 -1
@@ -0,0 +1,89 @@
1
+ import BaseModel from "../../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
2
+ import logger from "../../../../Utils/Logger";
3
+ import { RunOptions } from "../../ComponentCode";
4
+ import {
5
+ ID_ARGUMENT_KEY,
6
+ PRIMARY_KEY_COLUMN,
7
+ describeModelColumns,
8
+ } from "./ModelArguments";
9
+
10
+ /*
11
+ * TypeORM's EntityPropertyNotFoundError reads
12
+ * `Property "foo" was not found in "Monitor". Make sure your query is correct.`
13
+ * On its own that tells a workflow builder nothing they can act on: it names
14
+ * neither the argument at fault nor anything they can pick from, and it says
15
+ * "query" even when the offending key was in Data. Everything the builder
16
+ * needs is already on the model, so the components append it.
17
+ */
18
+ const UNKNOWN_PROPERTY_PATTERN: RegExp =
19
+ /Property "([^"]+)" was not found in "([^"]+)"/;
20
+
21
+ type BuildColumnHintFunction = (
22
+ message: string,
23
+ model: BaseModel,
24
+ ) => string | null;
25
+
26
+ export const buildColumnHint: BuildColumnHintFunction = (
27
+ message: string,
28
+ model: BaseModel,
29
+ ): string | null => {
30
+ const match: RegExpMatchArray | null = message.match(
31
+ UNKNOWN_PROPERTY_PATTERN,
32
+ );
33
+
34
+ if (!match) {
35
+ return null;
36
+ }
37
+
38
+ const property: string = match[1] as string;
39
+ const modelName: string = model.singularName || (match[2] as string);
40
+
41
+ if (property === ID_ARGUMENT_KEY) {
42
+ return `Tip: "${ID_ARGUMENT_KEY}" is not a column on ${modelName}. Use "${PRIMARY_KEY_COLUMN}" instead. Columns you can use: ${describeModelColumns(
43
+ model,
44
+ )}.`;
45
+ }
46
+
47
+ return `Tip: "${property}" is not a column on ${modelName}. Check every key in this component's Query, Select and Data arguments. Columns you can use: ${describeModelColumns(
48
+ model,
49
+ )}.`;
50
+ };
51
+
52
+ type LogComponentErrorFunction = (data: {
53
+ error: unknown;
54
+ model: BaseModel | null;
55
+ log: RunOptions["log"];
56
+ }) => void;
57
+
58
+ /*
59
+ * Every database component failed the same way before this: two lines in the
60
+ * workflow log and, for all but Create One, nothing at all in the server log.
61
+ */
62
+ const logComponentError: LogComponentErrorFunction = (data: {
63
+ error: unknown;
64
+ model: BaseModel | null;
65
+ log: RunOptions["log"];
66
+ }): void => {
67
+ const { error, model, log } = data;
68
+
69
+ logger.error(error);
70
+
71
+ const errorMessage: unknown = (error as { message?: unknown } | null)
72
+ ?.message;
73
+
74
+ const message: string =
75
+ typeof errorMessage === "string" && errorMessage
76
+ ? errorMessage
77
+ : JSON.stringify(error, null, 2);
78
+
79
+ log("Error running component");
80
+ log(message);
81
+
82
+ const hint: string | null = model ? buildColumnHint(message, model) : null;
83
+
84
+ if (hint) {
85
+ log(hint);
86
+ }
87
+ };
88
+
89
+ export default logComponentError;
@@ -0,0 +1,208 @@
1
+ import BaseModel from "../../../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
2
+ import { TableColumnMetadata } from "../../../../../Types/Database/TableColumn";
3
+ import TableColumnType from "../../../../../Types/Database/TableColumnType";
4
+ import { JSONObject, JSONValue } from "../../../../../Types/JSON";
5
+ import ObjectID from "../../../../../Types/ObjectID";
6
+
7
+ /*
8
+ * Workflow builders write "id", because that is what an ID is called
9
+ * everywhere they can see one: in the dashboard, in the API docs, and on the
10
+ * model itself (`monitor.id`). On a database model, though, "id" is only a
11
+ * TypeScript accessor - the persisted primary key column is "_id"
12
+ * (DatabaseBaseModel._id). A query, select or data object keyed on "id"
13
+ * therefore reached TypeORM verbatim and threw
14
+ * `Property "id" was not found in "Monitor". Make sure your query is correct.`,
15
+ * which is what https://github.com/OneUptime/oneuptime/issues/3132 reported.
16
+ *
17
+ * The create path has accepted "id" all along - DatabaseBaseModel._fromJSON
18
+ * rewrites it to "_id" - so the fix is to make every other workflow argument
19
+ * agree with create, rather than to take the alias away from create.
20
+ */
21
+
22
+ export const ID_ARGUMENT_KEY: string = "id";
23
+ export const PRIMARY_KEY_COLUMN: string = "_id";
24
+
25
+ /*
26
+ * Only alias when the model actually looks like a DatabaseBaseModel: it has
27
+ * the "_id" primary key and no column of its own literally called "id".
28
+ * No model ships an "id" column today, but a model that grew one would mean
29
+ * something different by "id" and must keep it.
30
+ */
31
+ type ModelAliasesIdFunction = (model: BaseModel) => boolean;
32
+
33
+ const modelAliasesId: ModelAliasesIdFunction = (model: BaseModel): boolean => {
34
+ return (
35
+ model.hasColumn(PRIMARY_KEY_COLUMN) && !model.hasColumn(ID_ARGUMENT_KEY)
36
+ );
37
+ };
38
+
39
+ /*
40
+ * A nested object is only worth walking into when it is a map of column names.
41
+ * Serialized values - ObjectID, Date, and every QueryHelper operator - travel
42
+ * as `{ "_type": "...", "value": ... }` and are values, not column maps, so
43
+ * key rewriting has to stop at them.
44
+ */
45
+ type IsColumnMapFunction = (value: JSONValue) => boolean;
46
+
47
+ const isColumnMap: IsColumnMapFunction = (value: JSONValue): boolean => {
48
+ if (value === null || value === undefined || typeof value !== "object") {
49
+ return false;
50
+ }
51
+
52
+ if (Array.isArray(value) || value instanceof Date) {
53
+ return false;
54
+ }
55
+
56
+ return (value as JSONObject)["_type"] === undefined;
57
+ };
58
+
59
+ type NormalizeValueFunction = (
60
+ value: JSONValue,
61
+ columnName: string,
62
+ model: BaseModel,
63
+ ) => JSONValue;
64
+
65
+ /*
66
+ * Relations are queried and selected one level deep - `{"project": {"id":
67
+ * true}}` - so the alias has to follow the relation into the related model
68
+ * rather than stopping at the top level.
69
+ */
70
+ const normalizeValue: NormalizeValueFunction = (
71
+ value: JSONValue,
72
+ columnName: string,
73
+ model: BaseModel,
74
+ ): JSONValue => {
75
+ if (!isColumnMap(value)) {
76
+ return value;
77
+ }
78
+
79
+ const metadata: TableColumnMetadata | undefined =
80
+ model.getTableColumnMetadata(columnName);
81
+
82
+ if (
83
+ !metadata ||
84
+ !metadata.modelType ||
85
+ (metadata.type !== TableColumnType.Entity &&
86
+ metadata.type !== TableColumnType.EntityArray)
87
+ ) {
88
+ return value;
89
+ }
90
+
91
+ return normalizeModelKeys(value as JSONObject, new metadata.modelType());
92
+ };
93
+
94
+ type NormalizeModelKeysFunction = (
95
+ json: JSONObject,
96
+ model: BaseModel,
97
+ ) => JSONObject;
98
+
99
+ /*
100
+ * Returns a copy of `json` with the "id" alias resolved to the "_id" column,
101
+ * including inside related-model objects one level down. Everything else is
102
+ * copied through untouched - this deliberately does not validate column names,
103
+ * so an argument that works today keeps working.
104
+ */
105
+ export const normalizeModelKeys: NormalizeModelKeysFunction = (
106
+ json: JSONObject,
107
+ model: BaseModel,
108
+ ): JSONObject => {
109
+ const normalized: JSONObject = {};
110
+ const aliasesId: boolean = modelAliasesId(model);
111
+
112
+ /*
113
+ * Someone who spells out "_id" meant "_id". If both spellings are present
114
+ * the explicit column wins and the alias is dropped, so the result never
115
+ * depends on key order.
116
+ */
117
+ const explicitPrimaryKeyGiven: boolean =
118
+ json[PRIMARY_KEY_COLUMN] !== undefined;
119
+
120
+ for (const key of Object.keys(json)) {
121
+ let columnName: string = key;
122
+
123
+ if (key === ID_ARGUMENT_KEY && aliasesId) {
124
+ if (explicitPrimaryKeyGiven) {
125
+ continue;
126
+ }
127
+
128
+ columnName = PRIMARY_KEY_COLUMN;
129
+ }
130
+
131
+ normalized[columnName] = normalizeValue(
132
+ json[key] as JSONValue,
133
+ columnName,
134
+ model,
135
+ );
136
+ }
137
+
138
+ return normalized;
139
+ };
140
+
141
+ type ApplyTenantColumnFunction = (
142
+ json: JSONObject,
143
+ model: BaseModel,
144
+ tenantId: ObjectID,
145
+ ) => JSONObject;
146
+
147
+ /*
148
+ * Stamps the record being written with the project the workflow runs in.
149
+ *
150
+ * Setting the scalar tenant column is not enough on its own. Every tenant
151
+ * model also exposes that same physical column through its many-to-one
152
+ * relation - Monitor.project is @JoinColumn({name: "projectId"}) - and TypeORM
153
+ * reads the relation property first, writing the column once. So a payload
154
+ * carrying {"project": "<some other project>"} silently beat the stamp and
155
+ * moved the record into that project. The relation keys pointing at the tenant
156
+ * column are therefore dropped before the scalar is written.
157
+ */
158
+ export const applyTenantColumn: ApplyTenantColumnFunction = (
159
+ json: JSONObject,
160
+ model: BaseModel,
161
+ tenantId: ObjectID,
162
+ ): JSONObject => {
163
+ const tenantColumn: string | null = model.getTenantColumn();
164
+
165
+ if (!tenantColumn) {
166
+ return json;
167
+ }
168
+
169
+ const stamped: JSONObject = {};
170
+
171
+ for (const key of Object.keys(json)) {
172
+ if (key === tenantColumn) {
173
+ continue;
174
+ }
175
+
176
+ const metadata: TableColumnMetadata | undefined =
177
+ model.getTableColumnMetadata(key);
178
+
179
+ if (metadata && metadata.manyToOneRelationColumn === tenantColumn) {
180
+ continue;
181
+ }
182
+
183
+ stamped[key] = json[key];
184
+ }
185
+
186
+ stamped[tenantColumn] = tenantId;
187
+
188
+ return stamped;
189
+ };
190
+
191
+ type DescribeModelColumnsFunction = (model: BaseModel) => string;
192
+
193
+ /*
194
+ * The raw TypeORM failure ("Property "foo" was not found in "Monitor") names
195
+ * neither the argument at fault nor anything the builder can pick from, so the
196
+ * components append the real column list to it.
197
+ */
198
+ export const describeModelColumns: DescribeModelColumnsFunction = (
199
+ model: BaseModel,
200
+ ): string => {
201
+ const columns: Array<string> = [...model.getTableColumns().columns].sort(
202
+ (a: string, b: string): number => {
203
+ return a.localeCompare(b);
204
+ },
205
+ );
206
+
207
+ return columns.join(", ");
208
+ };
@@ -24,6 +24,7 @@ import ComponentMetadata, {
24
24
  import BaseModelComponents from "../../../../../Types/Workflow/Components/BaseModel";
25
25
  import Workflow from "../../../../../Models/DatabaseModels/Workflow";
26
26
  import CaptureSpan from "../../../../Utils/Telemetry/CaptureSpan";
27
+ import { normalizeModelKeys } from "./ModelArguments";
27
28
 
28
29
  export default class OnTriggerBaseModel<
29
30
  TBaseModel extends BaseModel,
@@ -156,6 +157,16 @@ export default class OnTriggerBaseModel<
156
157
  (select as any)[key] = false;
157
158
  }
158
159
  }
160
+
161
+ /*
162
+ * "id" is only a TypeScript accessor on the model - the column is "_id".
163
+ * Selecting "id" reached TypeORM verbatim and threw, and this trigger
164
+ * has no error port, so it took the whole workflow run down with it.
165
+ */
166
+ select = normalizeModelKeys(
167
+ select as JSONObject,
168
+ this.service!.getModel(),
169
+ ) as Select<TBaseModel>;
159
170
  }
160
171
 
161
172
  const model: TBaseModel | null = await this.service!.findOneById({
@@ -14,6 +14,8 @@ import ComponentMetadata, {
14
14
  } from "../../../../../Types/Workflow/Component";
15
15
  import BaseModelComponents from "../../../../../Types/Workflow/Components/BaseModel";
16
16
  import CaptureSpan from "../../../../Utils/Telemetry/CaptureSpan";
17
+ import { applyTenantColumn, normalizeModelKeys } from "./ModelArguments";
18
+ import logComponentError from "./LogComponentError";
17
19
 
18
20
  export default class UpdateManyBaseModel<
19
21
  TBaseModel extends BaseModel,
@@ -92,11 +94,14 @@ export default class UpdateManyBaseModel<
92
94
  );
93
95
  }
94
96
 
95
- if (this.modelService.getModel().getTenantColumn()) {
96
- (args["data"] as JSONObject)[
97
- this.modelService.getModel().getTenantColumn() as string
98
- ] = options.projectId;
99
- }
97
+ args["data"] = applyTenantColumn(
98
+ normalizeModelKeys(
99
+ args["data"] as JSONObject,
100
+ this.modelService.getModel(),
101
+ ),
102
+ this.modelService.getModel(),
103
+ options.projectId,
104
+ );
100
105
 
101
106
  if (!args["query"]) {
102
107
  throw options.onError(new BadDataException("Query is undefined."));
@@ -137,22 +142,28 @@ export default class UpdateManyBaseModel<
137
142
  args["limit"] = LIMIT_PER_PROJECT;
138
143
  }
139
144
 
140
- let query: Query<TBaseModel> = args["query"] as Query<TBaseModel>;
141
-
142
- if (query) {
143
- query = JSONFunctions.deserialize(
145
+ const query: Query<TBaseModel> = JSONFunctions.deserialize(
146
+ normalizeModelKeys(
144
147
  args["query"] as JSONObject,
145
- ) as Query<TBaseModel>;
146
- }
147
-
148
+ this.modelService.getModel(),
149
+ ),
150
+ ) as Query<TBaseModel>;
151
+
152
+ /*
153
+ * The tenant column goes on the deserialized query, not on args["query"].
154
+ * JSONFunctions.deserialize returns a new object, so writing the tenant
155
+ * column to args afterwards left the query that actually ran unscoped -
156
+ * and an update as root is not re-scoped by the permission layer, so an
157
+ * Update Many could reach rows in other projects.
158
+ */
148
159
  if (this.modelService.getModel().getTenantColumn()) {
149
- (args["query"] as JSONObject)[
160
+ (query as JSONObject)[
150
161
  this.modelService.getModel().getTenantColumn() as string
151
162
  ] = options.projectId;
152
163
  }
153
164
 
154
- await this.modelService.updateBy({
155
- query: query || {},
165
+ const itemsUpdated: number = await this.modelService.updateBy({
166
+ query: query,
156
167
  data: args["data"] as QueryDeepPartialEntity<TBaseModel>,
157
168
  limit: new PositiveNumber(args["limit"] as number),
158
169
  skip: new PositiveNumber(args["skip"] as number),
@@ -162,13 +173,25 @@ export default class UpdateManyBaseModel<
162
173
  },
163
174
  });
164
175
 
176
+ options.log(
177
+ `Updated ${itemsUpdated} ${
178
+ this.modelService.getModel().singularName || "record"
179
+ }(s).`,
180
+ );
181
+
165
182
  return {
166
- returnValues: {},
183
+ returnValues: {
184
+ "items-updated": itemsUpdated,
185
+ },
167
186
  executePort: successPort,
168
187
  };
169
188
  } catch (err: any) {
170
- options.log("Error running component");
171
- options.log(err.message ? err.message : JSON.stringify(err, null, 2));
189
+ logComponentError({
190
+ error: err,
191
+ model: this.modelService?.getModel() || null,
192
+ log: options.log,
193
+ });
194
+
172
195
  return {
173
196
  returnValues: {},
174
197
  executePort: errorPort,
@@ -12,6 +12,8 @@ import ComponentMetadata, {
12
12
  } from "../../../../../Types/Workflow/Component";
13
13
  import BaseModelComponents from "../../../../../Types/Workflow/Components/BaseModel";
14
14
  import CaptureSpan from "../../../../Utils/Telemetry/CaptureSpan";
15
+ import { applyTenantColumn, normalizeModelKeys } from "./ModelArguments";
16
+ import logComponentError from "./LogComponentError";
15
17
 
16
18
  export default class UpdateOneBaseModel<
17
19
  TBaseModel extends BaseModel,
@@ -90,11 +92,14 @@ export default class UpdateOneBaseModel<
90
92
  );
91
93
  }
92
94
 
93
- if (this.modelService.getModel().getTenantColumn()) {
94
- (args["data"] as JSONObject)[
95
- this.modelService.getModel().getTenantColumn() as string
96
- ] = options.projectId;
97
- }
95
+ args["data"] = applyTenantColumn(
96
+ normalizeModelKeys(
97
+ args["data"] as JSONObject,
98
+ this.modelService.getModel(),
99
+ ),
100
+ this.modelService.getModel(),
101
+ options.projectId,
102
+ );
98
103
 
99
104
  if (!args["query"]) {
100
105
  throw options.onError(new BadDataException("Query is undefined."));
@@ -110,22 +115,26 @@ export default class UpdateOneBaseModel<
110
115
  );
111
116
  }
112
117
 
118
+ const query: Query<TBaseModel> = JSONFunctions.deserialize(
119
+ normalizeModelKeys(
120
+ args["query"] as JSONObject,
121
+ this.modelService.getModel(),
122
+ ),
123
+ ) as Query<TBaseModel>;
124
+
125
+ /*
126
+ * The tenant column goes on the deserialized query, not on args["query"]
127
+ * - JSONFunctions.deserialize returns a new object, so anything written
128
+ * to args after it runs never reaches the database.
129
+ */
113
130
  if (this.modelService.getModel().getTenantColumn()) {
114
- (args["query"] as JSONObject)[
131
+ (query as JSONObject)[
115
132
  this.modelService.getModel().getTenantColumn() as string
116
133
  ] = options.projectId;
117
134
  }
118
135
 
119
- let query: Query<TBaseModel> = args["query"] as Query<TBaseModel>;
120
-
121
- if (query) {
122
- query = JSONFunctions.deserialize(
123
- args["query"] as JSONObject,
124
- ) as Query<TBaseModel>;
125
- }
126
-
127
- await this.modelService.updateOneBy({
128
- query: query || {},
136
+ const itemsUpdated: number = await this.modelService.updateOneBy({
137
+ query: query,
129
138
  data: args["data"] as QueryDeepPartialEntity<TBaseModel>,
130
139
  props: {
131
140
  isRoot: true,
@@ -133,13 +142,30 @@ export default class UpdateOneBaseModel<
133
142
  },
134
143
  });
135
144
 
145
+ /*
146
+ * A query that matches nothing is not an error, but reporting it as a
147
+ * bare success left builders with no way to tell "updated" from "found
148
+ * nothing to update".
149
+ */
150
+ options.log(
151
+ `Updated ${itemsUpdated} ${
152
+ this.modelService.getModel().singularName || "record"
153
+ }(s).`,
154
+ );
155
+
136
156
  return {
137
- returnValues: {},
157
+ returnValues: {
158
+ "items-updated": itemsUpdated,
159
+ },
138
160
  executePort: successPort,
139
161
  };
140
162
  } catch (err: any) {
141
- options.log("Error running component");
142
- options.log(err.message ? err.message : JSON.stringify(err, null, 2));
163
+ logComponentError({
164
+ error: err,
165
+ model: this.modelService?.getModel() || null,
166
+ log: options.log,
167
+ });
168
+
143
169
  return {
144
170
  returnValues: {},
145
171
  executePort: errorPort,
@@ -1,4 +1,7 @@
1
1
  import ComponentCode, { RunOptions, RunReturnType } from "../../ComponentCode";
2
+ import IncomingWebhookUtils, {
3
+ DISCORD_WEBHOOK_DOMAINS,
4
+ } from "../IncomingWebhookUtils";
2
5
  import HTTPErrorResponse from "../../../../../Types/API/HTTPErrorResponse";
3
6
  import HTTPResponse from "../../../../../Types/API/HTTPResponse";
4
7
  import URL from "../../../../../Types/API/URL";
@@ -59,15 +62,12 @@ export default class SendMessageToChannel extends ComponentCode {
59
62
  throw options.onError(new BadDataException("Discord message not found"));
60
63
  }
61
64
 
62
- if (!args["webhook-url"]) {
63
- throw options.onError(
64
- new BadDataException("Discord Webhook URL not found"),
65
- );
66
- }
67
-
68
- args["webhook-url"] = URL.fromString(
69
- args["webhook-url"]?.toString() as string,
70
- );
65
+ args["webhook-url"] = IncomingWebhookUtils.getPinnedWebhookUrl({
66
+ args,
67
+ options,
68
+ allowedDomains: DISCORD_WEBHOOK_DOMAINS,
69
+ vendorName: "Discord",
70
+ });
71
71
 
72
72
  let apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null = null;
73
73
 
@@ -78,6 +78,13 @@ export default class SendMessageToChannel extends ComponentCode {
78
78
  data: {
79
79
  content: args["text"] as string,
80
80
  },
81
+ /*
82
+ * The host is pinned above; following a redirect would hand the
83
+ * destination back to whoever controls that host.
84
+ */
85
+ options: {
86
+ doNotFollowRedirects: true,
87
+ },
81
88
  });
82
89
 
83
90
  if (apiResult instanceof HTTPErrorResponse) {
@@ -0,0 +1,66 @@
1
+ import { RunOptions } from "../ComponentCode";
2
+ import URL from "../../../../Types/API/URL";
3
+ import BadDataException from "../../../../Types/Exception/BadDataException";
4
+ import { JSONObject } from "../../../../Types/JSON";
5
+ import SSRFProtection from "../../../Utils/SSRFProtection";
6
+
7
+ /*
8
+ * The Slack / Discord / Microsoft Teams workflow components each take a
9
+ * free-text "webhook-url" argument off the workflow graph, which any project
10
+ * member can author and which can additionally be templated from trigger data.
11
+ * They then POST to it from the API server - the same SSRF primitive that
12
+ * GHSA-v5xh-rw9h-77fv reported against the API components.
13
+ *
14
+ * These are chat webhooks, so unlike the generic API components there is a
15
+ * vendor host to pin to, and a pin is strictly better than a blocklist: it
16
+ * cannot be walked around with DNS rebinding, an alternate IP notation, or a
17
+ * redirect. Nothing legitimate is lost - a self-hosted OneUptime still posts to
18
+ * hooks.slack.com like everyone else.
19
+ */
20
+
21
+ export const DISCORD_WEBHOOK_DOMAINS: Array<string> = [
22
+ "discord.com",
23
+ "discordapp.com",
24
+ ];
25
+
26
+ export class IncomingWebhookUtils {
27
+ /*
28
+ * Reads the component's "webhook-url" argument, requires it to be on one of
29
+ * `allowedDomains`, and returns it parsed. Throws through options.onError so
30
+ * the workflow stops with a message the author can act on.
31
+ *
32
+ * Validates the RAW string: URL.fromString defaults an unrecognized scheme to
33
+ * https, so converting first would let "gopher://..." arrive looking clean.
34
+ */
35
+ public static getPinnedWebhookUrl(data: {
36
+ args: JSONObject;
37
+ options: RunOptions;
38
+ allowedDomains: Array<string>;
39
+ vendorName: string;
40
+ }): URL {
41
+ const rawUrl: unknown = data.args["webhook-url"];
42
+
43
+ if (!rawUrl) {
44
+ throw data.options.onError(
45
+ new BadDataException(`${data.vendorName} Webhook URL not found`),
46
+ );
47
+ }
48
+
49
+ if (
50
+ !SSRFProtection.isUrlOnAllowedDomain(
51
+ rawUrl.toString(),
52
+ data.allowedDomains,
53
+ )
54
+ ) {
55
+ throw data.options.onError(
56
+ new BadDataException(
57
+ `${data.vendorName} Webhook URL must be an https URL on ${data.allowedDomains.join(" or ")}.`,
58
+ ),
59
+ );
60
+ }
61
+
62
+ return URL.fromString(rawUrl.toString());
63
+ }
64
+ }
65
+
66
+ export default IncomingWebhookUtils;
@@ -1,4 +1,6 @@
1
1
  import ComponentCode, { RunOptions, RunReturnType } from "../../ComponentCode";
2
+ import IncomingWebhookUtils from "../IncomingWebhookUtils";
3
+ import { MICROSOFT_TEAMS_WEBHOOK_DOMAINS } from "../../../../Utils/Workspace/MicrosoftTeams/MicrosoftTeams";
2
4
  import HTTPErrorResponse from "../../../../../Types/API/HTTPErrorResponse";
3
5
  import HTTPResponse from "../../../../../Types/API/HTTPResponse";
4
6
  import URL from "../../../../../Types/API/URL";
@@ -60,15 +62,12 @@ export default class SendMessageToChannel extends ComponentCode {
60
62
  );
61
63
  }
62
64
 
63
- if (!args["webhook-url"]) {
64
- throw options.onError(
65
- new BadDataException("Microsoft teams Webhook URL not found"),
66
- );
67
- }
68
-
69
- args["webhook-url"] = URL.fromString(
70
- args["webhook-url"]?.toString() as string,
71
- );
65
+ args["webhook-url"] = IncomingWebhookUtils.getPinnedWebhookUrl({
66
+ args,
67
+ options,
68
+ allowedDomains: MICROSOFT_TEAMS_WEBHOOK_DOMAINS,
69
+ vendorName: "Microsoft Teams",
70
+ });
72
71
 
73
72
  let apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null = null;
74
73
 
@@ -100,6 +99,13 @@ export default class SendMessageToChannel extends ComponentCode {
100
99
  },
101
100
  ],
102
101
  },
102
+ /*
103
+ * The host is pinned above; following a redirect would hand the
104
+ * destination back to whoever controls that host.
105
+ */
106
+ options: {
107
+ doNotFollowRedirects: true,
108
+ },
103
109
  });
104
110
 
105
111
  if (apiResult instanceof HTTPErrorResponse) {