@@ -4,6 +4,7 @@ import { isGlobalAdmin, isWorkspaceAdmin } from "../perms.js";
44const SUPERADMINS = ( process . env . SUPERADMINS || "" ) . split ( "," ) . filter ( Boolean ) ;
55const CHANNEL_CACHE_TTL_MS = 5 * 60 * 1000 ;
66const channelInfoCache = new WeakMap ( ) ;
7+ let catalogCache = { expiresAt : 0 , promise : null } ;
78
89export 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+
4977function 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