@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
|
@@ -9,8 +9,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
import { getWorkspaceTypeDisplayName, } from "../../Types/Workspace/WorkspaceType";
|
|
11
11
|
import DatabaseService from "./DatabaseService";
|
|
12
|
+
import WorkspaceUserAuthTokenService from "./WorkspaceUserAuthTokenService";
|
|
12
13
|
import Model from "../../Models/DatabaseModels/WorkspaceProjectAuthToken";
|
|
13
|
-
import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
14
|
+
import LIMIT_MAX, { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
|
|
14
15
|
import BadDataException from "../../Types/Exception/BadDataException";
|
|
15
16
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
16
17
|
import logger from "../Utils/Logger";
|
|
@@ -18,6 +19,62 @@ export class Service extends DatabaseService {
|
|
|
18
19
|
constructor() {
|
|
19
20
|
super(Model);
|
|
20
21
|
}
|
|
22
|
+
/*
|
|
23
|
+
* Disconnecting a WORKSPACE disconnects every user link inside it.
|
|
24
|
+
*
|
|
25
|
+
* The dashboard's "Uninstall OneUptime from Slack / Microsoft Teams" button
|
|
26
|
+
* deletes this row through the generic CRUD path, and nothing else about
|
|
27
|
+
* the workspace survives that in a usable state: the user auth tokens were
|
|
28
|
+
* minted against this workspace's OAuth app, and the UserSlack /
|
|
29
|
+
* UserMicrosoftTeams notification methods are pointers at those links that
|
|
30
|
+
* WorkspaceUserNotificationService will deterministically refuse to send
|
|
31
|
+
* through once this row is gone ("This project is not connected to ...").
|
|
32
|
+
*
|
|
33
|
+
* Left behind, those verified-looking methods are worse than dead: the
|
|
34
|
+
* on-call fallback selects them into its zero-cost tier and stops looking,
|
|
35
|
+
* and the readiness surface keeps reporting the responder reachable. So the
|
|
36
|
+
* user tokens are deleted THROUGH THEIR SERVICE here, whose own
|
|
37
|
+
* onBeforeDelete cascades to the notification methods and their rules -
|
|
38
|
+
* returning every affected responder to the "no rule" state the
|
|
39
|
+
* verified-method fallback is built to rescue. This mirrors what the
|
|
40
|
+
* Slack-side app_uninstall webhook already did; the webhook remains for
|
|
41
|
+
* uninstalls initiated inside Slack, where this hook never fires.
|
|
42
|
+
*/
|
|
43
|
+
async onBeforeDelete(deleteBy) {
|
|
44
|
+
const itemsToDelete = await this.findBy({
|
|
45
|
+
query: deleteBy.query,
|
|
46
|
+
select: {
|
|
47
|
+
_id: true,
|
|
48
|
+
projectId: true,
|
|
49
|
+
workspaceType: true,
|
|
50
|
+
},
|
|
51
|
+
skip: 0,
|
|
52
|
+
limit: LIMIT_MAX,
|
|
53
|
+
props: {
|
|
54
|
+
isRoot: true,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
for (const item of itemsToDelete) {
|
|
58
|
+
if (!item.projectId || !item.workspaceType) {
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
await WorkspaceUserAuthTokenService.deleteBy({
|
|
62
|
+
query: {
|
|
63
|
+
projectId: item.projectId,
|
|
64
|
+
workspaceType: item.workspaceType,
|
|
65
|
+
},
|
|
66
|
+
limit: LIMIT_MAX,
|
|
67
|
+
skip: 0,
|
|
68
|
+
props: {
|
|
69
|
+
isRoot: true,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
deleteBy,
|
|
75
|
+
carryForward: null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
21
78
|
async getProjectAuth(data) {
|
|
22
79
|
if (!data.projectId) {
|
|
23
80
|
throw new BadDataException("projectId is required");
|
|
@@ -143,6 +200,12 @@ export class Service extends DatabaseService {
|
|
|
143
200
|
}
|
|
144
201
|
}
|
|
145
202
|
}
|
|
203
|
+
__decorate([
|
|
204
|
+
CaptureSpan(),
|
|
205
|
+
__metadata("design:type", Function),
|
|
206
|
+
__metadata("design:paramtypes", [Object]),
|
|
207
|
+
__metadata("design:returntype", Promise)
|
|
208
|
+
], Service.prototype, "onBeforeDelete", null);
|
|
146
209
|
__decorate([
|
|
147
210
|
CaptureSpan(),
|
|
148
211
|
__metadata("design:type", Function),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceProjectAuthTokenService.js","sourceRoot":"","sources":["../../../../Server/Services/WorkspaceProjectAuthTokenService.ts"],"names":[],"mappings":";;;;;;;;;AACA,OAAsB,EACpB,2BAA2B,GAC5B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAEN,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"WorkspaceProjectAuthTokenService.js","sourceRoot":"","sources":["../../../../Server/Services/WorkspaceProjectAuthTokenService.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,13 +7,77 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
+
import WorkspaceType from "../../Types/Workspace/WorkspaceType";
|
|
11
|
+
import LIMIT_MAX from "../../Types/Database/LimitMax";
|
|
10
12
|
import DatabaseService from "./DatabaseService";
|
|
13
|
+
import UserSlackService from "./UserSlackService";
|
|
14
|
+
import UserMicrosoftTeamsService from "./UserMicrosoftTeamsService";
|
|
11
15
|
import Model from "../../Models/DatabaseModels/WorkspaceUserAuthToken";
|
|
12
16
|
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
13
17
|
export class Service extends DatabaseService {
|
|
14
18
|
constructor() {
|
|
15
19
|
super(Model);
|
|
16
20
|
}
|
|
21
|
+
/*
|
|
22
|
+
* A UserSlack / UserMicrosoftTeams notification method is a pointer at the
|
|
23
|
+
* workspace link being deleted here, so it goes down with it (which also
|
|
24
|
+
* deletes the notification rules routing to it, via that service's own
|
|
25
|
+
* delete hook). Leaving the method row behind would be worse than deleting
|
|
26
|
+
* it: a rule pointing at a dead link fails with an error row and no re-page,
|
|
27
|
+
* while a user with NO matching rule is rescued by the verified-method
|
|
28
|
+
* fallback.
|
|
29
|
+
*/
|
|
30
|
+
async onBeforeDelete(deleteBy) {
|
|
31
|
+
const itemsToDelete = await this.findBy({
|
|
32
|
+
query: deleteBy.query,
|
|
33
|
+
select: {
|
|
34
|
+
_id: true,
|
|
35
|
+
projectId: true,
|
|
36
|
+
userId: true,
|
|
37
|
+
workspaceType: true,
|
|
38
|
+
},
|
|
39
|
+
skip: 0,
|
|
40
|
+
limit: LIMIT_MAX,
|
|
41
|
+
props: {
|
|
42
|
+
isRoot: true,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
for (const item of itemsToDelete) {
|
|
46
|
+
if (!item.projectId || !item.userId) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (item.workspaceType === WorkspaceType.Slack) {
|
|
50
|
+
await UserSlackService.deleteBy({
|
|
51
|
+
query: {
|
|
52
|
+
projectId: item.projectId,
|
|
53
|
+
userId: item.userId,
|
|
54
|
+
},
|
|
55
|
+
limit: LIMIT_MAX,
|
|
56
|
+
skip: 0,
|
|
57
|
+
props: {
|
|
58
|
+
isRoot: true,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (item.workspaceType === WorkspaceType.MicrosoftTeams) {
|
|
63
|
+
await UserMicrosoftTeamsService.deleteBy({
|
|
64
|
+
query: {
|
|
65
|
+
projectId: item.projectId,
|
|
66
|
+
userId: item.userId,
|
|
67
|
+
},
|
|
68
|
+
limit: LIMIT_MAX,
|
|
69
|
+
skip: 0,
|
|
70
|
+
props: {
|
|
71
|
+
isRoot: true,
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
deleteBy,
|
|
78
|
+
carryForward: null,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
17
81
|
async getUserAuth(data) {
|
|
18
82
|
return await this.findOneBy({
|
|
19
83
|
query: {
|
|
@@ -90,6 +154,12 @@ export class Service extends DatabaseService {
|
|
|
90
154
|
}
|
|
91
155
|
}
|
|
92
156
|
}
|
|
157
|
+
__decorate([
|
|
158
|
+
CaptureSpan(),
|
|
159
|
+
__metadata("design:type", Function),
|
|
160
|
+
__metadata("design:paramtypes", [Object]),
|
|
161
|
+
__metadata("design:returntype", Promise)
|
|
162
|
+
], Service.prototype, "onBeforeDelete", null);
|
|
93
163
|
__decorate([
|
|
94
164
|
CaptureSpan(),
|
|
95
165
|
__metadata("design:type", Function),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceUserAuthTokenService.js","sourceRoot":"","sources":["../../../../Server/Services/WorkspaceUserAuthTokenService.ts"],"names":[],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"WorkspaceUserAuthTokenService.js","sourceRoot":"","sources":["../../../../Server/Services/WorkspaceUserAuthTokenService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import BaseService from "./BaseService";
|
|
11
|
+
import UserOnCallLogTimelineService from "./UserOnCallLogTimelineService";
|
|
12
|
+
import WorkspaceNotificationLogService from "./WorkspaceNotificationLogService";
|
|
13
|
+
import WorkspaceProjectAuthTokenService from "./WorkspaceProjectAuthTokenService";
|
|
14
|
+
import SlackUtil from "../Utils/Workspace/Slack/Slack";
|
|
15
|
+
import MicrosoftTeamsUtil from "../Utils/Workspace/MicrosoftTeams/MicrosoftTeams";
|
|
16
|
+
import logger from "../Utils/Logger";
|
|
17
|
+
import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
|
|
18
|
+
import BadDataException from "../../Types/Exception/BadDataException";
|
|
19
|
+
import UserNotificationStatus from "../../Types/UserNotification/UserNotificationStatus";
|
|
20
|
+
import WorkspaceNotificationActionType from "../../Types/Workspace/WorkspaceNotificationActionType";
|
|
21
|
+
import WorkspaceNotificationStatus from "../../Types/Workspace/WorkspaceNotificationStatus";
|
|
22
|
+
import WorkspaceType, { getWorkspaceTypeDisplayName, } from "../../Types/Workspace/WorkspaceType";
|
|
23
|
+
export class WorkspaceUserNotificationService extends BaseService {
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
}
|
|
27
|
+
async sendDirectMessageToUser(options) {
|
|
28
|
+
const workspaceDisplayName = getWorkspaceTypeDisplayName(options.workspaceType);
|
|
29
|
+
let sendError = null;
|
|
30
|
+
try {
|
|
31
|
+
if (!options.workspaceUserId) {
|
|
32
|
+
throw new BadDataException(`This account is not connected to ${workspaceDisplayName}. Please go to User Settings and connect the account.`);
|
|
33
|
+
}
|
|
34
|
+
const projectAuth = await WorkspaceProjectAuthTokenService.getProjectAuth({
|
|
35
|
+
projectId: options.projectId,
|
|
36
|
+
workspaceType: options.workspaceType,
|
|
37
|
+
});
|
|
38
|
+
if (!projectAuth || !projectAuth.authToken) {
|
|
39
|
+
throw new BadDataException(`This project is not connected to ${workspaceDisplayName}. Please go to Project Settings and connect the account.`);
|
|
40
|
+
}
|
|
41
|
+
if (options.workspaceType === WorkspaceType.Slack) {
|
|
42
|
+
await SlackUtil.sendDirectMessageToUser({
|
|
43
|
+
authToken: projectAuth.authToken,
|
|
44
|
+
workspaceUserId: options.workspaceUserId,
|
|
45
|
+
messageBlocks: options.messageBlocks,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
else if (options.workspaceType === WorkspaceType.MicrosoftTeams) {
|
|
49
|
+
await MicrosoftTeamsUtil.sendDirectMessageToUserAsBot({
|
|
50
|
+
projectId: options.projectId,
|
|
51
|
+
workspaceUserId: options.workspaceUserId,
|
|
52
|
+
messageBlocks: options.messageBlocks,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
throw new BadDataException(`Direct messages are not supported for workspace type ${options.workspaceType}.`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const errorMessage = error instanceof Error && error.message
|
|
61
|
+
? error.message
|
|
62
|
+
: `${error}`;
|
|
63
|
+
sendError = error instanceof Error ? error : new Error(errorMessage);
|
|
64
|
+
logger.error(`Failed to send ${workspaceDisplayName} direct message notification.`);
|
|
65
|
+
logger.error(error);
|
|
66
|
+
}
|
|
67
|
+
/*
|
|
68
|
+
* Log the attempt for admin visibility. Best-effort: a failed log write
|
|
69
|
+
* must never turn a delivered page into a reported failure (or mask a
|
|
70
|
+
* real send error with a logging one).
|
|
71
|
+
*/
|
|
72
|
+
try {
|
|
73
|
+
await WorkspaceNotificationLogService.createWorkspaceLog({
|
|
74
|
+
projectId: options.projectId,
|
|
75
|
+
workspaceType: options.workspaceType,
|
|
76
|
+
actionType: WorkspaceNotificationActionType.SendMessage,
|
|
77
|
+
status: sendError
|
|
78
|
+
? WorkspaceNotificationStatus.Error
|
|
79
|
+
: WorkspaceNotificationStatus.Success,
|
|
80
|
+
message: options.messageSummary,
|
|
81
|
+
statusMessage: sendError
|
|
82
|
+
? sendError.message
|
|
83
|
+
: `Direct message sent on ${workspaceDisplayName}.`,
|
|
84
|
+
userId: options.userId,
|
|
85
|
+
incidentId: options.incidentId,
|
|
86
|
+
alertId: options.alertId,
|
|
87
|
+
alertEpisodeId: options.alertEpisodeId,
|
|
88
|
+
incidentEpisodeId: options.incidentEpisodeId,
|
|
89
|
+
onCallDutyPolicyId: options.onCallPolicyId,
|
|
90
|
+
onCallDutyPolicyEscalationRuleId: options.onCallPolicyEscalationRuleId,
|
|
91
|
+
onCallDutyPolicyScheduleId: options.onCallScheduleId,
|
|
92
|
+
teamId: options.teamId,
|
|
93
|
+
}, {
|
|
94
|
+
isRoot: true,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch (logError) {
|
|
98
|
+
logger.error("Failed to write workspace notification log.");
|
|
99
|
+
logger.error(logError);
|
|
100
|
+
}
|
|
101
|
+
if (options.userOnCallLogTimelineId) {
|
|
102
|
+
await UserOnCallLogTimelineService.updateOneById({
|
|
103
|
+
id: options.userOnCallLogTimelineId,
|
|
104
|
+
data: {
|
|
105
|
+
status: sendError
|
|
106
|
+
? UserNotificationStatus.Error
|
|
107
|
+
: UserNotificationStatus.Sent,
|
|
108
|
+
statusMessage: sendError
|
|
109
|
+
? sendError.message
|
|
110
|
+
: `Message sent on ${workspaceDisplayName}.`,
|
|
111
|
+
},
|
|
112
|
+
props: {
|
|
113
|
+
isRoot: true,
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
if (sendError) {
|
|
118
|
+
throw sendError;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
__decorate([
|
|
123
|
+
CaptureSpan(),
|
|
124
|
+
__metadata("design:type", Function),
|
|
125
|
+
__metadata("design:paramtypes", [Object]),
|
|
126
|
+
__metadata("design:returntype", Promise)
|
|
127
|
+
], WorkspaceUserNotificationService.prototype, "sendDirectMessageToUser", null);
|
|
128
|
+
export default new WorkspaceUserNotificationService();
|
|
129
|
+
//# sourceMappingURL=WorkspaceUserNotificationService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WorkspaceUserNotificationService.js","sourceRoot":"","sources":["../../../../Server/Services/WorkspaceUserNotificationService.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,4BAA4B,MAAM,gCAAgC,CAAC;AAC1E,OAAO,+BAA+B,MAAM,mCAAmC,CAAC;AAChF,OAAO,gCAAgC,MAAM,oCAAoC,CAAC;AAClF,OAAO,SAAS,MAAM,gCAAgC,CAAC;AACvD,OAAO,kBAAkB,MAAM,kDAAkD,CAAC;AAClF,OAAO,MAAM,MAAM,iBAAiB,CAAC;AACrC,OAAO,WAAW,MAAM,gCAAgC,CAAC;AAEzD,OAAO,gBAAgB,MAAM,wCAAwC,CAAC;AAEtE,OAAO,sBAAsB,MAAM,qDAAqD,CAAC;AACzF,OAAO,+BAA+B,MAAM,uDAAuD,CAAC;AACpG,OAAO,2BAA2B,MAAM,mDAAmD,CAAC;AAE5F,OAAO,aAAa,EAAE,EACpB,2BAA2B,GAC5B,MAAM,qCAAqC,CAAC;AA8C7C,MAAM,OAAO,gCAAiC,SAAQ,WAAW;IAC/D;QACE,KAAK,EAAE,CAAC;IACV,CAAC;IAGY,AAAN,KAAK,CAAC,uBAAuB,CAClC,OAA0C;QAE1C,MAAM,oBAAoB,GAAW,2BAA2B,CAC9D,OAAO,CAAC,aAAa,CACtB,CAAC;QAEF,IAAI,SAAS,GAAiB,IAAI,CAAC;QAEnC,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC7B,MAAM,IAAI,gBAAgB,CACxB,oCAAoC,oBAAoB,uDAAuD,CAChH,CAAC;YACJ,CAAC;YAED,MAAM,WAAW,GACf,MAAM,gCAAgC,CAAC,cAAc,CAAC;gBACpD,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;aACrC,CAAC,CAAC;YAEL,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,CAAC;gBAC3C,MAAM,IAAI,gBAAgB,CACxB,oCAAoC,oBAAoB,0DAA0D,CACnH,CAAC;YACJ,CAAC;YAED,IAAI,OAAO,CAAC,aAAa,KAAK,aAAa,CAAC,KAAK,EAAE,CAAC;gBAClD,MAAM,SAAS,CAAC,uBAAuB,CAAC;oBACtC,SAAS,EAAE,WAAW,CAAC,SAAS;oBAChC,eAAe,EAAE,OAAO,CAAC,eAAe;oBACxC,aAAa,EAAE,OAAO,CAAC,aAAa;iBACrC,CAAC,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,CAAC,aAAa,KAAK,aAAa,CAAC,cAAc,EAAE,CAAC;gBAClE,MAAM,kBAAkB,CAAC,4BAA4B,CAAC;oBACpD,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,eAAe,EAAE,OAAO,CAAC,eAAe;oBACxC,aAAa,EAAE,OAAO,CAAC,aAAa;iBACrC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,gBAAgB,CACxB,wDAAwD,OAAO,CAAC,aAAa,GAAG,CACjF,CAAC;YACJ,CAAC;QACH,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,YAAY,GAChB,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO;gBACrC,CAAC,CAAC,KAAK,CAAC,OAAO;gBACf,CAAC,CAAC,GAAG,KAAe,EAAE,CAAC;YAE3B,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAErE,MAAM,CAAC,KAAK,CACV,kBAAkB,oBAAoB,+BAA+B,CACtE,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QAED;;;;WAIG;QACH,IAAI,CAAC;YACH,MAAM,+BAA+B,CAAC,kBAAkB,CACtD;gBACE,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,UAAU,EAAE,+BAA+B,CAAC,WAAW;gBACvD,MAAM,EAAE,SAAS;oBACf,CAAC,CAAC,2BAA2B,CAAC,KAAK;oBACnC,CAAC,CAAC,2BAA2B,CAAC,OAAO;gBACvC,OAAO,EAAE,OAAO,CAAC,cAAc;gBAC/B,aAAa,EAAE,SAAS;oBACtB,CAAC,CAAC,SAAS,CAAC,OAAO;oBACnB,CAAC,CAAC,0BAA0B,oBAAoB,GAAG;gBACrD,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,cAAc,EAAE,OAAO,CAAC,cAAc;gBACtC,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,kBAAkB,EAAE,OAAO,CAAC,cAAc;gBAC1C,gCAAgC,EAC9B,OAAO,CAAC,4BAA4B;gBACtC,0BAA0B,EAAE,OAAO,CAAC,gBAAgB;gBACpD,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB,EACD;gBACE,MAAM,EAAE,IAAI;aACb,CACF,CAAC;QACJ,CAAC;QAAC,OAAO,QAAQ,EAAE,CAAC;YAClB,MAAM,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC5D,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QAED,IAAI,OAAO,CAAC,uBAAuB,EAAE,CAAC;YACpC,MAAM,4BAA4B,CAAC,aAAa,CAAC;gBAC/C,EAAE,EAAE,OAAO,CAAC,uBAAuB;gBACnC,IAAI,EAAE;oBACJ,MAAM,EAAE,SAAS;wBACf,CAAC,CAAC,sBAAsB,CAAC,KAAK;wBAC9B,CAAC,CAAC,sBAAsB,CAAC,IAAI;oBAC/B,aAAa,EAAE,SAAS;wBACtB,CAAC,CAAC,SAAS,CAAC,OAAO;wBACnB,CAAC,CAAC,mBAAmB,oBAAoB,GAAG;iBAC/C;gBACD,KAAK,EAAE;oBACL,MAAM,EAAE,IAAI;iBACb;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,SAAS,CAAC;QAClB,CAAC;IACH,CAAC;CACF;AAtHc;IADZ,WAAW,EAAE;;;;+EAsHb;AAGH,eAAe,IAAI,gCAAgC,EAAE,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import Attribution from "../Attribution";
|
|
2
|
+
import MarketingEventWebhook from "./MarketingEventWebhook";
|
|
3
|
+
import Queue, { QueueName } from "../../Infrastructure/Queue";
|
|
4
|
+
import { MARKETING_EVENT_SCHEMA_VERSION, } from "../../../Types/Marketing/MarketingEvent";
|
|
5
|
+
import logger from "../Logger";
|
|
6
|
+
/*
|
|
7
|
+
* How many times the queue delivers one event before giving up, and the base
|
|
8
|
+
* for its exponential backoff. Five attempts at 30s exponential spans roughly
|
|
9
|
+
* eight minutes, which covers a rolling deploy of the receiver.
|
|
10
|
+
*
|
|
11
|
+
* There is no dead-letter store and deliberately so: the point of this design
|
|
12
|
+
* is that OneUptime does not hold marketing data. An event that exhausts its
|
|
13
|
+
* attempts is logged as an error and lost, which is the cost of not keeping a
|
|
14
|
+
* ledger and should be alerted on rather than engineered around here.
|
|
15
|
+
*/
|
|
16
|
+
const DELIVERY_ATTEMPTS = 5;
|
|
17
|
+
const DELIVERY_BACKOFF_MS = 30000;
|
|
18
|
+
export default class MarketingEventUtil {
|
|
19
|
+
static buildAttribution(source) {
|
|
20
|
+
return {
|
|
21
|
+
utmSource: source === null || source === void 0 ? void 0 : source.utmSource,
|
|
22
|
+
utmMedium: source === null || source === void 0 ? void 0 : source.utmMedium,
|
|
23
|
+
utmCampaign: source === null || source === void 0 ? void 0 : source.utmCampaign,
|
|
24
|
+
utmTerm: source === null || source === void 0 ? void 0 : source.utmTerm,
|
|
25
|
+
utmContent: source === null || source === void 0 ? void 0 : source.utmContent,
|
|
26
|
+
utmUrl: source === null || source === void 0 ? void 0 : source.utmUrl,
|
|
27
|
+
clickIds: (source === null || source === void 0 ? void 0 : source.clickIds) || {},
|
|
28
|
+
firstTouch: (source === null || source === void 0 ? void 0 : source.firstTouchAttribution) || {},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
static buildEvent(data) {
|
|
32
|
+
const emailHash = Attribution.hashEmail(data.email);
|
|
33
|
+
return {
|
|
34
|
+
schemaVersion: MARKETING_EVENT_SCHEMA_VERSION,
|
|
35
|
+
eventId: data.eventId,
|
|
36
|
+
eventType: data.eventType,
|
|
37
|
+
occurredAt: data.occurredAt.toISOString(),
|
|
38
|
+
email: data.email,
|
|
39
|
+
emailHash: emailHash || undefined,
|
|
40
|
+
attribution: this.buildAttribution(data.attributionSource),
|
|
41
|
+
data: data.data || {},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/*
|
|
45
|
+
* Hand one event to the queue.
|
|
46
|
+
*
|
|
47
|
+
* Never throws and never awaits delivery. Every caller is a commercial code
|
|
48
|
+
* path — a signup completing, a plan change being written, a booking being
|
|
49
|
+
* accepted — and none of them may fail, block, or slow down because a
|
|
50
|
+
* marketing endpoint is unreachable. Enqueue is the only synchronous part
|
|
51
|
+
* and it is a single Redis write.
|
|
52
|
+
*/
|
|
53
|
+
static async emit(event) {
|
|
54
|
+
if (MarketingEventWebhook.isMisconfigured()) {
|
|
55
|
+
logger.error(`MarketingEvent: MARKETING_WEBHOOK_URL is set but MARKETING_WEBHOOK_SECRET is not — refusing to send ${event.eventType} unsigned. Set the secret or unset the URL.`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (!MarketingEventWebhook.isConfigured()) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
await Queue.addJob(QueueName.MarketingEvent, event.eventId, event.eventType, event, {
|
|
63
|
+
attempts: DELIVERY_ATTEMPTS,
|
|
64
|
+
backoffDelayInMs: DELIVERY_BACKOFF_MS,
|
|
65
|
+
});
|
|
66
|
+
logger.debug(`MarketingEvent: queued ${event.eventType} (${event.eventId})`);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
logger.error(`MarketingEvent: failed to queue ${event.eventType} (${event.eventId}): ${err}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/*
|
|
73
|
+
* Fire-and-forget wrapper for callers that are not async or must not await.
|
|
74
|
+
*
|
|
75
|
+
* Guarantees it neither throws nor rejects. Every caller is inside a
|
|
76
|
+
* commercial transaction that has already succeeded by the time it gets
|
|
77
|
+
* here — a user is created, a plan is changed, a booking is verified — so
|
|
78
|
+
* the one thing this must never do is turn a completed action into a failed
|
|
79
|
+
* one. The rejection path is covered by .catch and the synchronous path by
|
|
80
|
+
* the try, because an argument expression that throws (buildEvent on a
|
|
81
|
+
* malformed row) would otherwise propagate straight into the caller.
|
|
82
|
+
*/
|
|
83
|
+
static emitInBackground(event) {
|
|
84
|
+
try {
|
|
85
|
+
this.emit(event).catch((err) => {
|
|
86
|
+
logger.error(`MarketingEvent: failed to emit ${event.eventType}: ${err}`);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
logger.error(`MarketingEvent: failed to emit ${event.eventType}: ${err}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=MarketingEventUtil.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarketingEventUtil.js","sourceRoot":"","sources":["../../../../../Server/Utils/Marketing/MarketingEventUtil.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import axios, { AxiosError } from "axios";
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
import { MarketingWebhookSecret, MarketingWebhookUrl, } from "../../EnvironmentConfig";
|
|
4
|
+
import logger from "../Logger";
|
|
5
|
+
const REQUEST_TIMEOUT_MS = 15000;
|
|
6
|
+
/*
|
|
7
|
+
* Delivers marketing conversion events to one operator-configured endpoint.
|
|
8
|
+
*
|
|
9
|
+
* OneUptime keeps no conversion ledger, so this is the only exit for a signup,
|
|
10
|
+
* a booked meeting or a plan change. That has one consequence worth stating
|
|
11
|
+
* plainly: a delivery this class gives up on is gone, because there is no row
|
|
12
|
+
* anywhere to reconcile against later. deliver() therefore THROWS on anything
|
|
13
|
+
* that might succeed on a retry, and the queue is what retries it.
|
|
14
|
+
*
|
|
15
|
+
* SIGNING
|
|
16
|
+
*
|
|
17
|
+
* The signature is HMAC-SHA256 over the exact request body bytes, hex encoded,
|
|
18
|
+
* in `x-oneuptime-signature-256`. This is the same scheme OneUptime verifies
|
|
19
|
+
* on the way in from Cal, deliberately: one thing to understand rather than
|
|
20
|
+
* two. The receiver must compute its digest over the raw bytes it received —
|
|
21
|
+
* JSON parsed and re-serialised is NOT equivalent, because whitespace, key
|
|
22
|
+
* order and escaping all change the digest.
|
|
23
|
+
*
|
|
24
|
+
* The body is serialised once, here, and that exact string is both signed and
|
|
25
|
+
* sent, so nothing between the signature and the socket can reformat it.
|
|
26
|
+
*
|
|
27
|
+
* Both the URL and the secret are required. An endpoint configured without a
|
|
28
|
+
* secret is not sent to at all rather than sent to unsigned: the payload
|
|
29
|
+
* carries email addresses and campaign data, and a receiver with no way to
|
|
30
|
+
* tell OneUptime's POST from anyone else's is not a receiver worth having.
|
|
31
|
+
*/
|
|
32
|
+
export default class MarketingEventWebhook {
|
|
33
|
+
static isConfigured() {
|
|
34
|
+
return Boolean(MarketingWebhookUrl && MarketingWebhookSecret);
|
|
35
|
+
}
|
|
36
|
+
/*
|
|
37
|
+
* True when an endpoint is set but unusable, so callers can say so once at
|
|
38
|
+
* emit time rather than letting events vanish into a silent no-op.
|
|
39
|
+
*/
|
|
40
|
+
static isMisconfigured() {
|
|
41
|
+
return Boolean(MarketingWebhookUrl) && !MarketingWebhookSecret;
|
|
42
|
+
}
|
|
43
|
+
static sign(body) {
|
|
44
|
+
return crypto
|
|
45
|
+
.createHmac("sha256", MarketingWebhookSecret)
|
|
46
|
+
.update(body, "utf8")
|
|
47
|
+
.digest("hex");
|
|
48
|
+
}
|
|
49
|
+
/*
|
|
50
|
+
* One delivery attempt.
|
|
51
|
+
*
|
|
52
|
+
* Throws on a transport error or any non-2xx, which is what makes the queue
|
|
53
|
+
* retry. A 4xx is retried too: the receiver rejecting a payload it should
|
|
54
|
+
* have taken is far more often a deploy in progress or a bad rule than a
|
|
55
|
+
* payload that will never be acceptable, and the alternative — dropping it
|
|
56
|
+
* silently — has no backstop now that nothing is stored.
|
|
57
|
+
*/
|
|
58
|
+
static async deliver(event) {
|
|
59
|
+
var _a, _b;
|
|
60
|
+
if (!this.isConfigured()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Serialise once. This exact string is signed and sent.
|
|
64
|
+
const body = JSON.stringify(event);
|
|
65
|
+
try {
|
|
66
|
+
const response = await axios.post(MarketingWebhookUrl, body, {
|
|
67
|
+
headers: {
|
|
68
|
+
"content-type": "application/json",
|
|
69
|
+
"x-oneuptime-signature-256": this.sign(body),
|
|
70
|
+
"x-oneuptime-event-id": event.eventId,
|
|
71
|
+
"x-oneuptime-event-type": event.eventType,
|
|
72
|
+
},
|
|
73
|
+
timeout: REQUEST_TIMEOUT_MS,
|
|
74
|
+
// Non-2xx must reach the catch below rather than resolving.
|
|
75
|
+
validateStatus: (status) => {
|
|
76
|
+
return status >= 200 && status < 300;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
logger.debug(`MarketingEvent: delivered ${event.eventType} (${event.eventId}) — HTTP ${response.status}`);
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
const message = err instanceof AxiosError
|
|
83
|
+
? `HTTP ${((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) || "?"}: ${JSON.stringify(((_b = err.response) === null || _b === void 0 ? void 0 : _b.data) || err.message).slice(0, 500)}`
|
|
84
|
+
: (err === null || err === void 0 ? void 0 : err.message) || "Unknown error";
|
|
85
|
+
/*
|
|
86
|
+
* Rethrown, not swallowed. The queue's retry is the only thing standing
|
|
87
|
+
* between a receiver hiccup and a permanently lost conversion.
|
|
88
|
+
*/
|
|
89
|
+
throw new Error(`Marketing webhook delivery failed for ${event.eventType} (${event.eventId}): ${message}`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=MarketingEventWebhook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarketingEventWebhook.js","sourceRoot":"","sources":["../../../../../Server/Utils/Marketing/MarketingEventWebhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,UAAU,EAAiB,MAAM,OAAO,CAAC;AACzD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EACL,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,MAAM,MAAM,WAAW,CAAC;AAE/B,MAAM,kBAAkB,GAAW,KAAK,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAC,OAAO,OAAO,qBAAqB;IACjC,MAAM,CAAC,YAAY;QACxB,OAAO,OAAO,CAAC,mBAAmB,IAAI,sBAAsB,CAAC,CAAC;IAChE,CAAC;IAED;;;OAGG;IACI,MAAM,CAAC,eAAe;QAC3B,OAAO,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,sBAAsB,CAAC;IACjE,CAAC;IAEM,MAAM,CAAC,IAAI,CAAC,IAAY;QAC7B,OAAO,MAAM;aACV,UAAU,CAAC,QAAQ,EAAE,sBAAsB,CAAC;aAC5C,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC;aACpB,MAAM,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;IAED;;;;;;;;OAQG;IACI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,KAAqB;;QAC/C,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACzB,OAAO;QACT,CAAC;QAED,wDAAwD;QACxD,MAAM,IAAI,GAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAE3C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAkB,MAAM,KAAK,CAAC,IAAI,CAC9C,mBAAmB,EACnB,IAAI,EACJ;gBACE,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,2BAA2B,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC5C,sBAAsB,EAAE,KAAK,CAAC,OAAO;oBACrC,wBAAwB,EAAE,KAAK,CAAC,SAAS;iBAC1C;gBACD,OAAO,EAAE,kBAAkB;gBAC3B,4DAA4D;gBAC5D,cAAc,EAAE,CAAC,MAAc,EAAW,EAAE;oBAC1C,OAAO,MAAM,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,CAAC;gBACvC,CAAC;aACF,CACF,CAAC;YAEF,MAAM,CAAC,KAAK,CACV,6BAA6B,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,OAAO,YAAY,QAAQ,CAAC,MAAM,EAAE,CAC5F,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GACX,GAAG,YAAY,UAAU;gBACvB,CAAC,CAAC,QAAQ,CAAA,MAAA,GAAG,CAAC,QAAQ,0CAAE,MAAM,KAAI,GAAG,KAAK,IAAI,CAAC,SAAS,CACpD,CAAA,MAAA,GAAG,CAAC,QAAQ,0CAAE,IAAI,KAAI,GAAG,CAAC,OAAO,CAClC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;gBACnB,CAAC,CAAC,CAAC,GAAa,aAAb,GAAG,uBAAH,GAAG,CAAY,OAAO,KAAI,eAAe,CAAC;YAEjD;;;eAGG;YACH,MAAM,IAAI,KAAK,CACb,yCAAyC,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,OAAO,MAAM,OAAO,EAAE,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -4,6 +4,7 @@ import logger from "../Logger";
|
|
|
4
4
|
import GracefulShutdown, { ShutdownPriority } from "../GracefulShutdown";
|
|
5
5
|
import OneUptimeDate from "../../../Types/Date";
|
|
6
6
|
import ObjectID from "../../../Types/ObjectID";
|
|
7
|
+
import { redactForPersistence } from "./MonitorPayloadRedaction";
|
|
7
8
|
/*
|
|
8
9
|
* Maximum rows held in memory before we force a flush, and the
|
|
9
10
|
* maximum time we hold a row in the buffer before flushing.
|
|
@@ -88,7 +89,17 @@ class MonitorLogUtil {
|
|
|
88
89
|
projectId: data.projectId.toString(),
|
|
89
90
|
monitorId: data.monitorId.toString(),
|
|
90
91
|
time: logTimestamp,
|
|
91
|
-
|
|
92
|
+
/*
|
|
93
|
+
* Redact on the way out, never in place: `dataToProcess` is still
|
|
94
|
+
* live here (saveMonitorLog is fire-and-forget and the caller keeps
|
|
95
|
+
* evaluating criteria against it), so the stringify/parse clone is
|
|
96
|
+
* what gets masked. logBody is readable by Permission.Viewer, which
|
|
97
|
+
* makes it the widest-reach sink in the product — anything
|
|
98
|
+
* credential-shaped in it is readable by the least-privileged role
|
|
99
|
+
* OneUptime grants. See MonitorPayloadRedaction.
|
|
100
|
+
* https://github.com/OneUptime/oneuptime/issues/3360
|
|
101
|
+
*/
|
|
102
|
+
logBody: redactForPersistence(JSON.parse(JSON.stringify(data.dataToProcess))),
|
|
92
103
|
retentionDate: OneUptimeDate.toClickhouseDateTime(retentionDate),
|
|
93
104
|
};
|
|
94
105
|
this.enqueueRow(monitorLogRow);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MonitorLogUtil.js","sourceRoot":"","sources":["../../../../../Server/Utils/Monitor/MonitorLogUtil.ts"],"names":[],"mappings":"AAAA,OAAO,iBAAiB,MAAM,kCAAkC,CAAC;AACjE,OAAO,mBAAmB,MAAM,oCAAoC,CAAC;AAErE,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,gBAAgB,EAAE,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,aAAa,MAAM,qBAAqB,CAAC;AAChD,OAAO,QAAQ,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"MonitorLogUtil.js","sourceRoot":"","sources":["../../../../../Server/Utils/Monitor/MonitorLogUtil.ts"],"names":[],"mappings":"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"}
|