mirror of https://github.com/xwiki-labs/cryptpad
341 lines
13 KiB
JavaScript
341 lines
13 KiB
JavaScript
// SPDX-FileCopyrightText: 2023 XWiki CryptPad Team <contact@cryptpad.org> and contributors
|
||
//
|
||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||
|
||
define([
|
||
'jquery',
|
||
'/common/toolbar.js',
|
||
'/common/drive-ui.js',
|
||
'/common/common-util.js',
|
||
'/common/common-hash.js',
|
||
'/common/common-interface.js',
|
||
'/common/common-ui-elements.js',
|
||
'/common/common-feedback.js',
|
||
'/components/nthen/index.js',
|
||
'/common/sframe-common.js',
|
||
'/common/proxy-manager.js',
|
||
'/customize/application_config.js',
|
||
'/customize/messages.js',
|
||
|
||
'css!/components/bootstrap/dist/css/bootstrap.min.css',
|
||
'css!/components/components-font-awesome/css/font-awesome.min.css',
|
||
'less!/drive/app-drive.less',
|
||
], function (
|
||
$,
|
||
Toolbar,
|
||
DriveUI,
|
||
Util,
|
||
Hash,
|
||
UI,
|
||
UIElements,
|
||
Feedback,
|
||
nThen,
|
||
SFCommon,
|
||
ProxyManager,
|
||
AppConfig,
|
||
Messages)
|
||
{
|
||
var APP = {};
|
||
var SHARED_FOLDER_NAME = Messages.fm_sharedFolderName;
|
||
|
||
var copyObjectValue = function (objRef, objToCopy) {
|
||
for (var k in objRef) { delete objRef[k]; }
|
||
$.extend(true, objRef, objToCopy);
|
||
};
|
||
var updateSharedFolders = function (sframeChan, manager, drive, folders, cb) {
|
||
if (!drive || !drive.sharedFolders) {
|
||
return void cb();
|
||
}
|
||
var r = drive.restrictedFolders = {};
|
||
var oldIds = Object.keys(folders);
|
||
nThen(function (waitFor) {
|
||
Object.keys(drive.sharedFolders).forEach(function (fId) {
|
||
var sfData = drive.sharedFolders[fId] || {};
|
||
var href = (sfData.href && sfData.href.indexOf('#') !== -1) ? sfData.href : sfData.roHref;
|
||
var parsed = Hash.parsePadUrl(href);
|
||
var secret = Hash.getSecrets('drive', parsed.hash, sfData.password);
|
||
sframeChan.query('Q_DRIVE_GETOBJECT', {
|
||
sharedFolder: fId
|
||
}, waitFor(function (err, newObj) {
|
||
if (!APP.loggedIn && APP.newSharedFolder) {
|
||
if (!newObj || !Object.keys(newObj).length) {
|
||
// Empty anon drive: deleted
|
||
var msg = Messages.deletedError + '<br>' + Messages.errorRedirectToHome;
|
||
setTimeout(function () { UI.errorLoadingScreen(msg, false, true); });
|
||
APP.newSharedFolder = null;
|
||
}
|
||
}
|
||
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) {
|
||
delete manager.folders[fId];
|
||
}
|
||
return;
|
||
}
|
||
folders[fId] = folders[fId] || {};
|
||
copyObjectValue(folders[fId], newObj);
|
||
folders[fId].readOnly = !secret.keys.secondaryKey;
|
||
if (manager && oldIds.indexOf(fId) === -1) {
|
||
manager.addProxy(fId, { proxy: folders[fId] }, null, secret.keys.secondaryKey);
|
||
}
|
||
var readOnly = !secret.keys.editKeyStr;
|
||
if (!manager || !manager.folders[fId]) { return; }
|
||
manager.folders[fId].userObject.setReadOnly(readOnly, secret.keys.secondaryKey);
|
||
|
||
manager.folders[fId].offline = newObj.offline;
|
||
}));
|
||
});
|
||
// Remove from memory folders that have been deleted from the drive remotely
|
||
oldIds.forEach(function (fId) {
|
||
if (!drive.sharedFolders[fId]) {
|
||
delete folders[fId];
|
||
delete drive.sharedFolders[fId];
|
||
if (manager && manager.folders) {
|
||
delete manager.folders[fId];
|
||
}
|
||
}
|
||
});
|
||
}).nThen(function () {
|
||
cb();
|
||
});
|
||
};
|
||
var updateObject = function (sframeChan, obj, cb) {
|
||
sframeChan.query('Q_DRIVE_GETOBJECT', null, function (err, newObj) {
|
||
copyObjectValue(obj, newObj);
|
||
// If anon shared folder, make a virtual drive containing this folder
|
||
if (!APP.loggedIn && APP.newSharedFolder) {
|
||
obj.drive.root = {
|
||
sf: APP.newSharedFolder
|
||
};
|
||
obj.drive.sharedFolders = obj.drive.sharedFolders || {};
|
||
obj.drive.sharedFolders[APP.newSharedFolder] = {
|
||
href: APP.anonSFHref,
|
||
password: APP.anonSFPassword
|
||
};
|
||
}
|
||
cb();
|
||
});
|
||
};
|
||
|
||
var history = {
|
||
isHistoryMode: false,
|
||
};
|
||
|
||
var setEditable = DriveUI.setEditable;
|
||
|
||
var setHistory = function (bool, update) {
|
||
history.isHistoryMode = bool;
|
||
setEditable(!bool, true);
|
||
if (!bool && update) {
|
||
history.onLeaveHistory();
|
||
}
|
||
return true;
|
||
};
|
||
|
||
var main = function () {
|
||
var common;
|
||
var proxy = {};
|
||
var folders = {};
|
||
|
||
var startOnline = false;
|
||
var onReco;
|
||
|
||
nThen(function (waitFor) {
|
||
$(waitFor(function () {
|
||
UI.addLoadingScreen();
|
||
}));
|
||
window.cryptpadStore.getAll(waitFor(function (val) {
|
||
APP.store = JSON.parse(JSON.stringify(val));
|
||
}));
|
||
SFCommon.create(waitFor(function (c) { common = c; }));
|
||
}).nThen(function (waitFor) {
|
||
onReco = common.getSframeChannel().on('EV_NETWORK_RECONNECT', function () {
|
||
startOnline = true;
|
||
});
|
||
|
||
$('#cp-app-drive-connection-state').text(Messages.disconnected);
|
||
var privReady = Util.once(waitFor());
|
||
var metadataMgr = common.getMetadataMgr();
|
||
if (JSON.stringify(metadataMgr.getPrivateData()) !== '{}') {
|
||
privReady();
|
||
return;
|
||
}
|
||
metadataMgr.onChange(function () {
|
||
if (typeof(metadataMgr.getPrivateData().readOnly) === 'boolean') {
|
||
APP.readOnly = metadataMgr.getPrivateData().readOnly;
|
||
privReady();
|
||
}
|
||
});
|
||
}).nThen(function (waitFor) {
|
||
APP.loggedIn = common.isLoggedIn();
|
||
if (!APP.loggedIn) { Feedback.send('ANONYMOUS_DRIVE'); }
|
||
APP.$body = $('body');
|
||
APP.$bar = $('#cp-toolbar');
|
||
|
||
common.setTabTitle(Messages.type.drive);
|
||
|
||
var metadataMgr = common.getMetadataMgr();
|
||
var privateData = metadataMgr.getPrivateData();
|
||
if (privateData.newSharedFolder) {
|
||
APP.newSharedFolder = privateData.newSharedFolder;
|
||
APP.anonSFHref = privateData.anonSFHref;
|
||
APP.anonSFPassword = privateData.password;
|
||
}
|
||
|
||
var sframeChan = common.getSframeChannel();
|
||
updateObject(sframeChan, proxy, waitFor(function () {
|
||
updateSharedFolders(sframeChan, null, proxy.drive, folders, waitFor());
|
||
}));
|
||
}).nThen(function () {
|
||
var sframeChan = common.getSframeChannel();
|
||
var metadataMgr = common.getMetadataMgr();
|
||
var privateData = metadataMgr.getPrivateData();
|
||
var user = metadataMgr.getUserData();
|
||
|
||
APP.disableSF = !privateData.enableSF && AppConfig.disableSharedFolders;
|
||
if (APP.newSharedFolder && !APP.loggedIn) {
|
||
APP.readOnly = true;
|
||
var data = folders[APP.newSharedFolder];
|
||
if (data) {
|
||
sframeChan.query('Q_SET_PAD_TITLE_IN_DRIVE', {
|
||
title: data.metadata && data.metadata.title,
|
||
}, function () {});
|
||
}
|
||
}
|
||
|
||
// ANON_SHARED_FOLDER
|
||
var pageTitle = (!APP.loggedIn && APP.newSharedFolder) ? SHARED_FOLDER_NAME : Messages.type.drive;
|
||
|
||
var configTb = {
|
||
displayed: ['useradmin', 'pageTitle', 'newpad', 'limit', 'notifications'],
|
||
pageTitle: pageTitle,
|
||
metadataMgr: metadataMgr,
|
||
readOnly: privateData.readOnly,
|
||
sfCommon: common,
|
||
$container: APP.$bar
|
||
};
|
||
var toolbar = Toolbar.create(configTb);
|
||
|
||
var helpMenu = common.createHelpMenu(['drive']);
|
||
APP.help = helpMenu.menu;
|
||
$('#cp-app-drive-content-container').prepend(helpMenu.menu);
|
||
|
||
|
||
var $displayName = APP.$bar.find('.' + Toolbar.constants.username);
|
||
metadataMgr.onChange(function () {
|
||
var name = metadataMgr.getUserData().name || Messages.anonymous;
|
||
$displayName.text(name);
|
||
});
|
||
$displayName.text(user.name || Messages.anonymous);
|
||
|
||
|
||
/* add the usage */
|
||
var usageBar;
|
||
if (APP.loggedIn) {
|
||
usageBar = common.createUsageBar(null, function (err) {
|
||
if (err) { return void DriveUI.logError(err); }
|
||
}, true);
|
||
}
|
||
|
||
/* add a history button */
|
||
APP.histConfig = {
|
||
onLocal: function () {
|
||
UI.addLoadingScreen({ loadingText: Messages.fm_restoreDrive });
|
||
var data = {};
|
||
if (history.sfId) {
|
||
copyObjectValue(folders[history.sfId], history.currentObj);
|
||
data.sfId = history.sfId;
|
||
data.drive = history.currentObj;
|
||
} else {
|
||
proxy.drive = history.currentObj.drive;
|
||
data.drive = history.currentObj.drive;
|
||
}
|
||
sframeChan.query("Q_DRIVE_RESTORE", data, function () {
|
||
UI.removeLoadingScreen();
|
||
}, {
|
||
timeout: 5 * 60 * 1000
|
||
});
|
||
},
|
||
onOpen: function () {},
|
||
onRemote: function () {},
|
||
setHistory: setHistory,
|
||
applyVal: function (val) {
|
||
var obj = JSON.parse(val || '{}');
|
||
history.currentObj = obj;
|
||
history.onEnterHistory(obj);
|
||
},
|
||
drive: true,
|
||
$toolbar: APP.$bar,
|
||
};
|
||
|
||
// Add a "Burn this drive" button
|
||
if (!APP.loggedIn && !APP.readOnly) {
|
||
APP.$burnThisDrive = common.createButton(null, true, {
|
||
text: '',
|
||
name: 'burn-anon-drive',
|
||
icon: 'fa-ban',
|
||
tippy: Messages.fm_burnThisDriveButton,
|
||
drawer: false
|
||
}, function () {
|
||
var confirmContent = UIElements.fixInlineBRs(Messages.fm_burnThisDrive);
|
||
UI.confirm(confirmContent, function (yes) {
|
||
if (!yes) { return; }
|
||
common.getSframeChannel().event('EV_BURN_ANON_DRIVE');
|
||
});
|
||
});
|
||
}
|
||
|
||
$('body').css('display', '');
|
||
if (!proxy.drive || typeof(proxy.drive) !== 'object') {
|
||
throw new Error("Corrupted drive");
|
||
}
|
||
APP.online = startOnline || !privateData.offline;
|
||
var drive = DriveUI.create(common, {
|
||
$limit: usageBar && usageBar.$container,
|
||
proxy: proxy,
|
||
folders: folders,
|
||
updateObject: updateObject,
|
||
updateSharedFolders: updateSharedFolders,
|
||
history: history,
|
||
toolbar: toolbar,
|
||
APP: APP
|
||
});
|
||
|
||
var onDisconnect = function (noAlert) {
|
||
setEditable(false);
|
||
if (drive.refresh) { drive.refresh(); }
|
||
toolbar.failed();
|
||
if (!noAlert) { UIElements.disconnectAlert(); }
|
||
};
|
||
var onReconnect = function () {
|
||
setEditable(true);
|
||
if (drive.refresh) { drive.refresh(); }
|
||
toolbar.reconnecting();
|
||
UIElements.reconnectAlert();
|
||
};
|
||
|
||
sframeChan.on('EV_DRIVE_LOG', function (msg) {
|
||
UI.log(msg);
|
||
});
|
||
sframeChan.on('EV_NETWORK_DISCONNECT', function () {
|
||
onDisconnect();
|
||
});
|
||
onReco.stop();
|
||
sframeChan.on('EV_NETWORK_RECONNECT', function () {
|
||
onReconnect();
|
||
});
|
||
common.onLogout(function () { setEditable(false); });
|
||
|
||
// Check if our drive history needs to be trimmed
|
||
common.checkTrimHistory(null, true);
|
||
|
||
});
|
||
};
|
||
main();
|
||
});
|