@oneuptime/common 7.0.3717 → 7.0.3786

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 (203) hide show
  1. package/Models/DatabaseModels/Alert.ts +3 -2
  2. package/Models/DatabaseModels/Incident.ts +3 -2
  3. package/Models/DatabaseModels/Index.ts +3 -0
  4. package/Models/DatabaseModels/ProjectUser.ts +335 -0
  5. package/Models/DatabaseModels/ScheduledMaintenance.ts +3 -2
  6. package/Server/API/SlackAPI.ts +65 -97
  7. package/Server/API/UserOnCallLogTimelineAPI.ts +2 -9
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1740597525803-MigrationName.ts +17 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1740598793630-MigrationName.ts +17 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1741031019972-MigrationName.ts +17 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1741209339971-MigrationName.ts +101 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  13. package/Server/Middleware/SlackAuthorization.ts +11 -2
  14. package/Server/Services/AlertFeedService.ts +2 -2
  15. package/Server/Services/AlertInternalNoteService.ts +2 -2
  16. package/Server/Services/AlertOwnerTeamService.ts +4 -4
  17. package/Server/Services/AlertOwnerUserService.ts +3 -3
  18. package/Server/Services/AlertService.ts +62 -20
  19. package/Server/Services/AlertStateTimelineService.ts +8 -18
  20. package/Server/Services/IncidentFeedService.ts +101 -2
  21. package/Server/Services/IncidentInternalNoteService.ts +47 -4
  22. package/Server/Services/IncidentOwnerTeamService.ts +57 -4
  23. package/Server/Services/IncidentOwnerUserService.ts +59 -15
  24. package/Server/Services/IncidentPublicNoteService.ts +41 -4
  25. package/Server/Services/IncidentService.ts +279 -193
  26. package/Server/Services/IncidentStateService.ts +25 -0
  27. package/Server/Services/IncidentStateTimelineService.ts +37 -19
  28. package/Server/Services/MonitorStatusTimelineService.ts +7 -17
  29. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -0
  30. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +74 -7
  31. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +63 -4
  32. package/Server/Services/OnCallDutyPolicyService.ts +13 -0
  33. package/Server/Services/ProjectUserService.ts +130 -0
  34. package/Server/Services/ScheduledMaintenanceFeedService.ts +2 -2
  35. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +12 -10
  36. package/Server/Services/ScheduledMaintenanceOwnerTeamService.ts +22 -18
  37. package/Server/Services/ScheduledMaintenanceOwnerUserService.ts +28 -30
  38. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +12 -10
  39. package/Server/Services/ScheduledMaintenanceService.ts +16 -10
  40. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +1 -1
  41. package/Server/Services/StatusPageSubscriberService.ts +3 -0
  42. package/Server/Services/TeamMemberService.ts +20 -0
  43. package/Server/Services/UserNotificationRuleService.ts +74 -0
  44. package/Server/Services/UserOnCallLogService.ts +1 -1
  45. package/Server/Services/UserService.ts +35 -0
  46. package/Server/Services/WorkspaceNotificationRuleService.ts +508 -149
  47. package/Server/Services/WorkspaceUserAuthTokenService.ts +23 -0
  48. package/Server/Utils/Express.ts +1 -1
  49. package/Server/Utils/StartServer.ts +6 -1
  50. package/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.ts +195 -0
  51. package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +20 -0
  52. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +266 -0
  53. package/Server/Utils/Workspace/Slack/Actions/Incident.ts +1117 -0
  54. package/Server/Utils/Workspace/Slack/Messages/Incident.ts +116 -0
  55. package/Server/Utils/Workspace/Slack/Slack.ts +555 -18
  56. package/Server/Utils/Workspace/Slack/app-manifest.json +18 -10
  57. package/Server/Utils/Workspace/Workspace.ts +194 -1
  58. package/Server/Utils/Workspace/WorkspaceBase.ts +145 -19
  59. package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +68 -0
  60. package/Types/Icon/IconProp.ts +1 -0
  61. package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +2 -1
  62. package/Types/Workspace/NotificationRules/NotificationRuleUtil.ts +251 -121
  63. package/Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel.ts +6 -0
  64. package/Types/Workspace/WorkspaceMessagePayload.ts +71 -2
  65. package/UI/Components/ComingSoon/ComingSoon.tsx +13 -3
  66. package/UI/Components/Forms/Fields/FormField.tsx +2 -2
  67. package/UI/Components/Icon/Icon.tsx +39 -2
  68. package/UI/Components/ModelTable/BaseModelTable.tsx +16 -0
  69. package/UI/Components/Radio/Radio.tsx +11 -2
  70. package/UI/Components/Table/TableCard.tsx +2 -2
  71. package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
  72. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  73. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  74. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  75. package/build/dist/Models/DatabaseModels/ProjectUser.js +340 -0
  76. package/build/dist/Models/DatabaseModels/ProjectUser.js.map +1 -0
  77. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  78. package/build/dist/Server/API/SlackAPI.js +39 -79
  79. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  80. package/build/dist/Server/API/UserOnCallLogTimelineAPI.js.map +1 -1
  81. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740597525803-MigrationName.js +12 -0
  82. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740597525803-MigrationName.js.map +1 -0
  83. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740598793630-MigrationName.js +12 -0
  84. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740598793630-MigrationName.js.map +1 -0
  85. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741031019972-MigrationName.js +12 -0
  86. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741031019972-MigrationName.js.map +1 -0
  87. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741209339971-MigrationName.js +42 -0
  88. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741209339971-MigrationName.js.map +1 -0
  89. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  90. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  91. package/build/dist/Server/Middleware/SlackAuthorization.js +8 -2
  92. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  93. package/build/dist/Server/Services/AlertFeedService.js +2 -2
  94. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  95. package/build/dist/Server/Services/AlertInternalNoteService.js +2 -2
  96. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  97. package/build/dist/Server/Services/AlertOwnerTeamService.js +4 -4
  98. package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
  99. package/build/dist/Server/Services/AlertOwnerUserService.js +3 -3
  100. package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
  101. package/build/dist/Server/Services/AlertService.js +44 -19
  102. package/build/dist/Server/Services/AlertService.js.map +1 -1
  103. package/build/dist/Server/Services/AlertStateTimelineService.js +6 -16
  104. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  105. package/build/dist/Server/Services/IncidentFeedService.js +62 -2
  106. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  107. package/build/dist/Server/Services/IncidentInternalNoteService.js +35 -4
  108. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  109. package/build/dist/Server/Services/IncidentOwnerTeamService.js +42 -4
  110. package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
  111. package/build/dist/Server/Services/IncidentOwnerUserService.js +43 -15
  112. package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
  113. package/build/dist/Server/Services/IncidentPublicNoteService.js +32 -4
  114. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  115. package/build/dist/Server/Services/IncidentService.js +221 -170
  116. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  117. package/build/dist/Server/Services/IncidentStateService.js +14 -0
  118. package/build/dist/Server/Services/IncidentStateService.js.map +1 -1
  119. package/build/dist/Server/Services/IncidentStateTimelineService.js +31 -17
  120. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  121. package/build/dist/Server/Services/MonitorStatusTimelineService.js +5 -15
  122. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  123. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +1 -0
  124. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  125. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +62 -7
  126. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  127. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -5
  128. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  129. package/build/dist/Server/Services/OnCallDutyPolicyService.js +6 -0
  130. package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
  131. package/build/dist/Server/Services/ProjectUserService.js +106 -0
  132. package/build/dist/Server/Services/ProjectUserService.js.map +1 -0
  133. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js +2 -2
  134. package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js.map +1 -1
  135. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +2 -2
  136. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  137. package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js +4 -4
  138. package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js.map +1 -1
  139. package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js +8 -16
  140. package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js.map +1 -1
  141. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +2 -2
  142. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  143. package/build/dist/Server/Services/ScheduledMaintenanceService.js +5 -2
  144. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  145. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +1 -1
  146. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  147. package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
  148. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  149. package/build/dist/Server/Services/TeamMemberService.js +17 -0
  150. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  151. package/build/dist/Server/Services/UserNotificationRuleService.js +52 -0
  152. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  153. package/build/dist/Server/Services/UserOnCallLogService.js +1 -1
  154. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  155. package/build/dist/Server/Services/UserService.js +23 -0
  156. package/build/dist/Server/Services/UserService.js.map +1 -1
  157. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +306 -84
  158. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  159. package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +18 -0
  160. package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -1
  161. package/build/dist/Server/Utils/StartServer.js +4 -0
  162. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  163. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js +148 -0
  164. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js.map +1 -0
  165. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +19 -0
  166. package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -0
  167. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +167 -0
  168. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -0
  169. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +727 -0
  170. package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -0
  171. package/build/dist/Server/Utils/Workspace/Slack/Messages/Incident.js +82 -0
  172. package/build/dist/Server/Utils/Workspace/Slack/Messages/Incident.js.map +1 -0
  173. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +397 -14
  174. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  175. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +18 -10
  176. package/build/dist/Server/Utils/Workspace/Workspace.js +126 -0
  177. package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
  178. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +69 -11
  179. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  180. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js +47 -0
  181. package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -0
  182. package/build/dist/Types/Icon/IconProp.js +1 -0
  183. package/build/dist/Types/Icon/IconProp.js.map +1 -1
  184. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +2 -1
  185. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
  186. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleUtil.js +214 -120
  187. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleUtil.js.map +1 -1
  188. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel.js +2 -0
  189. package/build/dist/Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel.js.map +1 -0
  190. package/build/dist/UI/Components/ComingSoon/ComingSoon.js +3 -2
  191. package/build/dist/UI/Components/ComingSoon/ComingSoon.js.map +1 -1
  192. package/build/dist/UI/Components/Forms/Fields/FormField.js +2 -2
  193. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  194. package/build/dist/UI/Components/Icon/Icon.js +19 -2
  195. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  196. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +11 -0
  197. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  198. package/build/dist/UI/Components/Radio/Radio.js +5 -2
  199. package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
  200. package/build/dist/UI/Components/Table/TableCard.js +2 -2
  201. package/build/dist/UI/Components/Table/TableCard.js.map +1 -1
  202. package/package.json +3 -2
  203. package/Server/Utils/Workspace/Slack/app-manifest.example.json +0 -198
@@ -10,6 +10,29 @@ export class Service extends DatabaseService<Model> {
10
10
  super(Model);
11
11
  }
12
12
 
13
+ public async getUserAuth(data: {
14
+ projectId: ObjectID;
15
+ userId: ObjectID;
16
+ workspaceType: WorkspaceType;
17
+ }): Promise<Model | null> {
18
+ return await this.findOneBy({
19
+ query: {
20
+ userId: data.userId,
21
+ projectId: data.projectId,
22
+ workspaceType: data.workspaceType,
23
+ },
24
+ select: {
25
+ authToken: true,
26
+ workspaceUserId: true,
27
+ miscData: true,
28
+ workspaceType: true,
29
+ },
30
+ props: {
31
+ isRoot: true,
32
+ },
33
+ });
34
+ }
35
+
13
36
  public async doesExist(data: {
14
37
  projectId: ObjectID;
15
38
  userId: ObjectID;
@@ -38,7 +38,7 @@ export interface OneUptimeRequest extends express.Request {
38
38
  tenantId?: ObjectID;
39
39
  userGlobalAccessPermission?: UserGlobalAccessPermission;
40
40
  userTenantAccessPermission?: Dictionary<UserTenantAccessPermission>; // tenantId <-> UserTenantAccessPermission;
41
- rawBody?: string; // raw body of the request before json parsing.
41
+ rawFormUrlEncodedBody?: string;
42
42
  }
43
43
 
44
44
  export interface OneUptimeResponse extends express.Response {
@@ -31,7 +31,6 @@ import Typeof from "Common/Types/Typeof";
31
31
  import CookieParser from "cookie-parser";
32
32
  import cors from "cors";
33
33
  import zlib from "zlib";
34
-
35
34
  // Make sure we have stack trace for debugging.
36
35
  Error.stackTraceLimit = Infinity;
37
36
 
@@ -50,6 +49,12 @@ const jsonBodyParserMiddleware: RequestHandler = ExpressJson({
50
49
  const urlEncodedMiddleware: RequestHandler = ExpressUrlEncoded({
51
50
  limit: "50mb",
52
51
  extended: true,
52
+ verify: (req: ExpressRequest, _res: ExpressResponse, buf: Buffer) => {
53
+ (req as OneUptimeRequest).rawFormUrlEncodedBody = buf.toString();
54
+ logger.debug(
55
+ `Raw Form Url Encoded Body: ${(req as OneUptimeRequest).rawFormUrlEncodedBody}`,
56
+ );
57
+ },
53
58
  }); // 50 MB limit.
54
59
 
55
60
  const setDefaultHeaders: RequestHandler = (
@@ -0,0 +1,195 @@
1
+ import Incident from "../../../../../Models/DatabaseModels/Incident";
2
+ import BadDataException from "../../../../../Types/Exception/BadDataException";
3
+ import {
4
+ WorkspaceMessageBlock,
5
+ WorkspaceMessagePayloadButton,
6
+ WorkspacePayloadButtons,
7
+ WorkspacePayloadDivider,
8
+ WorkspacePayloadHeader,
9
+ WorkspacePayloadMarkdown,
10
+ } from "../../../../../Types/Workspace/WorkspaceMessagePayload";
11
+ import IncidentService from "../../../../Services/IncidentService";
12
+ import MonitorService from "../../../../Services/MonitorService";
13
+ import SlackActionType from "../../../../Utils/Workspace/Slack/Actions/ActionTypes";
14
+
15
+ export default class MicrosoftTeamsIncidentMessages {
16
+ public static async getIncidentCreateMessageBlocks(data: {
17
+ incident: Incident;
18
+ }): Promise<Array<WorkspaceMessageBlock>> {
19
+ const incident: Incident = data.incident;
20
+
21
+ if (!incident) {
22
+ throw new BadDataException("Incident not found");
23
+ }
24
+
25
+ // Slack.
26
+
27
+ const blockSlack: Array<WorkspaceMessageBlock> = [];
28
+
29
+ if (incident.incidentNumber) {
30
+ const markdownBlock1: WorkspacePayloadHeader = {
31
+ _type: "WorkspacePayloadHeader",
32
+ text: `:rotating_light: **Incident #${incident.incidentNumber}**`,
33
+ };
34
+ blockSlack.push(markdownBlock1);
35
+ }
36
+
37
+ if (incident.title) {
38
+ const markdownBlock2: WorkspacePayloadMarkdown = {
39
+ _type: "WorkspacePayloadMarkdown",
40
+ text: `**[${incident.title}](${(await IncidentService.getIncidentLinkInDashboard(incident.projectId!, incident.id!)).toString()})**`,
41
+ };
42
+ blockSlack.push(markdownBlock2);
43
+ }
44
+
45
+ if (incident.description) {
46
+ const markdownBlock3: WorkspacePayloadMarkdown = {
47
+ _type: "WorkspacePayloadMarkdown",
48
+ text: `${incident.description}`,
49
+ };
50
+ blockSlack.push(markdownBlock3);
51
+ }
52
+
53
+ if (incident.currentIncidentState?.name) {
54
+ const markdownBlock7: WorkspacePayloadMarkdown = {
55
+ _type: "WorkspacePayloadMarkdown",
56
+ text: `:arrow_right: **Incident State**: ${incident.currentIncidentState.name}`,
57
+ };
58
+ blockSlack.push(markdownBlock7);
59
+ }
60
+
61
+ if (incident.incidentSeverity?.name) {
62
+ const markdownBlock4: WorkspacePayloadMarkdown = {
63
+ _type: "WorkspacePayloadMarkdown",
64
+ text: `:warning: **Severity**: ${incident.incidentSeverity.name}`,
65
+ };
66
+ blockSlack.push(markdownBlock4);
67
+ }
68
+
69
+ // check for monitors.
70
+ if (incident.monitors && incident.monitors.length > 0) {
71
+ let text: string = `:earth_americas: *Resources Affected*:\n`;
72
+
73
+ for (const monitor of incident.monitors) {
74
+ text += `- [${monitor.name}](${(await MonitorService.getMonitorLinkInDashboard(incident.projectId!, monitor.id!)).toString()})\n`;
75
+ }
76
+
77
+ // now add text to markdwon block.
78
+ const markdownBlock5: WorkspacePayloadMarkdown = {
79
+ _type: "WorkspacePayloadMarkdown",
80
+ text: text,
81
+ };
82
+
83
+ blockSlack.push(markdownBlock5);
84
+ }
85
+
86
+ if (incident.rootCause) {
87
+ const markdownBlock5: WorkspacePayloadMarkdown = {
88
+ _type: "WorkspacePayloadMarkdown",
89
+ text: `:page_facing_up: **Root Cause**:
90
+ ${incident.rootCause}`,
91
+ };
92
+ blockSlack.push(markdownBlock5);
93
+ }
94
+
95
+ if (incident.remediationNotes) {
96
+ const markdownBlock6: WorkspacePayloadMarkdown = {
97
+ _type: "WorkspacePayloadMarkdown",
98
+ text: `:dart: **Remediation Notes**:
99
+ ${incident.remediationNotes}`,
100
+ };
101
+ blockSlack.push(markdownBlock6);
102
+ }
103
+
104
+ // add divider.
105
+
106
+ const dividerBlock: WorkspacePayloadDivider = {
107
+ _type: "WorkspacePayloadDivider",
108
+ };
109
+
110
+ blockSlack.push(dividerBlock);
111
+
112
+ // now add buttons.
113
+ // View Incident.
114
+ // Execute On Call
115
+ // Acknowledge incident
116
+ // Resolve Incident.
117
+ // Change Incident State.
118
+ // Add Note.
119
+
120
+ const buttons: Array<WorkspaceMessagePayloadButton> = [];
121
+
122
+ // view incident.
123
+ const viewIncidentButton: WorkspaceMessagePayloadButton = {
124
+ _type: "WorkspaceMessagePayloadButton",
125
+ title: "View Incident",
126
+ url: await IncidentService.getIncidentLinkInDashboard(
127
+ incident.projectId!,
128
+ incident.id!,
129
+ ),
130
+ value: "view_incident",
131
+ actionId: SlackActionType.ViewIncident,
132
+ };
133
+
134
+ buttons.push(viewIncidentButton);
135
+
136
+ // execute on call.
137
+ const executeOnCallButton: WorkspaceMessagePayloadButton = {
138
+ _type: "WorkspaceMessagePayloadButton",
139
+ title: ":telephone_receiver: Execute On Call",
140
+ value: "execute_on_call",
141
+ actionId: SlackActionType.ViewExecuteIncidentOnCallPolicy,
142
+ };
143
+
144
+ buttons.push(executeOnCallButton);
145
+
146
+ // acknowledge incident.
147
+ const acknowledgeIncidentButton: WorkspaceMessagePayloadButton = {
148
+ _type: "WorkspaceMessagePayloadButton",
149
+ title: ":eyes: Acknowledge Incident",
150
+ value: "acknowledge_incident",
151
+ actionId: SlackActionType.AcknowledgeIncident,
152
+ };
153
+
154
+ buttons.push(acknowledgeIncidentButton);
155
+
156
+ // resolve incident.
157
+ const resolveIncidentButton: WorkspaceMessagePayloadButton = {
158
+ _type: "WorkspaceMessagePayloadButton",
159
+ title: ":white_check_mark: Resolve Incident",
160
+ value: "resolve_incident",
161
+ actionId: SlackActionType.ResolveIncident,
162
+ };
163
+
164
+ buttons.push(resolveIncidentButton);
165
+
166
+ // change incident state.
167
+ const changeIncidentStateButton: WorkspaceMessagePayloadButton = {
168
+ _type: "WorkspaceMessagePayloadButton",
169
+ title: ":arrow_right: Change Incident State",
170
+ value: "change_incident_state",
171
+ actionId: SlackActionType.ViewChangeIncidentState,
172
+ };
173
+
174
+ buttons.push(changeIncidentStateButton);
175
+
176
+ // add note.
177
+ const addNoteButton: WorkspaceMessagePayloadButton = {
178
+ _type: "WorkspaceMessagePayloadButton",
179
+ title: ":page_facing_up: Add Note",
180
+ value: "add_note",
181
+ actionId: SlackActionType.ViewAddIncidentNote,
182
+ };
183
+
184
+ buttons.push(addNoteButton);
185
+
186
+ const workspacePayloadButtons: WorkspacePayloadButtons = {
187
+ buttons: buttons,
188
+ _type: "WorkspacePayloadButtons",
189
+ };
190
+
191
+ blockSlack.push(workspacePayloadButtons);
192
+
193
+ return blockSlack;
194
+ }
195
+ }
@@ -0,0 +1,20 @@
1
+ enum SlackActionType {
2
+ // Incident actions
3
+ AcknowledgeIncident = "AcknowledgeIncident",
4
+ ResolveIncident = "ResolveIncident",
5
+ ViewAddIncidentNote = "ViewAddIncidentNote",
6
+ SubmitIncidentNote = "SubmitIncidentNote",
7
+ ViewChangeIncidentState = "ViewChangeIncidentState",
8
+ SubmitChangeIncidentState = "SubmitChangeIncidentState",
9
+ ViewExecuteIncidentOnCallPolicy = "ViewExecuteIncidentOnCallPolicy",
10
+ SubmitExecuteIncidentOnCallPolicy = "SubmitExecuteIncidentOnCallPolicy",
11
+ ViewIncident = "ViewIncident",
12
+ NewIncident = "/incident", // new incident slash command
13
+ SubmitNewIncident = "SubmitNewIncident",
14
+
15
+ // Alert Actions
16
+
17
+ // Scheduled Maintenance Actions.
18
+ }
19
+
20
+ export default SlackActionType;
@@ -0,0 +1,266 @@
1
+ import WorkspaceProjectAuthToken, {
2
+ SlackMiscData,
3
+ } from "../../../../../Models/DatabaseModels/WorkspaceProjectAuthToken";
4
+ import WorkspaceUserAuthToken from "../../../../../Models/DatabaseModels/WorkspaceUserAuthToken";
5
+ import ObjectID from "../../../../../Types/ObjectID";
6
+ import { WorkspacePayloadMarkdown } from "../../../../../Types/Workspace/WorkspaceMessagePayload";
7
+ import WorkspaceUserAuthTokenService from "../../../../Services/WorkspaceUserAuthTokenService";
8
+ import { ExpressRequest } from "../../../Express";
9
+ import SlackUtil from "../Slack";
10
+ import SlackActionType from "./ActionTypes";
11
+ import WorkspaceProjectAuthTokenService from "../../../../Services/WorkspaceProjectAuthTokenService";
12
+ import logger from "../../../Logger";
13
+ import { JSONArray, JSONObject } from "../../../../../Types/JSON";
14
+ import { Dictionary } from "lodash";
15
+
16
+ export interface SlackAction {
17
+ actionValue?: string | undefined;
18
+ actionType?: SlackActionType | undefined;
19
+ }
20
+
21
+ export interface SlackRequest {
22
+ isAuthorized: boolean;
23
+ userId?: ObjectID | undefined;
24
+ projectId?: ObjectID | undefined;
25
+ projectAuthToken?: string | undefined;
26
+ userAuthToken?: string | undefined;
27
+ botUserId?: string | undefined;
28
+ slackChannelId?: string | undefined;
29
+ slackMessageId?: string | undefined;
30
+ slackUserFullName?: string | undefined;
31
+ slackUserId?: string | undefined;
32
+ slackUsername?: string | undefined;
33
+ actions?: SlackAction[] | undefined;
34
+ triggerId?: string | undefined;
35
+ view?: JSONObject | undefined; // view object from slack.
36
+ viewValues?: Dictionary<string | number | Array<string | number>> | undefined;
37
+ }
38
+
39
+ export default class SlackAuthAction {
40
+ public static async isAuthorized(data: {
41
+ req: ExpressRequest;
42
+ }): Promise<SlackRequest> {
43
+ const { req } = data;
44
+
45
+ logger.debug("Starting Slack request authorization");
46
+ logger.debug(`Request body: `);
47
+ logger.debug(req.body);
48
+
49
+ let payload: JSONObject = req.body;
50
+
51
+ if (payload["payload"] && typeof payload["payload"] === "string") {
52
+ payload = JSON.parse(payload["payload"]);
53
+ }
54
+
55
+ logger.debug(`Payload: `);
56
+ logger.debug(payload);
57
+
58
+ let slackUserId: string | undefined = (
59
+ (payload as JSONObject)["user"] as JSONObject
60
+ )?.["id"] as string;
61
+ let slackTeamId: string | undefined = (
62
+ (payload as JSONObject)["team"] as JSONObject
63
+ )?.["id"] as string;
64
+
65
+ // if there are no actions then return.
66
+ if (
67
+ (!payload["actions"] || (payload["actions"] as JSONArray).length === 0) &&
68
+ payload["type"] !== "view_submission" &&
69
+ payload["type"] !== "shortcut" &&
70
+ !payload["command"]
71
+ ) {
72
+ logger.debug("No actions found in payload. Returning unauthorized.");
73
+ return {
74
+ isAuthorized: false,
75
+ };
76
+ }
77
+
78
+ const actions: SlackAction[] = (
79
+ (payload["actions"] || []) as JSONArray
80
+ ).map((action: JSONObject) => {
81
+ return {
82
+ actionValue: action["value"] as string,
83
+ actionType: action["action_id"] as SlackActionType,
84
+ };
85
+ });
86
+
87
+ let slackChannelId: string | undefined = (
88
+ (payload as JSONObject)?.["channel"] as JSONObject
89
+ )?.["id"] as string;
90
+
91
+ if (!slackChannelId) {
92
+ slackChannelId = (payload as JSONObject)?.["channel_id"] as string;
93
+ }
94
+
95
+ const slackMessageId: string | undefined = (
96
+ (payload as JSONObject)?.["message"] as JSONObject
97
+ )?.["ts"] as string;
98
+
99
+ const slackUserFullName: string | undefined = (
100
+ (payload as JSONObject)?.["user"] as JSONObject
101
+ )?.["name"] as string;
102
+
103
+ let slackUsername: string | undefined = (
104
+ (payload as JSONObject)?.["user"] as JSONObject
105
+ )?.["username"] as string;
106
+
107
+ if (payload["user_id"]) {
108
+ slackUserId = payload["user_id"] as string;
109
+ }
110
+
111
+ if (payload["user_name"]) {
112
+ slackUsername = payload["user_name"] as string;
113
+ }
114
+
115
+ if (payload["team_id"]) {
116
+ slackTeamId = payload["team_id"] as string;
117
+ }
118
+
119
+ const triggerId: string | undefined = payload?.["trigger_id"] as string;
120
+
121
+ const projectAuth: WorkspaceProjectAuthToken | null =
122
+ await WorkspaceProjectAuthTokenService.findOneBy({
123
+ query: {
124
+ workspaceProjectId: slackTeamId,
125
+ },
126
+ select: {
127
+ projectId: true,
128
+ authToken: true,
129
+ miscData: true,
130
+ },
131
+ props: {
132
+ isRoot: true,
133
+ },
134
+ });
135
+
136
+ if (!projectAuth) {
137
+ return {
138
+ isAuthorized: false,
139
+ };
140
+ }
141
+
142
+ const projectId: ObjectID | undefined = projectAuth.projectId;
143
+
144
+ if (!projectId) {
145
+ logger.debug(
146
+ "Project ID not found in project auth. Returning unauthorized.",
147
+ );
148
+ return {
149
+ isAuthorized: false,
150
+ };
151
+ }
152
+
153
+ const userAuth: WorkspaceUserAuthToken | null =
154
+ await WorkspaceUserAuthTokenService.findOneBy({
155
+ query: {
156
+ workspaceUserId: slackUserId,
157
+ projectId: projectId,
158
+ },
159
+ select: {
160
+ userId: true,
161
+ authToken: true,
162
+ },
163
+ props: {
164
+ isRoot: true,
165
+ },
166
+ });
167
+
168
+ const botUserId: string | undefined = (
169
+ projectAuth.miscData as SlackMiscData
170
+ )?.botUserId;
171
+
172
+ const userId: ObjectID | undefined = userAuth?.userId;
173
+
174
+ if (!userAuth || !userId) {
175
+ const markdwonPayload: WorkspacePayloadMarkdown = {
176
+ _type: "WorkspacePayloadMarkdown",
177
+ text: `@${slackUsername}, Unfortunately your slack account is not connected to OneUptime. Please log into your OneUptime account, click on User Settings and then connect your Slack account. `,
178
+ };
179
+
180
+ await SlackUtil.sendDirectMessageToUser({
181
+ authToken: projectAuth.authToken!,
182
+ workspaceUserId: slackUserId,
183
+ messageBlocks: [markdwonPayload],
184
+ });
185
+
186
+ // clear response.
187
+ logger.debug("User auth not found. Returning unauthorized.");
188
+
189
+ return {
190
+ isAuthorized: false,
191
+ };
192
+ }
193
+
194
+ const view: JSONObject | undefined =
195
+ (payload["view"] as JSONObject) || undefined;
196
+
197
+ let viewValues: Dictionary<string | number | Array<string | number>> = {};
198
+
199
+ if (view) {
200
+ viewValues = SlackUtil.getValuesFromView({
201
+ view: view,
202
+ });
203
+
204
+ // add actionId and actionValue
205
+
206
+ const action: SlackAction = {
207
+ // view callbackId
208
+ actionType: view["callback_id"] as SlackActionType,
209
+ // private metadata
210
+ actionValue: view["private_metadata"]?.toString(),
211
+ };
212
+
213
+ actions.push(action);
214
+ logger.debug("View values: ");
215
+ logger.debug(viewValues);
216
+
217
+ logger.debug("Actions: ");
218
+ logger.debug(actions);
219
+ }
220
+
221
+ if (payload["callback_id"]) {
222
+ const action: SlackAction = {
223
+ actionType: payload["callback_id"] as SlackActionType,
224
+ };
225
+
226
+ actions.push(action);
227
+ }
228
+
229
+ const command: string | undefined = payload["command"] as string;
230
+ const commandText: string | undefined = payload["text"] as string;
231
+
232
+ // add command to actions.
233
+ if (command) {
234
+ const action: SlackAction = {
235
+ actionType: command as SlackActionType,
236
+ actionValue: commandText,
237
+ };
238
+
239
+ actions.push(action);
240
+ }
241
+
242
+ const slackRequest: SlackRequest = {
243
+ isAuthorized: true,
244
+ slackUserId: slackUserId,
245
+ userId: userId,
246
+ projectId: projectId,
247
+ projectAuthToken: projectAuth.authToken!,
248
+ userAuthToken: userAuth.authToken!,
249
+ botUserId: botUserId,
250
+ slackChannelId: slackChannelId,
251
+ slackUsername: slackUsername,
252
+ slackMessageId: slackMessageId,
253
+ slackUserFullName: slackUserFullName,
254
+ actions: actions,
255
+ triggerId: triggerId,
256
+ view: view,
257
+ viewValues: viewValues,
258
+ };
259
+
260
+ logger.debug("Slack request authorized successfully");
261
+ logger.debug("Slack request: ");
262
+ logger.debug(slackRequest);
263
+
264
+ return slackRequest;
265
+ }
266
+ }