Change: refactor sync logic, disallow implicit auth

This commit is contained in:
eight04 2021-02-09 16:50:18 +08:00
parent cd0645f606
commit 0c0240e26d
2 changed files with 29 additions and 42 deletions

View File

@ -64,18 +64,18 @@ const syncMan = (() => {
},
async login(name = prefs.get('sync.enabled')) {
// FIXME: it doesn't really make sense to wait pref after getting the pref value
if (ready.then) await ready;
await tokenMan.revokeToken(name);
try {
await tokenMan.getToken(name, true);
status.login = true;
} catch (err) {
if (/Authorization page could not be loaded/i.test(err.message)) {
// FIXME: Chrome always fails at the first login so we try again
await tokenMan.getToken(name);
}
status.login = false;
throw err;
} finally {
emitStatusChange();
}
status.login = true;
emitStatusChange();
},
async put(...args) {
@ -91,26 +91,24 @@ const syncMan = (() => {
if (currentDrive) return;
currentDrive = getDrive(name);
ctrl.use(currentDrive);
status.state = STATES.connecting;
status.currentDriveName = currentDrive.name;
status.login = true;
emitStatusChange();
try {
if (!fromPref) {
await syncMan.login(name).catch(handle401Error);
}
await syncMan.syncNow();
status.errorMessage = null;
lastError = null;
} catch (err) {
status.errorMessage = err.message;
lastError = err;
// FIXME: should we move this logic to options.js?
if (!fromPref) {
if (!fromPref) {
try {
await syncMan.login(name);
} catch (err) {
console.error(err);
status.errorMessage = err.message;
lastError = err;
emitStatusChange();
return syncMan.stop();
}
}
await syncMan.syncNow(name);
prefs.set('sync.enabled', name);
status.state = STATES.connected;
schedule(SYNC_INTERVAL);
@ -124,7 +122,7 @@ const syncMan = (() => {
status.state = STATES.disconnecting;
emitStatusChange();
try {
await ctrl.stop();
await ctrl.uninit();
await tokenMan.revokeToken(currentDrive.name);
await chromeLocal.remove(STORAGE_KEY + currentDrive.name);
} catch (e) {}
@ -138,14 +136,19 @@ const syncMan = (() => {
async syncNow() {
if (ready.then) await ready;
if (!currentDrive) throw new Error('cannot sync when disconnected');
if (!currentDrive || !status.login) throw new Error('cannot sync when disconnected');
try {
await (ctrl.isInit() ? ctrl.syncNow() : ctrl.start()).catch(handle401Error);
await ctrl.init();
await ctrl.syncNow();
status.errorMessage = null;
lastError = null;
} catch (err) {
status.errorMessage = err.message;
lastError = err;
if (isGrantError(err)) {
status.login = false;
}
}
emitStatusChange();
},
@ -192,21 +195,6 @@ const syncMan = (() => {
});
}
async function handle401Error(err) {
let authError = false;
if (err.code === 401) {
await tokenMan.revokeToken(currentDrive.name).catch(console.error);
authError = true;
} else if (/User interaction required|Requires user interaction/i.test(err.message)) {
authError = true;
}
if (authError) {
status.login = false;
emitStatusChange();
}
return Promise.reject(err);
}
function emitStatusChange() {
msg.broadcastExtension({method: 'syncStatusUpdate', status});

View File

@ -75,13 +75,12 @@ const tokenMan = (() => {
return obj[k.TOKEN];
}
if (obj[k.REFRESH]) {
try {
return await refreshToken(name, k, obj);
} catch (err) {
if (err.code !== 401) throw err;
}
return refreshToken(name, k, obj);
}
}
if (!interactive) {
throw new Error(`Invalid token: ${name}`);
}
return authUser(name, k, interactive);
},