resolve merge-conflict with accounting branch

pull/1/head
ansuz 8 years ago
commit 306f6ce806

@ -209,6 +209,21 @@ const handleMessage = function (ctx, user, msg) {
let parsedMsg = {state: 1, channel: parsed[1]};
sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify(parsedMsg)]);
});
} else if (ctx.rpc) {
/* RPC Calls... */
var rpc_call = parsed.slice(1);
// slice off the sequence number and pass in the rest of the message
ctx.rpc(rpc_call, function (err, output) {
if (err) {
console.error('[' + err + ']', output); // TODO make this disableable
sendMsg(ctx, user, [seq, 'ACK']);
sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify([parsed[0], 'ERROR', err])]);
return
}
sendMsg(ctx, user, [seq, 'ACK']);
sendMsg(ctx, user, [0, HISTORY_KEEPER_ID, 'MSG', user.id, JSON.stringify([parsed[0]].concat(output))]);
});
}
return;
}
@ -251,7 +266,7 @@ const handleMessage = function (ctx, user, msg) {
}
};
let run = module.exports.run = function (storage, socketServer, config) {
let run = module.exports.run = function (storage, socketServer, config, rpc) {
/* Channel removal timeout defaults to 60000ms (one minute) */
config.channelRemovalTimeout =
typeof(config.channelRemovalTimeout) === 'number'?
@ -263,7 +278,8 @@ let run = module.exports.run = function (storage, socketServer, config) {
channels: {},
timeouts: {},
store: storage,
config: config
config: config,
rpc: rpc,
};
setInterval(function () {
Object.keys(ctx.users).forEach(function (userId) {

@ -130,6 +130,13 @@ module.exports = {
*/
openFileLimit: 2048,
/* Cryptpad's socket server can be extended to respond to RPC calls
* you can configure it to respond to custom RPC calls if you like.
* provide the path to your RPC module here, or `false` if you would
* like to disable the RPC interface completely
*/
rpc: './rpc.js',
/* it is recommended that you serve cryptpad over https
* the filepaths below are used to configure your certificates
*/

@ -0,0 +1,37 @@
/* Use Nacl for checking signatures of messages
*/
var Nacl = require("tweetnacl");
var RPC = module.exports;
var pin = function (ctx, cb) { };
var unpin = function (ctx, cb) { };
var getHash = function (ctx, cb) { };
var getTotalSize = function (ctx, cb) { };
var getFileSize = function (ctx, cb) { };
RPC.create = function (config, cb) {
// load pin-store...
console.log('loading rpc module...');
rpc = function (msg, respond) {
switch (msg[0]) {
case 'ECHO':
respond(void 0, msg);
break;
case 'PIN':
case 'UNPIN':
case 'GET_HASH':
case 'GET_TOTAL_SIZE':
case 'GET_FILE_SIZE':
default:
respond('UNSUPPORTED_RPC_CALL', msg);
break;
}
};
cb(void 0, rpc);
};

@ -117,13 +117,32 @@ httpServer.listen(config.httpPort,config.httpAddress,function(){
var wsConfig = { server: httpServer };
if(!config.useExternalWebsocket) {
if (websocketPort !== config.httpPort) {
console.log("setting up a new websocket server");
wsConfig = { port: websocketPort};
var createSocketServer = function (err, rpc) {
if(!config.useExternalWebsocket) {
if (websocketPort !== config.httpPort) {
console.log("setting up a new websocket server");
wsConfig = { port: websocketPort};
}
var wsSrv = new WebSocketServer(wsConfig);
Storage.create(config, function (store) {
NetfluxSrv.run(store, wsSrv, config, rpc);
});
}
var wsSrv = new WebSocketServer(wsConfig);
Storage.create(config, function (store) {
NetfluxSrv.run(store, wsSrv, config);
});
}
};
var loadRPC = function (cb) {
config.rpc = typeof(config.rpc) === 'undefined'? './rpc.js' : config.rpc;
if (typeof(config.rpc) === 'string') {
// load pin store...
var Rpc = require(config.rpc);
Rpc.create(config, function (e, rpc) {
if (e) { throw e; }
cb(void 0, rpc);
});
} else {
cb();
}
};
loadRPC(createSocketServer);

@ -0,0 +1,19 @@
define([], function () {
var exports = {};
var hexToUint8Array = exports.hexToUint8Array = function (s) {
// if not hex or odd number of characters
if (!/[a-fA-F0-9]+/.test(s) || s.length % 2) { throw new Error("string is not hex"); }
return s.split(/([0-9a-fA-F]{2})/)
.filter(function (x) { return x; })
.map(function (x) { return Number('0x' + x); });
};
var uint8ArrayToHex = exports.uint8ArrayToHex = function (a) {
return a.reduce(function(memo, i) {
return memo + ((i < 16) ? '0' : '') + i.toString(16);
}, '');
};
return exports;
});

@ -0,0 +1,57 @@
define([
'/common/cryptpad-common.js',
'/common/rpc.js',
'/bower_components/tweetnacl/nacl-fast.min.js'
], function (Cryptpad, Rpc) {
var Nacl = window.nacl;
var deduplicate = function (array) {
var a = array.slice();
for(var i=0; i<a.length; i++) {
for(var j=i+1; j<a.length; j++) {
if(a[i] === a[j]) { a.splice(j--, 1); }
}
}
return a;
};
var create = function (network, ed) {
var exp = {};
var rpc = Rpc.create(network, ed);
var checkHash = exp.checkHash = function (fileList) {
//var fileList = fo.getFilesDataFiles();
var channelIdList = [];
fileList.forEach(function (href) {
var parsedHref = Cryptpad.parsePadUrl(href);
if (!parsedHref || !parsedHref.hash) { return; }
var parsedHash = Cryptpad.parseHash(parsedHref.hash);
if (!parsedHash || !parsedHash.channel) { return; }
channelIdList.push(Cryptpad.base64ToHex(parsedHash.channel));
});
var uniqueList = deduplicate(channelIdList).sort();
/*
1. every time you want to pin or unpid a pad you send a message to the server
2. the server sends back a hash of the sorted list of your pinned pads
3. you hash your sorted list of pinned pads that you should have according to your drive
4. compare them, if same
AWESOME
if they are not
UNPIN all, send all
*/
var hash = Nacl.util.encodeBase64(Nacl.hash(Nacl.util.decodeUTF8( JSON.stringify(uniqueList) )));
console.log(hash);
return hash;
};
return exp;
};
return { create: create };
});

@ -0,0 +1,106 @@
define([
'/common/encode.js',
'/bower_components/tweetnacl/nacl-fast.min.js',
], function (Encode) {
var MAX_LAG_BEFORE_TIMEOUT = 30000;
var uid = function () {
return Number(Math.floor(Math.random() * Number.MAX_SAFE_INTEGER))
.toString(32).replace(/\./g, '');
};
/*
types of messages:
pin -> hash
unpin -> hash
getHash -> hash
getTotalSize -> bytes
getFileSize -> bytes
*/
/* RPC communicates only with the history keeper
messages have the format:
[TYPE, txid, msg]
*/
var sendMsg = function (ctx, type, msg, cb) {
var network = ctx.network;
var hkn = network.historyKeeper;
var txid = uid();
ctx.pending[txid] = cb;
return network.sendto(hkn, JSON.stringify([txid, type, msg]));
};
var parse = function (msg) {
try {
return JSON.parse(msg);
} catch (e) {
return null;
}
};
/* Returning messages have the format:
[txid, {}]
*/
var onMsg = function (ctx, msg) {
var parsed = parse(msg);
if (!parsed) {
// TODO handle error
console.log(msg);
return;
}
var txid = parsed[0];
var pending = ctx.pending[txid];
var response = parsed.slice(1);
if (typeof(pending) === 'function') {
if (response[0] === 'ERROR') {
return void pending(response[1]);
}
pending(void 0, response);
} else {
console.log("No callback provided");
}
};
var cookie = function (ctx, cb) {
// TODO txid
};
var signMsg = function (msg, secKey) {
// TODO
};
var create = function (network, edPrivateKey) {
if (!/[0-9a-f]{64}/.test(edPrivateKey)) {
//throw new Error("private signing key is not valid");
}
var ctx = {
//privateKey: Encode.hexToUint8Array(edPrivateKey),
seq: new Date().getTime(),
network: network,
timeouts: {}, // timeouts
pending: {}, // callbacks
};
var pin = function (channel, cb) { };
var send = function (type, msg, cb) {
return sendMsg(ctx, type, msg, cb);
};
network.on('message', function (msg, sender) {
onMsg(ctx, msg);
});
return {
cookie: function (cb) { cookie(ctx, cb); },
send: send,
};
};
return { create: create };
});

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html class="cp slide">
<head>
<title>CryptPad</title>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<script data-bootload="main.js" data-main="/common/boot.js" src="/bower_components/requirejs/require.js"></script>
</head>
<body>
<div id="iframe-container">
<iframe id="pad-iframe"></iframe><script src="/common/noscriptfix.js"></script>
</div>
</body>
</html>

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<h1>PEWPEW

@ -0,0 +1,35 @@
require.config({ paths: { 'json.sortify': '/bower_components/json.sortify/dist/JSON.sortify' } });
define([
'/common/cryptpad-common.js',
'/common/rpc.js',
'/bower_components/jquery/dist/jquery.min.js',
], function (Cryptpad, RPC) {
var $ = window.jQuery;
var APP = window.APP = {
Cryptpad: Cryptpad,
};
$(function () {
Cryptpad.ready(function (err, env) {
var network = Cryptpad.getNetwork();
var rpc = RPC.create(network); // TODO signing key
var payload = {
a: Math.floor(Math.random() * 1000),
b: 7,
};
// console.log(payload);
rpc.send('ECHO', payload, function (e, msg) {
if (e) { return void console.error(e); }
console.log(msg);
});
// test a non-existent RPC call
rpc.send('PEWPEW', ['pew'], function (e, msg) {
if (e) { return void console.error(e); }
console.log(msg);
});
});
});
});
Loading…
Cancel
Save