mirror of https://github.com/xwiki-labs/cryptpad
Add new placeholder data and account script to admin panel
This commit is contained in:
parent
399d50e941
commit
f282db9121
|
@ -122,6 +122,9 @@ define([
|
|||
.on('ready', function () {
|
||||
setTimeout(function () { cb(void 0, rt); });
|
||||
})
|
||||
.on('error', function (info) {
|
||||
cb(info.type, {reason: info.message});
|
||||
})
|
||||
.on('disconnect', function (info) {
|
||||
cb('E_DISCONNECT', info);
|
||||
});
|
||||
|
@ -211,10 +214,13 @@ define([
|
|||
return void console.log("Block requires 2FA");
|
||||
}
|
||||
|
||||
if (err === 404 && response && response.reason
|
||||
&& response.reason !== 'PASSWORD_CHANGE') {
|
||||
if (err === 404 && response && response.reason) {
|
||||
waitFor.abort();
|
||||
w.abort();
|
||||
/*
|
||||
// the following block prevent users from re-using an old password
|
||||
if (isRegister) { return void cb('HAS_PLACEHOLDER'); }
|
||||
*/
|
||||
return void cb('DELETED_USER', response);
|
||||
}
|
||||
|
||||
|
@ -299,6 +305,7 @@ define([
|
|||
loadUserObject(opt, waitFor(function (err, rt) {
|
||||
if (err) {
|
||||
waitFor.abort();
|
||||
if (err === 'EDELETED') { return void cb('DELETED_USER', rt); }
|
||||
return void cb(err);
|
||||
}
|
||||
|
||||
|
@ -396,6 +403,7 @@ define([
|
|||
loadUserObject(opt, waitFor(function (err, rt) {
|
||||
if (err) {
|
||||
waitFor.abort();
|
||||
if (err === 'EDELETED') { return void cb('DELETED_USER', rt); }
|
||||
return void cb('MODERN_REGISTRATION_INIT');
|
||||
}
|
||||
|
||||
|
@ -603,8 +611,16 @@ define([
|
|||
});
|
||||
});
|
||||
break;
|
||||
/*
|
||||
case 'HAS_PLACEHOLDER':
|
||||
UI.errorLoadingScreen('UNAVAILABLE', true, true);
|
||||
break;
|
||||
*/
|
||||
case 'DELETED_USER':
|
||||
UI.errorLoadingScreen(UI.getDestroyedPlaceholder(result.reason, true));
|
||||
UI.errorLoadingScreen(
|
||||
UI.getDestroyedPlaceholder(result.reason, true), true, () => {
|
||||
window.location.reload();
|
||||
});
|
||||
break;
|
||||
case 'INVAL_PASS':
|
||||
UI.removeLoadingScreen(function () {
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* jshint esversion: 6, node: true */
|
||||
const nThen = require('nthen');
|
||||
const Pins = require('./pins');
|
||||
const Environment = require("./env");
|
||||
const Util = require("./common-util");
|
||||
const Store = require('./storage/file.js');
|
||||
const BlobStore = require("./storage/blob");
|
||||
|
@ -16,23 +15,9 @@ const Fse = require("fs-extra");
|
|||
|
||||
const { parentPort } = require('node:worker_threads');
|
||||
|
||||
const config = require('./load-config');
|
||||
const Env = Environment.create(config);
|
||||
const COMMANDS = {};
|
||||
let Log;
|
||||
|
||||
Env.computeMetadata = function (channel, cb) {
|
||||
const ref = {};
|
||||
const lineHandler = Meta.createLineHandler(ref, (err) => { console.log(err); });
|
||||
return void Env.store.readChannelMetadata(channel, lineHandler, function (err) {
|
||||
if (err) {
|
||||
// stream errors?
|
||||
return void cb(err);
|
||||
}
|
||||
cb(void 0, ref.meta);
|
||||
});
|
||||
};
|
||||
|
||||
const mkReportPath = function (Env, safeKey) {
|
||||
return Path.join(Env.paths.archive, 'accounts', safeKey);
|
||||
};
|
||||
|
@ -56,6 +41,21 @@ const deleteReport = (Env, key, cb) => {
|
|||
};
|
||||
|
||||
const init = (cb) => {
|
||||
const Environment = require("./env");
|
||||
const config = require('./load-config');
|
||||
const Env = Environment.create(config);
|
||||
Env.computeMetadata = function (channel, cb) {
|
||||
const ref = {};
|
||||
const lineHandler = Meta.createLineHandler(ref, (err) => { console.log(err); });
|
||||
return void Env.store.readChannelMetadata(channel, lineHandler, function (err) {
|
||||
if (err) {
|
||||
// stream errors?
|
||||
return void cb(err);
|
||||
}
|
||||
cb(void 0, ref.meta);
|
||||
});
|
||||
};
|
||||
|
||||
nThen((waitFor) => {
|
||||
Logger.create(config, waitFor(function (_) {
|
||||
Log = Env.Log = _;
|
||||
|
@ -91,7 +91,9 @@ const init = (cb) => {
|
|||
}
|
||||
Env.blobStore = blob;
|
||||
}));
|
||||
}).nThen(cb);
|
||||
}).nThen(() => {
|
||||
cb(Env);
|
||||
});
|
||||
};
|
||||
|
||||
COMMANDS.start = (edPublic, blockId, reason) => {
|
||||
|
@ -106,8 +108,11 @@ COMMANDS.start = (edPublic, blockId, reason) => {
|
|||
let channelsToArchive = [];
|
||||
let deletedChannels = [];
|
||||
let deletedBlobs = [];
|
||||
let Env;
|
||||
nThen((waitFor) => {
|
||||
init(waitFor());
|
||||
init(waitFor((_Env) => {
|
||||
Env = _Env;
|
||||
}));
|
||||
}).nThen((waitFor) => {
|
||||
let lineHandler = Pins.createLineHandler(ref, (err) => { console.log(err); });
|
||||
Env.pinStore.readMessagesBin(safeKey, 0, (msgObj, readMore) => {
|
||||
|
@ -197,7 +202,8 @@ COMMANDS.start = (edPublic, blockId, reason) => {
|
|||
key: safeKey,
|
||||
channels: deletedChannels,
|
||||
blobs: deletedBlobs,
|
||||
blockId: blockId
|
||||
blockId: blockId,
|
||||
reason: reason
|
||||
};
|
||||
storeReport(Env, report, waitFor((err) => {
|
||||
if (err) {
|
||||
|
@ -216,8 +222,11 @@ COMMANDS.restore = (edPublic) => {
|
|||
let pads, blobs;
|
||||
let blockId;
|
||||
let errors = [];
|
||||
let Env;
|
||||
nThen((waitFor) => {
|
||||
init(waitFor());
|
||||
init(waitFor((_Env) => {
|
||||
Env = _Env;
|
||||
}));
|
||||
}).nThen((waitFor) => {
|
||||
Log.info('MODERATION_ACCOUNT_RESTORE_START', edPublic, waitFor());
|
||||
readReport(Env, safeKey, waitFor((err, report) => {
|
||||
|
@ -290,14 +299,28 @@ COMMANDS.restore = (edPublic) => {
|
|||
|
||||
};
|
||||
|
||||
parentPort.on('message', (message) => {
|
||||
let parsed = message; //JSON.parse(message);
|
||||
let command = parsed.command;
|
||||
let content = parsed.content;
|
||||
let block = parsed.block;
|
||||
let reason = parsed.reason;
|
||||
COMMANDS[command](content, block, reason);
|
||||
});
|
||||
const getStatus = (Env, edPublic, cb) => {
|
||||
const safeKey = Util.escapeKeyCharacters(edPublic);
|
||||
readReport(Env, safeKey, (err, report) => {
|
||||
if (err) { return void cb(err); }
|
||||
cb(void 0, report);
|
||||
});
|
||||
};
|
||||
|
||||
parentPort.postMessage('READY');
|
||||
if (parentPort) {
|
||||
parentPort.on('message', (message) => {
|
||||
let parsed = message; //JSON.parse(message);
|
||||
let command = parsed.command;
|
||||
let content = parsed.content;
|
||||
let block = parsed.block;
|
||||
let reason = parsed.reason;
|
||||
COMMANDS[command](content, block, reason);
|
||||
});
|
||||
|
||||
parentPort.postMessage('READY');
|
||||
} else {
|
||||
|
||||
module.exports = {
|
||||
getStatus: getStatus
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ const Core = require("./core");
|
|||
const Channel = require("./channel");
|
||||
const BlockStore = require("../storage/block");
|
||||
const MFA = require("../storage/mfa");
|
||||
const ArchiveAccount = require('../archive-account');
|
||||
/* jshint ignore:start */
|
||||
const { Worker } = require('node:worker_threads');
|
||||
/* jshint ignore:end */
|
||||
|
@ -288,22 +289,28 @@ var restoreArchivedDocument = function (Env, Server, cb, data) {
|
|||
}
|
||||
};
|
||||
|
||||
// CryptPad_AsyncStore.rpc.send('ADMIN', ['ARCHIVE_ACCOUNT', edPublic], console.log)
|
||||
// CryptPad_AsyncStore.rpc.send('ADMIN', ['ARCHIVE_ACCOUNT', {key, block, reason}], console.log)
|
||||
var archiveAccount = function (Env, Server, _cb, data) {
|
||||
const cb = Util.once(_cb);
|
||||
const worker = new Worker('./lib/archive-account.js');
|
||||
const args = Array.isArray(data) && data[1];
|
||||
if (!args || typeof(args) !== 'object') { return void cb("EINVAL"); }
|
||||
worker.on('message', message => {
|
||||
if (message === 'READY') {
|
||||
return worker.postMessage({
|
||||
command: 'start',
|
||||
content: data && data[1],
|
||||
block: data && data[2],
|
||||
reason: data && data[3]
|
||||
content: args.key,
|
||||
block: args.block, // optional, may be including in pin log
|
||||
reason: args.reason
|
||||
});
|
||||
}
|
||||
|
||||
// DONE: disconnect all users from these channels
|
||||
const reason = `MODERATION_ACCOUNT:${data && data[3]}`;
|
||||
Env.Log.info('ARCHIVE_ACCOUNT_BY_ADMIN', {
|
||||
safeKey: args.key,
|
||||
reason: args.reason,
|
||||
});
|
||||
const reason = `MODERATION_ACCOUNT:${args.reason}`;
|
||||
var deletedChannels = Util.tryParse(message);
|
||||
if (Array.isArray(deletedChannels)) {
|
||||
let n = nThen;
|
||||
|
@ -326,14 +333,20 @@ var archiveAccount = function (Env, Server, _cb, data) {
|
|||
var restoreAccount = function (Env, Server, _cb, data) {
|
||||
const cb = Util.once(_cb);
|
||||
const worker = new Worker('./lib/archive-account.js');
|
||||
const args = Array.isArray(data) && data[1];
|
||||
if (!args || typeof(args) !== 'object') { return void cb("EINVAL"); }
|
||||
worker.on('message', message => {
|
||||
if (message === 'READY') {
|
||||
return worker.postMessage({
|
||||
command: 'restore',
|
||||
content: data && data[1]
|
||||
content: args.key
|
||||
});
|
||||
}
|
||||
// Response
|
||||
Env.Log.info('RESTORE_ACCOUNT_BY_ADMIN', {
|
||||
safeKey: args.key,
|
||||
reason: args.reason,
|
||||
});
|
||||
cb(void 0, {
|
||||
state: true,
|
||||
errors: Util.tryParse(message)
|
||||
|
@ -344,7 +357,11 @@ var restoreAccount = function (Env, Server, _cb, data) {
|
|||
cb(err);
|
||||
});
|
||||
worker.on('exit', () => { worker.unref(); });
|
||||
|
||||
};
|
||||
var getAccountArchiveStatus = function (Env, Server, cb, data) {
|
||||
const args = Array.isArray(data) && data[1];
|
||||
if (!args || typeof(args) !== 'object') { return void cb("EINVAL"); }
|
||||
ArchiveAccount.getStatus(Env, args.key, cb);
|
||||
};
|
||||
|
||||
// CryptPad_AsyncStore.rpc.send('ADMIN', ['CLEAR_CACHED_CHANNEL_INDEX', documentID], console.log)
|
||||
|
@ -567,6 +584,10 @@ var getDocumentStatus = function (Env, Server, cb, data) {
|
|||
}
|
||||
response.archived = result;
|
||||
}));
|
||||
BlockStore.readPlaceholder(Env, id, w((result) => {
|
||||
if (!result) { return; }
|
||||
response.placeholder = result;
|
||||
}));
|
||||
MFA.read(Env, id, w(function (err, v) {
|
||||
if (err === 'ENOENT') {
|
||||
response.totp = 'DISABLED';
|
||||
|
@ -598,6 +619,10 @@ var getDocumentStatus = function (Env, Server, cb, data) {
|
|||
}
|
||||
response.archived = result;
|
||||
}));
|
||||
Env.blobStore.getPlaceholder(id, w((result) => {
|
||||
if (!result) { return; }
|
||||
response.placeholder = result;
|
||||
}));
|
||||
}).nThen(function () {
|
||||
cb(void 0, response);
|
||||
});
|
||||
|
@ -616,6 +641,10 @@ var getDocumentStatus = function (Env, Server, cb, data) {
|
|||
}
|
||||
response.archived = result;
|
||||
}));
|
||||
Env.store.getPlaceholder(id, w((result) => {
|
||||
if (!result) { return; }
|
||||
response.placeholder = result;
|
||||
}));
|
||||
}).nThen(function () {
|
||||
cb(void 0, response);
|
||||
});
|
||||
|
@ -646,6 +675,8 @@ var getPinHistory = function (Env, Server, cb, data) {
|
|||
cb("NOT_IMPLEMENTED");
|
||||
};
|
||||
|
||||
/*
|
||||
// NOTE: Deprecated, archive whole account now
|
||||
var archivePinLog = function (Env, Server, cb, data) {
|
||||
var args = Array.isArray(data) && data[1];
|
||||
if (!args || typeof(args) !== 'object') { return void cb("EINVAL"); }
|
||||
|
@ -671,6 +702,7 @@ var archivePinLog = function (Env, Server, cb, data) {
|
|||
cb(err);
|
||||
});
|
||||
};
|
||||
*/
|
||||
|
||||
var archiveBlock = function (Env, Server, cb, data) {
|
||||
var args = Array.isArray(data) && data[1];
|
||||
|
@ -708,6 +740,8 @@ var restoreArchivedBlock = function (Env, Server, cb, data) {
|
|||
});
|
||||
};
|
||||
|
||||
/*
|
||||
// NOTE: Deprecated, archive whole account now
|
||||
var restoreArchivedPinLog = function (Env, Server, cb, data) {
|
||||
var args = Array.isArray(data) && data[1];
|
||||
if (!args || typeof(args) !== 'object') { return void cb("EINVAL"); }
|
||||
|
@ -732,6 +766,7 @@ var restoreArchivedPinLog = function (Env, Server, cb, data) {
|
|||
cb(err);
|
||||
});
|
||||
};
|
||||
*/
|
||||
|
||||
var archiveOwnedDocuments = function (Env, Server, cb, data) {
|
||||
Env.Log.debug('ARCHIVE_OWNED_DOCUMENTS', data);
|
||||
|
@ -842,9 +877,9 @@ var commands = {
|
|||
|
||||
GET_PIN_LIST: getPinList,
|
||||
GET_PIN_HISTORY: getPinHistory,
|
||||
ARCHIVE_PIN_LOG: archivePinLog,
|
||||
//ARCHIVE_PIN_LOG: archivePinLog,
|
||||
ARCHIVE_OWNED_DOCUMENTS: archiveOwnedDocuments,
|
||||
RESTORE_ARCHIVED_PIN_LOG: restoreArchivedPinLog,
|
||||
//RESTORE_ARCHIVED_PIN_LOG: restoreArchivedPinLog,
|
||||
|
||||
ARCHIVE_BLOCK: archiveBlock,
|
||||
RESTORE_ARCHIVED_BLOCK: restoreArchivedBlock,
|
||||
|
@ -854,6 +889,7 @@ var commands = {
|
|||
|
||||
ARCHIVE_ACCOUNT: archiveAccount,
|
||||
RESTORE_ACCOUNT: restoreAccount,
|
||||
GET_ACCOUNT_ARCHIVE_STATUS: getAccountArchiveStatus,
|
||||
|
||||
CLEAR_CACHED_CHANNEL_INDEX: clearChannelIndex,
|
||||
GET_CACHED_CHANNEL_INDEX: getChannelIndex,
|
||||
|
|
|
@ -689,6 +689,9 @@ BlobStore.create = function (config, _cb) {
|
|||
var path = prependArchive(Env, makeBlobPath(Env, blobId));
|
||||
isFile(path, cb);
|
||||
},
|
||||
getPlaceholder: function (blobId, cb) {
|
||||
readPlaceholder(Env, blobId, cb);
|
||||
},
|
||||
|
||||
closeBlobstage: function (safeKey) {
|
||||
closeBlobstage(Env, safeKey);
|
||||
|
|
|
@ -1429,6 +1429,9 @@ module.exports.create = function (conf, _cb) {
|
|||
channelBytes(env, channelName, Util.both(cb, next));
|
||||
});
|
||||
},
|
||||
getPlaceholder: function (channelName, cb) {
|
||||
readPlaceholder(env, channelName, cb);
|
||||
},
|
||||
// OTHER DATABASE FUNCTIONALITY
|
||||
// remove a particular channel from the cache
|
||||
closeChannel: function (channelName, cb) {
|
||||
|
|
|
@ -53,6 +53,20 @@ define([
|
|||
var common;
|
||||
var sFrameChan;
|
||||
|
||||
// XXX
|
||||
// TO DELETE
|
||||
// Messages.admin_archivePinLog
|
||||
// Messages.admin_restoreArchivedPins
|
||||
// TO ADD
|
||||
Messages.admin_archiveAccount = "Archive this account";
|
||||
Messages.admin_archiveAccountInfo = "Including its owned documents";
|
||||
Messages.admin_archiveAccountConfirm = "Please specify the reason for archival, this will be shown to the user.";
|
||||
Messages.admin_restoreAccount = "Restore this account";
|
||||
Messages.admin_accountSuspended = "Account archived by admin";
|
||||
Messages.admin_accountReport = "Account archive report";
|
||||
Messages.admin_accountReportFull = "Get detailed report";
|
||||
Messages.admin_channelPlaceholder = "Destroyed document placeholder";
|
||||
|
||||
var categories = {
|
||||
'general': [ // Msg.admin_cat_general
|
||||
'cp-admin-flush-cache',
|
||||
|
@ -226,6 +240,7 @@ define([
|
|||
data.currentlyOnline = response[0];
|
||||
}));
|
||||
}).nThen(function (w) {
|
||||
if (!data.first) { return; }
|
||||
sframeCommand('GET_USER_QUOTA', key, w((err, response) => {
|
||||
if (err || !response) {
|
||||
return void console.error('quota', err, response);
|
||||
|
@ -236,6 +251,7 @@ define([
|
|||
}
|
||||
}));
|
||||
}).nThen(function (w) {
|
||||
if (!data.first) { return; }
|
||||
// storage used
|
||||
sframeCommand('GET_USER_TOTAL_SIZE', key, w((err, response) => {
|
||||
if (err || !Array.isArray(response)) {
|
||||
|
@ -246,6 +262,7 @@ define([
|
|||
}
|
||||
}));
|
||||
}).nThen(function (w) {
|
||||
if (!data.first) { return; }
|
||||
// channels pinned
|
||||
// files pinned
|
||||
sframeCommand('GET_USER_STORAGE_STATS', key, w((err, response) => {
|
||||
|
@ -268,6 +285,17 @@ define([
|
|||
data.archived = response[0].archived;
|
||||
}
|
||||
}));
|
||||
}).nThen(function (w) {
|
||||
if (data.first) { return; }
|
||||
// Account is probably deleted
|
||||
sframeCommand('GET_ACCOUNT_ARCHIVE_STATUS', {key}, w((err, response) => {
|
||||
if (err || !Array.isArray(response) || !response[0]) {
|
||||
console.error('account status', err, response);
|
||||
} else {
|
||||
console.info('account status', response);
|
||||
data.archiveReport = response[0];
|
||||
}
|
||||
}));
|
||||
}).nThen(function () {
|
||||
//console.log(data);
|
||||
try {
|
||||
|
@ -281,6 +309,12 @@ define([
|
|||
if (typeof(val) !== 'number') { return; }
|
||||
data[`${k}_formatted`] = getPrettySize(val);
|
||||
});
|
||||
if (data.archiveReport) {
|
||||
let formatted = Util.clone(data.archiveReport);
|
||||
formatted.channels = data.archiveReport.channels.length;
|
||||
formatted.blobs = data.archiveReport.blobs.length;
|
||||
data['archiveReport_formatted'] = JSON.stringify(formatted, 0, 2);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
}
|
||||
|
@ -391,11 +425,13 @@ define([
|
|||
]));
|
||||
}
|
||||
|
||||
// First pin activity time
|
||||
row(Messages.admin_firstPinTime, maybeDate(data.first));
|
||||
if (data.first || data.latest) {
|
||||
// First pin activity time
|
||||
row(Messages.admin_firstPinTime, maybeDate(data.first));
|
||||
|
||||
// last pin activity time
|
||||
row(Messages.admin_lastPinTime, maybeDate(data.latest));
|
||||
// last pin activity time
|
||||
row(Messages.admin_lastPinTime, maybeDate(data.latest));
|
||||
}
|
||||
|
||||
// currently online
|
||||
row(Messages.admin_currentlyOnline, data.currentlyOnline);
|
||||
|
@ -407,27 +443,46 @@ define([
|
|||
row(Messages.admin_note, data.note || Messages.ui_none);
|
||||
|
||||
// storage limit
|
||||
row(Messages.admin_planlimit, getPrettySize(data.limit));
|
||||
if (data.limit) { row(Messages.admin_planlimit, getPrettySize(data.limit)); }
|
||||
|
||||
// data stored
|
||||
row(Messages.admin_storageUsage, getPrettySize(data.usage));
|
||||
if (data.usage) { row(Messages.admin_storageUsage, getPrettySize(data.usage)); }
|
||||
|
||||
// number of channels
|
||||
row(Messages.admin_channelCount, data.channels);
|
||||
if (typeof(data.channel) === "number") {
|
||||
row(Messages.admin_channelCount, data.channels);
|
||||
}
|
||||
|
||||
// number of files pinned
|
||||
row(Messages.admin_fileCount, data.files);
|
||||
if (typeof(data.channel) === "number") {
|
||||
row(Messages.admin_fileCount, data.files);
|
||||
}
|
||||
|
||||
row(Messages.admin_pinLogAvailable, localizeState(data.live));
|
||||
|
||||
// pin log archived
|
||||
row(Messages.admin_pinLogArchived, localizeState(data.archived));
|
||||
|
||||
if (data.archiveReport) {
|
||||
row(Messages.admin_accountSuspended, localizeState(Boolean(data.archiveReport)));
|
||||
}
|
||||
if (data.archiveReport_formatted) {
|
||||
let button, pre;
|
||||
row(Messages.admin_accountReport, h('div', [
|
||||
pre = h('pre', data.archiveReport_formatted),
|
||||
button = primary(Messages.admin_accountReportFull, () => {
|
||||
$(button).remove();
|
||||
$(pre).html(JSON.stringify(data.archiveReport, 0, 2));
|
||||
})
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
// actions
|
||||
if (data.archived && data.live === false) {
|
||||
row(Messages.admin_restoreArchivedPins, primary(Messages.ui_restore, function () {
|
||||
if (data.archived && data.live === false && data.archiveReport) {
|
||||
row(Messages.admin_restoreAccount, primary(Messages.ui_restore, function () {
|
||||
justifyRestorationDialog('', reason => {
|
||||
sframeCommand('RESTORE_ARCHIVED_PIN_LOG', {
|
||||
sframeCommand('RESTORE_ACCOUNT', {
|
||||
key: data.key,
|
||||
reason: reason,
|
||||
}, function (err) {
|
||||
|
@ -497,9 +552,10 @@ define([
|
|||
|
||||
// archive pin log
|
||||
var archiveHandler = () => {
|
||||
justifyArchivalDialog(Messages.admin_archivePinLogConfirm, reason => {
|
||||
sframeCommand('ARCHIVE_PIN_LOG', {
|
||||
justifyArchivalDialog(Messages.admin_archiveAccountConfirm, reason => {
|
||||
sframeCommand('ARCHIVE_ACCOUNT', {
|
||||
key: data.key,
|
||||
block: data.blockId,
|
||||
reason: reason,
|
||||
}, (err /*, response */) => {
|
||||
console.error(err);
|
||||
|
@ -512,7 +568,12 @@ define([
|
|||
});
|
||||
};
|
||||
|
||||
row(Messages.admin_archivePinLog, danger(Messages.admin_archiveButton, archiveHandler));
|
||||
var archiveAccountLabel = h('span', [
|
||||
Messages.admin_archiveAccount,
|
||||
h('br'),
|
||||
h('small', Messages.archiveAccountInfo)
|
||||
]);
|
||||
row(archiveAccountLabel, danger(Messages.admin_archiveButton, archiveHandler));
|
||||
|
||||
// archive owned documents
|
||||
/* // TODO not implemented
|
||||
|
@ -678,6 +739,7 @@ define([
|
|||
}
|
||||
data.live = res[0].live;
|
||||
data.archived = res[0].archived;
|
||||
data.placeholder = res[0].placeholder;
|
||||
//console.error("get channel status", err, res);
|
||||
}));
|
||||
}).nThen(function () {
|
||||
|
@ -696,7 +758,6 @@ define([
|
|||
|
||||
/* FIXME
|
||||
Messages.admin_getFullPinHistory = 'Pin history';
|
||||
Messages.admin_archivePinLogConfirm = "All content in this user's drive will be un-listed, meaning it may be deleted if it is not in any other drive.";
|
||||
Messages.admin_archiveOwnedAccountDocuments = "Archive this account's owned documents (not implemented)";
|
||||
Messages.admin_archiveOwnedDocumentsConfirm = "All content owned exclusively by this user will be archived. This means their documents, drive, and accounts will be made inaccessible. This action cannot be undone. Please save the full pin list before proceeding to ensure individual documents can be restored.";
|
||||
*/
|
||||
|
@ -791,6 +852,11 @@ define([
|
|||
|
||||
}
|
||||
|
||||
if (data.placeholder) {
|
||||
console.warn('Placeholder code', data.placeholder);
|
||||
row(Messages.admin_channelPlaceholder, UI.getDestroyedPlaceholderMessage(data.placeholder));
|
||||
}
|
||||
|
||||
if (data.live && data.archived) {
|
||||
let disableButtons;
|
||||
let restoreButton = danger(Messages.admin_unarchiveButton, function () {
|
||||
|
@ -1075,6 +1141,7 @@ define([
|
|||
data.live = res[0].live;
|
||||
data.archived = res[0].archived;
|
||||
data.totp = res[0].totp;
|
||||
data.placeholder = res[0].placeholder;
|
||||
}));
|
||||
}).nThen(function () {
|
||||
try {
|
||||
|
@ -1120,6 +1187,10 @@ define([
|
|||
});
|
||||
row(Messages.admin_archiveBlock, archiveButton);
|
||||
}
|
||||
if (data.placeholder) {
|
||||
console.warn('Placeholder code', data.placeholder);
|
||||
row(Messages.admin_channelPlaceholder, UI.getDestroyedPlaceholderMessage(data.placeholder, true));
|
||||
}
|
||||
if (data.archived && !data.live) {
|
||||
var restoreButton = danger(Messages.ui_restore, function () {
|
||||
justifyRestorationDialog('', reason => {
|
||||
|
|
|
@ -1969,6 +1969,42 @@ define([
|
|||
return void cb({ error: 'INVALID_CODE' });
|
||||
}
|
||||
}));
|
||||
}).nThen(function (waitFor) {
|
||||
var blockUrl = Block.getBlockUrl(blockKeys);
|
||||
// Check whether there is a block at that new location
|
||||
Util.getBlock(blockUrl, {}, waitFor(function (err, response) {
|
||||
// If there is no block or the block is invalid, continue.
|
||||
// error 401 means protected block
|
||||
|
||||
/*
|
||||
// the following block prevent users from re-using an old password
|
||||
if (err === 404 && response && response.reason) {
|
||||
waitFor.abort();
|
||||
return void cb({
|
||||
error: 'EDELELED',
|
||||
reason: response.reason
|
||||
});
|
||||
}
|
||||
*/
|
||||
|
||||
if (err && err !== 401) {
|
||||
console.log("no block found");
|
||||
return;
|
||||
}
|
||||
|
||||
response.arrayBuffer().then(waitFor(arraybuffer => {
|
||||
var block = new Uint8Array(arraybuffer);
|
||||
var decryptedBlock = Block.decrypt(block, blockKeys);
|
||||
if (!decryptedBlock) {
|
||||
console.error("Found a login block but failed to decrypt");
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is already a valid block, abort! We risk overriding another user's data
|
||||
waitFor.abort();
|
||||
cb({ error: 'EEXISTS' });
|
||||
}));
|
||||
}));
|
||||
}).nThen(function (waitFor) {
|
||||
// Create a new user hash
|
||||
// Get the current content, store it in the new user file
|
||||
|
@ -1997,27 +2033,6 @@ define([
|
|||
}
|
||||
}), optsPut);
|
||||
}));
|
||||
}).nThen(function (waitFor) {
|
||||
var blockUrl = Block.getBlockUrl(blockKeys);
|
||||
// Check whether there is a block at that new location
|
||||
Util.fetch(blockUrl, waitFor(function (err, block) {
|
||||
// If there is no block or the block is invalid, continue.
|
||||
// error 401 means protected block
|
||||
if (err && err !== 401) {
|
||||
console.log("no block found");
|
||||
return;
|
||||
}
|
||||
|
||||
var decryptedBlock = Block.decrypt(block, blockKeys);
|
||||
if (!decryptedBlock) {
|
||||
console.error("Found a login block but failed to decrypt");
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is already a valid block, abort! We risk overriding another user's data
|
||||
waitFor.abort();
|
||||
cb({ error: 'EEXISTS' });
|
||||
}));
|
||||
}).nThen(function (waitFor) {
|
||||
// Write the new login block
|
||||
var content = {
|
||||
|
|
|
@ -247,7 +247,7 @@ define([
|
|||
list.push(userChannel);
|
||||
|
||||
if (store.data && store.data.blockId) {
|
||||
list.push(`${store.data.blockId}#block`); // XXX 5.5.0?
|
||||
//list.push(`${store.data.blockId}#block`); // XXX 5.5.0?
|
||||
}
|
||||
|
||||
list.sort();
|
||||
|
|
Loading…
Reference in New Issue