@oneuptime/common 10.2.2 → 10.2.4

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 (84) hide show
  1. package/Models/DatabaseModels/Index.ts +6 -0
  2. package/Models/DatabaseModels/StatusPage.ts +43 -0
  3. package/Models/DatabaseModels/StatusPageOidc.ts +689 -0
  4. package/Models/DatabaseModels/UserNotificationRule.ts +49 -0
  5. package/Models/DatabaseModels/UserNotificationSetting.ts +17 -0
  6. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +48 -0
  7. package/Models/DatabaseModels/UserWebhook.ts +290 -0
  8. package/Models/DatabaseModels/WebhookLog.ts +992 -0
  9. package/Server/API/StatusPageAPI.ts +78 -3
  10. package/Server/API/UserWebhookAPI.ts +159 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1778506655291-AddProjectOIDC.ts +1 -1
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1778514515756-MigrationName.ts +259 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1778521361934-MigrationName.ts +17 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1778522070962-AddStatusPageOIDC.ts +63 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  16. package/Server/Services/Index.ts +2 -0
  17. package/Server/Services/ScheduledMaintenanceService.ts +34 -0
  18. package/Server/Services/StatusPageOidcService.ts +10 -0
  19. package/Server/Services/StatusPageSubscriberService.ts +101 -0
  20. package/Server/Services/UserNotificationRuleService.ts +213 -1
  21. package/Server/Services/UserNotificationSettingService.ts +95 -0
  22. package/Server/Services/UserWebhookService.ts +208 -0
  23. package/Server/Services/WebhookLogService.ts +15 -0
  24. package/Server/Services/WebhookService.ts +126 -0
  25. package/Server/Utils/StatusPageSubscriberWebhook.ts +39 -0
  26. package/Types/Permission.ts +58 -0
  27. package/Types/Webhook/WebhookMessage.ts +8 -0
  28. package/Types/WebhookStatus.ts +6 -0
  29. package/build/dist/Models/DatabaseModels/Index.js +6 -0
  30. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  31. package/build/dist/Models/DatabaseModels/StatusPage.js +45 -0
  32. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  33. package/build/dist/Models/DatabaseModels/StatusPageOidc.js +718 -0
  34. package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -0
  35. package/build/dist/Models/DatabaseModels/UserNotificationRule.js +49 -0
  36. package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
  37. package/build/dist/Models/DatabaseModels/UserNotificationSetting.js +19 -0
  38. package/build/dist/Models/DatabaseModels/UserNotificationSetting.js.map +1 -1
  39. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +48 -0
  40. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  41. package/build/dist/Models/DatabaseModels/UserWebhook.js +307 -0
  42. package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -0
  43. package/build/dist/Models/DatabaseModels/WebhookLog.js +1021 -0
  44. package/build/dist/Models/DatabaseModels/WebhookLog.js.map +1 -0
  45. package/build/dist/Server/API/StatusPageAPI.js +80 -35
  46. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  47. package/build/dist/Server/API/UserWebhookAPI.js +99 -0
  48. package/build/dist/Server/API/UserWebhookAPI.js.map +1 -0
  49. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778506655291-AddProjectOIDC.js.map +1 -1
  50. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778514515756-MigrationName.js +94 -0
  51. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778514515756-MigrationName.js.map +1 -0
  52. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778521361934-MigrationName.js +12 -0
  53. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778521361934-MigrationName.js.map +1 -0
  54. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778522070962-AddStatusPageOIDC.js +28 -0
  55. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1778522070962-AddStatusPageOIDC.js.map +1 -0
  56. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  57. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  58. package/build/dist/Server/Services/Index.js +2 -0
  59. package/build/dist/Server/Services/Index.js.map +1 -1
  60. package/build/dist/Server/Services/ScheduledMaintenanceService.js +31 -2
  61. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  62. package/build/dist/Server/Services/StatusPageOidcService.js +9 -0
  63. package/build/dist/Server/Services/StatusPageOidcService.js.map +1 -0
  64. package/build/dist/Server/Services/StatusPageSubscriberService.js +99 -4
  65. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  66. package/build/dist/Server/Services/UserNotificationRuleService.js +178 -21
  67. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  68. package/build/dist/Server/Services/UserNotificationSettingService.js +84 -1
  69. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  70. package/build/dist/Server/Services/UserWebhookService.js +190 -0
  71. package/build/dist/Server/Services/UserWebhookService.js.map +1 -0
  72. package/build/dist/Server/Services/WebhookLogService.js +13 -0
  73. package/build/dist/Server/Services/WebhookLogService.js.map +1 -0
  74. package/build/dist/Server/Services/WebhookService.js +92 -0
  75. package/build/dist/Server/Services/WebhookService.js.map +1 -0
  76. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js +19 -0
  77. package/build/dist/Server/Utils/StatusPageSubscriberWebhook.js.map +1 -0
  78. package/build/dist/Types/Permission.js +50 -0
  79. package/build/dist/Types/Permission.js.map +1 -1
  80. package/build/dist/Types/Webhook/WebhookMessage.js +2 -0
  81. package/build/dist/Types/Webhook/WebhookMessage.js.map +1 -0
  82. package/build/dist/Types/WebhookStatus.js +7 -0
  83. package/build/dist/Types/WebhookStatus.js.map +1 -0
  84. package/package.json +1 -1
@@ -26,6 +26,7 @@ import StatusPageService, {
26
26
  Service as StatusPageServiceType,
27
27
  } from "../Services/StatusPageService";
28
28
  import StatusPageSsoService from "../Services/StatusPageSsoService";
29
+ import StatusPageOidcService from "../Services/StatusPageOidcService";
29
30
  import StatusPageSubscriberService from "../Services/StatusPageSubscriberService";
30
31
  import Query from "../Types/Database/Query";
31
32
  import QueryHelper from "../Types/Database/QueryHelper";
@@ -81,6 +82,7 @@ import StatusPageHeaderLink from "../../Models/DatabaseModels/StatusPageHeaderLi
81
82
  import StatusPageHistoryChartBarColorRule from "../../Models/DatabaseModels/StatusPageHistoryChartBarColorRule";
82
83
  import StatusPageResource from "../../Models/DatabaseModels/StatusPageResource";
83
84
  import StatusPageSSO from "../../Models/DatabaseModels/StatusPageSso";
85
+ import StatusPageOIDC from "../../Models/DatabaseModels/StatusPageOidc";
84
86
  import StatusPageSubscriber from "../../Models/DatabaseModels/StatusPageSubscriber";
85
87
  import StatusPageEventType from "../../Types/StatusPage/StatusPageEventType";
86
88
  import StatusPageResourceUptimeUtil from "../../Utils/StatusPage/ResourceUptime";
@@ -863,6 +865,7 @@ export default class StatusPageAPI extends BaseAPI<
863
865
  enableEmailSubscribers: true,
864
866
  enableSlackSubscribers: true,
865
867
  enableMicrosoftTeamsSubscribers: true,
868
+ enableWebhookSubscribers: true,
866
869
  enableSmsSubscribers: true,
867
870
  isPublicStatusPage: true,
868
871
  enableMasterPassword: true,
@@ -1094,6 +1097,46 @@ export default class StatusPageAPI extends BaseAPI<
1094
1097
  },
1095
1098
  );
1096
1099
 
1100
+ this.router.post(
1101
+ `${new this.entityType().getCrudApiPath()?.toString()}/oidc/:statusPageId`,
1102
+ UserMiddleware.getUserMiddleware,
1103
+ async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
1104
+ try {
1105
+ const objectId: ObjectID = new ObjectID(
1106
+ req.params["statusPageId"] as string,
1107
+ );
1108
+
1109
+ const oidc: Array<StatusPageOIDC> =
1110
+ await StatusPageOidcService.findBy({
1111
+ query: {
1112
+ statusPageId: objectId,
1113
+ isEnabled: true,
1114
+ },
1115
+ select: {
1116
+ name: true,
1117
+ description: true,
1118
+ _id: true,
1119
+ },
1120
+ limit: LIMIT_PER_PROJECT,
1121
+ skip: 0,
1122
+ props: {
1123
+ isRoot: true,
1124
+ },
1125
+ });
1126
+
1127
+ return Response.sendEntityArrayResponse(
1128
+ req,
1129
+ res,
1130
+ oidc,
1131
+ new PositiveNumber(oidc.length),
1132
+ StatusPageOIDC,
1133
+ );
1134
+ } catch (err) {
1135
+ next(err);
1136
+ }
1137
+ },
1138
+ );
1139
+
1097
1140
  // Get all status page resources for subscriber to subscribe to.
1098
1141
  this.router.post(
1099
1142
  `${new this.entityType()
@@ -3146,6 +3189,7 @@ export default class StatusPageAPI extends BaseAPI<
3146
3189
  enableEmailSubscribers: true,
3147
3190
  enableSlackSubscribers: true,
3148
3191
  enableMicrosoftTeamsSubscribers: true,
3192
+ enableWebhookSubscribers: true,
3149
3193
  enableSmsSubscribers: true,
3150
3194
  allowSubscribersToChooseResources: true,
3151
3195
  allowSubscribersToChooseEventTypes: true,
@@ -3539,6 +3583,7 @@ export default class StatusPageAPI extends BaseAPI<
3539
3583
  enableSmsSubscribers: true,
3540
3584
  enableSlackSubscribers: true,
3541
3585
  enableMicrosoftTeamsSubscribers: true,
3586
+ enableWebhookSubscribers: true,
3542
3587
  allowSubscribersToChooseResources: true,
3543
3588
  allowSubscribersToChooseEventTypes: true,
3544
3589
  showSubscriberPageOnStatusPage: true,
@@ -3623,17 +3668,32 @@ export default class StatusPageAPI extends BaseAPI<
3623
3668
  }
3624
3669
 
3625
3670
  if (
3671
+ req.body.data["subscriberWebhook"] &&
3672
+ !statusPage.enableWebhookSubscribers
3673
+ ) {
3674
+ logger.debug(
3675
+ `Webhook subscribers not enabled for status page with ID: ${objectId}`,
3676
+ getLogAttributesFromRequest(req as any),
3677
+ );
3678
+ throw new BadDataException(
3679
+ "Webhook subscribers not enabled for this status page.",
3680
+ );
3681
+ }
3682
+
3683
+ if (
3684
+ !req.params["subscriberId"] &&
3626
3685
  !req.body.data["subscriberEmail"] &&
3627
3686
  !req.body.data["subscriberPhone"] &&
3628
3687
  !req.body.data["slackWorkspaceName"] &&
3629
- !req.body.data["microsoftTeamsWorkspaceName"]
3688
+ !req.body.data["microsoftTeamsWorkspaceName"] &&
3689
+ !req.body.data["subscriberWebhook"]
3630
3690
  ) {
3631
3691
  logger.debug(
3632
- `No email, phone, slack workspace name, or Microsoft Teams workspace name provided for subscription to status page with ID: ${objectId}`,
3692
+ `No email, phone, slack workspace name, Microsoft Teams workspace name, or webhook URL provided for subscription to status page with ID: ${objectId}`,
3633
3693
  getLogAttributesFromRequest(req as any),
3634
3694
  );
3635
3695
  throw new BadDataException(
3636
- "Email, phone, slack workspace name, or Microsoft Teams workspace name is required to subscribe to this status page.",
3696
+ "Email, phone, slack workspace name, Microsoft Teams workspace name, or webhook URL is required to subscribe to this status page.",
3637
3697
  );
3638
3698
  }
3639
3699
 
@@ -3669,6 +3729,12 @@ export default class StatusPageAPI extends BaseAPI<
3669
3729
  ? (req.body.data["microsoftTeamsWorkspaceName"] as string)
3670
3730
  : undefined;
3671
3731
 
3732
+ const subscriberWebhookUrl: string | undefined = req.body.data[
3733
+ "subscriberWebhook"
3734
+ ]
3735
+ ? (req.body.data["subscriberWebhook"] as string)
3736
+ : undefined;
3737
+
3672
3738
  let statusPageSubscriber: StatusPageSubscriber | null = null;
3673
3739
 
3674
3740
  let isUpdate: boolean = false;
@@ -3761,6 +3827,15 @@ export default class StatusPageAPI extends BaseAPI<
3761
3827
  microsoftTeamsWorkspaceName;
3762
3828
  }
3763
3829
 
3830
+ if (subscriberWebhookUrl) {
3831
+ logger.debug(
3832
+ `Setting subscriber webhook URL: ${subscriberWebhookUrl}`,
3833
+ getLogAttributesFromRequest(req as any),
3834
+ );
3835
+ statusPageSubscriber.subscriberWebhook =
3836
+ URL.fromString(subscriberWebhookUrl);
3837
+ }
3838
+
3764
3839
  if (
3765
3840
  !isUpdate &&
3766
3841
  req.body.data["statusPageResources"] &&
@@ -0,0 +1,159 @@
1
+ import UserMiddleware from "../Middleware/UserAuthorization";
2
+ import UserWebhookService, {
3
+ Service as UserWebhookServiceType,
4
+ } from "../Services/UserWebhookService";
5
+ import WebhookService from "../Services/WebhookService";
6
+ import {
7
+ ExpressRequest,
8
+ ExpressResponse,
9
+ NextFunction,
10
+ OneUptimeRequest,
11
+ } from "../Utils/Express";
12
+ import Response from "../Utils/Response";
13
+ import BaseAPI from "./BaseAPI";
14
+ import BadDataException from "../../Types/Exception/BadDataException";
15
+ import { JSONObject } from "../../Types/JSON";
16
+ import ObjectID from "../../Types/ObjectID";
17
+ import UserWebhook from "../../Models/DatabaseModels/UserWebhook";
18
+
19
+ export default class UserWebhookAPI extends BaseAPI<
20
+ UserWebhook,
21
+ UserWebhookServiceType
22
+ > {
23
+ public constructor() {
24
+ super(UserWebhook, UserWebhookService);
25
+
26
+ this.router.post(
27
+ `${new this.entityType().getCrudApiPath()?.toString()}/test`,
28
+ UserMiddleware.getUserMiddleware,
29
+ async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
30
+ try {
31
+ req = req as OneUptimeRequest;
32
+
33
+ if (!req.body["itemId"]) {
34
+ return Response.sendErrorResponse(
35
+ req,
36
+ res,
37
+ new BadDataException("Invalid item ID"),
38
+ );
39
+ }
40
+
41
+ const item: UserWebhook | null = await this.service.findOneById({
42
+ id: req.body["itemId"],
43
+ props: {
44
+ isRoot: true,
45
+ },
46
+ select: {
47
+ userId: true,
48
+ projectId: true,
49
+ webhookUrl: true,
50
+ secret: true,
51
+ name: true,
52
+ },
53
+ });
54
+
55
+ if (!item) {
56
+ return Response.sendErrorResponse(
57
+ req,
58
+ res,
59
+ new BadDataException("Item not found"),
60
+ );
61
+ }
62
+
63
+ if (
64
+ item.userId?.toString() !==
65
+ (req as OneUptimeRequest)?.userAuthorization?.userId?.toString()
66
+ ) {
67
+ return Response.sendErrorResponse(
68
+ req,
69
+ res,
70
+ new BadDataException("Invalid user ID"),
71
+ );
72
+ }
73
+
74
+ const payload: JSONObject = {
75
+ eventType: "test",
76
+ timestamp: new Date().toISOString(),
77
+ projectId: item.projectId?.toString() || "",
78
+ userId: item.userId?.toString() || "",
79
+ message:
80
+ "This is a OneUptime test webhook. Your endpoint is reachable.",
81
+ };
82
+
83
+ const sendResult: {
84
+ ok: boolean;
85
+ statusCode?: number | undefined;
86
+ message: string;
87
+ } = await this.deliverTestWebhook({
88
+ url: item.webhookUrl!,
89
+ secret: item.secret || undefined,
90
+ payload,
91
+ projectId: item.projectId!.toString(),
92
+ userId: item.userId!.toString(),
93
+ });
94
+
95
+ return Response.sendJsonObjectResponse(req, res, {
96
+ ok: sendResult.ok,
97
+ responseStatusCode: sendResult.statusCode || null,
98
+ statusMessage: sendResult.message,
99
+ });
100
+ } catch (err) {
101
+ return next(err);
102
+ }
103
+ },
104
+ );
105
+ }
106
+
107
+ private async deliverTestWebhook(input: {
108
+ url: string;
109
+ secret?: string | undefined;
110
+ payload: JSONObject;
111
+ projectId: string;
112
+ userId: string;
113
+ }): Promise<{
114
+ ok: boolean;
115
+ statusCode?: number | undefined;
116
+ message: string;
117
+ }> {
118
+ try {
119
+ const response: { isFailure?: () => boolean; statusCode?: number } =
120
+ (await WebhookService.sendWebhook(
121
+ {
122
+ url: input.url,
123
+ eventType: "test",
124
+ payload: input.payload,
125
+ secret: input.secret,
126
+ },
127
+ {
128
+ projectId: new ObjectID(input.projectId),
129
+ userId: new ObjectID(input.userId),
130
+ },
131
+ )) as { isFailure?: () => boolean; statusCode?: number };
132
+
133
+ if (
134
+ response &&
135
+ typeof response.isFailure === "function" &&
136
+ response.isFailure()
137
+ ) {
138
+ return {
139
+ ok: false,
140
+ statusCode: response.statusCode,
141
+ message: `Test webhook dispatch failed (status ${response.statusCode}). Check the Webhook Logs for details.`,
142
+ };
143
+ }
144
+
145
+ return {
146
+ ok: true,
147
+ statusCode: response?.statusCode,
148
+ message:
149
+ "Test webhook dispatched. Check the Webhook Logs and your endpoint for the delivered request.",
150
+ };
151
+ } catch (err) {
152
+ const message: string =
153
+ err instanceof Error && err.message
154
+ ? err.message
155
+ : "Unknown error sending test webhook.";
156
+ return { ok: false, message };
157
+ }
158
+ }
159
+ }
@@ -1,7 +1,7 @@
1
1
  import { MigrationInterface, QueryRunner } from "typeorm";
2
2
 
3
3
  export class AddProjectOIDC1778506655291 implements MigrationInterface {
4
- name = "AddProjectOIDC1778506655291";
4
+ public name = "AddProjectOIDC1778506655291";
5
5
 
6
6
  public async up(queryRunner: QueryRunner): Promise<void> {
7
7
  await queryRunner.query(
@@ -0,0 +1,259 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1778514515756 implements MigrationInterface {
4
+ public name = "MigrationName1778514515756";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `CREATE TABLE "WebhookLog" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "webhookUrl" character varying(500) NOT NULL, "requestBody" text, "responseStatusCode" integer, "responseBody" text, "statusMessage" character varying(500), "status" character varying(100) NOT NULL, "incidentId" uuid, "userId" uuid, "alertId" uuid, "monitorId" uuid, "scheduledMaintenanceId" uuid, "statusPageId" uuid, "statusPageAnnouncementId" uuid, "teamId" uuid, "onCallDutyPolicyId" uuid, "onCallDutyPolicyEscalationRuleId" uuid, "onCallDutyPolicyScheduleId" uuid, "deletedByUserId" uuid, CONSTRAINT "PK_8b4fb22fc2774d14ef402d1c95e" PRIMARY KEY ("_id"))`,
9
+ );
10
+ await queryRunner.query(
11
+ `CREATE INDEX "IDX_f056061dd856d2dd80535e3942" ON "WebhookLog" ("projectId") `,
12
+ );
13
+ await queryRunner.query(
14
+ `CREATE INDEX "IDX_8e2a6f99b1b4a71cb55d58a543" ON "WebhookLog" ("incidentId") `,
15
+ );
16
+ await queryRunner.query(
17
+ `CREATE INDEX "IDX_f25add443b218167cea96700df" ON "WebhookLog" ("userId") `,
18
+ );
19
+ await queryRunner.query(
20
+ `CREATE INDEX "IDX_3f72afbb4b77f17ce9dcf87bc2" ON "WebhookLog" ("alertId") `,
21
+ );
22
+ await queryRunner.query(
23
+ `CREATE INDEX "IDX_e5210a7081bc1ea3bf1aad779a" ON "WebhookLog" ("monitorId") `,
24
+ );
25
+ await queryRunner.query(
26
+ `CREATE INDEX "IDX_76a097527742676669dc19fa43" ON "WebhookLog" ("scheduledMaintenanceId") `,
27
+ );
28
+ await queryRunner.query(
29
+ `CREATE INDEX "IDX_77ca2f920c9c3fce2e135bd3f3" ON "WebhookLog" ("statusPageId") `,
30
+ );
31
+ await queryRunner.query(
32
+ `CREATE INDEX "IDX_4ed307f7eb8b93597310359a5c" ON "WebhookLog" ("statusPageAnnouncementId") `,
33
+ );
34
+ await queryRunner.query(
35
+ `CREATE INDEX "IDX_d625e8286c577c2f15391c3a38" ON "WebhookLog" ("teamId") `,
36
+ );
37
+ await queryRunner.query(
38
+ `CREATE INDEX "IDX_8721a253d2babe86ca2904c514" ON "WebhookLog" ("onCallDutyPolicyId") `,
39
+ );
40
+ await queryRunner.query(
41
+ `CREATE INDEX "IDX_0b12854b347864adb78bdda6f9" ON "WebhookLog" ("onCallDutyPolicyEscalationRuleId") `,
42
+ );
43
+ await queryRunner.query(
44
+ `CREATE INDEX "IDX_c340cb0653d553203a37f402e4" ON "WebhookLog" ("onCallDutyPolicyScheduleId") `,
45
+ );
46
+ await queryRunner.query(
47
+ `CREATE TABLE "UserWebhook" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "name" character varying(100) NOT NULL, "webhookUrl" character varying(500) NOT NULL, "secret" character varying(100), "userId" uuid, "createdByUserId" uuid, "deletedByUserId" uuid, CONSTRAINT "PK_e991ee25a603453aeb5b315af6b" PRIMARY KEY ("_id"))`,
48
+ );
49
+ await queryRunner.query(
50
+ `CREATE INDEX "IDX_9da84652f2f0459d4a27ea3f44" ON "UserWebhook" ("projectId") `,
51
+ );
52
+ await queryRunner.query(
53
+ `CREATE INDEX "IDX_a9836b0a924af14d912d344e21" ON "UserWebhook" ("userId") `,
54
+ );
55
+ await queryRunner.query(
56
+ `ALTER TABLE "UserNotificationRule" ADD "userWebhookId" uuid`,
57
+ );
58
+ await queryRunner.query(
59
+ `ALTER TABLE "UserNotificationSetting" ADD "alertByWebhook" boolean NOT NULL DEFAULT false`,
60
+ );
61
+ await queryRunner.query(
62
+ `ALTER TABLE "UserOnCallLogTimeline" ADD "userWebhookId" uuid`,
63
+ );
64
+ await queryRunner.query(
65
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
66
+ );
67
+ await queryRunner.query(
68
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
69
+ );
70
+ await queryRunner.query(
71
+ `CREATE INDEX "IDX_e183e6394d209918fbac3ec039" ON "UserNotificationRule" ("userWebhookId") `,
72
+ );
73
+ await queryRunner.query(
74
+ `CREATE INDEX "IDX_de891557845d64087311a45478" ON "UserOnCallLogTimeline" ("userWebhookId") `,
75
+ );
76
+ await queryRunner.query(
77
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_f056061dd856d2dd80535e39422" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
78
+ );
79
+ await queryRunner.query(
80
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_8e2a6f99b1b4a71cb55d58a5435" FOREIGN KEY ("incidentId") REFERENCES "Incident"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
81
+ );
82
+ await queryRunner.query(
83
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_f25add443b218167cea96700df3" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
84
+ );
85
+ await queryRunner.query(
86
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_3f72afbb4b77f17ce9dcf87bc2b" FOREIGN KEY ("alertId") REFERENCES "Alert"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
87
+ );
88
+ await queryRunner.query(
89
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_e5210a7081bc1ea3bf1aad779a0" FOREIGN KEY ("monitorId") REFERENCES "Monitor"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
90
+ );
91
+ await queryRunner.query(
92
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_76a097527742676669dc19fa430" FOREIGN KEY ("scheduledMaintenanceId") REFERENCES "ScheduledMaintenance"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
93
+ );
94
+ await queryRunner.query(
95
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_77ca2f920c9c3fce2e135bd3f33" FOREIGN KEY ("statusPageId") REFERENCES "StatusPage"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
96
+ );
97
+ await queryRunner.query(
98
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_4ed307f7eb8b93597310359a5cd" FOREIGN KEY ("statusPageAnnouncementId") REFERENCES "StatusPageAnnouncement"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
99
+ );
100
+ await queryRunner.query(
101
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_d625e8286c577c2f15391c3a38d" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
102
+ );
103
+ await queryRunner.query(
104
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_8721a253d2babe86ca2904c514f" FOREIGN KEY ("onCallDutyPolicyId") REFERENCES "OnCallDutyPolicy"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
105
+ );
106
+ await queryRunner.query(
107
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_0b12854b347864adb78bdda6f99" FOREIGN KEY ("onCallDutyPolicyEscalationRuleId") REFERENCES "OnCallDutyPolicyEscalationRule"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
108
+ );
109
+ await queryRunner.query(
110
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_c340cb0653d553203a37f402e4e" FOREIGN KEY ("onCallDutyPolicyScheduleId") REFERENCES "OnCallDutyPolicySchedule"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
111
+ );
112
+ await queryRunner.query(
113
+ `ALTER TABLE "WebhookLog" ADD CONSTRAINT "FK_41d96b5c3cb970753f81acd0142" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
114
+ );
115
+ await queryRunner.query(
116
+ `ALTER TABLE "UserWebhook" ADD CONSTRAINT "FK_9da84652f2f0459d4a27ea3f44e" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
117
+ );
118
+ await queryRunner.query(
119
+ `ALTER TABLE "UserWebhook" ADD CONSTRAINT "FK_a9836b0a924af14d912d344e211" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
120
+ );
121
+ await queryRunner.query(
122
+ `ALTER TABLE "UserWebhook" ADD CONSTRAINT "FK_5ef3baab14ef8ea04b1bf14ac3e" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
123
+ );
124
+ await queryRunner.query(
125
+ `ALTER TABLE "UserWebhook" ADD CONSTRAINT "FK_ef72bea12b483dcf47137aa7d82" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
126
+ );
127
+ await queryRunner.query(
128
+ `ALTER TABLE "UserNotificationRule" ADD CONSTRAINT "FK_e183e6394d209918fbac3ec039c" FOREIGN KEY ("userWebhookId") REFERENCES "UserWebhook"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
129
+ );
130
+ await queryRunner.query(
131
+ `ALTER TABLE "UserOnCallLogTimeline" ADD CONSTRAINT "FK_de891557845d64087311a45478d" FOREIGN KEY ("userWebhookId") REFERENCES "UserWebhook"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
132
+ );
133
+ }
134
+
135
+ public async down(queryRunner: QueryRunner): Promise<void> {
136
+ await queryRunner.query(
137
+ `ALTER TABLE "UserOnCallLogTimeline" DROP CONSTRAINT "FK_de891557845d64087311a45478d"`,
138
+ );
139
+ await queryRunner.query(
140
+ `ALTER TABLE "UserNotificationRule" DROP CONSTRAINT "FK_e183e6394d209918fbac3ec039c"`,
141
+ );
142
+ await queryRunner.query(
143
+ `ALTER TABLE "UserWebhook" DROP CONSTRAINT "FK_ef72bea12b483dcf47137aa7d82"`,
144
+ );
145
+ await queryRunner.query(
146
+ `ALTER TABLE "UserWebhook" DROP CONSTRAINT "FK_5ef3baab14ef8ea04b1bf14ac3e"`,
147
+ );
148
+ await queryRunner.query(
149
+ `ALTER TABLE "UserWebhook" DROP CONSTRAINT "FK_a9836b0a924af14d912d344e211"`,
150
+ );
151
+ await queryRunner.query(
152
+ `ALTER TABLE "UserWebhook" DROP CONSTRAINT "FK_9da84652f2f0459d4a27ea3f44e"`,
153
+ );
154
+ await queryRunner.query(
155
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_41d96b5c3cb970753f81acd0142"`,
156
+ );
157
+ await queryRunner.query(
158
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_c340cb0653d553203a37f402e4e"`,
159
+ );
160
+ await queryRunner.query(
161
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_0b12854b347864adb78bdda6f99"`,
162
+ );
163
+ await queryRunner.query(
164
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_8721a253d2babe86ca2904c514f"`,
165
+ );
166
+ await queryRunner.query(
167
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_d625e8286c577c2f15391c3a38d"`,
168
+ );
169
+ await queryRunner.query(
170
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_4ed307f7eb8b93597310359a5cd"`,
171
+ );
172
+ await queryRunner.query(
173
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_77ca2f920c9c3fce2e135bd3f33"`,
174
+ );
175
+ await queryRunner.query(
176
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_76a097527742676669dc19fa430"`,
177
+ );
178
+ await queryRunner.query(
179
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_e5210a7081bc1ea3bf1aad779a0"`,
180
+ );
181
+ await queryRunner.query(
182
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_3f72afbb4b77f17ce9dcf87bc2b"`,
183
+ );
184
+ await queryRunner.query(
185
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_f25add443b218167cea96700df3"`,
186
+ );
187
+ await queryRunner.query(
188
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_8e2a6f99b1b4a71cb55d58a5435"`,
189
+ );
190
+ await queryRunner.query(
191
+ `ALTER TABLE "WebhookLog" DROP CONSTRAINT "FK_f056061dd856d2dd80535e39422"`,
192
+ );
193
+ await queryRunner.query(
194
+ `DROP INDEX "public"."IDX_de891557845d64087311a45478"`,
195
+ );
196
+ await queryRunner.query(
197
+ `DROP INDEX "public"."IDX_e183e6394d209918fbac3ec039"`,
198
+ );
199
+ await queryRunner.query(
200
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
201
+ );
202
+ await queryRunner.query(
203
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
204
+ );
205
+ await queryRunner.query(
206
+ `ALTER TABLE "UserOnCallLogTimeline" DROP COLUMN "userWebhookId"`,
207
+ );
208
+ await queryRunner.query(
209
+ `ALTER TABLE "UserNotificationSetting" DROP COLUMN "alertByWebhook"`,
210
+ );
211
+ await queryRunner.query(
212
+ `ALTER TABLE "UserNotificationRule" DROP COLUMN "userWebhookId"`,
213
+ );
214
+ await queryRunner.query(
215
+ `DROP INDEX "public"."IDX_a9836b0a924af14d912d344e21"`,
216
+ );
217
+ await queryRunner.query(
218
+ `DROP INDEX "public"."IDX_9da84652f2f0459d4a27ea3f44"`,
219
+ );
220
+ await queryRunner.query(`DROP TABLE "UserWebhook"`);
221
+ await queryRunner.query(
222
+ `DROP INDEX "public"."IDX_c340cb0653d553203a37f402e4"`,
223
+ );
224
+ await queryRunner.query(
225
+ `DROP INDEX "public"."IDX_0b12854b347864adb78bdda6f9"`,
226
+ );
227
+ await queryRunner.query(
228
+ `DROP INDEX "public"."IDX_8721a253d2babe86ca2904c514"`,
229
+ );
230
+ await queryRunner.query(
231
+ `DROP INDEX "public"."IDX_d625e8286c577c2f15391c3a38"`,
232
+ );
233
+ await queryRunner.query(
234
+ `DROP INDEX "public"."IDX_4ed307f7eb8b93597310359a5c"`,
235
+ );
236
+ await queryRunner.query(
237
+ `DROP INDEX "public"."IDX_77ca2f920c9c3fce2e135bd3f3"`,
238
+ );
239
+ await queryRunner.query(
240
+ `DROP INDEX "public"."IDX_76a097527742676669dc19fa43"`,
241
+ );
242
+ await queryRunner.query(
243
+ `DROP INDEX "public"."IDX_e5210a7081bc1ea3bf1aad779a"`,
244
+ );
245
+ await queryRunner.query(
246
+ `DROP INDEX "public"."IDX_3f72afbb4b77f17ce9dcf87bc2"`,
247
+ );
248
+ await queryRunner.query(
249
+ `DROP INDEX "public"."IDX_f25add443b218167cea96700df"`,
250
+ );
251
+ await queryRunner.query(
252
+ `DROP INDEX "public"."IDX_8e2a6f99b1b4a71cb55d58a543"`,
253
+ );
254
+ await queryRunner.query(
255
+ `DROP INDEX "public"."IDX_f056061dd856d2dd80535e3942"`,
256
+ );
257
+ await queryRunner.query(`DROP TABLE "WebhookLog"`);
258
+ }
259
+ }
@@ -0,0 +1,17 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1778521361934 implements MigrationInterface {
4
+ public name = "MigrationName1778521361934";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `ALTER TABLE "StatusPage" ADD "enableWebhookSubscribers" boolean NOT NULL DEFAULT false`,
9
+ );
10
+ }
11
+
12
+ public async down(queryRunner: QueryRunner): Promise<void> {
13
+ await queryRunner.query(
14
+ `ALTER TABLE "StatusPage" DROP COLUMN "enableWebhookSubscribers"`,
15
+ );
16
+ }
17
+ }
@@ -0,0 +1,63 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddStatusPageOIDC1778522070962 implements MigrationInterface {
4
+ public name = "AddStatusPageOIDC1778522070962";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `CREATE TABLE "StatusPageOIDC" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "statusPageId" uuid NOT NULL, "name" character varying(100) NOT NULL, "description" character varying NOT NULL, "discoveryURL" text NOT NULL, "issuerURL" text NOT NULL, "clientId" character varying(100) NOT NULL, "clientSecret" character varying NOT NULL, "scopes" character varying(100) NOT NULL, "emailClaimName" character varying(100) NOT NULL, "nameClaimName" character varying(100), "createdByUserId" uuid, "deletedByUserId" uuid, "isEnabled" boolean NOT NULL DEFAULT false, "isTested" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_d48cc7131b1383a0c293e1142f4" PRIMARY KEY ("_id"))`,
9
+ );
10
+ await queryRunner.query(
11
+ `CREATE INDEX "IDX_da08a1ff289745767b094724f7" ON "StatusPageOIDC" ("projectId") `,
12
+ );
13
+ await queryRunner.query(
14
+ `CREATE INDEX "IDX_13c9b134ba46772392bdfb760f" ON "StatusPageOIDC" ("statusPageId") `,
15
+ );
16
+ await queryRunner.query(
17
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
18
+ );
19
+ await queryRunner.query(
20
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
21
+ );
22
+ await queryRunner.query(
23
+ `ALTER TABLE "StatusPageOIDC" ADD CONSTRAINT "FK_da08a1ff289745767b094724f79" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
24
+ );
25
+ await queryRunner.query(
26
+ `ALTER TABLE "StatusPageOIDC" ADD CONSTRAINT "FK_13c9b134ba46772392bdfb760fd" FOREIGN KEY ("statusPageId") REFERENCES "StatusPage"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
27
+ );
28
+ await queryRunner.query(
29
+ `ALTER TABLE "StatusPageOIDC" ADD CONSTRAINT "FK_8e3b6fea29c79c99389893961f1" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
30
+ );
31
+ await queryRunner.query(
32
+ `ALTER TABLE "StatusPageOIDC" ADD CONSTRAINT "FK_47054926e3844c88872599d5d55" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
33
+ );
34
+ }
35
+
36
+ public async down(queryRunner: QueryRunner): Promise<void> {
37
+ await queryRunner.query(
38
+ `ALTER TABLE "StatusPageOIDC" DROP CONSTRAINT "FK_47054926e3844c88872599d5d55"`,
39
+ );
40
+ await queryRunner.query(
41
+ `ALTER TABLE "StatusPageOIDC" DROP CONSTRAINT "FK_8e3b6fea29c79c99389893961f1"`,
42
+ );
43
+ await queryRunner.query(
44
+ `ALTER TABLE "StatusPageOIDC" DROP CONSTRAINT "FK_13c9b134ba46772392bdfb760fd"`,
45
+ );
46
+ await queryRunner.query(
47
+ `ALTER TABLE "StatusPageOIDC" DROP CONSTRAINT "FK_da08a1ff289745767b094724f79"`,
48
+ );
49
+ await queryRunner.query(
50
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
51
+ );
52
+ await queryRunner.query(
53
+ `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
54
+ );
55
+ await queryRunner.query(
56
+ `DROP INDEX "public"."IDX_13c9b134ba46772392bdfb760f"`,
57
+ );
58
+ await queryRunner.query(
59
+ `DROP INDEX "public"."IDX_da08a1ff289745767b094724f7"`,
60
+ );
61
+ await queryRunner.query(`DROP TABLE "StatusPageOIDC"`);
62
+ }
63
+ }