extensions/github-authentication/src/githubServer.ts/GitHubServer/login
class GitHubServer:	public async login(scopes: string): Promise<string> {
		this._logger.info(`Logging in for the following scopes: ${scopes}`);

		const nonce = uuid();
		const callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/did-authenticate?nonce=${encodeURIComponent(nonce)}`));

		if (!isSupportedEnvironment(callbackUri)) {
			const token = this._supportDeviceCodeFlow
				? await this.doDeviceCodeFlow(scopes)
				: await vscode.window.showInputBox({ prompt: 'GitHub Personal Access Token', ignoreFocusOut: true });

			if (!token) { throw new Error('No token provided'); }

			const tokenScopes = await getScopes(token, this.getServerUri('/'), this._logger); // Example: ['repo', 'user']
			const scopesList = scopes.split(' '); // Example: 'read:user repo user:email'
			if (!scopesList.every(scope => {
				const included = tokenScopes.includes(scope);
				if (included || !scope.includes(':')) {
					return included;
				}

				return scope.split(':').some(splitScopes => {
					return tokenScopes.includes(splitScopes);
				});
			})) {
				throw new Error(`The provided token does not match the requested scopes: ${scopes}`);
			}

			return token;
		}

		const existingNonces = this._pendingNonces.get(scopes) || [];
		this._pendingNonces.set(scopes, [...existingNonces, nonce]);

		const proxyEndpoints: { [providerId: string]: string } | undefined = await vscode.commands.executeCommand('workbench.getCodeExchangeProxyEndpoints');
		// If we are running in insiders vscode.dev, then ensure we use the redirect route on that.
		let redirectUri = REDIRECT_URL_STABLE;
		if (proxyEndpoints?.github && new URL(proxyEndpoints.github).hostname === 'insiders.vscode.dev') {
			redirectUri = REDIRECT_URL_INSIDERS;
		}
		const searchParams = new URLSearchParams([
			['client_id', CLIENT_ID],
			['redirect_uri', redirectUri],
			['scope', scopes],
			['state', encodeURIComponent(callbackUri.toString(true))]
		]);
		const uri = vscode.Uri.parse(`${GITHUB_AUTHORIZE_URL}?${searchParams.toString()}`);

		return vscode.window.withProgress({
			location: vscode.ProgressLocation.Window,
			title: localize('signingIn', " $(mark-github) Signing in to github.com..."),
		}, async () => {
			await vscode.env.openExternal(uri);

			// Register a single listener for the URI callback, in case the user starts the login process multiple times
			// before completing it.
			let codeExchangePromise = this._codeExchangePromises.get(scopes);
			if (!codeExchangePromise) {
				codeExchangePromise = promiseFromEvent(this._uriHandler.event, this.exchangeCodeForToken(scopes));
				this._codeExchangePromises.set(scopes, codeExchangePromise);
			}

			return Promise.race([
				codeExchangePromise.promise,
				promiseFromEvent<string | undefined, string>(this._onDidManuallyProvideToken.event, (token: string | undefined, resolve, reject): void => {
					if (!token) {
						reject('Cancelled');
					} else {
						resolve(token);
					}
				}).promise,
				new Promise<string>((_, reject) => setTimeout(() => reject('Cancelled'), 60000))
			]).finally(() => {
				this._pendingNonces.delete(scopes);
				codeExchangePromise?.cancel.fire();
				this._codeExchangePromises.delete(scopes);
			});
		});
	}