Skip to content

Commit

Permalink
Rebase against the upstream 4390ebc
Browse files Browse the repository at this point in the history
vscode-upstream-sha1: 4390ebc
  • Loading branch information
Eclipse Che Sync committed Jul 18, 2023
2 parents bd6c15f + 4390ebc commit 019f910
Show file tree
Hide file tree
Showing 16 changed files with 1,966 additions and 1,857 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ module.exports = withBrowserDefaults({
'uuid': path.resolve(__dirname, 'node_modules/uuid/dist/esm-browser/index.js'),
'./node/authServer': path.resolve(__dirname, 'src/browser/authServer'),
'./node/crypto': path.resolve(__dirname, 'src/browser/crypto'),
'./node/fetch': path.resolve(__dirname, 'src/browser/fetch')
'./node/fetch': path.resolve(__dirname, 'src/browser/fetch'),
'./node/buffer': path.resolve(__dirname, 'src/browser/buffer'),
}
}
});
8 changes: 8 additions & 0 deletions code/extensions/github-authentication/src/browser/buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export function base64Encode(text: string): string {
return btoa(text);
}
3 changes: 3 additions & 0 deletions code/extensions/github-authentication/src/common/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,7 @@ export class Log {
this.output.error(message);
}

public warn(message: string): void {
this.output.warn(message);
}
}
3 changes: 2 additions & 1 deletion code/extensions/github-authentication/src/flows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ const allFlows: IFlow[] = [
supportsGitHubEnterpriseServer: false,
supportsHostedGitHubEnterprise: true,
supportsRemoteExtensionHost: true,
supportsWebWorkerExtensionHost: true,
// Web worker can't open a port to listen for the redirect
supportsWebWorkerExtensionHost: false,
// exchanging a code for a token requires a client secret
supportsNoClientSecret: false,
supportsSupportedClients: true,
Expand Down
1 change: 1 addition & 0 deletions code/extensions/github-authentication/src/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
sessions.splice(sessionIndex, 1);

await this.storeSessions(sessions);
await this._githubServer.logout(session);

this._sessionChangeEmitter.fire({ added: [], removed: [session], changed: [] });
} else {
Expand Down
62 changes: 61 additions & 1 deletion code/extensions/github-authentication/src/githubServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import { crypto } from './node/crypto';
import { fetching } from './node/fetch';
import { ExtensionHost, GitHubTarget, getFlows } from './flows';
import { NETWORK_ERROR, USER_CANCELLATION_ERROR } from './common/errors';
import { Config } from './config';
import { base64Encode } from './node/buffer';

// This is the error message that we throw if the login was cancelled for any reason. Extensions
// calling `getSession` can handle this error to know that the user cancelled the login.
Expand All @@ -22,6 +24,7 @@ const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect';

export interface IGitHubServer {
login(scopes: string): Promise<string>;
logout(session: vscode.AuthenticationSession): Promise<void>;
getUserInfo(token: string): Promise<{ id: string; accountName: string }>;
sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise<void>;
friendlyName: string;
Expand Down Expand Up @@ -78,9 +81,14 @@ export class GitHubServer implements IGitHubServer {
}

// TODO@joaomoreno TODO@TylerLeonhardt
private _isNoCorsEnvironment: boolean | undefined;
private async isNoCorsEnvironment(): Promise<boolean> {
if (this._isNoCorsEnvironment !== undefined) {
return this._isNoCorsEnvironment;
}
const uri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/dummy`));
return (uri.scheme === 'https' && /^((insiders\.)?vscode|github)\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority));
this._isNoCorsEnvironment = (uri.scheme === 'https' && /^((insiders\.)?vscode|github)\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority));
return this._isNoCorsEnvironment;
}

public async login(scopes: string): Promise<string> {
Expand Down Expand Up @@ -144,6 +152,58 @@ export class GitHubServer implements IGitHubServer {
throw new Error(userCancelled ? CANCELLATION_ERROR : 'No auth flow succeeded.');
}

public async logout(session: vscode.AuthenticationSession): Promise<void> {
this._logger.trace(`Deleting session (${session.id}) from server...`);

if (!Config.gitHubClientSecret) {
this._logger.warn('No client secret configured for GitHub authentication. The token has been deleted with best effort on this system, but we are unable to delete the token on server without the client secret.');
return;
}

// Only attempt to delete OAuth tokens. They are always prefixed with `gho_`.
// https://docs.github.com/en/rest/apps/oauth-applications#about-oauth-apps-and-oauth-authorizations-of-github-apps
if (!session.accessToken.startsWith('gho_')) {
this._logger.warn('The token being deleted is not an OAuth token. It has been deleted locally, but we cannot delete it on server.');
return;
}

if (!isSupportedTarget(this._type, this._ghesUri)) {
this._logger.trace('GitHub.com and GitHub hosted GitHub Enterprise are the only options that support deleting tokens on the server. Skipping.');
return;
}

const authHeader = 'Basic ' + base64Encode(`${Config.gitHubClientId}:${Config.gitHubClientSecret}`);
const uri = this.getServerUri(`/applications/${Config.gitHubClientId}/token`);

try {
// Defined here: https://docs.github.com/en/rest/apps/oauth-applications?apiVersion=2022-11-28#delete-an-app-token
const result = await fetching(uri.toString(true), {
method: 'DELETE',
headers: {
Accept: 'application/vnd.github+json',
Authorization: authHeader,
'X-GitHub-Api-Version': '2022-11-28',
'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})`
},
body: JSON.stringify({ access_token: session.accessToken }),
});

if (result.status === 204) {
this._logger.trace(`Successfully deleted token from session (${session.id}) from server.`);
return;
}

try {
const body = await result.text();
throw new Error(body);
} catch (e) {
throw new Error(`${result.status} ${result.statusText}`);
}
} catch (e) {
this._logger.warn('Failed to delete token from server.' + e.message ?? e);
}
}

private getServerUri(path: string = '') {
const apiUri = this.baseUri;
// github.com and Hosted GitHub Enterprise instances
Expand Down
8 changes: 8 additions & 0 deletions code/extensions/github-authentication/src/node/buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

export function base64Encode(text: string): string {
return Buffer.from(text, 'binary').toString('base64');
}
2 changes: 1 addition & 1 deletion code/src/vs/base/worker/workerMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
try {
const func = (
trustedTypesPolicy
? globalThis.eval(<any>trustedTypesPolicy.createScript('', 'true'))
? globalThis.eval(<any>trustedTypesPolicy.createScript('', 'true')) // CodeQL [SM01632] fetch + eval is used on the web worker instead of importScripts if possible because importScripts is synchronous and we observed deadlocks on Safari
: new Function('true') // CodeQL [SM01632] fetch + eval is used on the web worker instead of importScripts if possible because importScripts is synchronous and we observed deadlocks on Safari
);
func.call(globalThis);
Expand Down
2 changes: 1 addition & 1 deletion code/src/vs/editor/common/languages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1179,7 +1179,7 @@ export const symbolKindNames: { [symbol: number]: string } = {
* @internal
*/
export function getAriaLabelForSymbol(symbolName: string, kind: SymbolKind): string {
return localize('symbolAriaLabel', '{0} Symbol: {1}', symbolName, symbolKindNames[kind]);
return localize('symbolAriaLabel', '{0} ({1})', symbolName, symbolKindNames[kind]);
}

export const enum SymbolTag {
Expand Down
Loading

0 comments on commit 019f910

Please sign in to comment.