Fix the settings app to allow backup for unregistered users
parent
f62267f8a1
commit
4206382865
|
@ -131,9 +131,10 @@ define([
|
|||
};
|
||||
|
||||
var onReady = function (f, proxy, Cryptpad, exp) {
|
||||
var fo = FO.init(proxy.drive, {
|
||||
var fo = exp.fo = FO.init(proxy.drive, {
|
||||
Cryptpad: Cryptpad
|
||||
});
|
||||
|
||||
//storeObj = proxy;
|
||||
store = initStore(fo, proxy, exp);
|
||||
if (typeof(f) === 'function') {
|
||||
|
|
|
@ -25,6 +25,7 @@ define(function () {
|
|||
|
||||
out.loading = "Chargement...";
|
||||
out.error = "Erreur";
|
||||
out.saved = "Enregistré";
|
||||
|
||||
out.disconnected = 'Déconnecté';
|
||||
out.synchronizing = 'Synchronisation';
|
||||
|
@ -248,6 +249,11 @@ define(function () {
|
|||
out.settings_resetTipsButton = "Réinitialiser les astuces visibles dans CryptDrive";
|
||||
out.settings_resetTipsDone = "Toutes les astuces sont de nouveau visibles.";
|
||||
|
||||
out.settings_importTitle = "Importer les pads récents de ce navigateur dans mon CryptDrive";
|
||||
out.settings_import = "Importer";
|
||||
out.settings_importConfirm = "Êtes-vous sûr de vouloir importer les pads récents de ce navigateur dans le CryptDrive de votre compte utilisateur ?";
|
||||
out.settings_importDone = "Importation terminée";
|
||||
|
||||
out.settings_userFeedbackHint1 = "CryptPad peut envoyer des retours d'expérience très limités vers le serveur, de manière à nous permettre d'améliorer l'expérience des utilisateurs.";
|
||||
out.settings_userFeedbackHint2 = "Le contenu de vos pads et les clés de déchiffrement ne seront jamais partagés avec le serveur.";
|
||||
out.settings_userFeedback = "Activer l'envoi de retours d'expérience";
|
||||
|
|
|
@ -27,6 +27,7 @@ define(function () {
|
|||
|
||||
out.loading = "Loading...";
|
||||
out.error = "Error";
|
||||
out.saved = "Saved";
|
||||
|
||||
out.disconnected = 'Disconnected';
|
||||
out.synchronizing = 'Synchronizing';
|
||||
|
@ -250,6 +251,11 @@ define(function () {
|
|||
out.settings_resetTipsButton = "Reset the available tips in CryptDrive";
|
||||
out.settings_resetTipsDone = "All the tips are now visible again.";
|
||||
|
||||
out.settings_importTitle = "Import this browser's recent pads in my CryptDrive";
|
||||
out.settings_import = "Import";
|
||||
out.settings_confirm = "Are you sure you want to import recent pads from this browser to your user account's CryptDrive?";
|
||||
out.settings_done = "Import completed";
|
||||
|
||||
out.settings_userFeedbackHint1 = "CryptPad provides some very basic feedback to the server, to let us know how to improve your experience.";
|
||||
out.settings_userFeedbackHint2 = "Your pad's content will never be shared with the server.";
|
||||
out.settings_userFeedback = "Enable user feedback";
|
||||
|
|
|
@ -621,6 +621,28 @@ define([
|
|||
};
|
||||
|
||||
// STORAGE
|
||||
var findWeaker = common.findWeaker = function (href, recents) {
|
||||
var rHref = href || getRelativeHref(window.location.href);
|
||||
var parsed = parsePadUrl(rHref);
|
||||
if (!parsed.hash) { return false; }
|
||||
var weaker;
|
||||
recents.some(function (pad) {
|
||||
var p = parsePadUrl(pad.href);
|
||||
if (p.type !== parsed.type) { return; } // Not the same type
|
||||
if (p.hash === parsed.hash) { return; } // Same hash, not stronger
|
||||
var pHash = parseHash(p.hash);
|
||||
var parsedHash = parseHash(parsed.hash);
|
||||
if (!parsedHash || !pHash) { return; }
|
||||
if (pHash.version !== parsedHash.version) { return; }
|
||||
if (pHash.channel !== parsedHash.channel) { return; }
|
||||
if (pHash.mode === 'view' && parsedHash.mode === 'edit') {
|
||||
weaker = pad.href;
|
||||
return true;
|
||||
}
|
||||
return;
|
||||
});
|
||||
return weaker;
|
||||
};
|
||||
var findStronger = common.findStronger = function (href, recents) {
|
||||
var rHref = href || getRelativeHref(window.location.href);
|
||||
var parsed = parsePadUrl(rHref);
|
||||
|
|
|
@ -6,10 +6,10 @@ define([
|
|||
|
||||
var Messages = {};
|
||||
|
||||
var ROOT = "root";
|
||||
var UNSORTED = "unsorted";
|
||||
var TRASH = "trash";
|
||||
var TEMPLATE = "template";
|
||||
var ROOT = module.ROOT = "root";
|
||||
var UNSORTED = module.UNSORTED = "unsorted";
|
||||
var TRASH = module.TRASH = "trash";
|
||||
var TEMPLATE = module.TEMPLATE = "template";
|
||||
|
||||
var init = module.init = function (files, config) {
|
||||
var Cryptpad = config.Cryptpad;
|
||||
|
|
|
@ -2,8 +2,9 @@ require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/J
|
|||
define([
|
||||
'/common/cryptpad-common.js',
|
||||
'/common/cryptget.js',
|
||||
'/common/fileObject.js',
|
||||
'json.sortify'
|
||||
], function (Cryptpad, Crypt, Sortify) {
|
||||
], function (Cryptpad, Crypt, FO, Sortify) {
|
||||
var exp = {};
|
||||
|
||||
var getType = function (el) {
|
||||
|
@ -17,6 +18,7 @@ define([
|
|||
var nkey = key;
|
||||
while (typeof (obj[nkey]) !== "undefined") {
|
||||
nkey = key + '_' + i;
|
||||
i++;
|
||||
}
|
||||
return nkey;
|
||||
};
|
||||
|
@ -39,7 +41,8 @@ define([
|
|||
};
|
||||
|
||||
// Merge obj2 into obj1
|
||||
// If keepOld is true, obj1 values are kept in case of conflict in the ROOT object
|
||||
// If keepOld is true, obj1 values are kept in case of conflicti
|
||||
// Not used ATM
|
||||
var merge = function (obj1, obj2, keepOld) {
|
||||
if (typeof (obj1) !== "object" || typeof (obj2) !== "object") { return; };
|
||||
Object.keys(obj2).forEach(function (k) {
|
||||
|
@ -57,40 +60,116 @@ define([
|
|||
}
|
||||
// Else, they're both maps or both arrays
|
||||
if (getType(obj1[k]) === "array" && getType(obj2[k]) === "array") {
|
||||
// CryptPad_RECENTPADS
|
||||
if (k === 'CryptPad_RECENTPADS') {
|
||||
var old = obj1[k];
|
||||
obj2[k].forEach(function (pad) {
|
||||
if (!old.some(function (op) {
|
||||
// TODO read-only links
|
||||
return op.href === pad.href;
|
||||
})) {
|
||||
old.push(pad);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
var c = obj1[k].concat(obj2[k]);
|
||||
obj1[k] = deduplicate(c);
|
||||
return;
|
||||
}
|
||||
merge(obj1[k], obj2[k]);
|
||||
merge(obj1[k], obj2[k], keepOld);
|
||||
});
|
||||
};
|
||||
|
||||
var createFromPath = function (proxy, oldFo, path, href) {
|
||||
var root = proxy.drive;
|
||||
|
||||
var error = function (msg) {
|
||||
console.error(msg || "Unable to find that path", path);
|
||||
};
|
||||
|
||||
if (path[0] === FO.TRASH && path.length === 4) {
|
||||
href = oldFo.getTrashElementData(path);
|
||||
path.pop();
|
||||
}
|
||||
|
||||
var p, next, nextRoot;
|
||||
path.forEach(function (p, i) {
|
||||
if (!root) { return; }
|
||||
if (typeof(p) === "string") {
|
||||
if (getType(root) !== "object") { root = undefined; error(); return; }
|
||||
if (i === path.length - 1) {
|
||||
root[findAvailableKey(root, p)] = href;
|
||||
return;
|
||||
}
|
||||
next = getType(path[i+1]);
|
||||
nextRoot = getType(root[p]);
|
||||
if (nextRoot !== "undefined") {
|
||||
if (next === "string" && nextRoot === "object" || next === "number" && nextRoot === "array") {
|
||||
root = root[p];
|
||||
return;
|
||||
}
|
||||
p = findAvailableKey(root, p);
|
||||
}
|
||||
if (next === "number") {
|
||||
root[p] = [];
|
||||
root = root[p];
|
||||
return;
|
||||
}
|
||||
root[p] = {};
|
||||
root = root[p];
|
||||
return;
|
||||
}
|
||||
// Path contains a non-string element: it's an array index
|
||||
if (typeof(p) !== "number") { root = undefined; error(); return; }
|
||||
if (getType(root) !== "array") { root = undefined; error(); return; }
|
||||
if (i === path.length - 1) {
|
||||
if (root.indexOf(href) === -1) { root.push(href); }
|
||||
return;
|
||||
}
|
||||
next = getType(path[i+1]);
|
||||
if (next === "number") {
|
||||
error('2 consecutives arrays in the user object');
|
||||
root = undefined;
|
||||
//root.push([]);
|
||||
//root = root[root.length - 1];
|
||||
return;
|
||||
}
|
||||
root.push({});
|
||||
root = root[root.length - 1];
|
||||
return;
|
||||
});
|
||||
};
|
||||
|
||||
var mergeAnonDrive = exp.anonDriveIntoUser = function (proxy, cb) {
|
||||
// Make sure we have an FS_hash and we don't use it, otherwise just stop the migration and cb
|
||||
if (!localStorage.FS_hash || !Cryptpad.isLoggedIn()) {
|
||||
delete sessionStorage.migrateAnonDrive;
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
}
|
||||
// Get the content of FS_hash and then merge the objects, remove the migration key and cb
|
||||
var todo = function (err, doc) {
|
||||
if (err) { logError("Cannot migrate recent pads", err); return; }
|
||||
if (err) { console.error("Cannot migrate recent pads", err); return; }
|
||||
var parsed;
|
||||
try { parsed = JSON.parse(doc); } catch (e) { logError("Cannot parsed recent pads", e); }
|
||||
if (parsed) {
|
||||
merge(proxy, parsed, true);
|
||||
//merge(proxy, parsed, true);
|
||||
var oldFo = FO.init(parsed.drive, {
|
||||
Cryptpad: Cryptpad
|
||||
});
|
||||
var newData = Cryptpad.getStore().getProxy();
|
||||
var newFo = newData.fo;
|
||||
var newRecentPads = proxy.drive[Cryptpad.storageKey];
|
||||
var newFiles = newFo.getFilesDataFiles();
|
||||
var oldFiles = oldFo.getFilesDataFiles();
|
||||
oldFiles.forEach(function (href) {
|
||||
// Do not migrate a pad if we already have it, it would create a duplicate in the drive
|
||||
if (newFiles.indexOf(href) !== -1) { return; }
|
||||
// If we have a stronger version, do not add the current href
|
||||
if (Cryptpad.findStronger(href, newRecentPads)) { return; }
|
||||
// If we have a weaker version, replace the href by the new one
|
||||
// NOTE: if that weaker version is in the trash, the strong one will be put in unsorted
|
||||
var weaker = Cryptpad.findWeaker(href, newRecentPads);
|
||||
if (weaker) {
|
||||
newFo.replaceHref(weaker, href);
|
||||
return;
|
||||
}
|
||||
// Here it means we have a new href, so we should add it to the drive at its old location
|
||||
var paths = oldFo.findFile(href);
|
||||
if (paths.length === 0) { return; }
|
||||
createFromPath(proxy, oldFo, paths[0], href);
|
||||
// Also, push the file data in our array
|
||||
var data = oldFo.getFileData(href);
|
||||
if (data) {
|
||||
newRecentPads.push(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (typeof(cb) === "function") { cb(); }
|
||||
};
|
||||
|
|
|
@ -66,10 +66,9 @@ define([
|
|||
'id': 'displayName',
|
||||
'placeholder': Messages.anonymous}).appendTo($div);
|
||||
var $save = $('<button>', {'class': 'btn btn-primary'}).text(Messages.settings_save).appendTo($div);
|
||||
var $ok = $('<span>', {'class': 'fa fa-check'}).appendTo($div);
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).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);
|
||||
|
||||
$spinner.hide();
|
||||
var displayName = obj[USERNAME_KEY] || '';
|
||||
$input.val(displayName);
|
||||
|
||||
|
@ -136,7 +135,7 @@ define([
|
|||
};
|
||||
var importFile = function (content, file) {
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'}).appendTo($div);
|
||||
Crypt.put(Cryptpad.getUserHash(), content, function (e) {
|
||||
Crypt.put(Cryptpad.getUserHash() || localStorage[Cryptpad.fileHashKey], content, function (e) {
|
||||
if (e) { console.error(e); }
|
||||
$spinner.remove();
|
||||
});
|
||||
|
@ -188,17 +187,27 @@ define([
|
|||
|
||||
$('<br>').appendTo($div);
|
||||
|
||||
var $ok = $('<span>', {'class': 'fa fa-check', title: Messages.saved});
|
||||
var $spinner = $('<span>', {'class': 'fa fa-spinner fa-pulse'});
|
||||
|
||||
var $checkbox = $('<input>', {
|
||||
'type': 'checkbox',
|
||||
}).on('change', function () {
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
obj.proxy.allowUserFeedback = $checkbox.is(':checked') || false;
|
||||
// TODO provide feedback to show if this is synced
|
||||
// Cryptpad.whenRealtimeSyncs...
|
||||
Cryptpad.whenRealtimeSyncs(obj.info.realtime, function () {
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
});
|
||||
});
|
||||
|
||||
$checkbox.appendTo($div);
|
||||
$label.appendTo($div);
|
||||
|
||||
$ok.hide().appendTo($div);
|
||||
$spinner.hide().appendTo($div);
|
||||
|
||||
if (obj.proxy.allowUserFeedback) {
|
||||
$checkbox[0].checked = true;
|
||||
}
|
||||
|
@ -206,17 +215,25 @@ define([
|
|||
};
|
||||
|
||||
var createImportLocalPads = function (obj) {
|
||||
if (!Cryptpad.isLoggedIn()) { return; }
|
||||
var $div = $('<div>', {'class': 'importLocalPads'});
|
||||
var $label = $('<label>', {'for' : 'importLocalPads'}).text("TODO: IMPORT LOCAL PADS LABEL").appendTo($div);
|
||||
var $label = $('<label>', {'for' : 'importLocalPads'}).text(Messages.settings_importTitle).appendTo($div);
|
||||
$('<br>').appendTo($div);
|
||||
var $button = $('<button>', {'id': 'importLocalPads', 'class': 'btn btn-default'})
|
||||
.text("TODO: IMPORT LOCAL PADS").appendTo($div);
|
||||
var $button = $('<button>', {'id': 'importLocalPads', 'class': 'btn btn-primary'})
|
||||
.text(Messages.settings_import).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 () {
|
||||
Cryptpad.confirm("ARE YOU SURE?", function (err) {
|
||||
if (err) { return; }
|
||||
Cryptpad.confirm(Messages.settings_importConfirm, function (yes) {
|
||||
if (!yes) { return; }
|
||||
$spinner.show();
|
||||
$ok.hide();
|
||||
Merge.anonDriveIntoUser(obj.proxy, function () {
|
||||
Cryptpad.alert("DONE");
|
||||
$spinner.hide();
|
||||
$ok.show();
|
||||
Cryptpad.alert(Messages.settings_importDone);
|
||||
});
|
||||
}, undefined, true);
|
||||
});
|
||||
|
@ -230,6 +247,7 @@ define([
|
|||
APP.$container.append(createDisplayNameInput(obj));
|
||||
APP.$container.append(createResetTips());
|
||||
APP.$container.append(createBackupDrive(obj));
|
||||
APP.$container.append(createImportLocalPads(obj));
|
||||
APP.$container.append(createResetDrive(obj));
|
||||
APP.$container.append(createUserFeedbackToggle(obj));
|
||||
obj.proxy.on('change', [], refresh);
|
||||
|
|
Loading…
Reference in New Issue