194 lines
7.3 KiB
JavaScript
194 lines
7.3 KiB
JavaScript
define([
|
||
'jquery',
|
||
'/api/config',
|
||
'/common/cryptget.js',
|
||
'/common/pinpad.js',
|
||
'/common/common-constants.js',
|
||
'/common/common-hash.js',
|
||
'/common/outer/local-store.js',
|
||
'/common/outer/login-block.js',
|
||
'/common/outer/network-config.js',
|
||
'/customize/login.js',
|
||
'/common/test.js',
|
||
'/bower_components/nthen/index.js',
|
||
'/bower_components/netflux-websocket/netflux-client.js',
|
||
'/bower_components/tweetnacl/nacl-fast.min.js'
|
||
], function ($, ApiConfig, Crypt, Pinpad, Constants, Hash, LocalStore, Block, NetConfig, Login, Test, nThen, Netflux) {
|
||
var Nacl = window.nacl;
|
||
|
||
var signMsg = function (msg, privKey) {
|
||
var signKey = Nacl.util.decodeBase64(privKey);
|
||
var buffer = Nacl.util.decodeUTF8(msg);
|
||
return Nacl.util.encodeBase64(Nacl.sign(buffer, signKey));
|
||
};
|
||
|
||
// TODO: Allow authing for any domain as long as the user clicks an "accept" button
|
||
// inside of the iframe.
|
||
var AUTHORIZED_DOMAINS = [
|
||
/\.cryptpad\.fr$/,
|
||
/^http(s)?:\/\/localhost\:/
|
||
];
|
||
|
||
// Safari is weird about localStorage in iframes but seems to let sessionStorage slide.
|
||
localStorage[Constants.userHashKey] = localStorage[Constants.userHashKey] ||
|
||
sessionStorage[Constants.userHashKey];
|
||
|
||
var proxy;
|
||
var rpc;
|
||
var network;
|
||
var rpcError;
|
||
var contacts = {};
|
||
|
||
var loadProxy = function (hash) {
|
||
nThen(function (waitFor) {
|
||
var wsUrl = NetConfig.getWebsocketURL();
|
||
var w = waitFor();
|
||
Netflux.connect(wsUrl).then(function (_network) {
|
||
network = _network;
|
||
w();
|
||
}, function (err) {
|
||
rpcError = err;
|
||
console.error(err);
|
||
});
|
||
}).nThen(function (waitFor) {
|
||
Crypt.get(hash, waitFor(function (err, val) {
|
||
if (err) {
|
||
waitFor.abort();
|
||
console.error(err);
|
||
return;
|
||
}
|
||
try {
|
||
var parsed = JSON.parse(val);
|
||
proxy = parsed;
|
||
} catch (e) {
|
||
console.log("Can't parse user drive", e);
|
||
}
|
||
}), {
|
||
network: network
|
||
});
|
||
}).nThen(function () {
|
||
var origin = ApiConfig.fileHost || window.location.origin;
|
||
// Get contacts and extract their avatar channel and key
|
||
var getData = function (obj, href) {
|
||
var parsed = Hash.parsePadUrl(href);
|
||
if (!parsed || parsed.type !== "file") { return; }
|
||
var secret = Hash.getSecrets('file', parsed.hash);
|
||
if (!secret.keys || !secret.channel) { return; }
|
||
obj.avatarKey = Hash.encodeBase64(secret.keys && secret.keys.cryptKey);
|
||
obj.avatarSrc = origin + Hash.getBlobPathFromHex(secret.channel);
|
||
};
|
||
contacts.teams = proxy.teams || {};
|
||
contacts.friends = proxy.friends || {};
|
||
Object.keys(contacts.friends).map(function (key) {
|
||
var friend = contacts.friends[key];
|
||
if (!friend) { return; }
|
||
var ret = {
|
||
edPublic: friend.edPublic,
|
||
name: friend.displayName,
|
||
};
|
||
getData(ret, friend.avatar);
|
||
contacts.friends[key] = ret;
|
||
});
|
||
Object.keys(contacts.teams).map(function (key) {
|
||
var team = contacts.teams[key];
|
||
if (!team) { return; }
|
||
var avatar = team.metadata && team.metadata.avatar;
|
||
var ret = {
|
||
edPublic: team.keys && team.keys.drive && team.keys.drive.edPublic,
|
||
name: team.metadata && team.metadata.name
|
||
};
|
||
getData(ret, avatar);
|
||
contacts.teams[key] = ret;
|
||
});
|
||
contacts.origin = window.location.origin;
|
||
}).nThen(function (waitFor) {
|
||
if (!network) { return void waitFor.abort(); }
|
||
Pinpad.create(network, proxy, waitFor(function (e, call) {
|
||
if (e) {
|
||
rpcError = e;
|
||
return void waitFor.abort();
|
||
}
|
||
rpc = call;
|
||
}));
|
||
}).nThen(function () {
|
||
Test(function () {
|
||
// This is only here to maybe trigger an error.
|
||
window.drive = proxy['drive'];
|
||
Test.passed();
|
||
});
|
||
});
|
||
};
|
||
|
||
var whenReady = function (cb) {
|
||
if (proxy && (rpc || rpcError)) { return void cb(); }
|
||
console.log('CryptPad not ready...');
|
||
setTimeout(function () {
|
||
whenReady(cb);
|
||
}, 100);
|
||
};
|
||
|
||
$(window).on("message", function (jqe) {
|
||
var evt = jqe.originalEvent;
|
||
var data = JSON.parse(evt.data);
|
||
var domain = evt.origin;
|
||
var srcWindow = evt.source;
|
||
var ret = { txid: data.txid };
|
||
console.log('CP receiving', data);
|
||
if (data.cmd === 'PING') {
|
||
ret.res = 'PONG';
|
||
} else if (data.cmd === 'LOGIN') {
|
||
Login.loginOrRegister(data.data.name, data.data.password, false, false, function (err) {
|
||
if (err) {
|
||
ret.error = 'LOGIN_ERROR';
|
||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||
return;
|
||
}
|
||
loadProxy(LocalStore.getUserHash());
|
||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||
});
|
||
return;
|
||
} else if (data.cmd === 'SIGN') {
|
||
if (!AUTHORIZED_DOMAINS.filter(function (x) { return x.test(domain); }).length) {
|
||
ret.error = "UNAUTH_DOMAIN";
|
||
} else if (!LocalStore.isLoggedIn()) {
|
||
ret.error = "NOT_LOGGED_IN";
|
||
} else {
|
||
return void whenReady(function () {
|
||
var sig = signMsg(data.data, proxy.edPrivate);
|
||
ret.res = {
|
||
uname: proxy.login_name,
|
||
edPublic: proxy.edPublic,
|
||
sig: sig
|
||
};
|
||
ret.contacts = contacts;
|
||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||
});
|
||
}
|
||
} else if (data.cmd === 'UPDATE_LIMIT') {
|
||
return void whenReady(function () {
|
||
if (rpcError) {
|
||
// Tell the user on accounts that there was an issue and they need to wait maximum 24h or contact an admin
|
||
ret.warning = true;
|
||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||
return;
|
||
}
|
||
rpc.updatePinLimits(function (e, limit, plan, note) {
|
||
if (e) {
|
||
ret.warning = true;
|
||
}
|
||
ret.res = [limit, plan, note];
|
||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||
});
|
||
});
|
||
} else {
|
||
ret.error = "UNKNOWN_CMD";
|
||
}
|
||
srcWindow.postMessage(JSON.stringify(ret), domain);
|
||
});
|
||
|
||
var userHash = LocalStore.getUserHash();
|
||
if (userHash) {
|
||
loadProxy(userHash);
|
||
}
|
||
});
|