Fix shared folders issues including disappearing folders

pull/1/head
yflory 6 years ago
parent 4325ed4dde
commit f2baaf5b5b

@ -446,6 +446,7 @@ define(function () {
out.fm_tags_name = "Mot-clé"; out.fm_tags_name = "Mot-clé";
out.fm_tags_used = "Nombre d'utilisations"; out.fm_tags_used = "Nombre d'utilisations";
out.fm_restoreDrive = "Restauration de votre CryptDrive à une version antérieure. Pour de meilleurs résultats, veuillez éviter de modifier votre CryptDrive avant que cette restauration ne soit terminée."; out.fm_restoreDrive = "Restauration de votre CryptDrive à une version antérieure. Pour de meilleurs résultats, veuillez éviter de modifier votre CryptDrive avant que cette restauration ne soit terminée.";
out.fm_moveNestedSF = "Les Drive partagés ne peuvent pas contenir d'autres Drive partagés. Le dossier {0} n'a pas été déplacé.";
// File - Context menu // File - Context menu
out.fc_newfolder = "Nouveau dossier"; out.fc_newfolder = "Nouveau dossier";
out.fc_newsharedfolder = "Nouveau Drive partagé"; out.fc_newsharedfolder = "Nouveau Drive partagé";

@ -446,7 +446,8 @@ define(function () {
out.fm_deletedPads = "These pads no longer exist on the server, they've been removed from your CryptDrive: {0}"; out.fm_deletedPads = "These pads no longer exist on the server, they've been removed from your CryptDrive: {0}";
out.fm_tags_name = "Tag name"; out.fm_tags_name = "Tag name";
out.fm_tags_used = "Number of uses"; out.fm_tags_used = "Number of uses";
out.fm_restoreDrive = "Resetting your drive to an earlier state. For best results, avoid making changes to your drive until this process is complete." out.fm_restoreDrive = "Resetting your drive to an earlier state. For best results, avoid making changes to your drive until this process is complete.";
out.fm_moveNestedSF = "Nested shared drive are not allowed. The folder {0} was not moved."; // XXX
// File - Context menu // File - Context menu
out.fc_newfolder = "New folder"; out.fc_newfolder = "New folder";
out.fc_newsharedfolder = "New shared Drive"; out.fc_newsharedfolder = "New shared Drive";

@ -125,6 +125,7 @@ define([
id: 'cp-app-prop-owners', id: 'cp-app-prop-owners',
})); }));
if (!data.noExpiration) {
var expire = Messages.creation_expireFalse; var expire = Messages.creation_expireFalse;
if (data.expire && typeof (data.expire) === "number") { if (data.expire && typeof (data.expire) === "number") {
expire = new Date(data.expire).toLocaleString(); expire = new Date(data.expire).toLocaleString();
@ -134,7 +135,9 @@ define([
$d.append(UI.dialog.selectable(expire, { $d.append(UI.dialog.selectable(expire, {
id: 'cp-app-prop-expire', id: 'cp-app-prop-expire',
})); }));
}
if (!data.noPassword) {
var hasPassword = data.password; var hasPassword = data.password;
if (hasPassword) { if (hasPassword) {
$('<label>', {'for': 'cp-app-prop-password'}).text(Messages.creation_passwordValue) $('<label>', {'for': 'cp-app-prop-password'}).text(Messages.creation_passwordValue)
@ -202,6 +205,7 @@ define([
}); });
$d.append(changePass); $d.append(changePass);
} }
}
cb(void 0, $d); cb(void 0, $d);
}; };

@ -94,8 +94,7 @@ define([
// Get the list of pads' channel ID in your drive // Get the list of pads' channel ID in your drive
// This list is filtered so that it doesn't include pad owned by other users // This list is filtered so that it doesn't include pad owned by other users
// It now includes channels from shared folders // It now includes channels from shared folders
var edPublic = store.proxy.edPublic; var list = store.manager.getChannelsList('pin');
var list = store.manager.getChannelsList(edPublic, 'pin');
// Get the avatar // Get the avatar
var profile = store.proxy.profile; var profile = store.proxy.profile;
@ -118,8 +117,7 @@ define([
}; };
var getExpirableChannelList = function () { var getExpirableChannelList = function () {
var edPublic = store.proxy.edPublic; return store.manager.getChannelsList('expirable');
return store.manager.getChannelsList(edPublic, 'expirable');
}; };
var getCanonicalChannelList = function (expirable) { var getCanonicalChannelList = function (expirable) {
@ -466,8 +464,7 @@ define([
}; };
var getOwnedPads = function () { var getOwnedPads = function () {
var edPublic = store.proxy.edPublic; var list = store.manager.getChannelsList('owned');
var list = store.manager.getChannelsList(edPublic, 'owned');
if (store.proxy.todo) { if (store.proxy.todo) {
// No password for todo // No password for todo
list.push(Hash.hrefToHexChannelId('/todo/#' + store.proxy.todo, null)); list.push(Hash.hrefToHexChannelId('/todo/#' + store.proxy.todo, null));

@ -80,9 +80,8 @@ define([
}; };
// Find files in FILES_DATA that are not anymore in the drive, and remove them from // Find files in FILES_DATA that are not anymore in the drive, and remove them from
// FILES_DATA. If there are owned pads, remove them from server too, unless the flag tells // FILES_DATA. If there are owned pads, remove them from server too.
// us they're already removed exp.checkDeletedFiles = function (cb) {
exp.checkDeletedFiles = function (isOwnPadRemoved, cb) {
if (!loggedIn && !config.testMode) { return void cb(); } if (!loggedIn && !config.testMode) { return void cb(); }
var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]); var filesList = exp.getFiles([ROOT, 'hrefArray', TRASH]);
@ -93,8 +92,8 @@ define([
var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id); var fd = exp.isSharedFolder(id) ? files[SHARED_FOLDERS][id] : exp.getFileData(id);
var channelId = fd.channel; var channelId = fd.channel;
// If trying to remove an owned pad, remove it from server also // If trying to remove an owned pad, remove it from server also
if (!isOwnPadRemoved && !sharedFolder && if (!sharedFolder && fd.owners && fd.owners.indexOf(edPublic) !== -1
fd.owners && fd.owners.indexOf(edPublic) !== -1 && channelId) { && channelId) {
if (channelId) { ownedRemoved.push(channelId); } if (channelId) { ownedRemoved.push(channelId); }
removeOwnedChannel(channelId, function (obj) { removeOwnedChannel(channelId, function (obj) {
if (obj && obj.error) { if (obj && obj.error) {
@ -132,7 +131,7 @@ define([
files[TRASH][obj.name].splice(idx, 1); files[TRASH][obj.name].splice(idx, 1);
}); });
}; };
exp.deleteMultiplePermanently = function (paths, nocheck, isOwnPadRemoved, cb) { exp.deleteMultiplePermanently = function (paths, nocheck, cb) {
var hrefPaths = paths.filter(function(x) { return exp.isPathIn(x, ['hrefArray']); }); var hrefPaths = paths.filter(function(x) { return exp.isPathIn(x, ['hrefArray']); });
var rootPaths = paths.filter(function(x) { return exp.isPathIn(x, [ROOT]); }); var rootPaths = paths.filter(function(x) { return exp.isPathIn(x, [ROOT]); });
var trashPaths = paths.filter(function(x) { return exp.isPathIn(x, [TRASH]); }); var trashPaths = paths.filter(function(x) { return exp.isPathIn(x, [TRASH]); });
@ -185,14 +184,14 @@ define([
// In some cases, we want to remove pads from a location without removing them from // In some cases, we want to remove pads from a location without removing them from
// FILES_DATA (replaceHref) // FILES_DATA (replaceHref)
if (!nocheck) { exp.checkDeletedFiles(isOwnPadRemoved, cb); } if (!nocheck) { exp.checkDeletedFiles(cb); }
else { cb(); } else { cb(); }
}; };
// Move // Move
// From another drive // From another drive
exp.copyFromOtherDrive = function (path, element, data) { exp.copyFromOtherDrive = function (path, element, data, key) {
// Copy files data // Copy files data
// We have to remove pads that are already in the current proxy to make sure // We have to remove pads that are already in the current proxy to make sure
// we won't create duplicates // we won't create duplicates
@ -241,7 +240,8 @@ define([
// Copy file or folder // Copy file or folder
var newParent = exp.find(path); var newParent = exp.find(path);
var newName = exp.getAvailableName(newParent, Hash.createChannelId()); var tempName = exp.isFile(element) ? Hash.createChannelId() : key;
var newName = exp.getAvailableName(newParent, tempName);
newParent[newName] = element; newParent[newName] = element;
}; };

@ -42,6 +42,13 @@ define([
/* /*
Tools Tools
*/ */
var _ownedByMe = function (Env, owners) {
return Array.isArray(owners) && owners.indexOf(Env.edPublic) !== -1;
};
var _ownedByOther = function (Env, owners) {
return Array.isArray(owners) && owners.length &&
(!Env.edPublic || owners.indexOf(Env.edPublic) === -1);
};
var _getUserObjects = function (Env) { var _getUserObjects = function (Env) {
var userObjects = [Env.user.userObject]; var userObjects = [Env.user.userObject];
@ -206,21 +213,36 @@ define([
}; };
// Get a copy of the elements located in the given paths, with their files data // Get a copy of the elements located in the given paths, with their files data
var _getCopyFromPaths = function (paths, userObject) { // Note: This function is only called to move files from a proxy to another
var _getCopyFromPaths = function (Env, paths, userObject) {
var data = []; var data = [];
paths.forEach(function (path) { var toNotRemove = [];
paths.forEach(function (path, idx) {
var el = userObject.find(path); var el = userObject.find(path);
var files = []; var files = [];
var key = path[path.length - 1];
// Get the files ID from the current path (file or folder) // Get the files ID from the current path (file or folder)
if (userObject.isFile(el)) { if (userObject.isFile(el)) {
files.push(el); files.push(el);
} else if (userObject.isSharedFolder(el)) {
files.push(el);
var obj = Env.folders[el].proxy.metadata || {};
if (obj) { key = obj.title; }
} else { } else {
userObject.getFilesRecursively(el, files); userObject.getFilesRecursively(el, files);
} }
// Remove the shared folder from this list of files ID // If the element is a folder and it contains a shared folder, abort!
files.filter(function (f) { return !userObject.isSharedFolder(f); }); // We don't want nested shared folders!
if (files.some(function (f) { return userObject.isSharedFolder(f); })) {
if (Env.cfg && Env.cfg.log) {
Env.cfg.log(Messages._getKey('fm_moveNestedSF', [key]));
}
toNotRemove.unshift(idx);
return;
}
// Deduplicate // Deduplicate
files = Util.deduplicateString(files); files = Util.deduplicateString(files);
@ -237,9 +259,16 @@ define([
data.push({ data.push({
el: el, el: el,
data: filesData data: filesData,
key: key
}); });
}); });
// Remove from the "paths" array the elements that we don't want to move
toNotRemove.forEach(function (idx) {
paths.splice(idx, 1);
});
return data; return data;
}; };
@ -264,18 +293,19 @@ define([
// Move from the main drive to a shared folder // Move from the main drive to a shared folder
// Copy the elements to the new location // Copy the elements to the new location
var toCopy = _getCopyFromPaths(resolved.main, Env.user.userObject); var toCopy = _getCopyFromPaths(Env, resolved.main, Env.user.userObject);
var newUserObject = newResolved.userObject; var newUserObject = newResolved.userObject;
var ownedPads = []; var ownedPads = [];
toCopy.forEach(function (obj) { toCopy.forEach(function (obj) {
newUserObject.copyFromOtherDrive(newResolved.path, obj.el, obj.data); newUserObject.copyFromOtherDrive(newResolved.path, obj.el, obj.data, obj.key);
var _owned = Object.keys(obj.data).filter(function (id) { var _owned = Object.keys(obj.data).filter(function (id) {
var owners = obj.data[id].owners; var owners = obj.data[id].owners;
return Array.isArray(owners) && owners.indexOf(Env.edPublic) !== -1; return _ownedByMe(Env, owners);
}); });
Array.prototype.push.apply(ownedPads, _owned); Array.prototype.push.apply(ownedPads, _owned);
}); });
if (resolved.main.length) {
var rootPath = resolved.main[0].slice(); var rootPath = resolved.main[0].slice();
rootPath.pop(); rootPath.pop();
ownedPads = Util.deduplicateString(ownedPads); ownedPads = Util.deduplicateString(ownedPads);
@ -287,6 +317,7 @@ define([
Env.user.userObject.delete(resolved.main, waitFor()); Env.user.userObject.delete(resolved.main, waitFor());
} }
} }
}
var folderIds = Object.keys(resolved.folders); var folderIds = Object.keys(resolved.folders);
if (folderIds.length) { if (folderIds.length) {
// Move from a shared folder // Move from a shared folder
@ -302,9 +333,9 @@ define([
var uoTo = newResolved.userObject; var uoTo = newResolved.userObject;
// Copy the elements to the new location // Copy the elements to the new location
var toCopy = _getCopyFromPaths(paths, uoFrom); var toCopy = _getCopyFromPaths(Env, paths, uoFrom);
toCopy.forEach(function (obj) { toCopy.forEach(function (obj) {
uoTo.copyFromOtherDrive(newResolved.path, obj.el, obj.data); uoTo.copyFromOtherDrive(newResolved.path, obj.el, obj.data, obj.key);
}); });
// Remove the elements from the old location (without unpinning) // Remove the elements from the old location (without unpinning)
@ -415,7 +446,7 @@ define([
if (!Env.unpinPads || !_toUnpin) { return; } if (!Env.unpinPads || !_toUnpin) { return; }
Array.prototype.push.apply(toUnpin, _toUnpin); Array.prototype.push.apply(toUnpin, _toUnpin);
ownedRemoved = _ownedRemoved; ownedRemoved = _ownedRemoved;
}), data.nocheck, data.isOwnPadRemoved); }));
} }
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
// Check if removed owned pads are duplicated is some shared folders // Check if removed owned pads are duplicated is some shared folders
@ -440,7 +471,7 @@ define([
Env.folders[id].userObject.delete(resolved.folders[id], waitFor(function (err, _toUnpin) { Env.folders[id].userObject.delete(resolved.folders[id], waitFor(function (err, _toUnpin) {
if (!Env.unpinPads || !_toUnpin) { return; } if (!Env.unpinPads || !_toUnpin) { return; }
Array.prototype.push.apply(toUnpin, _toUnpin); Array.prototype.push.apply(toUnpin, _toUnpin);
}), data.nocheck, data.isOwnPadRemoved); }));
}); });
}).nThen(function (waitFor) { }).nThen(function (waitFor) {
if (!Env.unpinPads) { return; } if (!Env.unpinPads) { return; }
@ -589,8 +620,7 @@ define([
*/ */
// Get the list of channels filtered by a type (expirable channels, owned channels, pin list) // Get the list of channels filtered by a type (expirable channels, owned channels, pin list)
var getChannelsList = function (Env, edPublic, type) { var getChannelsList = function (Env, type) {
//if (!edPublic) { return; }
var result = []; var result = [];
var addChannel = function (userObject) { var addChannel = function (userObject) {
if (type === 'expirable') { if (type === 'expirable') {
@ -599,8 +629,7 @@ define([
// Don't push duplicates // Don't push duplicates
if (result.indexOf(data.channel) !== -1) { return; } if (result.indexOf(data.channel) !== -1) { return; }
// Return pads owned by someone else or expired by time // Return pads owned by someone else or expired by time
if ((data.owners && data.owners.length && (!edPublic || data.owners.indexOf(edPublic) === -1)) if (_ownedByOther(Env, data.owners) || (data.expire && data.expire < (+new Date()))) {
|| (data.expire && data.expire < (+new Date()))) {
result.push(data.channel); result.push(data.channel);
} }
}; };
@ -611,8 +640,7 @@ define([
// Don't push duplicates // Don't push duplicates
if (result.indexOf(data.channel) !== -1) { return; } if (result.indexOf(data.channel) !== -1) { return; }
// Return owned pads // Return owned pads
if (Array.isArray(data.owners) && data.owners.length && if (_ownedByMe(Env, data.owners)) {
data.owners.indexOf(edPublic) !== -1) {
result.push(data.channel); result.push(data.channel);
} }
}; };
@ -621,8 +649,7 @@ define([
return function (fileId) { return function (fileId) {
var data = userObject.getFileData(fileId); var data = userObject.getFileData(fileId);
// Don't pin pads owned by someone else // Don't pin pads owned by someone else
if (Array.isArray(data.owners) && data.owners.length && if (_ownedByOther(Env, data.owners)) { return; }
data.owners.indexOf(edPublic) === -1) { return; }
// Don't push duplicates // Don't push duplicates
if (result.indexOf(data.channel) === -1) { if (result.indexOf(data.channel) === -1) {
result.push(data.channel); result.push(data.channel);
@ -631,8 +658,8 @@ define([
} }
}; };
if (type === 'owned' && !edPublic) { return result; } if (type === 'owned' && !Env.edPublic) { return result; }
if (type === 'pin' && !edPublic) { return result; } if (type === 'pin' && !Env.edPublic) { return result; }
// Get the list of user objects // Get the list of user objects
var userObjects = _getUserObjects(Env); var userObjects = _getUserObjects(Env);
@ -646,8 +673,7 @@ define([
if (type === "owned") { if (type === "owned") {
var sfOwned = Object.keys(Env.user.proxy[UserObject.SHARED_FOLDERS]).filter(function (fId) { var sfOwned = Object.keys(Env.user.proxy[UserObject.SHARED_FOLDERS]).filter(function (fId) {
var owners = Env.user.proxy[UserObject.SHARED_FOLDERS][fId].owners; var owners = Env.user.proxy[UserObject.SHARED_FOLDERS][fId].owners;
if (Array.isArray(owners) && owners.length && if (_ownedByMe(Env, owners)) { return true; }
owners.indexOf(edPublic) !== -1) { return true; }
}).map(function (fId) { }).map(function (fId) {
return Env.user.proxy[UserObject.SHARED_FOLDERS][fId].channel; return Env.user.proxy[UserObject.SHARED_FOLDERS][fId].channel;
}); });
@ -672,10 +698,22 @@ define([
p = resolved.path; p = resolved.path;
} }
var todo = function () { var todo = function () {
uo.pushData(pad, function (e, id) { var error;
if (e) { return void cb(e); } nThen(function (waitFor) {
uo.pushData(pad, waitFor(function (e, id) {
if (e) { error = e; return; }
uo.add(id, p); uo.add(id, p);
cb(); }));
if (uo.id && _ownedByMe(Env, pad.owners)) {
// Creating an owned pad in a shared folder:
// We must add a copy in the user's personnal drive
Env.user.userObject.pushData(pad, waitFor(function (e, id) {
if (e) { error = e; return; }
Env.user.userObject.add(id, ['root']);
}));
}
}).nThen(function () {
cb(error);
}); });
}; };
if (!Env.pinPads) { return void todo(); } if (!Env.pinPads) { return void todo(); }
@ -777,14 +815,11 @@ define([
} }
}, cb); }, cb);
}; };
var deleteInner = function (Env, paths, cb, nocheck, isOwnPadRemoved, noUnpin) { var deleteInner = function (Env, paths, cb) {
return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", { return void Env.sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "delete", cmd: "delete",
data: { data: {
paths: paths, paths: paths,
nocheck: nocheck,
noUnpin: noUnpin,
isOwnPadRemoved: isOwnPadRemoved
} }
}, cb); }, cb);
}; };
@ -857,7 +892,7 @@ define([
}; };
var getSharedFolderData = function (Env, id) { var getSharedFolderData = function (Env, id) {
if (!Env.folders[id]) { return; } if (!Env.folders[id]) { return {}; }
var obj = Env.folders[id].proxy.metadata || {}; var obj = Env.folders[id].proxy.metadata || {};
for (var k in Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {}) { for (var k in Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {}) {
obj[k] = Env.user.proxy[UserObject.SHARED_FOLDERS][id][k]; obj[k] = Env.user.proxy[UserObject.SHARED_FOLDERS][id][k];

@ -579,19 +579,18 @@ define([
// DELETE // DELETE
// Permanently delete multiple files at once using a list of paths // Permanently delete multiple files at once using a list of paths
// NOTE: We have to be careful when removing elements from arrays (trash root, unsorted or template) // NOTE: We have to be careful when removing elements from arrays (trash root, unsorted or template)
exp.delete = function (paths, cb, nocheck, isOwnPadRemoved) { exp.delete = function (paths, cb, nocheck) {
if (sframeChan) { if (sframeChan) {
return void sframeChan.query("Q_DRIVE_USEROBJECT", { return void sframeChan.query("Q_DRIVE_USEROBJECT", {
cmd: "delete", cmd: "delete",
data: { data: {
paths: paths, paths: paths,
nocheck: nocheck, nocheck: nocheck,
isOwnPadRemoved: isOwnPadRemoved
} }
}, cb); }, cb);
} }
cb = cb || function () {}; cb = cb || function () {};
exp.deleteMultiplePermanently(paths, nocheck, isOwnPadRemoved, cb); exp.deleteMultiplePermanently(paths, nocheck, cb);
//if (typeof cb === "function") { cb(); } //if (typeof cb === "function") { cb(); }
}; };
exp.emptyTrash = function (cb) { exp.emptyTrash = function (cb) {
@ -602,7 +601,7 @@ define([
}, cb); }, cb);
} }
files[TRASH] = {}; files[TRASH] = {};
exp.checkDeletedFiles(false, cb); exp.checkDeletedFiles(cb);
}; };
// RENAME // RENAME

@ -782,6 +782,7 @@
} }
.cp-app-drive-toolbar-rightside { .cp-app-drive-toolbar-rightside {
float: right; float: right;
flex-shrink: 0;
& > * { & > * {
float: right; float: right;
} }
@ -842,6 +843,8 @@
white-space: nowrap; white-space: nowrap;
display: flex; display: flex;
flex-flow: row-reverse; flex-flow: row-reverse;
flex-shrink: 1;
min-width: 50px;
max-width: 100%; max-width: 100%;
text-align: left; text-align: left;
.cp-app-drive-path-element { .cp-app-drive-path-element {

@ -2750,12 +2750,13 @@ define([
if (!manager.isFolder(root[key])) { return; } if (!manager.isFolder(root[key])) { return; }
var newPath = path.slice(); var newPath = path.slice();
newPath.push(key); newPath.push(key);
var nextPath = newPath.slice();
var isSharedFolder = manager.isSharedFolder(root[key]); var isSharedFolder = manager.isSharedFolder(root[key]);
var $icon, isCurrentFolder, subfolder; var $icon, isCurrentFolder, subfolder;
if (isSharedFolder) { if (isSharedFolder) {
var fId = root[key]; var fId = root[key];
// Fix path // Fix path
newPath.push(manager.user.userObject.ROOT); nextPath.push(manager.user.userObject.ROOT);
isCurrentFolder = manager.comparePath(newPath, currentPath); isCurrentFolder = manager.comparePath(newPath, currentPath);
// Subfolders? // Subfolders?
var newRoot = manager.folders[fId].proxy[manager.user.userObject.ROOT]; var newRoot = manager.folders[fId].proxy[manager.user.userObject.ROOT];
@ -2779,7 +2780,7 @@ define([
$element.find('>.cp-app-drive-element-row') $element.find('>.cp-app-drive-element-row')
.addClass('cp-app-drive-element-sharedf'); .addClass('cp-app-drive-element-sharedf');
} }
createTree($element, newPath); createTree($element, nextPath);
}); });
}; };
@ -2957,6 +2958,8 @@ define([
if (manager.isSharedFolder(el)) { if (manager.isSharedFolder(el)) {
delete data.roHref; delete data.roHref;
data.noPassword = true;
data.noExpiration = true;
} }
UIElements.getProperties(common, data, cb); UIElements.getProperties(common, data, cb);

Loading…
Cancel
Save