Skip to content

Commit

Permalink
Proxy auth dialog shown on hidden window (fix #109667)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpasero committed Oct 29, 2020
1 parent ffed43d commit 7690417
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 31 deletions.
21 changes: 11 additions & 10 deletions src/vs/code/electron-main/auth2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ interface ElectronAuthenticationResponseDetails extends AuthenticationResponseDe

type LoginEvent = {
event: ElectronEvent;
webContents: WebContents;
authInfo: AuthInfo;
req: ElectronAuthenticationResponseDetails;

Expand Down Expand Up @@ -80,7 +79,7 @@ export class ProxyAuthHandler2 extends Disposable {
this._register(onLogin(this.onLogin, this));
}

private async onLogin({ event, webContents, authInfo, req, callback }: LoginEvent): Promise<void> {
private async onLogin({ event, authInfo, req, callback }: LoginEvent): Promise<void> {
if (!authInfo.isProxy) {
return; // only for proxy
}
Expand All @@ -99,7 +98,7 @@ export class ProxyAuthHandler2 extends Disposable {
if (!this.pendingProxyResolve) {
this.logService.trace('auth#onLogin (proxy) - no pending proxy handling found, starting new');

this.pendingProxyResolve = this.resolveProxyCredentials(webContents, authInfo);
this.pendingProxyResolve = this.resolveProxyCredentials(authInfo);
try {
credentials = await this.pendingProxyResolve;
} finally {
Expand All @@ -121,11 +120,11 @@ export class ProxyAuthHandler2 extends Disposable {
callback(credentials?.username, credentials?.password);
}

private async resolveProxyCredentials(webContents: WebContents, authInfo: AuthInfo): Promise<Credentials | undefined> {
private async resolveProxyCredentials(authInfo: AuthInfo): Promise<Credentials | undefined> {
this.logService.trace('auth#resolveProxyCredentials (proxy) - enter');

try {
const credentials = await this.doResolveProxyCredentials(webContents, authInfo);
const credentials = await this.doResolveProxyCredentials(authInfo);
if (credentials) {
this.logService.trace('auth#resolveProxyCredentials (proxy) - got credentials');

Expand All @@ -140,7 +139,7 @@ export class ProxyAuthHandler2 extends Disposable {
return undefined;
}

private async doResolveProxyCredentials(webContents: WebContents, authInfo: AuthInfo): Promise<Credentials | undefined> {
private async doResolveProxyCredentials(authInfo: AuthInfo): Promise<Credentials | undefined> {
this.logService.trace('auth#doResolveProxyCredentials - enter', authInfo);

// Compute a hash over the authentication info to be used
Expand Down Expand Up @@ -174,8 +173,10 @@ export class ProxyAuthHandler2 extends Disposable {
return { username: storedUsername, password: storedPassword };
}

// Find suitable window to show dialog
const window = this.windowsMainService.getWindowByWebContents(webContents) || this.windowsMainService.getLastActiveWindow();
// Find suitable window to show dialog: prefer to show it in the
// active window because any other network request will wait on
// the credentials and we want the user to present the dialog.
const window = this.windowsMainService.getFocusedWindow() || this.windowsMainService.getLastActiveWindow();
if (!window) {
this.logService.trace('auth#doResolveProxyCredentials (proxy) - exit - no opened window found to show dialog in');

Expand All @@ -199,7 +200,7 @@ export class ProxyAuthHandler2 extends Disposable {
const proxyAuthResponseHandler = async (event: ElectronEvent, channel: string, reply: Credentials & { remember: boolean } | undefined /* canceled */) => {
if (channel === payload.replyChannel) {
this.logService.trace(`auth#doResolveProxyCredentials - exit - received credentials from window ${window.id}`);
webContents.off('ipc-message', proxyAuthResponseHandler);
window.win.webContents.off('ipc-message', proxyAuthResponseHandler);

// We got credentials from the window
if (reply) {
Expand Down Expand Up @@ -227,7 +228,7 @@ export class ProxyAuthHandler2 extends Disposable {
}
};

webContents.on('ipc-message', proxyAuthResponseHandler);
window.win.webContents.on('ipc-message', proxyAuthResponseHandler);
});

// Remember credentials for the session in case
Expand Down
4 changes: 2 additions & 2 deletions src/vs/platform/windows/electron-main/windows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { IProcessEnvironment } from 'vs/base/common/platform';
import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { ISerializableCommandAction } from 'vs/platform/actions/common/actions';
import { URI } from 'vs/base/common/uri';
import { Rectangle, BrowserWindow, WebContents } from 'electron';
import { Rectangle, BrowserWindow } from 'electron';
import { IDisposable } from 'vs/base/common/lifecycle';

export interface IWindowState {
Expand Down Expand Up @@ -109,10 +109,10 @@ export interface IWindowsMainService {
sendToFocused(channel: string, ...args: any[]): void;
sendToAll(channel: string, payload?: any, windowIdsToIgnore?: number[]): void;

getFocusedWindow(): ICodeWindow | undefined;
getLastActiveWindow(): ICodeWindow | undefined;

getWindowById(windowId: number): ICodeWindow | undefined;
getWindowByWebContents(webContents: WebContents): ICodeWindow | undefined;
getWindows(): ICodeWindow[];
getWindowCount(): number;
}
Expand Down
29 changes: 10 additions & 19 deletions src/vs/platform/windows/electron-main/windowsMainService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/e
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
import { IStateService } from 'vs/platform/state/node/state';
import { CodeWindow, defaultWindowState } from 'vs/code/electron-main/window';
import { screen, BrowserWindow, MessageBoxOptions, Display, app, WebContents } from 'electron';
import { screen, BrowserWindow, MessageBoxOptions, Display, app } from 'electron';
import { ILifecycleMainService, UnloadReason, LifecycleMainService, LifecycleMainPhase } from 'vs/platform/lifecycle/electron-main/lifecycleMainService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ILogService } from 'vs/platform/log/common/log';
Expand Down Expand Up @@ -1638,6 +1638,15 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
this._onWindowsCountChanged.fire({ oldCount: WindowsMainService.WINDOWS.length + 1, newCount: WindowsMainService.WINDOWS.length });
}

getFocusedWindow(): ICodeWindow | undefined {
const win = BrowserWindow.getFocusedWindow();
if (win) {
return this.getWindowById(win.id);
}

return undefined;
}

getLastActiveWindow(): ICodeWindow | undefined {
return getLastActiveWindow(WindowsMainService.WINDOWS);
}
Expand All @@ -1664,30 +1673,12 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
}
}

private getFocusedWindow(): ICodeWindow | undefined {
const win = BrowserWindow.getFocusedWindow();
if (win) {
return this.getWindowById(win.id);
}

return undefined;
}

getWindowById(windowId: number): ICodeWindow | undefined {
const res = WindowsMainService.WINDOWS.filter(window => window.id === windowId);

return arrays.firstOrDefault(res);
}

getWindowByWebContents(webContents: WebContents): ICodeWindow | undefined {
const win = BrowserWindow.fromWebContents(webContents);
if (win) {
return this.getWindowById(win.id);
}

return undefined;
}

getWindows(): ICodeWindow[] {
return WindowsMainService.WINDOWS;
}
Expand Down

0 comments on commit 7690417

Please sign in to comment.