src/vs/server/node/serverConnectionToken.ts

132 LOC · 84 covered · 48 uncovered · 24 ranges · 13 concepts · 13 introducers · 7 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the fileserverConnectionToken.ts ×3 · 10 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×2 · 4 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 2 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 3 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 2 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 2 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×2 · 3 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 1 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 1 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 2 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 2 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×1 · 1 introduced LOCserverConnectionToken.ts…serverConnectionToken.ts ×8 · 51 introduced LOCserverConnectionToken.ts…serverConnectionToken.test|title=parseServerConnectionToken --connection-token-file --connection-token results in error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken --connection-token-file --connection-token results in error|occurrence=1serverConnectionToken.te…serverConnectionToken.test|title=parseServerConnectionToken --connection-token-file|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken --connection-token-file|occurrence=1serverConnectionToken.te…serverConnectionToken.test|title=parseServerConnectionToken --connection-token|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken --connection-token|occurrence=1serverConnectionToken.te…serverConnectionToken.test|title=parseServerConnectionToken --without-connection-token --connection-token results in error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken --without-connection-token --connection-token results in error|occurrence=1serverConnectionToken.te…serverConnectionToken.test|title=parseServerConnectionToken --without-connection-token --connection-token-file results in error|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken --without-connection-token --connection-token-file results in error|occurrence=1serverConnectionToken.te…serverConnectionToken.test|title=parseServerConnectionToken --without-connection-token|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken --without-connection-token|occurrence=1serverConnectionToken.te…serverConnectionToken.test|title=parseServerConnectionToken no arguments generates a token that is mandatory|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/server/test/node/serverConnectionToken.test|title=parseServerConnectionToken no arguments generates a token that is mandatory|occurrence=1serverConnectionToken.te…Focused file · src/vs/server/node/serverConnectionToken.ts · 132 LOCnode/serverConnectionTok…

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- serverConnectionToken.ts ×8
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as cookie from 'cookie';
7 > import * as fs from 'fs';
8 > import type * as http from 'http';
9 > import * as url from 'url';
10 > import * as path from '../../base/common/path.js';
11 > import { generateUuid } from '../../base/common/uuid.js';
12 > import { connectionTokenCookieName, connectionTokenQueryName } from '../../base/common/network.js';
13 > import { ServerParsedArgs } from './serverEnvironmentService.js';
14 > import { Promises } from '../../base/node/pfs.js';
15 >
16 > const connectionTokenRegex = /^[0-9A-Za-z_-]+$/;
17 >
18 > export const enum ServerConnectionTokenType {
19 > None,
20 > Optional,// TODO: Remove this soon
21 > Mandatory
22 > }
23 >
24 > export class NoneServerConnectionToken {
25 > public readonly type = ServerConnectionTokenType.None; serverConnectionToken.ts ×2
27 > public validate(connectionToken: unknown): boolean {
28 return true;
29 }
31 >
32 > export class MandatoryServerConnectionToken {
33 > public readonly type = ServerConnectionTokenType.Mandatory;
34 >
35 > constructor(public readonly value: string) {
38 > public validate(connectionToken: unknown): boolean {
39 return (connectionToken === this.value);
40 }
42 >
43 > export type ServerConnectionToken = NoneServerConnectionToken | MandatoryServerConnectionToken;
44 >
45 > export class ServerConnectionTokenParseError {
46 > constructor(
47 > public readonly message: string serverConnectionToken.ts ×1
48 > ) { }
50 >
51 > export async function parseServerConnectionToken(args: ServerParsedArgs, defaultValue: () => Promise<string>): Promise<ServerConnectionToken | ServerConnectionTokenParseError> {
52 > const withoutConnectionToken = args['without-connection-token'];
53 > const connectionToken = args['connection-token'];
54 > const connectionTokenFile = args['connection-token-file'];
55 >
56 > if (withoutConnectionToken) {
57 > if (typeof connectionToken !== 'undefined' || typeof connectionTokenFile !== 'undefined') { serverConnectionToken.ts ×1
58 > return new ServerConnectionTokenParseError(`Please do not use the argument '--connection-token' or '--connection-token-file' at the same time as '--without-connection-token'.`); serverConnectionToken.ts ×1
59 > }
60 > return new NoneServerConnectionToken(); serverConnectionToken.ts ×2
61 > }
63 > if (typeof connectionTokenFile !== 'undefined') {
64 > if (typeof connectionToken !== 'undefined') { serverConnectionToken.ts ×1
65 > return new ServerConnectionTokenParseError(`Please do not use the argument '--connection-token' at the same time as '--connection-token-file'.`); serverConnectionToken.ts ×1
66 > }
68 > let rawConnectionToken: string;
69 > try {
70 > rawConnectionToken = fs.readFileSync(connectionTokenFile).toString().replace(/\r?\n$/, '');
71 > } catch (e) {
72 return new ServerConnectionTokenParseError(`Unable to read the connection token file at '${connectionTokenFile}'.`);
73 }
75 > if (!connectionTokenRegex.test(rawConnectionToken)) {
76 return new ServerConnectionTokenParseError(`The connection token defined in '${connectionTokenFile} does not adhere to the characters 0-9, a-z, A-Z, _, or -.`);
77 }
79 > return new MandatoryServerConnectionToken(rawConnectionToken);
80 > }
82 > if (typeof connectionToken !== 'undefined') {
83 > if (!connectionTokenRegex.test(connectionToken)) { serverConnectionToken.ts ×2
84 return new ServerConnectionTokenParseError(`The connection token '${connectionToken} does not adhere to the characters 0-9, a-z, A-Z or -.`);
85 }
87 > return new MandatoryServerConnectionToken(connectionToken);
88 > }
90 > return new MandatoryServerConnectionToken(await defaultValue());
91 > }
93 export async function determineServerConnectionToken(args: ServerParsedArgs): Promise<ServerConnectionToken | ServerConnectionTokenParseError> {
94 const readOrGenerateConnectionToken = async () => {
95 if (!args['user-data-dir']) {
96 // No place to store it!
97 return generateUuid();
98 }
99 const storageLocation = path.join(args['user-data-dir'], 'token');
100
101 // First try to find a connection token
102 try {
103 const fileContents = await fs.promises.readFile(storageLocation);
104 const connectionToken = fileContents.toString().replace(/\r?\n$/, '');
105 if (connectionTokenRegex.test(connectionToken)) {
106 return connectionToken;
107 }
108 } catch (err) { }
109
110 // No connection token found, generate one
111 const connectionToken = generateUuid();
112
113 try {
114 // Try to store it
115 await Promises.writeFile(storageLocation, connectionToken, { mode: 0o600 });
116 } catch (err) { }
117
118 return connectionToken;
119 };
120 return parseServerConnectionToken(args, readOrGenerateConnectionToken);
121 }
123 > export function requestHasValidConnectionToken(connectionToken: ServerConnectionToken, req: http.IncomingMessage, parsedUrl: url.UrlWithParsedQuery) {
124 // First check if there is a valid query parameter
125 if (connectionToken.validate(parsedUrl.query[connectionTokenQueryName])) {
126 return true;
127 }
128
129 // Otherwise, check if there is a valid cookie
130 const cookies = cookie.parse(req.headers.cookie || '');
131 return connectionToken.validate(cookies[connectionTokenCookieName]);
132 }