@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
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import Monitor from "../../../Models/DatabaseModels/Monitor";
|
|
2
|
+
import { ColumnAccessControl } from "../../../Types/BaseDatabase/AccessControl";
|
|
3
|
+
import Dictionary from "../../../Types/Dictionary";
|
|
4
|
+
import Permission, { PermissionHelper } from "../../../Types/Permission";
|
|
5
|
+
import { describe, expect, it } from "@jest/globals";
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* https://github.com/OneUptime/oneuptime/issues/3360
|
|
9
|
+
*
|
|
10
|
+
* Monitor carries three bearer credentials as ordinary columns:
|
|
11
|
+
*
|
|
12
|
+
* serverMonitorSecretKey - authenticates every host agent reporting in
|
|
13
|
+
* incomingRequestSecretKey - IS the heartbeat URL
|
|
14
|
+
* incomingEmailSecretKey - IS the monitor's inbound address
|
|
15
|
+
*
|
|
16
|
+
* All three used to list Permission.Viewer in their read ACL. Viewer is the
|
|
17
|
+
* least privilege OneUptime offers and is precisely what gets handed to a
|
|
18
|
+
* dashboard, an auditor, a contractor or an automation -- so "read-only" also
|
|
19
|
+
* meant "can read a live credential and then forge or suppress this monitor's
|
|
20
|
+
* heartbeats". Redacting the secret out of MonitorLog.logBody (the other half
|
|
21
|
+
* of the fix) does nothing about this path: it is a plain column select.
|
|
22
|
+
*
|
|
23
|
+
* The rule these tests encode is a single sentence: reading a monitor secret
|
|
24
|
+
* requires the ability to ROTATE it. Anything weaker is a credential handed to
|
|
25
|
+
* someone who cannot revoke it.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
const SECRET_KEY_COLUMNS: Array<string> = [
|
|
29
|
+
"serverMonitorSecretKey",
|
|
30
|
+
"incomingRequestSecretKey",
|
|
31
|
+
"incomingEmailSecretKey",
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
/*
|
|
35
|
+
* The read-only roles. Every one of these was on the read list before the fix,
|
|
36
|
+
* and none of them can rotate a key.
|
|
37
|
+
*/
|
|
38
|
+
const READ_ONLY_PERMISSIONS: Array<Permission> = [
|
|
39
|
+
Permission.Viewer,
|
|
40
|
+
Permission.MonitorViewer,
|
|
41
|
+
Permission.ReadProjectMonitor,
|
|
42
|
+
];
|
|
43
|
+
|
|
44
|
+
// The roles that can reset a monitor secret, and so may also see it.
|
|
45
|
+
const ROTATION_PERMISSIONS: Array<Permission> = [
|
|
46
|
+
Permission.ProjectOwner,
|
|
47
|
+
Permission.ProjectAdmin,
|
|
48
|
+
Permission.ProjectMember,
|
|
49
|
+
Permission.MonitorAdmin,
|
|
50
|
+
Permission.MonitorMember,
|
|
51
|
+
Permission.EditProjectMonitor,
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
const accessControl: Dictionary<ColumnAccessControl> =
|
|
55
|
+
new Monitor().getColumnAccessControlForAllColumns();
|
|
56
|
+
|
|
57
|
+
type CanReadFunction = (
|
|
58
|
+
columnName: string,
|
|
59
|
+
userPermissions: Array<Permission>,
|
|
60
|
+
) => boolean;
|
|
61
|
+
|
|
62
|
+
/*
|
|
63
|
+
* ColumnPermission.checkDataColumnPermissions, reduced to the question that
|
|
64
|
+
* matters. Note what the server does when this is false: it THROWS
|
|
65
|
+
* `User is not allowed to read on <column> column of Monitor` and the whole
|
|
66
|
+
* request fails. There is no partial response -- which is why the dashboard
|
|
67
|
+
* has to gate the select rather than the render.
|
|
68
|
+
*/
|
|
69
|
+
const canRead: CanReadFunction = (
|
|
70
|
+
columnName: string,
|
|
71
|
+
userPermissions: Array<Permission>,
|
|
72
|
+
): boolean => {
|
|
73
|
+
const columnPermissions: Array<Permission> =
|
|
74
|
+
accessControl[columnName]?.read || [];
|
|
75
|
+
|
|
76
|
+
return PermissionHelper.doesPermissionsIntersect(
|
|
77
|
+
userPermissions,
|
|
78
|
+
columnPermissions,
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
describe("Monitor secret key columns are not readable by read-only roles", () => {
|
|
83
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
84
|
+
"%s is unreadable by a Viewer-only principal",
|
|
85
|
+
(columnName: string) => {
|
|
86
|
+
/*
|
|
87
|
+
* This is step 2 of the reproduction in the issue: an API key whose only
|
|
88
|
+
* permission is Viewer.
|
|
89
|
+
*/
|
|
90
|
+
expect(canRead(columnName, [Permission.Viewer])).toBe(false);
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
95
|
+
"%s is unreadable by every read-only role, individually",
|
|
96
|
+
(columnName: string) => {
|
|
97
|
+
for (const permission of READ_ONLY_PERMISSIONS) {
|
|
98
|
+
expect(canRead(columnName, [permission])).toBe(false);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
104
|
+
"%s is unreadable even when all the read-only roles are held at once",
|
|
105
|
+
(columnName: string) => {
|
|
106
|
+
/*
|
|
107
|
+
* Intersection semantics mean any single surviving read-only permission
|
|
108
|
+
* re-opens the hole, so hold them all and assert the union is still
|
|
109
|
+
* refused.
|
|
110
|
+
*/
|
|
111
|
+
expect(canRead(columnName, READ_ONLY_PERMISSIONS)).toBe(false);
|
|
112
|
+
},
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
116
|
+
"%s names none of the read-only roles in its read ACL",
|
|
117
|
+
(columnName: string) => {
|
|
118
|
+
const readPermissions: Array<Permission> =
|
|
119
|
+
accessControl[columnName]?.read || [];
|
|
120
|
+
|
|
121
|
+
for (const permission of READ_ONLY_PERMISSIONS) {
|
|
122
|
+
expect(readPermissions).not.toContain(permission);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe("Monitor secret key columns stay readable by the roles that can rotate them", () => {
|
|
129
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
130
|
+
"%s is readable by each rotation-capable role",
|
|
131
|
+
(columnName: string) => {
|
|
132
|
+
/*
|
|
133
|
+
* The other failure mode. Locking these down too far breaks Monitor >
|
|
134
|
+
* Settings for a project member, who legitimately needs the key to set
|
|
135
|
+
* an agent up.
|
|
136
|
+
*/
|
|
137
|
+
for (const permission of ROTATION_PERMISSIONS) {
|
|
138
|
+
expect(canRead(columnName, [permission])).toBe(true);
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
144
|
+
"%s gates read on exactly the same roles as update",
|
|
145
|
+
(columnName: string) => {
|
|
146
|
+
/*
|
|
147
|
+
* The invariant, stated directly: you may see a monitor secret if and
|
|
148
|
+
* only if you may replace it. If someone later widens read without
|
|
149
|
+
* widening update, this is the test that should stop them and make them
|
|
150
|
+
* say why.
|
|
151
|
+
*/
|
|
152
|
+
const column: ColumnAccessControl | undefined = accessControl[columnName];
|
|
153
|
+
|
|
154
|
+
expect(column).toBeDefined();
|
|
155
|
+
expect([...(column?.read || [])].sort()).toEqual(
|
|
156
|
+
[...(column?.update || [])].sort(),
|
|
157
|
+
);
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
it.each(SECRET_KEY_COLUMNS)(
|
|
162
|
+
"%s is never writable on create",
|
|
163
|
+
(columnName: string) => {
|
|
164
|
+
// The keys are computed server-side by MonitorService, never supplied.
|
|
165
|
+
expect(accessControl[columnName]?.create || []).toEqual([]);
|
|
166
|
+
},
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
describe("the rest of the monitor page still loads for a Viewer", () => {
|
|
171
|
+
/*
|
|
172
|
+
* Tightening the secret columns must not collaterally break the monitor view
|
|
173
|
+
* for read-only users: an unreadable column in a select fails the WHOLE
|
|
174
|
+
* request, so if any of these regressed, a Viewer would get an error screen
|
|
175
|
+
* instead of a monitor. These are the other columns
|
|
176
|
+
* Pages/Monitor/View/Index.tsx asks for.
|
|
177
|
+
*/
|
|
178
|
+
const VIEWER_READABLE_COLUMNS: Array<string> = [
|
|
179
|
+
"monitorType",
|
|
180
|
+
"serverMonitorRequestReceivedAt",
|
|
181
|
+
"incomingRequestMonitorHeartbeatCheckedAt",
|
|
182
|
+
"incomingEmailMonitorHeartbeatCheckedAt",
|
|
183
|
+
"incomingEmailMonitorLastEmailReceivedAt",
|
|
184
|
+
"monitorSteps",
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
it.each(VIEWER_READABLE_COLUMNS)(
|
|
188
|
+
"%s is still readable by a Viewer",
|
|
189
|
+
(columnName: string) => {
|
|
190
|
+
expect(canRead(columnName, [Permission.Viewer])).toBe(true);
|
|
191
|
+
},
|
|
192
|
+
);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
describe("the payload columns rely on redaction, not on access control", () => {
|
|
196
|
+
/*
|
|
197
|
+
* serverMonitorResponse and incomingMonitorRequest are the OTHER two places
|
|
198
|
+
* the agent payload lands, and both remain Viewer-readable -- deliberately:
|
|
199
|
+
* they are what the monitor page renders. That is exactly why the secret has
|
|
200
|
+
* to be stripped at the ingest boundary (see MonitorPayloadRedaction) rather
|
|
201
|
+
* than merely hidden behind a permission. If someone ever removes that
|
|
202
|
+
* strip, no ACL here will catch it.
|
|
203
|
+
*
|
|
204
|
+
* This test is a signpost, not a guard. If these columns are deliberately
|
|
205
|
+
* locked down later, delete it -- but do not delete the redaction.
|
|
206
|
+
*/
|
|
207
|
+
it("serverMonitorResponse is readable by a Viewer", () => {
|
|
208
|
+
expect(canRead("serverMonitorResponse", [Permission.Viewer])).toBe(true);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("incomingMonitorRequest is readable by a Viewer", () => {
|
|
212
|
+
expect(canRead("incomingMonitorRequest", [Permission.Viewer])).toBe(true);
|
|
213
|
+
});
|
|
214
|
+
});
|