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.