diff --git a/config.example.js b/config.example.js index 76bba6eae..1be17e510 100644 --- a/config.example.js +++ b/config.example.js @@ -116,6 +116,12 @@ module.exports = { 'contact', ], + /* Domain + * If you want to have enable payments on your CryptPad instance, it has to be able to tell + * our account server what is your domain + */ + // domain: 'https://cryptpad.fr', + /* You have the option of specifying an alternative storage adaptor. These status of these alternatives are specified in their READMEs, diff --git a/rpc.js b/rpc.js index ec6e516d0..6e437e385 100644 --- a/rpc.js +++ b/rpc.js @@ -7,11 +7,14 @@ var Nacl = require("tweetnacl"); var Fs = require("fs"); var Path = require("path"); +var Https = require("https"); var RPC = module.exports; var Store = require("./storage/file"); +var DEFAULT_LIMIT = 100; + var isValidChannel = function (chan) { return /^[a-fA-F0-9]/.test(chan) || [32, 48].indexOf(chan.length) !== -1; @@ -454,8 +457,61 @@ var isPrivilegedUser = function (publicKey, cb) { }); }; -var getLimit = function (cb) { - cb = cb; // TODO +// 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) { + if (typeof cb !== "function") { cb = function () {}; } + + var body = JSON.stringify({ + domain: config.domain, + subdomain: config.subdomain + }); + var options = { + host: 'accounts.cryptpad.fr', + path: '/api/getauthorized', + method: 'POST', + headers: { + "Content-Type": "application/json", + "Content-Length": Buffer.byteLength(body) + } + }; + var req = Https.request(options, function (response) { + if (!('' + req.statusCode).match(/^2\d\d$/)) { + return void cb('SERVER ERROR ' + req.statusCode); + } + var str = ''; + + response.on('data', function (chunk) { + str += chunk; + }); + + response.on('end', function () { + try { + var json = JSON.parse(str); + limits = json; + var l; + if (publicKey) { + var limit = limits[publicKey]; + l = limit && typeof limit.limit === "number" ? limit.limit : DEFAULT_LIMIT; + } + cb(void 0, l); + } catch (e) { + cb(e); + } + }); + }); + + req.on('error', function (e) { + if (!config.domain) { return cb(); } + cb(e); + }); + + req.end(body); +}; +var getLimit = function (publicKey, cb) { + var limit = limits[publicKey]; + return limit && typeof limit.limit === "number" ? limit.limit : DEFAULT_LIMIT; }; var safeMkdir = function (path, cb) { @@ -714,10 +770,16 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) }); case 'GET_FILE_SIZE': return void getFileSize(ctx.store, msg[1], Respond); - case 'GET_LIMIT': // TODO implement this and cache it per-user - return void getLimit(function (e, limit) { + case 'UPDATE_LIMITS': + return void updateLimits(config, safeKey, function (e, limit) { + if (e) { return void Respond(e); } + Respond(void 0, limit); + }); + case 'GET_LIMIT': + return void getLimit(safeKey, function (e, limit) { + if (e) { return void Respond(e); } limit = limit; - Respond('NOT_IMPLEMENTED'); + Respond(void 0, limit); }); case 'GET_MULTIPLE_FILE_SIZE': return void getMultipleFileSize(ctx.store, msg[1], function (e, dict) { @@ -775,6 +837,14 @@ RPC.create = function (config /*:typeof(ConfigType)*/, cb /*:(?Error, ?Function) handleMessage(session.privilege); }; + var updateLimitDaily = function () { + updateLimits(config, undefined, function (e) { + if (e) { console.error('Error updating the storage limits', e); } + }); + }; + updateLimitDaily(); + setInterval(updateLimitDaily, 24*3600*1000); + Store.create({ filePath: pinPath, }, function (s) { diff --git a/www/common/cryptpad-common.js b/www/common/cryptpad-common.js index 73b51e8b3..e63399ec1 100644 --- a/www/common/cryptpad-common.js +++ b/www/common/cryptpad-common.js @@ -744,8 +744,15 @@ define([ }); }; + common.updatePinLimit = function (cb) { + if (!pinsReady()) { return void cb('[RPC_NOT_READY]'); } + rpc.getFileListSize(cb); + }; + common.getPinLimit = function (cb) { - cb(void 0, typeof(AppConfig.pinLimit) === 'number'? AppConfig.pinLimit: 1000); + if (!pinsReady()) { return void cb('[RPC_NOT_READY]'); } + rpc.getFileListSize(cb); + //cb(void 0, typeof(AppConfig.pinLimit) === 'number'? AppConfig.pinLimit: 1000); }; common.isOverPinLimit = function (cb) { diff --git a/www/common/pinpad.js b/www/common/pinpad.js index 3470db34e..efa915ec7 100644 --- a/www/common/pinpad.js +++ b/www/common/pinpad.js @@ -121,6 +121,29 @@ define([ }); }; + // Update the limit value for all the users and return the limit for your publicKey + exp.updatePinLimits = function (cb) { + rpc.send('UPDATE_LIMITS', undefined, function (e, response) { + if (e) { return void cb(e); } + if (response && typeof response === "number") { + cb (void 0, response); + } else { + cb('INVALID_RESPONSE'); + } + }); + }; + // Get the storage limit associated with your publicKey + exp.getLimit = function (cb) { + rpc.send('GET_LIMIT', undefined, function (e, response) { + if (e) { return void cb(e); } + if (response && typeof response === "number") { + cb (void 0, response); + } else { + cb('INVALID_RESPONSE'); + } + }); + }; + cb(e, exp); }); };