@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.
- package/Models/DatabaseModels/AlertInternalNote.ts +58 -1
- package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +1 -0
- package/Models/DatabaseModels/File.ts +1 -1
- package/Models/DatabaseModels/IncidentInternalNote.ts +58 -1
- package/Models/DatabaseModels/IncidentPublicNote.ts +58 -1
- package/Models/DatabaseModels/ScheduledMaintenanceInternalNote.ts +58 -1
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +58 -1
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +49 -0
- package/Server/API/AlertInternalNoteAPI.ts +96 -0
- package/Server/API/IncidentInternalNoteAPI.ts +96 -0
- package/Server/API/IncidentPublicNoteAPI.ts +96 -0
- package/Server/API/ScheduledMaintenanceInternalNoteAPI.ts +100 -0
- package/Server/API/ScheduledMaintenancePublicNoteAPI.ts +100 -0
- package/Server/API/StatusPageAPI.ts +585 -59
- package/Server/API/StatusPageAnnouncementAPI.ts +98 -0
- package/Server/API/UserAPI.ts +95 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.ts +81 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.ts +79 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/ProjectAuthorization.ts +3 -1
- package/Server/Services/AlertInternalNoteService.ts +75 -2
- package/Server/Services/IncidentInternalNoteService.ts +76 -2
- package/Server/Services/IncidentPublicNoteService.ts +76 -2
- package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +76 -2
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +76 -2
- package/Server/Services/ScheduledMaintenanceService.ts +10 -7
- package/Server/Services/StatusPagePrivateUserService.ts +10 -7
- package/Server/Services/StatusPageService.ts +12 -7
- package/Server/Services/StatusPageSubscriberService.ts +19 -13
- package/Server/Utils/FileAttachmentMarkdownUtil.ts +98 -0
- package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +9 -1
- package/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.ts +34 -0
- package/Server/Utils/Monitor/DataToProcess.ts +3 -1
- package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +13 -0
- package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +20 -0
- package/Server/Utils/Monitor/MonitorResource.ts +18 -0
- package/Server/Utils/Response.ts +13 -0
- package/Server/Utils/Telemetry.ts +15 -0
- package/Types/File/MimeType.ts +18 -0
- package/Types/Monitor/CriteriaFilter.ts +3 -0
- package/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.ts +12 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
- package/Types/Monitor/MonitorStep.ts +30 -0
- package/Types/Monitor/MonitorStepExceptionMonitor.ts +94 -0
- package/Types/Monitor/MonitorType.ts +10 -1
- package/Types/Telemetry/TelemetryQuery.ts +2 -1
- package/Types/Telemetry/TelemetryType.ts +1 -0
- package/UI/Components/AttachmentList/EventAttachmentList.tsx +121 -0
- package/UI/Components/EventItem/EventItem.tsx +22 -0
- package/UI/Components/Feed/FeedItem.tsx +9 -16
- package/UI/Components/FilePicker/FilePicker.tsx +441 -145
- package/UI/Components/Forms/Fields/FormField.tsx +32 -15
- package/UI/Components/Forms/FormSummary.tsx +168 -1
- package/UI/Components/Forms/ModelForm.tsx +46 -24
- package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
- package/UI/Components/Icon/Icon.tsx +1 -1
- package/UI/Utils/API/RequestOptions.ts +2 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +18 -0
- package/UI/Utils/User.ts +8 -0
- package/Utils/API.ts +11 -1
- package/build/dist/Models/DatabaseModels/AlertInternalNote.js +49 -1
- package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +1 -0
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/File.js +1 -1
- package/build/dist/Models/DatabaseModels/File.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentInternalNote.js +49 -1
- package/build/dist/Models/DatabaseModels/IncidentInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +49 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js +49 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +49 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +48 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Server/API/AlertInternalNoteAPI.js +68 -0
- package/build/dist/Server/API/AlertInternalNoteAPI.js.map +1 -0
- package/build/dist/Server/API/IncidentInternalNoteAPI.js +68 -0
- package/build/dist/Server/API/IncidentInternalNoteAPI.js.map +1 -0
- package/build/dist/Server/API/IncidentPublicNoteAPI.js +68 -0
- package/build/dist/Server/API/IncidentPublicNoteAPI.js.map +1 -0
- package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js +68 -0
- package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js.map +1 -0
- package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js +68 -0
- package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js.map +1 -0
- package/build/dist/Server/API/StatusPageAPI.js +488 -85
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAnnouncementAPI.js +68 -0
- package/build/dist/Server/API/StatusPageAnnouncementAPI.js.map +1 -0
- package/build/dist/Server/API/UserAPI.js +66 -0
- package/build/dist/Server/API/UserAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +4 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertInternalNoteService.js +54 -2
- package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentInternalNoteService.js +54 -2
- package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +54 -2
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +54 -2
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +54 -2
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +6 -5
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/StatusPagePrivateUserService.js +6 -4
- package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +7 -4
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +11 -7
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js +67 -0
- package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +6 -1
- package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js +34 -0
- package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +6 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +10 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +8 -0
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry.js +8 -1
- package/build/dist/Server/Utils/Telemetry.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +18 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js +2 -0
- package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +20 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +58 -0
- package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorType.js +9 -1
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
- package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +42 -0
- package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -0
- package/build/dist/UI/Components/EventItem/EventItem.js +5 -1
- package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +6 -4
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/FilePicker/FilePicker.js +262 -77
- package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +24 -12
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/FormSummary.js +77 -1
- package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +32 -18
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
- package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +1 -1
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +30 -45
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/User.js +7 -0
- package/build/dist/UI/Utils/User.js.map +1 -1
- package/build/dist/Utils/API.js +3 -0
- package/build/dist/Utils/API.js.map +1 -1
- 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 {
|
|
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
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
155
|
-
domain: {
|
|
156
|
-
isVerified: true,
|
|
157
|
-
},
|
|
185
|
+
_id: statusPageId,
|
|
158
186
|
},
|
|
159
187
|
select: {
|
|
160
|
-
|
|
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 (!
|
|
167
|
-
|
|
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
|
-
|
|
203
|
+
logger.debug(`Favicon file found. Sending file: ${statusPage.faviconFile.name}`);
|
|
204
|
+
return Response.sendFileResponse(req, res, statusPage.faviconFile);
|
|
170
205
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
statusPageId = new ObjectID(statusPageIdOrDomain);
|
|
206
|
+
catch (error) {
|
|
207
|
+
if (error instanceof NotFoundException) {
|
|
208
|
+
return Response.sendErrorResponse(req, res, error);
|
|
175
209
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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(`${(
|
|
207
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
321
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
359
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
385
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
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(`${(
|
|
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(`${(
|
|
449
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
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(`${(
|
|
593
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
627
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
808
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1143
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1153
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1163
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1173
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1183
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1194
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1205
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1216
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1228
|
-
.getCrudApiPath()) === null ||
|
|
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(`${(
|
|
1240
|
-
.getCrudApiPath()) === null ||
|
|
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(
|
|
1779
|
-
.addRoute(
|
|
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,
|