@oneuptime/common 8.0.5579 → 8.0.5581

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 (181) hide show
  1. package/Models/DatabaseModels/AlertInternalNote.ts +58 -1
  2. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +1 -0
  3. package/Models/DatabaseModels/File.ts +1 -1
  4. package/Models/DatabaseModels/IncidentInternalNote.ts +58 -1
  5. package/Models/DatabaseModels/IncidentPublicNote.ts +58 -1
  6. package/Models/DatabaseModels/ScheduledMaintenanceInternalNote.ts +58 -1
  7. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +58 -1
  8. package/Models/DatabaseModels/StatusPageAnnouncement.ts +49 -0
  9. package/Server/API/AlertInternalNoteAPI.ts +96 -0
  10. package/Server/API/IncidentInternalNoteAPI.ts +96 -0
  11. package/Server/API/IncidentPublicNoteAPI.ts +96 -0
  12. package/Server/API/ScheduledMaintenanceInternalNoteAPI.ts +100 -0
  13. package/Server/API/ScheduledMaintenancePublicNoteAPI.ts +100 -0
  14. package/Server/API/StatusPageAPI.ts +585 -59
  15. package/Server/API/StatusPageAnnouncementAPI.ts +98 -0
  16. package/Server/API/UserAPI.ts +95 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.ts +79 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.ts +81 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.ts +79 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  21. package/Server/Middleware/ProjectAuthorization.ts +3 -1
  22. package/Server/Services/AlertInternalNoteService.ts +75 -2
  23. package/Server/Services/IncidentInternalNoteService.ts +76 -2
  24. package/Server/Services/IncidentPublicNoteService.ts +76 -2
  25. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +76 -2
  26. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +76 -2
  27. package/Server/Services/ScheduledMaintenanceService.ts +10 -7
  28. package/Server/Services/StatusPagePrivateUserService.ts +10 -7
  29. package/Server/Services/StatusPageService.ts +12 -7
  30. package/Server/Services/StatusPageSubscriberService.ts +19 -13
  31. package/Server/Utils/FileAttachmentMarkdownUtil.ts +98 -0
  32. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +9 -1
  33. package/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.ts +34 -0
  34. package/Server/Utils/Monitor/DataToProcess.ts +3 -1
  35. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +13 -0
  36. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
  37. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +20 -0
  38. package/Server/Utils/Monitor/MonitorResource.ts +18 -0
  39. package/Server/Utils/Response.ts +13 -0
  40. package/Server/Utils/Telemetry.ts +15 -0
  41. package/Types/File/MimeType.ts +18 -0
  42. package/Types/Monitor/CriteriaFilter.ts +3 -0
  43. package/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.ts +12 -0
  44. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  45. package/Types/Monitor/MonitorStep.ts +30 -0
  46. package/Types/Monitor/MonitorStepExceptionMonitor.ts +94 -0
  47. package/Types/Monitor/MonitorType.ts +10 -1
  48. package/Types/Telemetry/TelemetryQuery.ts +2 -1
  49. package/Types/Telemetry/TelemetryType.ts +1 -0
  50. package/UI/Components/AttachmentList/EventAttachmentList.tsx +121 -0
  51. package/UI/Components/EventItem/EventItem.tsx +22 -0
  52. package/UI/Components/Feed/FeedItem.tsx +9 -16
  53. package/UI/Components/FilePicker/FilePicker.tsx +441 -145
  54. package/UI/Components/Forms/Fields/FormField.tsx +32 -15
  55. package/UI/Components/Forms/FormSummary.tsx +168 -1
  56. package/UI/Components/Forms/ModelForm.tsx +46 -24
  57. package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
  58. package/UI/Components/Icon/Icon.tsx +1 -1
  59. package/UI/Utils/API/RequestOptions.ts +2 -0
  60. package/UI/Utils/ModelAPI/ModelAPI.ts +18 -0
  61. package/UI/Utils/User.ts +8 -0
  62. package/Utils/API.ts +11 -1
  63. package/build/dist/Models/DatabaseModels/AlertInternalNote.js +49 -1
  64. package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -1
  65. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +1 -0
  66. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  67. package/build/dist/Models/DatabaseModels/File.js +1 -1
  68. package/build/dist/Models/DatabaseModels/File.js.map +1 -1
  69. package/build/dist/Models/DatabaseModels/IncidentInternalNote.js +49 -1
  70. package/build/dist/Models/DatabaseModels/IncidentInternalNote.js.map +1 -1
  71. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +49 -1
  72. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  73. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js +49 -1
  74. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js.map +1 -1
  75. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +49 -1
  76. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  77. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +48 -0
  78. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  79. package/build/dist/Server/API/AlertInternalNoteAPI.js +68 -0
  80. package/build/dist/Server/API/AlertInternalNoteAPI.js.map +1 -0
  81. package/build/dist/Server/API/IncidentInternalNoteAPI.js +68 -0
  82. package/build/dist/Server/API/IncidentInternalNoteAPI.js.map +1 -0
  83. package/build/dist/Server/API/IncidentPublicNoteAPI.js +68 -0
  84. package/build/dist/Server/API/IncidentPublicNoteAPI.js.map +1 -0
  85. package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js +68 -0
  86. package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js.map +1 -0
  87. package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js +68 -0
  88. package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js.map +1 -0
  89. package/build/dist/Server/API/StatusPageAPI.js +488 -85
  90. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  91. package/build/dist/Server/API/StatusPageAnnouncementAPI.js +68 -0
  92. package/build/dist/Server/API/StatusPageAnnouncementAPI.js.map +1 -0
  93. package/build/dist/Server/API/UserAPI.js +66 -0
  94. package/build/dist/Server/API/UserAPI.js.map +1 -0
  95. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js +34 -0
  96. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js.map +1 -0
  97. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js +34 -0
  98. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js.map +1 -0
  99. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js +34 -0
  100. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js.map +1 -0
  101. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  102. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  103. package/build/dist/Server/Middleware/ProjectAuthorization.js +4 -1
  104. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  105. package/build/dist/Server/Services/AlertInternalNoteService.js +54 -2
  106. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  107. package/build/dist/Server/Services/IncidentInternalNoteService.js +54 -2
  108. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  109. package/build/dist/Server/Services/IncidentPublicNoteService.js +54 -2
  110. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  111. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +54 -2
  112. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  113. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +54 -2
  114. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  115. package/build/dist/Server/Services/ScheduledMaintenanceService.js +6 -5
  116. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  117. package/build/dist/Server/Services/StatusPagePrivateUserService.js +6 -4
  118. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  119. package/build/dist/Server/Services/StatusPageService.js +7 -4
  120. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  121. package/build/dist/Server/Services/StatusPageSubscriberService.js +11 -7
  122. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  123. package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js +67 -0
  124. package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js.map +1 -0
  125. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +6 -1
  126. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  127. package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js +34 -0
  128. package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js.map +1 -0
  129. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +6 -0
  130. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  131. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
  132. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  133. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
  134. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  135. package/build/dist/Server/Utils/Monitor/MonitorResource.js +10 -0
  136. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  137. package/build/dist/Server/Utils/Response.js +8 -0
  138. package/build/dist/Server/Utils/Response.js.map +1 -1
  139. package/build/dist/Server/Utils/Telemetry.js +8 -1
  140. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  141. package/build/dist/Types/File/MimeType.js +18 -0
  142. package/build/dist/Types/File/MimeType.js.map +1 -1
  143. package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
  144. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  145. package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js +2 -0
  146. package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js.map +1 -0
  147. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  148. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  149. package/build/dist/Types/Monitor/MonitorStep.js +20 -1
  150. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  151. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +58 -0
  152. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -0
  153. package/build/dist/Types/Monitor/MonitorType.js +9 -1
  154. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  155. package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
  156. package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
  157. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +42 -0
  158. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -0
  159. package/build/dist/UI/Components/EventItem/EventItem.js +5 -1
  160. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  161. package/build/dist/UI/Components/Feed/FeedItem.js +6 -4
  162. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  163. package/build/dist/UI/Components/FilePicker/FilePicker.js +262 -77
  164. package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
  165. package/build/dist/UI/Components/Forms/Fields/FormField.js +24 -12
  166. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  167. package/build/dist/UI/Components/Forms/FormSummary.js +77 -1
  168. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  169. package/build/dist/UI/Components/Forms/ModelForm.js +32 -18
  170. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  171. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
  172. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
  173. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  174. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  175. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +30 -45
  176. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  177. package/build/dist/UI/Utils/User.js +7 -0
  178. package/build/dist/UI/Utils/User.js.map +1 -1
  179. package/build/dist/Utils/API.js +3 -0
  180. package/build/dist/Utils/API.js.map +1 -1
  181. package/package.json +6 -6
@@ -77,12 +77,45 @@ import ProjectCallSMSConfigService from "../Services/ProjectCallSMSConfigService
77
77
  import MailService from "../Services/MailService";
78
78
  import EmailTemplateType from "../../Types/Email/EmailTemplateType";
79
79
  import DatabaseConfig from "../DatabaseConfig";
80
- import { FileRoute } from "../../ServiceRoute";
80
+ import { StatusPageApiRoute } from "../../ServiceRoute";
81
81
  import ProjectSmtpConfigService from "../Services/ProjectSmtpConfigService";
82
82
  import SlackUtil from "../Utils/Workspace/Slack/Slack";
83
+ const resolveStatusPageIdOrThrow = async (statusPageIdOrDomain) => {
84
+ if (!statusPageIdOrDomain) {
85
+ throw new NotFoundException("Status Page not found");
86
+ }
87
+ if (statusPageIdOrDomain.includes(".")) {
88
+ const statusPageDomain = await StatusPageDomainService.findOneBy({
89
+ query: {
90
+ fullDomain: statusPageIdOrDomain,
91
+ domain: {
92
+ isVerified: true,
93
+ },
94
+ },
95
+ select: {
96
+ statusPageId: true,
97
+ },
98
+ props: {
99
+ isRoot: true,
100
+ },
101
+ });
102
+ if (!statusPageDomain || !statusPageDomain.statusPageId) {
103
+ throw new NotFoundException("Status Page not found");
104
+ }
105
+ return statusPageDomain.statusPageId;
106
+ }
107
+ try {
108
+ return new ObjectID(statusPageIdOrDomain);
109
+ }
110
+ catch (err) {
111
+ logger.error(`Error converting statusPageIdOrDomain to ObjectID: ${statusPageIdOrDomain}`);
112
+ logger.error(err);
113
+ throw new NotFoundException("Status Page not found");
114
+ }
115
+ };
83
116
  export default class StatusPageAPI extends BaseAPI {
84
117
  constructor() {
85
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
118
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
86
119
  super(StatusPage, StatusPageService);
87
120
  // get title, description of the page. This is used for SEO.
88
121
  this.router.get(`${(_a = new this.entityType().getCrudApiPath()) === null || _a === void 0 ? void 0 : _a.toString()}/seo/:statusPageIdOrDomain`, UserMiddleware.getUserMiddleware, async (req, res) => {
@@ -145,66 +178,133 @@ export default class StatusPageAPI extends BaseAPI {
145
178
  });
146
179
  // favicon api.
147
180
  this.router.get(`${(_b = new this.entityType().getCrudApiPath()) === null || _b === void 0 ? void 0 : _b.toString()}/favicon/:statusPageIdOrDomain`, async (req, res) => {
148
- const statusPageIdOrDomain = req.params["statusPageIdOrDomain"];
149
- let statusPageId = null;
150
- if (statusPageIdOrDomain && statusPageIdOrDomain.includes(".")) {
151
- // then this is a domain and not the status page id. We need to get the status page id from the domain.
152
- const statusPageDomain = await StatusPageDomainService.findOneBy({
181
+ try {
182
+ const statusPageId = await resolveStatusPageIdOrThrow(req.params["statusPageIdOrDomain"]);
183
+ const statusPage = await StatusPageService.findOneBy({
153
184
  query: {
154
- fullDomain: statusPageIdOrDomain,
155
- domain: {
156
- isVerified: true,
157
- },
185
+ _id: statusPageId,
158
186
  },
159
187
  select: {
160
- statusPageId: true,
188
+ faviconFile: {
189
+ file: true,
190
+ _id: true,
191
+ fileType: true,
192
+ name: true,
193
+ },
161
194
  },
162
195
  props: {
163
196
  isRoot: true,
164
197
  },
165
198
  });
166
- if (!statusPageDomain || !statusPageDomain.statusPageId) {
167
- return Response.sendErrorResponse(req, res, new NotFoundException("Status Page not found"));
199
+ if (!statusPage || !statusPage.faviconFile) {
200
+ logger.debug("Favicon file not found. Returning default favicon.");
201
+ return Response.sendFileByPath(req, res, `/usr/src/Common/UI/Images/favicon/status-green.png`);
168
202
  }
169
- statusPageId = statusPageDomain.statusPageId;
203
+ logger.debug(`Favicon file found. Sending file: ${statusPage.faviconFile.name}`);
204
+ return Response.sendFileResponse(req, res, statusPage.faviconFile);
170
205
  }
171
- else {
172
- // then this is a status page id. We need to get the status page id from the id.
173
- try {
174
- statusPageId = new ObjectID(statusPageIdOrDomain);
206
+ catch (error) {
207
+ if (error instanceof NotFoundException) {
208
+ return Response.sendErrorResponse(req, res, error);
175
209
  }
176
- catch (err) {
177
- logger.error(err);
178
- return Response.sendErrorResponse(req, res, new NotFoundException("Status Page not found"));
210
+ logger.error(error);
211
+ return Response.sendErrorResponse(req, res, new NotFoundException("Status Page not found"));
212
+ }
213
+ });
214
+ this.router.get(`${(_c = new this.entityType().getCrudApiPath()) === null || _c === void 0 ? void 0 : _c.toString()}/logo/:statusPageIdOrDomain`, async (req, res) => {
215
+ try {
216
+ const statusPageId = await resolveStatusPageIdOrThrow(req.params["statusPageIdOrDomain"]);
217
+ const statusPage = await StatusPageService.findOneBy({
218
+ query: {
219
+ _id: statusPageId,
220
+ },
221
+ select: {
222
+ logoFile: {
223
+ file: true,
224
+ _id: true,
225
+ fileType: true,
226
+ name: true,
227
+ },
228
+ },
229
+ props: {
230
+ isRoot: true,
231
+ },
232
+ });
233
+ if (!statusPage || !statusPage.logoFile) {
234
+ return Response.sendErrorResponse(req, res, new NotFoundException("Status Page logo not found"));
179
235
  }
236
+ return Response.sendFileResponse(req, res, statusPage.logoFile);
180
237
  }
181
- const statusPage = await StatusPageService.findOneBy({
182
- query: {
183
- _id: statusPageId,
184
- },
185
- select: {
186
- faviconFile: {
187
- file: true,
188
- _id: true,
189
- fileType: true,
190
- name: true,
238
+ catch (error) {
239
+ if (error instanceof NotFoundException) {
240
+ return Response.sendErrorResponse(req, res, error);
241
+ }
242
+ logger.error(error);
243
+ return Response.sendErrorResponse(req, res, new NotFoundException("Status Page logo not found"));
244
+ }
245
+ });
246
+ this.router.get(`${(_d = new this.entityType().getCrudApiPath()) === null || _d === void 0 ? void 0 : _d.toString()}/cover-image/:statusPageIdOrDomain`, async (req, res) => {
247
+ try {
248
+ const statusPageId = await resolveStatusPageIdOrThrow(req.params["statusPageIdOrDomain"]);
249
+ const statusPage = await StatusPageService.findOneBy({
250
+ query: {
251
+ _id: statusPageId,
191
252
  },
192
- },
193
- props: {
194
- isRoot: true,
195
- },
196
- });
197
- if (!statusPage || !statusPage.faviconFile) {
198
- logger.debug("Favicon file not found. Returning default favicon.");
199
- // return default favicon.
200
- return Response.sendFileByPath(req, res, `/usr/src/Common/UI/Images/favicon/status-green.png`);
253
+ select: {
254
+ coverImageFile: {
255
+ file: true,
256
+ _id: true,
257
+ fileType: true,
258
+ name: true,
259
+ },
260
+ },
261
+ props: {
262
+ isRoot: true,
263
+ },
264
+ });
265
+ if (!statusPage || !statusPage.coverImageFile) {
266
+ return Response.sendErrorResponse(req, res, new NotFoundException("Status Page cover image not found"));
267
+ }
268
+ return Response.sendFileResponse(req, res, statusPage.coverImageFile);
269
+ }
270
+ catch (error) {
271
+ if (error instanceof NotFoundException) {
272
+ return Response.sendErrorResponse(req, res, error);
273
+ }
274
+ logger.error(error);
275
+ return Response.sendErrorResponse(req, res, new NotFoundException("Status Page cover image not found"));
276
+ }
277
+ });
278
+ this.router.get(`${(_e = new this.entityType()
279
+ .getCrudApiPath()) === null || _e === void 0 ? void 0 : _e.toString()}/incident-public-note/attachment/:statusPageId/:incidentId/:noteId/:fileId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
280
+ try {
281
+ await this.getIncidentPublicNoteAttachment(req, res);
282
+ }
283
+ catch (err) {
284
+ next(err);
285
+ }
286
+ });
287
+ this.router.get(`${(_f = new this.entityType()
288
+ .getCrudApiPath()) === null || _f === void 0 ? void 0 : _f.toString()}/scheduled-maintenance-public-note/attachment/:statusPageId/:scheduledMaintenanceId/:noteId/:fileId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
289
+ try {
290
+ await this.getScheduledMaintenancePublicNoteAttachment(req, res);
291
+ }
292
+ catch (err) {
293
+ next(err);
294
+ }
295
+ });
296
+ this.router.get(`${(_g = new this.entityType()
297
+ .getCrudApiPath()) === null || _g === void 0 ? void 0 : _g.toString()}/status-page-announcement/attachment/:statusPageId/:announcementId/:fileId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
298
+ try {
299
+ await this.getStatusPageAnnouncementAttachment(req, res);
300
+ }
301
+ catch (err) {
302
+ next(err);
201
303
  }
202
- logger.debug(`Favicon file found. Sending file: ${statusPage.faviconFile.name}`);
203
- return Response.sendFileResponse(req, res, statusPage.faviconFile);
204
304
  });
205
305
  // embedded overall status badge api
206
- this.router.get(`${(_c = new this.entityType()
207
- .getCrudApiPath()) === null || _c === void 0 ? void 0 : _c.toString()}/badge/:statusPageId`, async (req, res) => {
306
+ this.router.get(`${(_h = new this.entityType()
307
+ .getCrudApiPath()) === null || _h === void 0 ? void 0 : _h.toString()}/badge/:statusPageId`, async (req, res) => {
208
308
  var _a;
209
309
  try {
210
310
  const statusPageId = new ObjectID(req.params["statusPageId"]);
@@ -317,8 +417,8 @@ export default class StatusPageAPI extends BaseAPI {
317
417
  }
318
418
  });
319
419
  // confirm subscription api
320
- this.router.get(`${(_d = new this.entityType()
321
- .getCrudApiPath()) === null || _d === void 0 ? void 0 : _d.toString()}/confirm-subscription/:statusPageSubscriberId`, async (req, res) => {
420
+ this.router.get(`${(_j = new this.entityType()
421
+ .getCrudApiPath()) === null || _j === void 0 ? void 0 : _j.toString()}/confirm-subscription/:statusPageSubscriberId`, async (req, res) => {
322
422
  const token = req.query["verification-token"];
323
423
  const statusPageSubscriberId = new ObjectID(req.params["statusPageSubscriberId"]);
324
424
  const subscriber = await StatusPageSubscriberService.findOneBy({
@@ -355,8 +455,8 @@ export default class StatusPageAPI extends BaseAPI {
355
455
  return Response.sendEmptySuccessResponse(req, res);
356
456
  });
357
457
  // CNAME verification api
358
- this.router.get(`${(_e = new this.entityType()
359
- .getCrudApiPath()) === null || _e === void 0 ? void 0 : _e.toString()}/cname-verification/:token`, async (req, res) => {
458
+ this.router.get(`${(_k = new this.entityType()
459
+ .getCrudApiPath()) === null || _k === void 0 ? void 0 : _k.toString()}/cname-verification/:token`, async (req, res) => {
360
460
  const host = req.get("host");
361
461
  if (!host) {
362
462
  throw new BadDataException("Host not found");
@@ -381,8 +481,8 @@ export default class StatusPageAPI extends BaseAPI {
381
481
  return Response.sendEmptySuccessResponse(req, res);
382
482
  });
383
483
  // ACME Challenge Validation.
384
- this.router.get(`${(_f = new this.entityType()
385
- .getCrudApiPath()) === null || _f === void 0 ? void 0 : _f.toString()}/.well-known/acme-challenge/:token`, async (req, res) => {
484
+ this.router.get(`${(_l = new this.entityType()
485
+ .getCrudApiPath()) === null || _l === void 0 ? void 0 : _l.toString()}/.well-known/acme-challenge/:token`, async (req, res) => {
386
486
  const challenge = await AcmeChallengeService.findOneBy({
387
487
  query: {
388
488
  token: req.params["token"],
@@ -399,7 +499,7 @@ export default class StatusPageAPI extends BaseAPI {
399
499
  }
400
500
  return Response.sendTextResponse(req, res, challenge.challenge);
401
501
  });
402
- this.router.post(`${(_g = new this.entityType().getCrudApiPath()) === null || _g === void 0 ? void 0 : _g.toString()}/test-email-report`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
502
+ this.router.post(`${(_m = new this.entityType().getCrudApiPath()) === null || _m === void 0 ? void 0 : _m.toString()}/test-email-report`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
403
503
  try {
404
504
  const email = new Email(req.body["email"]);
405
505
  const statusPageId = new ObjectID(req.body["statusPageId"].toString());
@@ -413,7 +513,7 @@ export default class StatusPageAPI extends BaseAPI {
413
513
  next(err);
414
514
  }
415
515
  });
416
- this.router.post(`${(_h = new this.entityType().getCrudApiPath()) === null || _h === void 0 ? void 0 : _h.toString()}/domain`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
516
+ this.router.post(`${(_o = new this.entityType().getCrudApiPath()) === null || _o === void 0 ? void 0 : _o.toString()}/domain`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
417
517
  try {
418
518
  if (!req.body["domain"]) {
419
519
  throw new BadDataException("domain is required in request body");
@@ -445,8 +545,8 @@ export default class StatusPageAPI extends BaseAPI {
445
545
  next(err);
446
546
  }
447
547
  });
448
- this.router.post(`${(_j = new this.entityType()
449
- .getCrudApiPath()) === null || _j === void 0 ? void 0 : _j.toString()}/master-page/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
548
+ this.router.post(`${(_p = new this.entityType()
549
+ .getCrudApiPath()) === null || _p === void 0 ? void 0 : _p.toString()}/master-page/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
450
550
  try {
451
551
  const objectId = new ObjectID(req.params["statusPageId"]);
452
552
  const select = {
@@ -562,7 +662,7 @@ export default class StatusPageAPI extends BaseAPI {
562
662
  next(err);
563
663
  }
564
664
  });
565
- this.router.post(`${(_k = new this.entityType().getCrudApiPath()) === null || _k === void 0 ? void 0 : _k.toString()}/sso/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
665
+ this.router.post(`${(_q = new this.entityType().getCrudApiPath()) === null || _q === void 0 ? void 0 : _q.toString()}/sso/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
566
666
  try {
567
667
  const objectId = new ObjectID(req.params["statusPageId"]);
568
668
  const sso = await StatusPageSsoService.findBy({
@@ -589,8 +689,8 @@ export default class StatusPageAPI extends BaseAPI {
589
689
  }
590
690
  });
591
691
  // Get all status page resources for subscriber to subscribe to.
592
- this.router.post(`${(_l = new this.entityType()
593
- .getCrudApiPath()) === null || _l === void 0 ? void 0 : _l.toString()}/resources/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
692
+ this.router.post(`${(_r = new this.entityType()
693
+ .getCrudApiPath()) === null || _r === void 0 ? void 0 : _r.toString()}/resources/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
594
694
  try {
595
695
  const statusPageId = new ObjectID(req.params["statusPageId"]);
596
696
  await this.checkHasReadAccess({
@@ -623,8 +723,8 @@ export default class StatusPageAPI extends BaseAPI {
623
723
  next(err);
624
724
  }
625
725
  });
626
- this.router.post(`${(_m = new this.entityType()
627
- .getCrudApiPath()) === null || _m === void 0 ? void 0 : _m.toString()}/uptime/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
726
+ this.router.post(`${(_s = new this.entityType()
727
+ .getCrudApiPath()) === null || _s === void 0 ? void 0 : _s.toString()}/uptime/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
628
728
  try {
629
729
  // This reosurce ID can be of a status page resource OR a status page group.
630
730
  const statusPageResourceId = new ObjectID(req.params["statusPageResourceId"]);
@@ -804,8 +904,8 @@ export default class StatusPageAPI extends BaseAPI {
804
904
  next(err);
805
905
  }
806
906
  });
807
- this.router.post(`${(_o = new this.entityType()
808
- .getCrudApiPath()) === null || _o === void 0 ? void 0 : _o.toString()}/overview/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
907
+ this.router.post(`${(_t = new this.entityType()
908
+ .getCrudApiPath()) === null || _t === void 0 ? void 0 : _t.toString()}/overview/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
809
909
  try {
810
910
  const statusPageId = new ObjectID(req.params["statusPageId"]);
811
911
  await this.checkHasReadAccess({
@@ -887,6 +987,10 @@ export default class StatusPageAPI extends BaseAPI {
887
987
  note: true,
888
988
  incidentId: true,
889
989
  postedAt: true,
990
+ attachments: {
991
+ _id: true,
992
+ name: true,
993
+ },
890
994
  },
891
995
  sort: {
892
996
  postedAt: SortOrder.Descending, // new note first
@@ -1044,6 +1148,10 @@ export default class StatusPageAPI extends BaseAPI {
1044
1148
  postedAt: true,
1045
1149
  note: true,
1046
1150
  scheduledMaintenanceId: true,
1151
+ attachments: {
1152
+ _id: true,
1153
+ name: true,
1154
+ },
1047
1155
  },
1048
1156
  sort: {
1049
1157
  postedAt: SortOrder.Ascending,
@@ -1139,8 +1247,8 @@ export default class StatusPageAPI extends BaseAPI {
1139
1247
  next(err);
1140
1248
  }
1141
1249
  });
1142
- this.router.put(`${(_p = new this.entityType()
1143
- .getCrudApiPath()) === null || _p === void 0 ? void 0 : _p.toString()}/update-subscription/:statusPageId/:subscriberId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1250
+ this.router.put(`${(_u = new this.entityType()
1251
+ .getCrudApiPath()) === null || _u === void 0 ? void 0 : _u.toString()}/update-subscription/:statusPageId/:subscriberId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1144
1252
  try {
1145
1253
  await this.subscribeToStatusPage(req);
1146
1254
  return Response.sendEmptySuccessResponse(req, res);
@@ -1149,8 +1257,8 @@ export default class StatusPageAPI extends BaseAPI {
1149
1257
  next(err);
1150
1258
  }
1151
1259
  });
1152
- this.router.post(`${(_q = new this.entityType()
1153
- .getCrudApiPath()) === null || _q === void 0 ? void 0 : _q.toString()}/get-subscription/:statusPageId/:subscriberId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1260
+ this.router.post(`${(_v = new this.entityType()
1261
+ .getCrudApiPath()) === null || _v === void 0 ? void 0 : _v.toString()}/get-subscription/:statusPageId/:subscriberId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1154
1262
  try {
1155
1263
  const subscriber = await this.getSubscriber(req);
1156
1264
  return Response.sendEntityResponse(req, res, subscriber, StatusPageSubscriber);
@@ -1159,8 +1267,8 @@ export default class StatusPageAPI extends BaseAPI {
1159
1267
  next(err);
1160
1268
  }
1161
1269
  });
1162
- this.router.post(`${(_r = new this.entityType()
1163
- .getCrudApiPath()) === null || _r === void 0 ? void 0 : _r.toString()}/subscribe/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1270
+ this.router.post(`${(_w = new this.entityType()
1271
+ .getCrudApiPath()) === null || _w === void 0 ? void 0 : _w.toString()}/subscribe/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1164
1272
  try {
1165
1273
  await this.subscribeToStatusPage(req);
1166
1274
  return Response.sendEmptySuccessResponse(req, res);
@@ -1169,8 +1277,8 @@ export default class StatusPageAPI extends BaseAPI {
1169
1277
  next(err);
1170
1278
  }
1171
1279
  });
1172
- this.router.post(`${(_s = new this.entityType()
1173
- .getCrudApiPath()) === null || _s === void 0 ? void 0 : _s.toString()}/manage-subscription/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1280
+ this.router.post(`${(_x = new this.entityType()
1281
+ .getCrudApiPath()) === null || _x === void 0 ? void 0 : _x.toString()}/manage-subscription/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1174
1282
  try {
1175
1283
  await this.manageExistingSubscription(req);
1176
1284
  return Response.sendEmptySuccessResponse(req, res);
@@ -1179,8 +1287,8 @@ export default class StatusPageAPI extends BaseAPI {
1179
1287
  next(err);
1180
1288
  }
1181
1289
  });
1182
- this.router.post(`${(_t = new this.entityType()
1183
- .getCrudApiPath()) === null || _t === void 0 ? void 0 : _t.toString()}/incidents/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1290
+ this.router.post(`${(_y = new this.entityType()
1291
+ .getCrudApiPath()) === null || _y === void 0 ? void 0 : _y.toString()}/incidents/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1184
1292
  try {
1185
1293
  const objectId = new ObjectID(req.params["statusPageId"]);
1186
1294
  const response = await this.getIncidents(objectId, null, req);
@@ -1190,8 +1298,8 @@ export default class StatusPageAPI extends BaseAPI {
1190
1298
  next(err);
1191
1299
  }
1192
1300
  });
1193
- this.router.post(`${(_u = new this.entityType()
1194
- .getCrudApiPath()) === null || _u === void 0 ? void 0 : _u.toString()}/scheduled-maintenance-events/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1301
+ this.router.post(`${(_z = new this.entityType()
1302
+ .getCrudApiPath()) === null || _z === void 0 ? void 0 : _z.toString()}/scheduled-maintenance-events/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1195
1303
  try {
1196
1304
  const objectId = new ObjectID(req.params["statusPageId"]);
1197
1305
  const response = await this.getScheduledMaintenanceEvents(objectId, null, req);
@@ -1201,8 +1309,8 @@ export default class StatusPageAPI extends BaseAPI {
1201
1309
  next(err);
1202
1310
  }
1203
1311
  });
1204
- this.router.post(`${(_v = new this.entityType()
1205
- .getCrudApiPath()) === null || _v === void 0 ? void 0 : _v.toString()}/announcements/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1312
+ this.router.post(`${(_0 = new this.entityType()
1313
+ .getCrudApiPath()) === null || _0 === void 0 ? void 0 : _0.toString()}/announcements/:statusPageId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1206
1314
  try {
1207
1315
  const objectId = new ObjectID(req.params["statusPageId"]);
1208
1316
  const response = await this.getAnnouncements(objectId, null, req);
@@ -1212,8 +1320,8 @@ export default class StatusPageAPI extends BaseAPI {
1212
1320
  next(err);
1213
1321
  }
1214
1322
  });
1215
- this.router.post(`${(_w = new this.entityType()
1216
- .getCrudApiPath()) === null || _w === void 0 ? void 0 : _w.toString()}/incidents/:statusPageId/:incidentId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1323
+ this.router.post(`${(_1 = new this.entityType()
1324
+ .getCrudApiPath()) === null || _1 === void 0 ? void 0 : _1.toString()}/incidents/:statusPageId/:incidentId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1217
1325
  try {
1218
1326
  const objectId = new ObjectID(req.params["statusPageId"]);
1219
1327
  const incidentId = new ObjectID(req.params["incidentId"]);
@@ -1224,8 +1332,8 @@ export default class StatusPageAPI extends BaseAPI {
1224
1332
  next(err);
1225
1333
  }
1226
1334
  });
1227
- this.router.post(`${(_x = new this.entityType()
1228
- .getCrudApiPath()) === null || _x === void 0 ? void 0 : _x.toString()}/scheduled-maintenance-events/:statusPageId/:scheduledMaintenanceId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1335
+ this.router.post(`${(_2 = new this.entityType()
1336
+ .getCrudApiPath()) === null || _2 === void 0 ? void 0 : _2.toString()}/scheduled-maintenance-events/:statusPageId/:scheduledMaintenanceId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1229
1337
  try {
1230
1338
  const objectId = new ObjectID(req.params["statusPageId"]);
1231
1339
  const scheduledMaintenanceId = new ObjectID(req.params["scheduledMaintenanceId"]);
@@ -1236,8 +1344,8 @@ export default class StatusPageAPI extends BaseAPI {
1236
1344
  next(err);
1237
1345
  }
1238
1346
  });
1239
- this.router.post(`${(_y = new this.entityType()
1240
- .getCrudApiPath()) === null || _y === void 0 ? void 0 : _y.toString()}/announcements/:statusPageId/:announcementId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1347
+ this.router.post(`${(_3 = new this.entityType()
1348
+ .getCrudApiPath()) === null || _3 === void 0 ? void 0 : _3.toString()}/announcements/:statusPageId/:announcementId`, UserMiddleware.getUserMiddleware, async (req, res, next) => {
1241
1349
  try {
1242
1350
  const objectId = new ObjectID(req.params["statusPageId"]);
1243
1351
  const announcementId = new ObjectID(req.params["announcementId"]);
@@ -1374,6 +1482,10 @@ export default class StatusPageAPI extends BaseAPI {
1374
1482
  postedAt: true,
1375
1483
  note: true,
1376
1484
  scheduledMaintenanceId: true,
1485
+ attachments: {
1486
+ _id: true,
1487
+ name: true,
1488
+ },
1377
1489
  },
1378
1490
  sort: {
1379
1491
  postedAt: SortOrder.Ascending,
@@ -1545,6 +1657,10 @@ export default class StatusPageAPI extends BaseAPI {
1545
1657
  _id: true,
1546
1658
  name: true,
1547
1659
  },
1660
+ attachments: {
1661
+ _id: true,
1662
+ name: true,
1663
+ },
1548
1664
  },
1549
1665
  skip: 0,
1550
1666
  limit: LIMIT_PER_PROJECT,
@@ -1631,6 +1747,7 @@ export default class StatusPageAPI extends BaseAPI {
1631
1747
  return response;
1632
1748
  }
1633
1749
  async manageExistingSubscription(req) {
1750
+ var _a, _b;
1634
1751
  const statusPageId = new ObjectID(req.params["statusPageId"]);
1635
1752
  logger.debug(`Managing Existing Subscription for Status Page: ${statusPageId}`);
1636
1753
  await this.checkHasReadAccess({
@@ -1767,16 +1884,17 @@ export default class StatusPageAPI extends BaseAPI {
1767
1884
  if (email) {
1768
1885
  const host = await DatabaseConfig.getHost();
1769
1886
  const httpProtocol = await DatabaseConfig.getHttpProtocol();
1887
+ const statusPageIdString = ((_a = statusPage.id) === null || _a === void 0 ? void 0 : _a.toString()) || ((_b = statusPage._id) === null || _b === void 0 ? void 0 : _b.toString()) || null;
1770
1888
  MailService.sendMail({
1771
1889
  toEmail: email,
1772
1890
  templateType: EmailTemplateType.ManageExistingStatusPageSubscriberSubscription,
1773
1891
  vars: {
1774
1892
  statusPageName: statusPage.name || "Status Page",
1775
1893
  statusPageUrl: statusPageURL,
1776
- logoUrl: statusPage.logoFileId
1894
+ logoUrl: statusPage.logoFileId && statusPageIdString
1777
1895
  ? new URL(httpProtocol, host)
1778
- .addRoute(FileRoute)
1779
- .addRoute("/image/" + statusPage.logoFileId)
1896
+ .addRoute(StatusPageApiRoute)
1897
+ .addRoute(`/logo/${statusPageIdString}`)
1780
1898
  .toString()
1781
1899
  : "",
1782
1900
  isPublicStatusPage: statusPage.isPublicStatusPage
@@ -2177,6 +2295,10 @@ export default class StatusPageAPI extends BaseAPI {
2177
2295
  postedAt: true,
2178
2296
  note: true,
2179
2297
  incidentId: true,
2298
+ attachments: {
2299
+ _id: true,
2300
+ name: true,
2301
+ },
2180
2302
  },
2181
2303
  sort: {
2182
2304
  postedAt: SortOrder.Descending, // new note first
@@ -2441,6 +2563,287 @@ export default class StatusPageAPI extends BaseAPI {
2441
2563
  monitorsInGroup,
2442
2564
  };
2443
2565
  }
2566
+ async getStatusPageAnnouncementAttachment(req, res) {
2567
+ var _a;
2568
+ const statusPageIdParam = req.params["statusPageId"];
2569
+ const announcementIdParam = req.params["announcementId"];
2570
+ const fileIdParam = req.params["fileId"];
2571
+ if (!statusPageIdParam || !announcementIdParam || !fileIdParam) {
2572
+ throw new NotFoundException("Attachment not found");
2573
+ }
2574
+ let statusPageId;
2575
+ let announcementId;
2576
+ let fileId;
2577
+ try {
2578
+ statusPageId = new ObjectID(statusPageIdParam);
2579
+ announcementId = new ObjectID(announcementIdParam);
2580
+ fileId = new ObjectID(fileIdParam);
2581
+ }
2582
+ catch (_b) {
2583
+ throw new NotFoundException("Attachment not found");
2584
+ }
2585
+ await this.checkHasReadAccess({
2586
+ statusPageId: statusPageId,
2587
+ req: req,
2588
+ });
2589
+ const statusPage = await StatusPageService.findOneBy({
2590
+ query: {
2591
+ _id: statusPageId.toString(),
2592
+ },
2593
+ select: {
2594
+ _id: true,
2595
+ projectId: true,
2596
+ showAnnouncementsOnStatusPage: true,
2597
+ },
2598
+ props: {
2599
+ isRoot: true,
2600
+ },
2601
+ });
2602
+ if (!statusPage ||
2603
+ !statusPage.projectId ||
2604
+ !statusPage.showAnnouncementsOnStatusPage) {
2605
+ throw new NotFoundException("Attachment not found");
2606
+ }
2607
+ const announcement = await StatusPageAnnouncementService.findOneBy({
2608
+ query: {
2609
+ _id: announcementId.toString(),
2610
+ projectId: statusPage.projectId,
2611
+ statusPages: [statusPageId],
2612
+ },
2613
+ select: {
2614
+ attachments: {
2615
+ _id: true,
2616
+ file: true,
2617
+ fileType: true,
2618
+ name: true,
2619
+ },
2620
+ },
2621
+ props: {
2622
+ isRoot: true,
2623
+ },
2624
+ });
2625
+ if (!announcement) {
2626
+ throw new NotFoundException("Attachment not found");
2627
+ }
2628
+ const attachment = (_a = announcement.attachments) === null || _a === void 0 ? void 0 : _a.find((file) => {
2629
+ const attachmentId = file._id
2630
+ ? file._id.toString()
2631
+ : file.id
2632
+ ? file.id.toString()
2633
+ : null;
2634
+ return attachmentId === fileId.toString();
2635
+ });
2636
+ if (!attachment || !attachment.file) {
2637
+ throw new NotFoundException("Attachment not found");
2638
+ }
2639
+ Response.setNoCacheHeaders(res);
2640
+ return Response.sendFileResponse(req, res, attachment);
2641
+ }
2642
+ async getScheduledMaintenancePublicNoteAttachment(req, res) {
2643
+ var _a;
2644
+ const statusPageIdParam = req.params["statusPageId"];
2645
+ const scheduledMaintenanceIdParam = req.params["scheduledMaintenanceId"];
2646
+ const noteIdParam = req.params["noteId"];
2647
+ const fileIdParam = req.params["fileId"];
2648
+ if (!statusPageIdParam ||
2649
+ !scheduledMaintenanceIdParam ||
2650
+ !noteIdParam ||
2651
+ !fileIdParam) {
2652
+ throw new NotFoundException("Attachment not found");
2653
+ }
2654
+ let statusPageId;
2655
+ let scheduledMaintenanceId;
2656
+ let noteId;
2657
+ let fileId;
2658
+ try {
2659
+ statusPageId = new ObjectID(statusPageIdParam);
2660
+ scheduledMaintenanceId = new ObjectID(scheduledMaintenanceIdParam);
2661
+ noteId = new ObjectID(noteIdParam);
2662
+ fileId = new ObjectID(fileIdParam);
2663
+ }
2664
+ catch (_b) {
2665
+ throw new NotFoundException("Attachment not found");
2666
+ }
2667
+ await this.checkHasReadAccess({
2668
+ statusPageId: statusPageId,
2669
+ req: req,
2670
+ });
2671
+ const statusPage = await StatusPageService.findOneBy({
2672
+ query: {
2673
+ _id: statusPageId.toString(),
2674
+ },
2675
+ select: {
2676
+ _id: true,
2677
+ projectId: true,
2678
+ showScheduledMaintenanceEventsOnStatusPage: true,
2679
+ },
2680
+ props: {
2681
+ isRoot: true,
2682
+ },
2683
+ });
2684
+ if (!statusPage ||
2685
+ !statusPage.projectId ||
2686
+ !statusPage.showScheduledMaintenanceEventsOnStatusPage) {
2687
+ throw new NotFoundException("Attachment not found");
2688
+ }
2689
+ const scheduledMaintenance = await ScheduledMaintenanceService.findOneBy({
2690
+ query: {
2691
+ _id: scheduledMaintenanceId.toString(),
2692
+ projectId: statusPage.projectId,
2693
+ isVisibleOnStatusPage: true,
2694
+ statusPages: statusPageId,
2695
+ },
2696
+ select: {
2697
+ _id: true,
2698
+ },
2699
+ props: {
2700
+ isRoot: true,
2701
+ },
2702
+ });
2703
+ if (!scheduledMaintenance) {
2704
+ throw new NotFoundException("Attachment not found");
2705
+ }
2706
+ const scheduledMaintenancePublicNote = await ScheduledMaintenancePublicNoteService.findOneBy({
2707
+ query: {
2708
+ _id: noteId.toString(),
2709
+ scheduledMaintenanceId: scheduledMaintenanceId.toString(),
2710
+ projectId: statusPage.projectId,
2711
+ },
2712
+ select: {
2713
+ attachments: {
2714
+ _id: true,
2715
+ file: true,
2716
+ fileType: true,
2717
+ name: true,
2718
+ },
2719
+ },
2720
+ props: {
2721
+ isRoot: true,
2722
+ },
2723
+ });
2724
+ if (!scheduledMaintenancePublicNote) {
2725
+ throw new NotFoundException("Attachment not found");
2726
+ }
2727
+ const attachment = (_a = scheduledMaintenancePublicNote.attachments) === null || _a === void 0 ? void 0 : _a.find((file) => {
2728
+ const attachmentId = file._id
2729
+ ? file._id.toString()
2730
+ : file.id
2731
+ ? file.id.toString()
2732
+ : null;
2733
+ return attachmentId === fileId.toString();
2734
+ });
2735
+ if (!attachment || !attachment.file) {
2736
+ throw new NotFoundException("Attachment not found");
2737
+ }
2738
+ Response.setNoCacheHeaders(res);
2739
+ return Response.sendFileResponse(req, res, attachment);
2740
+ }
2741
+ async getIncidentPublicNoteAttachment(req, res) {
2742
+ var _a;
2743
+ const statusPageIdParam = req.params["statusPageId"];
2744
+ const incidentIdParam = req.params["incidentId"];
2745
+ const noteIdParam = req.params["noteId"];
2746
+ const fileIdParam = req.params["fileId"];
2747
+ if (!statusPageIdParam ||
2748
+ !incidentIdParam ||
2749
+ !noteIdParam ||
2750
+ !fileIdParam) {
2751
+ throw new NotFoundException("Attachment not found");
2752
+ }
2753
+ let statusPageId;
2754
+ let incidentId;
2755
+ let noteId;
2756
+ let fileId;
2757
+ try {
2758
+ statusPageId = new ObjectID(statusPageIdParam);
2759
+ incidentId = new ObjectID(incidentIdParam);
2760
+ noteId = new ObjectID(noteIdParam);
2761
+ fileId = new ObjectID(fileIdParam);
2762
+ }
2763
+ catch (_b) {
2764
+ throw new NotFoundException("Attachment not found");
2765
+ }
2766
+ await this.checkHasReadAccess({
2767
+ statusPageId: statusPageId,
2768
+ req: req,
2769
+ });
2770
+ const statusPage = await StatusPageService.findOneBy({
2771
+ query: {
2772
+ _id: statusPageId.toString(),
2773
+ },
2774
+ select: {
2775
+ _id: true,
2776
+ projectId: true,
2777
+ showIncidentsOnStatusPage: true,
2778
+ },
2779
+ props: {
2780
+ isRoot: true,
2781
+ },
2782
+ });
2783
+ if (!statusPage || !statusPage.projectId) {
2784
+ throw new NotFoundException("Attachment not found");
2785
+ }
2786
+ if (!statusPage.showIncidentsOnStatusPage) {
2787
+ throw new NotFoundException("Attachment not found");
2788
+ }
2789
+ const { monitorsOnStatusPage } = await StatusPageService.getMonitorIdsOnStatusPage({
2790
+ statusPageId: statusPageId,
2791
+ });
2792
+ if (!monitorsOnStatusPage || monitorsOnStatusPage.length === 0) {
2793
+ throw new NotFoundException("Attachment not found");
2794
+ }
2795
+ const incident = await IncidentService.findOneBy({
2796
+ query: {
2797
+ _id: incidentId.toString(),
2798
+ projectId: statusPage.projectId,
2799
+ isVisibleOnStatusPage: true,
2800
+ monitors: monitorsOnStatusPage,
2801
+ },
2802
+ select: {
2803
+ _id: true,
2804
+ },
2805
+ props: {
2806
+ isRoot: true,
2807
+ },
2808
+ });
2809
+ if (!incident) {
2810
+ throw new NotFoundException("Attachment not found");
2811
+ }
2812
+ const incidentPublicNote = await IncidentPublicNoteService.findOneBy({
2813
+ query: {
2814
+ _id: noteId.toString(),
2815
+ incidentId: incidentId.toString(),
2816
+ projectId: statusPage.projectId,
2817
+ },
2818
+ select: {
2819
+ attachments: {
2820
+ _id: true,
2821
+ file: true,
2822
+ fileType: true,
2823
+ name: true,
2824
+ },
2825
+ },
2826
+ props: {
2827
+ isRoot: true,
2828
+ },
2829
+ });
2830
+ if (!incidentPublicNote) {
2831
+ throw new NotFoundException("Attachment not found");
2832
+ }
2833
+ const attachment = (_a = incidentPublicNote.attachments) === null || _a === void 0 ? void 0 : _a.find((file) => {
2834
+ const attachmentId = file._id
2835
+ ? file._id.toString()
2836
+ : file.id
2837
+ ? file.id.toString()
2838
+ : null;
2839
+ return attachmentId === fileId.toString();
2840
+ });
2841
+ if (!attachment || !attachment.file) {
2842
+ throw new NotFoundException("Attachment not found");
2843
+ }
2844
+ Response.setNoCacheHeaders(res);
2845
+ return Response.sendFileResponse(req, res, attachment);
2846
+ }
2444
2847
  async checkHasReadAccess(data) {
2445
2848
  const accessResult = await this.service.hasReadAccess({
2446
2849
  statusPageId: data.statusPageId,