@oneuptime/common 12.0.17 → 12.0.19
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/EnterpriseLicense.ts +23 -0
- package/Models/DatabaseModels/Index.ts +4 -2
- package/Models/DatabaseModels/Monitor.ts +39 -9
- package/Models/DatabaseModels/UserMicrosoftTeams.ts +344 -0
- package/Models/DatabaseModels/UserNotificationRule.ts +144 -8
- package/Models/DatabaseModels/UserNotificationSetting.ts +34 -0
- package/Models/DatabaseModels/UserOnCallLogTimeline.ts +95 -0
- package/Models/DatabaseModels/UserSlack.ts +341 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +9 -0
- package/Server/API/UserMicrosoftTeamsAPI.ts +127 -0
- package/Server/API/UserSlackAPI.ts +125 -0
- package/Server/EnvironmentConfig.ts +12 -107
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.ts +117 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.ts +197 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
- package/Server/Infrastructure/Queue.ts +7 -0
- package/Server/Services/BillingService.ts +8 -0
- package/Server/Services/EnterpriseLicenseService.ts +60 -0
- package/Server/Services/Index.ts +6 -2
- package/Server/Services/LlmLogService.ts +25 -9
- package/Server/Services/OnCallReadinessService.ts +86 -2
- package/Server/Services/ProjectService.ts +67 -0
- package/Server/Services/UserMicrosoftTeamsService.ts +208 -0
- package/Server/Services/UserNotificationMethodAdminService.ts +167 -5
- package/Server/Services/UserNotificationRuleAdminService.ts +40 -6
- package/Server/Services/UserNotificationRuleService.ts +589 -11
- package/Server/Services/UserNotificationSettingService.ts +138 -0
- package/Server/Services/UserService.ts +28 -0
- package/Server/Services/UserSlackService.ts +218 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +67 -1
- package/Server/Services/WorkspaceUserAuthTokenService.ts +73 -0
- package/Server/Services/WorkspaceUserNotificationService.ts +190 -0
- package/Server/Utils/Marketing/MarketingEventUtil.ts +145 -0
- package/Server/Utils/Marketing/MarketingEventWebhook.ts +114 -0
- package/Server/Utils/Monitor/MonitorLogUtil.ts +14 -1
- package/Server/Utils/Monitor/MonitorPayloadRedaction.ts +321 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +191 -4
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +22 -14
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +22 -11
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +37 -1
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +18 -10
- package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +17 -0
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +27 -1
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +214 -0
- package/Tests/Server/API/OnCallReadinessAPI.test.ts +145 -26
- package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +2 -2
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +11 -1
- package/Tests/Server/Services/AdminRuleEditGuards.test.ts +22 -8
- package/Tests/Server/Services/BillingService.test.ts +20 -0
- package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +18 -2
- package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +5 -1
- package/Tests/Server/Services/LlmLogServiceTokenAggregateParams.test.ts +640 -0
- package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +246 -22
- package/Tests/Server/Services/NotificationDeletionImpact.test.ts +136 -8
- package/Tests/Server/Services/OnCallNotificationFallback.test.ts +191 -8
- package/Tests/Server/Services/OnCallReadinessService.test.ts +343 -18
- package/Tests/Server/Services/SeverityRuleBackfill.test.ts +5 -1
- package/Tests/Server/Services/UserMicrosoftTeamsService.test.ts +343 -0
- package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +209 -8
- package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +22 -6
- package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +12 -6
- package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +37 -3
- package/Tests/Server/Services/UserNotificationRuleWorkspaceDelivery.test.ts +669 -0
- package/Tests/Server/Services/UserNotificationSettingWorkspaceChannels.test.ts +410 -0
- package/Tests/Server/Services/UserSlackService.test.ts +407 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenDisconnectCascade.test.ts +224 -0
- package/Tests/Server/Services/WorkspaceUserAuthTokenNotificationMethodCascade.test.ts +189 -0
- package/Tests/Server/Services/WorkspaceUserNotificationService.test.ts +496 -0
- package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +30 -17
- package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +8 -3
- package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +72 -3
- package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +22 -18
- package/Tests/Server/Types/Database/Permissions/WorkspaceMethodStampedColumnCreate.test.ts +178 -0
- package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +259 -0
- package/Tests/Server/Utils/Marketing/MarketingEventWebhook.test.ts +257 -0
- package/Tests/Server/Utils/Monitor/MonitorLogUtilRedaction.test.ts +300 -0
- package/Tests/Server/Utils/Monitor/MonitorPayloadRedaction.test.ts +381 -0
- package/Tests/Server/Utils/Runbook/RunbookExecutePermission.test.ts +228 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayErasureTombstone.test.ts +189 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +205 -0
- package/Tests/Server/Utils/Telemetry/AppMetrics.test.ts +275 -0
- package/Tests/Server/Utils/Telemetry/TelemetryContext.test.ts +279 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsDirectMessage.test.ts +454 -0
- package/Tests/Types/Kubernetes/KubernetesObjectParsers.test.ts +794 -0
- package/Tests/Types/Kubernetes/KubernetesRightSizing.test.ts +53 -0
- package/Tests/Types/Measurement/MeasurementAggregationType.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +114 -0
- package/Tests/Types/Workspace/WorkspaceType.test.ts +53 -0
- package/Tests/UI/Utils/NotificationMethodUtil.test.ts +137 -9
- package/Tests/UI/Utils/PermissionGate.test.ts +105 -0
- package/Tests/Utils/Dashboard/Components/DashboardComponentDefaults.test.ts +257 -0
- package/Types/Billing/PayAsYouGoPricing.ts +1 -1
- package/Types/Marketing/MarketingEvent.ts +97 -0
- package/UI/Utils/NotificationMethodUtil.ts +41 -1
- package/UI/Utils/PermissionGate.ts +56 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js +24 -0
- package/build/dist/Models/DatabaseModels/EnterpriseLicense.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +4 -2
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +39 -9
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js +363 -0
- package/build/dist/Models/DatabaseModels/UserMicrosoftTeams.js.map +1 -0
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js +145 -8
- package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserNotificationSetting.js +38 -0
- package/build/dist/Models/DatabaseModels/UserNotificationSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +96 -0
- package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/UserSlack.js +361 -0
- package/build/dist/Models/DatabaseModels/UserSlack.js.map +1 -0
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js +82 -0
- package/build/dist/Server/API/UserMicrosoftTeamsAPI.js.map +1 -0
- package/build/dist/Server/API/UserSlackAPI.js +81 -0
- package/build/dist/Server/API/UserSlackAPI.js.map +1 -0
- package/build/dist/Server/EnvironmentConfig.js +10 -70
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788700000000-RemoveMarketingConversionUploadState.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js +37 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788800000000-DropMarketingConversionAddEnterpriseLicenseEmail.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js +106 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1788900000000-RedactStoredMonitorIngestSecrets.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.js +78 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789000000000-AddUserSlackAndMicrosoftTeams.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/Infrastructure/Queue.js +7 -0
- package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
- package/build/dist/Server/Services/BillingService.js +6 -0
- package/build/dist/Server/Services/BillingService.js.map +1 -1
- package/build/dist/Server/Services/EnterpriseLicenseService.js +65 -0
- package/build/dist/Server/Services/EnterpriseLicenseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +6 -2
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/LlmLogService.js +25 -9
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/OnCallReadinessService.js +74 -2
- package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +56 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/UserMicrosoftTeamsService.js +183 -0
- package/build/dist/Server/Services/UserMicrosoftTeamsService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js +138 -2
- package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js +32 -4
- package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +499 -67
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationSettingService.js +118 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +26 -1
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Services/UserSlackService.js +195 -0
- package/build/dist/Server/Services/UserSlackService.js.map +1 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +64 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js +70 -0
- package/build/dist/Server/Services/WorkspaceUserAuthTokenService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceUserNotificationService.js +129 -0
- package/build/dist/Server/Services/WorkspaceUserNotificationService.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +94 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js +93 -0
- package/build/dist/Server/Utils/Marketing/MarketingEventWebhook.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js +12 -1
- package/build/dist/Server/Utils/Monitor/MonitorLogUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js +233 -0
- package/build/dist/Server/Utils/Monitor/MonitorPayloadRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +141 -4
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/Billing/PayAsYouGoPricing.js +1 -1
- package/build/dist/Types/Billing/PayAsYouGoPricing.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingEvent.js +43 -0
- package/build/dist/Types/Marketing/MarketingEvent.js.map +1 -0
- package/build/dist/UI/Utils/NotificationMethodUtil.js +33 -1
- package/build/dist/UI/Utils/NotificationMethodUtil.js.map +1 -1
- package/build/dist/UI/Utils/PermissionGate.js +32 -0
- package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
- package/package.json +1 -1
- package/Models/DatabaseModels/MarketingConversion.ts +0 -410
- package/Server/Services/MarketingConversionService.ts +0 -10
- package/Server/Utils/Marketing/ConversionUploadProvider.ts +0 -215
- package/Server/Utils/Marketing/ConversionUploadProviders.ts +0 -22
- package/Server/Utils/Marketing/Providers/GoogleAds.ts +0 -333
- package/Server/Utils/Marketing/Providers/LinkedIn.ts +0 -185
- package/Server/Utils/Marketing/Providers/Meta.ts +0 -182
- package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +0 -223
- package/Server/Utils/Marketing/Providers/Reddit.ts +0 -208
- package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +0 -315
- package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +0 -300
- package/Tests/Server/Utils/Marketing/GoogleAds.test.ts +0 -592
- package/Tests/Server/Utils/Marketing/LinkedIn.test.ts +0 -282
- package/Tests/Server/Utils/Marketing/Meta.test.ts +0 -304
- package/Tests/Server/Utils/Marketing/MicrosoftAds.test.ts +0 -263
- package/Tests/Server/Utils/Marketing/Reddit.test.ts +0 -259
- package/Types/Marketing/MarketingConversion.ts +0 -53
- package/build/dist/Models/DatabaseModels/MarketingConversion.js +0 -445
- package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +0 -1
- package/build/dist/Server/Services/MarketingConversionService.js +0 -9
- package/build/dist/Server/Services/MarketingConversionService.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +0 -93
- package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js +0 -20
- package/build/dist/Server/Utils/Marketing/ConversionUploadProviders.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +0 -221
- package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +0 -137
- package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js +0 -133
- package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +0 -143
- package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +0 -1
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +0 -145
- package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +0 -1
- package/build/dist/Types/Marketing/MarketingConversion.js +0 -52
- package/build/dist/Types/Marketing/MarketingConversion.js.map +0 -1
|
@@ -8,6 +8,7 @@ import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
|
8
8
|
import TableColumn from "../../Types/Database/TableColumn";
|
|
9
9
|
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
10
10
|
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
11
|
+
import Email from "../../Types/Email";
|
|
11
12
|
import IconProp from "../../Types/Icon/IconProp";
|
|
12
13
|
import { Column, Entity, Index } from "typeorm";
|
|
13
14
|
|
|
@@ -47,6 +48,28 @@ export default class EnterpriseLicense extends BaseModel {
|
|
|
47
48
|
})
|
|
48
49
|
public companyName?: string = undefined;
|
|
49
50
|
|
|
51
|
+
@ColumnAccessControl({
|
|
52
|
+
create: [],
|
|
53
|
+
read: [],
|
|
54
|
+
update: [],
|
|
55
|
+
})
|
|
56
|
+
@TableColumn({
|
|
57
|
+
required: false,
|
|
58
|
+
type: TableColumnType.Email,
|
|
59
|
+
title: "Email",
|
|
60
|
+
description:
|
|
61
|
+
"Contact email for this license. Set it to the address the customer booked their meeting with, so the licence can be joined to the conversion that produced it.",
|
|
62
|
+
})
|
|
63
|
+
@Index("idx_enterprise_license_email")
|
|
64
|
+
@Column({
|
|
65
|
+
nullable: true,
|
|
66
|
+
type: ColumnType.Email,
|
|
67
|
+
length: ColumnLength.Email,
|
|
68
|
+
unique: false,
|
|
69
|
+
transformer: Email.getDatabaseTransformer(),
|
|
70
|
+
})
|
|
71
|
+
public email?: Email = undefined;
|
|
72
|
+
|
|
50
73
|
@ColumnAccessControl({
|
|
51
74
|
create: [],
|
|
52
75
|
read: [],
|
|
@@ -278,6 +278,8 @@ import UserEmail from "./UserEmail";
|
|
|
278
278
|
import UserPush from "./UserPush";
|
|
279
279
|
import UserWhatsApp from "./UserWhatsApp";
|
|
280
280
|
import UserTelegram from "./UserTelegram";
|
|
281
|
+
import UserSlack from "./UserSlack";
|
|
282
|
+
import UserMicrosoftTeams from "./UserMicrosoftTeams";
|
|
281
283
|
import UserWebhook from "./UserWebhook";
|
|
282
284
|
// User Notification Rules
|
|
283
285
|
import UserNotificationRule from "./UserNotificationRule";
|
|
@@ -437,7 +439,6 @@ import MetricType from "./MetricType";
|
|
|
437
439
|
import ProjectSCIM from "./ProjectSCIM";
|
|
438
440
|
import ProjectSCIMLog from "./ProjectSCIMLog";
|
|
439
441
|
import StatusPageSCIMLog from "./StatusPageSCIMLog";
|
|
440
|
-
import MarketingConversion from "./MarketingConversion";
|
|
441
442
|
import DeletedProject from "./DeletedProject";
|
|
442
443
|
|
|
443
444
|
const AllModelTypes: Array<{
|
|
@@ -703,6 +704,8 @@ const AllModelTypes: Array<{
|
|
|
703
704
|
UserPush,
|
|
704
705
|
UserWhatsApp,
|
|
705
706
|
UserTelegram,
|
|
707
|
+
UserSlack,
|
|
708
|
+
UserMicrosoftTeams,
|
|
706
709
|
UserWebhook,
|
|
707
710
|
UserIncomingCallNumber,
|
|
708
711
|
|
|
@@ -897,7 +900,6 @@ const AllModelTypes: Array<{
|
|
|
897
900
|
RumSessionReplayView,
|
|
898
901
|
RumSessionErasureRequest,
|
|
899
902
|
RumSessionPin,
|
|
900
|
-
MarketingConversion,
|
|
901
903
|
DeletedProject,
|
|
902
904
|
];
|
|
903
905
|
|
|
@@ -1220,15 +1220,25 @@ export default class Monitor extends BaseModel {
|
|
|
1220
1220
|
|
|
1221
1221
|
@ColumnAccessControl({
|
|
1222
1222
|
create: [],
|
|
1223
|
+
/*
|
|
1224
|
+
* Gated on the ability to ROTATE the secret, not on the ability to view
|
|
1225
|
+
* the monitor: this read list is deliberately identical to the update list
|
|
1226
|
+
* below. A holder of this key can authenticate as any host
|
|
1227
|
+
* agent reporting to the monitor -- forging or suppressing heartbeats.
|
|
1228
|
+
*
|
|
1229
|
+
* Viewer, MonitorViewer and ReadProjectMonitor used to be here. Viewer is
|
|
1230
|
+
* the least privilege OneUptime grants and is what gets handed to
|
|
1231
|
+
* dashboards, auditors, contractors and automations, so "read-only" also
|
|
1232
|
+
* meant "can read a live bearer credential".
|
|
1233
|
+
* https://github.com/OneUptime/oneuptime/issues/3360
|
|
1234
|
+
*/
|
|
1223
1235
|
read: [
|
|
1224
1236
|
Permission.ProjectOwner,
|
|
1225
1237
|
Permission.ProjectAdmin,
|
|
1226
1238
|
Permission.ProjectMember,
|
|
1227
|
-
Permission.Viewer,
|
|
1228
1239
|
Permission.MonitorAdmin,
|
|
1229
1240
|
Permission.MonitorMember,
|
|
1230
|
-
Permission.
|
|
1231
|
-
Permission.ReadProjectMonitor,
|
|
1241
|
+
Permission.EditProjectMonitor,
|
|
1232
1242
|
],
|
|
1233
1243
|
update: [
|
|
1234
1244
|
Permission.ProjectOwner,
|
|
@@ -1258,15 +1268,25 @@ export default class Monitor extends BaseModel {
|
|
|
1258
1268
|
|
|
1259
1269
|
@ColumnAccessControl({
|
|
1260
1270
|
create: [],
|
|
1271
|
+
/*
|
|
1272
|
+
* Gated on the ability to ROTATE the secret, not on the ability to view
|
|
1273
|
+
* the monitor: this read list is deliberately identical to the update list
|
|
1274
|
+
* below. This key IS the heartbeat URL: a holder can beat the
|
|
1275
|
+
* monitor and keep a dead service looking alive.
|
|
1276
|
+
*
|
|
1277
|
+
* Viewer, MonitorViewer and ReadProjectMonitor used to be here. Viewer is
|
|
1278
|
+
* the least privilege OneUptime grants and is what gets handed to
|
|
1279
|
+
* dashboards, auditors, contractors and automations, so "read-only" also
|
|
1280
|
+
* meant "can read a live bearer credential".
|
|
1281
|
+
* https://github.com/OneUptime/oneuptime/issues/3360
|
|
1282
|
+
*/
|
|
1261
1283
|
read: [
|
|
1262
1284
|
Permission.ProjectOwner,
|
|
1263
1285
|
Permission.ProjectAdmin,
|
|
1264
1286
|
Permission.ProjectMember,
|
|
1265
|
-
Permission.Viewer,
|
|
1266
1287
|
Permission.MonitorAdmin,
|
|
1267
1288
|
Permission.MonitorMember,
|
|
1268
|
-
Permission.
|
|
1269
|
-
Permission.ReadProjectMonitor,
|
|
1289
|
+
Permission.EditProjectMonitor,
|
|
1270
1290
|
],
|
|
1271
1291
|
update: [
|
|
1272
1292
|
Permission.ProjectOwner,
|
|
@@ -1333,15 +1353,25 @@ export default class Monitor extends BaseModel {
|
|
|
1333
1353
|
|
|
1334
1354
|
@ColumnAccessControl({
|
|
1335
1355
|
create: [],
|
|
1356
|
+
/*
|
|
1357
|
+
* Gated on the ability to ROTATE the secret, not on the ability to view
|
|
1358
|
+
* the monitor: this read list is deliberately identical to the update list
|
|
1359
|
+
* below. This key IS the monitor's inbound address: a holder can
|
|
1360
|
+
* send mail that the monitor counts as a heartbeat.
|
|
1361
|
+
*
|
|
1362
|
+
* Viewer, MonitorViewer and ReadProjectMonitor used to be here. Viewer is
|
|
1363
|
+
* the least privilege OneUptime grants and is what gets handed to
|
|
1364
|
+
* dashboards, auditors, contractors and automations, so "read-only" also
|
|
1365
|
+
* meant "can read a live bearer credential".
|
|
1366
|
+
* https://github.com/OneUptime/oneuptime/issues/3360
|
|
1367
|
+
*/
|
|
1336
1368
|
read: [
|
|
1337
1369
|
Permission.ProjectOwner,
|
|
1338
1370
|
Permission.ProjectAdmin,
|
|
1339
1371
|
Permission.ProjectMember,
|
|
1340
|
-
Permission.Viewer,
|
|
1341
1372
|
Permission.MonitorAdmin,
|
|
1342
1373
|
Permission.MonitorMember,
|
|
1343
|
-
Permission.
|
|
1344
|
-
Permission.ReadProjectMonitor,
|
|
1374
|
+
Permission.EditProjectMonitor,
|
|
1345
1375
|
],
|
|
1346
1376
|
update: [
|
|
1347
1377
|
Permission.ProjectOwner,
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import Project from "./Project";
|
|
2
|
+
import User from "./User";
|
|
3
|
+
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
4
|
+
import Route from "../../Types/API/Route";
|
|
5
|
+
import AllowAccessIfSubscriptionIsUnpaid from "../../Types/Database/AccessControl/AllowAccessIfSubscriptionIsUnpaid";
|
|
6
|
+
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
7
|
+
import OwnerOnlyColumn from "../../Types/Database/AccessControl/OwnerOnlyColumn";
|
|
8
|
+
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
9
|
+
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
10
|
+
import ColumnType from "../../Types/Database/ColumnType";
|
|
11
|
+
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
12
|
+
import CurrentUserCanAccessRecordBy from "../../Types/Database/CurrentUserCanAccessRecordBy";
|
|
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 { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* `read` names Permission.CurrentUser and nothing else, exactly like the other
|
|
24
|
+
* notification-method models (UserTelegram has the full essay). That single
|
|
25
|
+
* entry is what keeps every row owner-only: row scoping comes from the TABLE
|
|
26
|
+
* list alone, and widening it would expose the Microsoft Entra user id every
|
|
27
|
+
* project member's pages are delivered to. Do not add administrator
|
|
28
|
+
* permissions here - OnCallReadinessService returns the masked,
|
|
29
|
+
* admin-sanctioned view instead.
|
|
30
|
+
*
|
|
31
|
+
* Unlike Telegram/SMS/WhatsApp there is no verification code: a row is only
|
|
32
|
+
* ever created from an existing, OAuth-established workspace link
|
|
33
|
+
* (WorkspaceUserAuthToken), so creation IS verification.
|
|
34
|
+
* UserMicrosoftTeamsService enforces that and stamps the Microsoft Teams
|
|
35
|
+
* identifiers server-side.
|
|
36
|
+
*/
|
|
37
|
+
@TenantColumn("projectId")
|
|
38
|
+
@AllowAccessIfSubscriptionIsUnpaid()
|
|
39
|
+
@TableAccessControl({
|
|
40
|
+
create: [Permission.CurrentUser],
|
|
41
|
+
read: [Permission.CurrentUser],
|
|
42
|
+
delete: [Permission.CurrentUser],
|
|
43
|
+
update: [Permission.CurrentUser],
|
|
44
|
+
})
|
|
45
|
+
@CrudApiEndpoint(new Route("/user-microsoft-teams"))
|
|
46
|
+
@Entity({
|
|
47
|
+
name: "UserMicrosoftTeams",
|
|
48
|
+
})
|
|
49
|
+
@TableMetadata({
|
|
50
|
+
tableName: "UserMicrosoftTeams",
|
|
51
|
+
singularName: "Microsoft Teams Account",
|
|
52
|
+
pluralName: "Microsoft Teams Accounts",
|
|
53
|
+
icon: IconProp.MicrosoftTeams,
|
|
54
|
+
tableDescription:
|
|
55
|
+
"Microsoft Teams accounts used for Microsoft Teams notifications.",
|
|
56
|
+
})
|
|
57
|
+
@CurrentUserCanAccessRecordBy("userId")
|
|
58
|
+
class UserMicrosoftTeams extends BaseModel {
|
|
59
|
+
@ColumnAccessControl({
|
|
60
|
+
create: [Permission.CurrentUser],
|
|
61
|
+
read: [Permission.CurrentUser],
|
|
62
|
+
update: [],
|
|
63
|
+
})
|
|
64
|
+
@TableColumn({
|
|
65
|
+
manyToOneRelationColumn: "projectId",
|
|
66
|
+
type: TableColumnType.Entity,
|
|
67
|
+
modelType: Project,
|
|
68
|
+
title: "Project",
|
|
69
|
+
description: "Relation to Project Resource in which this object belongs",
|
|
70
|
+
})
|
|
71
|
+
@ManyToOne(
|
|
72
|
+
() => {
|
|
73
|
+
return Project;
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
eager: false,
|
|
77
|
+
nullable: true,
|
|
78
|
+
onDelete: "CASCADE",
|
|
79
|
+
orphanedRowAction: "nullify",
|
|
80
|
+
},
|
|
81
|
+
)
|
|
82
|
+
@JoinColumn({ name: "projectId" })
|
|
83
|
+
public project?: Project = undefined;
|
|
84
|
+
|
|
85
|
+
@ColumnAccessControl({
|
|
86
|
+
create: [Permission.CurrentUser],
|
|
87
|
+
read: [Permission.CurrentUser],
|
|
88
|
+
update: [],
|
|
89
|
+
})
|
|
90
|
+
@Index()
|
|
91
|
+
@TableColumn({
|
|
92
|
+
type: TableColumnType.ObjectID,
|
|
93
|
+
required: true,
|
|
94
|
+
canReadOnRelationQuery: true,
|
|
95
|
+
title: "Project ID",
|
|
96
|
+
description: "ID of your OneUptime Project in which this object belongs",
|
|
97
|
+
})
|
|
98
|
+
@Column({
|
|
99
|
+
type: ColumnType.ObjectID,
|
|
100
|
+
nullable: false,
|
|
101
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
102
|
+
})
|
|
103
|
+
public projectId?: ObjectID = undefined;
|
|
104
|
+
|
|
105
|
+
@ColumnAccessControl({
|
|
106
|
+
/*
|
|
107
|
+
* CurrentUser here does NOT mean the client may choose the value: the
|
|
108
|
+
* service hook refuses any non-root payload that carries these columns
|
|
109
|
+
* and then stamps them itself, and hooks run BEFORE the column
|
|
110
|
+
* permission check (DatabaseService.create). The entry exists because
|
|
111
|
+
* that same check runs on the STAMPED data - with an empty list the
|
|
112
|
+
* server's own write is refused and no user can add this method at all.
|
|
113
|
+
* Same shape as UserWebAuthn's server-stamped isVerified.
|
|
114
|
+
*/
|
|
115
|
+
create: [Permission.CurrentUser],
|
|
116
|
+
read: [Permission.CurrentUser],
|
|
117
|
+
update: [],
|
|
118
|
+
})
|
|
119
|
+
@Index()
|
|
120
|
+
/*
|
|
121
|
+
* The Microsoft Entra (Azure AD) object id the project's bot delivers
|
|
122
|
+
* direct messages to. Holding it is enough to address bot messages at that
|
|
123
|
+
* person, so it is a delivery target and not a label. Captured server-side
|
|
124
|
+
* from the user's own WorkspaceUserAuthToken - never writable by the client.
|
|
125
|
+
*/
|
|
126
|
+
@OwnerOnlyColumn()
|
|
127
|
+
@TableColumn({
|
|
128
|
+
title: "Microsoft Teams User ID",
|
|
129
|
+
required: false,
|
|
130
|
+
unique: false,
|
|
131
|
+
type: TableColumnType.ShortText,
|
|
132
|
+
canReadOnRelationQuery: true,
|
|
133
|
+
description:
|
|
134
|
+
"Microsoft Entra user ID captured from your connected Microsoft Teams account. Populated automatically.",
|
|
135
|
+
})
|
|
136
|
+
@Column({
|
|
137
|
+
type: ColumnType.ShortText,
|
|
138
|
+
length: ColumnLength.ShortText,
|
|
139
|
+
unique: false,
|
|
140
|
+
nullable: true,
|
|
141
|
+
})
|
|
142
|
+
public microsoftTeamsUserId?: string = undefined;
|
|
143
|
+
|
|
144
|
+
@ColumnAccessControl({
|
|
145
|
+
/*
|
|
146
|
+
* CurrentUser here does NOT mean the client may choose the value: the
|
|
147
|
+
* service hook refuses any non-root payload that carries these columns
|
|
148
|
+
* and then stamps them itself, and hooks run BEFORE the column
|
|
149
|
+
* permission check (DatabaseService.create). The entry exists because
|
|
150
|
+
* that same check runs on the STAMPED data - with an empty list the
|
|
151
|
+
* server's own write is refused and no user can add this method at all.
|
|
152
|
+
* Same shape as UserWebAuthn's server-stamped isVerified.
|
|
153
|
+
*/
|
|
154
|
+
create: [Permission.CurrentUser],
|
|
155
|
+
read: [Permission.CurrentUser],
|
|
156
|
+
update: [],
|
|
157
|
+
})
|
|
158
|
+
/*
|
|
159
|
+
* The person's Microsoft Teams display name at the time the method was
|
|
160
|
+
* added. Only a label for the row, but it is still their identity in an
|
|
161
|
+
* outside workspace, so it stays owner-only like the Telegram handle.
|
|
162
|
+
*/
|
|
163
|
+
@OwnerOnlyColumn()
|
|
164
|
+
@TableColumn({
|
|
165
|
+
title: "Microsoft Teams Username",
|
|
166
|
+
required: false,
|
|
167
|
+
unique: false,
|
|
168
|
+
type: TableColumnType.ShortText,
|
|
169
|
+
canReadOnRelationQuery: true,
|
|
170
|
+
description:
|
|
171
|
+
"Display name captured from your connected Microsoft Teams account. Populated automatically.",
|
|
172
|
+
})
|
|
173
|
+
@Column({
|
|
174
|
+
type: ColumnType.ShortText,
|
|
175
|
+
length: ColumnLength.ShortText,
|
|
176
|
+
unique: false,
|
|
177
|
+
nullable: true,
|
|
178
|
+
})
|
|
179
|
+
public microsoftTeamsUserName?: string = undefined;
|
|
180
|
+
|
|
181
|
+
@ColumnAccessControl({
|
|
182
|
+
create: [Permission.CurrentUser],
|
|
183
|
+
read: [Permission.CurrentUser],
|
|
184
|
+
update: [],
|
|
185
|
+
})
|
|
186
|
+
@TableColumn({
|
|
187
|
+
manyToOneRelationColumn: "user",
|
|
188
|
+
type: TableColumnType.Entity,
|
|
189
|
+
modelType: User,
|
|
190
|
+
title: "User",
|
|
191
|
+
description: "Relation to User who this Microsoft Teams account belongs to",
|
|
192
|
+
})
|
|
193
|
+
@ManyToOne(
|
|
194
|
+
() => {
|
|
195
|
+
return User;
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
eager: false,
|
|
199
|
+
nullable: true,
|
|
200
|
+
onDelete: "CASCADE",
|
|
201
|
+
orphanedRowAction: "nullify",
|
|
202
|
+
},
|
|
203
|
+
)
|
|
204
|
+
@JoinColumn({ name: "userId" })
|
|
205
|
+
public user?: User = undefined;
|
|
206
|
+
|
|
207
|
+
@ColumnAccessControl({
|
|
208
|
+
create: [Permission.CurrentUser],
|
|
209
|
+
read: [Permission.CurrentUser],
|
|
210
|
+
update: [],
|
|
211
|
+
})
|
|
212
|
+
@TableColumn({
|
|
213
|
+
type: TableColumnType.ObjectID,
|
|
214
|
+
title: "User ID",
|
|
215
|
+
description: "User ID who this Microsoft Teams account belongs to",
|
|
216
|
+
})
|
|
217
|
+
@Column({
|
|
218
|
+
type: ColumnType.ObjectID,
|
|
219
|
+
nullable: true,
|
|
220
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
221
|
+
})
|
|
222
|
+
@Index()
|
|
223
|
+
public userId?: ObjectID = undefined;
|
|
224
|
+
|
|
225
|
+
@ColumnAccessControl({
|
|
226
|
+
create: [Permission.CurrentUser],
|
|
227
|
+
read: [Permission.CurrentUser],
|
|
228
|
+
update: [],
|
|
229
|
+
})
|
|
230
|
+
@TableColumn({
|
|
231
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
232
|
+
type: TableColumnType.Entity,
|
|
233
|
+
modelType: User,
|
|
234
|
+
title: "Created by User",
|
|
235
|
+
description:
|
|
236
|
+
"Relation to User who created this object (if this object was created by a User)",
|
|
237
|
+
})
|
|
238
|
+
@ManyToOne(
|
|
239
|
+
() => {
|
|
240
|
+
return User;
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
eager: false,
|
|
244
|
+
nullable: true,
|
|
245
|
+
onDelete: "SET NULL",
|
|
246
|
+
orphanedRowAction: "nullify",
|
|
247
|
+
},
|
|
248
|
+
)
|
|
249
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
250
|
+
public createdByUser?: User = undefined;
|
|
251
|
+
|
|
252
|
+
@ColumnAccessControl({
|
|
253
|
+
create: [Permission.CurrentUser],
|
|
254
|
+
read: [Permission.CurrentUser],
|
|
255
|
+
update: [],
|
|
256
|
+
})
|
|
257
|
+
@TableColumn({
|
|
258
|
+
type: TableColumnType.ObjectID,
|
|
259
|
+
title: "Created by User ID",
|
|
260
|
+
description:
|
|
261
|
+
"User ID who created this object (if this object was created by a User)",
|
|
262
|
+
})
|
|
263
|
+
@Column({
|
|
264
|
+
type: ColumnType.ObjectID,
|
|
265
|
+
nullable: true,
|
|
266
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
267
|
+
})
|
|
268
|
+
public createdByUserId?: ObjectID = undefined;
|
|
269
|
+
|
|
270
|
+
@ColumnAccessControl({
|
|
271
|
+
create: [],
|
|
272
|
+
read: [],
|
|
273
|
+
update: [],
|
|
274
|
+
})
|
|
275
|
+
@TableColumn({
|
|
276
|
+
manyToOneRelationColumn: "deletedByUserId",
|
|
277
|
+
type: TableColumnType.Entity,
|
|
278
|
+
title: "Deleted by User",
|
|
279
|
+
modelType: User,
|
|
280
|
+
description:
|
|
281
|
+
"Relation to User who deleted this object (if this object was deleted by a User)",
|
|
282
|
+
})
|
|
283
|
+
@ManyToOne(
|
|
284
|
+
() => {
|
|
285
|
+
return User;
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
cascade: false,
|
|
289
|
+
eager: false,
|
|
290
|
+
nullable: true,
|
|
291
|
+
onDelete: "SET NULL",
|
|
292
|
+
orphanedRowAction: "nullify",
|
|
293
|
+
},
|
|
294
|
+
)
|
|
295
|
+
@JoinColumn({ name: "deletedByUserId" })
|
|
296
|
+
public deletedByUser?: User = undefined;
|
|
297
|
+
|
|
298
|
+
@ColumnAccessControl({
|
|
299
|
+
create: [],
|
|
300
|
+
read: [],
|
|
301
|
+
update: [],
|
|
302
|
+
})
|
|
303
|
+
@TableColumn({
|
|
304
|
+
type: TableColumnType.ObjectID,
|
|
305
|
+
title: "Deleted by User ID",
|
|
306
|
+
description:
|
|
307
|
+
"User ID who deleted this object (if this object was deleted by a User)",
|
|
308
|
+
})
|
|
309
|
+
@Column({
|
|
310
|
+
type: ColumnType.ObjectID,
|
|
311
|
+
nullable: true,
|
|
312
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
313
|
+
})
|
|
314
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
315
|
+
|
|
316
|
+
@ColumnAccessControl({
|
|
317
|
+
/*
|
|
318
|
+
* CurrentUser here does NOT mean the client may choose the value: the
|
|
319
|
+
* service hook refuses any non-root payload that carries these columns
|
|
320
|
+
* and then stamps them itself, and hooks run BEFORE the column
|
|
321
|
+
* permission check (DatabaseService.create). The entry exists because
|
|
322
|
+
* that same check runs on the STAMPED data - with an empty list the
|
|
323
|
+
* server's own write is refused and no user can add this method at all.
|
|
324
|
+
* Same shape as UserWebAuthn's server-stamped isVerified.
|
|
325
|
+
*/
|
|
326
|
+
create: [Permission.CurrentUser],
|
|
327
|
+
read: [Permission.CurrentUser],
|
|
328
|
+
update: [],
|
|
329
|
+
})
|
|
330
|
+
@TableColumn({
|
|
331
|
+
title: "Is Verified",
|
|
332
|
+
description: "Is this Microsoft Teams account verified?",
|
|
333
|
+
isDefaultValueColumn: true,
|
|
334
|
+
type: TableColumnType.Boolean,
|
|
335
|
+
defaultValue: false,
|
|
336
|
+
})
|
|
337
|
+
@Column({
|
|
338
|
+
type: ColumnType.Boolean,
|
|
339
|
+
default: false,
|
|
340
|
+
})
|
|
341
|
+
public isVerified?: boolean = undefined;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
export default UserMicrosoftTeams;
|
|
@@ -7,6 +7,8 @@ import UserEmail from "./UserEmail";
|
|
|
7
7
|
import UserPush from "./UserPush";
|
|
8
8
|
import UserSMS from "./UserSMS";
|
|
9
9
|
import UserTelegram from "./UserTelegram";
|
|
10
|
+
import UserSlack from "./UserSlack";
|
|
11
|
+
import UserMicrosoftTeams from "./UserMicrosoftTeams";
|
|
10
12
|
import UserWebhook from "./UserWebhook";
|
|
11
13
|
import UserWhatsApp from "./UserWhatsApp";
|
|
12
14
|
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
@@ -80,9 +82,9 @@ const ADMIN_WRITE_PERMISSIONS: Array<Permission> = [
|
|
|
80
82
|
* only EditProjectUserNotificationRule would leave the feature dead on arrival
|
|
81
83
|
* for every project that already exists.
|
|
82
84
|
*
|
|
83
|
-
* Note the asymmetry with the
|
|
85
|
+
* Note the asymmetry with the nine notification-method models this rule points
|
|
84
86
|
* at (UserEmail, UserSMS, UserCall, UserPush, UserWhatsApp, UserTelegram,
|
|
85
|
-
* UserWebhook). There, only `read` is widened. An administrator may see which
|
|
87
|
+
* UserSlack, UserMicrosoftTeams, UserWebhook). There, only `read` is widened. An administrator may see which
|
|
86
88
|
* methods a member has and repair the rules that route to them, but may never
|
|
87
89
|
* create or edit a method on somebody else's behalf. Letting them would hand
|
|
88
90
|
* any administrator a paging-hijack primitive - add a phone number or webhook
|
|
@@ -382,11 +384,11 @@ class UserNotificationRule extends BaseModel {
|
|
|
382
384
|
public deletedByUserId?: ObjectID = undefined;
|
|
383
385
|
|
|
384
386
|
/*
|
|
385
|
-
* THE
|
|
387
|
+
* THE NINE METHOD RELATIONS BELOW ARE THE MOST DANGEROUS COLUMNS ON THIS
|
|
386
388
|
* MODEL. What follows applies to every one of them - userCall, userPush,
|
|
387
|
-
* userSms, userWhatsApp, userTelegram,
|
|
388
|
-
* their relation and their `*Id`
|
|
389
|
-
* rather than
|
|
389
|
+
* userSms, userWhatsApp, userTelegram, userSlack, userMicrosoftTeams,
|
|
390
|
+
* userWebhook and userEmail, in both their relation and their `*Id`
|
|
391
|
+
* spelling - and is written out once here rather than eighteen times.
|
|
390
392
|
*
|
|
391
393
|
* A rule is a pair: the ownership column decides WHOSE pages select the row,
|
|
392
394
|
* and the method relation decides WHERE those pages are delivered. The two
|
|
@@ -751,6 +753,139 @@ class UserNotificationRule extends BaseModel {
|
|
|
751
753
|
})
|
|
752
754
|
public userTelegramId?: ObjectID = undefined;
|
|
753
755
|
|
|
756
|
+
/*
|
|
757
|
+
* READ IS OWNER-ONLY ON THE RELATION, EVEN THOUGH THIS TABLE IS ADMIN-READABLE.
|
|
758
|
+
*
|
|
759
|
+
* Widening the relation would re-open the exposure that reverting the
|
|
760
|
+
* method models was meant to close, by a different route. A read of this
|
|
761
|
+
* table is NOT pinned to the caller's own rows for an administrator - that is
|
|
762
|
+
* the whole point of the phase - and QueryPermission.checkRelationQueryPermission
|
|
763
|
+
* authorises each nested field with relatedModel.hasReadPermissions, a
|
|
764
|
+
* name-intersection in which Permission.CurrentUser is auto-granted to every
|
|
765
|
+
* authenticated caller. So `select: { userSlack: { slackUserId: true } }` on somebody
|
|
766
|
+
* else's rule would hand back their raw Slack member id with no row scope
|
|
767
|
+
* anywhere in the path.
|
|
768
|
+
*
|
|
769
|
+
* The FK below stays admin-readable: an id is not sensitive, and it is what
|
|
770
|
+
* correlates a rule with the masked entry in OnCallReadinessService's
|
|
771
|
+
* ReadinessMethod { methodId, methodType, maskedIdentifier, isVerified }.
|
|
772
|
+
* That masked payload is the administrator's sanctioned view of a method.
|
|
773
|
+
*/
|
|
774
|
+
@ColumnAccessControl({
|
|
775
|
+
create: [Permission.CurrentUser, ...ADMIN_WRITE_PERMISSIONS],
|
|
776
|
+
read: [Permission.CurrentUser],
|
|
777
|
+
update: [],
|
|
778
|
+
})
|
|
779
|
+
@TableColumn({
|
|
780
|
+
manyToOneRelationColumn: "userSlackId",
|
|
781
|
+
type: TableColumnType.Entity,
|
|
782
|
+
modelType: UserSlack,
|
|
783
|
+
title: "User Slack",
|
|
784
|
+
description: "Relation to User Slack Resource in which this object belongs",
|
|
785
|
+
})
|
|
786
|
+
@ManyToOne(
|
|
787
|
+
() => {
|
|
788
|
+
return UserSlack;
|
|
789
|
+
},
|
|
790
|
+
{
|
|
791
|
+
eager: false,
|
|
792
|
+
nullable: true,
|
|
793
|
+
onDelete: "CASCADE",
|
|
794
|
+
orphanedRowAction: "nullify",
|
|
795
|
+
},
|
|
796
|
+
)
|
|
797
|
+
@JoinColumn({ name: "userSlackId" })
|
|
798
|
+
public userSlack?: UserSlack = undefined;
|
|
799
|
+
|
|
800
|
+
// Re-pointable by an administrator. Read the essay above `userCall` first.
|
|
801
|
+
@ColumnAccessControl({
|
|
802
|
+
create: [Permission.CurrentUser, ...ADMIN_WRITE_PERMISSIONS],
|
|
803
|
+
read: [Permission.CurrentUser, ...ADMIN_READ_PERMISSIONS],
|
|
804
|
+
update: [...ADMIN_WRITE_PERMISSIONS],
|
|
805
|
+
})
|
|
806
|
+
@Index()
|
|
807
|
+
@TableColumn({
|
|
808
|
+
type: TableColumnType.ObjectID,
|
|
809
|
+
required: false,
|
|
810
|
+
canReadOnRelationQuery: true,
|
|
811
|
+
title: "User Slack ID",
|
|
812
|
+
description: "ID of User Slack in which this object belongs",
|
|
813
|
+
example: "4d5e6f7a-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
|
|
814
|
+
})
|
|
815
|
+
@Column({
|
|
816
|
+
type: ColumnType.ObjectID,
|
|
817
|
+
nullable: true,
|
|
818
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
819
|
+
})
|
|
820
|
+
public userSlackId?: ObjectID = undefined;
|
|
821
|
+
|
|
822
|
+
/*
|
|
823
|
+
* READ IS OWNER-ONLY ON THE RELATION, EVEN THOUGH THIS TABLE IS ADMIN-READABLE.
|
|
824
|
+
*
|
|
825
|
+
* Widening the relation would re-open the exposure that reverting the
|
|
826
|
+
* method models was meant to close, by a different route. A read of this
|
|
827
|
+
* table is NOT pinned to the caller's own rows for an administrator - that is
|
|
828
|
+
* the whole point of the phase - and QueryPermission.checkRelationQueryPermission
|
|
829
|
+
* authorises each nested field with relatedModel.hasReadPermissions, a
|
|
830
|
+
* name-intersection in which Permission.CurrentUser is auto-granted to every
|
|
831
|
+
* authenticated caller. So `select: { userMicrosoftTeams: { microsoftTeamsUserId: true } }`
|
|
832
|
+
* on somebody else's rule would hand back their raw Microsoft Entra user id
|
|
833
|
+
* with no row scope anywhere in the path.
|
|
834
|
+
*
|
|
835
|
+
* The FK below stays admin-readable: an id is not sensitive, and it is what
|
|
836
|
+
* correlates a rule with the masked entry in OnCallReadinessService's
|
|
837
|
+
* ReadinessMethod { methodId, methodType, maskedIdentifier, isVerified }.
|
|
838
|
+
* That masked payload is the administrator's sanctioned view of a method.
|
|
839
|
+
*/
|
|
840
|
+
@ColumnAccessControl({
|
|
841
|
+
create: [Permission.CurrentUser, ...ADMIN_WRITE_PERMISSIONS],
|
|
842
|
+
read: [Permission.CurrentUser],
|
|
843
|
+
update: [],
|
|
844
|
+
})
|
|
845
|
+
@TableColumn({
|
|
846
|
+
manyToOneRelationColumn: "userMicrosoftTeamsId",
|
|
847
|
+
type: TableColumnType.Entity,
|
|
848
|
+
modelType: UserMicrosoftTeams,
|
|
849
|
+
title: "User Microsoft Teams",
|
|
850
|
+
description:
|
|
851
|
+
"Relation to User Microsoft Teams Resource in which this object belongs",
|
|
852
|
+
})
|
|
853
|
+
@ManyToOne(
|
|
854
|
+
() => {
|
|
855
|
+
return UserMicrosoftTeams;
|
|
856
|
+
},
|
|
857
|
+
{
|
|
858
|
+
eager: false,
|
|
859
|
+
nullable: true,
|
|
860
|
+
onDelete: "CASCADE",
|
|
861
|
+
orphanedRowAction: "nullify",
|
|
862
|
+
},
|
|
863
|
+
)
|
|
864
|
+
@JoinColumn({ name: "userMicrosoftTeamsId" })
|
|
865
|
+
public userMicrosoftTeams?: UserMicrosoftTeams = undefined;
|
|
866
|
+
|
|
867
|
+
// Re-pointable by an administrator. Read the essay above `userCall` first.
|
|
868
|
+
@ColumnAccessControl({
|
|
869
|
+
create: [Permission.CurrentUser, ...ADMIN_WRITE_PERMISSIONS],
|
|
870
|
+
read: [Permission.CurrentUser, ...ADMIN_READ_PERMISSIONS],
|
|
871
|
+
update: [...ADMIN_WRITE_PERMISSIONS],
|
|
872
|
+
})
|
|
873
|
+
@Index()
|
|
874
|
+
@TableColumn({
|
|
875
|
+
type: TableColumnType.ObjectID,
|
|
876
|
+
required: false,
|
|
877
|
+
canReadOnRelationQuery: true,
|
|
878
|
+
title: "User Microsoft Teams ID",
|
|
879
|
+
description: "ID of User Microsoft Teams in which this object belongs",
|
|
880
|
+
example: "5e6f7a8b-9c0d-1e2f-3a4b-5c6d7e8f9a0b",
|
|
881
|
+
})
|
|
882
|
+
@Column({
|
|
883
|
+
type: ColumnType.ObjectID,
|
|
884
|
+
nullable: true,
|
|
885
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
886
|
+
})
|
|
887
|
+
public userMicrosoftTeamsId?: ObjectID = undefined;
|
|
888
|
+
|
|
754
889
|
/*
|
|
755
890
|
* READ IS OWNER-ONLY ON THE RELATION, EVEN THOUGH THIS TABLE IS ADMIN-READABLE.
|
|
756
891
|
*
|
|
@@ -1020,8 +1155,9 @@ class UserNotificationRule extends BaseModel {
|
|
|
1020
1155
|
* An opt-out row is a rule that exists in order to send nothing. It carries a
|
|
1021
1156
|
* `ruleType` and a severity exactly like a normal rule, sets `isOptOut` to true, and
|
|
1022
1157
|
* holds NO notification-method relation at all — there is no userEmail, userSms,
|
|
1023
|
-
* userCall, userPush, userWhatsApp, userTelegram
|
|
1024
|
-
* absence is the point rather than a
|
|
1158
|
+
* userCall, userPush, userWhatsApp, userTelegram, userSlack, userMicrosoftTeams
|
|
1159
|
+
* or userWebhook on it, and that absence is the point rather than a
|
|
1160
|
+
* misconfiguration.
|
|
1025
1161
|
*
|
|
1026
1162
|
* It exists because "this user has zero rules matching this ruleType and severity" is
|
|
1027
1163
|
* otherwise two completely different situations wearing the same clothes. Almost
|