update block storage APIs
This commit is contained in:
parent
15a8284a30
commit
729d51fb9b
9 changed files with 109 additions and 36 deletions
|
@ -392,7 +392,7 @@ define([
|
|||
// send an RPC to store the block which you created.
|
||||
console.log("initializing rpc interface");
|
||||
|
||||
Pinpad.create(RT.network, RT.proxy, waitFor(function (e, _rpc) {
|
||||
Pinpad.create(RT.network, Block.keysToRPCFormat(res.opt.blockKeys), waitFor(function (e, _rpc) {
|
||||
if (e) {
|
||||
waitFor.abort();
|
||||
console.error(e); // INVALID_KEYS
|
||||
|
|
|
@ -86,7 +86,7 @@ var createLoginBlockPath = function (Env, publicKey) { // FIXME BLOCKS
|
|||
return Path.join(Env.paths.block, safeKey.slice(0, 2), safeKey);
|
||||
};
|
||||
|
||||
var validateAncestorProof = function (Env, proof, _cb) {
|
||||
Block.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 {
|
||||
|
@ -97,7 +97,6 @@ var validateAncestorProof = function (Env, proof, _cb) {
|
|||
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();
|
||||
|
@ -130,14 +129,23 @@ Block.writeLoginBlock = function (Env, safeKey, msg, _cb) { // FIXME BLOCKS
|
|||
|
||||
var validatedBlock, parsed, path;
|
||||
nThen(function (w) {
|
||||
if (Util.escapeKeyCharacters(publicKey) !== safeKey) {
|
||||
w.abort();
|
||||
return void cb("INCORRECT_KEY");
|
||||
}
|
||||
}).nThen(function (w) {
|
||||
if (!Env.restrictRegistration) { return; }
|
||||
if (!registrationProof) {
|
||||
// we allow users with existing blocks to create new ones
|
||||
// call back with error if registration is restricted and no proof of an existing block was provided
|
||||
w.abort();
|
||||
Env.Log.info("BLOCK_REJECTED_REGISTRATION", {
|
||||
safeKey: safeKey,
|
||||
publicKey: publicKey,
|
||||
});
|
||||
return cb("E_RESTRICTED");
|
||||
}
|
||||
validateAncestorProof(Env, registrationProof, w(function (err, provenKey) {
|
||||
Env.validateAncestorProof(registrationProof, w(function (err, provenKey) {
|
||||
if (err || !provenKey) { // double check that a key was validated
|
||||
w.abort();
|
||||
Env.Log.warn('BLOCK_REJECTED_INVALID_ANCESTOR', {
|
||||
|
@ -191,6 +199,7 @@ Block.writeLoginBlock = function (Env, safeKey, msg, _cb) { // FIXME BLOCKS
|
|||
blockId: publicKey,
|
||||
isChange: Boolean(registrationProof),
|
||||
previousKey: previousKey,
|
||||
path: path,
|
||||
});
|
||||
cb();
|
||||
});
|
||||
|
@ -212,26 +221,33 @@ Block.removeLoginBlock = function (Env, safeKey, msg, cb) { // FIXME BLOCKS
|
|||
var signature = msg[1];
|
||||
var block = Nacl.util.decodeUTF8('DELETE_BLOCK'); // clients and the server will have to agree on this constant
|
||||
|
||||
validateLoginBlock(Env, publicKey, signature, block, function (e /*::, validatedBlock */) {
|
||||
if (e) { return void cb(e); }
|
||||
// derive the filepath
|
||||
var path = createLoginBlockPath(Env, publicKey);
|
||||
|
||||
// make sure the path is valid
|
||||
if (typeof(path) !== 'string') {
|
||||
return void cb('E_INVALID_BLOCK_PATH');
|
||||
nThen(function (w) {
|
||||
if (Util.escapeKeyCharacters(publicKey) !== safeKey) {
|
||||
w.abort();
|
||||
return void cb("INCORRECT_KEY");
|
||||
}
|
||||
}).nThen(function () {
|
||||
validateLoginBlock(Env, publicKey, signature, block, function (e /*::, validatedBlock */) {
|
||||
if (e) { return void cb(e); }
|
||||
// derive the filepath
|
||||
var path = createLoginBlockPath(Env, publicKey);
|
||||
|
||||
// FIXME COLDSTORAGE
|
||||
Fs.unlink(path, function (err) {
|
||||
Env.Log.info('DELETION_BLOCK_BY_OWNER_RPC', {
|
||||
publicKey: publicKey,
|
||||
path: path,
|
||||
status: err? String(err): 'SUCCESS',
|
||||
// make sure the path is valid
|
||||
if (typeof(path) !== 'string') {
|
||||
return void cb('E_INVALID_BLOCK_PATH');
|
||||
}
|
||||
|
||||
// FIXME COLDSTORAGE
|
||||
Fs.unlink(path, function (err) {
|
||||
Env.Log.info('DELETION_BLOCK_BY_OWNER_RPC', {
|
||||
publicKey: publicKey,
|
||||
path: path,
|
||||
status: err? String(err): 'SUCCESS',
|
||||
});
|
||||
|
||||
if (err) { return void cb(err); }
|
||||
cb();
|
||||
});
|
||||
|
||||
if (err) { return void cb(err); }
|
||||
cb();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -158,6 +158,7 @@ module.exports.create = function (Env, cb) {
|
|||
pinPath: Env.paths.pin,
|
||||
filePath: Env.paths.data,
|
||||
archivePath: Env.paths.archive,
|
||||
blockPath: Env.paths.block,
|
||||
|
||||
inactiveTime: Env.inactiveTime,
|
||||
archiveRetentionTime: Env.archiveRetentionTime,
|
||||
|
|
|
@ -295,7 +295,7 @@ var owned_upload_complete = function (Env, safeKey, id, cb) {
|
|||
// removeBlob
|
||||
var remove = function (Env, blobId, cb) {
|
||||
var blobPath = makeBlobPath(Env, blobId);
|
||||
Fs.unlink(blobPath, cb); // TODO COLDSTORAGE
|
||||
Fs.unlink(blobPath, cb);
|
||||
};
|
||||
|
||||
// removeProof
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
const HK = require("../hk-util");
|
||||
const Store = require("../storage/file");
|
||||
const BlobStore = require("../storage/blob");
|
||||
const Block = require("../commands/block");
|
||||
const Util = require("../common-util");
|
||||
const nThen = require("nthen");
|
||||
const Meta = require("../metadata");
|
||||
|
@ -47,6 +48,7 @@ const init = function (config, _cb) {
|
|||
|
||||
Env.paths = {
|
||||
pin: config.pinPath,
|
||||
block: config.blockPath,
|
||||
};
|
||||
|
||||
Env.inactiveTime = config.inactiveTime;
|
||||
|
@ -688,6 +690,10 @@ COMMANDS.HASH_CHANNEL_LIST = function (data, cb) {
|
|||
cb(void 0, hash);
|
||||
};
|
||||
|
||||
COMMANDS.VALIDATE_ANCESTOR_PROOF = function (data, cb) {
|
||||
Block.validateAncestorProof(Env, data && data.proof, cb);
|
||||
};
|
||||
|
||||
process.on('message', function (data) {
|
||||
if (!data || !data.txid || !data.pid) {
|
||||
return void process.send({
|
||||
|
|
|
@ -444,6 +444,13 @@ Workers.initialize = function (Env, config, _cb) {
|
|||
}, cb);
|
||||
};
|
||||
|
||||
Env.validateAncestorProof = function (proof, cb) {
|
||||
sendCommand({
|
||||
command: 'VALIDATE_ANCESTOR_PROOF',
|
||||
proof: proof,
|
||||
}, cb);
|
||||
};
|
||||
|
||||
cb(void 0);
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1735,6 +1735,7 @@ define([
|
|||
var removeData = obj.Block.remove(blockKeys);
|
||||
|
||||
postMessage("DELETE_ACCOUNT", {
|
||||
keys: Block.keysToRPCFormat(blockKeys),
|
||||
removeData: removeData
|
||||
}, function (obj) {
|
||||
if (obj.state) {
|
||||
|
@ -1856,11 +1857,15 @@ define([
|
|||
|
||||
var content = Block.serialize(JSON.stringify(temp), blockKeys);
|
||||
console.error("OLD AND NEW BLOCK KEYS", oldBlockKeys, blockKeys);
|
||||
// XXX ignored unless restricted registration is active?
|
||||
content.registrationProof = Block.proveAncestor(oldBlockKeys);
|
||||
|
||||
console.log("writing new login block");
|
||||
common.writeLoginBlock(content, waitFor(function (obj) {
|
||||
|
||||
var data = {
|
||||
keys: Block.keysToRPCFormat(blockKeys),
|
||||
content: content,
|
||||
};
|
||||
common.writeLoginBlock(data, waitFor(function (obj) {
|
||||
if (obj && obj.error) {
|
||||
waitFor.abort();
|
||||
return void cb(obj);
|
||||
|
@ -1878,8 +1883,11 @@ define([
|
|||
// Remove block hash
|
||||
if (blockHash) {
|
||||
console.log('removing old login block');
|
||||
var removeData = Block.remove(oldBlockKeys);
|
||||
common.removeLoginBlock(removeData, waitFor(function (obj) {
|
||||
var data = {
|
||||
keys: Block.keysToRPCFormat(oldBlockKeys), // { edPrivate, edPublic }
|
||||
content: Block.remove(oldBlockKeys),
|
||||
};
|
||||
common.removeLoginBlock(data, waitFor(function (obj) {
|
||||
if (obj && obj.error) { return void console.error(obj.error); }
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -451,19 +451,33 @@ define([
|
|||
};
|
||||
|
||||
Store.writeLoginBlock = function (clientId, data, cb) {
|
||||
store.rpc.writeLoginBlock(data, function (e, res) {
|
||||
cb({
|
||||
error: e,
|
||||
data: res
|
||||
Pinpad.create(store.network, data && data.keys, function (err, rpc) {
|
||||
if (err) {
|
||||
return void cb({
|
||||
error: err,
|
||||
});
|
||||
}
|
||||
rpc.writeLoginBlock(data && data.content, function (e, res) {
|
||||
cb({
|
||||
error: e,
|
||||
data: res
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Store.removeLoginBlock = function (clientId, data, cb) {
|
||||
store.rpc.removeLoginBlock(data, function (e, res) {
|
||||
cb({
|
||||
error: e,
|
||||
data: res
|
||||
Pinpad.create(store.network, data && data.keys, function (err, rpc) {
|
||||
if (err) {
|
||||
return void cb({
|
||||
error: err,
|
||||
});
|
||||
}
|
||||
rpc.removeLoginBlock(data && data.content, function (e, res) {
|
||||
cb({
|
||||
error: e,
|
||||
data: res
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -815,6 +829,7 @@ define([
|
|||
Store.deleteAccount = function (clientId, data, cb) {
|
||||
var edPublic = store.proxy.edPublic;
|
||||
var removeData = data && data.removeData;
|
||||
var rpcKeys = data && data.keys;
|
||||
Store.anonRpcMsg(clientId, {
|
||||
msg: 'GET_METADATA',
|
||||
data: store.driveChannel
|
||||
|
@ -845,8 +860,15 @@ define([
|
|||
}, waitFor());
|
||||
}).nThen(function (waitFor) {
|
||||
if (!removeData) { return; }
|
||||
// Delete the block. Don't abort if it fails, it doesn't leak any data.
|
||||
store.rpc.removeLoginBlock(removeData, waitFor());
|
||||
var done = waitFor();
|
||||
Pinpad.create(store.network, rpcKeys, function (err, rpc) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return void done();
|
||||
}
|
||||
// Delete the block. Don't abort if it fails, it doesn't leak any data.
|
||||
rpc.removeLoginBlock(removeData, done);
|
||||
});
|
||||
}).nThen(function () {
|
||||
// Log out current worker
|
||||
postMessage(clientId, "DELETE_ACCOUNT", token, function () {});
|
||||
|
|
|
@ -40,6 +40,19 @@ define([
|
|||
};
|
||||
};
|
||||
|
||||
Block.keysToRPCFormat = function (keys) {
|
||||
try {
|
||||
var sign = keys.sign;
|
||||
return {
|
||||
edPrivate: Nacl.util.encodeBase64(sign.secretKey),
|
||||
edPublic: Nacl.util.encodeBase64(sign.publicKey),
|
||||
};
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
// (UTF8 content, keys object) => Uint8Array block
|
||||
Block.encrypt = function (version, content, keys) {
|
||||
var u8 = Nacl.util.decodeUTF8(content);
|
||||
|
|
Loading…
Reference in a new issue