@oneuptime/common 12.0.18 → 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/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/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/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/UI/Utils/NotificationMethodUtil.test.ts +137 -9
- package/Tests/UI/Utils/PermissionGate.test.ts +105 -0
- 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/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/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
|
@@ -2,6 +2,8 @@ import UserCall from "../../Models/DatabaseModels/UserCall";
|
|
|
2
2
|
import UserPush from "../../Models/DatabaseModels/UserPush";
|
|
3
3
|
import UserSMS from "../../Models/DatabaseModels/UserSMS";
|
|
4
4
|
import UserTelegram from "../../Models/DatabaseModels/UserTelegram";
|
|
5
|
+
import UserSlack from "../../Models/DatabaseModels/UserSlack";
|
|
6
|
+
import UserMicrosoftTeams from "../../Models/DatabaseModels/UserMicrosoftTeams";
|
|
5
7
|
import UserWebhook from "../../Models/DatabaseModels/UserWebhook";
|
|
6
8
|
import UserWhatsApp from "../../Models/DatabaseModels/UserWhatsApp";
|
|
7
9
|
/*
|
|
@@ -19,6 +21,16 @@ const NOTIFICATION_METHOD_RELATIONS = [
|
|
|
19
21
|
title: "Telegram",
|
|
20
22
|
columns: ["telegramUserHandle", "telegramChatId"],
|
|
21
23
|
},
|
|
24
|
+
{
|
|
25
|
+
relationName: "userSlack",
|
|
26
|
+
title: "Slack",
|
|
27
|
+
columns: ["slackUserName", "slackUserId"],
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
relationName: "userMicrosoftTeams",
|
|
31
|
+
title: "Microsoft Teams",
|
|
32
|
+
columns: ["microsoftTeamsUserName", "microsoftTeamsUserId"],
|
|
33
|
+
},
|
|
22
34
|
/*
|
|
23
35
|
* Only `name` is read here. A webhook URL is a bearer credential for
|
|
24
36
|
* Slack/Discord/Teams style hooks, so it is deliberately never selected into
|
|
@@ -97,6 +109,18 @@ export default class NotificationMethodUtil {
|
|
|
97
109
|
NotificationMethodUtil.readColumn(model, "telegramChatId") ||
|
|
98
110
|
"Unknown Chat"));
|
|
99
111
|
}
|
|
112
|
+
if (model instanceof UserSlack) {
|
|
113
|
+
return ("Slack: " +
|
|
114
|
+
(NotificationMethodUtil.readColumn(model, "slackUserName") ||
|
|
115
|
+
NotificationMethodUtil.readColumn(model, "slackUserId") ||
|
|
116
|
+
"Unknown Account"));
|
|
117
|
+
}
|
|
118
|
+
if (model instanceof UserMicrosoftTeams) {
|
|
119
|
+
return ("Microsoft Teams: " +
|
|
120
|
+
(NotificationMethodUtil.readColumn(model, "microsoftTeamsUserName") ||
|
|
121
|
+
NotificationMethodUtil.readColumn(model, "microsoftTeamsUserId") ||
|
|
122
|
+
"Unknown Account"));
|
|
123
|
+
}
|
|
100
124
|
const identifier = NotificationMethodUtil.readColumn(model, "phone") ||
|
|
101
125
|
NotificationMethodUtil.readColumn(model, "email") ||
|
|
102
126
|
"";
|
|
@@ -113,7 +137,7 @@ export default class NotificationMethodUtil {
|
|
|
113
137
|
}
|
|
114
138
|
/*
|
|
115
139
|
* Maps the id chosen in the dropdown back onto the rule being created. The
|
|
116
|
-
* dropdown is single-select, so at most one of the
|
|
140
|
+
* dropdown is single-select, so at most one of the nine foreign keys is set.
|
|
117
141
|
* An id that matches nothing leaves the rule untouched, and the server then
|
|
118
142
|
* rejects the create as having no notification method.
|
|
119
143
|
*/
|
|
@@ -149,6 +173,12 @@ export default class NotificationMethodUtil {
|
|
|
149
173
|
assignById(models.userTelegrams, (id) => {
|
|
150
174
|
rule.userTelegramId = id;
|
|
151
175
|
});
|
|
176
|
+
assignById(models.userSlacks, (id) => {
|
|
177
|
+
rule.userSlackId = id;
|
|
178
|
+
});
|
|
179
|
+
assignById(models.userMicrosoftTeamsAccounts, (id) => {
|
|
180
|
+
rule.userMicrosoftTeamsId = id;
|
|
181
|
+
});
|
|
152
182
|
assignById(models.userWebhooks, (id) => {
|
|
153
183
|
rule.userWebhookId = id;
|
|
154
184
|
});
|
|
@@ -166,6 +196,8 @@ export default class NotificationMethodUtil {
|
|
|
166
196
|
...models.userPush,
|
|
167
197
|
...models.userWhatsApps,
|
|
168
198
|
...models.userTelegrams,
|
|
199
|
+
...models.userSlacks,
|
|
200
|
+
...models.userMicrosoftTeamsAccounts,
|
|
169
201
|
...models.userWebhooks,
|
|
170
202
|
];
|
|
171
203
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NotificationMethodUtil.js","sourceRoot":"","sources":["../../../../UI/Utils/NotificationMethodUtil.ts"],"names":[],"mappings":"AAGA,OAAO,QAAQ,MAAM,sCAAsC,CAAC;AAG5D,OAAO,QAAQ,MAAM,sCAAsC,CAAC;AAC5D,OAAO,OAAO,MAAM,qCAAqC,CAAC;AAC1D,OAAO,YAAY,MAAM,0CAA0C,CAAC;AACpE,OAAO,WAAW,MAAM,yCAAyC,CAAC;AAClE,OAAO,YAAY,MAAM,0CAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"NotificationMethodUtil.js","sourceRoot":"","sources":["../../../../UI/Utils/NotificationMethodUtil.ts"],"names":[],"mappings":"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"}
|
|
@@ -156,6 +156,38 @@ export default class PermissionGate {
|
|
|
156
156
|
// Locked. The tooltip says which permission is missing.
|
|
157
157
|
} });
|
|
158
158
|
}
|
|
159
|
+
/*
|
|
160
|
+
* Whether the signed-in user may SELECT a column.
|
|
161
|
+
*
|
|
162
|
+
* Column access control is enforced differently from record access control:
|
|
163
|
+
* asking for a column you cannot read is not degraded, it is fatal.
|
|
164
|
+
* ColumnPermission throws `User is not allowed to read on <column> column of
|
|
165
|
+
* <model>` and the whole request fails, so one unreadable field in a select
|
|
166
|
+
* takes down the entire page rather than blanking one value. That is why
|
|
167
|
+
* ModelAction has no column-level members (see the comment on the enum) and
|
|
168
|
+
* why callers must ask this BEFORE building the select, not after.
|
|
169
|
+
*
|
|
170
|
+
* Deliberately fails closed. When the permission snapshot has not landed yet
|
|
171
|
+
* this returns false and the caller omits the field: the page renders
|
|
172
|
+
* without that one value, which is recoverable. Failing open would send the
|
|
173
|
+
* column anyway and hard-fail the request, which is not.
|
|
174
|
+
*
|
|
175
|
+
* A column with no declared read ACL is readable - there is nothing to
|
|
176
|
+
* enforce, and ColumnPermission agrees.
|
|
177
|
+
*/
|
|
178
|
+
static canReadColumn(model, columnName, options) {
|
|
179
|
+
var _a;
|
|
180
|
+
if (User.isMasterAdmin()) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
const accessControl = model.getColumnAccessControlForAllColumns()[columnName];
|
|
184
|
+
const columnPermissions = (accessControl === null || accessControl === void 0 ? void 0 : accessControl.read) || [];
|
|
185
|
+
if (columnPermissions.length === 0) {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
const userPermissions = (_a = options === null || options === void 0 ? void 0 : options.permissions) !== null && _a !== void 0 ? _a : PermissionUtil.getAllPermissions();
|
|
189
|
+
return PermissionHelper.doesPermissionsIntersect(userPermissions, columnPermissions);
|
|
190
|
+
}
|
|
159
191
|
/* Test seam - the props lookup is memoized for the lifetime of the page. */
|
|
160
192
|
static clearPermissionPropsCache() {
|
|
161
193
|
permissionPropsCache = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionGate.js","sourceRoot":"","sources":["../../../../UI/Utils/PermissionGate.ts"],"names":[],"mappings":"AAEA,OAAmB,EACjB,gBAAgB,GAEjB,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"PermissionGate.js","sourceRoot":"","sources":["../../../../UI/Utils/PermissionGate.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
import BaseModel from "./DatabaseBaseModel/DatabaseBaseModel";
|
|
2
|
-
import Route from "../../Types/API/Route";
|
|
3
|
-
import ColumnAccessControl from "../../Types/Database/AccessControl/ColumnAccessControl";
|
|
4
|
-
import TableAccessControl from "../../Types/Database/AccessControl/TableAccessControl";
|
|
5
|
-
import ColumnLength from "../../Types/Database/ColumnLength";
|
|
6
|
-
import ColumnType from "../../Types/Database/ColumnType";
|
|
7
|
-
import CrudApiEndpoint from "../../Types/Database/CrudApiEndpoint";
|
|
8
|
-
import TableColumn from "../../Types/Database/TableColumn";
|
|
9
|
-
import TableColumnType from "../../Types/Database/TableColumnType";
|
|
10
|
-
import TableMetadata from "../../Types/Database/TableMetadata";
|
|
11
|
-
import IconProp from "../../Types/Icon/IconProp";
|
|
12
|
-
import { JSONObject } from "../../Types/JSON";
|
|
13
|
-
import ObjectID from "../../Types/ObjectID";
|
|
14
|
-
import { Column, Entity, Index } from "typeorm";
|
|
15
|
-
|
|
16
|
-
/*
|
|
17
|
-
* Internal table (no API access) recording server-confirmed conversions —
|
|
18
|
-
* signups, booked meetings and paid subscriptions — together with the
|
|
19
|
-
* attribution the converting visitor carried (ad click IDs, UTM parameters,
|
|
20
|
-
* first touch) and the status of uploading them to ad platforms. Browser
|
|
21
|
-
* analytics never write this table: rows are written by the Cal.com webhook and
|
|
22
|
-
* the MarketingConversions worker job, which also reads it.
|
|
23
|
-
*
|
|
24
|
-
* This table is deliberately not a CRM. Contact, account and deal records live
|
|
25
|
-
* in Revenue, and nothing here creates or advances them — a booked meeting is
|
|
26
|
-
* a measured conversion, not a qualified opportunity.
|
|
27
|
-
*/
|
|
28
|
-
@TableAccessControl({
|
|
29
|
-
create: [],
|
|
30
|
-
read: [],
|
|
31
|
-
update: [],
|
|
32
|
-
delete: [],
|
|
33
|
-
})
|
|
34
|
-
@CrudApiEndpoint(new Route("/marketing-conversion"))
|
|
35
|
-
@TableMetadata({
|
|
36
|
-
tableName: "MarketingConversion",
|
|
37
|
-
singularName: "Marketing Conversion",
|
|
38
|
-
pluralName: "Marketing Conversions",
|
|
39
|
-
icon: IconProp.ChartBar,
|
|
40
|
-
tableDescription:
|
|
41
|
-
"Server-confirmed conversions (signups, meetings booked, paid subscriptions), the campaign attribution each carried, and their upload status to ad platforms for offline conversion tracking.",
|
|
42
|
-
})
|
|
43
|
-
@Entity({
|
|
44
|
-
name: "MarketingConversion",
|
|
45
|
-
})
|
|
46
|
-
/*
|
|
47
|
-
* One conversion of each type per user/project. Postgres treats NULLs as
|
|
48
|
-
* distinct, so these indexes only constrain rows that actually carry a user or
|
|
49
|
-
* project id — conversion types with neither (a booked meeting from an
|
|
50
|
-
* anonymous visitor) are de-duplicated by their deterministic primary key
|
|
51
|
-
* instead.
|
|
52
|
-
*/
|
|
53
|
-
@Index("uq_marketing_conversion_type_user", ["conversionType", "userId"], {
|
|
54
|
-
unique: true,
|
|
55
|
-
})
|
|
56
|
-
@Index(
|
|
57
|
-
"uq_marketing_conversion_type_project",
|
|
58
|
-
["conversionType", "projectId"],
|
|
59
|
-
{
|
|
60
|
-
unique: true,
|
|
61
|
-
},
|
|
62
|
-
)
|
|
63
|
-
export default class MarketingConversion extends BaseModel {
|
|
64
|
-
@ColumnAccessControl({
|
|
65
|
-
create: [],
|
|
66
|
-
read: [],
|
|
67
|
-
update: [],
|
|
68
|
-
})
|
|
69
|
-
@TableColumn({
|
|
70
|
-
type: TableColumnType.ShortText,
|
|
71
|
-
required: true,
|
|
72
|
-
title: "Conversion Type",
|
|
73
|
-
description: "SignUp, MeetingBooked or PaidSubscription.",
|
|
74
|
-
})
|
|
75
|
-
@Column({
|
|
76
|
-
type: ColumnType.ShortText,
|
|
77
|
-
length: ColumnLength.ShortText,
|
|
78
|
-
nullable: false,
|
|
79
|
-
})
|
|
80
|
-
public conversionType?: string = undefined;
|
|
81
|
-
|
|
82
|
-
@ColumnAccessControl({
|
|
83
|
-
create: [],
|
|
84
|
-
read: [],
|
|
85
|
-
update: [],
|
|
86
|
-
})
|
|
87
|
-
@Index("idx_marketing_conversion_user_id")
|
|
88
|
-
@TableColumn({
|
|
89
|
-
type: TableColumnType.ObjectID,
|
|
90
|
-
required: false,
|
|
91
|
-
title: "User ID",
|
|
92
|
-
description:
|
|
93
|
-
"User this conversion belongs to (SignUp conversions). Null when the conversion has no OneUptime user yet, as with a booked meeting.",
|
|
94
|
-
})
|
|
95
|
-
@Column({
|
|
96
|
-
type: ColumnType.ObjectID,
|
|
97
|
-
nullable: true,
|
|
98
|
-
transformer: ObjectID.getDatabaseTransformer(),
|
|
99
|
-
})
|
|
100
|
-
public userId?: ObjectID = undefined;
|
|
101
|
-
|
|
102
|
-
@ColumnAccessControl({
|
|
103
|
-
create: [],
|
|
104
|
-
read: [],
|
|
105
|
-
update: [],
|
|
106
|
-
})
|
|
107
|
-
@Index("idx_marketing_conversion_project_id")
|
|
108
|
-
@TableColumn({
|
|
109
|
-
type: TableColumnType.ObjectID,
|
|
110
|
-
required: false,
|
|
111
|
-
title: "Project ID",
|
|
112
|
-
description:
|
|
113
|
-
"Project this conversion belongs to (PaidSubscription conversions).",
|
|
114
|
-
})
|
|
115
|
-
@Column({
|
|
116
|
-
type: ColumnType.ObjectID,
|
|
117
|
-
nullable: true,
|
|
118
|
-
transformer: ObjectID.getDatabaseTransformer(),
|
|
119
|
-
})
|
|
120
|
-
public projectId?: ObjectID = undefined;
|
|
121
|
-
|
|
122
|
-
@ColumnAccessControl({
|
|
123
|
-
create: [],
|
|
124
|
-
read: [],
|
|
125
|
-
update: [],
|
|
126
|
-
})
|
|
127
|
-
@TableColumn({
|
|
128
|
-
type: TableColumnType.ShortText,
|
|
129
|
-
required: false,
|
|
130
|
-
title: "Email",
|
|
131
|
-
description:
|
|
132
|
-
"Email of the converting user. Never sent anywhere in the clear: every ad platform receives the SHA-256 in emailHash instead.",
|
|
133
|
-
})
|
|
134
|
-
@Column({
|
|
135
|
-
type: ColumnType.ShortText,
|
|
136
|
-
length: ColumnLength.ShortText,
|
|
137
|
-
nullable: true,
|
|
138
|
-
})
|
|
139
|
-
public email?: string | undefined = undefined;
|
|
140
|
-
|
|
141
|
-
@ColumnAccessControl({
|
|
142
|
-
create: [],
|
|
143
|
-
read: [],
|
|
144
|
-
update: [],
|
|
145
|
-
})
|
|
146
|
-
@TableColumn({
|
|
147
|
-
type: TableColumnType.JSON,
|
|
148
|
-
required: true,
|
|
149
|
-
title: "Click IDs",
|
|
150
|
-
description:
|
|
151
|
-
"Ad click identifiers (gclid, wbraid, gbraid, fbclid, ...) captured for this conversion.",
|
|
152
|
-
})
|
|
153
|
-
@Column({
|
|
154
|
-
type: ColumnType.JSON,
|
|
155
|
-
nullable: false,
|
|
156
|
-
})
|
|
157
|
-
public clickIds?: JSONObject = undefined;
|
|
158
|
-
|
|
159
|
-
@ColumnAccessControl({
|
|
160
|
-
create: [],
|
|
161
|
-
read: [],
|
|
162
|
-
update: [],
|
|
163
|
-
})
|
|
164
|
-
@TableColumn({
|
|
165
|
-
type: TableColumnType.Date,
|
|
166
|
-
required: true,
|
|
167
|
-
title: "Conversion At",
|
|
168
|
-
description: "When the conversion happened.",
|
|
169
|
-
})
|
|
170
|
-
@Column({
|
|
171
|
-
type: ColumnType.Date,
|
|
172
|
-
nullable: false,
|
|
173
|
-
})
|
|
174
|
-
public conversionAt?: Date = undefined;
|
|
175
|
-
|
|
176
|
-
@ColumnAccessControl({
|
|
177
|
-
create: [],
|
|
178
|
-
read: [],
|
|
179
|
-
update: [],
|
|
180
|
-
})
|
|
181
|
-
@TableColumn({
|
|
182
|
-
type: TableColumnType.Number,
|
|
183
|
-
required: false,
|
|
184
|
-
title: "Conversion Value (USD Cents)",
|
|
185
|
-
description:
|
|
186
|
-
"Conversion value in USD cents (monthly recurring revenue for paid subscriptions). Null when unknown (custom pricing) or not applicable (signups, booked meetings).",
|
|
187
|
-
})
|
|
188
|
-
@Column({
|
|
189
|
-
type: ColumnType.Number,
|
|
190
|
-
nullable: true,
|
|
191
|
-
})
|
|
192
|
-
public conversionValueInUSDCents?: number | undefined = undefined;
|
|
193
|
-
|
|
194
|
-
@ColumnAccessControl({
|
|
195
|
-
create: [],
|
|
196
|
-
read: [],
|
|
197
|
-
update: [],
|
|
198
|
-
})
|
|
199
|
-
@TableColumn({
|
|
200
|
-
type: TableColumnType.JSON,
|
|
201
|
-
required: false,
|
|
202
|
-
title: "Upload State",
|
|
203
|
-
description:
|
|
204
|
-
"Per-ad-platform upload state, keyed by provider (google, meta, microsoft, linkedin, reddit, ...): { status: Uploaded|Failed|Skipped, attempts, error, uploadedAt }. Absent key or absent status means pending.",
|
|
205
|
-
})
|
|
206
|
-
@Column({
|
|
207
|
-
type: ColumnType.JSON,
|
|
208
|
-
nullable: true,
|
|
209
|
-
})
|
|
210
|
-
public uploadState?: JSONObject = undefined;
|
|
211
|
-
|
|
212
|
-
/*
|
|
213
|
-
* Last-touch UTM parameters, copied from the User or Project this conversion
|
|
214
|
-
* belongs to, or read from Cal booking metadata for a booked meeting.
|
|
215
|
-
*
|
|
216
|
-
* The ledger carried only clickIds until now, which meant the only thing
|
|
217
|
-
* that could answer "how many demos did this campaign produce" was the ad
|
|
218
|
-
* platform, and only for clicks it had auto-tagged. Any campaign delivering
|
|
219
|
-
* UTMs without a click id — a newsletter, a sponsorship, a conference link —
|
|
220
|
-
* was invisible in OneUptime's own data. These columns are what make the
|
|
221
|
-
* ledger reportable on its own.
|
|
222
|
-
*/
|
|
223
|
-
@ColumnAccessControl({
|
|
224
|
-
create: [],
|
|
225
|
-
read: [],
|
|
226
|
-
update: [],
|
|
227
|
-
})
|
|
228
|
-
@Index("idx_marketing_conversion_utm_campaign")
|
|
229
|
-
@TableColumn({
|
|
230
|
-
type: TableColumnType.LongText,
|
|
231
|
-
required: false,
|
|
232
|
-
title: "UTM Campaign",
|
|
233
|
-
description: "Last-touch utm_campaign for this conversion.",
|
|
234
|
-
})
|
|
235
|
-
@Column({
|
|
236
|
-
type: ColumnType.LongText,
|
|
237
|
-
length: ColumnLength.LongText,
|
|
238
|
-
nullable: true,
|
|
239
|
-
})
|
|
240
|
-
public utmCampaign?: string | undefined = undefined;
|
|
241
|
-
|
|
242
|
-
@ColumnAccessControl({
|
|
243
|
-
create: [],
|
|
244
|
-
read: [],
|
|
245
|
-
update: [],
|
|
246
|
-
})
|
|
247
|
-
@Index("idx_marketing_conversion_utm_source")
|
|
248
|
-
@TableColumn({
|
|
249
|
-
type: TableColumnType.LongText,
|
|
250
|
-
required: false,
|
|
251
|
-
title: "UTM Source",
|
|
252
|
-
description: "Last-touch utm_source for this conversion.",
|
|
253
|
-
})
|
|
254
|
-
@Column({
|
|
255
|
-
type: ColumnType.LongText,
|
|
256
|
-
length: ColumnLength.LongText,
|
|
257
|
-
nullable: true,
|
|
258
|
-
})
|
|
259
|
-
public utmSource?: string | undefined = undefined;
|
|
260
|
-
|
|
261
|
-
@ColumnAccessControl({
|
|
262
|
-
create: [],
|
|
263
|
-
read: [],
|
|
264
|
-
update: [],
|
|
265
|
-
})
|
|
266
|
-
@TableColumn({
|
|
267
|
-
type: TableColumnType.LongText,
|
|
268
|
-
required: false,
|
|
269
|
-
title: "UTM Medium",
|
|
270
|
-
description: "Last-touch utm_medium for this conversion.",
|
|
271
|
-
})
|
|
272
|
-
@Column({
|
|
273
|
-
type: ColumnType.LongText,
|
|
274
|
-
length: ColumnLength.LongText,
|
|
275
|
-
nullable: true,
|
|
276
|
-
})
|
|
277
|
-
public utmMedium?: string | undefined = undefined;
|
|
278
|
-
|
|
279
|
-
@ColumnAccessControl({
|
|
280
|
-
create: [],
|
|
281
|
-
read: [],
|
|
282
|
-
update: [],
|
|
283
|
-
})
|
|
284
|
-
@TableColumn({
|
|
285
|
-
type: TableColumnType.LongText,
|
|
286
|
-
required: false,
|
|
287
|
-
title: "UTM Term",
|
|
288
|
-
description: "Last-touch utm_term for this conversion.",
|
|
289
|
-
})
|
|
290
|
-
@Column({
|
|
291
|
-
type: ColumnType.LongText,
|
|
292
|
-
length: ColumnLength.LongText,
|
|
293
|
-
nullable: true,
|
|
294
|
-
})
|
|
295
|
-
public utmTerm?: string | undefined = undefined;
|
|
296
|
-
|
|
297
|
-
@ColumnAccessControl({
|
|
298
|
-
create: [],
|
|
299
|
-
read: [],
|
|
300
|
-
update: [],
|
|
301
|
-
})
|
|
302
|
-
@TableColumn({
|
|
303
|
-
type: TableColumnType.LongText,
|
|
304
|
-
required: false,
|
|
305
|
-
title: "UTM Content",
|
|
306
|
-
description: "Last-touch utm_content for this conversion.",
|
|
307
|
-
})
|
|
308
|
-
@Column({
|
|
309
|
-
type: ColumnType.LongText,
|
|
310
|
-
length: ColumnLength.LongText,
|
|
311
|
-
nullable: true,
|
|
312
|
-
})
|
|
313
|
-
public utmContent?: string | undefined = undefined;
|
|
314
|
-
|
|
315
|
-
@ColumnAccessControl({
|
|
316
|
-
create: [],
|
|
317
|
-
read: [],
|
|
318
|
-
update: [],
|
|
319
|
-
})
|
|
320
|
-
@TableColumn({
|
|
321
|
-
type: TableColumnType.LongText,
|
|
322
|
-
required: false,
|
|
323
|
-
title: "UTM URL",
|
|
324
|
-
description:
|
|
325
|
-
"Landing URL of the attributed visit. The only attribution a campaign leaves when its link carried a click id and no UTMs at all, as Google Ads auto-tagging does.",
|
|
326
|
-
})
|
|
327
|
-
@Column({
|
|
328
|
-
type: ColumnType.LongText,
|
|
329
|
-
length: ColumnLength.LongText,
|
|
330
|
-
nullable: true,
|
|
331
|
-
})
|
|
332
|
-
public utmUrl?: string | undefined = undefined;
|
|
333
|
-
|
|
334
|
-
@ColumnAccessControl({
|
|
335
|
-
create: [],
|
|
336
|
-
read: [],
|
|
337
|
-
update: [],
|
|
338
|
-
})
|
|
339
|
-
@TableColumn({
|
|
340
|
-
type: TableColumnType.JSON,
|
|
341
|
-
required: false,
|
|
342
|
-
title: "First Touch Attribution",
|
|
343
|
-
description:
|
|
344
|
-
"UTM parameters, click IDs, landing URL and referrer from the visitor's first attributed visit. The utm* columns above hold last-touch values.",
|
|
345
|
-
})
|
|
346
|
-
@Column({
|
|
347
|
-
type: ColumnType.JSON,
|
|
348
|
-
nullable: true,
|
|
349
|
-
})
|
|
350
|
-
public firstTouchAttribution?: JSONObject | undefined = undefined;
|
|
351
|
-
|
|
352
|
-
/*
|
|
353
|
-
* SHA-256 of the lowercased, trimmed email (Common/Server/Utils/Attribution).
|
|
354
|
-
*
|
|
355
|
-
* Two jobs, and it is the same value for both. Ad platforms that support
|
|
356
|
-
* enhanced matching want exactly this digest, and it is the only key that
|
|
357
|
-
* can join a booked meeting to the signup it produced weeks later: a
|
|
358
|
-
* MeetingBooked row has no userId, a SignUp row has no booking, and the
|
|
359
|
-
* person may well have used a different device for each. Indexed because
|
|
360
|
-
* the chain-linking pass looks conversions up by it.
|
|
361
|
-
*/
|
|
362
|
-
@ColumnAccessControl({
|
|
363
|
-
create: [],
|
|
364
|
-
read: [],
|
|
365
|
-
update: [],
|
|
366
|
-
})
|
|
367
|
-
@Index("idx_marketing_conversion_email_hash")
|
|
368
|
-
@TableColumn({
|
|
369
|
-
type: TableColumnType.ShortText,
|
|
370
|
-
required: false,
|
|
371
|
-
title: "Email Hash",
|
|
372
|
-
description:
|
|
373
|
-
"SHA-256 of the normalized (trimmed, lowercased) email. Used for ad-platform enhanced matching and to join conversions by the same person across the demo/signup boundary.",
|
|
374
|
-
})
|
|
375
|
-
@Column({
|
|
376
|
-
type: ColumnType.ShortText,
|
|
377
|
-
length: ColumnLength.ShortText,
|
|
378
|
-
nullable: true,
|
|
379
|
-
})
|
|
380
|
-
public emailHash?: string | undefined = undefined;
|
|
381
|
-
|
|
382
|
-
/*
|
|
383
|
-
* The earlier conversion by the same person that this one followed.
|
|
384
|
-
*
|
|
385
|
-
* Set by the MarketingConversions worker, never by a writer: the writers see
|
|
386
|
-
* one moment each and cannot know what came before it. A paid subscription
|
|
387
|
-
* pointing at a booked meeting is what makes "revenue this demo campaign
|
|
388
|
-
* produced" answerable — without it the ledger holds four unrelated rows for
|
|
389
|
-
* one customer journey.
|
|
390
|
-
*/
|
|
391
|
-
@ColumnAccessControl({
|
|
392
|
-
create: [],
|
|
393
|
-
read: [],
|
|
394
|
-
update: [],
|
|
395
|
-
})
|
|
396
|
-
@Index("idx_marketing_conversion_attributed_to")
|
|
397
|
-
@TableColumn({
|
|
398
|
-
type: TableColumnType.ObjectID,
|
|
399
|
-
required: false,
|
|
400
|
-
title: "Attributed To Conversion ID",
|
|
401
|
-
description:
|
|
402
|
-
"The earliest earlier conversion by the same person (matched on emailHash) that this conversion followed. Null when this is the first conversion in the chain.",
|
|
403
|
-
})
|
|
404
|
-
@Column({
|
|
405
|
-
type: ColumnType.ObjectID,
|
|
406
|
-
nullable: true,
|
|
407
|
-
transformer: ObjectID.getDatabaseTransformer(),
|
|
408
|
-
})
|
|
409
|
-
public attributedToConversionId?: ObjectID | undefined = undefined;
|
|
410
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import DatabaseService from "./DatabaseService";
|
|
2
|
-
import MarketingConversion from "../../Models/DatabaseModels/MarketingConversion";
|
|
3
|
-
|
|
4
|
-
export class Service extends DatabaseService<MarketingConversion> {
|
|
5
|
-
public constructor() {
|
|
6
|
-
super(MarketingConversion);
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default new Service();
|