diff --git a/config.example.js b/config.example.js index 0af71afbb..2c234aee4 100644 --- a/config.example.js +++ b/config.example.js @@ -325,4 +325,12 @@ module.exports = { // '/etc/apache2/ssl/my_public_cert.crt', // '/etc/apache2/ssl/my_certificate_authorities_cert_chain.ca' //], + + /* You can get a repl for debugging the server if you want it. + * to enable this, specify the debugReplName and then you can + * connect to it with `nc -U /tmp/repl/.sock` + * If you run multiple cryptpad servers, you need to use different + * repl names. + */ + //debugReplName: "cryptpad" }; diff --git a/package.json b/package.json index b9cac6c82..eb6149506 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "express": "~4.10.1", "nthen": "~0.1.0", "pull-stream": "^3.6.1", + "replify": "^1.2.0", "saferphore": "0.0.1", "stream-to-pull-stream": "^1.7.2", "tweetnacl": "~0.12.2", diff --git a/rpc.js b/rpc.js index 83d166e2e..94d4d4e7e 100644 --- a/rpc.js +++ b/rpc.js @@ -428,8 +428,7 @@ var getHash = function (Env, publicKey, cb) { // The limits object contains storage limits for all the publicKey that have paid // To each key is associated an object containing the 'limit' value and a 'note' explaining that limit -var limits = {}; -var updateLimits = function (config, publicKey, cb /*:(?string, ?any[])=>void*/) { +var updateLimits = function (Env, config, publicKey, cb /*:(?string, ?any[])=>void*/) { if (config.adminEmail === false) { if (config.allowSubscriptions === false) { return; } throw new Error("allowSubscriptions must be false if adminEmail is false"); @@ -494,15 +493,15 @@ var updateLimits = function (config, publicKey, cb /*:(?string, ?any[])=>void*/) response.on('end', function () { try { var json = JSON.parse(str); - limits = json; + Env.limits = json; Object.keys(customLimits).forEach(function (k) { if (!isLimit(customLimits[k])) { return; } - limits[k] = customLimits[k]; + Env.limits[k] = customLimits[k]; }); var l; if (userId) { - var limit = limits[userId]; + var limit = Env.limits[userId]; l = limit && typeof limit.limit === "number" ? [limit.limit, limit.plan, limit.note] : [defaultLimit, '', '']; } @@ -523,7 +522,7 @@ var updateLimits = function (config, publicKey, cb /*:(?string, ?any[])=>void*/) var getLimit = function (Env, publicKey, cb) { var unescapedKey = unescapeKeyCharacters(publicKey); - var limit = limits[unescapedKey]; + var limit = Env.limits[unescapedKey]; var defaultLimit = typeof(Env.defaultStorageLimit) === 'number'? Env.defaultStorageLimit: DEFAULT_LIMIT; @@ -1097,7 +1096,11 @@ type NetfluxWebsocketSrvContext_t = { )=>void }; */ -RPC.create = function (config /*:Config_t*/, cb /*:(?Error, ?Function)=>void*/) { +RPC.create = function ( + config /*:Config_t*/, + debuggable /*:(string, T)=>T*/, + cb /*:(?Error, ?Function)=>void*/ +) { // load pin-store... console.log('loading rpc module...'); @@ -1115,8 +1118,10 @@ RPC.create = function (config /*:Config_t*/, cb /*:(?Error, ?Function)=>void*/) msgStore: (undefined /*:any*/), pinStore: (undefined /*:any*/), pinnedPads: {}, - evPinnedPadsReady: mkEvent(true) + evPinnedPadsReady: mkEvent(true), + limits: {} }; + debuggable('rpc_env', Env); var Sessions = Env.Sessions; var paths = Env.paths; @@ -1306,7 +1311,7 @@ RPC.create = function (config /*:Config_t*/, cb /*:(?Error, ?Function)=>void*/) Respond(e, size); }); case 'UPDATE_LIMITS': - return void updateLimits(config, safeKey, function (e, limit) { + return void updateLimits(Env, config, safeKey, function (e, limit) { if (e) { WARN(e, limit); return void Respond(e); @@ -1418,7 +1423,7 @@ RPC.create = function (config /*:Config_t*/, cb /*:(?Error, ?Function)=>void*/) }; var updateLimitDaily = function () { - updateLimits(config, undefined, function (e) { + updateLimits(Env, config, undefined, function (e) { if (e) { WARN('limitUpdate', e); } diff --git a/server.js b/server.js index 5a2cbfbb8..e803a829e 100644 --- a/server.js +++ b/server.js @@ -21,10 +21,25 @@ try { var websocketPort = config.websocketPort || config.httpPort; var useSecureWebsockets = config.useSecureWebsockets || false; +// This is stuff which will become available to replify +const debuggableStore = new WeakMap(); +const debuggable = function (name, x) { + if (name in debuggableStore) { + try { throw new Error(); } catch (e) { + console.error('cannot add ' + name + ' more than once [' + e.stack + ']'); + } + } else { + debuggableStore[name] = x; + } + return x; +}; +debuggable('global', global); +debuggable('config', config); + // support multiple storage back ends var Storage = require(config.storage||'./storage/file'); -var app = Express(); +var app = debuggable('app', Express()); var httpsOpts; @@ -204,7 +219,6 @@ var rpc; var nt = nThen(function (w) { if (!config.enableTaskScheduling) { return; } var Tasks = require("./storage/tasks"); - console.log("loading task scheduler"); Tasks.create(config, w(function (e, tasks) { config.tasks = tasks; @@ -214,7 +228,7 @@ var nt = nThen(function (w) { if (typeof(config.rpc) !== 'string') { return; } // load pin store... var Rpc = require(config.rpc); - Rpc.create(config, w(function (e, _rpc) { + Rpc.create(config, debuggable, w(function (e, _rpc) { if (e) { w.abort(); throw e; @@ -233,3 +247,6 @@ var nt = nThen(function (w) { }); }); +if (config.debugReplName) { + require('replify')({ name: config.debugReplName, app: debuggableStore }); +} \ No newline at end of file diff --git a/www/todo/inner.js b/www/todo/inner.js index 8d5de7778..6e6bcf297 100644 --- a/www/todo/inner.js +++ b/www/todo/inner.js @@ -70,6 +70,10 @@ define([ var makeCheckbox = function (id, cb) { var entry = APP.lm.proxy.data[id]; + if (!entry || typeof(entry) !== 'object') { + return void console.log('entry undefined'); + } + var checked = entry.state === 1 ? 'cp-app-todo-task-checkbox-checked fa-check-square-o': 'cp-app-todo-task-checkbox-unchecked fa-square-o'; @@ -108,6 +112,9 @@ define([ .appendTo($taskDiv); var entry = APP.lm.proxy.data[el]; + if (!entry || typeof(entry) !== 'object') { + return void console.log('entry undefined'); + } if (entry.state) { $taskDiv.addClass('cp-app-todo-task-complete');