You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cryptpad/www/report/main.js

303 lines
12 KiB
JavaScript

define([
'jquery',
'/api/config',
'/common/hyperscript.js',
'/customize/messages.js',
'/bower_components/nthen/index.js',
'/common/common-hash.js',
'/common/common-util.js',
'/common/cryptget.js',
'/common/cryptpad-common.js',
'/common/outer/cache-store.js',
'/common/common-interface.js',
'/bower_components/chainpad-netflux/chainpad-netflux.js',
'/bower_components/chainpad-crypto/crypto.js',
'/common/userObject.js',
'/common/clipboard.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
'css!/bower_components/components-font-awesome/css/font-awesome.min.css',
'less!/customize/src/less2/pages/page-report.less',
], function ($, ApiConfig, h, Messages,
nThen, Hash, Util, Crypt, Cryptpad, Cache, UI, CPNetflux,
Crypto, UserObject, Clipboard) {
var $report = $('#cp-report');
var hash = localStorage.User_hash;
if (!hash) {
return void UI.alert(Messages.mustLogin, function () {
var href = Hash.hashToHref('', 'login');
var url = Hash.getNewPadURL(href, {
href: '/report/',
});
console.log(url);
window.location.href = url;
});
}
var addReport = function (str) {
$report.append(h('div', str));
};
var getReportContent = window.getReportContent = function () {
try {
return $report[0].innerText;
} catch (err) {
return '';
}
};
var copyToClipboard = function () {
if (Clipboard.copy.multiline(getReportContent())) {
UI.log(Messages.genericCopySuccess);
} else {
UI.warn(Messages.error);
}
};
var checkCache = function (chan, cb) {
Cache.getChannelCache(chan, function (err, val) {
if (err) {
addReport('Cache error:' + err);
} else {
addReport('Cache: ' + val.c.length + ' entries');
}
cb();
});
};
var onCacheReady = function (info) {
var doc;
try {
doc = info.realtime.getUserDoc();
JSON.parse(doc);
addReport('Cache ready success: ' + info.id + ' - Length: ' + doc.length);
} catch (e) {
addReport('Cache ready error: ' + info.id + ' - Length: ' + (doc || '').length);
}
};
var network;
var proxy;
nThen(function (waitFor) {
Cryptpad.makeNetwork(waitFor(function (err, _network) {
if (err) {
console.error(err);
waitFor.abort();
return void UI.errorLoadingScreen(err);
}
network = _network;
}));
}).nThen(function (waitFor) {
addReport('BEGIN REPORT');
var secret = Hash.getSecrets('drive', hash);
addReport('Load drive. ID: ' + secret.channel);
checkCache(secret.channel, waitFor());
}).nThen(function (waitFor) {
Crypt.get(hash, waitFor(function (err, val) {
if (err) {
console.error(err);
addReport('Load drive error. err: ' + err);
return void waitFor.abort();
}
try {
proxy = JSON.parse(val);
} catch (e) {
console.error(e);
addReport('Load drive error. Parse error: ' + e);
waitFor.abort();
}
}), { network: network, onCacheReady: onCacheReady});
}).nThen(function (waitFor) {
var drive = proxy.drive || {};
if (!proxy.drive) {
addReport('ERROR: no drive');
return void waitFor.abort();
}
addReport('Load drive success.');
addReport('Public key: '+proxy.edPublic);
addReport('Shared folders: ' + Object.keys(drive.sharedFolders || {}).join(', '));
addReport('Teams: ' + Object.keys(proxy.teams || {}).join(', '));
addReport('-------------------');
var n = nThen;
Object.keys(drive.sharedFolders || {}).forEach(function (id) {
n = n(function (w) {
var next = w();
var obj = drive.sharedFolders[id];
addReport('Load shared folder. ID: ' + id + '. Channel ID: '+ obj.channel);
if (obj.password) { addReport("Password protected"); }
if (!obj.href) { addReport("View only"); }
checkCache(obj.channel, function () {
var parsed = Hash.parsePadUrl(obj.href || obj.roHref);
Crypt.get(parsed.hash, function (err, val, errorObj) {
if (err) {
addReport('ERROR: ' + err);
if (err === "ERESTRICTED") {
addReport('RESTRICTED: ' + (errorObj && errorObj.message));
}
} else {
addReport('Load shared folder: success. Size: ' + val.length);
}
addReport('-------------------');
next();
}, {
network: network,
password: obj.password,
onCacheReady: onCacheReady
});
});
}).nThen;
});
n(waitFor());
}).nThen(function () {
addReport('===================');
var n = nThen;
Object.keys(proxy.teams || {}).forEach(function (id) {
n = n(function (w) {
var next = w();
var obj = proxy.teams[id];
var team;
addReport('Load team. ID: ' + id + '. Channel ID: '+ obj.channel);
if (!obj.hash) { addReport("View only"); }
var teamSecret = Hash.getSecrets('team', obj.hash || obj.roHash, obj.password);
var cryptor = UserObject.createCryptor(teamSecret.keys.secondaryKey);
// Check team drive
nThen(function (ww) {
addReport('Team drive');
var _next = ww();
checkCache(obj.channel, function () {
Crypt.get(obj.hash || obj.roHash, function (err, val) {
if (err) {
addReport('ERROR: ' + err);
addReport('===================');
next();
ww.abort();
} else {
addReport('Team drive success. Size: ' + val.length);
try {
team = JSON.parse(val);
} catch (e) {
addReport('PARSE ERROR: ' + e);
addReport('===================');
next();
ww.abort();
}
addReport('Shared folders: ' + Object.keys(team.drive.sharedFolders || {}).join(', '));
}
addReport('-------------------');
_next();
}, {
network: network,
password: obj.password,
onCacheReady: onCacheReady
});
});
}).nThen(function (ww) {
var _next = ww();
var d = Util.find(obj, ['keys', 'roster']);
var rosterKeys = d.edit ? Crypto.Team.deriveMemberKeys(d.edit, proxy)
: Crypto.Team.deriveGuestKeys(d.view || '');
if (d.channel !== rosterKeys.channel) {
next();
ww.abort();
addReport("Invalid roster keys:", d.channel, rosterKeys.channel);
return;
}
addReport('Roster channel: ' + d.channel);
checkCache(d.channel, function () {
var crypto = Crypto.Team.createEncryptor(rosterKeys);
var m = 0;
CPNetflux.start({
lastKnownHash: d.lastKnownHash || -1,
network: network,
channel: d.channel,
crypto: crypto,
validateKey: rosterKeys.teamEdPublic,
Cache: Cache,
noChainPad: true,
onCacheReady: onCacheReady,
onChannelError: function (obj) {
addReport('ERROR:' + obj.error);
if (obj.error === "ERESTRICTED") {
addReport('RESTRICTED: ' + obj.message);
}
next();
ww.abort();
addReport('===================');
return;
},
onMessage: function () {
m++;
},
onReady: function () {
addReport("Roster success. Length: "+m);
addReport('-------------------');
_next();
}
});
});
}).nThen(function (ww) {
var _next = ww();
var n = nThen;
var drive = team.drive;
Object.keys(drive.sharedFolders || {}).forEach(function (id) {
n = n(function (w) {
var next = w();
var _obj = drive.sharedFolders[id];
addReport('Load shared folder. ID: ' + id + '. Channel ID: '+ _obj.channel);
if (_obj.password) { addReport("Password protected"); }
if (!_obj.href) { addReport("View only"); }
checkCache(_obj.channel, function () {
if (_obj.href && _obj.href.indexOf('#') === -1) {
_obj.href = cryptor.decrypt(_obj.href);
}
var parsed = Hash.parsePadUrl(_obj.href || _obj.roHref);
Crypt.get(parsed.hash, function (err, val, errorObj) {
if (err) {
addReport('ERROR: ' + err);
if (err === "ERESTRICTED") {
addReport('RESTRICTED: ' + (errorObj && errorObj.message));
}
} else {
addReport('Load shared folder: success. Size: ' + val.length);
}
addReport('-------------------');
next();
}, {
network: network,
password: _obj.password,
onCacheReady: onCacheReady
});
});
}).nThen;
});
n(_next);
}).nThen(next);
}).nThen;
});
n(function () {
addReport('===================');
addReport('DONE');
Messages.copyToClipboard = 'Copy report to clipboard'; // XXX
var copyButton = h('button.btn.btn-primary', Messages.copyToClipboard);
copyButton.onclick = copyToClipboard;
var buttonContainer = h('div#cp-report-ui', [
copyButton,
]);
document.body.appendChild(buttonContainer);
});
});
});