vivaldi bug workaround: open webAuth flow in a tab (#1186)

This commit is contained in:
tophf 2021-02-22 15:12:19 +03:00 committed by GitHub
parent b61cd75b25
commit cf1f51af0a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 18 deletions

View File

@ -1,4 +1,4 @@
/* global FIREFOX */// toolbox.js /* global FIREFOX getActiveTab waitForTabUrl */// toolbox.js
/* global chromeLocal */// storage-util.js /* global chromeLocal */// storage-util.js
'use strict'; 'use strict';
@ -51,6 +51,8 @@ const tokenMan = (() => {
}; };
const NETWORK_LATENCY = 30; // seconds const NETWORK_LATENCY = 30; // seconds
let alwaysUseTab = FIREFOX ? false : null;
return { return {
buildKeys(name) { buildKeys(name) {
@ -138,11 +140,20 @@ const tokenMan = (() => {
if (provider.authQuery) { if (provider.authQuery) {
Object.assign(query, provider.authQuery); Object.assign(query, provider.authQuery);
} }
if (alwaysUseTab == null) {
alwaysUseTab = await detectVivaldiWebRequestBug();
}
const url = `${provider.authURL}?${new URLSearchParams(query)}`; const url = `${provider.authURL}?${new URLSearchParams(query)}`;
const finalUrl = await webextLaunchWebAuthFlow({ const finalUrl = await webextLaunchWebAuthFlow({
url, url,
alwaysUseTab,
interactive, interactive,
redirect_uri: query.redirect_uri, redirect_uri: query.redirect_uri,
windowOptions: {
state: 'normal',
width: Math.min(screen.width - 100, 800),
height: Math.min(screen.height - 100, 800),
},
}); });
const params = new URLSearchParams( const params = new URLSearchParams(
provider.flow === 'token' ? provider.flow === 'token' ?
@ -203,4 +214,28 @@ const tokenMan = (() => {
err.code = r.status; err.code = r.status;
throw err; throw err;
} }
async function detectVivaldiWebRequestBug() {
// Workaround for https://github.com/openstyles/stylus/issues/1182
// Note that modern Vivaldi isn't exposed in `navigator.userAgent` but it adds `extData` to tabs
const anyTab = await getActiveTab() || (await browser.tabs.query({}))[0];
if (anyTab && !anyTab.extData) {
return false;
}
let bugged = true;
const TEST_URL = chrome.runtime.getURL('manifest.json');
const check = ({url}) => {
bugged = url !== TEST_URL;
};
chrome.webRequest.onBeforeRequest.addListener(check, {urls: [TEST_URL], types: ['main_frame']});
const {tabs: [tab]} = await browser.windows.create({
type: 'popup',
state: 'minimized',
url: TEST_URL,
});
await waitForTabUrl(tab);
chrome.windows.remove(tab.windowId);
chrome.webRequest.onBeforeRequest.removeListener(check);
return bugged;
}
})(); })();

View File

@ -18,6 +18,7 @@
stringAsRegExp stringAsRegExp
tryCatch tryCatch
tryRegExp tryRegExp
waitForTabUrl
*/ */
const CHROME = Boolean(chrome.app) && parseInt(navigator.userAgent.match(/Chrom\w+\/(\d+)|$/)[1]); const CHROME = Boolean(chrome.app) && parseInt(navigator.userAgent.match(/Chrom\w+\/(\d+)|$/)[1]);
@ -469,6 +470,20 @@ async function closeCurrentTab() {
if (tab) chrome.tabs.remove(tab.id); if (tab) chrome.tabs.remove(tab.id);
} }
function waitForTabUrl(tab) {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(...[
function onUpdated(tabId, info, updatedTab) {
if (info.url && tabId === tab.id) {
browser.tabs.onUpdated.removeListener(onUpdated);
resolve(updatedTab);
}
},
...'UpdateFilter' in browser.tabs ? [{tabId: tab.id}] : [], // FF only
]);
});
}
function capitalize(s) { function capitalize(s) {
return s[0].toUpperCase() + s.slice(1); return s[0].toUpperCase() + s.slice(1);
} }

View File

@ -1,5 +1,5 @@
/* global API */// msg.js /* global API */// msg.js
/* global URLS */// toolbox.js /* global URLS waitForTabUrl */// toolbox.js
'use strict'; 'use strict';
const ABOUT_BLANK = 'about:blank'; const ABOUT_BLANK = 'about:blank';
@ -7,7 +7,7 @@ const ABOUT_BLANK = 'about:blank';
const preinit = (async () => { const preinit = (async () => {
let [tab] = await browser.tabs.query({currentWindow: true, active: true}); let [tab] = await browser.tabs.query({currentWindow: true, active: true});
if (!chrome.app && tab.status === 'loading' && tab.url === ABOUT_BLANK) { if (!chrome.app && tab.status === 'loading' && tab.url === ABOUT_BLANK) {
tab = await waitForTabUrlFF(tab); tab = await waitForTabUrl(tab);
} }
const frames = sortTabFrames(await browser.webNavigation.getAllFrames({tabId: tab.id})); const frames = sortTabFrames(await browser.webNavigation.getAllFrames({tabId: tab.id}));
let url = tab.pendingUrl || tab.url || ''; // new Chrome uses pendingUrl while connecting let url = tab.pendingUrl || tab.url || ''; // new Chrome uses pendingUrl while connecting
@ -60,18 +60,3 @@ function sortTabFrames(frames) {
} }
return sortedFrames; return sortedFrames;
} }
function waitForTabUrlFF(tab) {
return new Promise(resolve => {
browser.tabs.onUpdated.addListener(...[
function onUpdated(tabId, info, updatedTab) {
if (info.url && tabId === tab.id) {
browser.tabs.onUpdated.removeListener(onUpdated);
resolve(updatedTab);
}
},
...'UpdateFilter' in browser.tabs ? [{tabId: tab.id}] : [],
// TODO: remove both spreads and tabId check when strict_min_version >= 61
]);
});
}