cryptpad/www/common/cryptget.js

206 lines
6.3 KiB
JavaScript
Raw Normal View History

define([
'/bower_components/chainpad-crypto/crypto.js',
'chainpad-netflux',
'netflux-client',
2017-11-13 15:32:40 +00:00
'/common/common-util.js',
'/common/common-hash.js',
'/common/common-realtime.js',
2017-11-23 11:28:49 +00:00
'/common/outer/network-config.js',
2020-11-30 11:07:03 +00:00
'/common/outer/cache-store.js',
'/common/pinpad.js',
'/bower_components/nthen/index.js',
'/bower_components/chainpad/chainpad.dist.js',
2020-11-30 11:07:03 +00:00
], function (Crypto, CPNetflux, Netflux, Util, Hash, Realtime, NetConfig, Cache, Pinpad, nThen) {
2016-12-22 15:00:13 +00:00
var finish = function (S, err, doc) {
if (S.done) { return; }
S.cb((err && err.error), doc, err);
2016-12-22 15:00:13 +00:00
S.done = true;
2018-10-18 16:50:38 +00:00
if (!S.hasNetwork) {
var disconnect = Util.find(S, ['network', 'disconnect']);
if (typeof(disconnect) === 'function') { disconnect(); }
}
if (S.realtime && S.realtime.stop) {
2019-08-14 13:59:16 +00:00
try {
S.realtime.stop();
2019-08-14 13:59:16 +00:00
} catch (e) { console.error(e); }
}
2018-10-18 16:50:38 +00:00
var abort = Util.find(S, ['session', 'realtime', 'abort']);
2016-12-22 15:00:13 +00:00
if (typeof(abort) === 'function') {
2018-10-18 16:50:38 +00:00
S.session.realtime.sync();
2016-12-22 15:00:13 +00:00
abort();
}
2016-12-22 15:00:13 +00:00
};
var makeNetwork = function (cb) {
var wsUrl = NetConfig.getWebsocketURL();
Netflux.connect(wsUrl).then(function (network) {
cb(null, network);
}, function (err) {
cb(err);
});
};
var start = function (Session, config) {
// Create a network and authenticate with all our keys if necessary,
// then start chainpad-netflux
nThen(function (waitFor) {
if (Session.hasNetwork) { return; }
makeNetwork(waitFor(function (err, network) {
if (err) { return; }
config.network = network;
}));
}).nThen(function () {
Session.realtime = CPNetflux.start(config);
});
};
var onRejected = function (config, Session, data, cb) {
// Check if we can authenticate
if (!Array.isArray(data) || !data.length || data[0].length !== 16) {
return void cb(true);
}
if (!Array.isArray(Session.accessKeys)) { return void cb(true); }
// Authenticate
config.network.historyKeeper = data[0];
nThen(function (waitFor) {
Session.accessKeys.forEach(function (obj) {
Pinpad.create(config.network, obj, waitFor(function (e) {
console.log('done', obj);
if (e) { console.error(e); }
}));
});
}).nThen(function () {
cb();
});
};
var makeConfig = function (hash, opt) {
2019-12-18 00:27:39 +00:00
var secret;
if (typeof(hash) === 'string') {
// We can't use cryptget with a file or a user so we can use 'pad' as hash type
2019-12-18 00:27:39 +00:00
secret = Hash.getSecrets('pad', hash, opt.password);
} else if (typeof(hash) === 'object') {
// we may want to just supply options directly
// and this is the easiest place to do it
secret = hash;
}
2016-12-22 15:00:13 +00:00
if (!secret.keys) { secret.keys = secret.key; } // support old hashses
var config = {
2019-12-17 09:57:13 +00:00
websocketURL: NetConfig.getWebsocketURL(opt.origin),
channel: secret.channel,
2016-12-22 15:00:13 +00:00
validateKey: secret.keys.validateKey || undefined,
crypto: Crypto.createEncryptor(secret.keys),
logLevel: 0,
2020-11-30 11:07:03 +00:00
initialState: opt.initialState,
Cache: Cache
};
2016-12-22 15:00:13 +00:00
return config;
};
2016-12-22 15:00:13 +00:00
var isObject = function (o) {
return typeof(o) === 'object';
};
var overwrite = function (a, b) {
if (!(isObject(a) && isObject(b))) { return; }
Object.keys(b).forEach(function (k) { a[k] = b[k]; });
};
2019-08-14 12:57:14 +00:00
var get = function (hash, cb, opt, progress) {
2016-12-22 15:00:13 +00:00
if (typeof(cb) !== 'function') {
throw new Error('Cryptget expects a callback');
}
opt = opt || {};
2019-08-14 12:57:14 +00:00
progress = progress || function () {};
var config = makeConfig(hash, opt);
var Session = {
cb: cb,
accessKeys: opt.accessKeys,
hasNetwork: Boolean(opt.network)
};
config.onRejected = function (data, cb) {
onRejected(config, Session, data, cb);
};
2017-05-04 14:16:09 +00:00
config.onReady = function (info) {
2016-12-22 15:00:13 +00:00
var rt = Session.session = info.realtime;
Session.network = info.network;
2019-08-14 12:57:14 +00:00
progress(1);
2016-12-22 15:00:13 +00:00
finish(Session, void 0, rt.getUserDoc());
};
config.onError = function (info) {
2020-11-30 11:07:03 +00:00
console.warn(info);
finish(Session, info);
};
config.onChannelError = function (info) {
2020-11-30 11:07:03 +00:00
console.error(info);
finish(Session, info);
2019-08-14 12:57:14 +00:00
};
config.onCacheReady = opt.onCacheReady;
2019-08-14 12:57:14 +00:00
// We use the new onMessage handler to compute the progress:
// we should receive 2 checkpoints max, so 100 messages max
// We're going to consider that 1 message = 1%, and we'll send 100%
// at the end
var i = 0;
config.onMessage = function () {
i++;
progress(Math.min(0.99, i/100));
};
2016-12-22 15:00:13 +00:00
overwrite(config, opt);
start(Session, config);
2016-12-22 15:00:13 +00:00
};
2016-12-22 15:00:13 +00:00
var put = function (hash, doc, cb, opt) {
if (typeof(cb) !== 'function') {
throw new Error('Cryptput expects a callback');
}
opt = opt || {};
2016-12-22 15:00:13 +00:00
var config = makeConfig(hash, opt);
var Session = {
cb: cb,
accessKeys: opt.accessKeys,
hasNetwork: Boolean(opt.network)
};
config.onRejected = function (data, cb) {
onRejected(config, Session, data, cb);
};
2016-12-22 15:00:13 +00:00
config.onReady = function (info) {
var realtime = Session.session = info.realtime;
Session.network = info.network;
2016-12-22 15:00:13 +00:00
realtime.contentUpdate(doc);
2016-12-22 15:00:13 +00:00
2017-11-30 14:01:17 +00:00
var to = setTimeout(function () {
cb(new Error("Timeout"));
2019-12-18 10:35:39 +00:00
}, 15000);
2017-11-13 15:32:40 +00:00
Realtime.whenRealtimeSyncs(realtime, function () {
2017-11-30 14:01:17 +00:00
clearTimeout(to);
2019-12-18 00:27:39 +00:00
var doc = realtime.getAuthDoc();
realtime.abort();
2019-12-18 00:27:39 +00:00
finish(Session, void 0, doc);
});
};
2016-12-22 15:00:13 +00:00
overwrite(config, opt);
start(Session, config);
};
2016-12-22 15:00:13 +00:00
return {
get: get,
put: put,
};
});