add 'log out everywhere' functionality in settings

pull/1/head
ansuz 8 years ago
parent c07d3e6162
commit a173e4c7a0

@ -333,6 +333,10 @@ define(function () {
out.settings_pinningError = "Something went wrong"; out.settings_pinningError = "Something went wrong";
out.settings_usageAmount = "Your pinned pads occupy {0}MB"; out.settings_usageAmount = "Your pinned pads occupy {0}MB";
out.settings_logoutEverywhere = "Expire remote sessions";
out.settings_logoutEverywhereTitle = "Log out of all other sessions";
out.settings_logoutEverywhereConfirm = "Are you sure? You will need to log in with all your devices.";
// index.html // index.html

@ -192,6 +192,7 @@ define([
[ [
userNameKey, userNameKey,
userHashKey, userHashKey,
'loginToken',
].forEach(function (k) { ].forEach(function (k) {
sessionStorage.removeItem(k); sessionStorage.removeItem(k);
localStorage.removeItem(k); localStorage.removeItem(k);

@ -134,6 +134,23 @@ define([
return ret; return ret;
}; };
var requestLogin = function () {
// log out so that you don't go into an endless loop...
Cryptpad.logout();
// redirect them to log in, and come back when they're done.
sessionStorage.redirectTo = window.location.href;
window.location.href = '/login/';
};
var tryParsing = function (x) {
try { return JSON.parse(x); }
catch (e) {
console.error(e);
return null;
}
};
var onReady = function (f, proxy, Cryptpad, exp) { var onReady = function (f, proxy, Cryptpad, exp) {
var fo = exp.fo = FO.init(proxy.drive, { var fo = exp.fo = FO.init(proxy.drive, {
Cryptpad: Cryptpad Cryptpad: Cryptpad
@ -145,6 +162,28 @@ define([
f(void 0, store); f(void 0, store);
} }
if (Cryptpad.isLoggedIn()) {
/* This isn't truly secure, since anyone who can read the user's object can
set their local loginToken to match that in the object. However, it exposes
a UI that will work most of the time. */
var tokenKey = 'loginToken';
// every user object should have a persistent, random number
if (typeof(proxy.loginToken) !== 'number') {
proxy[tokenKey] = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER);
}
var localToken = tryParsing(localStorage.getItem(tokenKey));
if (localToken === null) {
// if that number hasn't been set to localStorage, do so.
localStorage.setItem(tokenKey, proxy.loginToken);
} else if (localToken !== proxy[tokenKey]) {
// if it has been, and the local number doesn't match that in
// the user object, request that they reauthenticate.
return void requestLogin();
}
}
if (typeof(proxy.allowUserFeedback) !== 'boolean') { if (typeof(proxy.allowUserFeedback) !== 'boolean') {
proxy.allowUserFeedback = true; proxy.allowUserFeedback = true;
} }
@ -157,13 +196,7 @@ define([
// if the user is logged in, but does not have signing keys... // if the user is logged in, but does not have signing keys...
if (Cryptpad.isLoggedIn() && !Cryptpad.hasSigningKeys(proxy)) { if (Cryptpad.isLoggedIn() && !Cryptpad.hasSigningKeys(proxy)) {
// log out so that you don't go into an endless loop... return void requestLogin();
Cryptpad.logout();
// redirect them to log in, and come back when they're done.
sessionStorage.redirectTo = window.location.href;
window.location.href = '/login/';
return;
} }
proxy.on('change', [Cryptpad.displayNameKey], function (o, n) { proxy.on('change', [Cryptpad.displayNameKey], function (o, n) {

@ -252,6 +252,42 @@ define([
return $div; return $div;
}; };
var createLogoutEverywhere = function (obj) {
var proxy = obj.proxy;
var $div = $('<div>', { 'class': 'logoutEverywhere', });
$('<label>', { 'for': 'logoutEverywhere'})
.text(Messages.settings_logoutEverywhereTitle).appendTo($div);
$('<br>').appendTo($div);
var $button = $('<button>', { id: 'logoutEverywhere', 'class': 'btn btn-primary' })
.text(Messages.settings_logoutEverywhere)
.appendTo($div);
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved}).hide().appendTo($div);
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).hide().appendTo($div);
$button.click(function () {
var realtime = obj.info.realtime;
console.log(realtime);
Cryptpad.confirm(Messages.settings_logoutEverywhereConfirm, function (yes) {
if (!yes) { return; }
$spinner.show();
$ok.hide();
var token = proxy.loginToken = Math.floor(Math.random()*Number.MAX_SAFE_INTEGER);
localStorage.setItem('loginToken', token);
Cryptpad.whenRealtimeSyncs(realtime, function () {
$spinner.hide();
$ok.show();
window.setTimeout(function () {
$ok.fadeOut(1500);
}, 2500);
});
});
});
return $div;
};
var createImportLocalPads = function (obj) { var createImportLocalPads = function (obj) {
if (!Cryptpad.isLoggedIn()) { return; } if (!Cryptpad.isLoggedIn()) { return; }
var $div = $('<div>', {'class': 'importLocalPads'}); var $div = $('<div>', {'class': 'importLocalPads'});
@ -292,6 +328,10 @@ define([
APP.$container.append(createInfoBlock(obj)); APP.$container.append(createInfoBlock(obj));
APP.$container.append(createDisplayNameInput(obj)); APP.$container.append(createDisplayNameInput(obj));
APP.$container.append(createLanguageSelector()); APP.$container.append(createLanguageSelector());
if (Cryptpad.isLoggedIn()) {
APP.$container.append(createLogoutEverywhere(obj));
}
APP.$container.append(createResetTips()); APP.$container.append(createResetTips());
APP.$container.append(createBackupDrive(obj)); APP.$container.append(createBackupDrive(obj));
APP.$container.append(createImportLocalPads(obj)); APP.$container.append(createImportLocalPads(obj));

Loading…
Cancel
Save