Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 6.8k
Refactor logout#3277
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Refactor logout #3277
Changes from all commits
e7a5275bea13ddeee637a08ab0af49c26f7a48ac5010babb48b2c78cFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -19,3 +19,4 @@ | ||
| # These are code-server code symlinks. | ||
| src/vs/base/node/proxy_agent.ts | ||
| src/vs/ipc.d.ts | ||
| src/vs/server/common/util.ts | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,10 @@ | ||
| import * as path from 'vs/base/common/path'; | ||
| import { URI } from 'vs/base/common/uri'; | ||
| import { Options } from 'vs/ipc'; | ||
| import { localize } from 'vs/nls'; | ||
| import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions'; | ||
| import { CommandsRegistry } from 'vs/platform/commands/common/commands'; | ||
| import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry'; | ||
| import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; | ||
| import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; | ||
| import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; | ||
| import { ILogService } from 'vs/platform/log/common/log'; | ||
| @@ -11,10 +13,18 @@ import { Registry } from 'vs/platform/registry/common/platform'; | ||
| import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage'; | ||
| import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; | ||
| import { TelemetryChannelClient } from 'vs/server/common/telemetry'; | ||
| import { getOptions } from 'vs/server/common/util'; | ||
| import 'vs/workbench/contrib/localizations/browser/localizations.contribution'; | ||
| import 'vs/workbench/services/localizations/browser/localizationsService'; | ||
| import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService'; | ||
| /** | ||
| * All client-side customization to VS Code should live in this file when | ||
| * possible. | ||
| */ | ||
| const options = getOptions<Options>(); | ||
| class TelemetryService extends TelemetryChannelClient { | ||
| public constructor( | ||
| @IRemoteAgentService remoteAgentService: IRemoteAgentService, | ||
| @@ -23,26 +33,6 @@ class TelemetryService extends TelemetryChannelClient { | ||
| } | ||
| } | ||
| /** | ||
| * Remove extra slashes in a URL. | ||
| */ | ||
| export const normalize = (url: string, keepTrailing = false): string => { | ||
| return url.replace(/\/\/+/g, '/').replace(/\/+$/, keepTrailing ? '/' : ''); | ||
| }; | ||
| /** | ||
| * Get options embedded in the HTML. | ||
| */ | ||
| export const getOptions = <T extends Options>(): T => { | ||
| try { | ||
| return JSON.parse(document.getElementById('coder-options')!.getAttribute('data-settings')!); | ||
| } catch (error) { | ||
| return {} as T; | ||
| } | ||
| }; | ||
| const options = getOptions(); | ||
| const TELEMETRY_SECTION_ID = 'telemetry'; | ||
| Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({ | ||
| 'id': TELEMETRY_SECTION_ID, | ||
| @@ -173,38 +163,36 @@ export const initialize = async (services: ServiceCollection): Promise<void> => | ||
| if (theme) { | ||
| localStorage.setItem('colorThemeData', theme); | ||
| } | ||
| }; | ||
| export interface Query { | ||
| [key: string]: string | undefined; | ||
| } | ||
| /** | ||
| * Split a string up to the delimiter. If the delimiter doesn't exist the first | ||
| * item will have all the text and the second item will be an empty string. | ||
| */ | ||
| export const split = (str: string, delimiter: string): [string, string] => { | ||
| const index = str.indexOf(delimiter); | ||
| return index !== -1 ? [str.substring(0, index).trim(), str.substring(index + 1)] : [str, '']; | ||
| }; | ||
| // Use to show or hide logout commands and menu options. | ||
| const contextKeyService = (services.get(IContextKeyService) as IContextKeyService); | ||
| contextKeyService.createKey('code-server.authed', options.authed); | ||
| // Add a logout command. | ||
| const logoutEndpoint = path.join(options.base, '/logout') + `?base=${options.base}`; | ||
| const LOGOUT_COMMAND_ID = 'code-server.logout'; | ||
| CommandsRegistry.registerCommand( | ||
| LOGOUT_COMMAND_ID, | ||
| () => { | ||
| window.location.href = logoutEndpoint; | ||
code-asher marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| }, | ||
| ); | ||
| // Add logout to command palette. | ||
| MenuRegistry.appendMenuItem(MenuId.CommandPalette, { | ||
| command: { | ||
| id: LOGOUT_COMMAND_ID, | ||
| title: localize('logout', "Log out") | ||
| }, | ||
| when: ContextKeyExpr.has('code-server.authed') | ||
| }); | ||
| /** | ||
| * Return the URL modified with the specified query variables. It's pretty | ||
| * stupid so it probably doesn't cover any edge cases. Undefined values will | ||
| * unset existing values. Doesn't allow duplicates. | ||
| */ | ||
| export const withQuery = (url: string, replace: Query): string => { | ||
| const uri = URI.parse(url); | ||
| const query = { ...replace }; | ||
| uri.query.split('&').forEach((kv) => { | ||
| const [key, value] = split(kv, '='); | ||
| if (!(key in query)) { | ||
| query[key] = value; | ||
| } | ||
| // Add logout to the (web-only) home menu. | ||
code-asher marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| MenuRegistry.appendMenuItem(MenuId.MenubarHomeMenu, { | ||
| command: { | ||
| id: LOGOUT_COMMAND_ID, | ||
| title: localize('logout', "Log out") | ||
| }, | ||
| when: ContextKeyExpr.has('code-server.authed') | ||
| }); | ||
| return uri.with({ | ||
| query: Object.keys(query) | ||
| .filter((k) => typeof query[k] !== 'undefined') | ||
| .map((k) => `${k}=${query[k]}`).join('&'), | ||
| }).toString(true); | ||
| }; | ||
This file was deleted.
Uh oh!
There was an error while loading. Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| ../../../../../../src/common/util.ts |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import { logger } from "@coder/logger" | ||
| import { getOptions, normalize, logError } from "../common/util" | ||
| import "./pages/error.css" | ||
| @@ -6,19 +7,21 @@ import "./pages/login.css" | ||
| export async function registerServiceWorker(): Promise<void> { | ||
| const options = getOptions() | ||
| logger.level = options.logLevel | ||
| const path = normalize(`${options.csStaticBase}/dist/serviceWorker.js`) | ||
| try { | ||
| await navigator.serviceWorker.register(path, { | ||
| scope: options.base + "/", | ||
| }) | ||
| console.log("[Service Worker] registered") | ||
| logger.info(`[Service Worker] registered`) | ||
| } catch (error) { | ||
| logError(`[Service Worker] registration`, error) | ||
| logError(logger, `[Service Worker] registration`, error) | ||
code-asher marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| } | ||
| if (typeof navigator !== "undefined" && "serviceWorker" in navigator) { | ||
| registerServiceWorker() | ||
| } else { | ||
| console.error(`[Service Worker] navigator is undefined`) | ||
| logger.error(`[Service Worker] navigator is undefined`) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| import { Router } from "express" | ||
| import { getCookieDomain, redirect } from "../http" | ||
| import { Cookie } from "./login" | ||
| export const router = Router() | ||
| router.get("/", async (req, res) => { | ||
| // Must use the *identical* properties used to set the cookie. | ||
| res.clearCookie(Cookie.Key, { | ||
| domain: getCookieDomain(req.headers.host || "", req.args["proxy-domain"]), | ||
| path: req.body.base || "/", | ||
| sameSite: "lax", | ||
| }) | ||
| const to = (typeof req.query.to === "string" && req.query.to) || "/" | ||
| return redirect(req, res, to, { to: undefined, base: undefined }) | ||
| }) |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.