extensions/microsoft-authentication/src/AADHelper.ts/AzureActiveDirectoryService/createSessionWithoutLocalServer
class AzureActiveDirectoryService:	private async createSessionWithoutLocalServer(scopeData: IScopeData): Promise<vscode.AuthenticationSession> {
		let callbackUri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.microsoft-authentication`));
		const nonce = randomBytes(16).toString('base64');
		const callbackQuery = new URLSearchParams(callbackUri.query);
		callbackQuery.set('nonce', encodeURIComponent(nonce));
		callbackUri = callbackUri.with({
			query: callbackQuery.toString()
		});
		const state = encodeURIComponent(callbackUri.toString(true));
		const codeVerifier = toBase64UrlEncoding(randomBytes(32).toString('base64'));
		const codeChallenge = toBase64UrlEncoding(await sha256(codeVerifier));
		const signInUrl = `${loginEndpointUrl}${scopeData.tenant}/oauth2/v2.0/authorize`;
		const oauthStartQuery = new URLSearchParams({
			response_type: 'code',
			client_id: encodeURIComponent(scopeData.clientId),
			response_mode: 'query',
			redirect_uri: redirectUrl,
			state,
			scope: scopeData.scopesToSend,
			prompt: 'select_account',
			code_challenge_method: 'S256',
			code_challenge: codeChallenge,
		});
		const uri = vscode.Uri.parse(`${signInUrl}?${oauthStartQuery.toString()}`);
		vscode.env.openExternal(uri);

		const timeoutPromise = new Promise((_: (value: vscode.AuthenticationSession) => void, reject) => {
			const wait = setTimeout(() => {
				clearTimeout(wait);
				reject('Login timed out.');
			}, 1000 * 60 * 5);
		});

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

		// Register a single listener for the URI callback, in case the user starts the login process multiple times
		// before completing it.
		let existingPromise = this._codeExchangePromises.get(scopeData.scopeStr);
		if (!existingPromise) {
			existingPromise = this.handleCodeResponse(scopeData);
			this._codeExchangePromises.set(scopeData.scopeStr, existingPromise);
		}

		this._codeVerfifiers.set(nonce, codeVerifier);

		return Promise.race([existingPromise, timeoutPromise])
			.finally(() => {
				this._pendingNonces.delete(scopeData.scopeStr);
				this._codeExchangePromises.delete(scopeData.scopeStr);
				this._codeVerfifiers.delete(nonce);
			});
	}