diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml
index 34cff1e..99ce44c 100644
--- a/.github/workflows/linux.yml
+++ b/.github/workflows/linux.yml
@@ -27,9 +27,9 @@ jobs:
- vscode_arch: arm64
npm_arch: arm64
image: vscodium/vscodium-linux-build-agent:stretch-arm64
- - vscode_arch: armhf
- npm_arch: armv7l
- image: vscodium/vscodium-linux-build-agent:stretch-armhf
+ # - vscode_arch: armhf
+ # npm_arch: armv7l
+ # image: vscodium/vscodium-linux-build-agent:stretch-armhf
steps:
- uses: actions/checkout@v3
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 85d780a..53c7348 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -20,7 +20,10 @@ jobs:
strategy:
fail-fast: false
matrix:
- vscode_arch: [x64, ia32, arm64]
+ vscode_arch:
+ - x64
+ # - ia32
+ - arm64
steps:
- uses: actions/checkout@v3
@@ -33,10 +36,10 @@ jobs:
- name: Install Yarn
run: npm install -g yarn
- - name: Setup Python 2
+ - name: Setup Python 3
uses: actions/setup-python@v3
with:
- python-version: '2.x'
+ python-version: '3.x'
- name: Clone VSCode repo
run: ./get_repo.sh
diff --git a/build.sh b/build.sh
index 55daec6..a486ba9 100755
--- a/build.sh
+++ b/build.sh
@@ -4,6 +4,7 @@ set -ex
if [[ "${SHOULD_BUILD}" == "yes" ]]; then
npm config set scripts-prepend-node-path true
+ npm config set node_gyp
echo "MS_COMMIT: ${MS_COMMIT}"
diff --git a/docs/build.md b/docs/build.md
index e9b1258..f3dbdfa 100644
--- a/docs/build.md
+++ b/docs/build.md
@@ -40,7 +40,7 @@
- sed
- 7z
- [WiX Toolset](http://wixtoolset.org/releases/)
-- python2
+- python3
- 'Tools for Native Modules' from official Node.js installer
## Build Scripts
diff --git a/patches/fix-build-rpm.patch b/patches/fix-build-rpm.patch
new file mode 100644
index 0000000..4cdc753
--- /dev/null
+++ b/patches/fix-build-rpm.patch
@@ -0,0 +1,36 @@
+diff --git a/build/linux/rpm/dependencies-generator.js b/build/linux/rpm/dependencies-generator.js
+index 1d91eb8..ed6b775 100644
+--- a/build/linux/rpm/dependencies-generator.js
++++ b/build/linux/rpm/dependencies-generator.js
+@@ -16,7 +16,7 @@ const dep_lists_1 = require("./dep-lists");
+ // If true, we fail the build if there are new dependencies found during that task.
+ // The reference dependencies, which one has to update when the new dependencies
+ // are valid, are in dep-lists.ts
+-const FAIL_BUILD_FOR_NEW_DEPENDENCIES = true;
++const FAIL_BUILD_FOR_NEW_DEPENDENCIES = false;
+ function getDependencies(buildDir, applicationName, arch) {
+ // Get the files for which we want to find dependencies.
+ const nativeModulesPath = path.join(buildDir, 'resources', 'app', 'node_modules.asar.unpacked');
+diff --git a/build/linux/rpm/dependencies-generator.ts b/build/linux/rpm/dependencies-generator.ts
+index 95953ec..f5ffc2e 100644
+--- a/build/linux/rpm/dependencies-generator.ts
++++ b/build/linux/rpm/dependencies-generator.ts
+@@ -18,7 +18,7 @@ import { ArchString } from './types';
+ // If true, we fail the build if there are new dependencies found during that task.
+ // The reference dependencies, which one has to update when the new dependencies
+ // are valid, are in dep-lists.ts
+-const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = true;
++const FAIL_BUILD_FOR_NEW_DEPENDENCIES: boolean = false;
+
+ export function getDependencies(buildDir: string, applicationName: string, arch: ArchString): string[] {
+ // Get the files for which we want to find dependencies.
+diff --git a/resources/linux/rpm/code.spec.template b/resources/linux/rpm/code.spec.template
+index 5b7eadb..87c914d 100644
+--- a/resources/linux/rpm/code.spec.template
++++ b/resources/linux/rpm/code.spec.template
+@@ -74,3 +74,5 @@ update-mime-database /usr/share/mime &> /dev/null || :
+ /usr/share/pixmaps/@@ICON@@.png
+ /usr/share/bash-completion/completions/@@NAME@@
+ /usr/share/zsh/site-functions/_@@NAME@@
++
++%config(noreplace) /usr/share/@@NAME@@/resources/app/product.json
diff --git a/patches/fix-builtin-extensions.patch b/patches/fix-builtin-extensions.patch
deleted file mode 100644
index c163609..0000000
--- a/patches/fix-builtin-extensions.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
-index 2b0a0fa..499cff4 100644
---- a/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
-+++ b/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.ts
-@@ -206,6 +206,10 @@ export class Extension implements IExtension {
- if (!this.gallery || !this.local) {
- return false;
- }
-+ // Do not allow updating system extensions
-+ if (this.type === ExtensionType.System) {
-+ return false;
-+ }
- if (!this.local.preRelease && this.gallery.properties.isPreReleaseVersion) {
- return false;
- }
diff --git a/patches/fix-rpm-spec.patch b/patches/fix-rpm-spec.patch
deleted file mode 100644
index 6dedacd..0000000
--- a/patches/fix-rpm-spec.patch
+++ /dev/null
@@ -1,8 +0,0 @@
---- vscode/resources/linux/rpm/code.spec.template 2021-03-02 19:26:53.000000000 +0100
-+++ vscode/resources/linux/rpm/code.spec.template.new 2021-03-02 19:28:12.000000000 +0100
-@@ -69,3 +69,5 @@
- /usr/share/pixmaps/@@ICON@@.png
- /usr/share/bash-completion/completions/@@NAME@@
- /usr/share/zsh/site-functions/_@@NAME@@
-+
-+%config(noreplace) /usr/share/@@NAME@@/resources/app/product.json
diff --git a/patches/use-github-pat.patch b/patches/use-github-pat.patch
index bccbffc..a5a68d8 100644
--- a/patches/use-github-pat.patch
+++ b/patches/use-github-pat.patch
@@ -1,9 +1,12 @@
diff --git a/extensions/github-authentication/src/githubServer.ts b/extensions/github-authentication/src/githubServer.ts
-index 49a523b..d68588e 100644
+index c366ff3..75f32da 100644
--- a/extensions/github-authentication/src/githubServer.ts
+++ b/extensions/github-authentication/src/githubServer.ts
-@@ -6,23 +6,14 @@
- import * as nls from 'vscode-nls';
+@@ -3,27 +3,13 @@
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+-import * as nls from 'vscode-nls';
import * as vscode from 'vscode';
import fetch, { Response } from 'node-fetch';
-import { v4 as uuid } from 'uuid';
@@ -12,150 +15,322 @@ index 49a523b..d68588e 100644
import { AuthProviderType } from './github';
import { Log } from './common/logger';
-import { isSupportedEnvironment } from './common/env';
-
- const localize = nls.loadMessageBundle();
- const CLIENT_ID = '01ab8ac9400c4e429b23';
+-import { LoopbackAuthServer } from './authServer';
+-import path = require('path');
+-
+-const localize = nls.loadMessageBundle();
+-const CLIENT_ID = '01ab8ac9400c4e429b23';
-const GITHUB_AUTHORIZE_URL = 'https://github.com/login/oauth/authorize';
-// TODO: change to stable when that happens
-const GITHUB_TOKEN_URL = 'https://vscode.dev/codeExchangeProxyEndpoints/github/login/oauth/access_token';
- const NETWORK_ERROR = 'network error';
+-const NETWORK_ERROR = 'network error';
-const REDIRECT_URL_STABLE = 'https://vscode.dev/redirect';
-const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect';
--
++const NETWORK_ERROR = 'network error';
+
class UriEventHandler extends vscode.EventEmitter implements vscode.UriHandler {
constructor(private readonly Logger: Log) {
- super();
-@@ -110,10 +101,7 @@ async function getUserInfo(token: string, serverUri: vscode.Uri, logger: Log): P
- export class GitHubServer implements IGitHubServer {
+@@ -43,14 +29,6 @@ export interface IGitHubServer extends vscode.Disposable {
+ friendlyName: string;
+ type: AuthProviderType;
+ }
+-
+-interface IGitHubDeviceCodeResponse {
+- device_code: string;
+- user_code: string;
+- verification_uri: string;
+- interval: number;
+-}
+-
+ async function getScopes(token: string, serverUri: vscode.Uri, logger: Log): Promise {
+ try {
+ logger.info('Getting token scopes...');
+@@ -118,23 +96,11 @@ export class GitHubServer implements IGitHubServer {
friendlyName = 'GitHub';
type = AuthProviderType.github;
-- private _onDidManuallyProvideToken = new vscode.EventEmitter();
- private _pendingNonces = new Map();
- private _codeExchangePromises = new Map; cancel: vscode.EventEmitter }>();
private _disposable: vscode.Disposable;
private _uriHandler = new UriEventHandler(this._logger);
+- private readonly getRedirectEndpoint: Thenable;
-@@ -125,87 +113,31 @@ export class GitHubServer implements IGitHubServer {
- this._disposable.dispose();
+- constructor(private readonly _supportDeviceCodeFlow: boolean, private readonly _logger: Log, private readonly _telemetryReporter: ExperimentationTelemetry) {
++ constructor(_supportDeviceCodeFlow: boolean, private readonly _logger: Log, private readonly _telemetryReporter: ExperimentationTelemetry) {
+ this._disposable = vscode.window.registerUriHandler(this._uriHandler);
+-
+- this.getRedirectEndpoint = vscode.commands.executeCommand<{ [providerId: string]: string } | undefined>('workbench.getCodeExchangeProxyEndpoints').then((proxyEndpoints) => {
+- // If we are running in insiders vscode.dev, then ensure we use the redirect route on that.
+- let redirectUri = REDIRECT_URL_STABLE;
+- if (proxyEndpoints?.github && new URL(proxyEndpoints.github).hostname === 'insiders.vscode.dev') {
+- redirectUri = REDIRECT_URL_INSIDERS;
+- }
+- return redirectUri;
+- });
}
-- // TODO@joaomoreno TODO@TylerLeonhardt
-- private async isNoCorsEnvironment(): Promise {
-- 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));
-- }
--
- public async login(scopes: string): Promise {
- this._logger.info(`Logging in for the following scopes: ${scopes}`);
+ dispose() {
+@@ -152,181 +118,17 @@ export class GitHubServer implements IGitHubServer {
+ // Used for showing a friendlier message to the user when the explicitly cancel a flow.
+ let userCancelled: boolean | undefined;
+- const yes = localize('yes', "Yes");
+- const no = localize('no', "No");
+- const promptToContinue = async () => {
+- if (userCancelled === undefined) {
+- // We haven't had a failure yet so wait to prompt
+- return;
+- }
+- const message = userCancelled
+- ? localize('userCancelledMessage', "Having trouble logging in? Would you like to try a different way?")
+- : localize('otherReasonMessage', "You have not yet finished authorizing this extension to use GitHub. Would you like to keep trying?");
+- const result = await vscode.window.showWarningMessage(message, yes, no);
+- if (result !== yes) {
+- throw new Error('Cancelled');
+- }
+- };
+-
- const nonce = uuid();
- const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/did-authenticate?nonce=${encodeURIComponent(nonce)}`));
-
-- if (!isSupportedEnvironment(callbackUri)) {
-- const token = this._supportDeviceCodeFlow
-- ? await this.doDeviceCodeFlow(scopes)
-- : await vscode.window.showInputBox({ prompt: 'GitHub Personal Access Token', ignoreFocusOut: true });
-+ const token = this._supportDeviceCodeFlow
-+ ? await this.doDeviceCodeFlow(scopes)
-+ : await vscode.window.showInputBox({ prompt: 'GitHub Personal Access Token', ignoreFocusOut: true });
-
-- if (!token) { throw new Error('No token provided'); }
-+ if (!token) { throw new Error('No token provided'); }
-
-- const tokenScopes = await getScopes(token, this.getServerUri('/'), this._logger); // Example: ['repo', 'user']
-- const scopesList = scopes.split(' '); // Example: 'read:user repo user:email'
-- if (!scopesList.every(scope => {
-- const included = tokenScopes.includes(scope);
-- if (included || !scope.includes(':')) {
-- return included;
-- }
+- const supported = isSupportedEnvironment(callbackUri);
+- if (supported) {
+- try {
+- return await this.doLoginWithoutLocalServer(scopes, nonce, callbackUri);
+- } catch (e) {
+- this._logger.error(e);
+- userCancelled = e.message ?? e === 'User Cancelled';
+- }
+- }
-
-- return scope.split(':').some(splitScopes => {
-- return tokenScopes.includes(splitScopes);
-- });
-- })) {
-- throw new Error(`The provided token does not match the requested scopes: ${scopes}`);
-+ const tokenScopes = await getScopes(token, this.getServerUri('/'), this._logger); // Example: ['repo', 'user']
-+ const scopesList = scopes.split(' '); // Example: 'read:user repo user:email'
-+ if (!scopesList.every(scope => {
-+ const included = tokenScopes.includes(scope);
-+ if (included || !scope.includes(':')) {
-+ return included;
- }
+- // Starting a local server isn't supported in web
+- if (vscode.env.uiKind === vscode.UIKind.Desktop) {
+- try {
+- await promptToContinue();
+- return await this.doLoginWithLocalServer(scopes);
+- } catch (e) {
+- this._logger.error(e);
+- userCancelled = e.message ?? e === 'User Cancelled';
+- }
+- }
-- return token;
-+ return scope.split(':').some(splitScopes => {
-+ return tokenScopes.includes(splitScopes);
-+ });
-+ })) {
-+ throw new Error(`The provided token does not match the requested scopes: ${scopes}`);
+- if (this._supportDeviceCodeFlow) {
+- try {
+- await promptToContinue();
+- return await this.doLoginDeviceCodeFlow(scopes);
+- } catch (e) {
+- this._logger.error(e);
+- userCancelled = e.message ?? e === 'User Cancelled';
+- }
+- } else if (!supported) {
+- try {
+- await promptToContinue();
+- return await this.doLoginWithPat(scopes);
+- } catch (e) {
+- this._logger.error(e);
+- userCancelled = e.message ?? e === 'User Cancelled';
+- }
++ try {
++ return await this.doLoginWithPat(scopes);
++ } catch (e) {
++ this._logger.error(e);
++ userCancelled = e.message ?? e === 'User Cancelled';
}
-- const existingNonces = this._pendingNonces.get(scopes) || [];
-- this._pendingNonces.set(scopes, [...existingNonces, nonce]);
--
-- const proxyEndpoints: { [providerId: string]: string } | undefined = await vscode.commands.executeCommand('workbench.getCodeExchangeProxyEndpoints');
-- // If we are running in insiders vscode.dev, then ensure we use the redirect route on that.
-- const redirectUri = proxyEndpoints?.github?.includes('https://insiders.vscode.dev') ? REDIRECT_URL_INSIDERS : REDIRECT_URL_STABLE;
-- const searchParams = new URLSearchParams([
-- ['client_id', CLIENT_ID],
-- ['redirect_uri', redirectUri],
-- ['scope', scopes],
-- ['state', encodeURIComponent(callbackUri.toString(true))]
-- ]);
-- const uri = vscode.Uri.parse(`${GITHUB_AUTHORIZE_URL}?${searchParams.toString()}`);
--
-- return vscode.window.withProgress({
-- location: vscode.ProgressLocation.Window,
-- title: localize('signingIn', " $(mark-github) Signing in to github.com..."),
-- }, async () => {
+ throw new Error(userCancelled ? 'Cancelled' : 'No auth flow succeeded.');
+ }
+
+- private async doLoginWithoutLocalServer(scopes: string, nonce: string, callbackUri: vscode.Uri): Promise {
+- this._logger.info(`Trying without local server... (${scopes})`);
+- return await vscode.window.withProgress({
+- location: vscode.ProgressLocation.Notification,
+- title: localize('signingIn', "Signing in to github.com..."),
+- cancellable: true
+- }, async (_, token) => {
+- const existingNonces = this._pendingNonces.get(scopes) || [];
+- this._pendingNonces.set(scopes, [...existingNonces, nonce]);
+- const redirectUri = await this.getRedirectEndpoint;
+- const searchParams = new URLSearchParams([
+- ['client_id', CLIENT_ID],
+- ['redirect_uri', redirectUri],
+- ['scope', scopes],
+- ['state', encodeURIComponent(callbackUri.toString(true))]
+- ]);
+- const uri = vscode.Uri.parse(`${GITHUB_AUTHORIZE_URL}?${searchParams.toString()}`);
- await vscode.env.openExternal(uri);
-
- // Register a single listener for the URI callback, in case the user starts the login process multiple times
- // before completing it.
- let codeExchangePromise = this._codeExchangePromises.get(scopes);
- if (!codeExchangePromise) {
-- codeExchangePromise = promiseFromEvent(this._uriHandler.event, this.exchangeCodeForToken(scopes));
+- codeExchangePromise = promiseFromEvent(this._uriHandler.event, this.handleUri(scopes));
- this._codeExchangePromises.set(scopes, codeExchangePromise);
- }
-
-- return Promise.race([
-- codeExchangePromise.promise,
-- promiseFromEvent(this._onDidManuallyProvideToken.event, (token: string | undefined, resolve, reject): void => {
-- if (!token) {
-- reject('Cancelled');
-- } else {
-- resolve(token);
-- }
-- }).promise,
-- new Promise((_, reject) => setTimeout(() => reject('Cancelled'), 60000))
-- ]).finally(() => {
+- try {
+- return await Promise.race([
+- codeExchangePromise.promise,
+- new Promise((_, reject) => setTimeout(() => reject('Cancelled'), 60000)),
+- promiseFromEvent(token.onCancellationRequested, (_, __, reject) => { reject('User Cancelled'); }).promise
+- ]);
+- } finally {
- this._pendingNonces.delete(scopes);
- codeExchangePromise?.cancel.fire();
- this._codeExchangePromises.delete(scopes);
-- });
+- }
- });
-+ return token;
+- }
+-
+- private async doLoginWithLocalServer(scopes: string): Promise {
+- this._logger.info(`Trying with local server... (${scopes})`);
+- return await vscode.window.withProgress({
+- location: vscode.ProgressLocation.Notification,
+- title: localize('signingInAnotherWay', "Signing in to github.com..."),
+- cancellable: true
+- }, async (_, token) => {
+- const redirectUri = await this.getRedirectEndpoint;
+- const searchParams = new URLSearchParams([
+- ['client_id', CLIENT_ID],
+- ['redirect_uri', redirectUri],
+- ['scope', scopes],
+- ]);
+- const loginUrl = `${GITHUB_AUTHORIZE_URL}?${searchParams.toString()}`;
+- const server = new LoopbackAuthServer(path.join(__dirname, '../media'), loginUrl);
+- const port = await server.start();
+-
+- let codeToExchange;
+- try {
+- vscode.env.openExternal(vscode.Uri.parse(`http://127.0.0.1:${port}/signin?nonce=${encodeURIComponent(server.nonce)}`));
+- const { code } = await Promise.race([
+- server.waitForOAuthResponse(),
+- new Promise((_, reject) => setTimeout(() => reject('Cancelled'), 60000)),
+- promiseFromEvent(token.onCancellationRequested, (_, __, reject) => { reject('User Cancelled'); }).promise
+- ]);
+- codeToExchange = code;
+- } finally {
+- setTimeout(() => {
+- void server.stop();
+- }, 5000);
+- }
+-
+- const accessToken = await this.exchangeCodeForToken(codeToExchange);
+- return accessToken;
+- });
+- }
+-
+- private async doLoginDeviceCodeFlow(scopes: string): Promise {
+- this._logger.info(`Trying device code flow... (${scopes})`);
+-
+- // Get initial device code
+- const uri = `https://github.com/login/device/code?client_id=${CLIENT_ID}&scope=${scopes}`;
+- const result = await fetch(uri, {
+- method: 'POST',
+- headers: {
+- Accept: 'application/json'
+- }
+- });
+- if (!result.ok) {
+- throw new Error(`Failed to get one-time code: ${await result.text()}`);
+- }
+-
+- const json = await result.json() as IGitHubDeviceCodeResponse;
+-
+-
+- const modalResult = await vscode.window.showInformationMessage(
+- localize('code.title', "Your Code: {0}", json.user_code),
+- {
+- modal: true,
+- detail: localize('code.detail', "To finish authenticating, navigate to GitHub and paste in the above one-time code.")
+- }, 'Copy & Continue to GitHub');
+-
+- if (modalResult !== 'Copy & Continue to GitHub') {
+- throw new Error('User Cancelled');
+- }
+-
+- await vscode.env.clipboard.writeText(json.user_code);
+-
+- const uriToOpen = await vscode.env.asExternalUri(vscode.Uri.parse(json.verification_uri));
+- await vscode.env.openExternal(uriToOpen);
+-
+- return await this.waitForDeviceCodeAccessToken(json);
+- }
+
+ private async doLoginWithPat(scopes: string): Promise {
+ this._logger.info(`Trying to retrieve PAT... (${scopes})`);
+@@ -351,118 +153,6 @@ export class GitHubServer implements IGitHubServer {
+ return token;
}
- private async doDeviceCodeFlow(scopes: string): Promise {
-@@ -299,57 +231,6 @@ export class GitHubServer implements IGitHubServer {
- throw new Error('Cancelled');
- }
-
-- private exchangeCodeForToken: (scopes: string) => PromiseAdapter =
-- (scopes) => async (uri, resolve, reject) => {
+- private async waitForDeviceCodeAccessToken(
+- json: IGitHubDeviceCodeResponse,
+- ): Promise {
+- return await vscode.window.withProgress({
+- location: vscode.ProgressLocation.Notification,
+- cancellable: true,
+- title: localize(
+- 'progress',
+- "Open [{0}]({0}) in a new tab and paste your one-time code: {1}",
+- json.verification_uri,
+- json.user_code)
+- }, async (_, token) => {
+- const refreshTokenUri = `https://github.com/login/oauth/access_token?client_id=${CLIENT_ID}&device_code=${json.device_code}&grant_type=urn:ietf:params:oauth:grant-type:device_code`;
+-
+- // Try for 2 minutes
+- const attempts = 120 / json.interval;
+- for (let i = 0; i < attempts; i++) {
+- await new Promise(resolve => setTimeout(resolve, json.interval * 1000));
+- if (token.isCancellationRequested) {
+- throw new Error('User Cancelled');
+- }
+- let accessTokenResult;
+- try {
+- accessTokenResult = await fetch(refreshTokenUri, {
+- method: 'POST',
+- headers: {
+- Accept: 'application/json'
+- }
+- });
+- } catch {
+- continue;
+- }
+-
+- if (!accessTokenResult.ok) {
+- continue;
+- }
+-
+- const accessTokenJson = await accessTokenResult.json();
+-
+- if (accessTokenJson.error === 'authorization_pending') {
+- continue;
+- }
+-
+- if (accessTokenJson.error) {
+- throw new Error(accessTokenJson.error_description);
+- }
+-
+- return accessTokenJson.access_token;
+- }
+-
+- throw new Error('Cancelled');
+- });
+- }
+-
+- private handleUri: (scopes: string) => PromiseAdapter =
+- (scopes) => (uri, resolve, reject) => {
- const query = new URLSearchParams(uri.query);
- const code = query.get('code');
--
-- const acceptedNonces = this._pendingNonces.get(scopes) || [];
- const nonce = query.get('nonce');
-- if (!nonce) {
-- this._logger.error('No nonce in response.');
+- if (!code) {
+- reject(new Error('No code'));
- return;
- }
+- if (!nonce) {
+- reject(new Error('No nonce'));
+- return;
+- }
+-
+- const acceptedNonces = this._pendingNonces.get(scopes) || [];
- if (!acceptedNonces.includes(nonce)) {
- // A common scenario of this happening is if you:
- // 1. Trigger a sign in with one set of scopes
@@ -166,85 +341,42 @@ index 49a523b..d68588e 100644
- return;
- }
-
-- this._logger.info('Exchanging code for token...');
--
-- const proxyEndpoints: { [providerId: string]: string } | undefined = await vscode.commands.executeCommand('workbench.getCodeExchangeProxyEndpoints');
-- const endpointUrl = proxyEndpoints?.github ? `${proxyEndpoints.github}login/oauth/access_token` : GITHUB_TOKEN_URL;
--
-- try {
-- const body = `code=${code}`;
-- const result = await fetch(endpointUrl, {
-- method: 'POST',
-- headers: {
-- Accept: 'application/json',
-- 'Content-Type': 'application/x-www-form-urlencoded',
-- 'Content-Length': body.toString()
--
-- },
-- body
-- });
--
-- if (result.ok) {
-- const json = await result.json();
-- this._logger.info('Token exchange success!');
-- resolve(json.access_token);
-- } else {
-- reject(result.statusText);
-- }
-- } catch (ex) {
-- reject(ex);
-- }
+- resolve(this.exchangeCodeForToken(code));
- };
+-
+- private async exchangeCodeForToken(code: string): Promise {
+- this._logger.info('Exchanging code for token...');
+-
+- const proxyEndpoints: { [providerId: string]: string } | undefined = await vscode.commands.executeCommand('workbench.getCodeExchangeProxyEndpoints');
+- const endpointUrl = proxyEndpoints?.github ? `${proxyEndpoints.github}login/oauth/access_token` : GITHUB_TOKEN_URL;
+-
+- const body = `code=${code}`;
+- const result = await fetch(endpointUrl, {
+- method: 'POST',
+- headers: {
+- Accept: 'application/json',
+- 'Content-Type': 'application/x-www-form-urlencoded',
+- 'Content-Length': body.toString()
+-
+- },
+- body
+- });
+-
+- if (result.ok) {
+- const json = await result.json();
+- this._logger.info('Token exchange success!');
+- return json.access_token;
+- } else {
+- const text = await result.text();
+- const error = new Error(text);
+- error.name = 'GitHubTokenExchangeError';
+- throw error;
+- }
+- }
-
private getServerUri(path: string = '') {
const apiUri = vscode.Uri.parse('https://api.github.com');
return vscode.Uri.parse(`${apiUri.scheme}://${apiUri.authority}${path}`);
-@@ -359,44 +240,7 @@ export class GitHubServer implements IGitHubServer {
- return getUserInfo(token, this.getServerUri('/user'), this._logger);
- }
-
-- public async sendAdditionalTelemetryInfo(token: string): Promise {
-- if (!vscode.env.isTelemetryEnabled) {
-- return;
-- }
-- const nocors = await this.isNoCorsEnvironment();
--
-- if (nocors) {
-- return;
-- }
--
-- try {
-- const result = await fetch('https://education.github.com/api/user', {
-- headers: {
-- Authorization: `token ${token}`,
-- 'faculty-check-preview': 'true',
-- 'User-Agent': 'Visual-Studio-Code'
-- }
-- });
--
-- if (result.ok) {
-- const json: { student: boolean; faculty: boolean } = await result.json();
--
-- /* __GDPR__
-- "session" : {
-- "isEdu": { "classification": "NonIdentifiableDemographicInfo", "purpose": "FeatureInsight" }
-- }
-- */
-- this._telemetryReporter.sendTelemetryEvent('session', {
-- isEdu: json.student
-- ? 'student'
-- : json.faculty
-- ? 'faculty'
-- : 'none'
-- });
-- }
-- } catch (e) {
-- // No-op
-- }
-+ public async sendAdditionalTelemetryInfo(_: string): Promise {
- }
-
- public async checkEnterpriseVersion(token: string): Promise {
diff --git a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts b/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts
index 36647e6..55e722b 100644
--- a/src/vs/workbench/browser/parts/activitybar/activitybarActions.ts
@@ -259,32 +391,10 @@ index 36647e6..55e722b 100644
menus.push(noAccountsAvailableAction);
}
diff --git a/src/vs/workbench/services/authentication/browser/authenticationService.ts b/src/vs/workbench/services/authentication/browser/authenticationService.ts
-index 5f7431d..278cd3d 100644
+index f543021..ad40bc3 100644
--- a/src/vs/workbench/services/authentication/browser/authenticationService.ts
+++ b/src/vs/workbench/services/authentication/browser/authenticationService.ts
-@@ -13,7 +13,6 @@ import { isString } from 'vs/base/common/types';
- import * as nls from 'vs/nls';
- import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
- import { CommandsRegistry } from 'vs/platform/commands/common/commands';
--import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
- import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
- import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
- import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
-@@ -197,13 +196,6 @@ export class AuthenticationService extends Disposable implements IAuthentication
- @IQuickInputService private readonly quickInputService: IQuickInputService
- ) {
- super();
-- this._placeholderMenuItem = MenuRegistry.appendMenuItem(MenuId.AccountsContext, {
-- command: {
-- id: 'noAuthenticationProviders',
-- title: nls.localize('loading', "Loading..."),
-- precondition: ContextKeyExpr.false()
-- },
-- });
-
- authenticationExtPoint.setHandler((extensions, { added, removed }) => {
- added.forEach(point => {
-@@ -272,16 +264,6 @@ export class AuthenticationService extends Disposable implements IAuthentication
+@@ -272,16 +272,6 @@ export class AuthenticationService extends Disposable implements IAuthentication
this.removeAccessRequest(id, extensionId);
});
}