mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Merge from vscode 073a24de05773f2261f89172987002dc0ae2f1cd (#9711)
This commit is contained in:
@@ -96,6 +96,10 @@
|
||||
"fileMatch": "%APP_SETTINGS_HOME%/snippets/*.json",
|
||||
"url": "vscode://schemas/snippets"
|
||||
},
|
||||
{
|
||||
"fileMatch": "%APP_SETTINGS_HOME%/sync/snippets/preview/*.json",
|
||||
"url": "vscode://schemas/snippets"
|
||||
},
|
||||
{
|
||||
"fileMatch": "**/*.code-snippets",
|
||||
"url": "vscode://schemas/global-snippets"
|
||||
|
||||
@@ -2360,7 +2360,13 @@ export class CommandCenter {
|
||||
title = localize('git.title.diffRefs', '{0} ({1}) ⟷ {0} ({2})', basename, item.shortPreviousRef, item.shortRef);
|
||||
}
|
||||
|
||||
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title);
|
||||
const options: TextDocumentShowOptions = {
|
||||
preserveFocus: true,
|
||||
preview: true,
|
||||
viewColumn: ViewColumn.Active
|
||||
};
|
||||
|
||||
return commands.executeCommand('vscode.diff', toGitUri(uri, item.previousRef), item.ref === '' ? uri : toGitUri(uri, item.ref), title, options);
|
||||
}
|
||||
|
||||
@command('git.timeline.copyCommitId', { repository: false })
|
||||
|
||||
@@ -45,7 +45,7 @@ interface MutableRemote extends Remote {
|
||||
isReadOnly: boolean;
|
||||
}
|
||||
|
||||
// TODO[ECA]: Move to git.d.ts once we are good with the api
|
||||
// TODO@eamodio: Move to git.d.ts once we are good with the api
|
||||
/**
|
||||
* Log file options.
|
||||
*/
|
||||
|
||||
@@ -15,7 +15,7 @@ dayjs.extend(advancedFormat);
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
// TODO[ECA]: Localize or use a setting for date format
|
||||
// TODO@eamodio: Localize or use a setting for date format
|
||||
|
||||
export class GitTimelineItem extends TimelineItem {
|
||||
static is(item: TimelineItem): item is GitTimelineItem {
|
||||
@@ -71,21 +71,21 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
readonly id = 'git-history';
|
||||
readonly label = localize('git.timeline.source', 'Git History');
|
||||
|
||||
private _disposable: Disposable;
|
||||
private disposable: Disposable;
|
||||
|
||||
private _repo: Repository | undefined;
|
||||
private _repoDisposable: Disposable | undefined;
|
||||
private _repoStatusDate: Date | undefined;
|
||||
private repo: Repository | undefined;
|
||||
private repoDisposable: Disposable | undefined;
|
||||
private repoStatusDate: Date | undefined;
|
||||
|
||||
constructor(private readonly _model: Model) {
|
||||
this._disposable = Disposable.from(
|
||||
this.disposable = Disposable.from(
|
||||
_model.onDidOpenRepository(this.onRepositoriesChanged, this),
|
||||
workspace.registerTimelineProvider(['file', 'git', 'gitlens-git'], this),
|
||||
);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
this._disposable.dispose();
|
||||
this.disposable.dispose();
|
||||
}
|
||||
|
||||
async provideTimeline(uri: Uri, options: TimelineOptions, _token: CancellationToken): Promise<Timeline> {
|
||||
@@ -93,33 +93,33 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
|
||||
const repo = this._model.getRepository(uri);
|
||||
if (!repo) {
|
||||
this._repoDisposable?.dispose();
|
||||
this._repoStatusDate = undefined;
|
||||
this._repo = undefined;
|
||||
this.repoDisposable?.dispose();
|
||||
this.repoStatusDate = undefined;
|
||||
this.repo = undefined;
|
||||
|
||||
return { items: [] };
|
||||
}
|
||||
|
||||
if (this._repo?.root !== repo.root) {
|
||||
this._repoDisposable?.dispose();
|
||||
if (this.repo?.root !== repo.root) {
|
||||
this.repoDisposable?.dispose();
|
||||
|
||||
this._repo = repo;
|
||||
this._repoStatusDate = new Date();
|
||||
this._repoDisposable = Disposable.from(
|
||||
this.repo = repo;
|
||||
this.repoStatusDate = new Date();
|
||||
this.repoDisposable = Disposable.from(
|
||||
repo.onDidChangeRepository(uri => this.onRepositoryChanged(repo, uri)),
|
||||
repo.onDidRunGitStatus(() => this.onRepositoryStatusChanged(repo))
|
||||
);
|
||||
}
|
||||
|
||||
// TODO[ECA]: Ensure that the uri is a file -- if not we could get the history of the repo?
|
||||
// TODO@eamodio: Ensure that the uri is a file -- if not we could get the history of the repo?
|
||||
|
||||
let limit: number | undefined;
|
||||
if (options.limit !== undefined && typeof options.limit !== 'number') {
|
||||
try {
|
||||
const result = await this._model.git.exec(repo.root, ['rev-list', '--count', `${options.limit.cursor}..`, '--', uri.fsPath]);
|
||||
const result = await this._model.git.exec(repo.root, ['rev-list', '--count', `${options.limit.id}..`, '--', uri.fsPath]);
|
||||
if (!result.exitCode) {
|
||||
// Ask for 1 more than so we can determine if there are more commits
|
||||
limit = Number(result.stdout) + 1;
|
||||
// Ask for 2 more (1 for the limit commit and 1 for the next commit) than so we can determine if there are more commits
|
||||
limit = Number(result.stdout) + 2;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
@@ -130,21 +130,14 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
limit = options.limit === undefined ? undefined : options.limit + 1;
|
||||
}
|
||||
|
||||
|
||||
const commits = await repo.logFile(uri, {
|
||||
maxEntries: limit,
|
||||
hash: options.cursor,
|
||||
reverse: options.before,
|
||||
// sortByAuthorDate: true
|
||||
});
|
||||
|
||||
const more = limit === undefined || options.before ? false : commits.length >= limit;
|
||||
const paging = commits.length ? {
|
||||
more: more,
|
||||
cursors: {
|
||||
before: commits[0]?.hash,
|
||||
after: commits[commits.length - (more ? 1 : 2)]?.hash
|
||||
}
|
||||
cursor: limit === undefined ? undefined : (commits.length >= limit ? commits[commits.length - 1]?.hash : undefined)
|
||||
} : undefined;
|
||||
|
||||
// If we asked for an extra commit, strip it off
|
||||
@@ -153,12 +146,12 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
}
|
||||
|
||||
let dateFormatter: dayjs.Dayjs;
|
||||
const items = commits.map<GitTimelineItem>(c => {
|
||||
const items = commits.map<GitTimelineItem>((c, i) => {
|
||||
const date = c.commitDate; // c.authorDate
|
||||
|
||||
dateFormatter = dayjs(date);
|
||||
|
||||
const item = new GitTimelineItem(c.hash, `${c.hash}^`, c.message, date?.getTime() ?? 0, c.hash, 'git:file:commit');
|
||||
const item = new GitTimelineItem(c.hash, commits[i + 1]?.hash ?? `${c.hash}^`, c.message, date?.getTime() ?? 0, c.hash, 'git:file:commit');
|
||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||
item.description = c.authorName;
|
||||
item.detail = `${c.authorName} (${c.authorEmail}) \u2014 ${c.hash.substr(0, 8)}\n${dateFormatter.format('MMMM Do, YYYY h:mma')}\n\n${c.message}`;
|
||||
@@ -171,16 +164,16 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
return item;
|
||||
});
|
||||
|
||||
if (options.cursor === undefined || options.before) {
|
||||
if (options.cursor === undefined) {
|
||||
const you = localize('git.timeline.you', 'You');
|
||||
|
||||
const index = repo.indexGroup.resourceStates.find(r => r.resourceUri.fsPath === uri.fsPath);
|
||||
if (index) {
|
||||
const date = this._repoStatusDate ?? new Date();
|
||||
const date = this.repoStatusDate ?? new Date();
|
||||
dateFormatter = dayjs(date);
|
||||
|
||||
const item = new GitTimelineItem('~', 'HEAD', localize('git.timeline.stagedChanges', 'Staged Changes'), date.getTime(), 'index', 'git:file:index');
|
||||
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
||||
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
|
||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||
item.description = '';
|
||||
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.index', 'Index'), dateFormatter.format('MMMM Do, YYYY h:mma'), Resource.getStatusText(index.type));
|
||||
@@ -199,7 +192,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
dateFormatter = dayjs(date);
|
||||
|
||||
const item = new GitTimelineItem('', index ? '~' : 'HEAD', localize('git.timeline.uncommitedChanges', 'Uncommited Changes'), date.getTime(), 'working', 'git:file:working');
|
||||
// TODO[ECA]: Replace with a better icon -- reflecting its status maybe?
|
||||
// TODO@eamodio: Replace with a better icon -- reflecting its status maybe?
|
||||
item.iconPath = new (ThemeIcon as any)('git-commit');
|
||||
item.description = '';
|
||||
item.detail = localize('git.timeline.detail', '{0} \u2014 {1}\n{2}\n\n{3}', you, localize('git.workingTree', 'Working Tree'), dateFormatter.format('MMMM Do, YYYY h:mma'), Resource.getStatusText(working.type));
|
||||
@@ -222,7 +215,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
private onRepositoriesChanged(_repo: Repository) {
|
||||
// console.log(`GitTimelineProvider.onRepositoriesChanged`);
|
||||
|
||||
// TODO[ECA]: Being naive for now and just always refreshing each time there is a new repository
|
||||
// TODO@eamodio: Being naive for now and just always refreshing each time there is a new repository
|
||||
this.fireChanged();
|
||||
}
|
||||
|
||||
@@ -236,7 +229,7 @@ export class GitTimelineProvider implements TimelineProvider {
|
||||
// console.log(`GitTimelineProvider.onRepositoryStatusChanged`);
|
||||
|
||||
// This is crappy, but for now just save the last time a status was run and use that as the timestamp for staged items
|
||||
this._repoStatusDate = new Date();
|
||||
this.repoStatusDate = new Date();
|
||||
|
||||
this.fireChanged();
|
||||
}
|
||||
|
||||
@@ -20,7 +20,16 @@ function main() {
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(path.join(__dirname, '../src/common/config.json'), JSON.stringify(content));
|
||||
const githubAppId = process.env.GITHUB_APP_ID;
|
||||
const githubAppSecret = process.env.GITHUB_APP_SECRET;
|
||||
|
||||
if (githubAppId && githubAppSecret) {
|
||||
content.GITHUB_APP = { id: githubAppId, secret: githubAppSecret }
|
||||
}
|
||||
|
||||
if (Object.keys(content).length > 0) {
|
||||
fs.writeFileSync(path.join(__dirname, '../src/common/config.json'), JSON.stringify(content));
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri } from 'vscode';
|
||||
import { Uri, env } from 'vscode';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
export interface ClientDetails {
|
||||
id?: string;
|
||||
@@ -19,6 +21,8 @@ export interface ClientConfig {
|
||||
VSO: ClientDetails;
|
||||
VSO_PPE: ClientDetails;
|
||||
VSO_DEV: ClientDetails;
|
||||
|
||||
GITHUB_APP: ClientDetails;
|
||||
}
|
||||
|
||||
export class Registrar {
|
||||
@@ -26,7 +30,8 @@ export class Registrar {
|
||||
|
||||
constructor() {
|
||||
try {
|
||||
this._config = require('./config.json') as ClientConfig;
|
||||
const fileContents = fs.readFileSync(path.join(env.appRoot, 'extensions/github-authentication/src/common/config.json')).toString();
|
||||
this._config = JSON.parse(fileContents);
|
||||
} catch (e) {
|
||||
this._config = {
|
||||
OSS: {},
|
||||
@@ -35,10 +40,20 @@ export class Registrar {
|
||||
EXPLORATION: {},
|
||||
VSO: {},
|
||||
VSO_PPE: {},
|
||||
VSO_DEV: {}
|
||||
VSO_DEV: {},
|
||||
GITHUB_APP: {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
getGitHubAppDetails(): ClientDetails {
|
||||
if (!this._config.GITHUB_APP.id || !this._config.GITHUB_APP.secret) {
|
||||
throw new Error(`No GitHub App client configuration available`);
|
||||
}
|
||||
|
||||
return this._config.GITHUB_APP;
|
||||
}
|
||||
|
||||
getClientDetails(callbackUri: Uri): ClientDetails {
|
||||
let details: ClientDetails | undefined;
|
||||
switch (callbackUri.scheme) {
|
||||
|
||||
@@ -20,9 +20,9 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
displayName: 'GitHub',
|
||||
onDidChangeSessions: onDidChangeSessions.event,
|
||||
getSessions: () => Promise.resolve(loginService.sessions),
|
||||
login: async (scopes: string[]) => {
|
||||
login: async (scopeList: string[]) => {
|
||||
try {
|
||||
const session = await loginService.login(scopes.join(' '));
|
||||
const session = await loginService.login(scopeList.join(' '));
|
||||
Logger.info('Login success!');
|
||||
return session;
|
||||
} catch (e) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import { keychain } from './common/keychain';
|
||||
import { GitHubServer } from './githubServer';
|
||||
import Logger from './common/logger';
|
||||
|
||||
export const onDidChangeSessions = new vscode.EventEmitter<void>();
|
||||
export const onDidChangeSessions = new vscode.EventEmitter<vscode.AuthenticationSessionsChangeEvent>();
|
||||
|
||||
interface SessionData {
|
||||
id: string;
|
||||
@@ -29,14 +29,16 @@ export class GitHubAuthenticationProvider {
|
||||
private pollForChange() {
|
||||
setTimeout(async () => {
|
||||
const storedSessions = await this.readSessions();
|
||||
let didChange = false;
|
||||
|
||||
const added: string[] = [];
|
||||
const removed: string[] = [];
|
||||
|
||||
storedSessions.forEach(session => {
|
||||
const matchesExisting = this._sessions.some(s => s.id === session.id);
|
||||
// Another window added a session to the keychain, add it to our state as well
|
||||
if (!matchesExisting) {
|
||||
this._sessions.push(session);
|
||||
didChange = true;
|
||||
added.push(session.id);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -49,12 +51,12 @@ export class GitHubAuthenticationProvider {
|
||||
this._sessions.splice(sessionIndex, 1);
|
||||
}
|
||||
|
||||
didChange = true;
|
||||
removed.push(session.id);
|
||||
}
|
||||
});
|
||||
|
||||
if (didChange) {
|
||||
onDidChangeSessions.fire();
|
||||
if (added.length || removed.length) {
|
||||
onDidChangeSessions.fire({ added, removed, changed: [] });
|
||||
}
|
||||
|
||||
this.pollForChange();
|
||||
@@ -101,12 +103,22 @@ export class GitHubAuthenticationProvider {
|
||||
}
|
||||
|
||||
public async login(scopes: string): Promise<vscode.AuthenticationSession> {
|
||||
const token = await this._githubServer.login(scopes);
|
||||
const token = scopes === 'vso' ? await this.loginAndInstallApp(scopes) : await this._githubServer.login(scopes);
|
||||
const session = await this.tokenToSession(token, scopes.split(' '));
|
||||
await this.setToken(session);
|
||||
return session;
|
||||
}
|
||||
|
||||
public async loginAndInstallApp(scopes: string): Promise<string> {
|
||||
const token = await this._githubServer.login(scopes);
|
||||
const hasUserInstallation = await this._githubServer.hasUserInstallation(token);
|
||||
if (hasUserInstallation) {
|
||||
return token;
|
||||
} else {
|
||||
return this._githubServer.installApp();
|
||||
}
|
||||
}
|
||||
|
||||
private async tokenToSession(token: string, scopes: string[]): Promise<vscode.AuthenticationSession> {
|
||||
const userInfo = await this._githubServer.getUserInfo(token);
|
||||
return {
|
||||
|
||||
@@ -71,13 +71,58 @@ export class GitHubServer {
|
||||
Logger.info('Logging in...');
|
||||
const state = uuid();
|
||||
const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/did-authenticate`));
|
||||
const clientDetails = ClientRegistrar.getClientDetails(callbackUri);
|
||||
const clientDetails = scopes === 'vso' ? ClientRegistrar.getGitHubAppDetails() : ClientRegistrar.getClientDetails(callbackUri);
|
||||
const uri = vscode.Uri.parse(`https://github.com/login/oauth/authorize?redirect_uri=${encodeURIComponent(callbackUri.toString())}&scope=${scopes}&state=${state}&client_id=${clientDetails.id}`);
|
||||
|
||||
vscode.env.openExternal(uri);
|
||||
return promiseFromEvent(uriHandler.event, exchangeCodeForToken(state, clientDetails));
|
||||
}
|
||||
|
||||
public async hasUserInstallation(token: string): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
Logger.info('Getting user installations...');
|
||||
const post = https.request({
|
||||
host: 'api.github.com',
|
||||
path: `/user/installations`,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
Accept: 'application/vnd.github.machine-man-preview+json',
|
||||
Authorization: `token ${token}`,
|
||||
'User-Agent': 'Visual-Studio-Code'
|
||||
}
|
||||
}, result => {
|
||||
const buffer: Buffer[] = [];
|
||||
result.on('data', (chunk: Buffer) => {
|
||||
buffer.push(chunk);
|
||||
});
|
||||
result.on('end', () => {
|
||||
if (result.statusCode === 200) {
|
||||
const json = JSON.parse(Buffer.concat(buffer).toString());
|
||||
Logger.info('Got installation info!');
|
||||
const hasInstallation = json.installations.some((installation: { app_slug: string }) => installation.app_slug === 'microsoft-visual-studio-code');
|
||||
resolve(hasInstallation);
|
||||
} else {
|
||||
reject(new Error(result.statusMessage));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
post.end();
|
||||
post.on('error', err => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public async installApp(): Promise<string> {
|
||||
const clientDetails = ClientRegistrar.getGitHubAppDetails();
|
||||
const state = uuid();
|
||||
const uri = vscode.Uri.parse(`https://github.com/apps/microsoft-visual-studio-code/installations/new?state=${state}`);
|
||||
|
||||
vscode.env.openExternal(uri);
|
||||
return promiseFromEvent(uriHandler.event, exchangeCodeForToken(state, clientDetails));
|
||||
}
|
||||
|
||||
public async getUserInfo(token: string): Promise<{ id: string, accountName: string }> {
|
||||
return new Promise((resolve, reject) => {
|
||||
Logger.info('Getting account info...');
|
||||
|
||||
@@ -27,8 +27,8 @@ export class PreviewManager implements vscode.CustomEditorProvider {
|
||||
private readonly zoomStatusBarEntry: ZoomStatusBarEntry,
|
||||
) { }
|
||||
|
||||
public async resolveCustomDocument(_document: vscode.CustomDocument): Promise<void> {
|
||||
// noop
|
||||
public async openCustomDocument(uri: vscode.Uri) {
|
||||
return new vscode.CustomDocument(PreviewManager.viewType, uri);
|
||||
}
|
||||
|
||||
public async resolveCustomEditor(
|
||||
|
||||
@@ -63,6 +63,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
|
||||
private _activePreview: DynamicMarkdownPreview | undefined = undefined;
|
||||
|
||||
private readonly customEditorViewType = 'vscode.markdown.preview.editor';
|
||||
|
||||
public constructor(
|
||||
private readonly _contentProvider: MarkdownContentProvider,
|
||||
private readonly _logger: Logger,
|
||||
@@ -70,7 +72,7 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
) {
|
||||
super();
|
||||
this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this));
|
||||
this._register(vscode.window.registerCustomEditorProvider('vscode.markdown.preview.editor', this));
|
||||
this._register(vscode.window.registerCustomEditorProvider(this.customEditorViewType, this));
|
||||
}
|
||||
|
||||
public refresh() {
|
||||
@@ -148,8 +150,8 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
|
||||
this.registerDynamicPreview(preview);
|
||||
}
|
||||
|
||||
public async resolveCustomDocument(_document: vscode.CustomDocument): Promise<void> {
|
||||
// noop
|
||||
public async openCustomDocument(uri: vscode.Uri) {
|
||||
return new vscode.CustomDocument(this.customEditorViewType, uri);
|
||||
}
|
||||
|
||||
public async resolveCustomTextEditor(
|
||||
|
||||
@@ -48,12 +48,12 @@ export function loadDefaultTelemetryReporter(): TelemetryReporter {
|
||||
}
|
||||
|
||||
function getPackageInfo(): IPackageInfo | null {
|
||||
const extention = vscode.extensions.getExtension('Microsoft.vscode-markdown');
|
||||
if (extention && extention.packageJSON) {
|
||||
const extension = vscode.extensions.getExtension('Microsoft.vscode-markdown');
|
||||
if (extension && extension.packageJSON) {
|
||||
return {
|
||||
name: extention.packageJSON.name,
|
||||
version: extention.packageJSON.version,
|
||||
aiKey: extention.packageJSON.aiKey
|
||||
name: extension.packageJSON.name,
|
||||
version: extension.packageJSON.version,
|
||||
aiKey: extension.packageJSON.aiKey
|
||||
};
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -54,7 +54,7 @@ function parseQuery(uri: vscode.Uri) {
|
||||
}, {});
|
||||
}
|
||||
|
||||
export const onDidChangeSessions = new vscode.EventEmitter<void>();
|
||||
export const onDidChangeSessions = new vscode.EventEmitter<vscode.AuthenticationSessionsChangeEvent>();
|
||||
|
||||
export const REFRESH_NETWORK_FAILURE = 'Network failure';
|
||||
|
||||
@@ -129,7 +129,8 @@ export class AzureActiveDirectoryService {
|
||||
|
||||
private pollForChange() {
|
||||
setTimeout(async () => {
|
||||
let didChange = false;
|
||||
const addedIds: string[] = [];
|
||||
let removedIds: string[] = [];
|
||||
const storedData = await keychain.getToken();
|
||||
if (storedData) {
|
||||
try {
|
||||
@@ -139,7 +140,7 @@ export class AzureActiveDirectoryService {
|
||||
if (!matchesExisting) {
|
||||
try {
|
||||
await this.refreshToken(session.refreshToken, session.scope);
|
||||
didChange = true;
|
||||
addedIds.push(session.id);
|
||||
} catch (e) {
|
||||
if (e.message === REFRESH_NETWORK_FAILURE) {
|
||||
// Ignore, will automatically retry on next poll.
|
||||
@@ -154,7 +155,7 @@ export class AzureActiveDirectoryService {
|
||||
const matchesExisting = sessions.some(session => token.scope === session.scope && token.sessionId === session.id);
|
||||
if (!matchesExisting) {
|
||||
await this.logout(token.sessionId);
|
||||
didChange = true;
|
||||
removedIds.push(token.sessionId);
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -162,19 +163,19 @@ export class AzureActiveDirectoryService {
|
||||
} catch (e) {
|
||||
Logger.error(e.message);
|
||||
// if data is improperly formatted, remove all of it and send change event
|
||||
removedIds = this._tokens.map(token => token.sessionId);
|
||||
this.clearSessions();
|
||||
didChange = true;
|
||||
}
|
||||
} else {
|
||||
if (this._tokens.length) {
|
||||
// Log out all
|
||||
removedIds = this._tokens.map(token => token.sessionId);
|
||||
await this.clearSessions();
|
||||
didChange = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (didChange) {
|
||||
onDidChangeSessions.fire();
|
||||
if (addedIds.length || removedIds.length) {
|
||||
onDidChangeSessions.fire({ added: addedIds, removed: removedIds, changed: [] });
|
||||
}
|
||||
|
||||
this.pollForChange();
|
||||
@@ -377,7 +378,7 @@ export class AzureActiveDirectoryService {
|
||||
this._refreshTimeouts.set(token.sessionId, setTimeout(async () => {
|
||||
try {
|
||||
await this.refreshToken(token.refreshToken, scope);
|
||||
onDidChangeSessions.fire();
|
||||
onDidChangeSessions.fire({ added: [], removed: [], changed: [token.sessionId] });
|
||||
} catch (e) {
|
||||
if (e.message === REFRESH_NETWORK_FAILURE) {
|
||||
const didSucceedOnRetry = await this.handleRefreshNetworkError(token.sessionId, token.refreshToken, scope);
|
||||
@@ -386,7 +387,7 @@ export class AzureActiveDirectoryService {
|
||||
}
|
||||
} else {
|
||||
await this.logout(token.sessionId);
|
||||
onDidChangeSessions.fire();
|
||||
onDidChangeSessions.fire({ added: [], removed: [token.sessionId], changed: [] });
|
||||
}
|
||||
}
|
||||
}, 1000 * (parseInt(token.expiresIn) - 30)));
|
||||
@@ -548,9 +549,8 @@ export class AzureActiveDirectoryService {
|
||||
const token = this._tokens.find(token => token.sessionId === sessionId);
|
||||
if (token) {
|
||||
token.accessToken = undefined;
|
||||
onDidChangeSessions.fire({ added: [], removed: [], changed: [token.sessionId] });
|
||||
}
|
||||
|
||||
onDidChangeSessions.fire();
|
||||
}
|
||||
|
||||
const delayBeforeRetry = 5 * attempts * attempts;
|
||||
|
||||
@@ -25,13 +25,17 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
login: async (scopes: string[]) => {
|
||||
try {
|
||||
await loginService.login(scopes.sort().join(' '));
|
||||
const session = loginService.sessions[loginService.sessions.length - 1];
|
||||
onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] });
|
||||
return loginService.sessions[0]!;
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
},
|
||||
logout: async (id: string) => {
|
||||
return loginService.logout(id);
|
||||
await loginService.logout(id);
|
||||
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
|
||||
vscode.window.showInformationMessage(localize('signedOut', "Successfully signed out."));
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -46,8 +50,9 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
}
|
||||
|
||||
if (sessions.length === 1) {
|
||||
await loginService.logout(loginService.sessions[0].id);
|
||||
onDidChangeSessions.fire();
|
||||
const id = loginService.sessions[0].id;
|
||||
await loginService.logout(id);
|
||||
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
|
||||
vscode.window.showInformationMessage(localize('signedOut', "Successfully signed out."));
|
||||
return;
|
||||
}
|
||||
@@ -61,7 +66,7 @@ export async function activate(context: vscode.ExtensionContext) {
|
||||
|
||||
if (selectedSession) {
|
||||
await loginService.logout(selectedSession.id);
|
||||
onDidChangeSessions.fire();
|
||||
onDidChangeSessions.fire({ added: [], removed: [selectedSession.id], changed: [] });
|
||||
vscode.window.showInformationMessage(localize('signedOut', "Successfully signed out."));
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user