|
|
|
@ -86,20 +86,37 @@ var createLoginBlockPath = function (Env, publicKey) { // FIXME BLOCKS
|
|
|
|
|
return Path.join(Env.paths.block, safeKey.slice(0, 2), safeKey);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var validateAncestorProof = function (Env, proof, newPubKey, cb) {
|
|
|
|
|
/* prove that you own an existing block by signing for its publicKey
|
|
|
|
|
|
|
|
|
|
we will need:
|
|
|
|
|
|
|
|
|
|
1. the publicKey
|
|
|
|
|
2. for the old key's block to exist
|
|
|
|
|
* path = createLoginBlockPath(Env, oldPublicKey)
|
|
|
|
|
* path && FS.readFile(path, err => { !err })
|
|
|
|
|
3. a message signed with that publicKey
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
cb("E_RESTRICTED");
|
|
|
|
|
var validateAncestorProof = function (Env, proof, _cb) {
|
|
|
|
|
var cb = Util.once(Util.mkAsync(_cb));
|
|
|
|
|
/* prove that you own an existing block by signing for its publicKey */
|
|
|
|
|
try {
|
|
|
|
|
var parsed = JSON.parse(proof);
|
|
|
|
|
var pub = parsed[0];
|
|
|
|
|
var u8_pub = Nacl.util.decodeBase64(pub);
|
|
|
|
|
var sig = parsed[1];
|
|
|
|
|
var u8_sig = Nacl.util.decodeBase64(sig);
|
|
|
|
|
var valid = false;
|
|
|
|
|
nThen(function (w) {
|
|
|
|
|
// XXX restricted-registration do this in a worker
|
|
|
|
|
valid = Nacl.sign.detached.verify(u8_pub, u8_sig, u8_pub);
|
|
|
|
|
if (!valid) {
|
|
|
|
|
w.abort();
|
|
|
|
|
return void cb('E_INVALID_ANCESTOR_PROOF');
|
|
|
|
|
}
|
|
|
|
|
// else fall through to next step
|
|
|
|
|
}).nThen(function (w) {
|
|
|
|
|
var path = createLoginBlockPath(Env, pub);
|
|
|
|
|
Fs.access(path, Fs.constants.F_OK, w(function (err) {
|
|
|
|
|
if (!err) { return; }
|
|
|
|
|
w.abort(); // else
|
|
|
|
|
return void cb("E_MISSING_ANCESTOR");
|
|
|
|
|
}));
|
|
|
|
|
}).nThen(function () {
|
|
|
|
|
cb(void 0, valid);
|
|
|
|
|
});
|
|
|
|
|
} catch (err) {
|
|
|
|
|
return void cb(err);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Block.writeLoginBlock = function (Env, safeKey, msg, _cb) { // FIXME BLOCKS
|
|
|
|
@ -119,14 +136,13 @@ Block.writeLoginBlock = function (Env, safeKey, msg, _cb) { // FIXME BLOCKS
|
|
|
|
|
w.abort();
|
|
|
|
|
return cb("E_RESTRICTED");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// TODO check that the provided proof was valid
|
|
|
|
|
// XXX restricted-registration check whether proof of an existing block was provided
|
|
|
|
|
validateAncestorProof(Env, void 0, w(function (err) {
|
|
|
|
|
if (err) {
|
|
|
|
|
validateAncestorProof(Env, registrationProof, w(function (err, validated) {
|
|
|
|
|
if (err || !validated) { // double check that it was validated
|
|
|
|
|
w.abort();
|
|
|
|
|
cb(err);
|
|
|
|
|
// XXX Log
|
|
|
|
|
return void cb("E_RESTRICTED"); // XXX restricted-registration we can provide more descriptive errors if we check that the client will understand them
|
|
|
|
|
}
|
|
|
|
|
// else fall through to the next block
|
|
|
|
|
}));
|
|
|
|
|
}).nThen(function (w) {
|
|
|
|
|
validateLoginBlock(Env, publicKey, signature, block, w(function (e, _validatedBlock) {
|
|
|
|
|