Archive and restore UI in the admin panel

pull/1/head
yflory 4 years ago
parent 7b68a868ce
commit bd4b44476d

@ -167,12 +167,19 @@ var archiveDocument = function (Env, Server, cb, data) {
// Env.blobStore.archive.proof(userSafeKey, blobId, cb)
};
var restoreArchivedDocument = function (Env, Server, cb) {
// Env.msgStore.restoreArchivedChannel(channelName, cb)
// Env.blobStore.restore.blob(blobId, cb)
// Env.blobStore.restore.proof(userSafekey, blobId, cb)
var restoreArchivedDocument = function (Env, Server, cb, data) {
var id = Array.isArray(data) && data[1];
if (typeof(id) !== 'string' || id.length < 32) { return void cb("EINVAL"); }
cb("NOT_IMPLEMENTED");
switch (id.length) {
case 32:
return void Env.msgStore.restoreArchivedChannel(id, cb);
case 48:
// Env.blobStore.restore.proof(userSafekey, id, cb) // XXX ....
return void Env.blobStore.restore.blob(id, cb);
default:
return void cb("INVALID_ID_LENGTH");
}
};
// CryptPad_AsyncStore.rpc.send('ADMIN', ['CLEAR_CACHED_CHANNEL_INDEX', documentID], console.log)

@ -681,9 +681,9 @@ var unarchiveChannel = function (env, channelName, cb) {
// restore the metadata log
Fse.move(archiveMetadataPath, metadataPath, w(function (err) {
// if there's nothing to move, you're done.
if (err && err.code === 'ENOENT') {
/*if (err && err.code === 'ENOENT') {
return CB();
}
}*/ // XXX make sure removing this part won't break anything
// call back with an error if something goes wrong
if (err) {
w.abort();

@ -97,5 +97,15 @@
color: @colortheme_logo-2;
}
}
input.cp-admin-inval {
border-color: red !important;
}
.cp-admin-nopassword {
.cp-admin-pw {
display: none !important;
}
}
}

@ -43,6 +43,8 @@ define([
'general': [
'cp-admin-flush-cache',
'cp-admin-update-limit',
'cp-admin-archive',
'cp-admin-unarchive',
// 'cp-admin-registration',
],
'quota': [
@ -107,6 +109,141 @@ define([
});
return $div;
};
Messages.admin_archiveTitle = "Archive documents"; // XXX
Messages.admin_archiveHint = "Make a document unavailable without deleting it permanently. It will be placed in an 'archive' directory and deleted after a few days (configurable in the server configuration file)."; // XXX
Messages.admin_archiveButton = "Archive";
Messages.admin_unarchiveTitle = "Restore archived documents"; // XXX
Messages.admin_unarchiveHint = "Restore a document that has previously been archived";
Messages.admin_unarchiveButton = "Restore";
Messages.admin_archiveInput = "Document URL";
Messages.admin_archiveInput2 = "Document password";
Messages.admin_archiveInval = "Invalid document";
Messages.restoredFromServer = "Pad restored";
var archiveForm = function (archive, $div, $button) {
var label = h('label', { for: 'cp-admin-archive' }, Messages.admin_archiveInput);
var input = h('input#cp-admin-archive', {
type: 'text'
});
var label2 = h('label.cp-admin-pw', {
for: 'cp-admin-archive-pw'
}, Messages.admin_archiveInput2);
var input2 = UI.passwordInput({
id: 'cp-admin-archive-pw',
placeholder: Messages.login_password
});
var $pw = $(input2);
$pw.addClass('cp-admin-pw');
var $pwInput = $pw.find('input');
$button.before(h('div.cp-admin-setlimit-form', [
label,
input,
label2,
input2
]));
$div.addClass('cp-admin-nopassword');
var parsed;
var $input = $(input).on('keypress change paste', function () {
setTimeout(function () {
$input.removeClass('cp-admin-inval');
var val = $input.val().trim();
if (!val) {
$div.toggleClass('cp-admin-nopassword', true);
return;
}
parsed = Hash.isValidHref(val);
$pwInput.val('');
if (!parsed || !parsed.hashData) {
$div.toggleClass('cp-admin-nopassword', true);
return void $input.addClass('cp-admin-inval');
}
var pw = parsed.hashData.version !== 3 && parsed.hashData.password;
$div.toggleClass('cp-admin-nopassword', !pw);
});
});
$pw.on('keypress change', function () {
setTimeout(function () {
$pw.toggleClass('cp-admin-inval', !$pwInput.val());
});
});
var clicked = false;
$button.click(function () {
if (!parsed || !parsed.hashData) {
UI.warn(Messages.admin_archiveInval);
return;
}
var pw = parsed.hashData.password ? $pwInput.val() : undefined;
var channel;
if (parsed.hashData.version === 3) {
channel = parsed.hashData.channel;
} else {
var secret = Hash.getSecrets(parsed.type, parsed.hash, pw);
channel = secret && secret.channel;
}
if (!channel) {
UI.warn(Messages.admin_archiveInval);
return;
}
if (clicked) { return; }
clicked = true;
nThen(function (waitFor) {
if (!archive) { return; }
common.getFileSize(channel, waitFor(function (err, size) {
if (!err && size === 0) {
clicked = false;
waitFor.abort();
return void UI.warn(Messages.admin_archiveInval);
}
}));
}).nThen(function () {
sFrameChan.query('Q_ADMIN_RPC', {
cmd: archive ? 'ARCHIVE_DOCUMENT' : 'RESTORE_ARCHIVED_DOCUMENT',
data: channel
}, function (err, obj) {
var e = err || (obj && obj.error);
clicked = false;
if (e) {
UI.warn(Messages.error);
console.error(e);
return;
}
UI.log(archive ? Messages.deletedFromServer : Messages.restoredFromServer);
$input.val('');
$pwInput.val('');
});
});
});
};
create['archive'] = function () {
var key = 'archive';
var $div = makeBlock(key, true);
var $button = $div.find('button');
archiveForm(true, $div, $button);
return $div;
};
create['unarchive'] = function () {
var key = 'unarchive';
var $div = makeBlock(key, true);
var $button = $div.find('button');
archiveForm(false, $div, $button);
return $div;
};
create['registration'] = function () {
var key = 'registration';
var $div = makeBlock(key, true);

@ -464,6 +464,8 @@ Version 4: Data URL when not a realtime link yet (new pad or "static" app)
};
if (!/^https*:\/\//.test(href)) {
// If it doesn't start with http(s), it should be a relative href
if (!/^\//.test(href)) { return ret; }
idx = href.indexOf('/#');
ret.type = href.slice(1, idx);
if (idx === -1) { return ret; }
@ -661,7 +663,7 @@ Version 4: Data URL when not a realtime link yet (new pad or "static" app)
if (parsed.hashData.key && !/^[a-zA-Z0-9+-/=]+$/.test(parsed.hashData.key)) { return; }
}
}
return true;
return parsed;
};
Hash.decodeDataOptions = function (opts) {

Loading…
Cancel
Save