@oneuptime/common 12.0.18 → 12.0.20
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/EnterpriseLicenseAPI.ts +94 -19
- package/Server/API/UserMicrosoftTeamsAPI.ts +127 -0
- package/Server/API/UserSlackAPI.ts +125 -0
- package/Server/EnvironmentConfig.ts +29 -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/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 +171 -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/Response.ts +2 -2
- package/Server/Utils/StartServer.ts +2 -2
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +191 -4
- package/Server/Views/Partials/AnalyticsConsent.ejs +533 -0
- package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +22 -14
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +22 -11
- package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +465 -0
- package/Tests/App/Dashboard/DashboardChartWidgetZoom.test.tsx +302 -0
- package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +408 -0
- package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +474 -0
- package/Tests/App/Dashboard/MetricSeriesInvestigateMenu.test.tsx +368 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +37 -1
- package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +18 -10
- package/Tests/Models/DatabaseModels/DomainRoleTierCoverage.test.ts +27 -1
- package/Tests/Models/DatabaseModels/MonitorSecretKeyColumnAccessControl.test.ts +214 -0
- package/Tests/Server/API/EnterpriseLicenseReportUserCount.test.ts +763 -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/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/ProjectServiceChangePlan.test.ts +138 -0
- package/Tests/Server/Services/ProjectServiceCreateSubscriptionStarted.test.ts +516 -0
- 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/ResponseRenderAnalytics.test.ts +53 -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/Server/Views/AnalyticsConsentPartial.test.ts +241 -0
- package/Tests/UI/Components/Charts/ChartTooltipSorted.test.tsx +129 -0
- package/Tests/UI/Components/Charts/TooltipEntries.test.ts +155 -0
- package/Tests/UI/Components/Detail/DetailFieldErrors.test.tsx +347 -0
- package/Tests/UI/Components/Forms/BasicFormStepValidation.test.tsx +392 -0
- package/Tests/UI/Components/Forms/ValidationFormSteps.test.ts +549 -0
- package/Tests/UI/Utils/NotificationMethodUtil.test.ts +137 -9
- package/Tests/UI/Utils/PermissionGate.test.ts +105 -0
- package/Tests/Utils/EnterpriseLicenseSync.test.ts +562 -0
- package/Types/Analytics/RevenueEvent.ts +1 -0
- package/Types/Marketing/MarketingEvent.ts +140 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +8 -1
- package/UI/Components/Charts/Bar/BarChart.tsx +8 -1
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +19 -4
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +20 -2
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +19 -4
- package/UI/Components/Charts/ChartLibrary/Utils/TooltipEntries.ts +105 -0
- package/UI/Components/Charts/Line/LineChart.tsx +8 -1
- package/UI/Components/Detail/Detail.tsx +18 -1
- package/UI/Utils/NotificationMethodUtil.ts +41 -1
- package/UI/Utils/PermissionGate.ts +56 -0
- package/Utils/EnterpriseLicense/EnterpriseLicenseSync.ts +244 -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/EnterpriseLicenseAPI.js +66 -12
- package/build/dist/Server/API/EnterpriseLicenseAPI.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 +25 -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/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 +144 -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/Response.js +2 -2
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +2 -2
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- 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/Analytics/RevenueEvent.js +1 -0
- package/build/dist/Types/Analytics/RevenueEvent.js.map +1 -1
- package/build/dist/Types/Marketing/MarketingEvent.js +82 -0
- package/build/dist/Types/Marketing/MarketingEvent.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +9 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +9 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +22 -13
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +27 -15
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +27 -18
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/TooltipEntries.js +71 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/TooltipEntries.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +9 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +17 -1
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- 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/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js +174 -0
- package/build/dist/Utils/EnterpriseLicense/EnterpriseLicenseSync.js.map +1 -0
- 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
|
@@ -314,6 +314,40 @@ class UserNotificationSetting extends BaseModel {
|
|
|
314
314
|
})
|
|
315
315
|
public alertByTelegram?: boolean = undefined;
|
|
316
316
|
|
|
317
|
+
@ColumnAccessControl({
|
|
318
|
+
create: [Permission.CurrentUser],
|
|
319
|
+
read: [Permission.CurrentUser],
|
|
320
|
+
update: [Permission.CurrentUser],
|
|
321
|
+
})
|
|
322
|
+
@TableColumn({
|
|
323
|
+
isDefaultValueColumn: true,
|
|
324
|
+
type: TableColumnType.Boolean,
|
|
325
|
+
defaultValue: false,
|
|
326
|
+
example: false,
|
|
327
|
+
})
|
|
328
|
+
@Column({
|
|
329
|
+
type: ColumnType.Boolean,
|
|
330
|
+
default: false,
|
|
331
|
+
})
|
|
332
|
+
public alertBySlack?: boolean = undefined;
|
|
333
|
+
|
|
334
|
+
@ColumnAccessControl({
|
|
335
|
+
create: [Permission.CurrentUser],
|
|
336
|
+
read: [Permission.CurrentUser],
|
|
337
|
+
update: [Permission.CurrentUser],
|
|
338
|
+
})
|
|
339
|
+
@TableColumn({
|
|
340
|
+
isDefaultValueColumn: true,
|
|
341
|
+
type: TableColumnType.Boolean,
|
|
342
|
+
defaultValue: false,
|
|
343
|
+
example: false,
|
|
344
|
+
})
|
|
345
|
+
@Column({
|
|
346
|
+
type: ColumnType.Boolean,
|
|
347
|
+
default: false,
|
|
348
|
+
})
|
|
349
|
+
public alertByMicrosoftTeams?: boolean = undefined;
|
|
350
|
+
|
|
317
351
|
@ColumnAccessControl({
|
|
318
352
|
create: [Permission.CurrentUser],
|
|
319
353
|
read: [Permission.CurrentUser],
|
|
@@ -16,6 +16,8 @@ import UserPush from "./UserPush";
|
|
|
16
16
|
import UserOnCallLog from "./UserOnCallLog";
|
|
17
17
|
import UserSMS from "./UserSMS";
|
|
18
18
|
import UserTelegram from "./UserTelegram";
|
|
19
|
+
import UserSlack from "./UserSlack";
|
|
20
|
+
import UserMicrosoftTeams from "./UserMicrosoftTeams";
|
|
19
21
|
import UserWebhook from "./UserWebhook";
|
|
20
22
|
import UserWhatsApp from "./UserWhatsApp";
|
|
21
23
|
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
@@ -1057,6 +1059,99 @@ export default class UserOnCallLogTimeline extends BaseModel {
|
|
|
1057
1059
|
})
|
|
1058
1060
|
public userTelegramId?: ObjectID = undefined;
|
|
1059
1061
|
|
|
1062
|
+
@ColumnAccessControl({
|
|
1063
|
+
create: [],
|
|
1064
|
+
read: [Permission.CurrentUser],
|
|
1065
|
+
update: [],
|
|
1066
|
+
})
|
|
1067
|
+
@TableColumn({
|
|
1068
|
+
manyToOneRelationColumn: "userSlackId",
|
|
1069
|
+
type: TableColumnType.Entity,
|
|
1070
|
+
modelType: UserSlack,
|
|
1071
|
+
title: "User Slack",
|
|
1072
|
+
description: "Relation to User Slack Resource in which this object belongs",
|
|
1073
|
+
})
|
|
1074
|
+
@ManyToOne(
|
|
1075
|
+
() => {
|
|
1076
|
+
return UserSlack;
|
|
1077
|
+
},
|
|
1078
|
+
{
|
|
1079
|
+
eager: false,
|
|
1080
|
+
nullable: true,
|
|
1081
|
+
onDelete: "CASCADE",
|
|
1082
|
+
orphanedRowAction: "nullify",
|
|
1083
|
+
},
|
|
1084
|
+
)
|
|
1085
|
+
@JoinColumn({ name: "userSlackId" })
|
|
1086
|
+
public userSlack?: UserSlack = undefined;
|
|
1087
|
+
|
|
1088
|
+
@ColumnAccessControl({
|
|
1089
|
+
create: [],
|
|
1090
|
+
read: [Permission.CurrentUser],
|
|
1091
|
+
update: [],
|
|
1092
|
+
})
|
|
1093
|
+
@Index()
|
|
1094
|
+
@TableColumn({
|
|
1095
|
+
type: TableColumnType.ObjectID,
|
|
1096
|
+
required: false,
|
|
1097
|
+
canReadOnRelationQuery: true,
|
|
1098
|
+
title: "User Slack ID",
|
|
1099
|
+
description: "ID of User Slack in which this object belongs",
|
|
1100
|
+
})
|
|
1101
|
+
@Column({
|
|
1102
|
+
type: ColumnType.ObjectID,
|
|
1103
|
+
nullable: true,
|
|
1104
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
1105
|
+
})
|
|
1106
|
+
public userSlackId?: ObjectID = undefined;
|
|
1107
|
+
|
|
1108
|
+
@ColumnAccessControl({
|
|
1109
|
+
create: [],
|
|
1110
|
+
read: [Permission.CurrentUser],
|
|
1111
|
+
update: [],
|
|
1112
|
+
})
|
|
1113
|
+
@TableColumn({
|
|
1114
|
+
manyToOneRelationColumn: "userMicrosoftTeamsId",
|
|
1115
|
+
type: TableColumnType.Entity,
|
|
1116
|
+
modelType: UserMicrosoftTeams,
|
|
1117
|
+
title: "User Microsoft Teams",
|
|
1118
|
+
description:
|
|
1119
|
+
"Relation to User Microsoft Teams Resource in which this object belongs",
|
|
1120
|
+
})
|
|
1121
|
+
@ManyToOne(
|
|
1122
|
+
() => {
|
|
1123
|
+
return UserMicrosoftTeams;
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
eager: false,
|
|
1127
|
+
nullable: true,
|
|
1128
|
+
onDelete: "CASCADE",
|
|
1129
|
+
orphanedRowAction: "nullify",
|
|
1130
|
+
},
|
|
1131
|
+
)
|
|
1132
|
+
@JoinColumn({ name: "userMicrosoftTeamsId" })
|
|
1133
|
+
public userMicrosoftTeams?: UserMicrosoftTeams = undefined;
|
|
1134
|
+
|
|
1135
|
+
@ColumnAccessControl({
|
|
1136
|
+
create: [],
|
|
1137
|
+
read: [Permission.CurrentUser],
|
|
1138
|
+
update: [],
|
|
1139
|
+
})
|
|
1140
|
+
@Index()
|
|
1141
|
+
@TableColumn({
|
|
1142
|
+
type: TableColumnType.ObjectID,
|
|
1143
|
+
required: false,
|
|
1144
|
+
canReadOnRelationQuery: true,
|
|
1145
|
+
title: "User Microsoft Teams ID",
|
|
1146
|
+
description: "ID of User Microsoft Teams in which this object belongs",
|
|
1147
|
+
})
|
|
1148
|
+
@Column({
|
|
1149
|
+
type: ColumnType.ObjectID,
|
|
1150
|
+
nullable: true,
|
|
1151
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
1152
|
+
})
|
|
1153
|
+
public userMicrosoftTeamsId?: ObjectID = undefined;
|
|
1154
|
+
|
|
1060
1155
|
@ColumnAccessControl({
|
|
1061
1156
|
create: [],
|
|
1062
1157
|
read: [Permission.CurrentUser],
|
|
@@ -0,0 +1,341 @@
|
|
|
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 Slack member id every project
|
|
27
|
+
* member's pages are delivered to. Do not add administrator permissions here -
|
|
28
|
+
* OnCallReadinessService returns the masked, admin-sanctioned view instead.
|
|
29
|
+
*
|
|
30
|
+
* Unlike Telegram/SMS/WhatsApp there is no verification code: a row is only
|
|
31
|
+
* ever created from an existing, OAuth-established workspace link
|
|
32
|
+
* (WorkspaceUserAuthToken), so creation IS verification. UserSlackService
|
|
33
|
+
* enforces that and stamps the Slack identifiers server-side.
|
|
34
|
+
*/
|
|
35
|
+
@TenantColumn("projectId")
|
|
36
|
+
@AllowAccessIfSubscriptionIsUnpaid()
|
|
37
|
+
@TableAccessControl({
|
|
38
|
+
create: [Permission.CurrentUser],
|
|
39
|
+
read: [Permission.CurrentUser],
|
|
40
|
+
delete: [Permission.CurrentUser],
|
|
41
|
+
update: [Permission.CurrentUser],
|
|
42
|
+
})
|
|
43
|
+
@CrudApiEndpoint(new Route("/user-slack"))
|
|
44
|
+
@Entity({
|
|
45
|
+
name: "UserSlack",
|
|
46
|
+
})
|
|
47
|
+
@TableMetadata({
|
|
48
|
+
tableName: "UserSlack",
|
|
49
|
+
singularName: "Slack Account",
|
|
50
|
+
pluralName: "Slack Accounts",
|
|
51
|
+
icon: IconProp.Slack,
|
|
52
|
+
tableDescription: "Slack accounts used for Slack notifications.",
|
|
53
|
+
})
|
|
54
|
+
@CurrentUserCanAccessRecordBy("userId")
|
|
55
|
+
class UserSlack extends BaseModel {
|
|
56
|
+
@ColumnAccessControl({
|
|
57
|
+
create: [Permission.CurrentUser],
|
|
58
|
+
read: [Permission.CurrentUser],
|
|
59
|
+
update: [],
|
|
60
|
+
})
|
|
61
|
+
@TableColumn({
|
|
62
|
+
manyToOneRelationColumn: "projectId",
|
|
63
|
+
type: TableColumnType.Entity,
|
|
64
|
+
modelType: Project,
|
|
65
|
+
title: "Project",
|
|
66
|
+
description: "Relation to Project Resource in which this object belongs",
|
|
67
|
+
})
|
|
68
|
+
@ManyToOne(
|
|
69
|
+
() => {
|
|
70
|
+
return Project;
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
eager: false,
|
|
74
|
+
nullable: true,
|
|
75
|
+
onDelete: "CASCADE",
|
|
76
|
+
orphanedRowAction: "nullify",
|
|
77
|
+
},
|
|
78
|
+
)
|
|
79
|
+
@JoinColumn({ name: "projectId" })
|
|
80
|
+
public project?: Project = undefined;
|
|
81
|
+
|
|
82
|
+
@ColumnAccessControl({
|
|
83
|
+
create: [Permission.CurrentUser],
|
|
84
|
+
read: [Permission.CurrentUser],
|
|
85
|
+
update: [],
|
|
86
|
+
})
|
|
87
|
+
@Index()
|
|
88
|
+
@TableColumn({
|
|
89
|
+
type: TableColumnType.ObjectID,
|
|
90
|
+
required: true,
|
|
91
|
+
canReadOnRelationQuery: true,
|
|
92
|
+
title: "Project ID",
|
|
93
|
+
description: "ID of your OneUptime Project in which this object belongs",
|
|
94
|
+
})
|
|
95
|
+
@Column({
|
|
96
|
+
type: ColumnType.ObjectID,
|
|
97
|
+
nullable: false,
|
|
98
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
99
|
+
})
|
|
100
|
+
public projectId?: ObjectID = undefined;
|
|
101
|
+
|
|
102
|
+
@ColumnAccessControl({
|
|
103
|
+
/*
|
|
104
|
+
* CurrentUser here does NOT mean the client may choose the value: the
|
|
105
|
+
* service hook refuses any non-root payload that carries these columns
|
|
106
|
+
* and then stamps them itself, and hooks run BEFORE the column
|
|
107
|
+
* permission check (DatabaseService.create). The entry exists because
|
|
108
|
+
* that same check runs on the STAMPED data - with an empty list the
|
|
109
|
+
* server's own write is refused and no user can add this method at all.
|
|
110
|
+
* Same shape as UserWebAuthn's server-stamped isVerified.
|
|
111
|
+
*/
|
|
112
|
+
create: [Permission.CurrentUser],
|
|
113
|
+
read: [Permission.CurrentUser],
|
|
114
|
+
update: [],
|
|
115
|
+
})
|
|
116
|
+
@Index()
|
|
117
|
+
/*
|
|
118
|
+
* The Slack member id (e.g. U0123ABCD) the project's bot delivers direct
|
|
119
|
+
* messages to. Holding it is enough to address bot messages at that person,
|
|
120
|
+
* so it is a delivery target and not a label. Captured server-side from the
|
|
121
|
+
* user's own WorkspaceUserAuthToken - never writable by the client.
|
|
122
|
+
*/
|
|
123
|
+
@OwnerOnlyColumn()
|
|
124
|
+
@TableColumn({
|
|
125
|
+
title: "Slack User ID",
|
|
126
|
+
required: false,
|
|
127
|
+
unique: false,
|
|
128
|
+
type: TableColumnType.ShortText,
|
|
129
|
+
canReadOnRelationQuery: true,
|
|
130
|
+
description:
|
|
131
|
+
"Slack member ID captured from your connected Slack account. Populated automatically.",
|
|
132
|
+
})
|
|
133
|
+
@Column({
|
|
134
|
+
type: ColumnType.ShortText,
|
|
135
|
+
length: ColumnLength.ShortText,
|
|
136
|
+
unique: false,
|
|
137
|
+
nullable: true,
|
|
138
|
+
})
|
|
139
|
+
public slackUserId?: string = undefined;
|
|
140
|
+
|
|
141
|
+
@ColumnAccessControl({
|
|
142
|
+
/*
|
|
143
|
+
* CurrentUser here does NOT mean the client may choose the value: the
|
|
144
|
+
* service hook refuses any non-root payload that carries these columns
|
|
145
|
+
* and then stamps them itself, and hooks run BEFORE the column
|
|
146
|
+
* permission check (DatabaseService.create). The entry exists because
|
|
147
|
+
* that same check runs on the STAMPED data - with an empty list the
|
|
148
|
+
* server's own write is refused and no user can add this method at all.
|
|
149
|
+
* Same shape as UserWebAuthn's server-stamped isVerified.
|
|
150
|
+
*/
|
|
151
|
+
create: [Permission.CurrentUser],
|
|
152
|
+
read: [Permission.CurrentUser],
|
|
153
|
+
update: [],
|
|
154
|
+
})
|
|
155
|
+
/*
|
|
156
|
+
* The person's Slack display name at the time the method was added. Only a
|
|
157
|
+
* label for the row, but it is still their identity in an outside workspace,
|
|
158
|
+
* so it stays owner-only like the Telegram handle.
|
|
159
|
+
*/
|
|
160
|
+
@OwnerOnlyColumn()
|
|
161
|
+
@TableColumn({
|
|
162
|
+
title: "Slack Username",
|
|
163
|
+
required: false,
|
|
164
|
+
unique: false,
|
|
165
|
+
type: TableColumnType.ShortText,
|
|
166
|
+
canReadOnRelationQuery: true,
|
|
167
|
+
description:
|
|
168
|
+
"Slack username captured from your connected Slack account. Populated automatically.",
|
|
169
|
+
})
|
|
170
|
+
@Column({
|
|
171
|
+
type: ColumnType.ShortText,
|
|
172
|
+
length: ColumnLength.ShortText,
|
|
173
|
+
unique: false,
|
|
174
|
+
nullable: true,
|
|
175
|
+
})
|
|
176
|
+
public slackUserName?: string = undefined;
|
|
177
|
+
|
|
178
|
+
@ColumnAccessControl({
|
|
179
|
+
create: [Permission.CurrentUser],
|
|
180
|
+
read: [Permission.CurrentUser],
|
|
181
|
+
update: [],
|
|
182
|
+
})
|
|
183
|
+
@TableColumn({
|
|
184
|
+
manyToOneRelationColumn: "user",
|
|
185
|
+
type: TableColumnType.Entity,
|
|
186
|
+
modelType: User,
|
|
187
|
+
title: "User",
|
|
188
|
+
description: "Relation to User who this Slack account belongs to",
|
|
189
|
+
})
|
|
190
|
+
@ManyToOne(
|
|
191
|
+
() => {
|
|
192
|
+
return User;
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
eager: false,
|
|
196
|
+
nullable: true,
|
|
197
|
+
onDelete: "CASCADE",
|
|
198
|
+
orphanedRowAction: "nullify",
|
|
199
|
+
},
|
|
200
|
+
)
|
|
201
|
+
@JoinColumn({ name: "userId" })
|
|
202
|
+
public user?: User = undefined;
|
|
203
|
+
|
|
204
|
+
@ColumnAccessControl({
|
|
205
|
+
create: [Permission.CurrentUser],
|
|
206
|
+
read: [Permission.CurrentUser],
|
|
207
|
+
update: [],
|
|
208
|
+
})
|
|
209
|
+
@TableColumn({
|
|
210
|
+
type: TableColumnType.ObjectID,
|
|
211
|
+
title: "User ID",
|
|
212
|
+
description: "User ID who this Slack account belongs to",
|
|
213
|
+
})
|
|
214
|
+
@Column({
|
|
215
|
+
type: ColumnType.ObjectID,
|
|
216
|
+
nullable: true,
|
|
217
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
218
|
+
})
|
|
219
|
+
@Index()
|
|
220
|
+
public userId?: ObjectID = undefined;
|
|
221
|
+
|
|
222
|
+
@ColumnAccessControl({
|
|
223
|
+
create: [Permission.CurrentUser],
|
|
224
|
+
read: [Permission.CurrentUser],
|
|
225
|
+
update: [],
|
|
226
|
+
})
|
|
227
|
+
@TableColumn({
|
|
228
|
+
manyToOneRelationColumn: "createdByUserId",
|
|
229
|
+
type: TableColumnType.Entity,
|
|
230
|
+
modelType: User,
|
|
231
|
+
title: "Created by User",
|
|
232
|
+
description:
|
|
233
|
+
"Relation to User who created this object (if this object was created by a User)",
|
|
234
|
+
})
|
|
235
|
+
@ManyToOne(
|
|
236
|
+
() => {
|
|
237
|
+
return User;
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
eager: false,
|
|
241
|
+
nullable: true,
|
|
242
|
+
onDelete: "SET NULL",
|
|
243
|
+
orphanedRowAction: "nullify",
|
|
244
|
+
},
|
|
245
|
+
)
|
|
246
|
+
@JoinColumn({ name: "createdByUserId" })
|
|
247
|
+
public createdByUser?: User = undefined;
|
|
248
|
+
|
|
249
|
+
@ColumnAccessControl({
|
|
250
|
+
create: [Permission.CurrentUser],
|
|
251
|
+
read: [Permission.CurrentUser],
|
|
252
|
+
update: [],
|
|
253
|
+
})
|
|
254
|
+
@TableColumn({
|
|
255
|
+
type: TableColumnType.ObjectID,
|
|
256
|
+
title: "Created by User ID",
|
|
257
|
+
description:
|
|
258
|
+
"User ID who created this object (if this object was created by a User)",
|
|
259
|
+
})
|
|
260
|
+
@Column({
|
|
261
|
+
type: ColumnType.ObjectID,
|
|
262
|
+
nullable: true,
|
|
263
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
264
|
+
})
|
|
265
|
+
public createdByUserId?: ObjectID = undefined;
|
|
266
|
+
|
|
267
|
+
@ColumnAccessControl({
|
|
268
|
+
create: [],
|
|
269
|
+
read: [],
|
|
270
|
+
update: [],
|
|
271
|
+
})
|
|
272
|
+
@TableColumn({
|
|
273
|
+
manyToOneRelationColumn: "deletedByUserId",
|
|
274
|
+
type: TableColumnType.Entity,
|
|
275
|
+
title: "Deleted by User",
|
|
276
|
+
modelType: User,
|
|
277
|
+
description:
|
|
278
|
+
"Relation to User who deleted this object (if this object was deleted by a User)",
|
|
279
|
+
})
|
|
280
|
+
@ManyToOne(
|
|
281
|
+
() => {
|
|
282
|
+
return User;
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
cascade: false,
|
|
286
|
+
eager: false,
|
|
287
|
+
nullable: true,
|
|
288
|
+
onDelete: "SET NULL",
|
|
289
|
+
orphanedRowAction: "nullify",
|
|
290
|
+
},
|
|
291
|
+
)
|
|
292
|
+
@JoinColumn({ name: "deletedByUserId" })
|
|
293
|
+
public deletedByUser?: User = undefined;
|
|
294
|
+
|
|
295
|
+
@ColumnAccessControl({
|
|
296
|
+
create: [],
|
|
297
|
+
read: [],
|
|
298
|
+
update: [],
|
|
299
|
+
})
|
|
300
|
+
@TableColumn({
|
|
301
|
+
type: TableColumnType.ObjectID,
|
|
302
|
+
title: "Deleted by User ID",
|
|
303
|
+
description:
|
|
304
|
+
"User ID who deleted this object (if this object was deleted by a User)",
|
|
305
|
+
})
|
|
306
|
+
@Column({
|
|
307
|
+
type: ColumnType.ObjectID,
|
|
308
|
+
nullable: true,
|
|
309
|
+
transformer: ObjectID.getDatabaseTransformer(),
|
|
310
|
+
})
|
|
311
|
+
public deletedByUserId?: ObjectID = undefined;
|
|
312
|
+
|
|
313
|
+
@ColumnAccessControl({
|
|
314
|
+
/*
|
|
315
|
+
* CurrentUser here does NOT mean the client may choose the value: the
|
|
316
|
+
* service hook refuses any non-root payload that carries these columns
|
|
317
|
+
* and then stamps them itself, and hooks run BEFORE the column
|
|
318
|
+
* permission check (DatabaseService.create). The entry exists because
|
|
319
|
+
* that same check runs on the STAMPED data - with an empty list the
|
|
320
|
+
* server's own write is refused and no user can add this method at all.
|
|
321
|
+
* Same shape as UserWebAuthn's server-stamped isVerified.
|
|
322
|
+
*/
|
|
323
|
+
create: [Permission.CurrentUser],
|
|
324
|
+
read: [Permission.CurrentUser],
|
|
325
|
+
update: [],
|
|
326
|
+
})
|
|
327
|
+
@TableColumn({
|
|
328
|
+
title: "Is Verified",
|
|
329
|
+
description: "Is this Slack account verified?",
|
|
330
|
+
isDefaultValueColumn: true,
|
|
331
|
+
type: TableColumnType.Boolean,
|
|
332
|
+
defaultValue: false,
|
|
333
|
+
})
|
|
334
|
+
@Column({
|
|
335
|
+
type: ColumnType.Boolean,
|
|
336
|
+
default: false,
|
|
337
|
+
})
|
|
338
|
+
public isVerified?: boolean = undefined;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export default UserSlack;
|
|
@@ -34,6 +34,15 @@ export interface MicrosoftTeamsChat {
|
|
|
34
34
|
chatType: MicrosoftTeamsChatType;
|
|
35
35
|
serviceUrl?: string | undefined; // Bot Framework service URL captured when the bot was added.
|
|
36
36
|
addedAt?: string | undefined;
|
|
37
|
+
/*
|
|
38
|
+
* Microsoft Entra object ids of the human members, captured from the chat
|
|
39
|
+
* roster. What lets a personal chat be matched back to the OneUptime user
|
|
40
|
+
* it belongs to (WorkspaceUserAuthToken.workspaceUserId is the same id), so
|
|
41
|
+
* user direct-message notifications can reuse the existing chat instead of
|
|
42
|
+
* creating a new conversation. Absent on records captured before this
|
|
43
|
+
* shipped.
|
|
44
|
+
*/
|
|
45
|
+
memberAadObjectIds?: Array<string> | undefined;
|
|
37
46
|
}
|
|
38
47
|
|
|
39
48
|
/*
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import EnterpriseLicense from "../../Models/DatabaseModels/EnterpriseLicense";
|
|
2
2
|
import EnterpriseLicenseInstance from "../../Models/DatabaseModels/EnterpriseLicenseInstance";
|
|
3
3
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
4
|
-
import { JSONObject } from "../../Types/JSON";
|
|
5
4
|
import PartialEntity from "../../Types/Database/PartialEntity";
|
|
6
5
|
import EnterpriseLicenseInstanceSummary from "../../Types/EnterpriseLicense/EnterpriseLicenseInstanceSummary";
|
|
7
6
|
import EnterpriseLicenseUsageUtil from "../../Utils/EnterpriseLicense/EnterpriseLicenseUsage";
|
|
@@ -26,6 +25,20 @@ import {
|
|
|
26
25
|
import BaseAPI from "./BaseAPI";
|
|
27
26
|
// import { Host } from "../EnvironmentConfig";
|
|
28
27
|
|
|
28
|
+
/*
|
|
29
|
+
* The license state every installation of a license key mirrors locally.
|
|
30
|
+
* Returned by both /validate and /report-user-count so that the daily report
|
|
31
|
+
* keeps a self-hosted installation current on its own.
|
|
32
|
+
*/
|
|
33
|
+
export interface LicenseTerms {
|
|
34
|
+
companyName: string;
|
|
35
|
+
// ISO 8601, or null for a license with no expiry set.
|
|
36
|
+
expiresAt: string | null;
|
|
37
|
+
licenseKey: string;
|
|
38
|
+
// Null means the license carries no seat limit.
|
|
39
|
+
userLimit: number | null;
|
|
40
|
+
}
|
|
41
|
+
|
|
29
42
|
export interface LicenseInstanceUpsert {
|
|
30
43
|
licenseId: ObjectID;
|
|
31
44
|
instanceId: string;
|
|
@@ -137,24 +150,15 @@ export default class EnterpriseLicenseAPI extends BaseAPI<
|
|
|
137
150
|
const instances: Array<EnterpriseLicenseInstance> =
|
|
138
151
|
await this.findLicenseInstances(license.id!);
|
|
139
152
|
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
licenseKey: license.licenseKey || "",
|
|
144
|
-
userLimit:
|
|
145
|
-
typeof license.userLimit === "number" ? license.userLimit : null,
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const token: string = JSONWebToken.signJsonPayload(
|
|
149
|
-
payload,
|
|
150
|
-
Math.max(secondsUntilExpiry, 1),
|
|
151
|
-
);
|
|
153
|
+
const terms: LicenseTerms = this.getLicenseTerms(license);
|
|
154
|
+
|
|
155
|
+
const token: string | null = this.signLicenseToken(license);
|
|
152
156
|
|
|
153
157
|
return Response.sendJsonObjectResponse(req, res, {
|
|
154
|
-
companyName:
|
|
155
|
-
expiresAt:
|
|
156
|
-
licenseKey:
|
|
157
|
-
userLimit:
|
|
158
|
+
companyName: terms.companyName,
|
|
159
|
+
expiresAt: terms.expiresAt,
|
|
160
|
+
licenseKey: terms.licenseKey,
|
|
161
|
+
userLimit: terms.userLimit,
|
|
158
162
|
currentUserCount:
|
|
159
163
|
typeof license.currentUserCount === "number"
|
|
160
164
|
? license.currentUserCount
|
|
@@ -202,8 +206,19 @@ export default class EnterpriseLicenseAPI extends BaseAPI<
|
|
|
202
206
|
query: {
|
|
203
207
|
licenseKey: licenseKey,
|
|
204
208
|
},
|
|
209
|
+
/*
|
|
210
|
+
* The full set of terms, not just the usage columns: this
|
|
211
|
+
* response is what a self-hosted installation mirrors into its
|
|
212
|
+
* own GlobalConfig every day, so anything it is missing here is
|
|
213
|
+
* a field the customer keeps the stale value of until somebody
|
|
214
|
+
* re-types the license key by hand. Same indexed lookup either
|
|
215
|
+
* way.
|
|
216
|
+
*/
|
|
205
217
|
select: {
|
|
206
218
|
_id: true,
|
|
219
|
+
companyName: true,
|
|
220
|
+
expiresAt: true,
|
|
221
|
+
licenseKey: true,
|
|
207
222
|
userLimit: true,
|
|
208
223
|
isEvaluationLicense: true,
|
|
209
224
|
},
|
|
@@ -282,13 +297,25 @@ export default class EnterpriseLicenseAPI extends BaseAPI<
|
|
|
282
297
|
});
|
|
283
298
|
}
|
|
284
299
|
|
|
300
|
+
const terms: LicenseTerms = this.getLicenseTerms(license);
|
|
301
|
+
|
|
285
302
|
return Response.sendJsonObjectResponse(req, res, {
|
|
303
|
+
companyName: terms.companyName,
|
|
304
|
+
expiresAt: terms.expiresAt,
|
|
305
|
+
licenseKey: terms.licenseKey,
|
|
306
|
+
userLimit: terms.userLimit,
|
|
286
307
|
currentUserCount: currentUserCount,
|
|
287
308
|
userCountUpdatedAt: reportedAt.toISOString(),
|
|
288
|
-
userLimit:
|
|
289
|
-
typeof license.userLimit === "number" ? license.userLimit : null,
|
|
290
309
|
isEvaluationLicense: Boolean(license.isEvaluationLicense),
|
|
291
310
|
instances: this.getInstanceSummaries(instances),
|
|
311
|
+
/*
|
|
312
|
+
* Null once the license has expired. Unlike /validate this route
|
|
313
|
+
* does not reject an expired license - the instance is still
|
|
314
|
+
* expected to report, and the expiry notification emails are built
|
|
315
|
+
* from what it reports - but it must not keep being handed a fresh
|
|
316
|
+
* token, and the expiresAt above is what tells it the truth.
|
|
317
|
+
*/
|
|
318
|
+
token: this.signLicenseToken(license),
|
|
292
319
|
});
|
|
293
320
|
} catch (err) {
|
|
294
321
|
next(err);
|
|
@@ -297,6 +324,54 @@ export default class EnterpriseLicenseAPI extends BaseAPI<
|
|
|
297
324
|
);
|
|
298
325
|
}
|
|
299
326
|
|
|
327
|
+
/*
|
|
328
|
+
* The license terms a self-hosted installation mirrors locally. Built in one
|
|
329
|
+
* place so /validate and /report-user-count cannot drift: the seat limit was
|
|
330
|
+
* missing from what an instance could refresh for exactly as long as the two
|
|
331
|
+
* responses were written out by hand, separately.
|
|
332
|
+
*/
|
|
333
|
+
private getLicenseTerms(license: EnterpriseLicense): LicenseTerms {
|
|
334
|
+
return {
|
|
335
|
+
companyName: license.companyName || "",
|
|
336
|
+
expiresAt: license.expiresAt ? license.expiresAt.toISOString() : null,
|
|
337
|
+
licenseKey: license.licenseKey || "",
|
|
338
|
+
userLimit:
|
|
339
|
+
typeof license.userLimit === "number" ? license.userLimit : null,
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/*
|
|
344
|
+
* Signed with the license server's own secret, so it is opaque to the
|
|
345
|
+
* installation holding it - it is the proof that oneuptime.com recognized
|
|
346
|
+
* the key, and the instance only checks that it exists. An expired license
|
|
347
|
+
* gets none, which is why this returns null rather than a short-lived token.
|
|
348
|
+
*/
|
|
349
|
+
private signLicenseToken(license: EnterpriseLicense): string | null {
|
|
350
|
+
if (!license.expiresAt) {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const secondsUntilExpiry: number = Math.floor(
|
|
355
|
+
(license.expiresAt.getTime() - Date.now()) / 1000,
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
if (secondsUntilExpiry <= 0) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const terms: LicenseTerms = this.getLicenseTerms(license);
|
|
363
|
+
|
|
364
|
+
return JSONWebToken.signJsonPayload(
|
|
365
|
+
{
|
|
366
|
+
companyName: terms.companyName,
|
|
367
|
+
expiresAt: terms.expiresAt,
|
|
368
|
+
licenseKey: terms.licenseKey,
|
|
369
|
+
userLimit: terms.userLimit,
|
|
370
|
+
},
|
|
371
|
+
Math.max(secondsUntilExpiry, 1),
|
|
372
|
+
);
|
|
373
|
+
}
|
|
374
|
+
|
|
300
375
|
private parseShortText(value: unknown): string {
|
|
301
376
|
if (typeof value !== "string") {
|
|
302
377
|
return "";
|