diff --git a/web/packages/teleport/src/DesktopSession/DesktopSession.story.tsx b/web/packages/teleport/src/DesktopSession/DesktopSession.story.tsx index 4df1728c274c8..a6406dc6eb5fb 100644 --- a/web/packages/teleport/src/DesktopSession/DesktopSession.story.tsx +++ b/web/packages/teleport/src/DesktopSession/DesktopSession.story.tsx @@ -279,6 +279,41 @@ export const AnotherSessionActive = () => ( ); +export const ClipboardSharingDisabledRbac = () => ( + +); + +export const ClipboardSharingDisabledIncompatibleBrowser = () => ( + +); + +export const ClipboardSharingDisabledBrowserPermissions = () => ( + +); + export const Warnings = () => { const client = fakeClient(); client.connect = async () => { diff --git a/web/packages/teleport/src/DesktopSession/DesktopSession.tsx b/web/packages/teleport/src/DesktopSession/DesktopSession.tsx index a3a9a6f9eb39f..9d5cb9bb29abf 100644 --- a/web/packages/teleport/src/DesktopSession/DesktopSession.tsx +++ b/web/packages/teleport/src/DesktopSession/DesktopSession.tsx @@ -31,6 +31,7 @@ import TdpClientCanvas from 'teleport/components/TdpClientCanvas'; import AuthnDialog from 'teleport/components/AuthnDialog'; import useDesktopSession, { + clipboardSharingMessage, directorySharingPossible, isSharingClipboard, isSharingDirectory, @@ -57,7 +58,6 @@ export function DesktopSession(props: State) { tdpClient, username, hostname, - setClipboardSharingState, directorySharingState, setDirectorySharingState, clientOnPngFrame, @@ -80,6 +80,7 @@ export function DesktopSession(props: State) { windowOnResize, clientScreenSpecToRequest, clipboardSharingState, + setClipboardSharingState, onShareDirectory, onCtrlAltDel, warnings, @@ -133,6 +134,7 @@ export function DesktopSession(props: State) { canShareDirectory={directorySharingPossible(directorySharingState)} isSharingDirectory={isSharingDirectory(directorySharingState)} isSharingClipboard={isSharingClipboard(clipboardSharingState)} + clipboardSharingMessage={clipboardSharingMessage(clipboardSharingState)} onShareDirectory={onShareDirectory} onCtrlAltDel={onCtrlAltDel} warnings={warnings} diff --git a/web/packages/teleport/src/DesktopSession/TopBar.tsx b/web/packages/teleport/src/DesktopSession/TopBar.tsx index b2797d6df314e..b6f0dc6ba1170 100644 --- a/web/packages/teleport/src/DesktopSession/TopBar.tsx +++ b/web/packages/teleport/src/DesktopSession/TopBar.tsx @@ -32,6 +32,7 @@ export default function TopBar(props: Props) { const { userHost, isSharingClipboard, + clipboardSharingMessage, onDisconnect, canShareDirectory, isSharingDirectory, @@ -73,11 +74,7 @@ export default function TopBar(props: Props) { @@ -117,6 +114,7 @@ export const TopBarHeight = 40; type Props = { userHost: string; isSharingClipboard: boolean; + clipboardSharingMessage: string; canShareDirectory: boolean; isSharingDirectory: boolean; onDisconnect: VoidFunction; diff --git a/web/packages/teleport/src/DesktopSession/useDesktopSession.tsx b/web/packages/teleport/src/DesktopSession/useDesktopSession.tsx index a1cf2b32797be..9849c39fa269f 100644 --- a/web/packages/teleport/src/DesktopSession/useDesktopSession.tsx +++ b/web/packages/teleport/src/DesktopSession/useDesktopSession.tsx @@ -330,6 +330,26 @@ export function isSharingClipboard( ); } +/** + * Provides a user-friendly message indicating whether clipboard sharing is enabled, + * and the reason it is disabled. + */ +export function clipboardSharingMessage(state: ClipboardSharingState): string { + if (!state.allowedByAcl) { + return 'Clipboard Sharing disabled by Teleport RBAC.'; + } + if (!state.browserSupported) { + return 'Clipboard Sharing is not supported in this browser.'; + } + if (state.readState === 'denied' || state.writeState === 'denied') { + return 'Clipboard Sharing disabled due to browser permissions.'; + } + + return isSharingClipboard(state) + ? 'Clipboard Sharing enabled.' + : 'Clipboard Sharing disabled.'; +} + /** * Determines whether directory sharing is/should-be possible based on whether it's allowed by the acl * and whether it's supported by the browser.