diff --git a/patches/proxy-uri.diff b/patches/proxy-uri.diff index c5ed301b2..4065d4874 100644 --- a/patches/proxy-uri.diff +++ b/patches/proxy-uri.diff @@ -10,6 +10,15 @@ extensions, use --extensions-dir, or symlink it). This has e2e tests. +For the `asExternalUri` changes, you'll need to test manually by: +1. running code-server with the test extension +2. Command Palette > code-server: asExternalUri test +3. input a url like http://localhost:3000 +4. it should show a notification and show output as /proxy/3000 + +Do the same thing but set `VSCODE_PROXY_URI: "https://{{port}}-main-workspace-name-user-name.coder.com"` +and the output should replace `{{port}}` with port used in input url. + Index: code-server/lib/vscode/src/vs/base/common/product.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/product.ts @@ -68,7 +77,7 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts rootEndpoint: base, updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, -+ proxyEndpointTemplate: base + '/proxy/{{port}}', ++ proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}', embedderIdentifier: 'server-distro', extensionsGallery: this._productService.extensionsGallery, }, @@ -98,3 +107,38 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/terminal/common/terminalE // Merge config (settings) and ShellLaunchConfig environments mergeEnvironments(env, allowedEnvFromConfig); +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 +@@ -17,6 +17,7 @@ import { isFolderToOpen, isWorkspaceToOp + import { create, ICredentialsProvider, IURLCallbackProvider, IWorkbenchConstructionOptions, IWorkspace, IWorkspaceProvider } from 'vs/workbench/workbench.web.main'; + import { posix } from 'vs/base/common/path'; + import { ltrim } from 'vs/base/common/strings'; ++import { extractLocalHostUriMetaDataForPortMapping } from 'vs/platform/tunnel/common/tunnel'; + + interface ICredential { + service: string; +@@ -507,6 +508,21 @@ function doCreateUri(path: string, query + } : undefined, + workspaceProvider: WorkspaceProvider.create(config), + urlCallbackProvider: new LocalStorageURLCallbackProvider(config.callbackRoute), +- credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider() // with a remote, we don't use a local credentials provider ++ credentialsProvider: config.remoteAuthority ? undefined : new LocalStorageCredentialsProvider(), // with a remote, we don't use a local credentials provider ++ resolveExternalUri: (uri: URI): Promise => { ++ let resolvedUri = uri ++ const localhostMatch = extractLocalHostUriMetaDataForPortMapping(uri) ++ ++ if (localhostMatch) { ++ if (config.productConfiguration && config.productConfiguration.proxyEndpointTemplate) { ++ resolvedUri = URI.parse(new URL(config.productConfiguration.proxyEndpointTemplate.replace('{{port}}', localhostMatch.port.toString()), window.location.href).toString()) ++ } else { ++ throw new Error(`Failed to resolve external URI: ${uri.toString()}. Could not determine base url because productConfiguration missing.`) ++ } ++ } ++ ++ // If not localhost, return unmodified ++ return Promise.resolve(resolvedUri) ++ } + }); + })(); diff --git a/patches/service-worker.diff b/patches/service-worker.diff index 967e51b7d..ce902f64c 100644 --- a/patches/service-worker.diff +++ b/patches/service-worker.diff @@ -17,21 +17,6 @@ Index: code-server/lib/vscode/src/vs/base/common/product.ts 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 -@@ -319,6 +319,10 @@ export class WebClientServer { - updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, - logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? 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 @@ -65,3 +50,18 @@ Index: code-server/lib/vscode/src/vs/workbench/browser/client.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 +@@ -319,6 +319,10 @@ export class WebClientServer { + updateEndpoint: !this._environmentService.args['disable-update-check'] ? base + '/update/check' : undefined, + logoutEndpoint: this._environmentService.args['auth'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, + proxyEndpointTemplate: process.env.VSCODE_PROXY_URI ?? base + '/proxy/{{port}}', ++ serviceWorker: { ++ scope: vscodeBase + '/', ++ path: base + '/_static/out/browser/serviceWorker.js', ++ }, + embedderIdentifier: 'server-distro', + extensionsGallery: this._productService.extensionsGallery, + }, diff --git a/test/e2e/extensions/ms-ceintl.vscode-language-pack-es-1.70.0/package.json b/test/e2e/extensions/ms-ceintl.vscode-language-pack-es-1.70.0/package.json index 4f4aff17b..2b6992441 100644 --- a/test/e2e/extensions/ms-ceintl.vscode-language-pack-es-1.70.0/package.json +++ b/test/e2e/extensions/ms-ceintl.vscode-language-pack-es-1.70.0/package.json @@ -28,5 +28,11 @@ ] } ] + }, + "__metadata": { + "id": "47e020a1-33db-4cc0-a1b4-42f97781749a", + "publisherDisplayName": "MS-CEINTL", + "publisherId": "0b0882c3-aee3-4d7c-b5f9-872f9be0a115", + "isPreReleaseVersion": false } } diff --git a/test/e2e/extensions/test-extension/extension.ts b/test/e2e/extensions/test-extension/extension.ts index ea962efbd..ea4a1f896 100644 --- a/test/e2e/extensions/test-extension/extension.ts +++ b/test/e2e/extensions/test-extension/extension.ts @@ -2,6 +2,7 @@ import * as vscode from "vscode" export function activate(context: vscode.ExtensionContext) { vscode.window.showInformationMessage("test extension loaded") + // Test extension context.subscriptions.push( vscode.commands.registerCommand("codeServerTest.proxyUri", () => { if (process.env.VSCODE_PROXY_URI) { @@ -11,4 +12,20 @@ export function activate(context: vscode.ExtensionContext) { } }), ) + + // asExternalUri extension + context.subscriptions.push( + vscode.commands.registerCommand("codeServerTest.asExternalUri", async () => { + const input = await vscode.window.showInputBox({ + prompt: "URL to pass through to asExternalUri", + }) + + if (input) { + const output = await vscode.env.asExternalUri(vscode.Uri.parse(input)) + vscode.window.showInformationMessage(`input: ${input} output: ${output}`) + } else { + vscode.window.showErrorMessage(`Failed to run test case. No input provided.`) + } + }), + ) } diff --git a/test/e2e/extensions/test-extension/package.json b/test/e2e/extensions/test-extension/package.json index 8aca8815a..77482689f 100644 --- a/test/e2e/extensions/test-extension/package.json +++ b/test/e2e/extensions/test-extension/package.json @@ -17,6 +17,11 @@ "command": "codeServerTest.proxyUri", "title": "Get proxy URI", "category": "code-server" + }, + { + "command": "codeServerTest.asExternalUri", + "title": "asExternalUri test", + "category": "code-server" } ] }, diff --git a/test/playwright.config.ts b/test/playwright.config.ts index bcaa86540..c555f0960 100644 --- a/test/playwright.config.ts +++ b/test/playwright.config.ts @@ -8,6 +8,7 @@ import path from "path" // yarn test:e2e --workers 1 # Run with one worker // yarn test:e2e --project Chromium # Only run on Chromium // yarn test:e2e --grep login # Run tests matching "login" +// PWDEBUG=1 yarn test:e2e # Run Playwright inspector const config: PlaywrightTestConfig = { testDir: path.join(__dirname, "e2e"), // Search for tests in this directory. timeout: 60000, // Each test is given 60 seconds.