@oneuptime/common 12.0.12 → 12.0.13
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/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
- package/Models/DatabaseModels/NetworkDevice.ts +64 -0
- package/Models/DatabaseModels/StatusPage.ts +59 -0
- package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
- package/Server/API/AIChatAPI.ts +55 -56
- package/Server/API/CommonAPI.ts +89 -0
- package/Server/API/MicrosoftTeamsAPI.ts +20 -9
- package/Server/API/SlackAPI.ts +13 -10
- package/Server/API/StatusPageAPI.ts +2197 -2128
- package/Server/API/TelemetryAPI.ts +72 -3
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/UserAuthorization.ts +11 -2
- package/Server/Services/ApiKeyPermissionService.ts +116 -2
- package/Server/Services/DatabaseService.ts +17 -6
- package/Server/Services/LogAggregationService.ts +34 -0
- package/Server/Services/LogService.ts +21 -0
- package/Server/Services/NetworkSiteService.ts +12 -0
- package/Server/Services/SpanService.ts +21 -0
- package/Server/Services/TraceAggregationService.ts +15 -0
- package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
- package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
- package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
- package/Server/Utils/APIKey/AccessPermission.ts +16 -40
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
- package/Server/Utils/LogRedaction.ts +576 -0
- package/Server/Utils/Logger.ts +123 -46
- package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
- package/Server/Utils/Monitor/MonitorResource.ts +29 -9
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
- package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
- package/Server/Utils/StartServer.ts +30 -9
- package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
- package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
- package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +300 -0
- package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
- package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
- package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
- package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
- package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
- package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
- package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
- package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
- package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
- package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
- package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
- package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
- package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +332 -0
- package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
- package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
- package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
- package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
- package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
- package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
- package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
- package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
- package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
- package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
- package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
- package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
- package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
- package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
- package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
- package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
- package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
- package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
- package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
- package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
- package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
- package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
- package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
- package/Tests/UI/Components/MasterPage.test.tsx +36 -1
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
- package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
- package/Types/API/Hostname.ts +79 -0
- package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
- package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
- package/Types/Database/DatabaseProperty.ts +38 -0
- package/Types/Database/TableColumn.ts +34 -7
- package/Types/Events/Recurring.ts +16 -1
- package/Types/Monitor/MonitorStep.ts +13 -1
- package/Types/Monitor/MonitorType.ts +345 -40
- package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
- package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
- package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
- package/UI/Components/CardSelect/CardSelect.tsx +714 -105
- package/UI/Components/EmptyState/EmptyState.tsx +8 -1
- package/UI/Components/Footer/Footer.tsx +32 -6
- package/UI/Components/Forms/Fields/FormField.tsx +3 -0
- package/UI/Components/Forms/Types/Field.ts +8 -0
- package/UI/Components/Loader/PageLoader.tsx +29 -8
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
- package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +17 -1
- package/UI/Components/MasterPage/MasterPage.tsx +24 -11
- package/Utils/Monitor/MonitorMetricType.ts +16 -1
- package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
- package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
- package/Utils/Telemetry/CrossSignalScope.ts +75 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
- package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +48 -35
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/CommonAPI.js +59 -0
- package/build/dist/Server/API/CommonAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/SlackAPI.js +13 -10
- package/build/dist/Server/API/SlackAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +745 -673
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/TelemetryAPI.js +34 -3
- package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
- package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
- package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +15 -6
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/LogAggregationService.js +2 -0
- package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
- package/build/dist/Server/Services/LogService.js +16 -0
- package/build/dist/Server/Services/LogService.js.map +1 -1
- package/build/dist/Server/Services/NetworkSiteService.js +12 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
- package/build/dist/Server/Services/SpanService.js +16 -0
- package/build/dist/Server/Services/SpanService.js.map +1 -1
- package/build/dist/Server/Services/TraceAggregationService.js +2 -0
- package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
- package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
- package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
- package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/LogRedaction.js +449 -0
- package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
- package/build/dist/Server/Utils/Logger.js +98 -45
- package/build/dist/Server/Utils/Logger.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
- package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
- package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +10 -7
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
- package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
- package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/API/Hostname.js +63 -0
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
- package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
- package/build/dist/Types/Database/DatabaseProperty.js +38 -0
- package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js +24 -6
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Events/Recurring.js +13 -1
- package/build/dist/Types/Events/Recurring.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +9 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +330 -31
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
- package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
- package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
- package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
- package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
- package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
- package/build/dist/UI/Components/Footer/Footer.js +7 -4
- package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
- package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
- package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
- package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
- package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
- package/package.json +1 -1
|
@@ -252,228 +252,44 @@ export class Service extends DatabaseService<WorkspaceNotificationRule> {
|
|
|
252
252
|
throw new BadDataException((err as Error)?.message);
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
|
+
}
|
|
255
256
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
const getMessageSummary: (wt: WorkspaceType) => string = (
|
|
283
|
-
wt: WorkspaceType,
|
|
284
|
-
): string => {
|
|
285
|
-
const blocks: Array<WorkspaceMessageBlock> | undefined =
|
|
286
|
-
messageBlocksByWorkspaceTypes.find(
|
|
287
|
-
(b: MessageBlocksByWorkspaceType) => {
|
|
288
|
-
return b.workspaceType === wt;
|
|
289
|
-
},
|
|
290
|
-
)?.messageBlocks;
|
|
291
|
-
if (!blocks) {
|
|
292
|
-
return "";
|
|
293
|
-
}
|
|
294
|
-
const texts: Array<string> = [];
|
|
295
|
-
for (const block of blocks) {
|
|
296
|
-
if (
|
|
297
|
-
(block as WorkspacePayloadMarkdown)._type ===
|
|
298
|
-
"WorkspacePayloadMarkdown"
|
|
299
|
-
) {
|
|
300
|
-
texts.push((block as WorkspacePayloadMarkdown).text);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
const joined: string = texts.join(" \n").trim();
|
|
304
|
-
return joined;
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
for (const res of responses) {
|
|
308
|
-
const messageSummary: string = getMessageSummary(res.workspaceType);
|
|
309
|
-
|
|
310
|
-
// Check for errors in the response
|
|
311
|
-
if (res.errors && res.errors.length > 0) {
|
|
312
|
-
/*
|
|
313
|
-
* Record the failure before throwing. Test sends used to throw
|
|
314
|
-
* straight out of here, so a failed test left no trace in
|
|
315
|
-
* Notification Logs and support had no way to see what Microsoft
|
|
316
|
-
* or Slack actually said.
|
|
317
|
-
*/
|
|
318
|
-
await this.logTestSendFailures({
|
|
319
|
-
projectId: data.projectId,
|
|
320
|
-
workspaceType: res.workspaceType,
|
|
321
|
-
errors: res.errors,
|
|
322
|
-
message: messageSummary,
|
|
323
|
-
userId: data.testByUserId,
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
const errorMessages: Array<string> = res.errors.map(
|
|
327
|
-
(error: { channel: WorkspaceChannel; error: string }) => {
|
|
328
|
-
return `Channel ${error.channel.name}: ${error.error}`;
|
|
329
|
-
},
|
|
330
|
-
);
|
|
331
|
-
throw new BadDataException(
|
|
332
|
-
`Failed to send test message to some channels: ${errorMessages.join(
|
|
333
|
-
"; ",
|
|
334
|
-
)}`,
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
for (const thread of res.threads) {
|
|
339
|
-
const log: WorkspaceNotificationLog =
|
|
340
|
-
new WorkspaceNotificationLog();
|
|
341
|
-
log.projectId = data.projectId;
|
|
342
|
-
log.workspaceType = res.workspaceType;
|
|
343
|
-
log.channelId = thread.channel.id;
|
|
344
|
-
log.channelName = thread.channel.name;
|
|
345
|
-
log.threadId = thread.threadId;
|
|
346
|
-
log.message = messageSummary;
|
|
347
|
-
log.status = WorkspaceNotificationStatus.Success;
|
|
348
|
-
log.statusMessage = "Test message posted to workspace channel";
|
|
349
|
-
log.userId = data.testByUserId;
|
|
350
|
-
log.actionType = WorkspaceNotificationActionType.SendMessage;
|
|
351
|
-
|
|
352
|
-
await WorkspaceNotificationLogService.create({
|
|
353
|
-
data: log,
|
|
354
|
-
props: { isRoot: true },
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
} catch (err) {
|
|
359
|
-
throw new BadDataException(
|
|
360
|
-
"Cannot post message to channel. " + (err as Error)?.message,
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
for (const channel of existingChannels) {
|
|
366
|
-
try {
|
|
367
|
-
const responses: Array<WorkspaceSendMessageResponse> =
|
|
368
|
-
await WorkspaceUtil.postMessageToAllWorkspaceChannelsAsBot({
|
|
369
|
-
projectId: data.projectId,
|
|
370
|
-
messagePayloadsByWorkspace: messageBlocksByWorkspaceTypes.map(
|
|
371
|
-
(
|
|
372
|
-
messageBlocksByWorkspaceType: MessageBlocksByWorkspaceType,
|
|
373
|
-
) => {
|
|
374
|
-
const payload: WorkspaceMessagePayload = {
|
|
375
|
-
_type: "WorkspaceMessagePayload",
|
|
376
|
-
workspaceType: messageBlocksByWorkspaceType.workspaceType,
|
|
377
|
-
messageBlocks: messageBlocksByWorkspaceType.messageBlocks,
|
|
378
|
-
channelNames: [channel.name],
|
|
379
|
-
channelIds: [],
|
|
380
|
-
};
|
|
381
|
-
|
|
382
|
-
if (
|
|
383
|
-
messageBlocksByWorkspaceType.workspaceType ===
|
|
384
|
-
WorkspaceType.MicrosoftTeams
|
|
385
|
-
) {
|
|
386
|
-
payload.teamId = channel.teamId;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return payload;
|
|
390
|
-
},
|
|
391
|
-
),
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
// Log results for test sends (existing channels)
|
|
395
|
-
const getMessageSummary: (wt: WorkspaceType) => string = (
|
|
396
|
-
wt: WorkspaceType,
|
|
397
|
-
): string => {
|
|
398
|
-
const blocks: Array<WorkspaceMessageBlock> | undefined =
|
|
399
|
-
messageBlocksByWorkspaceTypes.find(
|
|
400
|
-
(b: MessageBlocksByWorkspaceType) => {
|
|
401
|
-
return b.workspaceType === wt;
|
|
402
|
-
},
|
|
403
|
-
)?.messageBlocks;
|
|
404
|
-
if (!blocks) {
|
|
405
|
-
return "";
|
|
406
|
-
}
|
|
407
|
-
const texts: Array<string> = [];
|
|
408
|
-
for (const block of blocks) {
|
|
409
|
-
if (
|
|
410
|
-
(block as WorkspacePayloadMarkdown)._type ===
|
|
411
|
-
"WorkspacePayloadMarkdown"
|
|
412
|
-
) {
|
|
413
|
-
texts.push((block as WorkspacePayloadMarkdown).text);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
const joined: string = texts.join(" \n").trim();
|
|
417
|
-
return joined;
|
|
418
|
-
};
|
|
419
|
-
|
|
420
|
-
for (const res of responses) {
|
|
421
|
-
const messageSummary: string = getMessageSummary(res.workspaceType);
|
|
422
|
-
|
|
423
|
-
// Check for errors in the response
|
|
424
|
-
if (res.errors && res.errors.length > 0) {
|
|
425
|
-
/*
|
|
426
|
-
* Record the failure before throwing. Test sends used to throw
|
|
427
|
-
* straight out of here, so a failed test left no trace in
|
|
428
|
-
* Notification Logs and support had no way to see what Microsoft
|
|
429
|
-
* or Slack actually said.
|
|
430
|
-
*/
|
|
431
|
-
await this.logTestSendFailures({
|
|
432
|
-
projectId: data.projectId,
|
|
433
|
-
workspaceType: res.workspaceType,
|
|
434
|
-
errors: res.errors,
|
|
435
|
-
message: messageSummary,
|
|
436
|
-
userId: data.testByUserId,
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
const errorMessages: Array<string> = res.errors.map(
|
|
440
|
-
(error: { channel: WorkspaceChannel; error: string }) => {
|
|
441
|
-
return `Channel ${error.channel.name}: ${error.error}`;
|
|
442
|
-
},
|
|
443
|
-
);
|
|
444
|
-
throw new BadDataException(
|
|
445
|
-
`Failed to send test message to some channels: ${errorMessages.join(
|
|
446
|
-
"; ",
|
|
447
|
-
)}`,
|
|
448
|
-
);
|
|
449
|
-
}
|
|
257
|
+
/*
|
|
258
|
+
* Post to the channels this test just created.
|
|
259
|
+
*
|
|
260
|
+
* This loop used to sit inside the shouldPostToExistingChannel block, so a
|
|
261
|
+
* rule that only creates a channel created it, invited nobody (a no-op on
|
|
262
|
+
* Teams) and reported success without ever attempting a send. The one
|
|
263
|
+
* action an admin runs to prove the bot can post proved nothing, and a
|
|
264
|
+
* passing test was read as evidence that the workspace app was wired up
|
|
265
|
+
* correctly when it had never been exercised.
|
|
266
|
+
*/
|
|
267
|
+
for (const createdChannel of createdChannels) {
|
|
268
|
+
await this.postTestMessageToChannels({
|
|
269
|
+
projectId: data.projectId,
|
|
270
|
+
messageBlocksByWorkspaceTypes: messageBlocksByWorkspaceTypes,
|
|
271
|
+
testByUserId: data.testByUserId,
|
|
272
|
+
channelNames: [],
|
|
273
|
+
channelIds: [createdChannel.id],
|
|
274
|
+
/*
|
|
275
|
+
* The team the channel was actually created in. This used to pass
|
|
276
|
+
* existingTeam, which is a different field on a different rule — for a
|
|
277
|
+
* create-only rule it is undefined, and when both are set they can name
|
|
278
|
+
* two different teams.
|
|
279
|
+
*/
|
|
280
|
+
teamId: createdChannel.teamId,
|
|
281
|
+
});
|
|
282
|
+
}
|
|
450
283
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
log.status = WorkspaceNotificationStatus.Success;
|
|
461
|
-
log.statusMessage = "Test message posted to workspace channel";
|
|
462
|
-
log.userId = data.testByUserId;
|
|
463
|
-
log.actionType = WorkspaceNotificationActionType.SendMessage;
|
|
464
|
-
|
|
465
|
-
await WorkspaceNotificationLogService.create({
|
|
466
|
-
data: log,
|
|
467
|
-
props: { isRoot: true },
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
} catch (err) {
|
|
472
|
-
throw new BadDataException(
|
|
473
|
-
"Cannot post message to channel. " + (err as Error)?.message,
|
|
474
|
-
);
|
|
475
|
-
}
|
|
476
|
-
}
|
|
284
|
+
for (const channel of existingChannels) {
|
|
285
|
+
await this.postTestMessageToChannels({
|
|
286
|
+
projectId: data.projectId,
|
|
287
|
+
messageBlocksByWorkspaceTypes: messageBlocksByWorkspaceTypes,
|
|
288
|
+
testByUserId: data.testByUserId,
|
|
289
|
+
channelNames: [channel.name],
|
|
290
|
+
channelIds: [],
|
|
291
|
+
teamId: channel.teamId,
|
|
292
|
+
});
|
|
477
293
|
}
|
|
478
294
|
|
|
479
295
|
// Post test message to Microsoft Teams chats.
|
|
@@ -568,6 +384,142 @@ export class Service extends DatabaseService<WorkspaceNotificationRule> {
|
|
|
568
384
|
}
|
|
569
385
|
}
|
|
570
386
|
|
|
387
|
+
/*
|
|
388
|
+
* The markdown of a test message, for the Notification Log entry.
|
|
389
|
+
*/
|
|
390
|
+
private getTestMessageSummary(data: {
|
|
391
|
+
messageBlocksByWorkspaceTypes: Array<MessageBlocksByWorkspaceType>;
|
|
392
|
+
workspaceType: WorkspaceType;
|
|
393
|
+
}): string {
|
|
394
|
+
const blocks: Array<WorkspaceMessageBlock> | undefined =
|
|
395
|
+
data.messageBlocksByWorkspaceTypes.find(
|
|
396
|
+
(b: MessageBlocksByWorkspaceType) => {
|
|
397
|
+
return b.workspaceType === data.workspaceType;
|
|
398
|
+
},
|
|
399
|
+
)?.messageBlocks;
|
|
400
|
+
|
|
401
|
+
if (!blocks) {
|
|
402
|
+
return "";
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
const texts: Array<string> = [];
|
|
406
|
+
|
|
407
|
+
for (const block of blocks) {
|
|
408
|
+
if (
|
|
409
|
+
(block as WorkspacePayloadMarkdown)._type === "WorkspacePayloadMarkdown"
|
|
410
|
+
) {
|
|
411
|
+
texts.push((block as WorkspacePayloadMarkdown).text);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
return texts.join(" \n").trim();
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/*
|
|
419
|
+
* Post one test message to one set of destinations, then record the outcome in
|
|
420
|
+
* Notification Logs.
|
|
421
|
+
*
|
|
422
|
+
* Created channels and existing channels ran two byte-identical copies of
|
|
423
|
+
* this, which is how the created-channel copy ended up nested in the wrong
|
|
424
|
+
* conditional without anyone noticing. One path now serves both.
|
|
425
|
+
*/
|
|
426
|
+
@CaptureSpan()
|
|
427
|
+
private async postTestMessageToChannels(data: {
|
|
428
|
+
projectId: ObjectID;
|
|
429
|
+
messageBlocksByWorkspaceTypes: Array<MessageBlocksByWorkspaceType>;
|
|
430
|
+
testByUserId: ObjectID;
|
|
431
|
+
channelNames: Array<string>;
|
|
432
|
+
channelIds: Array<string>;
|
|
433
|
+
teamId?: string | undefined;
|
|
434
|
+
}): Promise<void> {
|
|
435
|
+
try {
|
|
436
|
+
const responses: Array<WorkspaceSendMessageResponse> =
|
|
437
|
+
await WorkspaceUtil.postMessageToAllWorkspaceChannelsAsBot({
|
|
438
|
+
projectId: data.projectId,
|
|
439
|
+
messagePayloadsByWorkspace: data.messageBlocksByWorkspaceTypes.map(
|
|
440
|
+
(messageBlocksByWorkspaceType: MessageBlocksByWorkspaceType) => {
|
|
441
|
+
const payload: WorkspaceMessagePayload = {
|
|
442
|
+
_type: "WorkspaceMessagePayload",
|
|
443
|
+
workspaceType: messageBlocksByWorkspaceType.workspaceType,
|
|
444
|
+
messageBlocks: messageBlocksByWorkspaceType.messageBlocks,
|
|
445
|
+
channelNames: data.channelNames,
|
|
446
|
+
channelIds: data.channelIds,
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
// teamId is a Microsoft Teams concept; Slack has no equivalent.
|
|
450
|
+
if (
|
|
451
|
+
messageBlocksByWorkspaceType.workspaceType ===
|
|
452
|
+
WorkspaceType.MicrosoftTeams
|
|
453
|
+
) {
|
|
454
|
+
payload.teamId = data.teamId;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
return payload;
|
|
458
|
+
},
|
|
459
|
+
),
|
|
460
|
+
});
|
|
461
|
+
|
|
462
|
+
for (const res of responses) {
|
|
463
|
+
const messageSummary: string = this.getTestMessageSummary({
|
|
464
|
+
messageBlocksByWorkspaceTypes: data.messageBlocksByWorkspaceTypes,
|
|
465
|
+
workspaceType: res.workspaceType,
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// Check for errors in the response
|
|
469
|
+
if (res.errors && res.errors.length > 0) {
|
|
470
|
+
/*
|
|
471
|
+
* Record the failure before throwing. Test sends used to throw
|
|
472
|
+
* straight out of here, so a failed test left no trace in
|
|
473
|
+
* Notification Logs and support had no way to see what Microsoft
|
|
474
|
+
* or Slack actually said.
|
|
475
|
+
*/
|
|
476
|
+
await this.logTestSendFailures({
|
|
477
|
+
projectId: data.projectId,
|
|
478
|
+
workspaceType: res.workspaceType,
|
|
479
|
+
errors: res.errors,
|
|
480
|
+
message: messageSummary,
|
|
481
|
+
userId: data.testByUserId,
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
const errorMessages: Array<string> = res.errors.map(
|
|
485
|
+
(error: { channel: WorkspaceChannel; error: string }) => {
|
|
486
|
+
return `Channel ${error.channel.name}: ${error.error}`;
|
|
487
|
+
},
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
throw new BadDataException(
|
|
491
|
+
`Failed to send test message to some channels: ${errorMessages.join(
|
|
492
|
+
"; ",
|
|
493
|
+
)}`,
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
for (const thread of res.threads) {
|
|
498
|
+
const log: WorkspaceNotificationLog = new WorkspaceNotificationLog();
|
|
499
|
+
log.projectId = data.projectId;
|
|
500
|
+
log.workspaceType = res.workspaceType;
|
|
501
|
+
log.channelId = thread.channel.id;
|
|
502
|
+
log.channelName = thread.channel.name;
|
|
503
|
+
log.threadId = thread.threadId;
|
|
504
|
+
log.message = messageSummary;
|
|
505
|
+
log.status = WorkspaceNotificationStatus.Success;
|
|
506
|
+
log.statusMessage = "Test message posted to workspace channel";
|
|
507
|
+
log.userId = data.testByUserId;
|
|
508
|
+
log.actionType = WorkspaceNotificationActionType.SendMessage;
|
|
509
|
+
|
|
510
|
+
await WorkspaceNotificationLogService.create({
|
|
511
|
+
data: log,
|
|
512
|
+
props: { isRoot: true },
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
} catch (err) {
|
|
517
|
+
throw new BadDataException(
|
|
518
|
+
"Cannot post message to channel. " + (err as Error)?.message,
|
|
519
|
+
);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
|
|
571
523
|
/*
|
|
572
524
|
* Persist per-destination failures from a test send so they show up in
|
|
573
525
|
* Settings > Notification Logs alongside real notification failures. Real
|
|
@@ -366,6 +366,15 @@ export default class ModelPermission {
|
|
|
366
366
|
* never widens access (authorization stays on primaryEntityId).
|
|
367
367
|
*/
|
|
368
368
|
"entityScope",
|
|
369
|
+
/*
|
|
370
|
+
* Synthetic query key compiled by StatementGenerator to an AND of
|
|
371
|
+
* per-resource-facet OR groups (primaryEntityId / entityKeys /
|
|
372
|
+
* resource attribute). Like entityScope it is not a real column and
|
|
373
|
+
* only ever narrows rows — authorization still runs on
|
|
374
|
+
* primaryEntityId. Written by the telemetry services' onBeforeFind
|
|
375
|
+
* from the client-sent `resourceFilters` ids.
|
|
376
|
+
*/
|
|
377
|
+
"resourceEntityScopes",
|
|
369
378
|
];
|
|
370
379
|
|
|
371
380
|
return returnArr;
|
|
@@ -23,6 +23,17 @@ import { combineWithPrivacyClause } from "../../../Utils/PrivacyFilterUtil";
|
|
|
23
23
|
import QueryHelper from "../QueryHelper";
|
|
24
24
|
import QueryUtil from "../QueryUtil";
|
|
25
25
|
import CaptureSpan from "../../../Utils/Telemetry/CaptureSpan";
|
|
26
|
+
import Dictionary from "../../../../Types/Dictionary";
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
* Built once per invocation and threaded through the per-column loop; never
|
|
30
|
+
* cached on props or module scope (the multi-tenant path re-enters with
|
|
31
|
+
* different per-tenant props and must rebuild fresh).
|
|
32
|
+
*/
|
|
33
|
+
type AccessControlPermissionContext = {
|
|
34
|
+
nonAccessControlPermissions: Array<Permission>;
|
|
35
|
+
accessControlPermissions: Array<UserPermission>;
|
|
36
|
+
};
|
|
26
37
|
|
|
27
38
|
export default class AccessControlPermission {
|
|
28
39
|
@CaptureSpan()
|
|
@@ -290,7 +301,10 @@ export default class AccessControlPermission {
|
|
|
290
301
|
modelType: DatabaseBaseModelType,
|
|
291
302
|
props: DatabaseCommonInteractionProps,
|
|
292
303
|
type: DatabaseRequestType,
|
|
304
|
+
context?: AccessControlPermissionContext,
|
|
293
305
|
): Array<ObjectID> {
|
|
306
|
+
context = context ?? this.buildPermissionContext(props);
|
|
307
|
+
|
|
294
308
|
let labelIds: Array<ObjectID> = [];
|
|
295
309
|
|
|
296
310
|
// check model level permissions.
|
|
@@ -299,7 +313,7 @@ export default class AccessControlPermission {
|
|
|
299
313
|
TablePermission.getTablePermission(modelType, type);
|
|
300
314
|
|
|
301
315
|
const modelLevelLabelIds: Array<ObjectID> =
|
|
302
|
-
this.getAccessControlIdsByPermissions(modelLevelPermissions,
|
|
316
|
+
this.getAccessControlIdsByPermissions(modelLevelPermissions, context);
|
|
303
317
|
|
|
304
318
|
labelIds = [...labelIds, ...modelLevelLabelIds];
|
|
305
319
|
|
|
@@ -331,11 +345,23 @@ export default class AccessControlPermission {
|
|
|
331
345
|
];
|
|
332
346
|
}
|
|
333
347
|
|
|
334
|
-
|
|
348
|
+
// Build the permission context once — not per column.
|
|
349
|
+
const context: AccessControlPermissionContext =
|
|
350
|
+
this.buildPermissionContext(props);
|
|
351
|
+
|
|
352
|
+
labelIds = this.getAccessControlIdsForModel(
|
|
353
|
+
modelType,
|
|
354
|
+
props,
|
|
355
|
+
type,
|
|
356
|
+
context,
|
|
357
|
+
);
|
|
358
|
+
|
|
359
|
+
const columnAccessControlDictionary: Dictionary<ColumnAccessControl> =
|
|
360
|
+
model.getColumnAccessControlForAllColumns();
|
|
335
361
|
|
|
336
362
|
for (const column of columnsToCheckPermissionFor) {
|
|
337
363
|
const accessControl: ColumnAccessControl | null =
|
|
338
|
-
|
|
364
|
+
columnAccessControlDictionary[column] || null;
|
|
339
365
|
|
|
340
366
|
if (!accessControl) {
|
|
341
367
|
continue;
|
|
@@ -343,21 +369,21 @@ export default class AccessControlPermission {
|
|
|
343
369
|
|
|
344
370
|
if (type === DatabaseRequestType.Read && accessControl.read) {
|
|
345
371
|
const columnReadLabelIds: Array<ObjectID> =
|
|
346
|
-
this.getAccessControlIdsByPermissions(accessControl.read,
|
|
372
|
+
this.getAccessControlIdsByPermissions(accessControl.read, context);
|
|
347
373
|
|
|
348
374
|
labelIds = [...labelIds, ...columnReadLabelIds];
|
|
349
375
|
}
|
|
350
376
|
|
|
351
377
|
if (type === DatabaseRequestType.Create && accessControl.create) {
|
|
352
378
|
const columnCreateLabelIds: Array<ObjectID> =
|
|
353
|
-
this.getAccessControlIdsByPermissions(accessControl.create,
|
|
379
|
+
this.getAccessControlIdsByPermissions(accessControl.create, context);
|
|
354
380
|
|
|
355
381
|
labelIds = [...labelIds, ...columnCreateLabelIds];
|
|
356
382
|
}
|
|
357
383
|
|
|
358
384
|
if (type === DatabaseRequestType.Update && accessControl.update) {
|
|
359
385
|
const columnUpdateLabelIds: Array<ObjectID> =
|
|
360
|
-
this.getAccessControlIdsByPermissions(accessControl.update,
|
|
386
|
+
this.getAccessControlIdsByPermissions(accessControl.update, context);
|
|
361
387
|
|
|
362
388
|
labelIds = [...labelIds, ...columnUpdateLabelIds];
|
|
363
389
|
}
|
|
@@ -369,35 +395,40 @@ export default class AccessControlPermission {
|
|
|
369
395
|
return distinctLabelIds;
|
|
370
396
|
}
|
|
371
397
|
|
|
372
|
-
private static
|
|
373
|
-
permissions: Array<Permission>,
|
|
398
|
+
private static buildPermissionContext(
|
|
374
399
|
props: DatabaseCommonInteractionProps,
|
|
375
|
-
):
|
|
400
|
+
): AccessControlPermissionContext {
|
|
376
401
|
const userPermissions: Array<UserPermission> =
|
|
377
402
|
DatabaseCommonInteractionPropsUtil.getUserPermissions(
|
|
378
403
|
props,
|
|
379
404
|
PermissionType.Allow,
|
|
380
405
|
);
|
|
381
406
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
407
|
+
return {
|
|
408
|
+
nonAccessControlPermissions:
|
|
409
|
+
PermissionHelper.getNonAccessControlPermissions(userPermissions),
|
|
410
|
+
accessControlPermissions:
|
|
411
|
+
PermissionHelper.getAccessControlPermissions(userPermissions),
|
|
412
|
+
};
|
|
413
|
+
}
|
|
387
414
|
|
|
415
|
+
private static getAccessControlIdsByPermissions(
|
|
416
|
+
permissions: Array<Permission>,
|
|
417
|
+
context: AccessControlPermissionContext,
|
|
418
|
+
): Array<ObjectID> {
|
|
388
419
|
let labelIds: Array<ObjectID> = [];
|
|
389
420
|
|
|
390
421
|
if (
|
|
391
422
|
PermissionHelper.doesPermissionsIntersect(
|
|
392
423
|
permissions,
|
|
393
|
-
|
|
424
|
+
context.nonAccessControlPermissions,
|
|
394
425
|
)
|
|
395
426
|
) {
|
|
396
427
|
return []; // if this is intersecting, then return empty array. We dont need to check for access control.
|
|
397
428
|
}
|
|
398
429
|
|
|
399
430
|
for (const permission of permissions) {
|
|
400
|
-
for (const accessControlPermission of accessControlPermissions) {
|
|
431
|
+
for (const accessControlPermission of context.accessControlPermissions) {
|
|
401
432
|
if (
|
|
402
433
|
accessControlPermission.permission === permission &&
|
|
403
434
|
accessControlPermission.labelIds.length > 0
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import APIKeyPermission from "../../../Models/DatabaseModels/ApiKeyPermission";
|
|
2
|
-
import Label from "../../../Models/DatabaseModels/Label";
|
|
3
|
-
import LIMIT_MAX from "../../../Types/Database/LimitMax";
|
|
4
1
|
import ObjectID from "../../../Types/ObjectID";
|
|
5
2
|
import Permission, {
|
|
6
3
|
UserGlobalAccessPermission,
|
|
7
4
|
UserPermission,
|
|
8
5
|
UserTenantAccessPermission,
|
|
9
6
|
} from "../../../Types/Permission";
|
|
10
|
-
import ApiKeyPermissionService
|
|
7
|
+
import ApiKeyPermissionService, {
|
|
8
|
+
ApiKeyPermissionRow,
|
|
9
|
+
} from "../../Services/ApiKeyPermissionService";
|
|
11
10
|
import CaptureSpan from "../Telemetry/CaptureSpan";
|
|
12
11
|
import UserPermissionUtil from "../UserPermission/UserPermission";
|
|
13
12
|
|
|
@@ -68,43 +67,20 @@ export default class APIKeyAccessPermission {
|
|
|
68
67
|
projectId: ObjectID,
|
|
69
68
|
apiKeyId: ObjectID,
|
|
70
69
|
): Promise<UserTenantAccessPermission> {
|
|
71
|
-
// get team permissions.
|
|
72
|
-
const
|
|
73
|
-
await ApiKeyPermissionService.
|
|
74
|
-
query: {
|
|
75
|
-
apiKeyId: apiKeyId,
|
|
76
|
-
},
|
|
77
|
-
select: {
|
|
78
|
-
permission: true,
|
|
79
|
-
labels: {
|
|
80
|
-
_id: true,
|
|
81
|
-
},
|
|
82
|
-
isBlockPermission: true,
|
|
83
|
-
},
|
|
70
|
+
// get team permissions (cached — see ApiKeyPermissionService).
|
|
71
|
+
const apiKeyPermissionRows: Array<ApiKeyPermissionRow> =
|
|
72
|
+
await ApiKeyPermissionService.findPermissionsByApiKeyId(apiKeyId);
|
|
84
73
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (!apiPermission.labels) {
|
|
96
|
-
apiPermission.labels = [];
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
userPermissions.push({
|
|
100
|
-
permission: apiPermission.permission!,
|
|
101
|
-
labelIds: apiPermission.labels.map((label: Label) => {
|
|
102
|
-
return label.id!;
|
|
103
|
-
}),
|
|
104
|
-
isBlockPermission: apiPermission.isBlockPermission,
|
|
105
|
-
_type: "UserPermission",
|
|
106
|
-
});
|
|
107
|
-
}
|
|
74
|
+
const userPermissions: Array<UserPermission> = apiKeyPermissionRows.map(
|
|
75
|
+
(row: ApiKeyPermissionRow): UserPermission => {
|
|
76
|
+
return {
|
|
77
|
+
permission: row.permission,
|
|
78
|
+
labelIds: row.labelIds,
|
|
79
|
+
isBlockPermission: row.isBlockPermission,
|
|
80
|
+
_type: "UserPermission",
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
);
|
|
108
84
|
|
|
109
85
|
const permission: UserTenantAccessPermission =
|
|
110
86
|
UserPermissionUtil.getDefaultUserTenantAccessPermission(projectId);
|