@oneuptime/common 7.0.3718 → 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.
- package/Models/DatabaseModels/Alert.ts +3 -2
- package/Models/DatabaseModels/Incident.ts +3 -2
- package/Models/DatabaseModels/Index.ts +3 -0
- package/Models/DatabaseModels/ProjectUser.ts +335 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +3 -2
- package/Server/API/SlackAPI.ts +65 -97
- package/Server/Infrastructure/Postgres/SchemaMigrations/1740597525803-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1740598793630-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741031019972-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1741209339971-MigrationName.ts +101 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Middleware/SlackAuthorization.ts +11 -2
- package/Server/Services/AlertFeedService.ts +2 -2
- package/Server/Services/AlertInternalNoteService.ts +2 -2
- package/Server/Services/AlertOwnerTeamService.ts +4 -4
- package/Server/Services/AlertOwnerUserService.ts +3 -3
- package/Server/Services/AlertService.ts +62 -20
- package/Server/Services/AlertStateTimelineService.ts +8 -18
- package/Server/Services/IncidentFeedService.ts +101 -2
- package/Server/Services/IncidentInternalNoteService.ts +47 -4
- package/Server/Services/IncidentOwnerTeamService.ts +57 -4
- package/Server/Services/IncidentOwnerUserService.ts +59 -15
- package/Server/Services/IncidentPublicNoteService.ts +41 -4
- package/Server/Services/IncidentService.ts +279 -193
- package/Server/Services/IncidentStateService.ts +25 -0
- package/Server/Services/IncidentStateTimelineService.ts +37 -19
- package/Server/Services/MonitorStatusTimelineService.ts +7 -17
- package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +2 -0
- package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +74 -7
- package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +63 -4
- package/Server/Services/OnCallDutyPolicyService.ts +13 -0
- package/Server/Services/ProjectUserService.ts +130 -0
- package/Server/Services/ScheduledMaintenanceFeedService.ts +2 -2
- package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +12 -10
- package/Server/Services/ScheduledMaintenanceOwnerTeamService.ts +22 -18
- package/Server/Services/ScheduledMaintenanceOwnerUserService.ts +28 -30
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +12 -10
- package/Server/Services/ScheduledMaintenanceService.ts +16 -10
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +1 -1
- package/Server/Services/StatusPageSubscriberService.ts +3 -0
- package/Server/Services/TeamMemberService.ts +20 -0
- package/Server/Services/UserNotificationRuleService.ts +74 -0
- package/Server/Services/UserOnCallLogService.ts +1 -1
- package/Server/Services/UserService.ts +35 -0
- package/Server/Services/WorkspaceNotificationRuleService.ts +508 -149
- package/Server/Services/WorkspaceUserAuthTokenService.ts +23 -0
- package/Server/Utils/Express.ts +1 -1
- package/Server/Utils/StartServer.ts +6 -1
- package/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.ts +195 -0
- package/Server/Utils/Workspace/Slack/Actions/ActionTypes.ts +20 -0
- package/Server/Utils/Workspace/Slack/Actions/Auth.ts +266 -0
- package/Server/Utils/Workspace/Slack/Actions/Incident.ts +1117 -0
- package/Server/Utils/Workspace/Slack/Messages/Incident.ts +116 -0
- package/Server/Utils/Workspace/Slack/Slack.ts +555 -18
- package/Server/Utils/Workspace/Slack/app-manifest.json +18 -10
- package/Server/Utils/Workspace/Workspace.ts +194 -1
- package/Server/Utils/Workspace/WorkspaceBase.ts +145 -19
- package/Server/Utils/Workspace/WorkspaceMessages/Incident.ts +68 -0
- package/Types/Icon/IconProp.ts +1 -0
- package/Types/Workspace/NotificationRules/NotificationRuleCondition.ts +2 -1
- package/Types/Workspace/NotificationRules/NotificationRuleUtil.ts +251 -121
- package/Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel.ts +6 -0
- package/Types/Workspace/WorkspaceMessagePayload.ts +71 -2
- package/UI/Components/ComingSoon/ComingSoon.tsx +13 -3
- package/UI/Components/Forms/Fields/FormField.tsx +2 -2
- package/UI/Components/Icon/Icon.tsx +39 -2
- package/UI/Components/ModelTable/BaseModelTable.tsx +16 -0
- package/UI/Components/Radio/Radio.tsx +11 -2
- package/UI/Components/Table/TableCard.tsx +2 -2
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProjectUser.js +340 -0
- package/build/dist/Models/DatabaseModels/ProjectUser.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +39 -79
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740597525803-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740597525803-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740598793630-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1740598793630-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741031019972-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741031019972-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741209339971-MigrationName.js +42 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1741209339971-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/SlackAuthorization.js +8 -2
- package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AlertFeedService.js +2 -2
- package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
- package/build/dist/Server/Services/AlertInternalNoteService.js +2 -2
- package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerTeamService.js +4 -4
- package/build/dist/Server/Services/AlertOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/AlertOwnerUserService.js +3 -3
- package/build/dist/Server/Services/AlertOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +44 -19
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertStateTimelineService.js +6 -16
- package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFeedService.js +62 -2
- package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
- package/build/dist/Server/Services/IncidentInternalNoteService.js +35 -4
- package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerTeamService.js +42 -4
- package/build/dist/Server/Services/IncidentOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/IncidentOwnerUserService.js +43 -15
- package/build/dist/Server/Services/IncidentOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +32 -4
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +221 -170
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateService.js +14 -0
- package/build/dist/Server/Services/IncidentStateService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +31 -17
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/MonitorStatusTimelineService.js +5 -15
- package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +1 -0
- package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +62 -7
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -5
- package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
- package/build/dist/Server/Services/OnCallDutyPolicyService.js +6 -0
- package/build/dist/Server/Services/OnCallDutyPolicyService.js.map +1 -1
- package/build/dist/Server/Services/ProjectUserService.js +106 -0
- package/build/dist/Server/Services/ProjectUserService.js.map +1 -0
- package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js +2 -2
- package/build/dist/Server/Services/ScheduledMaintenanceFeedService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +2 -2
- package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js +4 -4
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerTeamService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js +8 -16
- package/build/dist/Server/Services/ScheduledMaintenanceOwnerUserService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +2 -2
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +5 -2
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +17 -0
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +52 -0
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js +1 -1
- package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +23 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +306 -84
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +18 -0
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +4 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js +148 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Messages/Incident.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js +19 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/ActionTypes.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +167 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js +727 -0
- package/build/dist/Server/Utils/Workspace/Slack/Actions/Incident.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/Incident.js +82 -0
- package/build/dist/Server/Utils/Workspace/Slack/Messages/Incident.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +397 -14
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +18 -10
- package/build/dist/Server/Utils/Workspace/Workspace.js +126 -0
- package/build/dist/Server/Utils/Workspace/Workspace.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js +69 -11
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js +47 -0
- package/build/dist/Server/Utils/Workspace/WorkspaceMessages/Incident.js.map +1 -0
- package/build/dist/Types/Icon/IconProp.js +1 -0
- package/build/dist/Types/Icon/IconProp.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js +2 -1
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleCondition.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleUtil.js +214 -120
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleUtil.js.map +1 -1
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel.js +2 -0
- package/build/dist/Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel.js.map +1 -0
- package/build/dist/UI/Components/ComingSoon/ComingSoon.js +3 -2
- package/build/dist/UI/Components/ComingSoon/ComingSoon.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +2 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Icon/Icon.js +19 -2
- package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +11 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/Radio/Radio.js +5 -2
- package/build/dist/UI/Components/Radio/Radio.js.map +1 -1
- package/build/dist/UI/Components/Table/TableCard.js +2 -2
- package/build/dist/UI/Components/Table/TableCard.js.map +1 -1
- package/package.json +3 -2
- package/Server/Utils/Workspace/Slack/app-manifest.example.json +0 -198
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
ManyToOne,
|
|
37
37
|
} from "typeorm";
|
|
38
38
|
import { TelemetryQuery } from "../../Types/Telemetry/TelemetryQuery";
|
|
39
|
-
import
|
|
39
|
+
import NotificationRuleWorkspaceChannel from "../../Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel";
|
|
40
40
|
|
|
41
41
|
@EnableDocumentation()
|
|
42
42
|
@AccessControlColumn("labels")
|
|
@@ -1053,5 +1053,6 @@ export default class Alert extends BaseModel {
|
|
|
1053
1053
|
type: ColumnType.JSON,
|
|
1054
1054
|
nullable: true,
|
|
1055
1055
|
})
|
|
1056
|
-
public postUpdatesToWorkspaceChannels?: Array<
|
|
1056
|
+
public postUpdatesToWorkspaceChannels?: Array<NotificationRuleWorkspaceChannel> =
|
|
1057
|
+
undefined;
|
|
1057
1058
|
}
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
ManyToOne,
|
|
38
38
|
} from "typeorm";
|
|
39
39
|
import { TelemetryQuery } from "../../Types/Telemetry/TelemetryQuery";
|
|
40
|
-
import
|
|
40
|
+
import NotificationRuleWorkspaceChannel from "../../Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel";
|
|
41
41
|
|
|
42
42
|
@EnableDocumentation()
|
|
43
43
|
@AccessControlColumn("labels")
|
|
@@ -1138,7 +1138,8 @@ export default class Incident extends BaseModel {
|
|
|
1138
1138
|
type: ColumnType.JSON,
|
|
1139
1139
|
nullable: true,
|
|
1140
1140
|
})
|
|
1141
|
-
public postUpdatesToWorkspaceChannels?: Array<
|
|
1141
|
+
public postUpdatesToWorkspaceChannels?: Array<NotificationRuleWorkspaceChannel> =
|
|
1142
|
+
undefined;
|
|
1142
1143
|
|
|
1143
1144
|
@ColumnAccessControl({
|
|
1144
1145
|
create: [
|
|
@@ -165,6 +165,7 @@ import WorkspaceUserAuthToken from "./WorkspaceUserAuthToken";
|
|
|
165
165
|
import WorkspaceProjectAuthToken from "./WorkspaceProjectAuthToken";
|
|
166
166
|
import WorkspaceSetting from "./WorkspaceSetting";
|
|
167
167
|
import WorkspaceNotificationRule from "./WorkspaceNotificationRule";
|
|
168
|
+
import ProjectUser from "./ProjectUser";
|
|
168
169
|
|
|
169
170
|
const AllModelTypes: Array<{
|
|
170
171
|
new (): BaseModel;
|
|
@@ -353,6 +354,8 @@ const AllModelTypes: Array<{
|
|
|
353
354
|
|
|
354
355
|
WorkspaceSetting,
|
|
355
356
|
WorkspaceNotificationRule,
|
|
357
|
+
|
|
358
|
+
ProjectUser,
|
|
356
359
|
];
|
|
357
360
|
|
|
358
361
|
const modelTypeMap: { [key: string]: { new (): BaseModel } } = {};
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import Project from "./Project";
|
|
2
|
+
import Team from "./Team";
|
|
3
|
+
import User from "./User";
|
|
4
|
+
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
5
|
+
import Route from "../../Types/API/Route";
|
|
6
|
+
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
7
|
+
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
8
|
+
import AllowUserQueryWithoutTenant from "../../Types/Database/AllowUserQueryWithoutTenant";
|
|
9
|
+
import ColumnType from "../../Types/Database/ColumnType";
|
|
10
|
+
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
11
|
+
import CurrentUserCanAccessRecordBy from "../../Types/Database/CurrentUserCanAccessRecordBy";
|
|
12
|
+
import MultiTenentQueryAllowed from "../../Types/Database/MultiTenentQueryAllowed";
|
|
13
|
+
import TableColumn from "../../Types/Database/TableColumn";
|
|
14
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
15
|
+
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
16
|
+
import TenantColumn from "../../Types/Database/TenantColumn";
|
|
17
|
+
import IconProp from "../../Types/Icon/IconProp";
|
|
18
|
+
import ObjectID from "../../Types/ObjectID";
|
|
19
|
+
import Permission from "../../Types/Permission";
|
|
20
|
+
import {
|
|
21
|
+
Column,
|
|
22
|
+
Entity,
|
|
23
|
+
Index,
|
|
24
|
+
JoinColumn,
|
|
25
|
+
JoinTable,
|
|
26
|
+
ManyToMany,
|
|
27
|
+
ManyToOne,
|
|
28
|
+
} from "typeorm";
|
|
29
|
+
|
|
30
|
+
@TableAccessControl({
|
|
31
|
+
create: [],
|
|
32
|
+
read: [
|
|
33
|
+
Permission.ProjectOwner,
|
|
34
|
+
Permission.ProjectAdmin,
|
|
35
|
+
Permission.ProjectMember,
|
|
36
|
+
Permission.ReadProjectTeam,
|
|
37
|
+
Permission.CurrentUser,
|
|
38
|
+
],
|
|
39
|
+
delete: [],
|
|
40
|
+
update: [],
|
|
41
|
+
})
|
|
42
|
+
@MultiTenentQueryAllowed(true)
|
|
43
|
+
@AllowUserQueryWithoutTenant(true)
|
|
44
|
+
@CurrentUserCanAccessRecordBy("userId")
|
|
45
|
+
@TenantColumn("projectId")
|
|
46
|
+
@CrudApiEndpoint(new Route("/project-user"))
|
|
47
|
+
@Entity({
|
|
48
|
+
name: "ProjectUser",
|
|
49
|
+
})
|
|
50
|
+
@TableMetadata({
|
|
51
|
+
tableName: "ProjectUser",
|
|
52
|
+
singularName: "User",
|
|
53
|
+
pluralName: "Users",
|
|
54
|
+
icon: IconProp.User,
|
|
55
|
+
tableDescription:
|
|
56
|
+
"This model connects users and teams. This is an internal table. Its a view on TeamMembers table.",
|
|
57
|
+
})
|
|
58
|
+
export default class ProjectUser extends BaseModel {
|
|
59
|
+
@ColumnAccessControl({
|
|
60
|
+
create: [],
|
|
61
|
+
read: [
|
|
62
|
+
Permission.ProjectOwner,
|
|
63
|
+
Permission.ProjectAdmin,
|
|
64
|
+
Permission.ProjectMember,
|
|
65
|
+
Permission.ReadProjectTeam,
|
|
66
|
+
Permission.CurrentUser,
|
|
67
|
+
],
|
|
68
|
+
update: [],
|
|
69
|
+
})
|
|
70
|
+
@TableColumn({
|
|
71
|
+
required: false,
|
|
72
|
+
type: TableColumnType.EntityArray,
|
|
73
|
+
modelType: Team,
|
|
74
|
+
title: "Teams",
|
|
75
|
+
description: "Teams to which this user belongs.",
|
|
76
|
+
})
|
|
77
|
+
@ManyToMany(
|
|
78
|
+
() => {
|
|
79
|
+
return Team;
|
|
80
|
+
},
|
|
81
|
+
{ eager: false },
|
|
82
|
+
)
|
|
83
|
+
@JoinTable({
|
|
84
|
+
name: "ProjectUserAcceptedTeams",
|
|
85
|
+
inverseJoinColumn: {
|
|
86
|
+
name: "teamId",
|
|
87
|
+
referencedColumnName: "_id",
|
|
88
|
+
},
|
|
89
|
+
joinColumn: {
|
|
90
|
+
name: "projectUserId",
|
|
91
|
+
referencedColumnName: "_id",
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
public acceptedTeams?: Array<Team> = undefined; // user is accepted to these teams. This is a view on TeamMembers table.
|
|
95
|
+
|
|
96
|
+
@ColumnAccessControl({
|
|
97
|
+
create: [],
|
|
98
|
+
read: [
|
|
99
|
+
Permission.ProjectOwner,
|
|
100
|
+
Permission.ProjectAdmin,
|
|
101
|
+
Permission.ProjectMember,
|
|
102
|
+
Permission.ReadProjectTeam,
|
|
103
|
+
Permission.CurrentUser,
|
|
104
|
+
],
|
|
105
|
+
update: [],
|
|
106
|
+
})
|
|
107
|
+
@TableColumn({
|
|
108
|
+
required: false,
|
|
109
|
+
type: TableColumnType.EntityArray,
|
|
110
|
+
modelType: Team,
|
|
111
|
+
title: "Teams",
|
|
112
|
+
description: "Teams to which this user belongs.",
|
|
113
|
+
})
|
|
114
|
+
@ManyToMany(
|
|
115
|
+
() => {
|
|
116
|
+
return Team;
|
|
117
|
+
},
|
|
118
|
+
{ eager: false },
|
|
119
|
+
)
|
|
120
|
+
@JoinTable({
|
|
121
|
+
name: "ProjectUserInvitedTeams",
|
|
122
|
+
inverseJoinColumn: {
|
|
123
|
+
name: "teamId",
|
|
124
|
+
referencedColumnName: "_id",
|
|
125
|
+
},
|
|
126
|
+
joinColumn: {
|
|
127
|
+
name: "projectUserId",
|
|
128
|
+
referencedColumnName: "_id",
|
|
129
|
+
},
|
|
130
|
+
})
|
|
131
|
+
public invitedTeams?: Array<Team> = undefined; // user is invited to these teams.
|
|
132
|
+
|
|
133
|
+
@ColumnAccessControl({
|
|
134
|
+
create: [],
|
|
135
|
+
read: [
|
|
136
|
+
Permission.ProjectOwner,
|
|
137
|
+
Permission.ProjectAdmin,
|
|
138
|
+
Permission.ProjectMember,
|
|
139
|
+
Permission.ReadProjectTeam,
|
|
140
|
+
Permission.CurrentUser,
|
|
141
|
+
],
|
|
142
|
+
update: [],
|
|
143
|
+
})
|
|
144
|
+
@TableColumn({
|
|
145
|
+
manyToOneRelationColumn: "projectId",
|
|
146
|
+
type: TableColumnType.Entity,
|
|
147
|
+
modelType: Project,
|
|
148
|
+
title: "Project",
|
|
149
|
+
description: "Relation to Project Resource in which this object belongs",
|
|
150
|
+
})
|
|
151
|
+
@ManyToOne(
|
|
152
|
+
() => {
|
|
153
|
+
return Project;
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
eager: false,
|
|
157
|
+
nullable: true,
|
|
158
|
+
onDelete: "CASCADE",
|
|
159
|
+
orphanedRowAction: "nullify",
|
|
160
|
+
},
|
|
161
|
+
)
|
|
162
|
+
@JoinColumn({ name: "projectId" })
|
|
163
|
+
public project?: Project = undefined;
|
|
164
|
+
|
|
165
|
+
@ColumnAccessControl({
|
|
166
|
+
create: [],
|
|
167
|
+
read: [
|
|
168
|
+
Permission.ProjectOwner,
|
|
169
|
+
Permission.ProjectAdmin,
|
|
170
|
+
Permission.ProjectMember,
|
|
171
|
+
Permission.ReadProjectTeam,
|
|
172
|
+
Permission.CurrentUser,
|
|
173
|
+
],
|
|
174
|
+
update: [],
|
|
175
|
+
})
|
|
176
|
+
@Index()
|
|
177
|
+
@TableColumn({
|
|
178
|
+
type: TableColumnType.ObjectID,
|
|
179
|
+
required: true,
|
|
180
|
+
canReadOnRelationQuery: true,
|
|
181
|
+
title: "Project ID",
|
|
182
|
+
description: "ID of your OneUptime Project in which this object belongs",
|
|
183
|
+
})
|
|
184
|
+
@Column({
|
|
185
|
+
type: ColumnType.ObjectID,
|
|
186
|
+
nullable: false,
|
|
187
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
188
|
+
})
|
|
189
|
+
public projectId?: ObjectID = undefined;
|
|
190
|
+
|
|
191
|
+
@ColumnAccessControl({
|
|
192
|
+
create: [],
|
|
193
|
+
read: [
|
|
194
|
+
Permission.ProjectOwner,
|
|
195
|
+
Permission.ProjectAdmin,
|
|
196
|
+
Permission.ReadProjectTeam,
|
|
197
|
+
Permission.ProjectMember,
|
|
198
|
+
],
|
|
199
|
+
update: [],
|
|
200
|
+
})
|
|
201
|
+
@TableColumn({
|
|
202
|
+
manyToOneRelationColumn: "userId",
|
|
203
|
+
type: TableColumnType.Entity,
|
|
204
|
+
modelType: User,
|
|
205
|
+
title: "User",
|
|
206
|
+
description: "User who belongs to this team.",
|
|
207
|
+
})
|
|
208
|
+
@ManyToOne(
|
|
209
|
+
() => {
|
|
210
|
+
return User;
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
eager: false,
|
|
214
|
+
nullable: false,
|
|
215
|
+
onDelete: "CASCADE",
|
|
216
|
+
orphanedRowAction: "nullify",
|
|
217
|
+
},
|
|
218
|
+
)
|
|
219
|
+
@JoinColumn({ name: "userId" })
|
|
220
|
+
public user?: User = undefined;
|
|
221
|
+
|
|
222
|
+
@ColumnAccessControl({
|
|
223
|
+
create: [],
|
|
224
|
+
read: [
|
|
225
|
+
Permission.ProjectOwner,
|
|
226
|
+
Permission.ProjectAdmin,
|
|
227
|
+
Permission.ProjectMember,
|
|
228
|
+
Permission.ReadProjectTeam,
|
|
229
|
+
Permission.CurrentUser,
|
|
230
|
+
],
|
|
231
|
+
update: [],
|
|
232
|
+
})
|
|
233
|
+
@TableColumn({
|
|
234
|
+
type: TableColumnType.ObjectID,
|
|
235
|
+
required: true,
|
|
236
|
+
title: "User ID",
|
|
237
|
+
description: "ID of User who belongs to this team",
|
|
238
|
+
})
|
|
239
|
+
@Column({
|
|
240
|
+
type: ColumnType.ObjectID,
|
|
241
|
+
nullable: false,
|
|
242
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
243
|
+
})
|
|
244
|
+
public userId?: ObjectID = undefined;
|
|
245
|
+
|
|
246
|
+
@ColumnAccessControl({
|
|
247
|
+
create: [],
|
|
248
|
+
read: [],
|
|
249
|
+
update: [],
|
|
250
|
+
})
|
|
251
|
+
@TableColumn({
|
|
252
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
253
|
+
type: TableColumnType.Entity,
|
|
254
|
+
modelType: User,
|
|
255
|
+
title: "Created by User",
|
|
256
|
+
description:
|
|
257
|
+
"Relation to User who created this object (if this object was created by a User)",
|
|
258
|
+
})
|
|
259
|
+
@ManyToOne(
|
|
260
|
+
() => {
|
|
261
|
+
return User;
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
eager: false,
|
|
265
|
+
nullable: true,
|
|
266
|
+
onDelete: "SET NULL",
|
|
267
|
+
orphanedRowAction: "nullify",
|
|
268
|
+
},
|
|
269
|
+
)
|
|
270
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
271
|
+
public createdByUser?: User = undefined;
|
|
272
|
+
|
|
273
|
+
@ColumnAccessControl({
|
|
274
|
+
create: [],
|
|
275
|
+
read: [],
|
|
276
|
+
update: [],
|
|
277
|
+
})
|
|
278
|
+
@TableColumn({
|
|
279
|
+
type: TableColumnType.ObjectID,
|
|
280
|
+
title: "Created by User ID",
|
|
281
|
+
description:
|
|
282
|
+
"User ID who created this object (if this object was created by a User)",
|
|
283
|
+
})
|
|
284
|
+
@Column({
|
|
285
|
+
type: ColumnType.ObjectID,
|
|
286
|
+
nullable: true,
|
|
287
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
288
|
+
})
|
|
289
|
+
public createdByUserId?: ObjectID = undefined;
|
|
290
|
+
|
|
291
|
+
@ColumnAccessControl({
|
|
292
|
+
create: [],
|
|
293
|
+
read: [],
|
|
294
|
+
update: [],
|
|
295
|
+
})
|
|
296
|
+
@TableColumn({
|
|
297
|
+
manyToOneRelationColumn: "deletedByUserId",
|
|
298
|
+
type: TableColumnType.Entity,
|
|
299
|
+
title: "Deleted by User",
|
|
300
|
+
description:
|
|
301
|
+
"Relation to User who deleted this object (if this object was deleted by a User)",
|
|
302
|
+
})
|
|
303
|
+
@ManyToOne(
|
|
304
|
+
() => {
|
|
305
|
+
return User;
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
cascade: false,
|
|
309
|
+
eager: false,
|
|
310
|
+
nullable: true,
|
|
311
|
+
onDelete: "SET NULL",
|
|
312
|
+
orphanedRowAction: "nullify",
|
|
313
|
+
},
|
|
314
|
+
)
|
|
315
|
+
@JoinColumn({ name: "deletedByUserId" })
|
|
316
|
+
public deletedByUser?: User = undefined;
|
|
317
|
+
|
|
318
|
+
@ColumnAccessControl({
|
|
319
|
+
create: [],
|
|
320
|
+
read: [],
|
|
321
|
+
update: [],
|
|
322
|
+
})
|
|
323
|
+
@TableColumn({
|
|
324
|
+
type: TableColumnType.ObjectID,
|
|
325
|
+
title: "Deleted by User ID",
|
|
326
|
+
description:
|
|
327
|
+
"User ID who deleted this object (if this object was deleted by a User)",
|
|
328
|
+
})
|
|
329
|
+
@Column({
|
|
330
|
+
type: ColumnType.ObjectID,
|
|
331
|
+
nullable: true,
|
|
332
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
333
|
+
})
|
|
334
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
335
|
+
}
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
ManyToOne,
|
|
36
36
|
} from "typeorm";
|
|
37
37
|
import Recurring from "../../Types/Events/Recurring";
|
|
38
|
-
import
|
|
38
|
+
import NotificationRuleWorkspaceChannel from "../../Types/Workspace/NotificationRules/NotificationRuleWorkspaceChannel";
|
|
39
39
|
|
|
40
40
|
@EnableDocumentation()
|
|
41
41
|
@AccessControlColumn("labels")
|
|
@@ -997,7 +997,8 @@ export default class ScheduledMaintenance extends BaseModel {
|
|
|
997
997
|
type: ColumnType.JSON,
|
|
998
998
|
nullable: true,
|
|
999
999
|
})
|
|
1000
|
-
public postUpdatesToWorkspaceChannels?: Array<
|
|
1000
|
+
public postUpdatesToWorkspaceChannels?: Array<NotificationRuleWorkspaceChannel> =
|
|
1001
|
+
undefined;
|
|
1001
1002
|
|
|
1002
1003
|
@ColumnAccessControl({
|
|
1003
1004
|
create: [
|
package/Server/API/SlackAPI.ts
CHANGED
|
@@ -12,6 +12,8 @@ import BadDataException from "../../Types/Exception/BadDataException";
|
|
|
12
12
|
import {
|
|
13
13
|
AppApiClientUrl,
|
|
14
14
|
DashboardClientUrl,
|
|
15
|
+
Host,
|
|
16
|
+
HttpProtocol,
|
|
15
17
|
SlackAppClientId,
|
|
16
18
|
SlackAppClientSecret,
|
|
17
19
|
} from "../EnvironmentConfig";
|
|
@@ -24,6 +26,10 @@ import WorkspaceProjectAuthTokenService from "../Services/WorkspaceProjectAuthTo
|
|
|
24
26
|
import ObjectID from "../../Types/ObjectID";
|
|
25
27
|
import WorkspaceUserAuthTokenService from "../Services/WorkspaceUserAuthTokenService";
|
|
26
28
|
import WorkspaceType from "../../Types/Workspace/WorkspaceType";
|
|
29
|
+
import SlackAuthAction, {
|
|
30
|
+
SlackRequest,
|
|
31
|
+
} from "../Utils/Workspace/Slack/Actions/Auth";
|
|
32
|
+
import SlackIncidentActions from "../Utils/Workspace/Slack/Actions/Incident";
|
|
27
33
|
|
|
28
34
|
export default class SlackAPI {
|
|
29
35
|
public getRouter(): ExpressRouter {
|
|
@@ -33,7 +39,23 @@ export default class SlackAPI {
|
|
|
33
39
|
"/slack/app-manifest",
|
|
34
40
|
(req: ExpressRequest, res: ExpressResponse) => {
|
|
35
41
|
// return app manifest for slack app
|
|
36
|
-
|
|
42
|
+
|
|
43
|
+
let ServerURL: string = new URL(HttpProtocol, Host).toString();
|
|
44
|
+
|
|
45
|
+
//remove trailing slash if present.
|
|
46
|
+
if (ServerURL.endsWith("/")) {
|
|
47
|
+
ServerURL = ServerURL.slice(0, -1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// replace SERVER_URL in the manifest with the actual server url.
|
|
51
|
+
const manifestInString: string = JSON.stringify(
|
|
52
|
+
SlackAppManifest,
|
|
53
|
+
).replace(/{{SERVER_URL}}/g, ServerURL.toString());
|
|
54
|
+
|
|
55
|
+
// convert it back to json.
|
|
56
|
+
const manifest: JSONObject = JSON.parse(manifestInString);
|
|
57
|
+
|
|
58
|
+
return Response.sendJsonObjectResponse(req, res, manifest);
|
|
37
59
|
},
|
|
38
60
|
);
|
|
39
61
|
|
|
@@ -251,108 +273,42 @@ export default class SlackAPI {
|
|
|
251
273
|
router.post(
|
|
252
274
|
"/slack/interactive",
|
|
253
275
|
SlackAuthorization.isAuthorizedSlackRequest,
|
|
254
|
-
(req: ExpressRequest, res: ExpressResponse) => {
|
|
255
|
-
|
|
256
|
-
response_action: "clear",
|
|
257
|
-
});
|
|
258
|
-
},
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
// options load endpoint.
|
|
262
|
-
|
|
263
|
-
router.post(
|
|
264
|
-
"/slack/options-load",
|
|
265
|
-
SlackAuthorization.isAuthorizedSlackRequest,
|
|
266
|
-
(req: ExpressRequest, res: ExpressResponse) => {
|
|
267
|
-
return Response.sendJsonObjectResponse(req, res, {
|
|
268
|
-
response_action: "clear",
|
|
269
|
-
});
|
|
270
|
-
},
|
|
271
|
-
);
|
|
276
|
+
async (req: ExpressRequest, res: ExpressResponse) => {
|
|
277
|
+
logger.debug("Slack Interactive Request: ");
|
|
272
278
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
SlackAuthorization.isAuthorizedSlackRequest,
|
|
276
|
-
(req: ExpressRequest, res: ExpressResponse) => {
|
|
277
|
-
return Response.sendJsonObjectResponse(req, res, {
|
|
278
|
-
response_action: "clear",
|
|
279
|
+
const authResult: SlackRequest = await SlackAuthAction.isAuthorized({
|
|
280
|
+
req: req,
|
|
279
281
|
});
|
|
280
|
-
},
|
|
281
|
-
);
|
|
282
282
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
SlackAuthorization.isAuthorizedSlackRequest,
|
|
286
|
-
(req: ExpressRequest, res: ExpressResponse) => {
|
|
287
|
-
// respond to slack challenge
|
|
283
|
+
logger.debug("Slack Interactive Auth Result: ");
|
|
284
|
+
logger.debug(authResult);
|
|
288
285
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
return Response.sendJsonObjectResponse(req, res, {
|
|
293
|
-
challenge: body.challenge,
|
|
294
|
-
});
|
|
286
|
+
if (authResult.isAuthorized === false) {
|
|
287
|
+
// return empty response if not authorized. Do nothing in this case.
|
|
288
|
+
return Response.sendTextResponse(req, res, "");
|
|
295
289
|
}
|
|
296
290
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
label: {
|
|
319
|
-
type: "plain_text",
|
|
320
|
-
text: "Title",
|
|
321
|
-
},
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
type: "input",
|
|
325
|
-
block_id: "description",
|
|
326
|
-
element: {
|
|
327
|
-
type: "plain_text_input",
|
|
328
|
-
action_id: "description",
|
|
329
|
-
placeholder: {
|
|
330
|
-
type: "plain_text",
|
|
331
|
-
text: "Incident Description",
|
|
332
|
-
},
|
|
333
|
-
},
|
|
334
|
-
label: {
|
|
335
|
-
type: "plain_text",
|
|
336
|
-
text: "Description",
|
|
337
|
-
},
|
|
338
|
-
},
|
|
339
|
-
// button
|
|
340
|
-
{
|
|
341
|
-
type: "actions",
|
|
342
|
-
elements: [
|
|
343
|
-
{
|
|
344
|
-
type: "button",
|
|
345
|
-
text: {
|
|
346
|
-
type: "plain_text",
|
|
347
|
-
text: "Submit",
|
|
348
|
-
},
|
|
349
|
-
style: "primary",
|
|
350
|
-
value: "submit",
|
|
351
|
-
},
|
|
352
|
-
],
|
|
353
|
-
},
|
|
354
|
-
],
|
|
355
|
-
});
|
|
291
|
+
for (const action of authResult.actions || []) {
|
|
292
|
+
if (!action.actionType) {
|
|
293
|
+
return Response.sendErrorResponse(
|
|
294
|
+
req,
|
|
295
|
+
res,
|
|
296
|
+
new BadRequestException("Invalid request"),
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
if (
|
|
301
|
+
SlackIncidentActions.isIncidentAction({
|
|
302
|
+
actionType: action.actionType,
|
|
303
|
+
})
|
|
304
|
+
) {
|
|
305
|
+
return SlackIncidentActions.handleIncidentAction({
|
|
306
|
+
slackRequest: authResult,
|
|
307
|
+
action: action,
|
|
308
|
+
req: req,
|
|
309
|
+
res: res,
|
|
310
|
+
});
|
|
311
|
+
}
|
|
356
312
|
}
|
|
357
313
|
|
|
358
314
|
return Response.sendErrorResponse(
|
|
@@ -363,6 +319,18 @@ export default class SlackAPI {
|
|
|
363
319
|
},
|
|
364
320
|
);
|
|
365
321
|
|
|
322
|
+
// options load endpoint.
|
|
323
|
+
|
|
324
|
+
router.post(
|
|
325
|
+
"/slack/options-load",
|
|
326
|
+
SlackAuthorization.isAuthorizedSlackRequest,
|
|
327
|
+
(req: ExpressRequest, res: ExpressResponse) => {
|
|
328
|
+
return Response.sendJsonObjectResponse(req, res, {
|
|
329
|
+
response_action: "clear",
|
|
330
|
+
});
|
|
331
|
+
},
|
|
332
|
+
);
|
|
333
|
+
|
|
366
334
|
return router;
|
|
367
335
|
}
|
|
368
336
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1740597525803 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1740597525803";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "Incident" ADD "workspaceThreadIds" jsonb`,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "Incident" DROP COLUMN "workspaceThreadIds"`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1740598793630 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1740598793630";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "Incident" RENAME COLUMN "workspaceThreadIds" TO "workspaceSendMessageResponse"`,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "Incident" RENAME COLUMN "workspaceSendMessageResponse" TO "workspaceThreadIds"`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1741031019972 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1741031019972";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "Incident" DROP COLUMN "workspaceSendMessageResponse"`,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "Incident" ADD "workspaceSendMessageResponse" jsonb`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|