web/rac: Ignore empty remote clipboard payloads (#22067)

web/rac: ignore empty remote clipboard payloads

Some remote sessions (notably SSH) push empty or whitespace-only
clipboard updates that overwrite the user's local clipboard, leaving
subsequent paste attempts with nothing to deliver. Filter those payloads
in the StringReader.onend callback so the local clipboard is preserved.

Closes #21439

Co-authored-by: Agent (authentik-i21439-featured-elevated-kobicha) <279763771+playpen-agent@users.noreply.github.com>
This commit is contained in:
Teffen Ellis
2026-05-06 20:34:34 +02:00
committed by GitHub
parent cf05037761
commit e50f093685
+22 -7
View File
@@ -2,6 +2,8 @@ import "#elements/LoadingOverlay";
import Styles from "./index.entrypoint.css";
import { writeToClipboard } from "#common/clipboard";
import { Interface } from "#elements/Interface";
import { WithBrandConfig } from "#elements/mixins/branding";
@@ -155,22 +157,35 @@ export class RacInterface extends WithBrandConfig(Interface) {
if (/^text\//.exec(mimetype)) {
const reader = new Guacamole.StringReader(stream);
let data = "";
reader.ontext = (text) => {
data += text;
};
reader.onend = () => {
this._previousClipboardValue = data;
navigator.clipboard.writeText(data);
const trimmed = data.trim();
// Some remote sessions (notably SSH) push empty clipboard
// payloads that would otherwise clobber the user's local
// clipboard, breaking subsequent paste attempts. Ignore
// them so the local clipboard remains intact.
if (!trimmed) {
console.debug("authentik/rac: ignored empty remote clipboard payload");
return;
}
this._previousClipboardValue = trimmed;
writeToClipboard(trimmed);
};
} else {
const reader = new Guacamole.BlobReader(stream, mimetype);
reader.onend = () => {
const blob = reader.getBlob();
navigator.clipboard.write([
new ClipboardItem({
[blob.type]: blob,
}),
]);
const item = new ClipboardItem({
[blob.type]: blob,
});
writeToClipboard(item);
};
}
console.debug("authentik/rac: updated clipboard from remote");