Merge from vscode 2e5312cd61ff99c570299ecc122c52584265eda2

This commit is contained in:
ADS Merger
2020-04-23 02:50:35 +00:00
committed by Anthony Dresser
parent 3603f55d97
commit 7f1d8fc32f
659 changed files with 22709 additions and 12497 deletions

View File

@@ -7,8 +7,11 @@ import * as vscode from 'vscode';
import { GitHubAuthenticationProvider, onDidChangeSessions } from './github';
import { uriHandler } from './githubServer';
import Logger from './common/logger';
import TelemetryReporter from 'vscode-extension-telemetry';
export async function activate(context: vscode.ExtensionContext) {
const { name, version, aiKey } = require('../package.json') as { name: string, version: string, aiKey: string };
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
const loginService = new GitHubAuthenticationProvider();
@@ -22,19 +25,29 @@ export async function activate(context: vscode.ExtensionContext) {
getSessions: () => Promise.resolve(loginService.sessions),
login: async (scopeList: string[]) => {
try {
const session = await loginService.login(scopeList.join(' '));
telemetryReporter.sendTelemetryEvent('login');
const session = await loginService.login(scopeList.sort().join(' '));
Logger.info('Login success!');
onDidChangeSessions.fire({ added: [session.id], removed: [], changed: [] });
return session;
} catch (e) {
telemetryReporter.sendTelemetryEvent('loginFailed');
vscode.window.showErrorMessage(`Sign in failed: ${e}`);
Logger.error(e);
throw e;
}
},
logout: async (id: string) => {
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
try {
telemetryReporter.sendTelemetryEvent('logout');
await loginService.logout(id);
onDidChangeSessions.fire({ added: [], removed: [id], changed: [] });
} catch (e) {
telemetryReporter.sendTelemetryEvent('logoutFailed');
vscode.window.showErrorMessage(`Sign out failed: ${e}`);
Logger.error(e);
throw e;
}
}
});

View File

@@ -12,12 +12,27 @@ import Logger from './common/logger';
export const onDidChangeSessions = new vscode.EventEmitter<vscode.AuthenticationSessionsChangeEvent>();
interface SessionData {
id: string;
account?: {
displayName: string;
id: string;
}
scopes: string[];
accessToken: string;
}
// TODO remove
interface OldSessionData {
id: string;
accountName: string;
scopes: string[];
accessToken: string;
}
function isOldSessionData(x: any): x is OldSessionData {
return !!x.accountName;
}
export class GitHubAuthenticationProvider {
private _sessions: vscode.AuthenticationSession[] = [];
private _githubServer = new GitHubServer();
@@ -68,15 +83,34 @@ export class GitHubAuthenticationProvider {
const storedSessions = await keychain.getToken();
if (storedSessions) {
try {
const sessionData: SessionData[] = JSON.parse(storedSessions);
return sessionData.map(session => {
return {
id: session.id,
accountName: session.accountName,
scopes: session.scopes,
getAccessToken: () => Promise.resolve(session.accessToken)
};
const sessionData: (SessionData | OldSessionData)[] = JSON.parse(storedSessions);
const sessionPromises = sessionData.map(async (session: SessionData | OldSessionData): Promise<vscode.AuthenticationSession | undefined> => {
try {
const needsUserInfo = isOldSessionData(session) || !session.account;
let userInfo: { id: string, accountName: string };
if (needsUserInfo) {
userInfo = await this._githubServer.getUserInfo(session.accessToken);
}
return {
id: session.id,
account: {
displayName: isOldSessionData(session)
? session.accountName
: session.account?.displayName ?? userInfo!.accountName,
id: isOldSessionData(session)
? userInfo!.id
: session.account?.id ?? userInfo!.id
},
scopes: session.scopes,
getAccessToken: () => Promise.resolve(session.accessToken)
};
} catch (e) {
return undefined;
}
});
return (await Promise.all(sessionPromises)).filter((x: vscode.AuthenticationSession | undefined): x is vscode.AuthenticationSession => !!x);
} catch (e) {
Logger.error(`Error reading sessions: ${e}`);
}
@@ -90,7 +124,7 @@ export class GitHubAuthenticationProvider {
const resolvedAccessToken = await session.getAccessToken();
return {
id: session.id,
accountName: session.accountName,
account: session.account,
scopes: session.scopes,
accessToken: resolvedAccessToken
};
@@ -125,7 +159,10 @@ export class GitHubAuthenticationProvider {
return {
id: uuid(),
getAccessToken: () => Promise.resolve(token),
accountName: userInfo.accountName,
account: {
displayName: userInfo.accountName,
id: userInfo.id
},
scopes: scopes
};
}
@@ -137,7 +174,7 @@ export class GitHubAuthenticationProvider {
this._sessions.push(session);
}
this.storeSessions();
await this.storeSessions();
}
public async logout(id: string) {
@@ -145,9 +182,13 @@ export class GitHubAuthenticationProvider {
if (sessionIndex > -1) {
const session = this._sessions.splice(sessionIndex, 1)[0];
const token = await session.getAccessToken();
await this._githubServer.revokeToken(token);
try {
await this._githubServer.revokeToken(token);
} catch (_) {
// ignore, should still remove from keychain
}
}
this.storeSessions();
await this.storeSessions();
}
}

View File

@@ -145,6 +145,7 @@ export class GitHubServer {
Logger.info('Got account info!');
resolve({ id: json.id, accountName: json.login });
} else {
Logger.error('Getting account info failed');
reject(new Error(result.statusMessage));
}
});
@@ -186,6 +187,7 @@ export class GitHubServer {
Logger.info('Revoked token!');
resolve();
} else {
Logger.info(`Revoking token failed: ${result.statusMessage}`);
reject(new Error(result.statusMessage));
}
});