update block storage APIs

This commit is contained in:
ansuz 2021-04-29 13:32:19 +05:30
parent 15a8284a30
commit 729d51fb9b
9 changed files with 109 additions and 36 deletions

View file

@ -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

View file

@ -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();
});
});
};

View file

@ -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,

View file

@ -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

View file

@ -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({

View file

@ -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);
});
};

View file

@ -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); }
}));
}

View file

@ -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 () {});

View file

@ -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);