Merge vscode source through release 1.79.2 (#23482)

* log when an editor action doesn't run because of enablement

* notebooks create/dispose editors. this means controllers must be created eagerly (😢) and that notebooks need a custom way of plugging comparision keys for session. works unless creating another session for the same cell of a duplicated editor

* Set offSide to sql lang configuration to true (#183461)

* Fixes #181764 (#183550)

* fix typo

* Always scroll down and focus the input (#183557)

* Fixes #180386 (#183561)

* cli: ensure ordering of rpc server messages (#183558)

* cli: ensure ordering of rpc server messages

Sending lots of messages to a stream would block them around the async
tokio mutex, which is "fair" so doesn't preserve ordering. Instead, use
the write_loop approach I introduced to the server_multiplexer for the
same reason some time ago.

* fix clippy

* update for May endgame

* testing: allow invalidateTestResults to take an array (#183569)

* Document `ShareProvider` API proposal (#183568)

* Document `ShareProvider` API proposal

* Remove mention of VS Code from JSDoc

* Add support for rendering svg and md in welcome message (#183580)

* Remove toggle setting more eagerly (#183584)

* rm message abt macOS

* Change text (#183589)

* Change text

* Accidentally changed the wrong file

* cli: improve output for code tunnel status (#183571)

* testing: allow invalidateTestResults to take an array

* cli: improve output for code tunnel status

Fixes #183570

* [json/css/html] update services (#183595)

* Add experimental setting to enable this dialog

* Fix exporting chat model to JSON before it is initialized (#183597)

* minimum scrolling to reveal the next cell on shift+enter (#183600)

do minimum scrolling to reveal the next cell on Execute cell and select next

* Fixing Jupyter notebook issue 13263 (#183527)

fix for the issue, still need to understand why there is strange focusing

* Tweak proposed API JSDoc (#183590)

* Tweak proposed API JSDoc

* workbench -> workspace

* fix ? operator

* Use active editor and show progress when sharing (#183603)

Use active editor and show progress

* use scroll setting variable correctly

* Schedule welcome widget to show once between typing. (#183606)

* Schedule dialog to show once between typing

* Don't re-render if already displayed once

* Add F10 keybinding for debugger step, even on Web. (#183510)

Fixes #181792.
Previously, for Web the keyboard shortcut was Alt-F10, because it was
believed that F10 could not be bound on browsers. This turned out to be
incorrect, so we make the shortcut consistent (F10) with desktop VSCode
which is also what many other debuggers use.
We keep Alt-F10 on web as a secondary keybinding to keep the experience
some web users may have gotten used to by now.

* Also pass process.env

* Restore missing chat clear commands (#183651)

* chore: update electron@22.5.4 (#183716)

* Show remote indicator in web when remoteAuthority is set (#183728)

* feat: .vuerc as json file (#153017)

Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>

* Delete --compatibility=1.63 code from the server (#183738)

* Copy vscode.dev link to tunnel generates an invalid link when an untitled workspace is open (#183739)

* Recent devcontainer display string corrupted on Get Started page (#183740)

* Improve "next codeblock" navigation (#183744)

* Improve "next codeblock" navigation
Operate on the current focused response, or the last one, and scroll to the selected item

* Normalize command title

* Git - run git status if similarityThreshold changes (#183762)

* fix aria-label issue in kb editor

fixes A11y_GradeB_VSCode_Keyboard shortcut reads words together - Blind: Arrow key navigation to row Find the binding keys and  "when" cell data are read together resulting in a word " CTRL + FeditorFocus  instead of CTRL + F editorFocus" #182490

* Status - fix compact padding (#183768)

* Remove angle brackets from VB brackets (#183782)

Fixes #183359

* Update language config schema with more details about brackets. (#183779)

* fix comment (#183812)

* Support for `Notebook` CodeAction Kind (#183457)

* nb kind support -- wip

* allow notebook codeactions around single cell edit check

* move notebook code action type out of editor

---------

Co-authored-by: rebornix <penn.lv@gmail.com>

* cli: fix connection default being applied (#183827)

* cli: bump to openssl 1.1.1u (#183828)

* Implement "delete" action for chat history (#183609)

* Use desired file name when generating new md pasted file paths (#183861)

Fixes #183851

* Default to filename for markdown new file if empty (#183864)

Fixes #183848

* Fix small typo (#183865)

Fixes #183819

* Noop when moving a symbol into the file it is already in (#183866)

Fixes #183793

* Adjust codeAction validation to account for notebook kind (#183859)

* Make JS/TS `go to configuration` commands work on non-`file:` file systems (#183688)

Make `go to project` commands work on non-`file:` file systems

Fixes #183685

* Can't do regex search after opening notebook (#183884)

Fixes #183858

* Default to current dir for `move to file` select (#183875)

Fixes #183870

`showOpenDialog` seems to ignore `defaultUri` if the file doesn't exist

* Use `<...>` style markdown links when needed (#183876)

Fixes #183849

* Remove check for context keys

* Update xterm package

* Enable updating a chat model without triggering incremental typing (#183894)

* Enable chat "move" commands on empty sessions (#183895)

* Enable chat "move" commands on empty sessions
and also imported sessions

* Fix command name

* Fix some chat keybindings on windows (#183896)

* "Revert File" on inactive editors are ignored (fix #177557) (#183903)

* Empty reason while switching profile (fix #183775) (#183904)

* fix https://github.com/microsoft/vscode-internalbacklog/issues/4278 (#183910)

* fix https://github.com/microsoft/vscode/issues/183770 (#183914)

* code --status displays a lot of errors before actual status output (fix #183787) (#183915)

* joh/icy manatee (#183917)

* Use idle value for widget of interactive editor controller

https://github.com/microsoft/vscode/issues/183820

* also make preview editors idle values

https://github.com/microsoft/vscode/issues/183820

* Fix #183777 (#183929)

* Fix #182309 (#183925)

* Tree checkbox item -> items (#183931)

Fixes #183826

* Fixes #183909 (#183940)

* Fix #183837 (#183943)

fix #183837

* Git - fix #183941 (#183944)

* Update xterm.css

Fixes #181242

* chore: add @ulugbekna and @aiday-mar to my-endgame notebook (#183946)

* Revert "When snippet mode is active, make `Tab` not accept suggestion but advance placeholder"

This reverts commit 50a80cdb61511343996ff1d41d0b676c3d329f48.

* revert not focusing completion list when quick suggest happens during snippet

* change `snippetsPreventQuickSuggestions` default to false

* Fix #181446 (#183956)

* fix https://github.com/microsoft/vscode-internalbacklog/issues/4298 (#183957)

* fix: remove extraneous incorrect context keys (#183959)

These were actually getting added in getTestItemContextOverlay, and the test ID was using the extended ID which extensions do not know about.

Fixes #183612

* Fixes https://github.com/microsoft/monaco-editor/issues/3920 (#183960)

* fix https://github.com/microsoft/vscode-internalbacklog/issues/4324 (#183961)

* fix #183030

* fix #180826 (#183962)

* make message more generic for interactive editor help

* .

* fix #183968

* Keep codeblock toolbar visible when focused

* Fix when clause on "Run in terminal" command

* add important info to help menu

* fix #183970

* Set `isRefactoring` for all TS refactoring edits (#183982)

* consolidate

* Disable move to file in TS versions < 5.2 (#183992)

There are still a few key bugs with refactoring. We will  ship this as a preview for TS 5.2+ instead of for 5.1

* Polish query accepting (#183995)

We shouldn't send the same request to Copilot if the query hasn't changed. So if the query is the same, we short circut.

Fixes https://github.com/microsoft/vscode-internalbacklog/issues/4286

Also, when we open in chat, we should use the last accepted query, not what's in the input box.

Fixes https://github.com/microsoft/vscode-internalbacklog/issues/4280

* Allow widget to have focus (#184000)

So that selecting non-code text works.

Fixes https://github.com/microsoft/vscode-internalbacklog/issues/4294

* Fix microsoft/vscode-internalbacklog#4257. Mitigate zindex for zone widgets. (#184001)

* Change welcome dialog contribution to Eventually

* Misc fixes

* Workspace folder picker entry descriptions are suboptimal for some filesystems (fix #183418) (#184018)

* cli - ignore std error unless verbose (#183787) (#184031)

* joh/inquisitive meerkat (#184034)

* only stash sessions that are none empty

https://github.com/microsoft/vscode-internalbacklog/issues/4281

* only unstash a session once - unless new exchanges are made,

https://github.com/microsoft/vscode-internalbacklog/issues/4281

* account for all exchange types

* Improve declared components (#184039)

* make sure to read setting (#184040)

d'oh, related to https://github.com/microsoft/vscode/issues/173387#issuecomment-1571696644

* [html] update service (#184049)

[html] update service. FIxes #181176

* reset context keys on reset/hide (#184042)

fixes https://github.com/microsoft/vscode-internalbacklog/issues/4330

* use `Lazy`, not `IdleValue` for the IE widget held by the eager controller (#184048)

https://github.com/microsoft/vscode/issues/183820

* fix https://github.com/microsoft/vscode-internalbacklog/issues/4333 (#184067)

* use undo-loop instead of undo-edit when discarding chat session (#184063)

* use undo-loop instead of undo-edit when discarding chat session

fixes https://github.com/microsoft/vscode-internalbacklog/issues/4118

* fix tests, wait for correct state

* Add logging to node download (#184070)

Add logging to node download. For #182951

* re-enable default zone widget revealing when showing (#184072)

fixes https://github.com/microsoft/vscode-internalbacklog/issues/4332, also fixes https://github.com/microsoft/vscode-internalbacklog/issues/3784

* fix #178202

* Allow APIs in stable (#184062)

* Fix microsoft/vscode-internalbacklog#4206. Override List view whitespace css for monaco editor (#184087)

* Fix JSDoc grammatical error (#184090)

* Pick up TS 5.1.3 (#184091)

Fixes #182931

* Misc fixes

* update distro (#184097)

* chore: update electron@22.5.5 (#184116)

* Extension host veto is registered multiple times on restart (fix #183778) (#184127)

Extension host veto is registered multiple times on restart (#183778)

* Do not auto start the local web worker extension host (#184137)

* Allow embedders to intercept trustedTypes.createPolicy calls (#184136)

Allow embedders to intercept trustedTypes.createPolicy calls (#184100)

* fix: reading from console output for --status on windows and linux (#184138)

fix: reading from console output for --status on windows and linux (#184118)

* Misc fixes

* code --status displays a lot of errors before actual status output (fix #183787) (#184200)

fix 183787

* (cherry-pick to 1.79 from main) Handle galleryExtension failure in featuredExtensionService (#184205)

Handle galleryExtension failure in featuredExtensionService (#184198)

Handle galleryExtension failure

* Fix #184183. Multiple output height updates are skipped. (#184188)

* Post merge init fixes

* Misc build issues

* disable toggle inline diff of `alt` down

https://github.com/microsoft/vscode-internalbacklog/issues/4342

* Take into account already activated extensions when computing running locations (#184303)

Take into account already activated extensions when computing running locations (fixes #184180)

* Avoid `extensionService.getExtension` and use `ActivationKind.Immediate` to allow that URI handling works while resolving (#184310)

Avoid `extensionService.getExtension` and use `ActivationKind.Immediate` to allow that URI handling works while resolving (fixes #182217)

* WIP

* rm fish auto injection

* More breaks

* Fix Port Attributes constructor (#184412)

* WIP

* WIP

* Allow extensions to get at the exports of other extensions during resolving (#184487)

Allow extensions to get at the exports of other extensions during resolving (fixes #184472)

* do not auto finish session when inline chat widgets have focus

re https://github.com/microsoft/vscode-internalbacklog/issues/4354

* fix compile errors caused by new base method

* WIP

* WIP

* WIP

* WIP

* Build errors

* unc - fix path traversal bypass

* Bump version

* cherry-pick prod changes from main

* Disable sandbox

* Build break from merge

* bump version

* Merge pull request #184739 from max06/max06/issue184659

Restore ShellIntegration for fish (#184659)

* Git - only add --find-renames if the value is not the default one (#185053)

Git - only add --find-renames if the value is not the default one (#184992)

* Cherry-pick: Revert changes to render featured extensions when available (#184747)

Revert changes to render featured extensions when available.  (#184573)

* Lower timeouts for experimentation and gallery service

* Revert changes to render extensions when available

* Add audio cues

* fix: disable app sandbox when --no-sandbox is present (#184913)

* fix: disable app sandbox when --no-sandbox is present (#184897)

* fix: loading minimist in packaged builds

* Runtime errors

* UNC allow list checks cannot be disabled in extension host (fix #184989) (#185085)

* UNC allow list checks cannot be disabled in extension host (#184989)

* Update src/vs/base/node/unc.js

Co-authored-by: Robo <hop2deep@gmail.com>

---------

Co-authored-by: Robo <hop2deep@gmail.com>

* Add notebook extension

* Fix mangling issues

* Fix mangling issues

* npm install

* npm install

* Issues blocking bundle

* Fix build folder compile errors

* Fix windows bundle build

* Linting fixes

* Fix sqllint issues

* Update yarn.lock files

* Fix unit tests

* Fix a couple breaks from test fixes

* Bump distro

* redo the checkbox style

* Update linux build container dockerfile

* Bump build image tag

* Bump native watch dog package

* Bump node-pty

* Bump distro

* Fix documnetation error

* Update distro

* redo the button styles

* Update datasource TS

* Add missing yarn.lock files

* Windows setup fix

* Turn off extension unit tests while investigating

* color box style

* Remove appx

* Turn off test log upload

* update dropdownlist style

* fix universal app build error (#23488)

* Skip flaky bufferContext vscode test

---------

Co-authored-by: Johannes <johannes.rieken@gmail.com>
Co-authored-by: Henning Dieterichs <hdieterichs@microsoft.com>
Co-authored-by: Julien Richard <jairbubbles@hotmail.com>
Co-authored-by: Charles Gagnon <chgagnon@microsoft.com>
Co-authored-by: Megan Rogge <merogge@microsoft.com>
Co-authored-by: meganrogge <megan.rogge@microsoft.com>
Co-authored-by: Rob Lourens <roblourens@gmail.com>
Co-authored-by: Connor Peet <connor@peet.io>
Co-authored-by: Joyce Er <joyce.er@microsoft.com>
Co-authored-by: Bhavya U <bhavyau@microsoft.com>
Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>
Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>
Co-authored-by: Aaron Munger <aamunger@microsoft.com>
Co-authored-by: Aiday Marlen Kyzy <amarlenkyzy@microsoft.com>
Co-authored-by: rebornix <penn.lv@gmail.com>
Co-authored-by: Ole <oler@google.com>
Co-authored-by: Jean Pierre <jeanp413@hotmail.com>
Co-authored-by: Robo <hop2deep@gmail.com>
Co-authored-by: Yash Singh <saiansh2525@gmail.com>
Co-authored-by: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com>
Co-authored-by: Ulugbek Abdullaev <ulugbekna@gmail.com>
Co-authored-by: Alex Ross <alros@microsoft.com>
Co-authored-by: Michael Lively <milively@microsoft.com>
Co-authored-by: Matt Bierner <matb@microsoft.com>
Co-authored-by: Andrea Mah <31675041+andreamah@users.noreply.github.com>
Co-authored-by: Benjamin Pasero <benjamin.pasero@microsoft.com>
Co-authored-by: Sandeep Somavarapu <sasomava@microsoft.com>
Co-authored-by: Daniel Imms <2193314+Tyriar@users.noreply.github.com>
Co-authored-by: Tyler James Leonhardt <me@tylerleonhardt.com>
Co-authored-by: Alexandru Dima <alexdima@microsoft.com>
Co-authored-by: Joao Moreno <Joao.Moreno@microsoft.com>
Co-authored-by: Alan Ren <alanren@microsoft.com>
This commit is contained in:
Karl Burtram
2023-06-27 15:26:51 -07:00
committed by GitHub
parent 7975fda6dd
commit 01e66ab3e6
4335 changed files with 252586 additions and 164604 deletions

View File

@@ -16,14 +16,12 @@ module.exports = withBrowserDefaults({
entry: {
extension: './src/extension.ts',
},
externals: {
'keytar': 'commonjs keytar',
},
resolve: {
alias: {
'node-fetch': path.resolve(__dirname, 'node_modules/node-fetch/browser.js'),
'uuid': path.resolve(__dirname, 'node_modules/uuid/dist/esm-browser/index.js'),
'./authServer': path.resolve(__dirname, 'src/env/browser/authServer'),
'./node/authServer': path.resolve(__dirname, 'src/browser/authServer'),
'./node/crypto': path.resolve(__dirname, 'src/browser/crypto'),
'./node/fetch': path.resolve(__dirname, 'src/browser/fetch')
}
}
});

View File

@@ -13,8 +13,5 @@ module.exports = withDefaults({
context: __dirname,
entry: {
extension: './src/extension.ts',
},
externals: {
'keytar': 'commonjs keytar'
}
});

View File

@@ -17,14 +17,14 @@
"ui",
"workspace"
],
"activationEvents": [
"onAuthenticationRequest:github",
"onAuthenticationRequest:github-enterprise"
],
"activationEvents": [],
"capabilities": {
"virtualWorkspaces": true,
"untrustedWorkspaces": {
"supported": true
"supported": "limited",
"restrictedConfigurations": [
"github-enterprise.uri"
]
}
},
"contributes": {
@@ -34,16 +34,16 @@
"id": "github"
},
{
"label": "GitHub Enterprise",
"label": "GitHub Enterprise Server",
"id": "github-enterprise"
}
],
"configuration": {
"title": "GitHub Enterprise Authentication Provider",
"title": "GitHub Enterprise Server Authentication Provider",
"properties": {
"github-enterprise.uri": {
"type": "string",
"description": "URI of your GitHub Enterprise Instance"
"description": "GitHub Enterprise Server URI"
}
}
}
@@ -60,15 +60,12 @@
},
"dependencies": {
"node-fetch": "2.6.7",
"uuid": "8.1.0",
"@vscode/extension-telemetry": "0.6.2",
"vscode-nls": "^5.0.0",
"@vscode/extension-telemetry": "0.7.5",
"vscode-tas-client": "^0.1.47"
},
"devDependencies": {
"@types/node": "16.x",
"@types/node-fetch": "^2.5.7",
"@types/uuid": "8.0.0"
"@types/node-fetch": "^2.5.7"
},
"repository": {
"type": "git",

View File

@@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export const crypto = globalThis.crypto;

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Uri } from 'vscode';
import { AuthProviderType } from '../github';
const VALID_DESKTOP_CALLBACK_SCHEMES = [
'vscode',
@@ -15,7 +16,7 @@ const VALID_DESKTOP_CALLBACK_SCHEMES = [
'vscode-exploration'
];
export function isSupportedEnvironment(uri: Uri): boolean {
export function isSupportedClient(uri: Uri): boolean {
return (
VALID_DESKTOP_CALLBACK_SCHEMES.includes(uri.scheme) ||
// vscode.dev & insiders.vscode.dev
@@ -24,3 +25,10 @@ export function isSupportedEnvironment(uri: Uri): boolean {
/(?:^|\.)github\.dev$/.test(uri.authority)
);
}
export function isSupportedTarget(type: AuthProviderType, gheUri?: Uri): boolean {
return (
type === AuthProviderType.github ||
/\.ghe\.com$/.test(gheUri!.authority)
);
}

View File

@@ -18,14 +18,19 @@ export class ExperimentationTelemetry implements IExperimentationTelemetry {
switch (vscode.env.uriScheme) {
case 'vscode':
targetPopulation = TargetPopulation.Public;
break;
case 'vscode-insiders':
targetPopulation = TargetPopulation.Insiders;
break;
case 'vscode-exploration':
targetPopulation = TargetPopulation.Internal;
break;
case 'code-oss':
targetPopulation = TargetPopulation.Team;
break;
default:
targetPopulation = TargetPopulation.Public;
break;
}
const id = this.context.extension.id;

View File

@@ -6,53 +6,24 @@
import * as vscode from 'vscode';
import { AuthProviderType } from '../github';
type LogLevel = 'Trace' | 'Info' | 'Error';
export class Log {
private output: vscode.OutputChannel;
private output: vscode.LogOutputChannel;
constructor(private readonly type: AuthProviderType) {
const friendlyName = this.type === AuthProviderType.github ? 'GitHub' : 'GitHub Enterprise';
this.output = vscode.window.createOutputChannel(`${friendlyName} Authentication`);
this.output = vscode.window.createOutputChannel(`${friendlyName} Authentication`, { log: true });
}
private data2String(data: any): string {
if (data instanceof Error) {
return data.stack || data.message;
}
if (data.success === false && data.message) {
return data.message;
}
return data.toString();
public trace(message: string): void {
this.output.trace(message);
}
public trace(message: string, data?: any): void {
this.logLevel('Trace', message, data);
public info(message: string): void {
this.output.info(message);
}
public info(message: string, data?: any): void {
this.logLevel('Info', message, data);
public error(message: string): void {
this.output.error(message);
}
public error(message: string, data?: any): void {
this.logLevel('Error', message, data);
}
public logLevel(level: LogLevel, message: string, data?: any): void {
this.output.appendLine(`[${level} - ${this.now()}] ${message}`);
if (data) {
this.output.appendLine(this.data2String(data));
}
}
private now(): string {
const now = new Date();
return padLeft(now.getUTCHours() + '', 2, '0')
+ ':' + padLeft(now.getMinutes() + '', 2, '0')
+ ':' + padLeft(now.getUTCSeconds() + '', 2, '0') + '.' + now.getMilliseconds();
}
}
function padLeft(s: string, n: number, pad = ' ') {
return pad.repeat(Math.max(0, n - s.length)) + s;
}

View File

@@ -4,22 +4,42 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { GitHubAuthenticationProvider, AuthProviderType } from './github';
import { GitHubAuthenticationProvider, UriEventHandler } from './github';
function initGHES(context: vscode.ExtensionContext, uriHandler: UriEventHandler) {
const settingValue = vscode.workspace.getConfiguration().get<string>('github-enterprise.uri');
if (!settingValue) {
return undefined;
}
// validate user value
let uri: vscode.Uri;
try {
uri = vscode.Uri.parse(settingValue, true);
} catch (e) {
vscode.window.showErrorMessage(vscode.l10n.t('GitHub Enterprise Server URI is not a valid URI: {0}', e.message ?? e));
return;
}
const githubEnterpriseAuthProvider = new GitHubAuthenticationProvider(context, uriHandler, uri);
context.subscriptions.push(githubEnterpriseAuthProvider);
return githubEnterpriseAuthProvider;
}
export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(new GitHubAuthenticationProvider(context, AuthProviderType.github));
const uriHandler = new UriEventHandler();
context.subscriptions.push(uriHandler);
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
let githubEnterpriseAuthProvider: GitHubAuthenticationProvider | undefined;
if (vscode.workspace.getConfiguration().get<string>('github-enterprise.uri')) {
githubEnterpriseAuthProvider = new GitHubAuthenticationProvider(context, AuthProviderType.githubEnterprise);
context.subscriptions.push(githubEnterpriseAuthProvider);
}
context.subscriptions.push(new GitHubAuthenticationProvider(context, uriHandler));
let githubEnterpriseAuthProvider: GitHubAuthenticationProvider | undefined = initGHES(context, uriHandler);
context.subscriptions.push(vscode.workspace.onDidChangeConfiguration(async e => {
if (e.affectsConfiguration('github-enterprise.uri')) {
if (!githubEnterpriseAuthProvider && vscode.workspace.getConfiguration().get<string>('github-enterprise.uri')) {
githubEnterpriseAuthProvider = new GitHubAuthenticationProvider(context, AuthProviderType.githubEnterprise);
context.subscriptions.push(githubEnterpriseAuthProvider);
if (vscode.workspace.getConfiguration().get<string>('github-enterprise.uri')) {
githubEnterpriseAuthProvider?.dispose();
githubEnterpriseAuthProvider = initGHES(context, uriHandler);
}
}
}));

View File

@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { v4 as uuid } from 'uuid';
import { Keychain } from './common/keychain';
import { GitHubEnterpriseServer, GitHubServer, IGitHubServer } from './githubServer';
import { arrayEquals } from './common/utils';
import { ExperimentationTelemetry } from './experimentationService';
import TelemetryReporter from '@vscode/extension-telemetry';
import { Keychain } from './common/keychain';
import { GitHubServer, IGitHubServer } from './githubServer';
import { arrayEquals } from './common/utils';
import { ExperimentationTelemetry } from './common/experimentationService';
import { Log } from './common/logger';
import { crypto } from './node/crypto';
interface SessionData {
id: string;
@@ -28,30 +28,48 @@ export enum AuthProviderType {
githubEnterprise = 'github-enterprise'
}
export class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.UriHandler {
public handleUri(uri: vscode.Uri) {
this.fire(uri);
}
}
export class GitHubAuthenticationProvider implements vscode.AuthenticationProvider, vscode.Disposable {
private _sessionChangeEmitter = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
private _logger = new Log(this.type);
private _githubServer: IGitHubServer;
private _telemetryReporter: ExperimentationTelemetry;
private readonly _sessionChangeEmitter = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
private readonly _logger: Log;
private readonly _githubServer: IGitHubServer;
private readonly _telemetryReporter: ExperimentationTelemetry;
private readonly _keychain: Keychain;
private readonly _accountsSeen = new Set<string>();
private readonly _disposable: vscode.Disposable | undefined;
private _keychain: Keychain = new Keychain(this.context, `${this.type}.auth`, this._logger);
private _sessionsPromise: Promise<vscode.AuthenticationSession[]>;
private _accountsSeen = new Set<string>();
private _disposable: vscode.Disposable;
constructor(private readonly context: vscode.ExtensionContext, private readonly type: AuthProviderType) {
const { name, version, aiKey } = context.extension.packageJSON as { name: string; version: string; aiKey: string };
this._telemetryReporter = new ExperimentationTelemetry(context, new TelemetryReporter(name, version, aiKey));
constructor(
private readonly context: vscode.ExtensionContext,
uriHandler: UriEventHandler,
ghesUri?: vscode.Uri
) {
const { aiKey } = context.extension.packageJSON as { name: string; version: string; aiKey: string };
this._telemetryReporter = new ExperimentationTelemetry(context, new TelemetryReporter(aiKey));
if (this.type === AuthProviderType.github) {
this._githubServer = new GitHubServer(
// We only can use the Device Code flow when we have a full node environment because of CORS.
context.extension.extensionKind === vscode.ExtensionKind.Workspace || vscode.env.uiKind === vscode.UIKind.Desktop,
this._logger,
this._telemetryReporter);
} else {
this._githubServer = new GitHubEnterpriseServer(this._logger, this._telemetryReporter);
}
const type = ghesUri ? AuthProviderType.githubEnterprise : AuthProviderType.github;
this._logger = new Log(type);
this._keychain = new Keychain(
this.context,
type === AuthProviderType.github
? `${type}.auth`
: `${ghesUri?.authority}${ghesUri?.path}.ghes.auth`,
this._logger);
this._githubServer = new GitHubServer(
this._logger,
this._telemetryReporter,
uriHandler,
context.extension.extensionKind,
ghesUri);
// Contains the current state of the sessions we have available.
this._sessionsPromise = this.readSessions().then((sessions) => {
@@ -62,14 +80,13 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
this._disposable = vscode.Disposable.from(
this._telemetryReporter,
this._githubServer,
vscode.authentication.registerAuthenticationProvider(type, this._githubServer.friendlyName, this, { supportsMultipleAccounts: false }),
this.context.secrets.onDidChange(() => this.checkForUpdates())
);
}
dispose() {
this._disposable.dispose();
this._disposable?.dispose();
}
get onDidChangeSessions() {
@@ -93,7 +110,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
// We only want to fire a telemetry if we haven't seen this account yet in this session.
if (!this._accountsSeen.has(session.account.id)) {
this._accountsSeen.add(session.account.id);
this._githubServer.sendAdditionalTelemetryInfo(session.accessToken);
this._githubServer.sendAdditionalTelemetryInfo(session);
}
}
@@ -259,7 +276,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
*/
this._telemetryReporter?.sendTelemetryEvent('loginFailed');
vscode.window.showErrorMessage(`Sign in failed: ${e}`);
vscode.window.showErrorMessage(vscode.l10n.t('Sign in failed: {0}', `${e}`));
this._logger.error(e);
throw e;
}
@@ -268,7 +285,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
private async tokenToSession(token: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
const userInfo = await this._githubServer.getUserInfo(token);
return {
id: uuid(),
id: crypto.getRandomValues(new Uint32Array(2)).reduce((prev, curr) => prev += curr.toString(16), ''),
accessToken: token,
account: { label: userInfo.accountName, id: userInfo.id },
scopes
@@ -302,7 +319,7 @@ export class GitHubAuthenticationProvider implements vscode.AuthenticationProvid
*/
this._telemetryReporter?.sendTelemetryEvent('logoutFailed');
vscode.window.showErrorMessage(`Sign out failed: ${e}`);
vscode.window.showErrorMessage(vscode.l10n.t('Sign out failed: {0}', `${e}`));
this._logger.error(e);
throw e;
}

View File

@@ -3,45 +3,36 @@
* Licensed under the Source EULA. 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';
import * as path from 'path';
import { PromiseAdapter, promiseFromEvent } from './common/utils';
import { ExperimentationTelemetry } from './experimentationService';
import { AuthProviderType } from './github';
import { ExperimentationTelemetry } from './common/experimentationService';
import { AuthProviderType, UriEventHandler } from './github';
import { Log } from './common/logger';
import { isSupportedEnvironment } from './common/env';
import { LoopbackAuthServer } from './authServer';
import path = require('path');
import { isSupportedClient, isSupportedTarget } from './common/env';
import { LoopbackAuthServer } from './node/authServer';
import { crypto } from './node/crypto';
import { fetching } from './node/fetch';
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';
// 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.
const CANCELLATION_ERROR = 'Cancelled';
// These error messages are internal and should not be shown to the user in any way.
const TIMED_OUT_ERROR = 'Timed out';
const USER_CANCELLATION_ERROR = 'User Cancelled';
const NETWORK_ERROR = 'network error';
const REDIRECT_URL_STABLE = 'https://vscode.dev/redirect';
const REDIRECT_URL_INSIDERS = 'https://insiders.vscode.dev/redirect';
class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.UriHandler {
constructor(private readonly Logger: Log) {
super();
}
public handleUri(uri: vscode.Uri) {
this.Logger.trace('Handling Uri...');
this.fire(uri);
}
}
export interface IGitHubServer extends vscode.Disposable {
export interface IGitHubServer {
login(scopes: string): Promise<string>;
getUserInfo(token: string): Promise<{ id: string; accountName: string }>;
sendAdditionalTelemetryInfo(token: string): Promise<void>;
sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise<void>;
friendlyName: string;
type: AuthProviderType;
}
interface IGitHubDeviceCodeResponse {
@@ -54,10 +45,10 @@ interface IGitHubDeviceCodeResponse {
async function getScopes(token: string, serverUri: vscode.Uri, logger: Log): Promise<string[]> {
try {
logger.info('Getting token scopes...');
const result = await fetch(serverUri.toString(), {
const result = await fetching(serverUri.toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})`
}
});
@@ -74,71 +65,55 @@ async function getScopes(token: string, serverUri: vscode.Uri, logger: Log): Pro
}
}
async function getUserInfo(token: string, serverUri: vscode.Uri, logger: Log): Promise<{ id: string; accountName: string }> {
let result: Response;
try {
logger.info('Getting user info...');
result = await fetch(serverUri.toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
}
});
} catch (ex) {
logger.error(ex.message);
throw new Error(NETWORK_ERROR);
}
if (result.ok) {
try {
const json = await result.json();
logger.info('Got account info!');
return { id: json.id, accountName: json.login };
} catch (e) {
logger.error(`Unexpected error parsing response from GitHub: ${e.message ?? e}`);
throw e;
}
} else {
// either display the response message or the http status text
let errorMessage = result.statusText;
try {
const json = await result.json();
if (json.message) {
errorMessage = json.message;
}
} catch (err) {
// noop
}
logger.error(`Getting account info failed: ${errorMessage}`);
throw new Error(errorMessage);
}
}
export class GitHubServer implements IGitHubServer {
friendlyName = 'GitHub';
type = AuthProviderType.github;
readonly friendlyName: string;
private _pendingNonces = new Map<string, string[]>();
private _codeExchangePromises = new Map<string, { promise: Promise<string>; cancel: vscode.EventEmitter<void> }>();
private _disposable: vscode.Disposable;
private _uriHandler = new UriEventHandler(this._logger);
private readonly getRedirectEndpoint: Thenable<string>;
private readonly _pendingNonces = new Map<string, string[]>();
private readonly _codeExchangePromises = new Map<string, { promise: Promise<string>; cancel: vscode.EventEmitter<void> }>();
private readonly _type: AuthProviderType;
constructor(private readonly _supportDeviceCodeFlow: boolean, private readonly _logger: Log, private readonly _telemetryReporter: ExperimentationTelemetry) {
this._disposable = vscode.window.registerUriHandler(this._uriHandler);
private _redirectEndpoint: string | undefined;
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;
});
constructor(
private readonly _logger: Log,
private readonly _telemetryReporter: ExperimentationTelemetry,
private readonly _uriHandler: UriEventHandler,
private readonly _extensionKind: vscode.ExtensionKind,
private readonly _ghesUri?: vscode.Uri
) {
this._type = _ghesUri ? AuthProviderType.githubEnterprise : AuthProviderType.github;
this.friendlyName = this._type === AuthProviderType.github ? 'GitHub' : _ghesUri?.authority!;
}
dispose() {
this._disposable.dispose();
get baseUri() {
if (this._type === AuthProviderType.github) {
return vscode.Uri.parse('https://github.com/');
}
return this._ghesUri!;
}
private async getRedirectEndpoint(): Promise<string> {
if (this._redirectEndpoint) {
return this._redirectEndpoint;
}
if (this._type === AuthProviderType.github) {
const proxyEndpoints = await vscode.commands.executeCommand<{ [providerId: string]: string } | undefined>('workbench.getCodeExchangeProxyEndpoints');
// If we are running in insiders vscode.dev, then ensure we use the redirect route on that.
this._redirectEndpoint = REDIRECT_URL_STABLE;
if (proxyEndpoints?.github && new URL(proxyEndpoints.github).hostname === 'insiders.vscode.dev') {
this._redirectEndpoint = REDIRECT_URL_INSIDERS;
}
} else {
// GHE only supports a single redirect endpoint, so we can't use
// insiders.vscode.dev/redirect when we're running in Insiders, unfortunately.
// Additionally, we make the assumption that this function will only be used
// in flows that target supported GHE targets, not on-prem GHES. Because of this
// assumption, we can assume that the GHE version used is at least 3.8 which is
// the version that changed the redirect endpoint to this URI from the old
// GitHub maintained server.
this._redirectEndpoint = 'https://vscode.dev/redirect';
}
return this._redirectEndpoint;
}
// TODO@joaomoreno TODO@TylerLeonhardt
@@ -152,99 +127,117 @@ 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 () => {
const yes = vscode.l10n.t('Yes');
const no = vscode.l10n.t('No');
const promptToContinue = async (mode: string) => {
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?");
? vscode.l10n.t('Having trouble logging in? Would you like to try a different way? ({0})', mode)
: vscode.l10n.t('You have not yet finished authorizing this extension to use GitHub. Would you like to try a different way? ({0})', mode);
const result = await vscode.window.showWarningMessage(message, yes, no);
if (result !== yes) {
throw new Error('Cancelled');
throw new Error(CANCELLATION_ERROR);
}
};
const nonce = uuid();
const nonce: string = crypto.getRandomValues(new Uint32Array(2)).reduce((prev, curr) => prev += curr.toString(16), '');
const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/did-authenticate?nonce=${encodeURIComponent(nonce)}`));
const supported = isSupportedEnvironment(callbackUri);
if (supported) {
const supportedClient = isSupportedClient(callbackUri);
const supportedTarget = isSupportedTarget(this._type, this._ghesUri);
if (supportedClient && supportedTarget) {
try {
return await this.doLoginWithoutLocalServer(scopes, nonce, callbackUri);
} catch (e) {
this._logger.error(e);
userCancelled = e.message ?? e === 'User Cancelled';
userCancelled = e.message ?? e === USER_CANCELLATION_ERROR;
}
}
// Starting a local server isn't supported in web
if (vscode.env.uiKind === vscode.UIKind.Desktop) {
// Starting a local server is only supported if:
// 1. We are in a UI extension because we need to open a port on the machine that has the browser
// 2. We are in a node runtime because we need to open a port on the machine
// 3. code exchange can only be done with a supported target
if (
this._extensionKind === vscode.ExtensionKind.UI &&
typeof navigator === 'undefined' &&
supportedTarget
) {
try {
await promptToContinue();
await promptToContinue(vscode.l10n.t('local server'));
return await this.doLoginWithLocalServer(scopes);
} catch (e) {
this._logger.error(e);
userCancelled = e.message ?? e === 'User Cancelled';
userCancelled = this.processLoginError(e);
}
}
if (this._supportDeviceCodeFlow) {
// We only can use the Device Code flow when we have a full node environment because of CORS.
if (typeof navigator === 'undefined') {
try {
await promptToContinue();
await promptToContinue(vscode.l10n.t('device code'));
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';
userCancelled = this.processLoginError(e);
}
}
throw new Error(userCancelled ? 'Cancelled' : 'No auth flow succeeded.');
// In a supported environment, we can't use PAT auth because we use this auth for Settings Sync and it doesn't support PATs.
// With that said, GitHub Enterprise isn't used by Settings Sync so we can use PATs for that.
if (!supportedClient || this._type === AuthProviderType.githubEnterprise) {
try {
await promptToContinue(vscode.l10n.t('personal access token'));
return await this.doLoginWithPat(scopes);
} catch (e) {
userCancelled = this.processLoginError(e);
}
}
throw new Error(userCancelled ? CANCELLATION_ERROR : 'No auth flow succeeded.');
}
private async doLoginWithoutLocalServer(scopes: string, nonce: string, callbackUri: vscode.Uri): Promise<string> {
this._logger.info(`Trying without local server... (${scopes})`);
return await vscode.window.withProgress<string>({
location: vscode.ProgressLocation.Notification,
title: localize('signingIn', "Signing in to github.com..."),
title: vscode.l10n.t({
message: 'Signing in to {0}...',
args: [this.baseUri.authority],
comment: ['The {0} will be a url, e.g. github.com']
}),
cancellable: true
}, async (_, token) => {
const existingNonces = this._pendingNonces.get(scopes) || [];
this._pendingNonces.set(scopes, [...existingNonces, nonce]);
const redirectUri = await this.getRedirectEndpoint;
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()}`);
const uri = vscode.Uri.parse(this.baseUri.with({
path: '/login/oauth/authorize',
query: searchParams.toString()
}).toString(true));
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.handleUri(scopes));
codeExchangePromise = promiseFromEvent(this._uriHandler!.event, this.handleUri(scopes));
this._codeExchangePromises.set(scopes, codeExchangePromise);
}
try {
return await Promise.race([
codeExchangePromise.promise,
new Promise<string>((_, reject) => setTimeout(() => reject('Cancelled'), 60000)),
promiseFromEvent<any, any>(token.onCancellationRequested, (_, __, reject) => { reject('User Cancelled'); }).promise
new Promise<string>((_, reject) => setTimeout(() => reject(TIMED_OUT_ERROR), 300_000)), // 5min timeout
promiseFromEvent<any, any>(token.onCancellationRequested, (_, __, reject) => { reject(USER_CANCELLATION_ERROR); }).promise
]);
} finally {
this._pendingNonces.delete(scopes);
@@ -258,17 +251,25 @@ export class GitHubServer implements IGitHubServer {
this._logger.info(`Trying with local server... (${scopes})`);
return await vscode.window.withProgress<string>({
location: vscode.ProgressLocation.Notification,
title: localize('signingInAnotherWay', "Signing in to github.com..."),
title: vscode.l10n.t({
message: 'Signing in to {0}...',
args: [this.baseUri.authority],
comment: ['The {0} will be a url, e.g. github.com']
}),
cancellable: true
}, async (_, token) => {
const redirectUri = await this.getRedirectEndpoint;
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 loginUrl = this.baseUri.with({
path: '/login/oauth/authorize',
query: searchParams.toString()
});
const server = new LoopbackAuthServer(path.join(__dirname, '../media'), loginUrl.toString(true));
const port = await server.start();
let codeToExchange;
@@ -276,8 +277,8 @@ export class GitHubServer implements IGitHubServer {
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<any>((_, reject) => setTimeout(() => reject('Cancelled'), 60000)),
promiseFromEvent<any, any>(token.onCancellationRequested, (_, __, reject) => { reject('User Cancelled'); }).promise
new Promise<any>((_, reject) => setTimeout(() => reject(TIMED_OUT_ERROR), 300_000)), // 5min timeout
promiseFromEvent<any, any>(token.onCancellationRequested, (_, __, reject) => { reject(USER_CANCELLATION_ERROR); }).promise
]);
codeToExchange = code;
} finally {
@@ -295,8 +296,11 @@ export class GitHubServer implements IGitHubServer {
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, {
const uri = this.baseUri.with({
path: '/login/device/code',
query: `client_id=${CLIENT_ID}&scope=${scopes}`
});
const result = await fetching(uri.toString(true), {
method: 'POST',
headers: {
Accept: 'application/json'
@@ -308,16 +312,16 @@ export class GitHubServer implements IGitHubServer {
const json = await result.json() as IGitHubDeviceCodeResponse;
const button = vscode.l10n.t('Copy & Continue to GitHub');
const modalResult = await vscode.window.showInformationMessage(
localize('code.title', "Your Code: {0}", json.user_code),
vscode.l10n.t({ message: 'Your Code: {0}', args: [json.user_code], comment: ['The {0} will be a code, e.g. 123-456'] }),
{
modal: true,
detail: localize('code.detail', "To finish authenticating, navigate to GitHub and paste in the above one-time code.")
}, 'Copy & Continue to GitHub');
detail: vscode.l10n.t('To finish authenticating, navigate to GitHub and paste in the above one-time code.')
}, button);
if (modalResult !== 'Copy & Continue to GitHub') {
throw new Error('User Cancelled');
if (modalResult !== button) {
throw new Error(USER_CANCELLATION_ERROR);
}
await vscode.env.clipboard.writeText(json.user_code);
@@ -330,8 +334,24 @@ export class GitHubServer implements IGitHubServer {
private async doLoginWithPat(scopes: string): Promise<string> {
this._logger.info(`Trying to retrieve PAT... (${scopes})`);
const token = await vscode.window.showInputBox({ prompt: 'GitHub Personal Access Token', ignoreFocusOut: true });
if (!token) { throw new Error('User Cancelled'); }
const button = vscode.l10n.t('Continue to GitHub');
const modalResult = await vscode.window.showInformationMessage(
vscode.l10n.t('Continue to GitHub to create a Personal Access Token (PAT)'),
{
modal: true,
detail: vscode.l10n.t('To finish authenticating, navigate to GitHub to create a PAT then paste the PAT into the input box.')
}, button);
if (modalResult !== button) {
throw new Error(USER_CANCELLATION_ERROR);
}
const description = `${vscode.env.appName} (${scopes})`;
const uriToOpen = await vscode.env.asExternalUri(this.baseUri.with({ path: '/settings/tokens/new', query: `description=${description}&scopes=${scopes.split(' ').join(',')}` }));
await vscode.env.openExternal(uriToOpen);
const token = await vscode.window.showInputBox({ placeHolder: `ghp_1a2b3c4...`, prompt: `GitHub Personal Access Token - ${scopes}`, ignoreFocusOut: true });
if (!token) { throw new Error(USER_CANCELLATION_ERROR); }
const tokenScopes = await getScopes(token, this.getServerUri('/'), this._logger); // Example: ['repo', 'user']
const scopesList = scopes.split(' '); // Example: 'read:user repo user:email'
@@ -357,24 +377,30 @@ export class GitHubServer implements IGitHubServer {
return await vscode.window.withProgress<string>({
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)
title: vscode.l10n.t({
message: 'Open [{0}]({0}) in a new tab and paste your one-time code: {1}',
args: [json.verification_uri, json.user_code],
comment: [
'The [{0}]({0}) will be a url and the {1} will be a code, e.g. 123-456',
'{Locked="[{0}]({0})"}'
]
})
}, 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`;
const refreshTokenUri = this.baseUri.with({
path: '/login/oauth/access_token',
query: `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');
throw new Error(USER_CANCELLATION_ERROR);
}
let accessTokenResult;
try {
accessTokenResult = await fetch(refreshTokenUri, {
accessTokenResult = await fetching(refreshTokenUri.toString(true), {
method: 'POST',
headers: {
Accept: 'application/json'
@@ -401,7 +427,7 @@ export class GitHubServer implements IGitHubServer {
return accessTokenJson.access_token;
}
throw new Error('Cancelled');
throw new Error(TIMED_OUT_ERROR);
});
}
@@ -439,8 +465,12 @@ export class GitHubServer implements IGitHubServer {
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, {
const body = new URLSearchParams([['code', code]]);
if (this._type === AuthProviderType.githubEnterprise) {
body.append('github_enterprise', this.baseUri.toString(true));
body.append('redirect_uri', await this.getRedirectEndpoint());
}
const result = await fetching(endpointUrl, {
method: 'POST',
headers: {
Accept: 'application/json',
@@ -448,7 +478,7 @@ export class GitHubServer implements IGitHubServer {
'Content-Length': body.toString()
},
body
body: body.toString()
});
if (result.ok) {
@@ -464,15 +494,56 @@ export class GitHubServer implements IGitHubServer {
}
private getServerUri(path: string = '') {
const apiUri = vscode.Uri.parse('https://api.github.com');
return vscode.Uri.parse(`${apiUri.scheme}://${apiUri.authority}${path}`);
const apiUri = this.baseUri;
// github.com and Hosted GitHub Enterprise instances
if (isSupportedTarget(this._type, this._ghesUri)) {
return vscode.Uri.parse(`${apiUri.scheme}://api.${apiUri.authority}`).with({ path });
}
// GitHub Enterprise Server (aka on-prem)
return vscode.Uri.parse(`${apiUri.scheme}://${apiUri.authority}/api/v3${path}`);
}
public getUserInfo(token: string): Promise<{ id: string; accountName: string }> {
return getUserInfo(token, this.getServerUri('/user'), this._logger);
public async getUserInfo(token: string): Promise<{ id: string; accountName: string }> {
let result;
try {
this._logger.info('Getting user info...');
result = await fetching(this.getServerUri('/user').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})`
}
});
} catch (ex) {
this._logger.error(ex.message);
throw new Error(NETWORK_ERROR);
}
if (result.ok) {
try {
const json = await result.json();
this._logger.info('Got account info!');
return { id: json.id, accountName: json.login };
} catch (e) {
this._logger.error(`Unexpected error parsing response from GitHub: ${e.message ?? e}`);
throw e;
}
} else {
// either display the response message or the http status text
let errorMessage = result.statusText;
try {
const json = await result.json();
if (json.message) {
errorMessage = json.message;
}
} catch (err) {
// noop
}
this._logger.error(`Getting account info failed: ${errorMessage}`);
throw new Error(errorMessage);
}
}
public async sendAdditionalTelemetryInfo(token: string): Promise<void> {
public async sendAdditionalTelemetryInfo(session: vscode.AuthenticationSession): Promise<void> {
if (!vscode.env.isTelemetryEnabled) {
return;
}
@@ -482,53 +553,75 @@ export class GitHubServer implements IGitHubServer {
return;
}
if (this._type === AuthProviderType.github) {
return await this.checkUserDetails(session);
}
// GHES
await this.checkEnterpriseVersion(session.accessToken);
}
private async checkUserDetails(session: vscode.AuthenticationSession): Promise<void> {
let edu: string | undefined;
try {
const result = await fetch('https://education.github.com/api/user', {
const result = await fetching('https://education.github.com/api/user', {
headers: {
Authorization: `token ${token}`,
Authorization: `token ${session.accessToken}`,
'faculty-check-preview': 'true',
'User-Agent': 'Visual-Studio-Code'
'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})`
}
});
if (result.ok) {
const json: { student: boolean; faculty: boolean } = await result.json();
/* __GDPR__
"session" : {
"owner": "TylerLeonhardt",
"isEdu": { "classification": "NonIdentifiableDemographicInfo", "purpose": "FeatureInsight" }
}
*/
this._telemetryReporter.sendTelemetryEvent('session', {
isEdu: json.student
? 'student'
: json.faculty
? 'faculty'
: 'none'
});
edu = json.student
? 'student'
: json.faculty
? 'faculty'
: 'none';
} else {
edu = 'unknown';
}
} catch (e) {
// No-op
edu = 'unknown';
}
/* __GDPR__
"session" : {
"owner": "TylerLeonhardt",
"isEdu": { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"isManaged": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this._telemetryReporter.sendTelemetryEvent('session', {
isEdu: edu,
// Apparently, this is how you tell if a user is an EMU...
isManaged: session.account.label.includes('_') ? 'true' : 'false'
});
}
public async checkEnterpriseVersion(token: string): Promise<void> {
private async checkEnterpriseVersion(token: string): Promise<void> {
try {
let version: string;
if (!isSupportedTarget(this._type, this._ghesUri)) {
const result = await fetching(this.getServerUri('/meta').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': `${vscode.env.appName} (${vscode.env.appHost})`
}
});
const result = await fetch(this.getServerUri('/meta').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
if (!result.ok) {
return;
}
});
if (!result.ok) {
return;
const json: { verifiable_password_authentication: boolean; installed_version: string } = await result.json();
version = json.installed_version;
} else {
version = 'hosted';
}
const json: { verifiable_password_authentication: boolean; installed_version: string } = await result.json();
/* __GDPR__
"ghe-session" : {
"owner": "TylerLeonhardt",
@@ -536,82 +629,18 @@ export class GitHubServer implements IGitHubServer {
}
*/
this._telemetryReporter.sendTelemetryEvent('ghe-session', {
version: json.installed_version
version
});
} catch {
// No-op
}
}
}
export class GitHubEnterpriseServer implements IGitHubServer {
friendlyName = 'GitHub Enterprise';
type = AuthProviderType.githubEnterprise;
constructor(private readonly _logger: Log, private readonly telemetryReporter: ExperimentationTelemetry) { }
dispose() { }
public async login(scopes: string): Promise<string> {
this._logger.info(`Logging in for the following scopes: ${scopes}`);
const token = await vscode.window.showInputBox({ prompt: 'GitHub Personal Access Token', ignoreFocusOut: true });
if (!token) { throw new Error('Sign in failed: 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;
}
return scope.split(':').some(splitScopes => {
return tokenScopes.includes(splitScopes);
});
})) {
throw new Error(`The provided token does not match the requested scopes: ${scopes}`);
}
return token;
}
private getServerUri(path: string = '') {
const apiUri = vscode.Uri.parse(vscode.workspace.getConfiguration('github-enterprise').get<string>('uri') || '', true);
return vscode.Uri.parse(`${apiUri.scheme}://${apiUri.authority}/api/v3${path}`);
}
public async getUserInfo(token: string): Promise<{ id: string; accountName: string }> {
return getUserInfo(token, this.getServerUri('/user'), this._logger);
}
public async sendAdditionalTelemetryInfo(token: string): Promise<void> {
try {
const result = await fetch(this.getServerUri('/meta').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
}
});
if (!result.ok) {
return;
}
const json: { verifiable_password_authentication: boolean; installed_version: string } = await result.json();
/* __GDPR__
"ghe-session" : {
"owner": "TylerLeonhardt",
"version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('ghe-session', {
version: json.installed_version
});
} catch {
// No-op
private processLoginError(error: Error): boolean {
if (error.message === CANCELLATION_ERROR) {
throw error;
}
this._logger.error(error.message ?? error);
return error.message === USER_CANCELLATION_ERROR;
}
}

View File

@@ -0,0 +1,8 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { webcrypto } from 'crypto';
export const crypto = webcrypto as any as Crypto;

View File

@@ -0,0 +1,7 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import fetch from 'node-fetch';
export const fetching = fetch;

View File

@@ -2,41 +2,167 @@
# yarn lockfile v1
"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7"
integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g==
"@azure/abort-controller@^1.0.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@azure/abort-controller/-/abort-controller-1.1.0.tgz#788ee78457a55af8a1ad342acb182383d2119249"
integrity sha512-TrRLIoSQVzfAJX9H1JeFjzAoDGcoK1IYX1UImfceTZpsyYfWr09Ss1aHW1y5TrrR3iq6RZLBwJ3E24uwPhwahw==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.4"
"@microsoft/applicationinsights-shims" "^2.0.1"
"@microsoft/dynamicproto-js" "^1.1.6"
tslib "^2.2.0"
"@microsoft/1ds-post-js@^3.2.3":
version "3.2.3"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216"
integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ==
"@azure/core-auth@^1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.4.0.tgz#6fa9661c1705857820dbc216df5ba5665ac36a9e"
integrity sha512-HFrcTgmuSuukRf/EdPmqBrc5l6Q5Uu+2TbuhaKbgaCpP2TfAeiNaQPAadxO+CYBRHGUzIDteMAjFspFLDLnKVQ==
dependencies:
"@microsoft/1ds-core-js" "3.2.3"
"@microsoft/applicationinsights-shims" "^2.0.1"
"@microsoft/dynamicproto-js" "^1.1.6"
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@microsoft/applicationinsights-core-js@2.8.4":
version "2.8.4"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596"
integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ==
"@azure/core-rest-pipeline@^1.10.0":
version "1.10.3"
resolved "https://registry.yarnpkg.com/@azure/core-rest-pipeline/-/core-rest-pipeline-1.10.3.tgz#7603afd71ff3c290351dbeeab2c814832e47b8ef"
integrity sha512-AMQb0ttiGJ0MIV/r+4TVra6U4+90mPeOveehFnrqKlo7dknPJYdJ61wOzYJXJjDxF8LcCtSogfRelkq+fCGFTw==
dependencies:
"@microsoft/applicationinsights-shims" "2.0.1"
"@microsoft/dynamicproto-js" "^1.1.6"
"@azure/abort-controller" "^1.0.0"
"@azure/core-auth" "^1.4.0"
"@azure/core-tracing" "^1.0.1"
"@azure/core-util" "^1.3.0"
"@azure/logger" "^1.0.0"
form-data "^4.0.0"
http-proxy-agent "^5.0.0"
https-proxy-agent "^5.0.0"
tslib "^2.2.0"
"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd"
integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ==
"@azure/core-tracing@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.1.tgz#352a38cbea438c4a83c86b314f48017d70ba9503"
integrity sha512-I5CGMoLtX+pI17ZdiFJZgxMJApsK6jjfm85hpgp3oazCdq5Wxgh4wMr7ge/TTWW1B5WBuvIOI1fMU/FrOAMKrw==
dependencies:
tslib "^2.2.0"
"@microsoft/dynamicproto-js@^1.1.6":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc"
integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg==
"@azure/core-util@^1.3.0":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@azure/core-util/-/core-util-1.3.2.tgz#3f8cfda1e87fac0ce84f8c1a42fcd6d2a986632d"
integrity sha512-2bECOUh88RvL1pMZTcc6OzfobBeWDBf5oBbhjIhT1MV9otMVWCzpOJkkiKtrnO88y5GGBelgY8At73KGAdbkeQ==
dependencies:
"@azure/abort-controller" "^1.0.0"
tslib "^2.2.0"
"@azure/logger@^1.0.0":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@azure/logger/-/logger-1.0.4.tgz#28bc6d0e5b3c38ef29296b32d35da4e483593fa1"
integrity sha512-ustrPY8MryhloQj7OWGe+HrYx+aoiOxzbXTtgblbV3xwCqpzUK36phH3XNHQKj3EPonyFUuDTfR3qFhTEAuZEg==
dependencies:
tslib "^2.2.0"
"@microsoft/1ds-core-js@3.2.11", "@microsoft/1ds-core-js@^3.2.8":
version "3.2.11"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.11.tgz#0a3857562a9bde7c15a2fa141c647f40aabd52e2"
integrity sha512-UuqZ1iWjaEFsBsnB+J0Q4IbgJdvJAq3LcNArAdMQQq9+wBWpjyGG4yu9gL6fS5AKfpF6yy73mtgWD7WzvphMLQ==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.13"
"@microsoft/applicationinsights-shims" "^2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/1ds-post-js@^3.2.8":
version "3.2.11"
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.11.tgz#bbfc935bafb43982ccaf94ebd12f1fabf5ef8ebe"
integrity sha512-86prrN8cKjfpqfeyC4k0rFqg7fJDkTwPeKLHnkUgfq9mKVzu+BdtlEzaJtc56MroKWNYPkitZ/PWSwwpTPIgMA==
dependencies:
"@microsoft/1ds-core-js" "3.2.11"
"@microsoft/applicationinsights-shims" "^2.0.2"
"@microsoft/dynamicproto-js" "^1.1.7"
"@microsoft/applicationinsights-channel-js@2.8.13":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-channel-js/-/applicationinsights-channel-js-2.8.13.tgz#bd117cc7b00ec929e74a6555cb7462ab4fccdf62"
integrity sha512-zc2BSsHk4HAqK5STdNzKGV817jKNbiTZPYpNt3zuE+jO5druJgloqrvclUfLnCoa7zwrQ2UxoAXlpJGmroGZPA==
dependencies:
"@microsoft/applicationinsights-common" "2.8.13"
"@microsoft/applicationinsights-core-js" "2.8.13"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.9"
"@microsoft/applicationinsights-common@2.8.13":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-common/-/applicationinsights-common-2.8.13.tgz#e3457bdc54a61cbfa481494da25e55bb9156096e"
integrity sha512-UYLLGVtuzrWUEmGYRroMzLyTi2fHqL6SwJUlmVWPJrmdK43PGpviRix/sBW0Qs+6qjiI1Z6CiG4Xah6w/HylhA==
dependencies:
"@microsoft/applicationinsights-core-js" "2.8.13"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.9"
"@microsoft/applicationinsights-core-js@2.8.13":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.13.tgz#45c2b8fff35e5aa519355dd3a69e3758293b08f4"
integrity sha512-PP7Xjplvy0d5G2Tk7DcSDYRmgDYRv+7n3wEiqgm63DrSoa8rEuoODavjWunhX058zPNIeKbus59NE+DusLLyZg==
dependencies:
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.9"
"@microsoft/applicationinsights-shims@2.0.2", "@microsoft/applicationinsights-shims@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.2.tgz#92b36a09375e2d9cb2b4203383b05772be837085"
integrity sha512-PoHEgsnmcqruLNHZ/amACqdJ6YYQpED0KSRe6J7gIJTtpZC1FfFU9b1fmDKDKtFoUSrPzEh1qzO3kmRZP0betg==
"@microsoft/applicationinsights-web-basic@^2.8.9":
version "2.8.13"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-basic/-/applicationinsights-web-basic-2.8.13.tgz#a3934fa7b7f221d09fbf403fcfeb06a8c18ca246"
integrity sha512-DgPx1ryZucLWc285qkAEBG6LCcTSG6Gdb4u4yAlmAW0G+Qau49GoJnfJGR+cDXvyXSwHcH0dsainqzeYYY1K7A==
dependencies:
"@microsoft/applicationinsights-channel-js" "2.8.13"
"@microsoft/applicationinsights-common" "2.8.13"
"@microsoft/applicationinsights-core-js" "2.8.13"
"@microsoft/applicationinsights-shims" "2.0.2"
"@microsoft/dynamicproto-js" "^1.1.9"
"@microsoft/applicationinsights-web-snippet@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-web-snippet/-/applicationinsights-web-snippet-1.0.1.tgz#6bb788b2902e48bf5d460c38c6bb7fedd686ddd7"
integrity sha512-2IHAOaLauc8qaAitvWS+U931T+ze+7MNWrDHY47IENP5y2UA0vqJDu67kWZDdpCN1fFC77sfgfB+HV7SrKshnQ==
"@microsoft/dynamicproto-js@^1.1.7", "@microsoft/dynamicproto-js@^1.1.9":
version "1.1.9"
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.9.tgz#7437db7aa061162ee94e4131b69a62b8dad5dea6"
integrity sha512-n1VPsljTSkthsAFYdiWfC+DKzK2WwcRp83Y1YAqdX552BstvsDjft9YXppjUzp11BPsapDoO1LDgrDB0XVsfNQ==
"@opentelemetry/api@^1.0.4":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f"
integrity sha512-O2yRJce1GOc6PAy3QxFM4NzFiWzvScDC1/5ihYBL6BUEVdq0XMWN01sppE+H6bBXbaFYipjwFLEWLg5PaSOThA==
"@opentelemetry/core@1.13.0", "@opentelemetry/core@^1.0.1":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.13.0.tgz#7cdcb4176d260d279b0aa31456c4ce2ba7f410aa"
integrity sha512-2dBX3Sj99H96uwJKvc2w9NOiNgbvAO6mOFJFramNkKfS9O4Um+VWgpnlAazoYjT6kUJ1MP70KQ5ngD4ed+4NUw==
dependencies:
"@opentelemetry/semantic-conventions" "1.13.0"
"@opentelemetry/resources@1.13.0":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.13.0.tgz#436b33ea950004e66fce6575f2776a05faca7f8e"
integrity sha512-euqjOkiN6xhjE//0vQYGvbStxoD/WWQRhDiO0OTLlnLBO9Yw2Gd/VoSx2H+svsebjzYk5OxLuREBmcdw6rbUNg==
dependencies:
"@opentelemetry/core" "1.13.0"
"@opentelemetry/semantic-conventions" "1.13.0"
"@opentelemetry/sdk-trace-base@^1.0.1":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.13.0.tgz#096cc2759430d880c5d886e009df2605097403dc"
integrity sha512-moTiQtc0uPR1hQLt6gLDJH9IIkeBhgRb71OKjNHZPE1VF45fHtD6nBDi5J/DkTHTwYP5X3kBJLa3xN7ub6J4eg==
dependencies:
"@opentelemetry/core" "1.13.0"
"@opentelemetry/resources" "1.13.0"
"@opentelemetry/semantic-conventions" "1.13.0"
"@opentelemetry/semantic-conventions@1.13.0", "@opentelemetry/semantic-conventions@^1.0.1":
version "1.13.0"
resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.13.0.tgz#0290398b3eaebc6029c348988a78c3b688fe9219"
integrity sha512-LMGqfSZkaMQXqewO0o1wvWr/2fQdCh4a3Sqlxka/UsJCe0cfLulh6x2aqnKLnsrSGiCq5rSCwvINd152i0nCqw==
"@tootallnate/once@2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
"@types/node-fetch@^2.5.7":
version "2.5.7"
@@ -56,18 +182,54 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
"@types/uuid@8.0.0":
version "8.0.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.0.0.tgz#165aae4819ad2174a17476dbe66feebd549556c0"
integrity sha512-xSQfNcvOiE5f9dyd4Kzxbof1aTrLobL278pGLKOZI6esGfZ7ts9Ka16CzIN6Y8hFHE1C7jIBZokULhK1bOgjRw==
"@vscode/extension-telemetry@0.6.2":
version "0.6.2"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e"
integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w==
"@vscode/extension-telemetry@0.7.5":
version "0.7.5"
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.7.5.tgz#bf965731816e08c3f146f96d901ec67954fc913b"
integrity sha512-fJ5y3TcpqqkFYHneabYaoB4XAhDdVflVm+TDKshw9VOs77jkgNS4UA7LNXrWeO0eDne3Sh3JgURf+xzc1rk69w==
dependencies:
"@microsoft/1ds-core-js" "^3.2.3"
"@microsoft/1ds-post-js" "^3.2.3"
"@microsoft/1ds-core-js" "^3.2.8"
"@microsoft/1ds-post-js" "^3.2.8"
"@microsoft/applicationinsights-web-basic" "^2.8.9"
applicationinsights "2.4.1"
agent-base@6:
version "6.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==
dependencies:
debug "4"
applicationinsights@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-2.4.1.tgz#4de4c4dd3c7c4a44445cfbf3d15808fc0dcc423d"
integrity sha512-0n0Ikd0gzSm460xm+M0UTWIwXrhrH/0bqfZatcJjYObWyefxfAxapGEyNnSGd1Tg90neHz+Yhf+Ff/zgvPiQYA==
dependencies:
"@azure/core-auth" "^1.4.0"
"@azure/core-rest-pipeline" "^1.10.0"
"@microsoft/applicationinsights-web-snippet" "^1.0.1"
"@opentelemetry/api" "^1.0.4"
"@opentelemetry/core" "^1.0.1"
"@opentelemetry/sdk-trace-base" "^1.0.1"
"@opentelemetry/semantic-conventions" "^1.0.1"
cls-hooked "^4.2.2"
continuation-local-storage "^3.2.1"
diagnostic-channel "1.1.0"
diagnostic-channel-publishers "1.0.5"
async-hook-jl@^1.7.6:
version "1.7.6"
resolved "https://registry.yarnpkg.com/async-hook-jl/-/async-hook-jl-1.7.6.tgz#4fd25c2f864dbaf279c610d73bf97b1b28595e68"
integrity sha512-gFaHkFfSxTjvoxDMYqDuGHlcRyUuamF8s+ZTtJdDzqjws4mCt7v0vuV79/E2Wr2/riMQgtG4/yUtXWs1gZ7JMg==
dependencies:
stack-chain "^1.3.7"
async-listener@^0.6.0:
version "0.6.10"
resolved "https://registry.yarnpkg.com/async-listener/-/async-listener-0.6.10.tgz#a7c97abe570ba602d782273c0de60a51e3e17cbc"
integrity sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==
dependencies:
semver "^5.3.0"
shimmer "^1.1.0"
asynckit@^0.4.0:
version "0.4.0"
@@ -81,6 +243,15 @@ axios@^0.26.1:
dependencies:
follow-redirects "^1.14.8"
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
integrity sha512-J4Xj5f5wq/4jAvcdgoGsL3G103BtWpZrMo8NEinRltN+xpTZdI+M38pyQqhuFU/P792xkMFvnKSf+Lm81U1bxw==
dependencies:
async-hook-jl "^1.7.6"
emitter-listener "^1.0.1"
semver "^5.4.1"
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -88,11 +259,45 @@ combined-stream@^1.0.8:
dependencies:
delayed-stream "~1.0.0"
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
integrity sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==
dependencies:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
debug@4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
diagnostic-channel-publishers@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.5.tgz#df8c317086c50f5727fdfb5d2fce214d2e4130ae"
integrity sha512-dJwUS0915pkjjimPJVDnS/QQHsH0aOYhnZsLJdnZIMOrB+csj8RnZhWTuwnm8R5v3Z7OZs+ksv5luC14DGB7eg==
diagnostic-channel@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/diagnostic-channel/-/diagnostic-channel-1.1.0.tgz#6985e9dfedfbc072d91dc4388477e4087147756e"
integrity sha512-fwujyMe1gj6rk6dYi9hMZm0c8Mz8NDMVl2LB4iaYh3+LIAThZC8RKFGXWG0IML2OxAit/ZFRgZhMkhQ3d/bobQ==
dependencies:
semver "^5.3.0"
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
integrity sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==
dependencies:
shimmer "^1.2.0"
follow-redirects@^1.14.8:
version "1.15.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
@@ -107,6 +312,32 @@ form-data@^3.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
http-proxy-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43"
integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==
dependencies:
"@tootallnate/once" "2"
agent-base "6"
debug "4"
https-proxy-agent@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6"
integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==
dependencies:
agent-base "6"
debug "4"
mime-db@1.44.0:
version "1.44.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
@@ -119,6 +350,11 @@ mime-types@^2.1.12:
dependencies:
mime-db "1.44.0"
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
node-fetch@2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
@@ -126,6 +362,21 @@ node-fetch@2.6.7:
dependencies:
whatwg-url "^5.0.0"
semver@^5.3.0, semver@^5.4.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
shimmer@^1.1.0, shimmer@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.1.tgz#610859f7de327b587efebf501fb43117f9aff337"
integrity sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha512-D8cWtWVdIe/jBA7v5p5Hwl5yOSOrmZPWDPe2KxQ5UAGD+nxbxU0lKXA4h85Ta6+qgdKVL3vUxsbIZjc1kBG7ug==
tas-client@0.1.58:
version "0.1.58"
resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.58.tgz#67d66bf0e27df5276ebc751105e6ad47791c36d8"
@@ -138,15 +389,10 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
uuid@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
integrity sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg==
vscode-nls@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840"
integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==
tslib@^2.2.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
vscode-tas-client@^0.1.47:
version "0.1.63"