Fix various issues with restricted pads
This commit is contained in:
parent
a87d0f2943
commit
69c26fe8c7
4 changed files with 162 additions and 36 deletions
|
@ -80,6 +80,10 @@ module.exports.create = function (Env, cb) {
|
||||||
return void cb();
|
return void cb();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the channel is restricted, send the history keeper ID so that they
|
||||||
|
// can try to authenticate
|
||||||
|
allowed.unshift(Env.id);
|
||||||
|
|
||||||
// otherwise they're not allowed.
|
// otherwise they're not allowed.
|
||||||
// respond with a special error that includes the list of keys
|
// respond with a special error that includes the list of keys
|
||||||
// which would be allowed...
|
// which would be allowed...
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
define([
|
define([
|
||||||
'/bower_components/chainpad-crypto/crypto.js',
|
'/bower_components/chainpad-crypto/crypto.js',
|
||||||
'/bower_components/chainpad-netflux/chainpad-netflux.js',
|
'/bower_components/chainpad-netflux/chainpad-netflux.js',
|
||||||
|
'/bower_components/netflux-websocket/netflux-client.js',
|
||||||
'/common/common-util.js',
|
'/common/common-util.js',
|
||||||
'/common/common-hash.js',
|
'/common/common-hash.js',
|
||||||
'/common/common-realtime.js',
|
'/common/common-realtime.js',
|
||||||
'/common/outer/network-config.js',
|
'/common/outer/network-config.js',
|
||||||
|
'/common/pinpad.js',
|
||||||
|
'/bower_components/nthen/index.js',
|
||||||
'/bower_components/chainpad/chainpad.dist.js',
|
'/bower_components/chainpad/chainpad.dist.js',
|
||||||
], function (Crypto, CPNetflux, Util, Hash, Realtime, NetConfig) {
|
], function (Crypto, CPNetflux, Netflux, Util, Hash, Realtime, NetConfig, Pinpad, nThen) {
|
||||||
var finish = function (S, err, doc) {
|
var finish = function (S, err, doc) {
|
||||||
if (S.done) { return; }
|
if (S.done) { return; }
|
||||||
S.cb(err, doc);
|
S.cb(err, doc);
|
||||||
|
@ -28,6 +31,50 @@ define([
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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) {
|
var makeConfig = function (hash, opt) {
|
||||||
var secret;
|
var secret;
|
||||||
if (typeof(hash) === 'string') {
|
if (typeof(hash) === 'string') {
|
||||||
|
@ -67,7 +114,15 @@ define([
|
||||||
progress = progress || function () {};
|
progress = progress || function () {};
|
||||||
|
|
||||||
var config = makeConfig(hash, opt);
|
var config = makeConfig(hash, opt);
|
||||||
var Session = { cb: cb, hasNetwork: Boolean(opt.network) };
|
var Session = {
|
||||||
|
cb: cb,
|
||||||
|
accessKeys: opt.accessKeys,
|
||||||
|
hasNetwork: Boolean(opt.network)
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onRejected = function (data, cb) {
|
||||||
|
onRejected(config, Session, data, cb);
|
||||||
|
};
|
||||||
|
|
||||||
config.onReady = function (info) {
|
config.onReady = function (info) {
|
||||||
var rt = Session.session = info.realtime;
|
var rt = Session.session = info.realtime;
|
||||||
|
@ -95,7 +150,7 @@ define([
|
||||||
|
|
||||||
overwrite(config, opt);
|
overwrite(config, opt);
|
||||||
|
|
||||||
Session.realtime = CPNetflux.start(config);
|
start(Session, config);
|
||||||
};
|
};
|
||||||
|
|
||||||
var put = function (hash, doc, cb, opt) {
|
var put = function (hash, doc, cb, opt) {
|
||||||
|
@ -105,7 +160,15 @@ define([
|
||||||
opt = opt || {};
|
opt = opt || {};
|
||||||
|
|
||||||
var config = makeConfig(hash, opt);
|
var config = makeConfig(hash, opt);
|
||||||
var Session = { cb: cb, hasNetwork: Boolean(opt.network) };
|
var Session = {
|
||||||
|
cb: cb,
|
||||||
|
accessKeys: opt.accessKeys,
|
||||||
|
hasNetwork: Boolean(opt.network)
|
||||||
|
};
|
||||||
|
|
||||||
|
config.onRejected = function (data, cb) {
|
||||||
|
onRejected(config, Session, data, cb);
|
||||||
|
};
|
||||||
|
|
||||||
config.onReady = function (info) {
|
config.onReady = function (info) {
|
||||||
var realtime = Session.session = info.realtime;
|
var realtime = Session.session = info.realtime;
|
||||||
|
@ -126,7 +189,7 @@ define([
|
||||||
};
|
};
|
||||||
overwrite(config, opt);
|
overwrite(config, opt);
|
||||||
|
|
||||||
Session.session = CPNetflux.start(config);
|
start(Session, config);
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -68,6 +68,38 @@ define([
|
||||||
}, cb);
|
}, cb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
common.getAccessKeys = function (cb) {
|
||||||
|
var keys = [];
|
||||||
|
Nthen(function (waitFor) {
|
||||||
|
// Push account keys
|
||||||
|
postMessage("GET", {
|
||||||
|
key: ['edPrivate'],
|
||||||
|
}, waitFor(function (obj) {
|
||||||
|
if (obj.error) { return; }
|
||||||
|
try {
|
||||||
|
keys.push({
|
||||||
|
edPrivate: obj,
|
||||||
|
edPublic: Hash.getSignPublicFromPrivate(obj)
|
||||||
|
});
|
||||||
|
} catch (e) { console.error(e); }
|
||||||
|
}));
|
||||||
|
// Push teams keys
|
||||||
|
postMessage("GET", {
|
||||||
|
key: ['teams'],
|
||||||
|
}, waitFor(function (obj) {
|
||||||
|
if (obj.error) { return; }
|
||||||
|
Object.keys(obj || {}).forEach(function (id) {
|
||||||
|
var t = obj[id];
|
||||||
|
var _keys = t.keys.drive || {};
|
||||||
|
if (!_keys.edPrivate) { return; }
|
||||||
|
keys.push(t.keys.drive);
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}).nThen(function () {
|
||||||
|
cb(keys);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
common.makeNetwork = function (cb) {
|
common.makeNetwork = function (cb) {
|
||||||
require([
|
require([
|
||||||
'/bower_components/netflux-websocket/netflux-client.js',
|
'/bower_components/netflux-websocket/netflux-client.js',
|
||||||
|
@ -629,6 +661,10 @@ define([
|
||||||
optsPut.password = password;
|
optsPut.password = password;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
common.getAccessKeys(waitFor(function (keys) {
|
||||||
|
optsGet.accessKeys = keys;
|
||||||
|
optsPut.accessKeys = keys;
|
||||||
|
}));
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
Crypt.get(parsed.hash, function (err, val) {
|
Crypt.get(parsed.hash, function (err, val) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -666,19 +702,28 @@ define([
|
||||||
password: data.password,
|
password: data.password,
|
||||||
initialState: parsed.type === 'poll' ? '{}' : undefined
|
initialState: parsed.type === 'poll' ? '{}' : undefined
|
||||||
};
|
};
|
||||||
Crypt.get(parsed.hash, _waitFor(function (err, _val) {
|
var next = _waitFor();
|
||||||
if (err) {
|
Nthen(function (waitFor) {
|
||||||
_waitFor.abort();
|
// Authenticate in case the pad os restricted
|
||||||
return void cb(err);
|
common.getAccessKeys(waitFor(function (keys) {
|
||||||
}
|
optsGet.accessKeys = keys;
|
||||||
try {
|
}));
|
||||||
val = JSON.parse(_val);
|
}).nThen(function () {
|
||||||
fixPadMetadata(val, true);
|
Crypt.get(parsed.hash, function (err, _val) {
|
||||||
} catch (e) {
|
if (err) {
|
||||||
_waitFor.abort();
|
_waitFor.abort();
|
||||||
return void cb(e.message);
|
return void cb(err);
|
||||||
}
|
}
|
||||||
}), optsGet);
|
try {
|
||||||
|
val = JSON.parse(_val);
|
||||||
|
fixPadMetadata(val, true);
|
||||||
|
next();
|
||||||
|
} catch (e) {
|
||||||
|
_waitFor.abort();
|
||||||
|
return void cb(e.message);
|
||||||
|
}
|
||||||
|
}, optsGet);
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -741,9 +786,6 @@ define([
|
||||||
}).nThen(function () {
|
}).nThen(function () {
|
||||||
Crypt.put(parsed2.hash, JSON.stringify(val), function () {
|
Crypt.put(parsed2.hash, JSON.stringify(val), function () {
|
||||||
cb();
|
cb();
|
||||||
Crypt.get(parsed2.hash, function (err, val) {
|
|
||||||
console.warn(val);
|
|
||||||
});
|
|
||||||
}, optsPut);
|
}, optsPut);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1006,7 +1048,7 @@ define([
|
||||||
oldSecret = Hash.getSecrets(parsed.type, parsed.hash, optsGet.password);
|
oldSecret = Hash.getSecrets(parsed.type, parsed.hash, optsGet.password);
|
||||||
oldChannel = oldSecret.channel;
|
oldChannel = oldSecret.channel;
|
||||||
common.getPadMetadata({channel: oldChannel}, waitFor(function (metadata) {
|
common.getPadMetadata({channel: oldChannel}, waitFor(function (metadata) {
|
||||||
oldMetadata = metadata;
|
oldMetadata = metadata || {};
|
||||||
}));
|
}));
|
||||||
common.getMetadata(waitFor(function (err, data) {
|
common.getMetadata(waitFor(function (err, data) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -1058,6 +1100,11 @@ define([
|
||||||
if (expire) {
|
if (expire) {
|
||||||
optsPut.metadata.expire = (expire - (+new Date())) / 1000; // Lifetime in seconds
|
optsPut.metadata.expire = (expire - (+new Date())) / 1000; // Lifetime in seconds
|
||||||
}
|
}
|
||||||
|
}).nThen(function (waitFor) {
|
||||||
|
common.getAccessKeys(waitFor(function (keys) {
|
||||||
|
optsGet.accessKeys = keys;
|
||||||
|
optsPut.accessKeys = keys;
|
||||||
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
Crypt.get(parsed.hash, waitFor(function (err, val) {
|
Crypt.get(parsed.hash, waitFor(function (err, val) {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -1074,6 +1121,8 @@ define([
|
||||||
}
|
}
|
||||||
}), optsGet);
|
}), optsGet);
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
|
optsPut.metadata.restricted = oldMetadata.restricted;
|
||||||
|
optsPut.metadata.allowed = oldMetadata.allowed;
|
||||||
Crypt.put(newHash, cryptgetVal, waitFor(function (err) {
|
Crypt.put(newHash, cryptgetVal, waitFor(function (err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
waitFor.abort();
|
waitFor.abort();
|
||||||
|
@ -1309,11 +1358,17 @@ define([
|
||||||
validateKey: newSecret.keys.validateKey
|
validateKey: newSecret.keys.validateKey
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
var optsGet = {};
|
||||||
|
|
||||||
Nthen(function (waitFor) {
|
Nthen(function (waitFor) {
|
||||||
common.getPadAttribute('', waitFor(function (err, _data) {
|
common.getPadAttribute('', waitFor(function (err, _data) {
|
||||||
padData = _data;
|
padData = _data;
|
||||||
|
optsGet.password = padData.password;
|
||||||
}), href);
|
}), href);
|
||||||
|
common.getAccessKeys(waitFor(function (keys) {
|
||||||
|
optsGet.accessKeys = keys;
|
||||||
|
optsPut.accessKeys = keys;
|
||||||
|
}));
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
oldSecret = Hash.getSecrets(parsed.type, parsed.hash, padData.password);
|
oldSecret = Hash.getSecrets(parsed.type, parsed.hash, padData.password);
|
||||||
|
|
||||||
|
@ -1392,9 +1447,7 @@ define([
|
||||||
waitFor.abort();
|
waitFor.abort();
|
||||||
return void cb({ error: 'CANT_PARSE' });
|
return void cb({ error: 'CANT_PARSE' });
|
||||||
}
|
}
|
||||||
}), {
|
}), optsGet);
|
||||||
password: padData.password
|
|
||||||
});
|
|
||||||
}).nThen(function (waitFor) {
|
}).nThen(function (waitFor) {
|
||||||
// Re-encrypt rtchannel
|
// Re-encrypt rtchannel
|
||||||
oldRtChannel = Util.find(cryptgetVal, ['content', 'channel']);
|
oldRtChannel = Util.find(cryptgetVal, ['content', 'channel']);
|
||||||
|
|
|
@ -1380,8 +1380,10 @@ define([
|
||||||
};
|
};
|
||||||
var i = 0;
|
var i = 0;
|
||||||
sframeChan.on('Q_CRYPTGET', function (data, cb) {
|
sframeChan.on('Q_CRYPTGET', function (data, cb) {
|
||||||
|
var keys;
|
||||||
var todo = function () {
|
var todo = function () {
|
||||||
data.opts.network = cgNetwork;
|
data.opts.network = cgNetwork;
|
||||||
|
data.opts.accessKeys = keys;
|
||||||
Cryptget.get(data.hash, function (err, val) {
|
Cryptget.get(data.hash, function (err, val) {
|
||||||
cb({
|
cb({
|
||||||
error: err,
|
error: err,
|
||||||
|
@ -1400,17 +1402,21 @@ define([
|
||||||
cgNetwork = undefined;
|
cgNetwork = undefined;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
if (!cgNetwork) {
|
|
||||||
cgNetwork = true;
|
Cryptpad.getAccessKeys(function (_keys) {
|
||||||
return void Cryptpad.makeNetwork(function (err, nw) {
|
keys = _keys;
|
||||||
console.log(nw);
|
if (!cgNetwork) {
|
||||||
cgNetwork = nw;
|
cgNetwork = true;
|
||||||
todo();
|
return void Cryptpad.makeNetwork(function (err, nw) {
|
||||||
});
|
console.log(nw);
|
||||||
} else if (cgNetwork === true) {
|
cgNetwork = nw;
|
||||||
return void whenCGReady(todo);
|
todo();
|
||||||
}
|
});
|
||||||
todo();
|
} else if (cgNetwork === true) {
|
||||||
|
return void whenCGReady(todo);
|
||||||
|
}
|
||||||
|
todo();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
sframeChan.on('EV_CRYPTGET_DISCONNECT', function () {
|
sframeChan.on('EV_CRYPTGET_DISCONNECT', function () {
|
||||||
if (!cgNetwork) { return; }
|
if (!cgNetwork) { return; }
|
||||||
|
|
Loading…
Reference in a new issue