diff --git a/ci/build/build-release.sh b/ci/build/build-release.sh index e484b251888d..8bcf823070dc 100755 --- a/ci/build/build-release.sh +++ b/ci/build/build-release.sh @@ -98,43 +98,6 @@ bundle_vscode() { rsync "${rsync_opts[@]}" ./lib/vscode-reh-web-*/ "$VSCODE_OUT_PATH" - # Add the commit, date, our name, links, and enable telemetry. This just makes - # telemetry available; telemetry can still be disabled by flag or setting. - jq --slurp '.[0] * .[1]' "$VSCODE_SRC_PATH/product.json" <( - cat << EOF - { - "enableTelemetry": true, - "commit": "$(cd "$VSCODE_SRC_PATH" && git rev-parse HEAD)", - "quality": "stable", - "date": $(jq -n 'now | todate'), - "codeServerVersion": "$VERSION", - "nameShort": "code-server", - "nameLong": "code-server", - "applicationName": "code-server", - "dataFolderName": ".code-server", - "win32MutexName": "codeserver", - "licenseUrl": "https://github.com/coder/code-server/blob/main/LICENSE", - "win32DirName": "code-server", - "win32NameVersion": "code-server", - "win32AppUserModelId": "coder.code-server", - "win32ShellNameShort": "c&ode-server", - "darwinBundleIdentifier": "com.coder.code.server", - "linuxIconName": "com.coder.code.server", - "reportIssueUrl": "https://github.com/coder/code-server/issues/new", - "documentationUrl": "https://go.microsoft.com/fwlink/?LinkID=533484#vscode", - "keyboardShortcutsUrlMac": "https://go.microsoft.com/fwlink/?linkid=832143", - "keyboardShortcutsUrlLinux": "https://go.microsoft.com/fwlink/?linkid=832144", - "keyboardShortcutsUrlWin": "https://go.microsoft.com/fwlink/?linkid=832145", - "introductoryVideosUrl": "https://go.microsoft.com/fwlink/?linkid=832146", - "tipsAndTricksUrl": "https://go.microsoft.com/fwlink/?linkid=852118", - "newsletterSignupUrl": "https://www.research.net/r/vsc-newsletter", - "linkProtectionTrustedDomains": [ - "https://open-vsx.org" - ] - } -EOF - ) > "$VSCODE_OUT_PATH/product.json" - # Use the package.json for the web/remote server. It does not have the right # version though so pull that from the main package.json. jq --slurp '.[0] * {version: .[1].version}' \ diff --git a/ci/build/build-vscode.sh b/ci/build/build-vscode.sh index bb3225a2b517..71d33960fb63 100755 --- a/ci/build/build-vscode.sh +++ b/ci/build/build-vscode.sh @@ -9,10 +9,62 @@ MINIFY=${MINIFY-true} main() { cd "$(dirname "${0}")/../.." + source ./ci/lib.sh + cd lib/vscode + # Set the commit Code will embed into the product.json. We need to do this + # since Code tries to get the commit from the `.git` directory which will fail + # as it is a submodule. + export VSCODE_DISTRO_COMMIT + VSCODE_DISTRO_COMMIT=$(git rev-parse HEAD) + + # Add the date, our name, links, and enable telemetry (this just makes + # telemetry available; telemetry can still be disabled by flag or setting). + # This needs to be done before building as Code will read this file and embed + # it into the client-side code. + git checkout product.json # Reset in case the script exited early. + cp product.json product.original.json # Since jq has no inline edit. + jq --slurp '.[0] * .[1]' product.original.json <( + cat << EOF + { + "enableTelemetry": true, + "quality": "stable", + "codeServerVersion": "$VERSION", + "nameShort": "code-server", + "nameLong": "code-server", + "applicationName": "code-server", + "dataFolderName": ".code-server", + "win32MutexName": "codeserver", + "licenseUrl": "https://github.com/coder/code-server/blob/main/LICENSE", + "win32DirName": "code-server", + "win32NameVersion": "code-server", + "win32AppUserModelId": "coder.code-server", + "win32ShellNameShort": "c&ode-server", + "darwinBundleIdentifier": "com.coder.code.server", + "linuxIconName": "com.coder.code.server", + "reportIssueUrl": "https://github.com/coder/code-server/issues/new", + "documentationUrl": "https://go.microsoft.com/fwlink/?LinkID=533484#vscode", + "keyboardShortcutsUrlMac": "https://go.microsoft.com/fwlink/?linkid=832143", + "keyboardShortcutsUrlLinux": "https://go.microsoft.com/fwlink/?linkid=832144", + "keyboardShortcutsUrlWin": "https://go.microsoft.com/fwlink/?linkid=832145", + "introductoryVideosUrl": "https://go.microsoft.com/fwlink/?linkid=832146", + "tipsAndTricksUrl": "https://go.microsoft.com/fwlink/?linkid=852118", + "newsletterSignupUrl": "https://www.research.net/r/vsc-newsletter", + "linkProtectionTrustedDomains": [ + "https://open-vsx.org" + ] + } +EOF + ) > product.json + # Any platform works since we have our own packaging step (for now). yarn gulp "vscode-reh-web-linux-x64${MINIFY:+-min}" + + # Reset so if you develop after building you will not be stuck with the wrong + # commit (the dev client will use `oss-dev` but the dev server will still use + # product.json which will have `stable-$commit`). + git checkout product.json } main "$@" diff --git a/lib/vscode b/lib/vscode index dfd34e8260c2..30d9c6cd9483 160000 --- a/lib/vscode +++ b/lib/vscode @@ -1 +1 @@ -Subproject commit dfd34e8260c270da74b5c2d86d61aee4b6d56977 +Subproject commit 30d9c6cd9483b2cc586687151bcbcd635f373630 diff --git a/patches/base-path.diff b/patches/base-path.diff index 95bb8388eb78..bf16984651c9 100644 --- a/patches/base-path.diff +++ b/patches/base-path.diff @@ -10,16 +10,14 @@ Index: code-server/lib/vscode/src/vs/base/common/network.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/network.ts +++ code-server/lib/vscode/src/vs/base/common/network.ts -@@ -151,8 +151,10 @@ class RemoteAuthoritiesImpl { - } +@@ -157,7 +157,9 @@ class RemoteAuthoritiesImpl { return URI.from({ scheme: platform.isWeb ? this._preferredWebSchema : Schemas.vscodeRemoteResource, -- authority: `${host}:${port}`, -- path: `/vscode-remote-resource`, -+ authority: platform.isWeb ? window.location.host : `${host}:${port}`, + authority: `${host}:${port}`, +- path: this._remoteResourcesPath, + path: platform.isWeb -+ ? URI.joinPath(URI.parse(window.location.href), `/vscode-remote-resource`).path -+ : `/vscode-remote-resource`, ++ ? (window.location.pathname + "/" + this._remoteResourcesPath).replace(/\/\/+/g, "/") ++ : this._remoteResourcesPath, query }); } @@ -38,40 +36,28 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html <!-- Disable pinch zooming --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> -@@ -27,23 +27,26 @@ +@@ -27,9 +27,9 @@ <meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}"> <!-- Workbench Icon/Manifest/CSS --> - <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" /> -- <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" /> +- <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" /> - <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> + <link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" /> -+ <link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" /> ++ <link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" /> + <link rel="manifest" href="{{VS_BASE}}/manifest.json" crossorigin="use-credentials" /> </head> <body aria-label=""> - </body> - - <!-- Startup (do not modify order of script tags!) --> -- <script src="./static/out/vs/loader.js"></script> -- <script src="./static/out/vs/webPackagePaths.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/loader.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/webPackagePaths.js"></script> +@@ -39,7 +39,7 @@ + <script src="{{WORKBENCH_WEB_BASE_URL}}/out/vs/loader.js"></script> + <script src="{{WORKBENCH_WEB_BASE_URL}}/out/vs/webPackagePaths.js"></script> <script> +- const baseUrl = new URL('{{WORKBENCH_WEB_BASE_URL}}', window.location.origin).toString(); ++ const baseUrl = new URL('{{WORKBENCH_WEB_BASE_URL}}', window.location).toString(); Object.keys(self.webPackagePaths).map(function (key, index) { -- self.webPackagePaths[key] = `${window.location.origin}/static/remote/web/node_modules/${key}/${self.webPackagePaths[key]}`; -+ self.webPackagePaths[key] = new URL( -+ `{{VS_BASE}}/static/remote/web/node_modules/${key}/${self.webPackagePaths[key]}`, -+ window.location, -+ ).toString(); + self.webPackagePaths[key] = `${baseUrl}/remote/web/node_modules/${key}/${self.webPackagePaths[key]}`; }); - require.config({ -- baseUrl: `${window.location.origin}/static/out`, -+ baseUrl: new URL(`{{VS_BASE}}/static/out`, window.location).toString(), - recordStats: true, - trustedTypesPolicy: window.trustedTypes?.createPolicy('amdLoader', { - createScriptURL(value) { Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html =================================================================== --- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.html @@ -87,68 +73,32 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html <!-- Disable pinch zooming --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> -@@ -24,10 +24,10 @@ +@@ -24,9 +24,9 @@ <meta id="vscode-workbench-auth-session" data-settings="{{WORKBENCH_AUTH_SESSION}}"> <!-- Workbench Icon/Manifest/CSS --> - <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" /> -- <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" /> +- <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" /> - <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> -- <link data-name="vs/workbench/workbench.web.main" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.main.css"> + <link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" /> -+ <link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" /> ++ <link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" /> + <link rel="manifest" href="{{VS_BASE}}/manifest.json" crossorigin="use-credentials" /> -+ <link data-name="vs/workbench/workbench.web.main" rel="stylesheet" href="{{VS_BASE}}/static/out/vs/workbench/workbench.web.main.css"> + <link data-name="vs/workbench/workbench.web.main" rel="stylesheet" href="{{WORKBENCH_WEB_BASE_URL}}/out/vs/workbench/workbench.web.main.css"> </head> - -@@ -35,14 +35,17 @@ - </body> - - <!-- Startup (do not modify order of script tags!) --> -- <script src="./static/out/vs/loader.js"></script> -- <script src="./static/out/vs/webPackagePaths.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/loader.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/webPackagePaths.js"></script> - <script> - Object.keys(self.webPackagePaths).map(function (key, index) { -- self.webPackagePaths[key] = `${window.location.origin}/static/node_modules/${key}/${self.webPackagePaths[key]}`; -+ self.webPackagePaths[key] = new URL( -+ `{{VS_BASE}}/static/node_modules/${key}/${self.webPackagePaths[key]}`, -+ window.location, -+ ).toString(); - }); - require.config({ -- baseUrl: `${window.location.origin}/static/out`, -+ baseUrl: new URL(`{{VS_BASE}}/static/out`, window.location).toString(), - recordStats: true, - trustedTypesPolicy: window.trustedTypes?.createPolicy('amdLoader', { - createScriptURL(value) { -@@ -55,7 +58,7 @@ - <script> - performance.mark('code/willLoadWorkbenchMain'); - </script> -- <script src="./static/out/vs/workbench/workbench.web.main.nls.js"></script> -- <script src="./static/out/vs/workbench/workbench.web.main.js"></script> -- <script src="./static/out/vs/code/browser/workbench/workbench.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/workbench/workbench.web.main.nls.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/workbench/workbench.web.main.js"></script> -+ <script src="{{VS_BASE}}/static/out/vs/code/browser/workbench/workbench.js"></script> - </html> Index: code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts +++ code-server/lib/vscode/src/vs/platform/remote/browser/browserSocketFactory.ts -@@ -274,7 +274,7 @@ export class BrowserSocketFactory implem +@@ -274,6 +274,7 @@ export class BrowserSocketFactory implem - connect(host: string, port: number, query: string, debugLabel: string, callback: IConnectCallback): void { + connect(host: string, port: number, path: string, query: string, debugLabel: string, callback: IConnectCallback): void { const webSocketSchema = (/^https:/.test(window.location.href) ? 'wss' : 'ws'); -- const socket = this._webSocketFactory.create(`${webSocketSchema}://${/:/.test(host) ? `[${host}]` : host}:${port}/?${query}&skipWebSocketFrames=false`, debugLabel); -+ const socket = this._webSocketFactory.create(`${webSocketSchema}://${window.location.host}${window.location.pathname}?${query}&skipWebSocketFrames=false`, debugLabel); ++ path = (window.location.pathname + "/" + path).replace(/\/\/+/g, "/") + const socket = this._webSocketFactory.create(`${webSocketSchema}://${/:/.test(host) ? `[${host}]` : host}:${port}${path}?${query}&skipWebSocketFrames=false`, debugLabel); const errorListener = socket.onError((err) => callback(err, undefined)); socket.onOpen(() => { - errorListener.dispose(); -@@ -282,6 +282,3 @@ export class BrowserSocketFactory implem +@@ -282,6 +283,3 @@ export class BrowserSocketFactory implem }); } } @@ -159,47 +109,56 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -253,7 +253,10 @@ export class WebClientServer { +@@ -267,14 +267,10 @@ export class WebClientServer { return res.end(); } -- const remoteAuthority = req.headers.host; +- let originalHost = req.headers['x-original-host']; +- if (Array.isArray(originalHost)) { +- originalHost = originalHost[0]; +- } +- const remoteAuthority = originalHost || req.headers.host; +- if (!remoteAuthority) { +- return serveError(req, res, 400, `Bad request.`); +- } + // It is not possible to reliably detect the remote authority on the server + // in all cases. Set this to something invalid to make sure we catch code + // that is using this when it should not. + const remoteAuthority = 'remote'; - function escapeAttribute(value: string): string { - return value.replace(/"/g, '"'); -@@ -275,6 +278,8 @@ export class WebClientServer { - accessToken: this._environmentService.args['github-auth'], + function asJSON(value: unknown): string { + return JSON.stringify(value).replace(/"/g, '"'); +@@ -297,6 +293,8 @@ export class WebClientServer { scopes: [['user:email'], ['repo']] } : undefined; + + const base = relativeRoot(getOriginalUrl(req)) + const vscodeBase = relativePath(getOriginalUrl(req)) - const data = (await util.promisify(fs.readFile)(filePath)).toString() - .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ - remoteAuthority, -@@ -285,6 +290,7 @@ export class WebClientServer { - folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), - workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), - productConfiguration: <Partial<IProductConfiguration>>{ -+ rootEndpoint: base, - codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', - extensionsGallery: this._webExtensionResourceUrlTemplate ? { -@@ -297,7 +303,9 @@ export class WebClientServer { - } : undefined - } - }))) -- .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : ''); -+ .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') -+ .replace(/{{BASE}}/g, base) -+ .replace(/{{VS_BASE}}/g, vscodeBase); - const cspDirectives = [ - 'default-src \'self\';', -@@ -376,3 +384,70 @@ export class WebClientServer { + const workbenchWebConfiguration = { + remoteAuthority, +@@ -308,6 +306,7 @@ export class WebClientServer { + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), + productConfiguration: <Partial<IProductConfiguration>>{ + codeServerVersion: this._productService.codeServerVersion, ++ rootEndpoint: base, + embedderIdentifier: 'server-distro', + extensionsGallery: this._webExtensionResourceUrlTemplate ? { + ...this._productService.extensionsGallery, +@@ -328,8 +327,10 @@ export class WebClientServer { + const values: { [key: string]: string } = { + WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration), + WORKBENCH_AUTH_SESSION: authSessionInfo ? asJSON(authSessionInfo) : '', +- WORKBENCH_WEB_BASE_URL: this._staticRoute, +- WORKBENCH_NLS_BASE_URL: nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : '', ++ WORKBENCH_WEB_BASE_URL: vscodeBase + this._staticRoute, ++ WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : ''), ++ BASE: base, ++ VS_BASE: vscodeBase, + }; + + +@@ -419,3 +420,70 @@ export class WebClientServer { return res.end(data); } } @@ -286,7 +245,7 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.ts +++ code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts -@@ -482,6 +482,7 @@ function doCreateUri(path: string, query +@@ -485,6 +485,7 @@ function doCreateUri(path: string, query }); } @@ -294,12 +253,12 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.ts return URI.parse(window.location.href).with({ path, query }); } -@@ -493,7 +494,7 @@ function doCreateUri(path: string, query +@@ -496,7 +497,7 @@ function doCreateUri(path: string, query if (!configElement || !configElementAttribute) { throw new Error('Missing web configuration element'); } -- const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents } = JSON.parse(configElementAttribute); -+ const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents, workspaceUri?: UriComponents } = { ...JSON.parse(configElementAttribute), remoteAuthority: location.host } +- const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = JSON.parse(configElementAttribute); ++ const config: IWorkbenchConstructionOptions & { folderUri?: UriComponents; workspaceUri?: UriComponents; callbackRoute: string } = { ...JSON.parse(configElementAttribute), remoteAuthority: location.host } // Create workbench create(document.body, { @@ -312,10 +271,10 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/ import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; -import { RemoteAuthorities } from 'vs/base/common/network'; + import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts'; export const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource'; - -@@ -72,7 +71,7 @@ export abstract class AbstractExtensionR +@@ -75,7 +74,7 @@ export abstract class AbstractExtensionR public getExtensionGalleryResourceURL(galleryExtension: { publisher: string; name: string; version: string }, path?: string): URI | undefined { if (this._extensionGalleryResourceUrlTemplate) { const uri = URI.parse(format2(this._extensionGalleryResourceUrlTemplate, { publisher: galleryExtension.publisher, name: galleryExtension.name, version: galleryExtension.version, path: 'extension' })); diff --git a/patches/connection-type.diff b/patches/connection-type.diff index 050715c90ff5..7ea29cd0764f 100644 --- a/patches/connection-type.diff +++ b/patches/connection-type.diff @@ -14,12 +14,13 @@ Index: code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnectio =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts +++ code-server/lib/vscode/src/vs/platform/remote/common/remoteAgentConnection.ts -@@ -231,7 +231,7 @@ async function connectToRemoteExtensionH - +@@ -233,7 +233,8 @@ async function connectToRemoteExtensionH + let socket: ISocket; try { -- socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); -+ socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, `type=${connectionTypeToString(connectionType)}&reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); +- socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, getRemoteServerRootPath(options), `reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); ++ ++ socket = await createSocket(options.logService, options.socketFactory, options.host, options.port, getRemoteServerRootPath(options), `type=${connectionTypeToString(connectionType)}&reconnectionToken=${options.reconnectionToken}&reconnection=${options.reconnectionProtocol ? 'true' : 'false'}`, `renderer-${connectionTypeToString(connectionType)}-${options.reconnectionToken}`, timeoutCancellationToken); } catch (error) { options.logService.error(`${logPrefix} socketFactory.connect() failed or timed out. Error:`); options.logService.error(error); diff --git a/patches/disable-builtin-ext-update.diff b/patches/disable-builtin-ext-update.diff index 4cee1361abe8..cbfd77406428 100644 --- a/patches/disable-builtin-ext-update.diff +++ b/patches/disable-builtin-ext-update.diff @@ -7,17 +7,18 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts -@@ -206,6 +206,9 @@ export class Extension implements IExten - if (!this.gallery || !this.local) { - return false; - } -+ if (this.type !== ExtensionType.User) { -+ return false; -+ } - if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) { - return false; - } -@@ -1057,6 +1060,10 @@ export class ExtensionsWorkbenchService +@@ -234,6 +234,10 @@ export class Extension implements IExten + if (this.type === ExtensionType.System && this.productService.quality === 'stable') { + return false; + } ++ // Do not update builtin extensions. ++ if (this.type !== ExtensionType.User) { ++ return false; ++ } + if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) { + return false; + } +@@ -1088,6 +1092,10 @@ export class ExtensionsWorkbenchService // Skip if check updates only for builtin extensions and current extension is not builtin. continue; } @@ -25,6 +26,6 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens + // Never update builtin extensions. + continue; + } - if (installed.isBuiltin && !installed.local?.identifier.uuid) { - // Skip if the builtin extension does not have Marketplace id + if (installed.isBuiltin && (!installed.local?.identifier.uuid || (!isWeb && this.productService.quality === 'stable'))) { + // Skip checking updates for a builtin extension if it does not has Marketplace identifier or the current product is VS Code Desktop stable. continue; diff --git a/patches/disable-downloads.diff b/patches/disable-downloads.diff index 7568fcd0b6e5..b5f7dc7233e9 100644 --- a/patches/disable-downloads.diff +++ b/patches/disable-downloads.diff @@ -12,7 +12,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -215,6 +215,11 @@ export interface IWorkbenchConstructionO +@@ -250,6 +250,11 @@ export interface IWorkbenchConstructionO */ readonly userDataPath?: string @@ -28,7 +28,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -30,6 +30,11 @@ export interface IBrowserWorkbenchEnviro +@@ -31,6 +31,11 @@ export interface IBrowserWorkbenchEnviro * Options used to configure the workbench. */ readonly options?: IWorkbenchConstructionOptions; @@ -40,7 +40,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi } export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvironmentService { -@@ -61,6 +66,13 @@ export class BrowserWorkbenchEnvironment +@@ -62,6 +67,13 @@ export class BrowserWorkbenchEnvironment return this.options.userDataPath; } @@ -58,18 +58,18 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts -@@ -15,6 +15,7 @@ export const serverOptions: OptionDescri +@@ -14,6 +14,7 @@ export const serverOptions: OptionDescri + /* ----- code-server ----- */ 'disable-update-check': { type: 'boolean' }, 'auth': { type: 'string' }, - 'locale': { type: 'string' }, + 'disable-file-downloads': { type: 'boolean' }, /* ----- server setup ----- */ -@@ -96,6 +97,7 @@ export interface ServerParsedArgs { +@@ -94,6 +95,7 @@ export interface ServerParsedArgs { + /* ----- code-server ----- */ 'disable-update-check'?: boolean; 'auth'?: string - 'locale'?: string + 'disable-file-downloads'?: boolean; /* ----- server setup ----- */ @@ -78,14 +78,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -293,6 +293,7 @@ export class WebClientServer { - logLevel: this._logService.getLevel(), - }, - userDataPath: this._environmentService.userDataPath, -+ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'], - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], - folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), +@@ -300,6 +300,7 @@ export class WebClientServer { + remoteAuthority, + webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', + userDataPath: this._environmentService.userDataPath, ++ isEnabledFileDownloads: !this._environmentService.args['disable-file-downloads'], + _wrapWebWorkerExtHostInIframe, + developmentOptions: { + enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, Index: code-server/lib/vscode/src/vs/workbench/browser/contextkeys.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/contextkeys.ts @@ -144,7 +144,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/files/browser/fileActions import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys'; import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; -@@ -476,13 +476,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo +@@ -477,13 +477,16 @@ MenuRegistry.appendMenuItem(MenuId.Explo id: DOWNLOAD_COMMAND_ID, title: DOWNLOAD_LABEL }, diff --git a/patches/display-language.diff b/patches/display-language.diff index aad709545fb5..c3de5a83ff88 100644 --- a/patches/display-language.diff +++ b/patches/display-language.diff @@ -1,17 +1,28 @@ Add display language support -This likely needs tweaking if we want to upstream. +We can remove this once upstream supports all language packs. + +1. Proxies language packs to the service on the backend. +2. NLS configuration is embedded into the HTML for the browser to pick up. This + code to generate this configuration is copied from the native portion. +3. Remove navigator.language default since that will prevent the argv file from + being created if you are changing the language to whatever your browser + default happens to be. +4. Move the argv.json file to the server instead of in-browser storage. This is + where the current locale is stored and currently the server needs to be able + to read it. +5. Add the locale flag. Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts +++ code-server/lib/vscode/src/vs/server/node/serverServices.ts -@@ -192,6 +192,9 @@ export async function setupServerService +@@ -202,6 +202,9 @@ export async function setupServerService const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority)); socketServer.registerChannel('extensions', channel); -+ const localizationsChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(ILocalizationsService)); -+ socketServer.registerChannel('localizations', localizationsChannel); ++ const languagePackChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(ILanguagePackService)); ++ socketServer.registerChannel('languagePacks', languagePackChannel); + const encryptionChannel = ProxyChannel.fromService<RemoteAgentConnectionContext>(accessor.get(IEncryptionMainService)); socketServer.registerChannel('encryption', encryptionChannel); @@ -20,9 +31,12 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/platform.ts +++ code-server/lib/vscode/src/vs/base/common/platform.ts -@@ -84,6 +84,17 @@ if (typeof navigator === 'object' && !is +@@ -80,8 +80,19 @@ if (typeof navigator === 'object' && !is + _isIOS = (_userAgent.indexOf('Macintosh') >= 0 || _userAgent.indexOf('iPad') >= 0 || _userAgent.indexOf('iPhone') >= 0) && !!navigator.maxTouchPoints && navigator.maxTouchPoints > 0; + _isLinux = _userAgent.indexOf('Linux') >= 0; _isWeb = true; - _locale = navigator.language; +- _locale = navigator.language; ++ _locale = LANGUAGE_DEFAULT; _language = _locale; + + const el = typeof document !== 'undefined' && document.getElementById('vscode-remote-nls-configuration'); @@ -51,23 +65,33 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html + <!-- Workbench Icon/Manifest/CSS --> <link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" /> - <link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" /> -@@ -38,6 +41,27 @@ - <script src="{{VS_BASE}}/static/out/vs/loader.js"></script> - <script src="{{VS_BASE}}/static/out/vs/webPackagePaths.js"></script> - <script> -+ let nlsConfig + <link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" /> +@@ -43,17 +46,27 @@ + self.webPackagePaths[key] = `${baseUrl}/node_modules/${key}/${self.webPackagePaths[key]}`; + }); + +- // Set up nls if the user is not using the default language (English) + const nlsConfig = {}; +- const locale = navigator.language; +- if (!locale.startsWith('en')) { +- nlsConfig['vs/nls'] = { +- availableLanguages: { +- '*': locale +- }, +- baseUrl: '{{WORKBENCH_NLS_BASE_URL}}' +- }; +- } + try { -+ nlsConfig = JSON.parse(document.getElementById("vscode-remote-nls-configuration").getAttribute("data-settings")) -+ if (nlsConfig._resolvedLanguagePackCoreLocation) { ++ nlsConfig['vs/nls'] = JSON.parse(document.getElementById("vscode-remote-nls-configuration").getAttribute("data-settings")) ++ if (nlsConfig['vs/nls']._resolvedLanguagePackCoreLocation) { + const bundles = Object.create(null) -+ nlsConfig.loadBundle = (bundle, _language, cb) => { ++ nlsConfig['vs/nls'].loadBundle = (bundle, _language, cb) => { + const result = bundles[bundle] + if (result) { + return cb(undefined, result) + } -+ const path = nlsConfig._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json" -+ fetch(`{{VS_BASE}}/vscode-remote-resource?path=${encodeURIComponent(path)}`) ++ const path = nlsConfig['vs/nls']._resolvedLanguagePackCoreLocation + "/" + bundle.replace(/\//g, "!") + ".nls.json" ++ fetch(`{{WORKBENCH_WEB_BASE_URL}}/vscode-remote-resource?path=${encodeURIComponent(path)}`) + .then((response) => response.json()) + .then((json) => { + bundles[bundle] = json @@ -77,19 +101,9 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html + } + } + } catch (error) { /* Probably fine. */ } - Object.keys(self.webPackagePaths).map(function (key, index) { - self.webPackagePaths[key] = new URL( - `{{VS_BASE}}/static/node_modules/${key}/${self.webPackagePaths[key]}`, -@@ -52,7 +76,8 @@ - return value; - } - }), -- paths: self.webPackagePaths -+ paths: self.webPackagePaths, -+ 'vs/nls': nlsConfig, - }); - </script> - <script> + + require.config({ + baseUrl: `${baseUrl}/out`, Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts @@ -168,98 +182,88 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -27,6 +27,7 @@ import { URI } from 'vs/base/common/uri' +@@ -26,6 +26,7 @@ import { URI } from 'vs/base/common/uri' import { streamToBuffer } from 'vs/base/common/buffer'; import { IProductConfiguration } from 'vs/base/common/product'; import { isString } from 'vs/base/common/types'; +import { getLocaleFromConfig, getNLSConfiguration } from 'vs/server/node/remoteLanguagePacks'; + import { CharCode } from 'vs/base/common/charCode'; + import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts'; + +@@ -295,6 +296,8 @@ export class WebClientServer { - const textMimeType = { - '.html': 'text/html', -@@ -280,6 +281,8 @@ export class WebClientServer { - } : undefined; const base = relativeRoot(getOriginalUrl(req)) const vscodeBase = relativePath(getOriginalUrl(req)) + const locale = this._environmentService.args.locale || await getLocaleFromConfig(this._environmentService.argvResource.fsPath); + const nlsConfiguration = await getNLSConfiguration(locale, this._environmentService.userDataPath) - const data = (await util.promisify(fs.readFile)(filePath)).toString() - .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ - remoteAuthority, -@@ -309,7 +312,8 @@ export class WebClientServer { - }))) - .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') - .replace(/{{BASE}}/g, base) -- .replace(/{{VS_BASE}}/g, vscodeBase); -+ .replace(/{{VS_BASE}}/g, vscodeBase) -+ .replace(/{{NLS_CONFIGURATION}}/g, () => escapeAttribute(JSON.stringify(nlsConfiguration))); - const cspDirectives = [ - 'default-src \'self\';', + const workbenchWebConfiguration = { + remoteAuthority, +@@ -338,6 +341,7 @@ export class WebClientServer { + WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl}${this._productService.commit}/${this._productService.version}/` : ''), + BASE: base, + VS_BASE: vscodeBase, ++ NLS_CONFIGURATION: asJSON(nlsConfiguration), + }; + + Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts -@@ -14,6 +14,7 @@ export const serverOptions: OptionDescri - /* ----- code-server ----- */ +@@ -15,6 +15,7 @@ export const serverOptions: OptionDescri 'disable-update-check': { type: 'boolean' }, 'auth': { type: 'string' }, + 'disable-file-downloads': { type: 'boolean' }, + 'locale': { type: 'string' }, /* ----- server setup ----- */ -@@ -94,6 +95,7 @@ export interface ServerParsedArgs { - /* ----- code-server ----- */ +@@ -96,6 +97,7 @@ export interface ServerParsedArgs { 'disable-update-check'?: boolean; 'auth'?: string + 'disable-file-downloads'?: boolean; + 'locale'?: string /* ----- server setup ----- */ -Index: code-server/lib/vscode/src/vs/workbench/services/localizations/browser/localizationsService.ts +Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts =================================================================== ---- /dev/null -+++ code-server/lib/vscode/src/vs/workbench/services/localizations/browser/localizationsService.ts -@@ -0,0 +1,28 @@ -+/*--------------------------------------------------------------------------------------------- -+ * Copyright (c) Coder Technologies. All rights reserved. -+ * Licensed under the MIT License. See License.txt in the project root for license information. -+ *--------------------------------------------------------------------------------------------*/ +--- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts ++++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts +@@ -109,6 +109,12 @@ registerSingleton(IDiagnosticsService, N + + //#region --- workbench contributions + ++// Localization. These do not actually import anything specific to Electron so ++// they should be safe. ++import 'vs/workbench/services/localization/electron-sandbox/localeService'; ++import 'vs/workbench/contrib/localization/electron-sandbox/localization.contribution'; ++import 'vs/platform/languagePacks/browser/languagePacks'; + + // Output + import 'vs/workbench/contrib/output/common/outputChannelModelService'; + +Index: code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts +=================================================================== +--- /dev/null ++++ code-server/lib/vscode/src/vs/platform/languagePacks/browser/languagePacks.ts +@@ -0,0 +1,18 @@ +import { ProxyChannel } from 'vs/base/parts/ipc/common/ipc'; +import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -+import { ILocalizationsService } from 'vs/platform/localizations/common/localizations'; ++import { ILanguagePackService } from 'vs/platform/languagePacks/common/languagePacks'; +import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; + -+/** -+ * Add localizations service for the browser. -+ * @author coder -+ */ -+ +// @ts-ignore: interface is implemented via proxy -+export class LocalizationsService implements ILocalizationsService { ++export class LanguagePackService implements ILanguagePackService { + + declare readonly _serviceBrand: undefined; + + constructor( + @IRemoteAgentService remoteAgentService: IRemoteAgentService, + ) { -+ return ProxyChannel.toService<ILocalizationsService>(remoteAgentService.getConnection()!.getChannel('localizations')); ++ return ProxyChannel.toService<ILanguagePackService>(remoteAgentService.getConnection()!.getChannel('languagePacks')); + } +} + -+registerSingleton(ILocalizationsService, LocalizationsService, true); -Index: code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts -=================================================================== ---- code-server.orig/lib/vscode/src/vs/workbench/workbench.web.main.ts -+++ code-server/lib/vscode/src/vs/workbench/workbench.web.main.ts -@@ -112,6 +112,10 @@ registerSingleton(IDiagnosticsService, N - - //#region --- workbench contributions - -+// Localizations -+import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; -+import 'vs/workbench/services/localizations/browser/localizationsService'; -+ - // Output - import 'vs/workbench/contrib/output/common/outputChannelModelService'; - ++registerSingleton(ILanguagePackService, LanguagePackService, true); diff --git a/patches/github-auth.diff b/patches/github-auth.diff index 53b98d0f422f..20ab57e42724 100644 --- a/patches/github-auth.diff +++ b/patches/github-auth.diff @@ -7,7 +7,7 @@ Index: code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainSe =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts +++ code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainService.ts -@@ -5,18 +5,32 @@ +@@ -5,9 +5,18 @@ import { InMemoryCredentialsProvider } from 'vs/platform/credentials/common/credentials'; import { ILogService } from 'vs/platform/log/common/log'; @@ -26,6 +26,8 @@ Index: code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainSe +} export class CredentialsWebMainService extends BaseCredentialsMainService { + // Since we fallback to the in-memory credentials provider, we do not need to surface any Keytar load errors +@@ -16,10 +25,15 @@ export class CredentialsWebMainService e constructor( @ILogService logService: ILogService, @@ -42,7 +44,7 @@ Index: code-server/lib/vscode/src/vs/platform/credentials/node/credentialsMainSe } // If the credentials service is running on the server, we add a suffix -server to differentiate from the location that the -@@ -45,4 +59,59 @@ export class CredentialsWebMainService e +@@ -48,4 +62,59 @@ export class CredentialsWebMainService e } return this._keytarCache; } diff --git a/patches/integration.diff b/patches/integration.diff index e8c1972383dd..f3d63771f91f 100644 --- a/patches/integration.diff +++ b/patches/integration.diff @@ -7,6 +7,7 @@ Prepare Code for integration with code-server 3. Add the code-server version to the help dialog. 4. Add ready events for use in an iframe. 5. Add our icons. +6. Use our own manifest. Index: code-server/lib/vscode/src/vs/server/node/server.main.ts =================================================================== @@ -21,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/server/node/server.main.ts import product from 'vs/platform/product/common/product'; import * as perf from 'vs/base/common/performance'; -@@ -33,38 +33,43 @@ const errorReporter: ErrorReporter = { +@@ -34,38 +34,43 @@ const errorReporter: ErrorReporter = { } }; @@ -106,7 +107,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandl =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts +++ code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandler.ts -@@ -143,12 +143,15 @@ export class BrowserDialogHandler implem +@@ -143,8 +143,11 @@ export class BrowserDialogHandler implem async about(): Promise<void> { const detailString = (useAgo: boolean): string => { @@ -120,11 +121,6 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/parts/dialogs/dialogHandl this.productService.version || 'Unknown', this.productService.commit || 'Unknown', this.productService.date ? `${this.productService.date}${useAgo ? ' (' + fromNow(new Date(this.productService.date), true) + ')' : ''}` : 'Unknown', -- navigator.userAgent -+ navigator.userAgent, - ); - }; - Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- /dev/null @@ -185,10 +181,10 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts import { IWorkspace } from 'vs/workbench/services/host/browser/browserHostService'; import { WebFileSystemAccess } from 'vs/platform/files/browser/webFileSystemAccess'; +import { CodeServerClient } from 'vs/workbench/browser/client'; - - export class BrowserMain extends Disposable { - -@@ -103,6 +104,9 @@ export class BrowserMain extends Disposa + import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; + import { IProgressService } from 'vs/platform/progress/common/progress'; + import { DelayedLogChannel } from 'vs/workbench/services/output/common/delayedLogChannel'; +@@ -109,6 +110,9 @@ export class BrowserMain extends Disposa // Startup const instantiationService = workbench.startup(); @@ -219,22 +215,24 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench-dev.html <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-title" content="Code"> -- <link rel="apple-touch-icon" href="/code-192.png" /> +- <link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/code-192.png" /> + <link rel="apple-touch-icon" sizes="192x192" href="/_static/src/browser/media/pwa-icon-192.png" /> + <link rel="apple-touch-icon" sizes="512x512" href="/_static/src/browser/media/pwa-icon-512.png" /> <!-- Disable pinch zooming --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> -@@ -26,7 +27,8 @@ +@@ -26,8 +27,9 @@ <meta id="vscode-workbench-builtin-extensions" data-settings="{{WORKBENCH_BUILTIN_EXTENSIONS}}"> <!-- Workbench Icon/Manifest/CSS --> -- <link rel="icon" href="/favicon.ico" type="image/x-icon" /> +- <link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" /> +- <link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" /> + <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" /> -+ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" /> - <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> ++ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" /> ++ <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> </head> + <body aria-label=""> Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html =================================================================== --- code-server.orig/lib/vscode/src/vs/code/browser/workbench/workbench.html @@ -243,31 +241,33 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html <meta name="mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-title" content="Code"> -- <link rel="apple-touch-icon" href="/code-192.png" /> +- <link rel="apple-touch-icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/code-192.png" /> + <link rel="apple-touch-icon" sizes="192x192" href="/_static/src/browser/media/pwa-icon-192.png" /> + <link rel="apple-touch-icon" sizes="512x512" href="/_static/src/browser/media/pwa-icon-512.png" /> <!-- Disable pinch zooming --> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> -@@ -23,7 +24,8 @@ +@@ -23,8 +24,9 @@ <meta id="vscode-workbench-auth-session" data-settings="{{WORKBENCH_AUTH_SESSION}}"> <!-- Workbench Icon/Manifest/CSS --> -- <link rel="icon" href="/favicon.ico" type="image/x-icon" /> +- <link rel="icon" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/favicon.ico" type="image/x-icon" /> +- <link rel="manifest" href="{{WORKBENCH_WEB_BASE_URL}}/resources/server/manifest.json" crossorigin="use-credentials" /> + <link rel="icon" href="/_static/src/browser/media/favicon-dark-support.svg" /> -+ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" /> - <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> - <link data-name="vs/workbench/workbench.web.main" rel="stylesheet" href="./static/out/vs/workbench/workbench.web.main.css"> ++ <link rel="alternate icon" href="/_static/src/browser/media/favicon.ico" type="image/x-icon" /> ++ <link rel="manifest" href="/manifest.json" crossorigin="use-credentials" /> + <link data-name="vs/workbench/workbench.web.main" rel="stylesheet" href="{{WORKBENCH_WEB_BASE_URL}}/out/vs/workbench/workbench.web.main.css"> + </head> Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -285,6 +285,7 @@ export class WebClientServer { - folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), - workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), - productConfiguration: <Partial<IProductConfiguration>>{ -+ codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', - extensionsGallery: this._webExtensionResourceUrlTemplate ? { - ...this._productService.extensionsGallery, +@@ -307,6 +307,7 @@ export class WebClientServer { + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), + workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), + productConfiguration: <Partial<IProductConfiguration>>{ ++ codeServerVersion: this._productService.codeServerVersion, + embedderIdentifier: 'server-distro', + extensionsGallery: this._webExtensionResourceUrlTemplate ? { + ...this._productService.extensionsGallery, diff --git a/patches/local-storage.diff b/patches/local-storage.diff index 744540bbfafd..a7aa8b06b489 100644 --- a/patches/local-storage.diff +++ b/patches/local-storage.diff @@ -20,19 +20,19 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -292,6 +292,7 @@ export class WebClientServer { - enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined, - logLevel: this._logService.getLevel(), - }, -+ userDataPath: this._environmentService.userDataPath, - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], - folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), +@@ -299,6 +299,7 @@ export class WebClientServer { + const workbenchWebConfiguration = { + remoteAuthority, + webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', ++ userDataPath: this._environmentService.userDataPath, + _wrapWebWorkerExtHostInIframe, + developmentOptions: { + enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, Index: code-server/lib/vscode/src/vs/workbench/browser/web.api.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.api.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.api.ts -@@ -210,6 +210,11 @@ export interface IWorkbenchConstructionO +@@ -245,6 +245,11 @@ export interface IWorkbenchConstructionO */ readonly configurationDefaults?: Record<string, any>; @@ -48,7 +48,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -52,7 +52,14 @@ export class BrowserWorkbenchEnvironment +@@ -53,7 +53,14 @@ export class BrowserWorkbenchEnvironment get logFile(): URI { return joinPath(this.logsHome, 'window.log'); } @memoize diff --git a/patches/log-level.diff b/patches/log-level.diff index 8b4f125b5d43..53226c226338 100644 --- a/patches/log-level.diff +++ b/patches/log-level.diff @@ -7,15 +7,15 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -288,7 +288,10 @@ export class WebClientServer { - remoteAuthority, - webviewEndpoint: vscodeBase + '/static/out/vs/workbench/contrib/webview/browser/pre', - _wrapWebWorkerExtHostInIframe, -- developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, -+ developmentOptions: { -+ enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined, -+ logLevel: this._logService.getLevel(), -+ }, - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, - enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], - folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), +@@ -300,7 +300,10 @@ export class WebClientServer { + remoteAuthority, + webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', + _wrapWebWorkerExtHostInIframe, +- developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined }, ++ developmentOptions: { ++ enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined, ++ logLevel: this._logService.getLevel(), ++ }, + settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, + enableWorkspaceTrust: !this._environmentService.args['disable-workspace-trust'], + folderUri: resolveWorkspaceURI(this._environmentService.args['default-folder']), diff --git a/patches/logout.diff b/patches/logout.diff index 1a8d0f00567b..24c4923dff64 100644 --- a/patches/logout.diff +++ b/patches/logout.diff @@ -40,14 +40,14 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -293,6 +293,7 @@ export class WebClientServer { - productConfiguration: <Partial<IProductConfiguration>>{ - rootEndpoint: base, - updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, -+ logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, - codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', - extensionsGallery: { +@@ -309,6 +309,7 @@ export class WebClientServer { + codeServerVersion: this._productService.codeServerVersion, + rootEndpoint: base, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, ++ logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + embedderIdentifier: 'server-distro', + extensionsGallery: this._productService.extensionsGallery, + }, Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts diff --git a/patches/marketplace.diff b/patches/marketplace.diff index d6e799756320..8eb88101dc49 100644 --- a/patches/marketplace.diff +++ b/patches/marketplace.diff @@ -3,6 +3,13 @@ Add Open VSX default and an env var for marketplace, fix old marketplace Our old marketplace only supports `serviceUrl` but this causes the marketplace to be disabled entirely so this moves the template var check to fix that. +This also removes serverRootPath from the web extension route because that will +include the commit. When you update code-server (including this update) the web +extension will continue using the old path since it is stored in the browser but +the path will 404 because the commit no longer matches. This change is only to +support current installations though because this patch also removes the +in-between and has web extensions install directly from the marketplace. + This can be tested by setting EXTENSIONS_GALLERY set to: '{"serviceUrl": "https://extensions.coder.com/api"}' @@ -32,22 +39,49 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -293,14 +293,14 @@ export class WebClientServer { - rootEndpoint: base, - codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', -- extensionsGallery: this._webExtensionResourceUrlTemplate ? { -+ extensionsGallery: { - ...this._productService.extensionsGallery, -- 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({ -+ 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate ? this._webExtensionResourceUrlTemplate.with({ - scheme: 'http', - authority: remoteAuthority, - path: `web-extension-resource/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}` -- }).toString(true) -- } : undefined -+ }).toString(true) : undefined -+ }, - } - }))) - .replace('{{WORKBENCH_AUTH_SESSION}}', () => authSessionInfo ? escapeAttribute(JSON.stringify(authSessionInfo)) : '') +@@ -111,7 +111,7 @@ export class WebClientServer { + const serverRootPath = getRemoteServerRootPath(_productService); + this._staticRoute = `${serverRootPath}/static`; + this._callbackRoute = `${serverRootPath}/callback`; +- this._webExtensionRoute = `${serverRootPath}/web-extension-resource`; ++ this._webExtensionRoute = `/web-extension-resource`; + } + + /** +@@ -308,14 +308,7 @@ export class WebClientServer { + codeServerVersion: this._productService.codeServerVersion, + rootEndpoint: base, + embedderIdentifier: 'server-distro', +- extensionsGallery: this._webExtensionResourceUrlTemplate ? { +- ...this._productService.extensionsGallery, +- 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate.with({ +- scheme: 'http', +- authority: remoteAuthority, +- path: `${this._webExtensionRoute}/${this._webExtensionResourceUrlTemplate.authority}${this._webExtensionResourceUrlTemplate.path}` +- }).toString(true) +- } : undefined ++ extensionsGallery: this._productService.extensionsGallery, + }, + callbackRoute: this._callbackRoute + }; +Index: code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts ++++ code-server/lib/vscode/src/vs/workbench/services/extensionResourceLoader/common/extensionResourceLoader.ts +@@ -16,7 +16,6 @@ import { getServiceMachineId } from 'vs/ + import { IStorageService } from 'vs/platform/storage/common/storage'; + import { TelemetryLevel } from 'vs/platform/telemetry/common/telemetry'; + import { getTelemetryLevel, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils'; +-import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts'; + + export const WEB_EXTENSION_RESOURCE_END_POINT = 'web-extension-resource'; + +@@ -60,7 +59,7 @@ export abstract class AbstractExtensionR + private readonly _environmentService: IEnvironmentService, + private readonly _configurationService: IConfigurationService, + ) { +- this._webExtensionResourceEndPoint = `${getRemoteServerRootPath(_productService)}/${WEB_EXTENSION_RESOURCE_END_POINT}/`; ++ this._webExtensionResourceEndPoint = `/${WEB_EXTENSION_RESOURCE_END_POINT}/`; + if (_productService.extensionsGallery) { + this._extensionGalleryResourceUrlTemplate = _productService.extensionsGallery.resourceUrlTemplate; + this._extensionGalleryAuthority = this._extensionGalleryResourceUrlTemplate ? this._getExtensionGalleryAuthority(URI.parse(this._extensionGalleryResourceUrlTemplate)) : undefined; diff --git a/patches/proposed-api.diff b/patches/proposed-api.diff index ebd5deb57569..397a3767e697 100644 --- a/patches/proposed-api.diff +++ b/patches/proposed-api.diff @@ -9,7 +9,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstra =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/abstractExtensionService.ts -@@ -1471,7 +1471,7 @@ class ProposedApiController { +@@ -1451,7 +1451,7 @@ class ProposedApiController { this._envEnabledExtensions = new Set((_environmentService.extensionEnabledProposedApi ?? []).map(id => ExtensionIdentifier.toKey(id))); @@ -22,7 +22,7 @@ Index: code-server/lib/vscode/src/vs/workbench/services/extensions/common/extens =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts +++ code-server/lib/vscode/src/vs/workbench/services/extensions/common/extensions.ts -@@ -163,10 +163,7 @@ export interface IExtensionHost { +@@ -359,10 +359,7 @@ function extensionDescriptionArrayToMap( } export function isProposedApiEnabled(extension: IExtensionDescription, proposal: ApiProposalName): boolean { diff --git a/patches/proxy-uri.diff b/patches/proxy-uri.diff index b153b20df00d..c0899b0b7298 100644 --- a/patches/proxy-uri.diff +++ b/patches/proxy-uri.diff @@ -26,25 +26,25 @@ Index: code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityReso =================================================================== --- code-server.orig/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts +++ code-server/lib/vscode/src/vs/platform/remote/browser/remoteAuthorityResolverService.ts -@@ -7,7 +7,7 @@ import { Emitter } from 'vs/base/common/ - import { Disposable } from 'vs/base/common/lifecycle'; +@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/comm import { RemoteAuthorities } from 'vs/base/common/network'; import { URI } from 'vs/base/common/uri'; + import { IProductService } from 'vs/platform/product/common/productService'; -import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver'; +import { IRemoteAuthorityResolverService, IRemoteConnectionData, ResolvedAuthority, ResolvedOptions, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver'; + import { getRemoteServerRootPath } from 'vs/platform/remote/common/remoteHosts'; export class RemoteAuthorityResolverService extends Disposable implements IRemoteAuthorityResolverService { - -@@ -20,7 +20,7 @@ export class RemoteAuthorityResolverServ +@@ -22,7 +22,7 @@ export class RemoteAuthorityResolverServ private readonly _connectionToken: string | undefined; private readonly _connectionTokens: Map<string, string>; -- constructor(connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) { -+ constructor(connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined, private readonly proxyEndpointTemplate?: string) { +- constructor(@IProductService productService: IProductService, connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined) { ++ constructor(@IProductService productService: IProductService, connectionToken: string | undefined, resourceUriProvider: ((uri: URI) => URI) | undefined, private readonly proxyEndpointTemplate?: string) { super(); this._cache = new Map<string, ResolverResult>(); this._connectionToken = connectionToken; -@@ -59,12 +59,17 @@ export class RemoteAuthorityResolverServ +@@ -62,12 +62,17 @@ export class RemoteAuthorityResolverServ private _doResolveAuthority(authority: string): ResolverResult { const connectionToken = this._connectionTokens.get(authority) || this._connectionToken; @@ -68,24 +68,24 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -294,6 +294,7 @@ export class WebClientServer { - rootEndpoint: base, - updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, - logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, -+ proxyEndpointTemplate: base + '/proxy/{{port}}', - codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', - extensionsGallery: { +@@ -310,6 +310,7 @@ export class WebClientServer { + rootEndpoint: base, + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, ++ proxyEndpointTemplate: base + '/proxy/{{port}}', + embedderIdentifier: 'server-distro', + extensionsGallery: this._productService.extensionsGallery, + }, Index: code-server/lib/vscode/src/vs/workbench/browser/web.main.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/web.main.ts +++ code-server/lib/vscode/src/vs/workbench/browser/web.main.ts -@@ -179,7 +179,7 @@ export class BrowserMain extends Disposa +@@ -209,7 +209,7 @@ export class BrowserMain extends Disposa // Remote const connectionToken = environmentService.options.connectionToken || getCookieValue(connectionTokenCookieName); -- const remoteAuthorityResolverService = new RemoteAuthorityResolverService(connectionToken, this.configuration.resourceUriProvider); -+ const remoteAuthorityResolverService = new RemoteAuthorityResolverService(connectionToken, this.configuration.resourceUriProvider, this.configuration.productConfiguration?.proxyEndpointTemplate); +- const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider); ++ const remoteAuthorityResolverService = new RemoteAuthorityResolverService(productService, connectionToken, this.configuration.resourceUriProvider, this.configuration.productConfiguration?.proxyEndpointTemplate); serviceCollection.set(IRemoteAuthorityResolverService, remoteAuthorityResolverService); // Signing @@ -93,7 +93,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts -@@ -388,7 +388,7 @@ export function createTerminalEnvironmen +@@ -388,7 +388,7 @@ export async function createTerminalEnvi // Sanitize the environment, removing any undesirable VS Code and Electron environment // variables diff --git a/patches/series b/patches/series index 318ad7abac9d..69b66b6ffc76 100644 --- a/patches/series +++ b/patches/series @@ -9,7 +9,6 @@ update-check.diff logout.diff store-socket.diff proxy-uri.diff -display-language.diff github-auth.diff unique-db.diff log-level.diff @@ -19,3 +18,4 @@ connection-type.diff sourcemaps.diff disable-downloads.diff telemetry.diff +display-language.diff diff --git a/patches/service-worker.diff b/patches/service-worker.diff index db2bacd22ef1..6ead1a60eec1 100644 --- a/patches/service-worker.diff +++ b/patches/service-worker.diff @@ -21,17 +21,17 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -304,6 +304,10 @@ export class WebClientServer { - proxyEndpointTemplate: base + '/proxy/{{port}}', - codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', -+ serviceWorker: { -+ scope: vscodeBase + '/', -+ path: base + '/_static/out/browser/serviceWorker.js', -+ }, - extensionsGallery: { - ...this._productService.extensionsGallery, - 'resourceUrlTemplate': this._webExtensionResourceUrlTemplate ? this._webExtensionResourceUrlTemplate.with({ +@@ -315,6 +315,10 @@ export class WebClientServer { + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, + proxyEndpointTemplate: base + '/proxy/{{port}}', ++ serviceWorker: { ++ scope: vscodeBase + '/', ++ path: base + '/_static/out/browser/serviceWorker.js', ++ }, + embedderIdentifier: 'server-distro', + extensionsGallery: this._productService.extensionsGallery, + }, Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts diff --git a/patches/sourcemaps.diff b/patches/sourcemaps.diff index 03502650c23b..fb252cfecddd 100644 --- a/patches/sourcemaps.diff +++ b/patches/sourcemaps.diff @@ -10,7 +10,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js =================================================================== --- code-server.orig/lib/vscode/build/gulpfile.reh.js +++ code-server/lib/vscode/build/gulpfile.reh.js -@@ -191,8 +191,7 @@ function packageTask(type, platform, arc +@@ -194,8 +194,7 @@ function packageTask(type, platform, arc const src = gulp.src(sourceFolderName + '/**', { base: '.' }) .pipe(rename(function (path) { path.dirname = path.dirname.replace(new RegExp('^' + sourceFolderName), 'out'); })) @@ -20,7 +20,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js const workspaceExtensionPoints = ['debuggers', 'jsonValidation']; const isUIExtension = (manifest) => { -@@ -231,9 +230,9 @@ function packageTask(type, platform, arc +@@ -234,9 +233,9 @@ function packageTask(type, platform, arc .map(name => `.build/extensions/${name}/**`); const extensions = gulp.src(extensionPaths, { base: '.build', dot: true }); @@ -32,7 +32,7 @@ Index: code-server/lib/vscode/build/gulpfile.reh.js let version = packageJson.version; const quality = product.quality; -@@ -368,7 +367,7 @@ function tweakProductForServerWeb(produc +@@ -371,7 +370,7 @@ function tweakProductForServerWeb(produc const minifyTask = task.define(`minify-vscode-${type}`, task.series( optimizeTask, util.rimraf(`out-vscode-${type}-min`), diff --git a/patches/telemetry.diff b/patches/telemetry.diff index 2d0feabac82b..77b5064b40ce 100644 --- a/patches/telemetry.diff +++ b/patches/telemetry.diff @@ -4,15 +4,15 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts +++ code-server/lib/vscode/src/vs/server/node/serverServices.ts -@@ -68,6 +68,7 @@ import { REMOTE_TERMINAL_CHANNEL_NAME } - import { RemoteExtensionLogFileName } from 'vs/workbench/services/remote/common/remoteAgentService'; - import { REMOTE_FILE_SYSTEM_CHANNEL_NAME } from 'vs/workbench/services/remote/common/remoteFileSystemProviderClient'; +@@ -70,6 +70,7 @@ import { REMOTE_FILE_SYSTEM_CHANNEL_NAME import { ExtensionHostStatusService, IExtensionHostStatusService } from 'vs/server/node/extensionHostStatusService'; + import { IExtensionsScannerService } from 'vs/platform/extensionManagement/common/extensionsScannerService'; + import { ExtensionsScannerService } from 'vs/server/node/extensionsScannerService'; +import { TelemetryClient } from "vs/server/node/telemetryClient"; + import { NullPolicyService } from 'vs/platform/policy/common/policy'; const eventPrefix = 'monacoworkbench'; - -@@ -120,7 +121,11 @@ export async function setupServerService +@@ -123,7 +124,11 @@ export async function setupServerService let appInsightsAppender: ITelemetryAppender = NullAppender; const machineId = await getMachineId(); if (supportsTelemetry(productService, environmentService)) { @@ -165,23 +165,11 @@ Index: code-server/lib/vscode/src/vs/server/node/telemetryClient.ts + } + } +} -Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts -=================================================================== ---- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts -+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -304,6 +304,7 @@ export class WebClientServer { - logoutEndpoint: this._environmentService.args['auth'] ? base + '/logout' : undefined, - proxyEndpointTemplate: base + '/proxy/{{port}}', - codeServerVersion: this._productService.codeServerVersion, -+ enableTelemetry: this._productService.enableTelemetry, - embedderIdentifier: 'server-distro', - serviceWorker: { - scope: vscodeBase + '/', Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts +++ code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/telemetryService.ts -@@ -119,16 +119,19 @@ export class TelemetryService extends Di +@@ -120,16 +120,19 @@ export class TelemetryService extends Di ) { super(); @@ -210,3 +198,15 @@ Index: code-server/lib/vscode/src/vs/workbench/services/telemetry/browser/teleme } else { this.impl = NullTelemetryService; } +Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts +=================================================================== +--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts ++++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts +@@ -320,6 +320,7 @@ export class WebClientServer { + scope: vscodeBase + '/', + path: base + '/_static/out/browser/serviceWorker.js', + }, ++ enableTelemetry: this._productService.enableTelemetry, + embedderIdentifier: 'server-distro', + extensionsGallery: this._productService.extensionsGallery, + }, diff --git a/patches/update-check.diff b/patches/update-check.diff index c36871094f81..941ffa16e59b 100644 --- a/patches/update-check.diff +++ b/patches/update-check.diff @@ -19,7 +19,7 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts import { INotificationService, Severity } from 'vs/platform/notification/common/notification'; +import { IProductService } from 'vs/platform/product/common/productService'; +import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; - + export class CodeServerClient extends Disposable { constructor ( + @ILogService private logService: ILogService, @@ -98,40 +98,40 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts readonly codeServerVersion?: string readonly rootEndpoint?: string + readonly updateEndpoint?: string - + readonly version: string; readonly date?: string; Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -292,6 +292,7 @@ export class WebClientServer { - workspaceUri: resolveWorkspaceURI(this._environmentService.args['default-workspace']), - productConfiguration: <Partial<IProductConfiguration>>{ - rootEndpoint: base, -+ updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, - codeServerVersion: this._productService.codeServerVersion, - embedderIdentifier: 'server-distro', - extensionsGallery: { +@@ -308,6 +308,7 @@ export class WebClientServer { + productConfiguration: <Partial<IProductConfiguration>>{ + codeServerVersion: this._productService.codeServerVersion, + rootEndpoint: base, ++ updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + embedderIdentifier: 'server-distro', + extensionsGallery: this._productService.extensionsGallery, + }, Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts +++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts @@ -11,6 +11,8 @@ import { refineServiceDecorator } from ' import { IEnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; - + export const serverOptions: OptionDescriptions<ServerParsedArgs> = { + /* ----- code-server ----- */ + 'disable-update-check': { type: 'boolean' }, - + /* ----- server setup ----- */ - + @@ -88,6 +90,8 @@ export const serverOptions: OptionDescri }; - + export interface ServerParsedArgs { + /* ----- code-server ----- */ + 'disable-update-check'?: boolean; - + /* ----- server setup ----- */ - + diff --git a/patches/webview.diff b/patches/webview.diff index c04847e1bf88..178dff9bada6 100644 --- a/patches/webview.diff +++ b/patches/webview.diff @@ -24,73 +24,94 @@ Index: code-server/lib/vscode/src/vs/workbench/services/environment/browser/envi =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts +++ code-server/lib/vscode/src/vs/workbench/services/environment/browser/environmentService.ts -@@ -179,7 +179,7 @@ export class BrowserWorkbenchEnvironment +@@ -183,7 +183,7 @@ export class BrowserWorkbenchEnvironment @memoize get webviewExternalEndpoint(): string { - const endpoint = this.options.webviewEndpoint + const endpoint = (this.options.webviewEndpoint && new URL(this.options.webviewEndpoint, window.location.toString()).toString()) || this.productService.webviewContentExternalBaseUrlTemplate - || 'https://{{uuid}}.vscode-webview.net/{{quality}}/{{commit}}/out/vs/workbench/contrib/webview/browser/pre/'; + || 'https://{{uuid}}.vscode-cdn.net/{{quality}}/{{commit}}/out/vs/workbench/contrib/webview/browser/pre/'; Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts +++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts -@@ -283,6 +283,7 @@ export class WebClientServer { - const data = (await util.promisify(fs.readFile)(filePath)).toString() - .replace('{{WORKBENCH_WEB_CONFIGURATION}}', escapeAttribute(JSON.stringify({ - remoteAuthority, -+ webviewEndpoint: vscodeBase + '/static/out/vs/workbench/contrib/webview/browser/pre', - _wrapWebWorkerExtHostInIframe, - developmentOptions: { enableSmokeTestDriver: this._environmentService.driverHandle === 'web' ? true : undefined }, - settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, -Index: code-server/lib/vscode/src/vs/workbench/common/webview.ts +@@ -298,6 +298,7 @@ export class WebClientServer { + + const workbenchWebConfiguration = { + remoteAuthority, ++ webviewEndpoint: vscodeBase + this._staticRoute + '/out/vs/workbench/contrib/webview/browser/pre', + _wrapWebWorkerExtHostInIframe, + developmentOptions: { enableSmokeTestDriver: this._environmentService.args['enable-smoke-test-driver'] ? true : undefined }, + settingsSyncOptions: !this._environmentService.isBuilt && this._environmentService.args['enable-sync'] ? { enabled: true } : undefined, +Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html =================================================================== ---- code-server.orig/lib/vscode/src/vs/workbench/common/webview.ts -+++ code-server/lib/vscode/src/vs/workbench/common/webview.ts -@@ -22,7 +22,7 @@ export const webviewResourceBaseHost = ' +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html ++++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index.html +@@ -5,7 +5,7 @@ + <meta charset="UTF-8"> - export const webviewRootResourceAuthority = `vscode-resource.${webviewResourceBaseHost}`; + <meta http-equiv="Content-Security-Policy" +- content="default-src 'none'; script-src 'sha256-xgIcbQmGjpT42GEj54VFSNh6MI15PZ2D1+DdVehfYBI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> ++ content="default-src 'none'; script-src 'sha256-aOCIU83V9nV+0ERJudbrKLqgIVOHqU71i4Lv5urjGTI=' 'self'; frame-src 'self'; style-src 'unsafe-inline';"> --export const webviewGenericCspSource = `https://*.${webviewResourceBaseHost}`; -+export const webviewGenericCspSource = `'self' https://*.${webviewResourceBaseHost}`; + <!-- Disable pinch zooming --> + <meta name="viewport" +@@ -331,6 +331,12 @@ - /** - * Construct a uri that can load resources inside a webview -Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/service-worker.js -=================================================================== ---- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/service-worker.js -+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/service-worker.js -@@ -188,9 +188,11 @@ sw.addEventListener('fetch', (event) => - } - } + const hostname = location.hostname; -- // If we're making a request against the remote authority, we want to go -- // back through VS Code itself so that we are authenticated properly -- if (requestUrl.host === remoteAuthority) { -+ // If we're making a request against the remote authority, we want to go back -+ // through VS Code itself so that we are authenticated properly. If the -+ // service worker is hosted on the same origin we will have cookies and -+ // authentication will not be an issue. -+ if (requestUrl.origin !== sw.origin && requestUrl.host === remoteAuthority) { - switch (event.request.method) { - case 'GET': - case 'HEAD': -Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js ++ // It is safe to run if we are on the same host. ++ const parent = new URL(parentOrigin) ++ if (parent.hostname === hostname) { ++ return start(parentOrigin) ++ } ++ + if (!crypto.subtle) { + // cannot validate, not running in a secure context + throw new Error(`Cannot validate in current context!`); +Index: code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html =================================================================== ---- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js -+++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/main.js -@@ -318,6 +318,12 @@ const hostMessaging = new class HostMess +--- code-server.orig/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html ++++ code-server/lib/vscode/src/vs/workbench/contrib/webview/browser/pre/index-no-csp.html +@@ -330,6 +330,12 @@ - const hostname = location.hostname; + const hostname = location.hostname; ++ // It is safe to run if we are on the same host. ++ const parent = new URL(parentOrigin) ++ if (parent.hostname === hostname) { ++ return start(parentOrigin) ++ } ++ + if (!crypto.subtle) { + // cannot validate, not running in a secure context + throw new Error(`Cannot validate in current context!`); +Index: code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +=================================================================== +--- code-server.orig/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html ++++ code-server/lib/vscode/src/vs/workbench/services/extensions/worker/webWorkerExtensionHostIframe.html +@@ -4,7 +4,7 @@ + <meta http-equiv="Content-Security-Policy" content=" + default-src 'none'; + child-src 'self' data: blob:; +- script-src 'self' 'unsafe-eval' 'sha256-fh3TwPMflhsEIpR8g1OYTIMVWhXTLcjQ9kh2tIpmv54=' https:; ++ script-src 'self' 'unsafe-eval' 'sha256-yHVIAbzODFRINjoLGID5qWPP45HzMtwhyVRC+7yiuXg=' https:; + connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*;"/> + </head> + <body> +@@ -23,6 +23,13 @@ + // validation not requested + return start(); + } ++ + // It is safe to run if we are on the same host. + const parent = new URL(parentOrigin) -+ if (parent.hostname === location.hostname) { -+ return start(parentOrigin) ++ if (parent.hostname === hostname) { ++ return start() + } + if (!crypto.subtle) { // cannot validate, not running in a secure context - throw new Error(`Cannot validate in current context!`); + return sendError(new Error(`Cannot validate in current context!`)); diff --git a/src/node/routes/vscode.ts b/src/node/routes/vscode.ts index 8b85b68a5c8e..a0ba3869b367 100644 --- a/src/node/routes/vscode.ts +++ b/src/node/routes/vscode.ts @@ -172,7 +172,7 @@ export class CodeServerRouteWrapper { this.router.get("/", this.ensureCodeServerLoaded, this.$root) this.router.get(/manifest.json$/, this.manifest) this.router.all("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyRequest) - this._wsRouterWrapper.ws("/", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyWebsocket) + this._wsRouterWrapper.ws("*", ensureAuthenticated, this.ensureCodeServerLoaded, this.$proxyWebsocket) } dispose() { diff --git a/test/unit/node/routes/vscode.test.ts b/test/unit/node/routes/vscode.test.ts index 88b2c4b2d852..9f453369322a 100644 --- a/test/unit/node/routes/vscode.test.ts +++ b/test/unit/node/routes/vscode.test.ts @@ -33,10 +33,10 @@ describe("vscode", () => { switch (route) { case "/": case "/vscode/": - expect(html).toContain(`src="./static/`) + expect(html).toMatch(/src="\.\/[a-z]+-[0-9a-z]+\/static\//) break case "/vscode": - expect(html).toContain(`src="./vscode/static/`) + expect(html).toMatch(/src="\.\/vscode\/[a-z]+-[0-9a-z]+\/static\//) break } }