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

302 lines
12 KiB
JavaScript

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

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',
'chainpad-netflux',
'/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');
var copyButton = h('button.btn.btn-primary', Messages.copyToClipboard);
copyButton.onclick = copyToClipboard;
var buttonContainer = h('div#cp-report-ui', [
copyButton,
]);
document.body.appendChild(buttonContainer);
});
});
});