@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,450 @@
1
+ import AIAgent from "../../../Models/DatabaseModels/AIAgent";
2
+ import IncidentEpisodePublicNote from "../../../Models/DatabaseModels/IncidentEpisodePublicNote";
3
+ import IncidentPublicNote from "../../../Models/DatabaseModels/IncidentPublicNote";
4
+ import Probe from "../../../Models/DatabaseModels/Probe";
5
+ import ScheduledMaintenancePublicNote from "../../../Models/DatabaseModels/ScheduledMaintenancePublicNote";
6
+ import StatusPageAnnouncement from "../../../Models/DatabaseModels/StatusPageAnnouncement";
7
+ import AIAgentService from "../../../Server/Services/AIAgentService";
8
+ import FileService from "../../../Server/Services/FileService";
9
+ import IncidentEpisodeFeedService from "../../../Server/Services/IncidentEpisodeFeedService";
10
+ import IncidentEpisodePublicNoteService from "../../../Server/Services/IncidentEpisodePublicNoteService";
11
+ import IncidentEpisodeService from "../../../Server/Services/IncidentEpisodeService";
12
+ import IncidentFeedService from "../../../Server/Services/IncidentFeedService";
13
+ import IncidentPublicNoteService from "../../../Server/Services/IncidentPublicNoteService";
14
+ import IncidentService from "../../../Server/Services/IncidentService";
15
+ import ProbeService from "../../../Server/Services/ProbeService";
16
+ import ScheduledMaintenanceFeedService from "../../../Server/Services/ScheduledMaintenanceFeedService";
17
+ import ScheduledMaintenancePublicNoteService from "../../../Server/Services/ScheduledMaintenancePublicNoteService";
18
+ import ScheduledMaintenanceService from "../../../Server/Services/ScheduledMaintenanceService";
19
+ import StatusPageAnnouncementService from "../../../Server/Services/StatusPageAnnouncementService";
20
+ import URL from "../../../Types/API/URL";
21
+ import ObjectID from "../../../Types/ObjectID";
22
+ import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
23
+
24
+ /*
25
+ * Inline images uploaded through the markdown editor arrive PRIVATE — that is
26
+ * what stops a private incident screenshot being readable by anyone holding
27
+ * the URL. They have to flip to public at exactly the moment their parent
28
+ * becomes visible on a status page, or every image in a published note 404s
29
+ * for the anonymous visitors the note was written for.
30
+ *
31
+ * These tests drive the real hooks and assert the flip lands on FileService,
32
+ * so they cover the whole chain (service hook -> sync util -> file write)
33
+ * rather than just "some function was called".
34
+ */
35
+
36
+ const FILE_ID: string = "11111111-1111-4111-8111-111111111111";
37
+ const ICON_FILE_ID: ObjectID = new ObjectID(
38
+ "22222222-2222-4222-8222-222222222222",
39
+ );
40
+ const TOKEN: string = "abc123def456";
41
+ const NOTE_WITH_IMAGE: string = `Here is what broke: ![shot](https://example.com/file/image/access-token/${TOKEN})`;
42
+
43
+ type CallHookFunction = (
44
+ service: unknown,
45
+ name: string,
46
+ ...args: Array<unknown>
47
+ ) => Promise<unknown>;
48
+
49
+ // Calls a protected hook without widening the service's public surface.
50
+ const callHook: CallHookFunction = (
51
+ service: unknown,
52
+ name: string,
53
+ ...args: Array<unknown>
54
+ ): Promise<unknown> => {
55
+ const hooks: Record<
56
+ string,
57
+ (...hookArgs: Array<unknown>) => Promise<unknown>
58
+ > = service as Record<
59
+ string,
60
+ (...hookArgs: Array<unknown>) => Promise<unknown>
61
+ >;
62
+
63
+ return hooks[name]!.apply(service, args);
64
+ };
65
+
66
+ type UpdatedFileIds = () => Array<string>;
67
+
68
+ // Every file id the code under test flipped to public.
69
+ const filesMadePublic: UpdatedFileIds = (): Array<string> => {
70
+ return (FileService.updateOneById as unknown as jest.Mock).mock.calls
71
+ .filter((call: Array<any>) => {
72
+ return call[0]?.data?.isPublic === true;
73
+ })
74
+ .map((call: Array<any>) => {
75
+ return String(call[0]?.id);
76
+ });
77
+ };
78
+
79
+ describe("publish-time inline image visibility", () => {
80
+ beforeEach(() => {
81
+ jest.spyOn(FileService, "findOneBy").mockResolvedValue({
82
+ _id: FILE_ID,
83
+ } as never);
84
+ jest
85
+ .spyOn(FileService, "updateOneById")
86
+ .mockResolvedValue(undefined as never);
87
+ });
88
+
89
+ afterEach(() => {
90
+ jest.restoreAllMocks();
91
+ });
92
+
93
+ describe("IncidentPublicNoteService", () => {
94
+ beforeEach(() => {
95
+ jest.spyOn(IncidentService, "getIncidentNumber").mockResolvedValue({
96
+ number: 1,
97
+ numberWithPrefix: "#1",
98
+ });
99
+ jest
100
+ .spyOn(IncidentService, "getIncidentLinkInDashboard")
101
+ .mockResolvedValue(URL.fromString("https://oneuptime.test/incident"));
102
+ jest
103
+ .spyOn(IncidentFeedService, "createIncidentFeedItem")
104
+ .mockResolvedValue(undefined as never);
105
+ jest
106
+ .spyOn(IncidentPublicNoteService, "findOneById")
107
+ .mockResolvedValue(null);
108
+ });
109
+
110
+ it("publishes inline images when a public note is created", async () => {
111
+ const note: IncidentPublicNote = new IncidentPublicNote();
112
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
113
+ note.incidentId = new ObjectID("44444444-4444-4444-8444-444444444444");
114
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
115
+ note.note = NOTE_WITH_IMAGE;
116
+
117
+ await callHook(IncidentPublicNoteService, "onCreateSuccess", {}, note);
118
+
119
+ expect(filesMadePublic()).toEqual([FILE_ID]);
120
+ });
121
+
122
+ it("publishes inline images when a public note is edited", async () => {
123
+ const note: IncidentPublicNote = new IncidentPublicNote();
124
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
125
+ note.incidentId = new ObjectID("44444444-4444-4444-8444-444444444444");
126
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
127
+ note.note = NOTE_WITH_IMAGE;
128
+ note.incident = {
129
+ id: new ObjectID("44444444-4444-4444-8444-444444444444"),
130
+ projectId: new ObjectID("55555555-5555-4555-8555-555555555555"),
131
+ incidentNumber: 1,
132
+ } as never;
133
+
134
+ jest.spyOn(IncidentPublicNoteService, "findBy").mockResolvedValue([note]);
135
+
136
+ await callHook(
137
+ IncidentPublicNoteService,
138
+ "onUpdateSuccess",
139
+ {
140
+ updateBy: {
141
+ query: {},
142
+ data: { note: NOTE_WITH_IMAGE },
143
+ props: { isRoot: true },
144
+ },
145
+ },
146
+ [],
147
+ );
148
+
149
+ expect(filesMadePublic()).toEqual([FILE_ID]);
150
+ });
151
+
152
+ it("does not touch any file when the note has no inline images", async () => {
153
+ const note: IncidentPublicNote = new IncidentPublicNote();
154
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
155
+ note.incidentId = new ObjectID("44444444-4444-4444-8444-444444444444");
156
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
157
+ note.note = "No screenshots on this one.";
158
+
159
+ await callHook(IncidentPublicNoteService, "onCreateSuccess", {}, note);
160
+
161
+ expect(FileService.updateOneById).not.toHaveBeenCalled();
162
+ });
163
+ });
164
+
165
+ describe("IncidentEpisodePublicNoteService", () => {
166
+ beforeEach(() => {
167
+ jest.spyOn(IncidentEpisodeService, "getEpisodeNumber").mockResolvedValue({
168
+ number: 1,
169
+ numberWithPrefix: "#1",
170
+ });
171
+ jest
172
+ .spyOn(IncidentEpisodeService, "getEpisodeLinkInDashboard")
173
+ .mockResolvedValue(URL.fromString("https://oneuptime.test/episode"));
174
+ jest
175
+ .spyOn(IncidentEpisodeFeedService, "createIncidentEpisodeFeedItem")
176
+ .mockResolvedValue(undefined as never);
177
+ jest
178
+ .spyOn(IncidentEpisodePublicNoteService, "findOneById")
179
+ .mockResolvedValue(null);
180
+ });
181
+
182
+ it("publishes inline images when a public note is created", async () => {
183
+ const note: IncidentEpisodePublicNote = new IncidentEpisodePublicNote();
184
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
185
+ note.incidentEpisodeId = new ObjectID(
186
+ "44444444-4444-4444-8444-444444444444",
187
+ );
188
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
189
+ note.note = NOTE_WITH_IMAGE;
190
+
191
+ await callHook(
192
+ IncidentEpisodePublicNoteService,
193
+ "onCreateSuccess",
194
+ {},
195
+ note,
196
+ );
197
+
198
+ expect(filesMadePublic()).toEqual([FILE_ID]);
199
+ });
200
+
201
+ it("publishes inline images when a public note is edited", async () => {
202
+ const note: IncidentEpisodePublicNote = new IncidentEpisodePublicNote();
203
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
204
+ note.incidentEpisodeId = new ObjectID(
205
+ "44444444-4444-4444-8444-444444444444",
206
+ );
207
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
208
+ note.note = NOTE_WITH_IMAGE;
209
+ note.incidentEpisode = {
210
+ id: new ObjectID("44444444-4444-4444-8444-444444444444"),
211
+ projectId: new ObjectID("55555555-5555-4555-8555-555555555555"),
212
+ episodeNumber: 1,
213
+ } as never;
214
+
215
+ jest
216
+ .spyOn(IncidentEpisodePublicNoteService, "findBy")
217
+ .mockResolvedValue([note]);
218
+
219
+ await callHook(
220
+ IncidentEpisodePublicNoteService,
221
+ "onUpdateSuccess",
222
+ {
223
+ updateBy: {
224
+ query: {},
225
+ data: { note: NOTE_WITH_IMAGE },
226
+ props: { isRoot: true },
227
+ },
228
+ },
229
+ [],
230
+ );
231
+
232
+ expect(filesMadePublic()).toEqual([FILE_ID]);
233
+ });
234
+ });
235
+
236
+ describe("ScheduledMaintenancePublicNoteService", () => {
237
+ beforeEach(() => {
238
+ jest
239
+ .spyOn(ScheduledMaintenanceService, "getScheduledMaintenanceNumber")
240
+ .mockResolvedValue({ number: 1, numberWithPrefix: "#1" });
241
+ jest
242
+ .spyOn(
243
+ ScheduledMaintenanceService,
244
+ "getScheduledMaintenanceLinkInDashboard",
245
+ )
246
+ .mockResolvedValue(
247
+ URL.fromString("https://oneuptime.test/maintenance"),
248
+ );
249
+ jest
250
+ .spyOn(
251
+ ScheduledMaintenanceFeedService,
252
+ "createScheduledMaintenanceFeedItem",
253
+ )
254
+ .mockResolvedValue(undefined as never);
255
+ jest
256
+ .spyOn(ScheduledMaintenancePublicNoteService, "findOneById")
257
+ .mockResolvedValue(null);
258
+ });
259
+
260
+ it("publishes inline images when a public note is created", async () => {
261
+ const note: ScheduledMaintenancePublicNote =
262
+ new ScheduledMaintenancePublicNote();
263
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
264
+ note.scheduledMaintenanceId = new ObjectID(
265
+ "44444444-4444-4444-8444-444444444444",
266
+ );
267
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
268
+ note.note = NOTE_WITH_IMAGE;
269
+
270
+ await callHook(
271
+ ScheduledMaintenancePublicNoteService,
272
+ "onCreateSuccess",
273
+ {},
274
+ note,
275
+ );
276
+
277
+ expect(filesMadePublic()).toEqual([FILE_ID]);
278
+ });
279
+
280
+ it("publishes inline images when a public note is edited", async () => {
281
+ const note: ScheduledMaintenancePublicNote =
282
+ new ScheduledMaintenancePublicNote();
283
+ note.id = new ObjectID("33333333-3333-4333-8333-333333333333");
284
+ note.scheduledMaintenanceId = new ObjectID(
285
+ "44444444-4444-4444-8444-444444444444",
286
+ );
287
+ note.projectId = new ObjectID("55555555-5555-4555-8555-555555555555");
288
+ note.note = NOTE_WITH_IMAGE;
289
+ note.scheduledMaintenance = {
290
+ id: new ObjectID("44444444-4444-4444-8444-444444444444"),
291
+ projectId: new ObjectID("55555555-5555-4555-8555-555555555555"),
292
+ scheduledMaintenanceNumber: 1,
293
+ } as never;
294
+
295
+ jest
296
+ .spyOn(ScheduledMaintenancePublicNoteService, "findBy")
297
+ .mockResolvedValue([note]);
298
+
299
+ await callHook(
300
+ ScheduledMaintenancePublicNoteService,
301
+ "onUpdateSuccess",
302
+ {
303
+ updateBy: {
304
+ query: {},
305
+ data: { note: NOTE_WITH_IMAGE },
306
+ props: { isRoot: true },
307
+ },
308
+ },
309
+ [],
310
+ );
311
+
312
+ expect(filesMadePublic()).toEqual([FILE_ID]);
313
+ });
314
+ });
315
+
316
+ describe("StatusPageAnnouncementService", () => {
317
+ it("publishes inline images when an announcement is created", async () => {
318
+ const announcement: StatusPageAnnouncement = new StatusPageAnnouncement();
319
+ announcement.id = new ObjectID("33333333-3333-4333-8333-333333333333");
320
+ announcement.description = NOTE_WITH_IMAGE;
321
+
322
+ await callHook(
323
+ StatusPageAnnouncementService,
324
+ "onCreateSuccess",
325
+ {},
326
+ announcement,
327
+ );
328
+
329
+ expect(filesMadePublic()).toEqual([FILE_ID]);
330
+ });
331
+
332
+ it("publishes inline images when an announcement is edited", async () => {
333
+ const announcement: StatusPageAnnouncement = new StatusPageAnnouncement();
334
+ announcement.id = new ObjectID("33333333-3333-4333-8333-333333333333");
335
+ announcement.description = NOTE_WITH_IMAGE;
336
+
337
+ jest
338
+ .spyOn(StatusPageAnnouncementService, "findBy")
339
+ .mockResolvedValue([announcement]);
340
+
341
+ await callHook(
342
+ StatusPageAnnouncementService,
343
+ "onUpdateSuccess",
344
+ { updateBy: { query: {}, data: { description: NOTE_WITH_IMAGE } } },
345
+ [],
346
+ );
347
+
348
+ expect(filesMadePublic()).toEqual([FILE_ID]);
349
+ });
350
+
351
+ it("does not touch any file when the description has no inline images", async () => {
352
+ const announcement: StatusPageAnnouncement = new StatusPageAnnouncement();
353
+ announcement.id = new ObjectID("33333333-3333-4333-8333-333333333333");
354
+ announcement.description = "Scheduled work is now complete.";
355
+
356
+ await callHook(
357
+ StatusPageAnnouncementService,
358
+ "onCreateSuccess",
359
+ {},
360
+ announcement,
361
+ );
362
+
363
+ expect(FileService.updateOneById).not.toHaveBeenCalled();
364
+ });
365
+ });
366
+
367
+ /*
368
+ * Probe and AI agent icons are the only readers of the id-based image
369
+ * route, which serves public files only. They upload through the file
370
+ * picker, which marks uploads private — so attaching one has to publish it
371
+ * or the icon 404s.
372
+ */
373
+ describe("intentionally public icons", () => {
374
+ it("publishes a probe icon on create", async () => {
375
+ const probe: Probe = new Probe();
376
+ probe.id = new ObjectID("33333333-3333-4333-8333-333333333333");
377
+ probe.iconFileId = ICON_FILE_ID;
378
+
379
+ await callHook(ProbeService, "onCreateSuccess", {}, probe);
380
+
381
+ expect(filesMadePublic()).toEqual([ICON_FILE_ID.toString()]);
382
+ });
383
+
384
+ it("publishes a probe icon when it is swapped out", async () => {
385
+ await callHook(
386
+ ProbeService,
387
+ "onUpdateSuccess",
388
+ {
389
+ updateBy: { query: {}, data: { iconFileId: ICON_FILE_ID } },
390
+ carryForward: null,
391
+ },
392
+ [],
393
+ );
394
+
395
+ expect(filesMadePublic()).toEqual([ICON_FILE_ID.toString()]);
396
+ });
397
+
398
+ it("leaves files alone when a probe update does not touch the icon", async () => {
399
+ await callHook(
400
+ ProbeService,
401
+ "onUpdateSuccess",
402
+ {
403
+ updateBy: { query: {}, data: { name: "Renamed probe" } },
404
+ carryForward: null,
405
+ },
406
+ [],
407
+ );
408
+
409
+ expect(FileService.updateOneById).not.toHaveBeenCalled();
410
+ });
411
+
412
+ it("publishes an AI agent icon on create", async () => {
413
+ const agent: AIAgent = new AIAgent();
414
+ agent.id = new ObjectID("33333333-3333-4333-8333-333333333333");
415
+ agent.iconFileId = ICON_FILE_ID;
416
+
417
+ await callHook(AIAgentService, "onCreateSuccess", {}, agent);
418
+
419
+ expect(filesMadePublic()).toEqual([ICON_FILE_ID.toString()]);
420
+ });
421
+
422
+ it("publishes an AI agent icon when it is swapped out", async () => {
423
+ await callHook(
424
+ AIAgentService,
425
+ "onUpdateSuccess",
426
+ {
427
+ updateBy: { query: {}, data: { iconFileId: ICON_FILE_ID } },
428
+ carryForward: null,
429
+ },
430
+ [],
431
+ );
432
+
433
+ expect(filesMadePublic()).toEqual([ICON_FILE_ID.toString()]);
434
+ });
435
+
436
+ it("leaves files alone when an agent update does not touch the icon", async () => {
437
+ await callHook(
438
+ AIAgentService,
439
+ "onUpdateSuccess",
440
+ {
441
+ updateBy: { query: {}, data: { description: "Renamed" } },
442
+ carryForward: null,
443
+ },
444
+ [],
445
+ );
446
+
447
+ expect(FileService.updateOneById).not.toHaveBeenCalled();
448
+ });
449
+ });
450
+ });