Skip to content

Commit

Permalink
[v16] Add xterm/image-addon to web terminal (#48842)
Browse files Browse the repository at this point in the history
* [v16] Add xterm/image-addon to web terminal

Backport #48780

* [v16] Add wasm to content security policy for web ssh terminal
  • Loading branch information
avatus authored Nov 14, 2024
1 parent 46c0141 commit 68277e6
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 3 deletions.
6 changes: 5 additions & 1 deletion lib/httplib/httpheaders.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ var desktopSessionRe = regexp.MustCompile(`^/web/cluster/[^/]+/desktops/[^/]+/[^
// which is a route to a desktop recording that uses WASM.
var recordingRe = regexp.MustCompile(`^/web/cluster/[^/]+/session/[^/]+$`)

// regex for the ssh terminal endpoint /web/cluster/:clusterId/console/node/:sid/:login
// which is a route to a ssh session that uses WASM.
var sshSessionRe = regexp.MustCompile(`^/web/cluster/[^/]+/console/node/[^/]+/[^/]+$`)

var indexCSPStringCache *cspCache = newCSPCache()

func getIndexContentSecurityPolicyString(cfg proto.Features, urlPath string) string {
Expand All @@ -209,7 +213,7 @@ func getIndexContentSecurityPolicyString(cfg proto.Features, urlPath string) str
}

// Nothing found in cache, calculate regex and result
withWasm := desktopSessionRe.MatchString(urlPath) || recordingRe.MatchString(urlPath)
withWasm := desktopSessionRe.MatchString(urlPath) || recordingRe.MatchString(urlPath) || sshSessionRe.MatchString(urlPath)
cspString := GetContentSecurityPolicyString(
getIndexContentSecurityPolicy(withStripe, withWasm),
)
Expand Down
19 changes: 18 additions & 1 deletion lib/httplib/httplib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,24 @@ func TestSetIndexContentSecurityPolicy(t *testing.T) {
},
},
{
name: "for cloud based usage & desktop session, Stripe managed product (with stripe, with wasm)",
name: "for web ssh session (with wasm)",
features: proto.Features{},
urlPath: "/web/cluster/:clusterId/console/node/:sessionId/:username",
expectedCspVals: map[string]string{
"default-src": "'self'",
"base-uri": "'self'",
"form-action": "'self'",
"frame-ancestors": "'none'",
"object-src": "'none'",
"script-src": "'self' 'wasm-unsafe-eval'",
"style-src": "'self' 'unsafe-inline'",
"img-src": "'self' data: blob:",
"font-src": "'self' data:",
"connect-src": "'self' wss:",
},
},
{
name: "for cloud based usage & desktop session, with wasm",
features: proto.Features{Cloud: true, IsUsageBased: true, IsStripeManaged: true},
urlPath: "/web/cluster/:clusterId/desktops/:desktopName/:username",
expectedCspVals: map[string]string{
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion web/packages/teleport/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@
"@opentelemetry/sdk-trace-base": "1.25.1",
"@opentelemetry/sdk-trace-web": "1.25.1",
"@opentelemetry/semantic-conventions": "1.25.1",
"@xterm/xterm": "^5.5.0",
"@xterm/addon-canvas": "^0.7.0",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-image": "^0.8.0",
"@xterm/addon-web-links": "^0.11.0",
"@xterm/addon-webgl": "^0.18.0",
"@xterm/xterm": "^5.5.0",
"create-react-class": "^15.6.3",
"events": "3.3.0"
},
Expand Down
4 changes: 4 additions & 0 deletions web/packages/teleport/src/lib/term/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import '@xterm/xterm/css/xterm.css';
import { ITheme, Terminal } from '@xterm/xterm';
import { FitAddon } from '@xterm/addon-fit';
import { ImageAddon } from '@xterm/addon-image';
import { WebglAddon } from '@xterm/addon-webgl';
import { WebLinksAddon } from '@xterm/addon-web-links';
import { CanvasAddon } from '@xterm/addon-canvas';
Expand Down Expand Up @@ -50,6 +51,7 @@ export default class TtyTerminal {
_convertEol: boolean;
_debouncedResize: DebouncedFunc<() => void>;
_fitAddon = new FitAddon();
_imageAddon = new ImageAddon();
_webLinksAddon = new WebLinksAddon();
_webglAddon: WebglAddon;
_canvasAddon = new CanvasAddon();
Expand Down Expand Up @@ -88,6 +90,7 @@ export default class TtyTerminal {

this.term.loadAddon(this._fitAddon);
this.term.loadAddon(this._webLinksAddon);
this.term.loadAddon(this._imageAddon);
// handle context loss and load webgl addon
try {
// try to create a new WebglAddon. If webgl is not supported, this
Expand Down Expand Up @@ -155,6 +158,7 @@ export default class TtyTerminal {
this._disconnect();
this._debouncedResize.cancel();
this._fitAddon.dispose();
this._imageAddon.dispose();
this._webglAddon?.dispose();
this._canvasAddon?.dispose();
this._el.innerHTML = null;
Expand Down

0 comments on commit 68277e6

Please sign in to comment.