Merge branch 'sfAllow' into staging
commit
cb1701ec97
|
@ -159,6 +159,10 @@
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
.cp-app-drive-element-restricted {
|
||||
color: #939393;
|
||||
}
|
||||
|
||||
.cp-app-drive-element-droppable {
|
||||
background-color: @drive_droppable-bg;
|
||||
color: #222;
|
||||
|
|
|
@ -129,6 +129,7 @@ define([
|
|||
//var $ownerIcon = $('<span>', {"class": "fa fa-id-card"});
|
||||
var $tagsIcon = $('<span>', {"class": "fa " + faTags});
|
||||
var $passwordIcon = $('<span>', {"class": "fa fa-lock"});
|
||||
var $restrictedIcon = $('<span>', {"class": "fa fa-ban"});
|
||||
var $expirableIcon = $('<span>', {"class": "fa fa-clock-o"});
|
||||
var $separator = $('<div>', {"class": "dropdown-divider"});
|
||||
|
||||
|
@ -1211,6 +1212,9 @@ define([
|
|||
if (!$element.is('.cp-app-drive-element-owned')) {
|
||||
hide.push('deleteowned');
|
||||
}
|
||||
if ($element.is('.cp-app-drive-element-restricted')) {
|
||||
hide.push('rename', 'download', 'share', 'access', 'color');
|
||||
}
|
||||
if ($element.is('.cp-app-drive-element-notrash')) {
|
||||
// We can't delete elements in virtual categories
|
||||
hide.push('delete');
|
||||
|
@ -1949,7 +1953,8 @@ define([
|
|||
var $ro;
|
||||
if (manager.isSharedFolder(element)) {
|
||||
var data = manager.getSharedFolderData(element);
|
||||
key = data && data.title ? data.title : key;
|
||||
var fId = element;
|
||||
key = data.title || data.lastTitle;
|
||||
element = manager.folders[element].proxy[manager.user.userObject.ROOT];
|
||||
$span.addClass('cp-app-drive-element-sharedf');
|
||||
_addOwnership($span, $state, data);
|
||||
|
@ -1964,6 +1969,11 @@ define([
|
|||
$ro.attr('title', Messages.readonly);
|
||||
}
|
||||
|
||||
if (files.restrictedFolders[fId]) {
|
||||
var $restricted = $restrictedIcon.clone().appendTo($state);
|
||||
$restricted.attr('title', Messages.fm_restricted);
|
||||
}
|
||||
|
||||
var $shared = $sharedIcon.clone().appendTo($state);
|
||||
$shared.attr('title', Messages.fm_canBeShared);
|
||||
} else if ($content.data('readOnlyFolder') || APP.readOnly) {
|
||||
|
@ -1972,14 +1982,14 @@ define([
|
|||
}
|
||||
|
||||
var sf = manager.hasSubfolder(element);
|
||||
var files = manager.hasFile(element);
|
||||
var hasFiles = manager.hasFile(element);
|
||||
var $name = $('<span>', {'class': 'cp-app-drive-element-name'}).text(key);
|
||||
var $subfolders = $('<span>', {
|
||||
'class': 'cp-app-drive-element-folders cp-app-drive-element-list'
|
||||
}).text(sf);
|
||||
var $files = $('<span>', {
|
||||
'class': 'cp-app-drive-element-files cp-app-drive-element-list'
|
||||
}).text(files);
|
||||
}).text(hasFiles);
|
||||
var $filler = $('<span>', {
|
||||
'class': 'cp-app-drive-element-filler cp-app-drive-element-list'
|
||||
});
|
||||
|
@ -2034,6 +2044,7 @@ define([
|
|||
return $shareBlock;
|
||||
};
|
||||
|
||||
Messages.fm_restricted = "Forbidden access"; // XXX
|
||||
// Create the "li" element corresponding to the file/folder located in "path"
|
||||
var createElement = function (path, elPath, root, isFolder) {
|
||||
// Forbid drag&drop inside the trash
|
||||
|
@ -2051,32 +2062,38 @@ define([
|
|||
element = root[key];
|
||||
}
|
||||
|
||||
var restricted = files.restrictedFolders[element];
|
||||
var isSharedFolder = manager.isSharedFolder(element);
|
||||
|
||||
var $icon = !isFolder ? getFileIcon(element) : undefined;
|
||||
var ro = manager.isReadOnlyFile(element);
|
||||
// ro undefined means it's an old hash which doesn't support read-only
|
||||
var roClass = typeof(ro) === 'undefined' ?' cp-app-drive-element-noreadonly' :
|
||||
ro ? ' cp-app-drive-element-readonly' : '';
|
||||
var liClass = 'cp-app-drive-element-file cp-app-drive-element' + roClass;
|
||||
var roClass = typeof(ro) === 'undefined' ? '.cp-app-drive-element-noreadonly' :
|
||||
ro ? '.cp-app-drive-element-readonly' : '';
|
||||
var liClass = '.cp-app-drive-element-file';
|
||||
var restrictedClass = restricted ? '.cp-app-drive-element-restricted' : '';
|
||||
if (isSharedFolder) {
|
||||
liClass = 'cp-app-drive-element-folder cp-app-drive-element';
|
||||
liClass = '.cp-app-drive-element-folder';
|
||||
$icon = $sharedFolderIcon.clone();
|
||||
$icon.css("color", getFolderColor(path.concat(elPath)));
|
||||
} else if (isFolder) {
|
||||
liClass = 'cp-app-drive-element-folder cp-app-drive-element';
|
||||
liClass = '.cp-app-drive-element-folder';
|
||||
$icon = manager.isFolderEmpty(root[key]) ? $folderEmptyIcon.clone() : $folderIcon.clone();
|
||||
$icon.css("color", getFolderColor(path.concat(elPath)));
|
||||
}
|
||||
var $element = $('<li>', {
|
||||
draggable: true,
|
||||
'class': 'cp-app-drive-element-row'
|
||||
});
|
||||
var classes = restrictedClass + roClass + liClass;
|
||||
var $element = $(h('li.cp-app-drive-element.cp-app-drive-element-row' + classes, {
|
||||
draggable: true
|
||||
}));
|
||||
$element.data('path', newPath);
|
||||
if (isElementSelected($element)) {
|
||||
selectElement($element);
|
||||
}
|
||||
$element.prepend($icon).dblclick(function () {
|
||||
if (restricted) {
|
||||
UI.warn(Messages.fm_restricted);
|
||||
return;
|
||||
}
|
||||
if (isFolder) {
|
||||
APP.displayDirectory(newPath);
|
||||
return;
|
||||
|
@ -2100,8 +2117,7 @@ define([
|
|||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
$element.addClass(liClass);
|
||||
var droppable = !isTrash && !APP.$content.data('readOnlyFolder');
|
||||
var droppable = !isTrash && !APP.$content.data('readOnlyFolder') && !restricted;
|
||||
addDragAndDropHandlers($element, newPath, isFolder, droppable);
|
||||
$element.click(function(e) {
|
||||
e.stopPropagation();
|
||||
|
@ -3600,6 +3616,13 @@ define([
|
|||
var $list = $('<ul>').appendTo($dirContent);
|
||||
|
||||
var sfId = manager.isInSharedFolder(currentPath);
|
||||
|
||||
// Restricted folder? display ROOT instead
|
||||
if (sfId && files.restrictedFolders[sfId]) {
|
||||
_displayDirectory([ROOT], true);
|
||||
return;
|
||||
}
|
||||
|
||||
var readOnlyFolder = false;
|
||||
if (APP.readOnly) {
|
||||
// Read-only drive (team?)
|
||||
|
@ -3753,8 +3776,15 @@ define([
|
|||
}
|
||||
var $elementRow = $('<span>', {'class': 'cp-app-drive-element-row'}).append($collapse).append($icon).append($name).click(function (e) {
|
||||
e.stopPropagation();
|
||||
if (files.restrictedFolders[isSharedFolder]) {
|
||||
UI.warn(Messages.fm_restricted);
|
||||
return;
|
||||
}
|
||||
APP.displayDirectory(path);
|
||||
});
|
||||
if (files.restrictedFolders[isSharedFolder]) {
|
||||
$elementRow.addClass('cp-app-drive-element-restricted');
|
||||
}
|
||||
if (isSharedFolder) {
|
||||
var sfData = manager.getSharedFolderData(isSharedFolder);
|
||||
_addOwnership($elementRow, $(), sfData);
|
||||
|
@ -3837,7 +3867,7 @@ define([
|
|||
if (!manager.isFolder(root[key])) { return; }
|
||||
var newPath = path.slice();
|
||||
newPath.push(key);
|
||||
var isSharedFolder = manager.isSharedFolder(root[key]);
|
||||
var isSharedFolder = manager.isSharedFolder(root[key]) && root[key];
|
||||
var sfId = manager.isInSharedFolder(newPath) || (isSharedFolder && root[key]);
|
||||
var $icon, isCurrentFolder, subfolder;
|
||||
if (isSharedFolder) {
|
||||
|
@ -4130,6 +4160,10 @@ define([
|
|||
else if ($this.hasClass('cp-app-drive-context-open')) {
|
||||
paths.forEach(function (p) {
|
||||
var el = manager.find(p.path);
|
||||
if (files.restrictedFolders[el]) {
|
||||
UI.warn(Messages.fm_restricted);
|
||||
return;
|
||||
}
|
||||
openFile(el, false, true);
|
||||
});
|
||||
}
|
||||
|
@ -4715,7 +4749,6 @@ define([
|
|||
});
|
||||
}
|
||||
*/
|
||||
var deprecated = files.sharedFoldersTemp;
|
||||
var nt = nThen;
|
||||
var passwordModal = function (fId, data, cb) {
|
||||
var content = [];
|
||||
|
@ -4771,6 +4804,7 @@ define([
|
|||
onClose: cb
|
||||
});
|
||||
};
|
||||
var deprecated = files.sharedFoldersTemp;
|
||||
if (typeof (deprecated) === "object" && APP.editable && Object.keys(deprecated).length) {
|
||||
Object.keys(deprecated).forEach(function (fId) {
|
||||
var data = deprecated[fId];
|
||||
|
@ -4787,7 +4821,6 @@ define([
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
refresh: refresh,
|
||||
close: function () {
|
||||
|
|
|
@ -372,8 +372,7 @@ define([
|
|||
var parsed = Hash.parsePadUrl(data.href || data.roHref);
|
||||
var owned = Modal.isOwned(Env, data);
|
||||
var disabled = !owned || !parsed.hashData || parsed.hashData.type !== 'pad';
|
||||
var allowDisabled = parsed.type === 'drive';
|
||||
if (disabled || allowDisabled) { return void cb(); }
|
||||
if (disabled) { return void cb(); }
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
|
|
|
@ -2083,6 +2083,9 @@ define([
|
|||
Store.addSharedFolder = function (clientId, data, cb) {
|
||||
var s = getStore(data.teamId);
|
||||
s.manager.addSharedFolder(data, function (id) {
|
||||
if (id && typeof(id) === "object" && id.error) {
|
||||
return void cb(id);
|
||||
}
|
||||
var send = data.teamId ? s.sendEvent : sendDriveEvent;
|
||||
send('DRIVE_CHANGE', {
|
||||
path: ['drive', UserObject.FILES_DATA]
|
||||
|
@ -2188,6 +2191,8 @@ define([
|
|||
});
|
||||
};
|
||||
registerProxyEvents = function (proxy, fId) {
|
||||
if (!proxy) { return; }
|
||||
if (proxy.deprecated || proxy.restricted) { return; }
|
||||
if (!fId) {
|
||||
// Listen for shared folder password change
|
||||
proxy.on('change', ['drive', UserObject.SHARED_FOLDERS], function (o, n, p) {
|
||||
|
|
|
@ -225,6 +225,7 @@ define([
|
|||
sf.teams.forEach(function (obj) {
|
||||
obj.store.manager.restrictedProxy(obj.id, secret.channel);
|
||||
});
|
||||
delete allSharedFolders[secret.channel];
|
||||
return void cb();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ define([
|
|||
};
|
||||
|
||||
var restrictedProxy = function (Env, id) {
|
||||
var lm = { proxy: { deprecated: true } };
|
||||
var lm = { proxy: { restricted: true, root: {}, filesData: {} } };
|
||||
removeProxy(Env, id);
|
||||
addProxy(Env, id, lm, function () {});
|
||||
return void Env.Store.refreshDriveUI();
|
||||
|
@ -215,7 +215,7 @@ define([
|
|||
if (!Env.folders[id]) { return {}; }
|
||||
var obj = Env.folders[id].proxy.metadata || {};
|
||||
for (var k in Env.user.proxy[UserObject.SHARED_FOLDERS][id] || {}) {
|
||||
var data = JSON.parse(JSON.stringify(Env.user.proxy[UserObject.SHARED_FOLDERS][id][k]));
|
||||
var data = Util.clone(Env.user.proxy[UserObject.SHARED_FOLDERS][id][k] || {});
|
||||
if (k === "href" && data.indexOf('#') === -1) {
|
||||
try {
|
||||
data = Env.user.userObject.cryptor.decrypt(data);
|
||||
|
@ -491,6 +491,17 @@ define([
|
|||
};
|
||||
if (data.password) { folderData.password = data.password; }
|
||||
if (data.owned) { folderData.owners = [Env.edPublic]; }
|
||||
}).nThen(function (waitFor) {
|
||||
Env.Store.getPadMetadata(null, {
|
||||
channel: folderData.channel
|
||||
}, waitFor(function (obj) {
|
||||
if (obj && (obj.error || obj.rejected)) {
|
||||
waitFor.abort();
|
||||
return void cb({
|
||||
error: obj.error || 'ERESTRICTED'
|
||||
});
|
||||
}
|
||||
}));
|
||||
}).nThen(function (waitFor) {
|
||||
Env.pinPads([folderData.channel], waitFor());
|
||||
}).nThen(function (waitFor) {
|
||||
|
|
|
@ -378,7 +378,7 @@ define([
|
|||
}
|
||||
}).nThen(function (waitFor) {
|
||||
if (cfg.afterSecrets) {
|
||||
cfg.afterSecrets(Cryptpad, Utils, secret, waitFor());
|
||||
cfg.afterSecrets(Cryptpad, Utils, secret, waitFor(), sframeChan);
|
||||
}
|
||||
}).nThen(function (waitFor) {
|
||||
// Check if the pad exists on server
|
||||
|
|
|
@ -671,6 +671,10 @@ define([
|
|||
UIElements.displayPasswordPrompt(funcs, cfg);
|
||||
});
|
||||
|
||||
ctx.sframeChan.on("EV_RESTRICTED_ERROR", function () {
|
||||
UI.errorLoadingScreen(Messages.restrictedError);
|
||||
});
|
||||
|
||||
ctx.sframeChan.on("EV_PAD_PASSWORD_ERROR", function () {
|
||||
UI.errorLoadingScreen(Messages.password_error_seed);
|
||||
});
|
||||
|
|
|
@ -42,6 +42,7 @@ define([
|
|||
if (!drive || !drive.sharedFolders) {
|
||||
return void cb();
|
||||
}
|
||||
var r = drive.restrictedFolders = drive.restrictedFolders || {};
|
||||
var oldIds = Object.keys(folders);
|
||||
nThen(function (waitFor) {
|
||||
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
||||
|
@ -60,7 +61,11 @@ define([
|
|||
APP.newSharedFolder = null;
|
||||
}
|
||||
}
|
||||
if (newObj && newObj.deprecated) {
|
||||
if (newObj && newObj.restricted) {
|
||||
r[fId] = drive.sharedFolders[fId];
|
||||
if (!r[fId].title) { r[fId].title = r[fId].lastTitle; }
|
||||
}
|
||||
if (newObj && (newObj.deprecated /*|| newObj.restricted*/)) {
|
||||
delete folders[fId];
|
||||
delete drive.sharedFolders[fId];
|
||||
if (manager && manager.folders) {
|
||||
|
|
|
@ -45,11 +45,16 @@ define([
|
|||
};
|
||||
window.addEventListener('message', onMsg);
|
||||
}).nThen(function (/*waitFor*/) {
|
||||
var afterSecrets = function (Cryptpad, Utils, secret, cb) {
|
||||
var afterSecrets = function (Cryptpad, Utils, secret, cb, sframeChan) {
|
||||
var _hash = hash.slice(1);
|
||||
if (_hash && Utils.LocalStore.isLoggedIn()) {
|
||||
// Add a shared folder!
|
||||
Cryptpad.addSharedFolder(null, secret, function (id) {
|
||||
if (id && typeof(id) === "object" && id.error) {
|
||||
sframeChan.event("EV_RESTRICTED_ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
window.CryptPad_newSharedFolder = id;
|
||||
|
||||
// Clear the hash now that the secrets have been generated
|
||||
|
|
|
@ -55,6 +55,7 @@ define([
|
|||
if (!drive || !drive.sharedFolders) {
|
||||
return void cb();
|
||||
}
|
||||
var r = drive.restrictedFolders = drive.restrictedFolders || {};
|
||||
var oldIds = Object.keys(folders);
|
||||
nThen(function (waitFor) {
|
||||
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
||||
|
@ -65,7 +66,11 @@ define([
|
|||
sframeChan.query('Q_DRIVE_GETOBJECT', {
|
||||
sharedFolder: fId
|
||||
}, waitFor(function (err, newObj) {
|
||||
if (newObj && newObj.deprecated) {
|
||||
if (newObj && newObj.restricted) {
|
||||
r[fId] = drive.sharedFolders[fId];
|
||||
if (!r[fId].title) { r[fId].title = r[fId].lastTitle; }
|
||||
}
|
||||
if (newObj && (newObj.deprecated || newObj.restricted)) {
|
||||
delete folders[fId];
|
||||
delete drive.sharedFolders[fId];
|
||||
if (manager && manager.folders) {
|
||||
|
|
Loading…
Reference in New Issue