@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
|
@@ -59,7 +59,7 @@ import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
|
59
59
|
* to be tempted will add a button, not a sentence.
|
|
60
60
|
*
|
|
61
61
|
* - AN ADMIN READING SOMEBODY ELSE'S PHONE NUMBER, which is the same defect
|
|
62
|
-
* one step earlier and is what this page originally did. The
|
|
62
|
+
* one step earlier and is what this page originally did. The nine method
|
|
63
63
|
* models are scoped to the person who owns the device - the columns behind
|
|
64
64
|
* them are the raw number, the webhook bearer url, the push device token,
|
|
65
65
|
* the telegram chat id and the verification code - and that scope was
|
|
@@ -389,8 +389,10 @@ import TeamMember from "../../../Models/DatabaseModels/TeamMember";
|
|
|
389
389
|
import User from "../../../Models/DatabaseModels/User";
|
|
390
390
|
import UserCall from "../../../Models/DatabaseModels/UserCall";
|
|
391
391
|
import UserEmail from "../../../Models/DatabaseModels/UserEmail";
|
|
392
|
+
import UserMicrosoftTeams from "../../../Models/DatabaseModels/UserMicrosoftTeams";
|
|
392
393
|
import UserNotificationRule from "../../../Models/DatabaseModels/UserNotificationRule";
|
|
393
394
|
import UserPush from "../../../Models/DatabaseModels/UserPush";
|
|
395
|
+
import UserSlack from "../../../Models/DatabaseModels/UserSlack";
|
|
394
396
|
import UserSMS from "../../../Models/DatabaseModels/UserSMS";
|
|
395
397
|
import UserTelegram from "../../../Models/DatabaseModels/UserTelegram";
|
|
396
398
|
import UserWebhook from "../../../Models/DatabaseModels/UserWebhook";
|
|
@@ -413,7 +415,7 @@ const PROJECT_ID: ObjectID = new ObjectID(PROJECT_ID_STRING);
|
|
|
413
415
|
const SIGNED_IN_USER_ID: ObjectID = new ObjectID(SIGNED_IN_USER_ID_STRING);
|
|
414
416
|
|
|
415
417
|
/*
|
|
416
|
-
* The
|
|
418
|
+
* The nine models only their owner may read. They are asserted as a SET because
|
|
417
419
|
* which one an admin surface reaches for hardly matters - every one of them
|
|
418
420
|
* carries a raw identifier and most carry a credential.
|
|
419
421
|
*/
|
|
@@ -424,11 +426,13 @@ const NOTIFICATION_METHOD_MODELS: Array<unknown> = [
|
|
|
424
426
|
UserPush,
|
|
425
427
|
UserWhatsApp,
|
|
426
428
|
UserTelegram,
|
|
429
|
+
UserSlack,
|
|
430
|
+
UserMicrosoftTeams,
|
|
427
431
|
UserWebhook,
|
|
428
432
|
];
|
|
429
433
|
|
|
430
434
|
/*
|
|
431
|
-
* The RELATION spelling of those same
|
|
435
|
+
* The RELATION spelling of those same nine, as they appear in a nested select
|
|
432
436
|
* on UserNotificationRule. Selecting any of them pulls a column out of the
|
|
433
437
|
* method model itself - the address, the number, the handle - through a table
|
|
434
438
|
* an administrator may read and which is not row-scoped for them. It is the
|
|
@@ -442,6 +446,8 @@ const METHOD_RELATION_KEYS: Array<string> = [
|
|
|
442
446
|
"userPush",
|
|
443
447
|
"userWhatsApp",
|
|
444
448
|
"userTelegram",
|
|
449
|
+
"userSlack",
|
|
450
|
+
"userMicrosoftTeams",
|
|
445
451
|
"userWebhook",
|
|
446
452
|
];
|
|
447
453
|
|
|
@@ -453,6 +459,8 @@ const METHOD_FOREIGN_KEYS: Array<keyof UserNotificationRule> = [
|
|
|
453
459
|
"userPushId",
|
|
454
460
|
"userWhatsAppId",
|
|
455
461
|
"userTelegramId",
|
|
462
|
+
"userSlackId",
|
|
463
|
+
"userMicrosoftTeamsId",
|
|
456
464
|
"userWebhookId",
|
|
457
465
|
];
|
|
458
466
|
|
|
@@ -673,7 +681,7 @@ const setUpLists: SetUpListsFunction = (
|
|
|
673
681
|
}
|
|
674
682
|
|
|
675
683
|
/*
|
|
676
|
-
* Anything else, INCLUDING the
|
|
684
|
+
* Anything else, INCLUDING the nine notification-method models - which this
|
|
677
685
|
* page must never ask for. A non-empty answer here would make a leak look
|
|
678
686
|
* like a feature working, so the fallback stays empty and the assertion that
|
|
679
687
|
* matters is about the request rather than the response: see "never reads a
|
|
@@ -1172,7 +1180,7 @@ afterEach(async (): Promise<void> => {
|
|
|
1172
1180
|
|
|
1173
1181
|
/*
|
|
1174
1182
|
* Unmounting stops the RENDERING, not the fetching. A rule table that belongs
|
|
1175
|
-
* to the viewer loads the
|
|
1183
|
+
* to the viewer loads the nine notification-method models one after another,
|
|
1176
1184
|
* so a test that reads its own page leaves a chain of awaits running after its
|
|
1177
1185
|
* last assertion - and every one of those calls is recorded on the same
|
|
1178
1186
|
* `getListMock` the next test resets and then asserts against.
|
|
@@ -1365,14 +1373,14 @@ describe("the page is read at rest, whichever order its fetches land in", () =>
|
|
|
1365
1373
|
assertEveryTableIsSettled();
|
|
1366
1374
|
});
|
|
1367
1375
|
|
|
1368
|
-
test("waits out the
|
|
1376
|
+
test("waits out the nine method reads a self-serve page makes for its owner", async () => {
|
|
1369
1377
|
// A self-serve page is always the viewer's own, so this is the owner path.
|
|
1370
1378
|
await renderSelfServePage(IncidentOnCallRules);
|
|
1371
1379
|
|
|
1372
1380
|
/*
|
|
1373
|
-
* A rule table belonging to the viewer loads the
|
|
1381
|
+
* A rule table belonging to the viewer loads the nine notification-method
|
|
1374
1382
|
* models one after another, and unmounting the page does not stop that
|
|
1375
|
-
* chain - it stops the rendering. Any of those
|
|
1383
|
+
* chain - it stops the rendering. Any of those nine still running when the
|
|
1376
1384
|
* next test resets `getListMock` is recorded as that test's request, which
|
|
1377
1385
|
* is how "never reads a notification method model" comes to fail on a page
|
|
1378
1386
|
* that never asked for one.
|
|
@@ -1484,7 +1492,7 @@ describe("the shared rules table, as the admin page wires it", () => {
|
|
|
1484
1492
|
/*
|
|
1485
1493
|
* The redesign, in one assertion.
|
|
1486
1494
|
*
|
|
1487
|
-
* These
|
|
1495
|
+
* These nine models are readable only by the person who owns the row, and
|
|
1488
1496
|
* that is the whole protection: the table scope pins every read to the
|
|
1489
1497
|
* caller. Widening it so this page could fill a dropdown exposed the raw
|
|
1490
1498
|
* email and phone, the webhook url, the push device token, the telegram chat
|
|
@@ -1619,7 +1627,7 @@ describe("the shared rules table, as the admin page wires it", () => {
|
|
|
1619
1627
|
});
|
|
1620
1628
|
|
|
1621
1629
|
/*
|
|
1622
|
-
* The
|
|
1630
|
+
* The nine foreign keys are mutually exclusive, and writing an SMS id into
|
|
1623
1631
|
* `userEmailId` would page an address instead of a phone without erroring
|
|
1624
1632
|
* anywhere, so the whole set is asserted rather than the one column.
|
|
1625
1633
|
*/
|
|
@@ -1639,7 +1647,7 @@ describe("the shared rules table, as the admin page wires it", () => {
|
|
|
1639
1647
|
/*
|
|
1640
1648
|
* The failure mode this seam had to be designed around. Readiness is the
|
|
1641
1649
|
* only source of methods here, so when it is down there are none to offer -
|
|
1642
|
-
* and "then read the models directly" is not a fallback, it is
|
|
1650
|
+
* and "then read the models directly" is not a fallback, it is nine refused
|
|
1643
1651
|
* requests that would replace the rule tables with an error page. The rules
|
|
1644
1652
|
* stay editable; only the method choice is missing.
|
|
1645
1653
|
*/
|
|
@@ -2002,7 +2010,7 @@ describe("methods are a page of their own now, not a card on this one", () => {
|
|
|
2002
2010
|
* It asserted that an administrator was offered NO control for adding a
|
|
2003
2011
|
* notification method to somebody else's account: a masked, read-only list
|
|
2004
2012
|
* and a prefilled "please add one yourself" email. That was correct for what
|
|
2005
|
-
* the server could do at the time - the
|
|
2013
|
+
* the server could do at the time - the nine method models are scoped to
|
|
2006
2014
|
* their owner and the attempt to widen them leaked every raw column behind
|
|
2007
2015
|
* them - but it left the commonest broken responder, a new joiner with no
|
|
2008
2016
|
* method at all, fixable by nobody but themselves.
|
|
@@ -2167,7 +2175,7 @@ describe("the coverage grid, now shared with the readiness page", () => {
|
|
|
2167
2175
|
* The edit path.
|
|
2168
2176
|
*
|
|
2169
2177
|
* `isEditable` was hardcoded false on the ModelTable, so this page issued no
|
|
2170
|
-
* PATCH at all: the phase opened `notifyAfterMinutes` (and the
|
|
2178
|
+
* PATCH at all: the phase opened `notifyAfterMinutes` (and the nine method
|
|
2171
2179
|
* foreign keys) to update behind the largest guard in the codebase, and bought
|
|
2172
2180
|
* zero capability anybody could reach. These assertions are about the two halves
|
|
2173
2181
|
* of making that real - the editor being on for exactly the viewers allowed to
|
|
@@ -2225,7 +2233,7 @@ describe("the rules are editable, not merely addable and removable", () => {
|
|
|
2225
2233
|
|
|
2226
2234
|
/*
|
|
2227
2235
|
* The dropdown is an override field: its value travels in `miscDataProps`
|
|
2228
|
-
* and is mapped onto one of the
|
|
2236
|
+
* and is mapped onto one of the nine foreign keys by `onBeforeCreate`.
|
|
2229
2237
|
* ModelForm calls that hook only for FormType.Create and BaseAPI.updateItem
|
|
2230
2238
|
* never reads `miscDataProps`, so on the edit path the choice is discarded
|
|
2231
2239
|
* in transit. Rendering it anyway would give an administrator a control
|
|
@@ -33,7 +33,7 @@ import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
|
33
33
|
* decision satisfied by the new answer.
|
|
34
34
|
*
|
|
35
35
|
* The old surface showed a masked, read-only list and a prefilled "please add
|
|
36
|
-
* one yourself" email, because the
|
|
36
|
+
* one yourself" email, because the nine notification method models are scoped
|
|
37
37
|
* to the person who owns the device: the columns behind them are the raw
|
|
38
38
|
* address, the phone number, the webhook bearer url, the push device token and
|
|
39
39
|
* the verification code, and an attempt to widen that scope so an admin could
|
|
@@ -44,7 +44,7 @@ import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
|
44
44
|
* So the models are STILL owner-scoped, and this page talks to a narrow
|
|
45
45
|
* server-side capability instead. What that buys, and what it must not:
|
|
46
46
|
*
|
|
47
|
-
* - NO METHOD MODEL IS READ. Not by ModelAPI over UserEmail and its
|
|
47
|
+
* - NO METHOD MODEL IS READ. Not by ModelAPI over UserEmail and its eight
|
|
48
48
|
* siblings, and not through a nested relation select on a rule, which
|
|
49
49
|
* reaches the same columns through a table an administrator IS allowed to
|
|
50
50
|
* read. The assertion is about the REQUEST, because a component that asks
|
|
@@ -192,7 +192,7 @@ jest.mock("react-i18next", () => {
|
|
|
192
192
|
* A stand-in ModelTable that records the model it was mounted over.
|
|
193
193
|
*
|
|
194
194
|
* It renders nothing on purpose. What this file needs from it is the single
|
|
195
|
-
* fact that a table over UserEmail (or any of its
|
|
195
|
+
* fact that a table over UserEmail (or any of its eight siblings) would be
|
|
196
196
|
* visible here at all — the self-serve method components mount exactly those,
|
|
197
197
|
* so "did the admin branch accidentally render the self-serve one?" is answered
|
|
198
198
|
* by this list.
|
|
@@ -217,7 +217,9 @@ import TeamMember from "../../../Models/DatabaseModels/TeamMember";
|
|
|
217
217
|
import User from "../../../Models/DatabaseModels/User";
|
|
218
218
|
import UserCall from "../../../Models/DatabaseModels/UserCall";
|
|
219
219
|
import UserEmail from "../../../Models/DatabaseModels/UserEmail";
|
|
220
|
+
import UserMicrosoftTeams from "../../../Models/DatabaseModels/UserMicrosoftTeams";
|
|
220
221
|
import UserPush from "../../../Models/DatabaseModels/UserPush";
|
|
222
|
+
import UserSlack from "../../../Models/DatabaseModels/UserSlack";
|
|
221
223
|
import UserSMS from "../../../Models/DatabaseModels/UserSMS";
|
|
222
224
|
import UserTelegram from "../../../Models/DatabaseModels/UserTelegram";
|
|
223
225
|
import UserWebhook from "../../../Models/DatabaseModels/UserWebhook";
|
|
@@ -238,7 +240,7 @@ const PROJECT_ID: ObjectID = new ObjectID(PROJECT_ID_STRING);
|
|
|
238
240
|
const SIGNED_IN_USER_ID: ObjectID = new ObjectID(SIGNED_IN_USER_ID_STRING);
|
|
239
241
|
|
|
240
242
|
/*
|
|
241
|
-
* The
|
|
243
|
+
* The nine models only their owner may read. Asserted as a SET because which
|
|
242
244
|
* one an admin surface reaches for hardly matters — every one carries a raw
|
|
243
245
|
* identifier and most carry a credential.
|
|
244
246
|
*/
|
|
@@ -249,6 +251,8 @@ const NOTIFICATION_METHOD_MODELS: Array<unknown> = [
|
|
|
249
251
|
UserPush,
|
|
250
252
|
UserWhatsApp,
|
|
251
253
|
UserTelegram,
|
|
254
|
+
UserSlack,
|
|
255
|
+
UserMicrosoftTeams,
|
|
252
256
|
UserWebhook,
|
|
253
257
|
];
|
|
254
258
|
|
|
@@ -486,7 +490,7 @@ beforeEach((): void => {
|
|
|
486
490
|
}
|
|
487
491
|
|
|
488
492
|
/*
|
|
489
|
-
* Anything else, INCLUDING the
|
|
493
|
+
* Anything else, INCLUDING the nine method models this page must never ask
|
|
490
494
|
* for. A non-empty answer would make a leak look like a feature working, so
|
|
491
495
|
* the fallback stays empty and the assertion that matters is about the
|
|
492
496
|
* request rather than the response.
|
|
@@ -570,7 +574,7 @@ describe("the list", () => {
|
|
|
570
574
|
);
|
|
571
575
|
|
|
572
576
|
/*
|
|
573
|
-
* The assertion is about the REQUEST, not the render. The
|
|
577
|
+
* The assertion is about the REQUEST, not the render. The nine models are
|
|
574
578
|
* scoped to their owner, so a read here would be refused — but a component
|
|
575
579
|
* that asks is already wrong, and the refusal is not something this page
|
|
576
580
|
* may rely on.
|
|
@@ -657,10 +661,11 @@ describe("adding a method on somebody's behalf", () => {
|
|
|
657
661
|
|
|
658
662
|
/*
|
|
659
663
|
* Push is a device token minted at registration — there is nothing to type.
|
|
660
|
-
* Telegram needs the account holder to message the bot first.
|
|
661
|
-
*
|
|
662
|
-
*
|
|
663
|
-
*
|
|
664
|
+
* Telegram needs the account holder to message the bot first. Slack and
|
|
665
|
+
* Microsoft Teams are born from the account holder's own OAuth workspace
|
|
666
|
+
* link, which nobody can establish for them. Webhook has no verification
|
|
667
|
+
* at all, so an admin-created one would be live the instant it was
|
|
668
|
+
* written, which is exactly the silent redirect this design rules out.
|
|
664
669
|
*/
|
|
665
670
|
const modalText: string = document.body.textContent || "";
|
|
666
671
|
|
|
@@ -674,7 +679,13 @@ describe("adding a method on somebody's behalf", () => {
|
|
|
674
679
|
return option.textContent || "";
|
|
675
680
|
});
|
|
676
681
|
|
|
677
|
-
for (const forbidden of [
|
|
682
|
+
for (const forbidden of [
|
|
683
|
+
"Push",
|
|
684
|
+
"Telegram",
|
|
685
|
+
"Slack",
|
|
686
|
+
"Microsoft Teams",
|
|
687
|
+
"Webhook",
|
|
688
|
+
]) {
|
|
678
689
|
expect(optionLabels).not.toContain(forbidden);
|
|
679
690
|
}
|
|
680
691
|
});
|
|
@@ -122,14 +122,18 @@ import CallMethods from "../../../../App/FeatureSet/Dashboard/src/Components/Not
|
|
|
122
122
|
import PushMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Push";
|
|
123
123
|
import WhatsAppMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/WhatsApp";
|
|
124
124
|
import TelegramMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Telegram";
|
|
125
|
+
import SlackMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Slack";
|
|
126
|
+
import MicrosoftTeamsMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/MicrosoftTeams";
|
|
125
127
|
import WebhookMethods from "../../../../App/FeatureSet/Dashboard/src/Components/NotificationMethods/Webhook";
|
|
126
128
|
import BaseModel, {
|
|
127
129
|
DatabaseBaseModelType,
|
|
128
130
|
} from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
129
131
|
import UserCall from "../../../Models/DatabaseModels/UserCall";
|
|
130
132
|
import UserEmail from "../../../Models/DatabaseModels/UserEmail";
|
|
133
|
+
import UserMicrosoftTeams from "../../../Models/DatabaseModels/UserMicrosoftTeams";
|
|
131
134
|
import UserNotificationRule from "../../../Models/DatabaseModels/UserNotificationRule";
|
|
132
135
|
import UserPush from "../../../Models/DatabaseModels/UserPush";
|
|
136
|
+
import UserSlack from "../../../Models/DatabaseModels/UserSlack";
|
|
133
137
|
import UserSMS from "../../../Models/DatabaseModels/UserSMS";
|
|
134
138
|
import UserTelegram from "../../../Models/DatabaseModels/UserTelegram";
|
|
135
139
|
import UserWebhook from "../../../Models/DatabaseModels/UserWebhook";
|
|
@@ -1470,7 +1474,7 @@ describe("Escalation rules, wired: the delete confirmation says what it costs",
|
|
|
1470
1474
|
|
|
1471
1475
|
/*
|
|
1472
1476
|
* ---------------------------------------------------------------------------
|
|
1473
|
-
* THE
|
|
1477
|
+
* THE NINE METHOD TABLES, RENDERED FOR REAL.
|
|
1474
1478
|
* ---------------------------------------------------------------------------
|
|
1475
1479
|
*
|
|
1476
1480
|
* This block exists because the first cut of this feature shipped a correct,
|
|
@@ -1532,6 +1536,8 @@ const METHOD_ID_CALL: string = "33333333-9999-4999-8999-999999999999";
|
|
|
1532
1536
|
const METHOD_ID_PUSH: string = "44444444-aaaa-4aaa-8aaa-aaaaaaaaaaaa";
|
|
1533
1537
|
const METHOD_ID_WHATSAPP: string = "55555555-bbbb-4bbb-8bbb-bbbbbbbbbbbb";
|
|
1534
1538
|
const METHOD_ID_TELEGRAM: string = "66666666-cccc-4ccc-8ccc-cccccccccccc";
|
|
1539
|
+
const METHOD_ID_SLACK: string = "88888888-eeee-4eee-8eee-eeeeeeeeeeee";
|
|
1540
|
+
const METHOD_ID_TEAMS: string = "99999999-ffff-4fff-8fff-ffffffffffff";
|
|
1535
1541
|
const METHOD_ID_WEBHOOK: string = "77777777-dddd-4ddd-8ddd-dddddddddddd";
|
|
1536
1542
|
|
|
1537
1543
|
const METHOD_SURFACES: Array<MethodSurface> = [
|
|
@@ -1624,6 +1630,36 @@ const METHOD_SURFACES: Array<MethodSurface> = [
|
|
|
1624
1630
|
modalTitle: "Delete Telegram Account",
|
|
1625
1631
|
methodLabel: "Telegram: @alexchen",
|
|
1626
1632
|
},
|
|
1633
|
+
{
|
|
1634
|
+
name: "Slack",
|
|
1635
|
+
Component: SlackMethods,
|
|
1636
|
+
modelType: UserSlack,
|
|
1637
|
+
relationName: "userSlack",
|
|
1638
|
+
methodId: METHOD_ID_SLACK,
|
|
1639
|
+
buildRow: (): BaseModel => {
|
|
1640
|
+
return buildMethodRow(UserSlack, METHOD_ID_SLACK, {
|
|
1641
|
+
slackUserName: "alexchen",
|
|
1642
|
+
isVerified: true,
|
|
1643
|
+
});
|
|
1644
|
+
},
|
|
1645
|
+
modalTitle: "Delete Slack Account",
|
|
1646
|
+
methodLabel: "Slack: alexchen",
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
name: "Microsoft Teams",
|
|
1650
|
+
Component: MicrosoftTeamsMethods,
|
|
1651
|
+
modelType: UserMicrosoftTeams,
|
|
1652
|
+
relationName: "userMicrosoftTeams",
|
|
1653
|
+
methodId: METHOD_ID_TEAMS,
|
|
1654
|
+
buildRow: (): BaseModel => {
|
|
1655
|
+
return buildMethodRow(UserMicrosoftTeams, METHOD_ID_TEAMS, {
|
|
1656
|
+
microsoftTeamsUserName: "Alex Example",
|
|
1657
|
+
isVerified: true,
|
|
1658
|
+
});
|
|
1659
|
+
},
|
|
1660
|
+
modalTitle: "Delete Microsoft Teams Account",
|
|
1661
|
+
methodLabel: "Microsoft Teams: Alex Example",
|
|
1662
|
+
},
|
|
1627
1663
|
{
|
|
1628
1664
|
name: "Webhook",
|
|
1629
1665
|
Component: WebhookMethods,
|
|
@@ -38,7 +38,7 @@ import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
|
38
38
|
*
|
|
39
39
|
* The fourth is where the "Notification Method" dropdown comes from, which is
|
|
40
40
|
* now two different places depending on whose rules are on screen. For the
|
|
41
|
-
* signed-in user it is still
|
|
41
|
+
* signed-in user it is still nine reads of the nine method models, and that
|
|
42
42
|
* path is the four settings pages every existing user relies on. For anybody
|
|
43
43
|
* else those reads are REFUSED - the models are scoped to the person who owns
|
|
44
44
|
* the device, because the columns behind them are the raw phone number, the
|
|
@@ -186,8 +186,10 @@ import AlertSeverity from "../../../Models/DatabaseModels/AlertSeverity";
|
|
|
186
186
|
import IncidentSeverity from "../../../Models/DatabaseModels/IncidentSeverity";
|
|
187
187
|
import UserCall from "../../../Models/DatabaseModels/UserCall";
|
|
188
188
|
import UserEmail from "../../../Models/DatabaseModels/UserEmail";
|
|
189
|
+
import UserMicrosoftTeams from "../../../Models/DatabaseModels/UserMicrosoftTeams";
|
|
189
190
|
import UserNotificationRule from "../../../Models/DatabaseModels/UserNotificationRule";
|
|
190
191
|
import UserPush from "../../../Models/DatabaseModels/UserPush";
|
|
192
|
+
import UserSlack from "../../../Models/DatabaseModels/UserSlack";
|
|
191
193
|
import UserSMS from "../../../Models/DatabaseModels/UserSMS";
|
|
192
194
|
import UserTelegram from "../../../Models/DatabaseModels/UserTelegram";
|
|
193
195
|
import UserWebhook from "../../../Models/DatabaseModels/UserWebhook";
|
|
@@ -199,7 +201,7 @@ import ObjectID from "../../../Types/ObjectID";
|
|
|
199
201
|
import ProjectUtil from "../../../UI/Utils/Project";
|
|
200
202
|
|
|
201
203
|
/*
|
|
202
|
-
* The
|
|
204
|
+
* The nine models whose rows only their owner may read. They are listed
|
|
203
205
|
* together because the assertion that matters is about the SET: an admin
|
|
204
206
|
* surface that reads any one of them is reading a row it is not entitled to,
|
|
205
207
|
* and which one hardly matters.
|
|
@@ -211,13 +213,15 @@ const NOTIFICATION_METHOD_MODELS: Array<unknown> = [
|
|
|
211
213
|
UserPush,
|
|
212
214
|
UserWhatsApp,
|
|
213
215
|
UserTelegram,
|
|
216
|
+
UserSlack,
|
|
217
|
+
UserMicrosoftTeams,
|
|
214
218
|
UserWebhook,
|
|
215
219
|
];
|
|
216
220
|
|
|
217
221
|
/*
|
|
218
222
|
* What the admin surface hands over in place of those reads: a channel name, the
|
|
219
223
|
* id of the row, and a mask. Telegram is unverified on purpose - the self-serve
|
|
220
|
-
* path filters `isVerified: true` in
|
|
224
|
+
* path filters `isVerified: true` in eight of its nine queries, so a supplied
|
|
221
225
|
* list that offered unverified methods would be the two paths disagreeing about
|
|
222
226
|
* what is pickable.
|
|
223
227
|
*/
|
|
@@ -250,6 +254,8 @@ const METHOD_FOREIGN_KEYS: Array<keyof UserNotificationRule> = [
|
|
|
250
254
|
"userPushId",
|
|
251
255
|
"userWhatsAppId",
|
|
252
256
|
"userTelegramId",
|
|
257
|
+
"userSlackId",
|
|
258
|
+
"userMicrosoftTeamsId",
|
|
253
259
|
"userWebhookId",
|
|
254
260
|
];
|
|
255
261
|
|
|
@@ -343,7 +349,7 @@ const getMethodOptions: GetMethodOptions = (
|
|
|
343
349
|
};
|
|
344
350
|
|
|
345
351
|
/*
|
|
346
|
-
* The
|
|
352
|
+
* The nine RELATION spellings. Selecting any of these on a rule pulls columns
|
|
347
353
|
* out of the method models themselves - the raw address, the raw number, the
|
|
348
354
|
* telegram handle - through a table an administrator is allowed to read.
|
|
349
355
|
*
|
|
@@ -366,6 +372,8 @@ const METHOD_RELATIONS: Array<string> = [
|
|
|
366
372
|
"userPush",
|
|
367
373
|
"userWhatsApp",
|
|
368
374
|
"userTelegram",
|
|
375
|
+
"userSlack",
|
|
376
|
+
"userMicrosoftTeams",
|
|
369
377
|
"userWebhook",
|
|
370
378
|
];
|
|
371
379
|
|
|
@@ -719,7 +727,7 @@ describe("OnCallRulesTable", () => {
|
|
|
719
727
|
|
|
720
728
|
/*
|
|
721
729
|
* The whole point of the redesign, in one assertion. Not "reads them and
|
|
722
|
-
* shows fewer columns" - does not read them. Each of these
|
|
730
|
+
* shows fewer columns" - does not read them. Each of these nine models is
|
|
723
731
|
* scoped to the person who owns the device, and the columns behind them are
|
|
724
732
|
* the raw phone number, the webhook bearer url, the push device token, the
|
|
725
733
|
* telegram chat id and the verification code. A request here is a request
|
|
@@ -748,7 +756,7 @@ describe("OnCallRulesTable", () => {
|
|
|
748
756
|
* The readiness payload the admin page sources these from is fetched
|
|
749
757
|
* asynchronously and can fail outright, so an absent list is a real state
|
|
750
758
|
* rather than a caller mistake. Treating it as "then fetch them yourself"
|
|
751
|
-
* would fire
|
|
759
|
+
* would fire nine refused requests and turn this component's error state on
|
|
752
760
|
* - taking the rule repair away because a DIFFERENT read failed.
|
|
753
761
|
*/
|
|
754
762
|
await renderForOtherUser(undefined);
|
|
@@ -786,7 +794,7 @@ describe("OnCallRulesTable", () => {
|
|
|
786
794
|
|
|
787
795
|
/*
|
|
788
796
|
* The unverified Telegram method is absent, which mirrors the
|
|
789
|
-
* `isVerified: true` filter on
|
|
797
|
+
* `isVerified: true` filter on eight of the nine self-serve queries. A rule
|
|
790
798
|
* pointed at an unverified device is a rule that pages nothing.
|
|
791
799
|
*/
|
|
792
800
|
expect(
|
|
@@ -805,7 +813,7 @@ describe("OnCallRulesTable", () => {
|
|
|
805
813
|
});
|
|
806
814
|
|
|
807
815
|
/*
|
|
808
|
-
* The
|
|
816
|
+
* The nine foreign keys are mutually exclusive and nothing validates that
|
|
809
817
|
* client-side, so this asserts the whole set: an SMS id written to
|
|
810
818
|
* `userEmailId` would page an address rather than a phone, and would not
|
|
811
819
|
* error anywhere on the way.
|
|
@@ -968,7 +976,7 @@ describe("OnCallRulesTable", () => {
|
|
|
968
976
|
test("the signed-in user's own table still reads the method models itself", async () => {
|
|
969
977
|
/*
|
|
970
978
|
* The regression surface. Four settings pages every existing user already
|
|
971
|
-
* relies on read their own
|
|
979
|
+
* relies on read their own nine models to fill this dropdown, and reading
|
|
972
980
|
* your own rows is exactly what those models allow. Nothing about the admin
|
|
973
981
|
* surface is a reason to change it - and an unmasked label is more use to
|
|
974
982
|
* somebody looking at their own phone number than a mask of it.
|
|
@@ -985,7 +993,7 @@ describe("OnCallRulesTable", () => {
|
|
|
985
993
|
getQueriedUserIds().filter((userId: string | undefined) => {
|
|
986
994
|
return userId === CURRENT_USER_ID_STRING;
|
|
987
995
|
}),
|
|
988
|
-
).toHaveLength(
|
|
996
|
+
).toHaveLength(9);
|
|
989
997
|
|
|
990
998
|
expect(getMethodOptions(capturedTables[0]!)).toEqual([
|
|
991
999
|
{ label: `Email: ${OWN_EMAIL_ADDRESS}`, value: OWN_EMAIL_ID },
|
|
@@ -117,6 +117,30 @@ const NOT_READABLE_BY_THEIR_DOMAIN_ROLES: Array<string> = [
|
|
|
117
117
|
"IncomingCallPolicyEscalationRule",
|
|
118
118
|
];
|
|
119
119
|
|
|
120
|
+
/*
|
|
121
|
+
* Columns inside an in-domain table whose read list deliberately stops short of
|
|
122
|
+
* the domain's full tier set, and why. The table-level list above is about
|
|
123
|
+
* whole tables a role holder is kept out of; this is the same idea one level
|
|
124
|
+
* down, for a table they are otherwise welcome in.
|
|
125
|
+
*
|
|
126
|
+
* Entries are the exact `<table>.<column> is missing <tier>` strings the sweep
|
|
127
|
+
* produces, so the list is self-policing: widen one of these read lists again
|
|
128
|
+
* and the entry stops being produced and the assertion fails.
|
|
129
|
+
*
|
|
130
|
+
* https://github.com/OneUptime/oneuptime/issues/3360 - Monitor's three secret
|
|
131
|
+
* keys are bearer credentials, not monitor data. Reading one is gated on being
|
|
132
|
+
* able to ROTATE it, which is what separates MonitorMember (may edit a monitor,
|
|
133
|
+
* so may see and reset its key) from MonitorViewer (read-only, so may not).
|
|
134
|
+
* Viewer used to be on these lists, which made "read-only" mean "can read a
|
|
135
|
+
* live credential for every agent in the project" -- the same reasoning that
|
|
136
|
+
* keeps MonitorSecret out of the table list above.
|
|
137
|
+
*/
|
|
138
|
+
const COLUMNS_NOT_READABLE_BY_THEIR_DOMAIN_ROLES: Array<string> = [
|
|
139
|
+
"Monitor.incomingEmailSecretKey is missing MonitorViewer",
|
|
140
|
+
"Monitor.incomingRequestSecretKey is missing MonitorViewer",
|
|
141
|
+
"Monitor.serverMonitorSecretKey is missing MonitorViewer",
|
|
142
|
+
];
|
|
143
|
+
|
|
120
144
|
type ModelNameFunction = (modelType: ModelType) => string;
|
|
121
145
|
|
|
122
146
|
const modelName: ModelNameFunction = (modelType: ModelType): string => {
|
|
@@ -317,7 +341,9 @@ describe("Domain role tier coverage", () => {
|
|
|
317
341
|
}
|
|
318
342
|
}
|
|
319
343
|
|
|
320
|
-
expect(missing.sort()).toEqual(
|
|
344
|
+
expect(missing.sort()).toEqual(
|
|
345
|
+
COLUMNS_NOT_READABLE_BY_THEIR_DOMAIN_ROLES.slice().sort(),
|
|
346
|
+
);
|
|
321
347
|
expect(checked).toBeGreaterThan(500);
|
|
322
348
|
});
|
|
323
349
|
});
|