Add: login button to generate the access token interactively

This commit is contained in:
eight 2019-10-21 02:34:08 +08:00
parent fca75ce207
commit 6c4f73a49a
4 changed files with 40 additions and 11 deletions

View File

@ -68,7 +68,8 @@ window.API_METHODS = Object.assign(window.API_METHODS || {}, {
syncStart: sync.start,
syncStop: sync.stop,
syncNow: sync.syncNow,
getSyncStatus: sync.getStatus
getSyncStatus: sync.getStatus,
syncLogin: sync.login
});
// eslint-disable-next-line no-var

View File

@ -12,7 +12,8 @@ const sync = (() => {
syncing: false,
progress: null,
currentDriveName: null,
errorMessage: null
errorMessage: null,
login: false
};
let currentDrive;
const ctrl = dbToCloud.dbToCloud({
@ -73,7 +74,8 @@ const sync = (() => {
return ctrl.delete(...args);
},
syncNow,
getStatus: () => status
getStatus: () => status,
login
});
function ensurePrepared(obj) {
@ -141,10 +143,17 @@ const sync = (() => {
function handle401Error(err) {
if (err.code === 401) {
return tokenManager.revokeToken(currentDrive.name)
.catch(console.error)
.then(() => {
status.login = false;
emitStatusChange();
throw err;
});
}
if (/User interaction required|Requires user interaction/i.test(err.message)) {
status.login = false;
emitStatusChange();
}
throw err;
}
@ -152,6 +161,21 @@ const sync = (() => {
msg.broadcastExtension({method: 'syncStatusUpdate', status});
}
function login(name = prefs.get('sync.enabled')) {
return tokenManager.getToken(name, 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
return tokenManager.getToken(name);
}
throw err;
})
.then(() => {
status.login = true;
emitStatusChange();
});
}
function start(name, fromPref = false) {
if (currentDrive) {
return Promise.resolve();
@ -160,16 +184,10 @@ const sync = (() => {
ctrl.use(currentDrive);
status.state = 'connecting';
status.currentDriveName = currentDrive.name;
status.login = true;
emitStatusChange();
return withFinally(
tokenManager.getToken(name, !fromPref)
.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
return tokenManager.getToken(name);
}
throw err;
})
(fromPref ? Promise.resolve() : login(name))
.catch(handle401Error)
.then(() => syncNow()),
err => {
@ -211,6 +229,7 @@ const sync = (() => {
prefs.set('sync.enabled', 'none');
status.state = 'disconnected';
status.currentDriveName = null;
status.login = false;
emitStatusChange();
}
);

View File

@ -154,6 +154,7 @@
<button type="button" class="connect">Connect</button>
<button type="button" class="disconnect">Disconnect</button>
<button type="button" class="sync-now">Sync now</button>
<button type="button" class="sync-login">Login</button>
</div>
</div>
</div>

View File

@ -81,6 +81,7 @@ document.onclick = e => {
const disconnectButton = document.querySelector('.sync-options .disconnect');
const syncButton = document.querySelector('.sync-options .sync-now');
const statusText = document.querySelector('.sync-options .sync-status');
const loginButton = document.querySelector('.sync-options .sync-login');
let status = {};
@ -112,6 +113,7 @@ document.onclick = e => {
disconnectButton.disabled = status.state !== 'connected' || status.syncing;
syncButton.disabled = status.state !== 'connected' || status.syncing;
statusText.textContent = getStatusText();
loginButton.style.display = status.state === 'connected' && !status.login ? '' : 'none';
}
function getStatusText() {
@ -149,6 +151,12 @@ document.onclick = e => {
API.syncNow().catch(console.error);
}
});
loginButton.addEventListener('click', e => {
if (validClick(e)) {
API.syncLogin().catch(console.error);
}
});
})();
function checkUpdates() {