Skip to content

Commit eca0905

Browse files
committed
batch requests
1 parent 91abefa commit eca0905

1 file changed

Lines changed: 32 additions & 2 deletions

File tree

lib/web/permissions.js

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { isGlobalAdmin, isWorkspaceAdmin } from "../perms.js";
44
const SUPERADMINS = (process.env.SUPERADMINS || "").split(",").filter(Boolean);
55
const CHANNEL_CACHE_TTL_MS = 5 * 60 * 1000;
66
const channelInfoCache = new WeakMap();
7+
let catalogCache = { expiresAt: 0, promise: null };
78

89
export const roleAbilities = {
910
manager: [
@@ -46,6 +47,33 @@ function inheritedAbilities(globalAdmin, workspaceAdmin, superAdmin) {
4647
return abilities;
4748
}
4849

50+
async function fetchChannelCatalog(client) {
51+
const channels = new Map();
52+
let cursor;
53+
do {
54+
const response = await client.conversations.list({
55+
cursor,
56+
exclude_archived: true,
57+
limit: 1000,
58+
types: "public_channel,private_channel",
59+
});
60+
for (const channel of response.channels || []) channels.set(channel.id, channel);
61+
cursor = response.response_metadata?.next_cursor;
62+
} while (cursor);
63+
return channels;
64+
}
65+
66+
function loadChannelCatalog(client) {
67+
if (catalogCache.promise && catalogCache.expiresAt > Date.now()) return catalogCache.promise;
68+
69+
const promise = fetchChannelCatalog(client);
70+
catalogCache = { expiresAt: Date.now() + CHANNEL_CACHE_TTL_MS, promise };
71+
promise.catch(() => {
72+
if (catalogCache.promise === promise) catalogCache = { expiresAt: 0, promise: null };
73+
});
74+
return promise;
75+
}
76+
4977
function cachedChannelInfo(client, channelId) {
5078
let clientCache = channelInfoCache.get(client);
5179
if (!clientCache) {
@@ -93,12 +121,14 @@ export async function loadPermissions(client, userId, discoveryClient = client)
93121
if (globalAdmin) {
94122
for (const channelId of await listConfiguredChannelIds()) channelIds.add(channelId);
95123
}
124+
const catalog = await loadChannelCatalog(discoveryClient);
96125
const visibleChannels = (
97126
await Promise.all(
98127
[...channelIds].map(async (channelId) => {
99128
const grant = grants.get(channelId);
100-
const channel = await channelInfo(channelId, [client, discoveryClient]);
101-
if (!channel && !grant) return null;
129+
let channel = catalog.get(channelId);
130+
if (!channel && grant) channel = await channelInfo(channelId, [client, discoveryClient]);
131+
if (!channel && !grant && !globalAdmin) return null;
102132
if (channel?.is_archived && !grant) return null;
103133
return {
104134
...grant,

0 commit comments

Comments
 (0)