diff --git a/.changeset/desktop-set-user-roles.md b/.changeset/desktop-set-user-roles.md new file mode 100644 index 0000000000000..369f18c00b4de --- /dev/null +++ b/.changeset/desktop-set-user-roles.md @@ -0,0 +1,6 @@ +--- +'@rocket.chat/desktop-api': minor +'@rocket.chat/meteor': patch +--- + +Added a `setUserRoles` bridge method to the desktop API and pushed the logged-in user's roles to the desktop app. This lets the desktop client restrict supportedVersions messages (such as version-expiration warnings) to specific roles like admins, instead of showing them to every user. The push is reactive to role changes; desktop builds without the bridge method fall back to their own role lookup. diff --git a/apps/meteor/client/views/root/AppLayout.tsx b/apps/meteor/client/views/root/AppLayout.tsx index b355d9c7b44f2..108254199ae0d 100644 --- a/apps/meteor/client/views/root/AppLayout.tsx +++ b/apps/meteor/client/views/root/AppLayout.tsx @@ -18,6 +18,7 @@ import { useCodeHighlight } from './hooks/useCodeHighlight'; import { useCorsSSLConfig } from './hooks/useCorsSSLConfig'; import { useDesktopFavicon } from './hooks/useDesktopFavicon'; import { useDesktopTitle } from './hooks/useDesktopTitle'; +import { useDesktopUserRoles } from './hooks/useDesktopUserRoles'; import { useEmojiOne } from './hooks/useEmojiOne'; import { useEscapeKeyStroke } from './hooks/useEscapeKeyStroke'; import { useGoogleTagManager } from './hooks/useGoogleTagManager'; @@ -73,6 +74,7 @@ const AppLayout = () => { useLoadMissedMessages(); useDesktopFavicon(); useDesktopTitle(); + useDesktopUserRoles(); useStartupEvent(); useIframeCommands(); diff --git a/apps/meteor/client/views/root/hooks/useDesktopUserRoles.ts b/apps/meteor/client/views/root/hooks/useDesktopUserRoles.ts new file mode 100644 index 0000000000000..5b58578ede81c --- /dev/null +++ b/apps/meteor/client/views/root/hooks/useDesktopUserRoles.ts @@ -0,0 +1,23 @@ +import { useUser } from '@rocket.chat/ui-contexts'; +import { useEffect } from 'react'; + +/** + * Pushes the logged-in user's roles to the desktop app so it can decide which + * supportedVersions messages to show (e.g. restricting version-expiration + * warnings to admins). The desktop app falls back to its own role lookup when + * this bridge is unavailable, so `setUserRoles` is called optionally. + */ +export const useDesktopUserRoles = () => { + // A single canonical value derived from the reactive user. Logout, login and + // account switch all surface as a change to this key, so the effect re-runs + // and re-pushes only when the roles actually change — no userId branch and no + // effect cleanup (which would fire on every deps change and flicker + // role-targeted UI). Logged-out and "logged in with no roles" both resolve to + // an empty list, which is the correct signal for the desktop either way. + const rolesKey = (useUser()?.roles ?? []).join(','); + + useEffect(() => { + if (typeof window === 'undefined') return; + window.RocketChatDesktop?.setUserRoles?.(rolesKey ? rolesKey.split(',') : []); + }, [rolesKey]); +}; diff --git a/packages/desktop-api/src/index.ts b/packages/desktop-api/src/index.ts index 2d7b18c5cabb9..04b1b6491103a 100644 --- a/packages/desktop-api/src/index.ts +++ b/packages/desktop-api/src/index.ts @@ -38,6 +38,7 @@ export interface IRocketChatDesktop { setSidebarCustomTheme: (customTheme: string) => void; setTitle: (title: string) => void; setUserLoggedIn: (userLoggedIn: boolean) => void; + setUserRoles: (roles: string[]) => void; setUserPresenceDetection: (options: { isAutoAwayEnabled: boolean; idleThreshold: number | null;