@oneuptime/common 8.0.5203 → 8.0.5209
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/Index.ts +2 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +403 -0
- package/Server/API/TeamComplianceAPI.ts +106 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1758626094132-MigrationName.ts +63 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1758629540993-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/TeamComplianceService.ts +556 -0
- package/Server/Services/TeamComplianceSettingService.ts +41 -0
- package/Types/Team/ComplianceRuleType.ts +10 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +424 -0
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -0
- package/build/dist/Server/API/TeamComplianceAPI.js +52 -0
- package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1758626094132-MigrationName.js +28 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1758626094132-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1758629540993-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1758629540993-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceService.js +385 -0
- package/build/dist/Server/Services/TeamComplianceService.js.map +1 -0
- package/build/dist/Server/Services/TeamComplianceSettingService.js +45 -0
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +11 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -0
- package/package.json +1 -1
|
@@ -123,6 +123,7 @@ import StatusPageSubscriber from "./StatusPageSubscriber";
|
|
|
123
123
|
import Team from "./Team";
|
|
124
124
|
import TeamMember from "./TeamMember";
|
|
125
125
|
import TeamPermission from "./TeamPermission";
|
|
126
|
+
import TeamComplianceSetting from "./TeamComplianceSetting";
|
|
126
127
|
import TelemetryService from "./TelemetryService";
|
|
127
128
|
import UsageBilling from "./TelemetryUsageBilling";
|
|
128
129
|
import User from "./User";
|
|
@@ -196,6 +197,7 @@ const AllModelTypes: Array<{
|
|
|
196
197
|
Team,
|
|
197
198
|
TeamMember,
|
|
198
199
|
TeamPermission,
|
|
200
|
+
TeamComplianceSetting,
|
|
199
201
|
ApiKey,
|
|
200
202
|
Label,
|
|
201
203
|
ApiKeyPermission,
|
|
@@ -0,0 +1,403 @@
|
|
|
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 { PlanType } from "../../Types/Billing/SubscriptionPlan";
|
|
7
|
+
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
8
|
+
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
9
|
+
import TableBillingAccessControl from "../../Types/Database/AccessControl/TableBillingAccessControl";
|
|
10
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
11
|
+
import ColumnType from "../../Types/Database/ColumnType";
|
|
12
|
+
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
13
|
+
import EnableDocumentation from "../../Types/Database/EnableDocumentation";
|
|
14
|
+
import EnableWorkflow from "../../Types/Database/EnableWorkflow";
|
|
15
|
+
import TableColumn from "../../Types/Database/TableColumn";
|
|
16
|
+
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
17
|
+
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
18
|
+
import TenantColumn from "../../Types/Database/TenantColumn";
|
|
19
|
+
import IconProp from "../../Types/Icon/IconProp";
|
|
20
|
+
import { JSONObject } from "../../Types/JSON";
|
|
21
|
+
import ObjectID from "../../Types/ObjectID";
|
|
22
|
+
import Permission from "../../Types/Permission";
|
|
23
|
+
import ComplianceRuleType from "../../Types/Team/ComplianceRuleType";
|
|
24
|
+
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
25
|
+
|
|
26
|
+
@TableBillingAccessControl({
|
|
27
|
+
create: PlanType.Scale,
|
|
28
|
+
read: PlanType.Free,
|
|
29
|
+
update: PlanType.Scale,
|
|
30
|
+
delete: PlanType.Free,
|
|
31
|
+
})
|
|
32
|
+
@EnableDocumentation()
|
|
33
|
+
@TableAccessControl({
|
|
34
|
+
create: [
|
|
35
|
+
Permission.ProjectOwner,
|
|
36
|
+
Permission.ProjectAdmin,
|
|
37
|
+
Permission.EditProjectTeam,
|
|
38
|
+
],
|
|
39
|
+
read: [
|
|
40
|
+
Permission.ProjectOwner,
|
|
41
|
+
Permission.ProjectAdmin,
|
|
42
|
+
Permission.ProjectMember,
|
|
43
|
+
Permission.ReadProjectTeam,
|
|
44
|
+
],
|
|
45
|
+
delete: [
|
|
46
|
+
Permission.ProjectOwner,
|
|
47
|
+
Permission.ProjectAdmin,
|
|
48
|
+
Permission.EditProjectTeam,
|
|
49
|
+
],
|
|
50
|
+
update: [
|
|
51
|
+
Permission.ProjectOwner,
|
|
52
|
+
Permission.ProjectAdmin,
|
|
53
|
+
Permission.EditProjectTeam,
|
|
54
|
+
],
|
|
55
|
+
})
|
|
56
|
+
@TenantColumn("projectId")
|
|
57
|
+
@CrudApiEndpoint(new Route("/team-compliance-setting"))
|
|
58
|
+
@Index(["teamId", "ruleType"], { unique: true })
|
|
59
|
+
@Entity({
|
|
60
|
+
name: "TeamComplianceSetting",
|
|
61
|
+
})
|
|
62
|
+
@EnableWorkflow({
|
|
63
|
+
create: false,
|
|
64
|
+
delete: false,
|
|
65
|
+
update: false,
|
|
66
|
+
read: false,
|
|
67
|
+
})
|
|
68
|
+
@TableMetadata({
|
|
69
|
+
tableName: "TeamComplianceSetting",
|
|
70
|
+
singularName: "Team Compliance Setting",
|
|
71
|
+
pluralName: "Team Compliance Settings",
|
|
72
|
+
icon: IconProp.CheckCircle,
|
|
73
|
+
tableDescription: "Compliance settings for your OneUptime team",
|
|
74
|
+
})
|
|
75
|
+
export default class TeamComplianceSetting extends BaseModel {
|
|
76
|
+
@ColumnAccessControl({
|
|
77
|
+
create: [
|
|
78
|
+
Permission.ProjectOwner,
|
|
79
|
+
Permission.ProjectAdmin,
|
|
80
|
+
Permission.EditProjectTeam,
|
|
81
|
+
],
|
|
82
|
+
read: [
|
|
83
|
+
Permission.ProjectOwner,
|
|
84
|
+
Permission.ProjectAdmin,
|
|
85
|
+
Permission.ProjectMember,
|
|
86
|
+
Permission.ReadProjectTeam,
|
|
87
|
+
],
|
|
88
|
+
update: [],
|
|
89
|
+
})
|
|
90
|
+
@TableColumn({
|
|
91
|
+
manyToOneRelationColumn: "projectId",
|
|
92
|
+
type: TableColumnType.Entity,
|
|
93
|
+
modelType: Project,
|
|
94
|
+
title: "Project",
|
|
95
|
+
description: "Relation to Project Resource in which this object belongs",
|
|
96
|
+
})
|
|
97
|
+
@ManyToOne(
|
|
98
|
+
() => {
|
|
99
|
+
return Project;
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
eager: false,
|
|
103
|
+
nullable: true,
|
|
104
|
+
onDelete: "CASCADE",
|
|
105
|
+
orphanedRowAction: "nullify",
|
|
106
|
+
},
|
|
107
|
+
)
|
|
108
|
+
@JoinColumn({ name: "projectId" })
|
|
109
|
+
public project?: Project = undefined;
|
|
110
|
+
|
|
111
|
+
@ColumnAccessControl({
|
|
112
|
+
create: [
|
|
113
|
+
Permission.ProjectOwner,
|
|
114
|
+
Permission.ProjectAdmin,
|
|
115
|
+
Permission.EditProjectTeam,
|
|
116
|
+
],
|
|
117
|
+
read: [
|
|
118
|
+
Permission.ProjectOwner,
|
|
119
|
+
Permission.ProjectAdmin,
|
|
120
|
+
Permission.ProjectMember,
|
|
121
|
+
Permission.ReadProjectTeam,
|
|
122
|
+
],
|
|
123
|
+
update: [],
|
|
124
|
+
})
|
|
125
|
+
@Index()
|
|
126
|
+
@TableColumn({
|
|
127
|
+
type: TableColumnType.ObjectID,
|
|
128
|
+
required: true,
|
|
129
|
+
canReadOnRelationQuery: true,
|
|
130
|
+
title: "Project ID",
|
|
131
|
+
description: "ID of your OneUptime Project in which this object belongs",
|
|
132
|
+
})
|
|
133
|
+
@Column({
|
|
134
|
+
type: ColumnType.ObjectID,
|
|
135
|
+
nullable: false,
|
|
136
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
137
|
+
})
|
|
138
|
+
public projectId?: ObjectID = undefined;
|
|
139
|
+
|
|
140
|
+
@ColumnAccessControl({
|
|
141
|
+
create: [
|
|
142
|
+
Permission.ProjectOwner,
|
|
143
|
+
Permission.ProjectAdmin,
|
|
144
|
+
Permission.EditProjectTeam,
|
|
145
|
+
],
|
|
146
|
+
read: [
|
|
147
|
+
Permission.ProjectOwner,
|
|
148
|
+
Permission.ProjectAdmin,
|
|
149
|
+
Permission.ProjectMember,
|
|
150
|
+
Permission.ReadProjectTeam,
|
|
151
|
+
],
|
|
152
|
+
update: [],
|
|
153
|
+
})
|
|
154
|
+
@TableColumn({
|
|
155
|
+
manyToOneRelationColumn: "teamId",
|
|
156
|
+
type: TableColumnType.Entity,
|
|
157
|
+
modelType: Team,
|
|
158
|
+
title: "Team",
|
|
159
|
+
description: "Team this compliance setting belongs to.",
|
|
160
|
+
})
|
|
161
|
+
@ManyToOne(
|
|
162
|
+
() => {
|
|
163
|
+
return Team;
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
eager: false,
|
|
167
|
+
nullable: true,
|
|
168
|
+
onDelete: "CASCADE",
|
|
169
|
+
orphanedRowAction: "nullify",
|
|
170
|
+
},
|
|
171
|
+
)
|
|
172
|
+
@JoinColumn({ name: "teamId" })
|
|
173
|
+
public team?: Team = undefined;
|
|
174
|
+
|
|
175
|
+
@ColumnAccessControl({
|
|
176
|
+
create: [
|
|
177
|
+
Permission.ProjectOwner,
|
|
178
|
+
Permission.ProjectAdmin,
|
|
179
|
+
Permission.EditProjectTeam,
|
|
180
|
+
],
|
|
181
|
+
read: [
|
|
182
|
+
Permission.ProjectOwner,
|
|
183
|
+
Permission.ProjectAdmin,
|
|
184
|
+
Permission.ProjectMember,
|
|
185
|
+
Permission.ReadProjectTeam,
|
|
186
|
+
],
|
|
187
|
+
update: [],
|
|
188
|
+
})
|
|
189
|
+
@Index()
|
|
190
|
+
@TableColumn({
|
|
191
|
+
type: TableColumnType.ObjectID,
|
|
192
|
+
required: true,
|
|
193
|
+
title: "Team ID",
|
|
194
|
+
description: "ID of Team this compliance setting belongs to.",
|
|
195
|
+
})
|
|
196
|
+
@Column({
|
|
197
|
+
type: ColumnType.ObjectID,
|
|
198
|
+
nullable: false,
|
|
199
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
200
|
+
})
|
|
201
|
+
public teamId?: ObjectID = undefined;
|
|
202
|
+
|
|
203
|
+
@ColumnAccessControl({
|
|
204
|
+
create: [
|
|
205
|
+
Permission.ProjectOwner,
|
|
206
|
+
Permission.ProjectAdmin,
|
|
207
|
+
Permission.EditProjectTeam,
|
|
208
|
+
],
|
|
209
|
+
read: [
|
|
210
|
+
Permission.ProjectOwner,
|
|
211
|
+
Permission.ProjectAdmin,
|
|
212
|
+
Permission.ProjectMember,
|
|
213
|
+
Permission.ReadProjectTeam,
|
|
214
|
+
],
|
|
215
|
+
update: [],
|
|
216
|
+
})
|
|
217
|
+
@TableColumn({
|
|
218
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
219
|
+
type: TableColumnType.Entity,
|
|
220
|
+
modelType: User,
|
|
221
|
+
title: "Created by User",
|
|
222
|
+
description:
|
|
223
|
+
"Relation to User who created this object (if this object was created by a User)",
|
|
224
|
+
})
|
|
225
|
+
@ManyToOne(
|
|
226
|
+
() => {
|
|
227
|
+
return User;
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
eager: false,
|
|
231
|
+
nullable: true,
|
|
232
|
+
onDelete: "SET NULL",
|
|
233
|
+
orphanedRowAction: "nullify",
|
|
234
|
+
},
|
|
235
|
+
)
|
|
236
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
237
|
+
public createdByUser?: User = undefined;
|
|
238
|
+
|
|
239
|
+
@ColumnAccessControl({
|
|
240
|
+
create: [
|
|
241
|
+
Permission.ProjectOwner,
|
|
242
|
+
Permission.ProjectAdmin,
|
|
243
|
+
Permission.EditProjectTeam,
|
|
244
|
+
],
|
|
245
|
+
read: [
|
|
246
|
+
Permission.ProjectOwner,
|
|
247
|
+
Permission.ProjectAdmin,
|
|
248
|
+
Permission.ProjectMember,
|
|
249
|
+
Permission.ReadProjectTeam,
|
|
250
|
+
],
|
|
251
|
+
update: [],
|
|
252
|
+
})
|
|
253
|
+
@TableColumn({
|
|
254
|
+
type: TableColumnType.ObjectID,
|
|
255
|
+
title: "Created by User ID",
|
|
256
|
+
description:
|
|
257
|
+
"User ID who created this object (if this object was created by a User)",
|
|
258
|
+
})
|
|
259
|
+
@Column({
|
|
260
|
+
type: ColumnType.ObjectID,
|
|
261
|
+
nullable: true,
|
|
262
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
263
|
+
})
|
|
264
|
+
public createdByUserId?: ObjectID = undefined;
|
|
265
|
+
|
|
266
|
+
@ColumnAccessControl({
|
|
267
|
+
create: [],
|
|
268
|
+
read: [],
|
|
269
|
+
update: [],
|
|
270
|
+
})
|
|
271
|
+
@TableColumn({
|
|
272
|
+
manyToOneRelationColumn: "deletedByUserId",
|
|
273
|
+
type: TableColumnType.Entity,
|
|
274
|
+
title: "Deleted by User",
|
|
275
|
+
modelType: User,
|
|
276
|
+
description:
|
|
277
|
+
"Relation to User who deleted this object (if this object was deleted by a User)",
|
|
278
|
+
})
|
|
279
|
+
@ManyToOne(
|
|
280
|
+
() => {
|
|
281
|
+
return User;
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
cascade: false,
|
|
285
|
+
eager: false,
|
|
286
|
+
nullable: true,
|
|
287
|
+
onDelete: "SET NULL",
|
|
288
|
+
orphanedRowAction: "nullify",
|
|
289
|
+
},
|
|
290
|
+
)
|
|
291
|
+
@JoinColumn({ name: "deletedByUserId" })
|
|
292
|
+
public deletedByUser?: User = undefined;
|
|
293
|
+
|
|
294
|
+
@ColumnAccessControl({
|
|
295
|
+
create: [],
|
|
296
|
+
read: [],
|
|
297
|
+
update: [],
|
|
298
|
+
})
|
|
299
|
+
@TableColumn({
|
|
300
|
+
type: TableColumnType.ObjectID,
|
|
301
|
+
title: "Deleted by User ID",
|
|
302
|
+
description:
|
|
303
|
+
"User ID who deleted this object (if this object was deleted by a User)",
|
|
304
|
+
})
|
|
305
|
+
@Column({
|
|
306
|
+
type: ColumnType.ObjectID,
|
|
307
|
+
nullable: true,
|
|
308
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
309
|
+
})
|
|
310
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
311
|
+
|
|
312
|
+
@ColumnAccessControl({
|
|
313
|
+
create: [
|
|
314
|
+
Permission.ProjectOwner,
|
|
315
|
+
Permission.ProjectAdmin,
|
|
316
|
+
Permission.EditProjectTeam,
|
|
317
|
+
],
|
|
318
|
+
read: [
|
|
319
|
+
Permission.ProjectOwner,
|
|
320
|
+
Permission.ProjectAdmin,
|
|
321
|
+
Permission.ProjectMember,
|
|
322
|
+
Permission.ReadProjectTeam,
|
|
323
|
+
],
|
|
324
|
+
update: [
|
|
325
|
+
Permission.ProjectOwner,
|
|
326
|
+
Permission.ProjectAdmin,
|
|
327
|
+
Permission.EditProjectTeam,
|
|
328
|
+
],
|
|
329
|
+
})
|
|
330
|
+
@TableColumn({
|
|
331
|
+
required: true,
|
|
332
|
+
type: TableColumnType.LongText,
|
|
333
|
+
title: "Rule Type",
|
|
334
|
+
description: "Type of compliance rule.",
|
|
335
|
+
})
|
|
336
|
+
@Column({
|
|
337
|
+
nullable: false,
|
|
338
|
+
type: ColumnType.LongText,
|
|
339
|
+
length: ColumnLength.LongText,
|
|
340
|
+
})
|
|
341
|
+
public ruleType?: ComplianceRuleType = undefined;
|
|
342
|
+
|
|
343
|
+
@ColumnAccessControl({
|
|
344
|
+
create: [
|
|
345
|
+
Permission.ProjectOwner,
|
|
346
|
+
Permission.ProjectAdmin,
|
|
347
|
+
Permission.EditProjectTeam,
|
|
348
|
+
],
|
|
349
|
+
read: [
|
|
350
|
+
Permission.ProjectOwner,
|
|
351
|
+
Permission.ProjectAdmin,
|
|
352
|
+
Permission.ProjectMember,
|
|
353
|
+
Permission.ReadProjectTeam,
|
|
354
|
+
],
|
|
355
|
+
update: [
|
|
356
|
+
Permission.ProjectOwner,
|
|
357
|
+
Permission.ProjectAdmin,
|
|
358
|
+
Permission.EditProjectTeam,
|
|
359
|
+
],
|
|
360
|
+
})
|
|
361
|
+
@TableColumn({
|
|
362
|
+
isDefaultValueColumn: true,
|
|
363
|
+
type: TableColumnType.Boolean,
|
|
364
|
+
title: "Enabled",
|
|
365
|
+
description: "Whether this compliance rule is enabled.",
|
|
366
|
+
defaultValue: false,
|
|
367
|
+
})
|
|
368
|
+
@Column({
|
|
369
|
+
type: ColumnType.Boolean,
|
|
370
|
+
default: false,
|
|
371
|
+
})
|
|
372
|
+
public enabled?: boolean = undefined;
|
|
373
|
+
|
|
374
|
+
@ColumnAccessControl({
|
|
375
|
+
create: [
|
|
376
|
+
Permission.ProjectOwner,
|
|
377
|
+
Permission.ProjectAdmin,
|
|
378
|
+
Permission.EditProjectTeam,
|
|
379
|
+
],
|
|
380
|
+
read: [
|
|
381
|
+
Permission.ProjectOwner,
|
|
382
|
+
Permission.ProjectAdmin,
|
|
383
|
+
Permission.ProjectMember,
|
|
384
|
+
Permission.ReadProjectTeam,
|
|
385
|
+
],
|
|
386
|
+
update: [
|
|
387
|
+
Permission.ProjectOwner,
|
|
388
|
+
Permission.ProjectAdmin,
|
|
389
|
+
Permission.EditProjectTeam,
|
|
390
|
+
],
|
|
391
|
+
})
|
|
392
|
+
@TableColumn({
|
|
393
|
+
required: false,
|
|
394
|
+
type: TableColumnType.JSON,
|
|
395
|
+
title: "Options",
|
|
396
|
+
description: "Additional options for this compliance rule.",
|
|
397
|
+
})
|
|
398
|
+
@Column({
|
|
399
|
+
type: ColumnType.JSON,
|
|
400
|
+
nullable: true,
|
|
401
|
+
})
|
|
402
|
+
public options?: JSONObject = undefined;
|
|
403
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import UserMiddleware from "../Middleware/UserAuthorization";
|
|
2
|
+
import TeamComplianceService, {
|
|
3
|
+
TeamComplianceStatus,
|
|
4
|
+
UserComplianceStatus,
|
|
5
|
+
} from "../Services/TeamComplianceService";
|
|
6
|
+
import {
|
|
7
|
+
ExpressRequest,
|
|
8
|
+
ExpressResponse,
|
|
9
|
+
NextFunction,
|
|
10
|
+
} from "../Utils/Express";
|
|
11
|
+
import Response from "../Utils/Response";
|
|
12
|
+
import BaseAPI from "./BaseAPI";
|
|
13
|
+
import CommonAPI from "./CommonAPI";
|
|
14
|
+
import DatabaseCommonInteractionProps from "../../Types/BaseDatabase/DatabaseCommonInteractionProps";
|
|
15
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
16
|
+
import ObjectID from "../../Types/ObjectID";
|
|
17
|
+
import Team from "../../Models/DatabaseModels/Team";
|
|
18
|
+
import TeamService, {
|
|
19
|
+
Service as TeamServiceType,
|
|
20
|
+
} from "../Services/TeamService";
|
|
21
|
+
import ComplianceRuleType from "../../Types/Team/ComplianceRuleType";
|
|
22
|
+
|
|
23
|
+
export default class TeamComplianceAPI extends BaseAPI<Team, TeamServiceType> {
|
|
24
|
+
public constructor() {
|
|
25
|
+
super(Team, TeamService);
|
|
26
|
+
|
|
27
|
+
// Get team compliance status
|
|
28
|
+
this.router.get(
|
|
29
|
+
`${new this.entityType().getCrudApiPath()?.toString()}/compliance-status/:teamId`,
|
|
30
|
+
UserMiddleware.getUserMiddleware,
|
|
31
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
32
|
+
try {
|
|
33
|
+
const databaseProps: DatabaseCommonInteractionProps =
|
|
34
|
+
await CommonAPI.getDatabaseCommonInteractionProps(req);
|
|
35
|
+
|
|
36
|
+
const projectId: ObjectID = databaseProps.tenantId as ObjectID;
|
|
37
|
+
|
|
38
|
+
const teamId: ObjectID = new ObjectID(req.params["teamId"] as string);
|
|
39
|
+
|
|
40
|
+
if (!projectId) {
|
|
41
|
+
return Response.sendErrorResponse(
|
|
42
|
+
req,
|
|
43
|
+
res,
|
|
44
|
+
new BadDataException("Invalid projectId."),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!teamId) {
|
|
49
|
+
return Response.sendErrorResponse(
|
|
50
|
+
req,
|
|
51
|
+
res,
|
|
52
|
+
new BadDataException("Invalid teamId."),
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const complianceStatus: TeamComplianceStatus =
|
|
57
|
+
await TeamComplianceService.getTeamComplianceStatus(
|
|
58
|
+
teamId,
|
|
59
|
+
projectId,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
// Convert ObjectIDs to strings for JSON response
|
|
63
|
+
const responseData: {
|
|
64
|
+
teamId: string;
|
|
65
|
+
teamName: string;
|
|
66
|
+
complianceSettings: Array<{
|
|
67
|
+
ruleType: ComplianceRuleType;
|
|
68
|
+
enabled: boolean;
|
|
69
|
+
}>;
|
|
70
|
+
userComplianceStatuses: Array<{
|
|
71
|
+
userId: string;
|
|
72
|
+
userName: string;
|
|
73
|
+
userEmail: string;
|
|
74
|
+
userProfilePictureId: string | undefined;
|
|
75
|
+
isCompliant: boolean;
|
|
76
|
+
nonCompliantRules: Array<{
|
|
77
|
+
ruleType: ComplianceRuleType;
|
|
78
|
+
reason: string;
|
|
79
|
+
}>;
|
|
80
|
+
}>;
|
|
81
|
+
} = {
|
|
82
|
+
teamId: complianceStatus.teamId.toString(),
|
|
83
|
+
teamName: complianceStatus.teamName,
|
|
84
|
+
complianceSettings: complianceStatus.complianceSettings,
|
|
85
|
+
userComplianceStatuses: complianceStatus.userComplianceStatuses.map(
|
|
86
|
+
(user: UserComplianceStatus) => {
|
|
87
|
+
return {
|
|
88
|
+
userId: user.userId.toString(),
|
|
89
|
+
userName: user.userName,
|
|
90
|
+
userEmail: user.userEmail,
|
|
91
|
+
userProfilePictureId: user.userProfilePictureId?.toString(),
|
|
92
|
+
isCompliant: user.isCompliant,
|
|
93
|
+
nonCompliantRules: user.nonCompliantRules,
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
),
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
return Response.sendJsonObjectResponse(req, res, responseData);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
next(e);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1758626094132 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1758626094132";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`CREATE TABLE "TeamComplianceSetting" ("_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, "teamId" uuid NOT NULL, "createdByUserId" uuid, "deletedByUserId" uuid, "ruleType" character varying(100) NOT NULL, "enabled" boolean NOT NULL DEFAULT false, "options" jsonb, CONSTRAINT "PK_7fdfcc67b176bbc26d188e84c3f" PRIMARY KEY ("_id"))`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`CREATE INDEX "IDX_510f0d225fc3cec252790630e7" ON "TeamComplianceSetting" ("projectId") `,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`CREATE INDEX "IDX_1afaa319cf5f476122b131e2b8" ON "TeamComplianceSetting" ("teamId") `,
|
|
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 "TeamComplianceSetting" ADD CONSTRAINT "FK_510f0d225fc3cec252790630e77" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "TeamComplianceSetting" ADD CONSTRAINT "FK_1afaa319cf5f476122b131e2b8f" FOREIGN KEY ("teamId") REFERENCES "Team"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "TeamComplianceSetting" ADD CONSTRAINT "FK_a639b6b7654f5b6ee6eb431a036" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "TeamComplianceSetting" ADD CONSTRAINT "FK_380d3ad2f032b7a77956ef29095" 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 "TeamComplianceSetting" DROP CONSTRAINT "FK_380d3ad2f032b7a77956ef29095"`,
|
|
39
|
+
);
|
|
40
|
+
await queryRunner.query(
|
|
41
|
+
`ALTER TABLE "TeamComplianceSetting" DROP CONSTRAINT "FK_a639b6b7654f5b6ee6eb431a036"`,
|
|
42
|
+
);
|
|
43
|
+
await queryRunner.query(
|
|
44
|
+
`ALTER TABLE "TeamComplianceSetting" DROP CONSTRAINT "FK_1afaa319cf5f476122b131e2b8f"`,
|
|
45
|
+
);
|
|
46
|
+
await queryRunner.query(
|
|
47
|
+
`ALTER TABLE "TeamComplianceSetting" DROP CONSTRAINT "FK_510f0d225fc3cec252790630e77"`,
|
|
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_1afaa319cf5f476122b131e2b8"`,
|
|
57
|
+
);
|
|
58
|
+
await queryRunner.query(
|
|
59
|
+
`DROP INDEX "public"."IDX_510f0d225fc3cec252790630e7"`,
|
|
60
|
+
);
|
|
61
|
+
await queryRunner.query(`DROP TABLE "TeamComplianceSetting"`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1758629540993 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1758629540993";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "TeamComplianceSetting" DROP COLUMN "ruleType"`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "TeamComplianceSetting" ADD "ruleType" character varying(500) NOT NULL`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`CREATE UNIQUE INDEX "IDX_ef7342919ff02501c2b0ddc029" ON "TeamComplianceSetting" ("teamId", "ruleType") `,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`DROP INDEX "public"."IDX_ef7342919ff02501c2b0ddc029"`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "TeamComplianceSetting" DROP COLUMN "ruleType"`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "TeamComplianceSetting" ADD "ruleType" character varying(100) NOT NULL`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`,
|
|
36
|
+
);
|
|
37
|
+
await queryRunner.query(
|
|
38
|
+
`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`,
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -168,6 +168,8 @@ import { MigrationName1756821449686 } from "./1756821449686-MigrationName";
|
|
|
168
168
|
import { MigrationName1757416939595 } from "./1757416939595-MigrationName";
|
|
169
169
|
import { MigrationName1757423505855 } from "./1757423505855-MigrationName";
|
|
170
170
|
import { MigrationName1758313975491 } from "./1758313975491-MigrationName";
|
|
171
|
+
import { MigrationName1758626094132 } from "./1758626094132-MigrationName";
|
|
172
|
+
import { MigrationName1758629540993 } from "./1758629540993-MigrationName";
|
|
171
173
|
|
|
172
174
|
export default [
|
|
173
175
|
InitialMigration,
|
|
@@ -340,4 +342,6 @@ export default [
|
|
|
340
342
|
MigrationName1757416939595,
|
|
341
343
|
MigrationName1757423505855,
|
|
342
344
|
MigrationName1758313975491,
|
|
345
|
+
MigrationName1758626094132,
|
|
346
|
+
MigrationName1758629540993,
|
|
343
347
|
];
|
package/Server/Services/Index.ts
CHANGED
|
@@ -111,6 +111,7 @@ import StatusPageSsoService from "./StatusPageSsoService";
|
|
|
111
111
|
import StatusPageSubscriberService from "./StatusPageSubscriberService";
|
|
112
112
|
import TeamMemberService from "./TeamMemberService";
|
|
113
113
|
import TeamPermissionService from "./TeamPermissionService";
|
|
114
|
+
import TeamComplianceSettingService from "./TeamComplianceSettingService";
|
|
114
115
|
// Team
|
|
115
116
|
import TeamService from "./TeamService";
|
|
116
117
|
import TelemetryServiceService from "./TelemetryServiceService";
|
|
@@ -268,6 +269,7 @@ const services: Array<BaseService> = [
|
|
|
268
269
|
|
|
269
270
|
TeamMemberService,
|
|
270
271
|
TeamPermissionService,
|
|
272
|
+
TeamComplianceSettingService,
|
|
271
273
|
TeamService,
|
|
272
274
|
|
|
273
275
|
UserService,
|