Add a logout command and menu item This will only show if you have authentication enabled. This has e2e tests but are currently disabled and need to be fixed. Index: code-server/lib/vscode/src/vs/base/common/product.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/base/common/product.ts +++ code-server/lib/vscode/src/vs/base/common/product.ts @@ -58,6 +58,7 @@ export interface IProductConfiguration { readonly codeServerVersion?: string readonly rootEndpoint?: string readonly updateEndpoint?: string + readonly logoutEndpoint?: string readonly version: string; readonly date?: string; 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 @@ import { URI } from '../../base/common/u export const serverOptions: OptionDescriptions> = { /* ----- code-server ----- */ 'disable-update-check': { type: 'boolean' }, + 'auth': { type: 'string' }, /* ----- server setup ----- */ @@ -97,6 +98,7 @@ export const serverOptions: OptionDescri export interface ServerParsedArgs { /* ----- code-server ----- */ 'disable-update-check'?: boolean; + 'auth'?: string; /* ----- server setup ----- */ 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 @@ -313,6 +313,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'] && this._environmentService.args['auth'] !== "none" ? base + '/logout' : undefined, embedderIdentifier: 'server-distro', extensionsGallery: this._productService.extensionsGallery, } satisfies Partial; Index: code-server/lib/vscode/src/vs/workbench/browser/client.ts =================================================================== --- code-server.orig/lib/vscode/src/vs/workbench/browser/client.ts +++ code-server/lib/vscode/src/vs/workbench/browser/client.ts @@ -1,11 +1,15 @@ import { Disposable } from "../../base/common/lifecycle.js"; import { localize } from '../../nls.js'; +import { MenuId, MenuRegistry } from '../../platform/actions/common/actions.js'; +import { CommandsRegistry } from '../../platform/commands/common/commands.js'; import { ILogService } from '../../platform/log/common/log.js'; import { INotificationService, Severity } from '../../platform/notification/common/notification.js'; import { IProductService } from '../../platform/product/common/productService.js'; import { IStorageService, StorageScope, StorageTarget } from '../../platform/storage/common/storage.js'; export class CodeServerClient extends Disposable { + static LOGOUT_COMMAND_ID = 'code-server.logout'; + constructor ( @ILogService private logService: ILogService, @INotificationService private notificationService: INotificationService, @@ -81,6 +85,10 @@ export class CodeServerClient extends Di if (this.productService.updateEndpoint) { this.checkUpdates(this.productService.updateEndpoint) } + + if (this.productService.logoutEndpoint) { + this.addLogoutCommand(this.productService.logoutEndpoint); + } } private checkUpdates(updateEndpoint: string) { @@ -132,4 +140,25 @@ export class CodeServerClient extends Di updateLoop(); } + + private addLogoutCommand(logoutEndpoint: string) { + CommandsRegistry.registerCommand(CodeServerClient.LOGOUT_COMMAND_ID, () => { + const logoutUrl = new URL(logoutEndpoint, window.location.href); + // Cookies must be set with absolute paths and must use the same path to + // be unset (we set it on the root) so send the relative root and the + // current href so the backend can derive the absolute path to the root. + logoutUrl.searchParams.set('base', this.productService.rootEndpoint || "."); + logoutUrl.searchParams.set('href', window.location.href); + window.location.assign(logoutUrl); + }); + + for (const menuId of [MenuId.CommandPalette, MenuId.MenubarHomeMenu]) { + MenuRegistry.appendMenuItem(menuId, { + command: { + id: CodeServerClient.LOGOUT_COMMAND_ID, + title: localize('logout', "Sign out of {0}", 'code-server'), + }, + }); + } + } }