From 82f7fa7545e9eb56f2e9fa803837cd40bcd3a9fe Mon Sep 17 00:00:00 2001 From: eshmeshek Date: Sat, 16 May 2026 22:31:37 +0300 Subject: [PATCH] =?UTF-8?q?fix(1.0.9):=20revert=20OAuth=20popup=20BrowserW?= =?UTF-8?q?indow=20=E2=80=94=20Google=20detects=20embedded=20popups?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.0.1 ("trusted-domains OAuth popups") changed setWindowOpenHandler to return action:'allow' with overrideBrowserWindowOptions for trusted domains (Google, Yandex, etc.), opening a real Electron BrowserWindow as popup. The reasoning was that OAuth flows need window.opener + postMessage. That's correct for some flows but wrong for YouTube-style login, which uses straight redirect. Worse: Google specifically detects popup-style embedded browsers (Electron BrowserWindow has distinct fingerprint vs real Chrome popup) and blocks them with "Возможно, этот браузер небезопасны". The user reported this stopped working after 1.0.0 — that's why. Restore the 1.0.0 behavior for trusted domains: deny the popup and call view.webContents.loadURL(newUrl) in the same view. The OAuth flow now happens as a normal in-place navigation: YouTube → accounts.google.com → (user logs in) → redirect back to YouTube. No popup, no fingerprint mismatch. The only UX loss is the popup window aesthetic; behavior is functionally identical and matches what worked in 1.0.0. Untrusted cross-domain still asks for confirmation, same-origin popups still navigate in-place — unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) --- main.js | 31 ++++++++++++------------------- package.json | 2 +- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/main.js b/main.js index 57eb230..aa73190 100644 --- a/main.js +++ b/main.js @@ -659,37 +659,30 @@ ipcMain.on('create-view', async (_event, name, url, imageUrl, _zoom, useProxy) = trackNavigation(newUrl); }); view.webContents.on('will-redirect', (_e, u) => trackNavigation(u)); - view.webContents.setWindowOpenHandler(({ url: newUrl, frameName, features }) => { + view.webContents.setWindowOpenHandler(({ url: newUrl }) => { let newHostname = ''; try { newHostname = new URL(newUrl).hostname; } catch (_) {} - // Trusted domain → open as real popup BrowserWindow with same session. - // This is what OAuth flows need: window.opener.postMessage() works, - // popup can close itself when done, parent stays on the original page. + // Trusted domain (Google, Yandex, etc.) → navigate IN-PLACE, no popup. + // 1.0.1 tried opening a real popup BrowserWindow here for OAuth postMessage + // flows — turns out Google specifically detects popup-style embedded + // browsers and blocks OAuth ("Возможно, этот браузер небезопасны"). + // YouTube-style login uses standard redirect flow, so in-place navigation + // works AND avoids the popup fingerprint. 1.0.0 behavior, restored. if (newHostname && isTrustedDomain(newHostname)) { - return { - action: 'allow', - overrideBrowserWindowOptions: { - width: 520, height: 640, - parent: mainWindow, - autoHideMenuBar: true, - webPreferences: { - session: view.webContents.session, - contextIsolation: true, - nodeIntegration: false, - }, - }, - }; + trackNavigation(newUrl); + view.webContents.loadURL(newUrl); + return { action: 'deny' }; } - // Untrusted cross-domain → ask the user (original behavior). + // Untrusted cross-domain → ask the user. if (origHostname && newHostname && newHostname !== origHostname) { pendingNavigate = { view, url: newUrl }; setConfirm(`Перейти на "${newHostname}"?`, 'navigate-confirmed'); return { action: 'deny' }; } - // Same-origin popup → just navigate the current view. + // Same-origin popup → navigate the current view. trackNavigation(newUrl); view.webContents.loadURL(newUrl); return { action: 'deny' }; diff --git a/package.json b/package.json index 204b2e3..dd24b07 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ESH-Media", - "version": "1.0.8", + "version": "1.0.9", "private": true, "main": "main.js", "scripts": {