Fix: only auth user on 401 error, don't display login window without user interaction

This commit is contained in:
eight 2019-10-21 01:53:26 +08:00
parent 7d5ca17c6e
commit 003fbead0c
2 changed files with 36 additions and 13 deletions

View File

@ -48,8 +48,10 @@ const sync = (() => {
} }
}); });
const initializing = prefs.initializing.then(() => {
prefs.subscribe(['sync.enabled'], onPrefChange); prefs.subscribe(['sync.enabled'], onPrefChange);
onPrefChange(null, prefs.get('sync.enabled')); onPrefChange(null, prefs.get('sync.enabled'));
});
chrome.alarms.onAlarm.addListener(info => { chrome.alarms.onAlarm.addListener(info => {
if (info.name === 'syncNow') { if (info.name === 'syncNow') {
@ -57,7 +59,7 @@ const sync = (() => {
} }
}); });
return { return ensurePrepared({
start, start,
stop, stop,
put: (...args) => { put: (...args) => {
@ -72,7 +74,15 @@ const sync = (() => {
}, },
syncNow, syncNow,
getStatus: () => status getStatus: () => status
}; });
function ensurePrepared(obj) {
return Object.entries(obj).reduce((o, [key, fn]) => {
o[key] = (...args) =>
initializing.then(() => fn(...args));
return o;
}, {});
}
function onProgress(e) { function onProgress(e) {
if (e.phase === 'start') { if (e.phase === 'start') {
@ -152,7 +162,7 @@ const sync = (() => {
status.currentDriveName = currentDrive.name; status.currentDriveName = currentDrive.name;
emitStatusChange(); emitStatusChange();
return withFinally( return withFinally(
tokenManager.getToken(name) tokenManager.getToken(name, !fromPref)
.catch(err => { .catch(err => {
if (/Authorization page could not be loaded/i.test(err.message)) { if (/Authorization page could not be loaded/i.test(err.message)) {
// FIXME: Chrome always fails at the first login so we try again // FIXME: Chrome always fails at the first login so we try again

View File

@ -65,15 +65,26 @@ const tokenManager = (() => {
return k; return k;
} }
function getToken(name) { function getToken(name, interactive) {
const k = buildKeys(name); const k = buildKeys(name);
return chromeLocal.get(k.LIST) return chromeLocal.get(k.LIST)
.then(obj => { .then(obj => {
if (!obj[k.TOKEN] || Date.now() > obj[k.EXPIRE]) { if (!obj[k.TOKEN]) {
return refreshToken(name, k, obj) return authUser(name, k, interactive);
.catch(() => authUser(name, k));
} }
if (Date.now() < obj[k.EXPIRE]) {
return obj[k.TOKEN]; return obj[k.TOKEN];
}
if (obj[k.EXPIRE]) {
return refreshToken(name, k, obj)
.catch(err => {
if (err.code === 401) {
return authUser(name, k, interactive);
}
throw err;
});
}
return authUser(name, k, interactive);
}); });
} }
@ -124,7 +135,7 @@ const tokenManager = (() => {
return search.toString(); return search.toString();
} }
function authUser(name, k) { function authUser(name, k, interactive = false) {
const provider = AUTH[name]; const provider = AUTH[name];
const state = Math.random().toFixed(8).slice(2); const state = Math.random().toFixed(8).slice(2);
const query = { const query = {
@ -142,7 +153,7 @@ const tokenManager = (() => {
const url = `${provider.authURL}?${stringifyQuery(query)}`; const url = `${provider.authURL}?${stringifyQuery(query)}`;
return launchWebAuthFlow({ return launchWebAuthFlow({
url, url,
interactive: true interactive
}) })
.then(url => { .then(url => {
const params = new URLSearchParams( const params = new URLSearchParams(
@ -201,7 +212,9 @@ const tokenManager = (() => {
} }
return r.text() return r.text()
.then(body => { .then(body => {
throw new Error(`failed to fetch (${r.status}): ${body}`); const err = new Error(`failed to fetch (${r.status}): ${body}`);
err.code = r.status;
throw err;
}); });
}); });
} }