Merge branch 'staging' into small-config

pull/1/head
ansuz 5 years ago
commit 02fc343727

@ -1,4 +1,3 @@
/*@flow*/
/* /*
globals module globals module
*/ */
@ -200,6 +199,9 @@ module.exports = {
*/ */
maxUploadSize: 20 * 1024 * 1024, maxUploadSize: 20 * 1024 * 1024,
// XXX
premiumUploadSize: 100 * 1024 * 1024,
/* ===================== /* =====================
* DATABASE VOLUMES * DATABASE VOLUMES
* ===================== */ * ===================== */

@ -12,9 +12,41 @@ Upload.status = function (Env, safeKey, filesize, _cb) { // FIXME FILES
if (typeof(filesize) !== 'number' && if (typeof(filesize) !== 'number' &&
filesize >= 0) { return void cb('E_INVALID_SIZE'); } filesize >= 0) { return void cb('E_INVALID_SIZE'); }
if (filesize >= Env.maxUploadSize) { return cb('TOO_LARGE'); }
nThen(function (w) { nThen(function (w) {
// if the proposed upload size is within the regular limit
// jump ahead to the next block
if (filesize <= Env.maxUploadSize) { return; }
// if larger uploads aren't explicitly enabled then reject them
if (typeof(Env.premiumUploadSize) !== 'number') {
w.abort();
return void cb('TOO_LARGE');
}
// otherwise go and retrieve info about the user's quota
Pinning.getLimit(Env, safeKey, w(function (err, limit) {
if (err) {
w.abort();
return void cb("E_BAD_LIMIT");
}
var plan = limit[1];
// see if they have a special plan, reject them if not
if (plan === '') {
w.abort();
return void cb('TOO_LARGE');
}
// and that they're not over the greater limit
if (filesize >= Env.premiumUploadSize) {
w.abort();
return void cb("TOO_LARGE");
}
// fallthrough will proceed to the next block
}));
}).nThen(function (w) {
var abortAndCB = Util.both(w.abort, cb); var abortAndCB = Util.both(w.abort, cb);
Env.blobStore.status(safeKey, w(function (err, inProgress) { Env.blobStore.status(safeKey, w(function (err, inProgress) {
// if there's an error something is weird // if there's an error something is weird

@ -43,6 +43,7 @@ module.exports.create = function (config, cb) {
//historyKeeper: config.historyKeeper, //historyKeeper: config.historyKeeper,
intervals: config.intervals || {}, intervals: config.intervals || {},
maxUploadSize: config.maxUploadSize || (20 * 1024 * 1024), maxUploadSize: config.maxUploadSize || (20 * 1024 * 1024),
premiumUploadSize: false, // overridden below...
Sessions: {}, Sessions: {},
paths: {}, paths: {},
//msgStore: config.store, //msgStore: config.store,
@ -70,6 +71,13 @@ module.exports.create = function (config, cb) {
domain: config.domain domain: config.domain
}; };
(function () {
var pes = config.premiumUploadSize;
if (!isNaN(pes) && pes >= Env.maxUploadSize) {
Env.premiumUploadSize = pes;
}
}());
var paths = Env.paths; var paths = Env.paths;
var keyOrDefaultString = function (key, def) { var keyOrDefaultString = function (key, def) {

@ -7,6 +7,7 @@ var Fs = require('fs');
var Package = require('./package.json'); var Package = require('./package.json');
var Path = require("path"); var Path = require("path");
var nThen = require("nthen"); var nThen = require("nthen");
var Util = require("./lib/common-util");
var config = require("./lib/load-config"); var config = require("./lib/load-config");
@ -34,7 +35,9 @@ if (process.env.PACKAGE) {
FRESH_KEY = +new Date(); FRESH_KEY = +new Date();
} }
var configCache = {};
config.flushCache = function () { config.flushCache = function () {
configCache = {};
FRESH_KEY = +new Date(); FRESH_KEY = +new Date();
if (!(DEV_MODE || FRESH_MODE)) { FRESH_MODE = true; } if (!(DEV_MODE || FRESH_MODE)) { FRESH_MODE = true; }
if (!config.log) { return; } if (!config.log) { return; }
@ -143,38 +146,72 @@ try {
}); });
} catch (e) { console.error("Can't parse admin keys"); } } catch (e) { console.error("Can't parse admin keys"); }
// TODO, cache this /api/config responses instead of re-computing it each time var serveConfig = (function () {
app.get('/api/config', function(req, res){ // if dev mode: never cache
// TODO precompute any data that isn't dynamic to save some CPU time var cacheString = function () {
var host = req.headers.host.replace(/\:[0-9]+/, ''); return (FRESH_KEY? '-' + FRESH_KEY: '') + (DEV_MODE? '-' + (+new Date()): '');
res.setHeader('Content-Type', 'text/javascript'); };
res.send('define(function(){\n' + [
'var obj = ' + JSON.stringify({ var template = function (host) {
requireConf: { return [
waitSeconds: 600, 'define(function(){',
urlArgs: 'ver=' + Package.version + (FRESH_KEY? '-' + FRESH_KEY: '') + (DEV_MODE? '-' + (+new Date()): ''), 'var obj = ' + JSON.stringify({
}, requireConf: {
removeDonateButton: (config.removeDonateButton === true), waitSeconds: 600,
allowSubscriptions: (config.allowSubscriptions === true), urlArgs: 'ver=' + Package.version + cacheString(),
websocketPath: config.externalWebsocketURL, },
httpUnsafeOrigin: config.httpUnsafeOrigin.replace(/^\s*/, ''), removeDonateButton: (config.removeDonateButton === true),
adminEmail: config.adminEmail, allowSubscriptions: (config.allowSubscriptions === true),
adminKeys: admins, websocketPath: config.externalWebsocketURL,
inactiveTime: config.inactiveTime, httpUnsafeOrigin: config.httpUnsafeOrigin.replace(/^\s*/, ''),
supportMailbox: config.supportMailboxPublicKey adminEmail: config.adminEmail,
}, null, '\t'), adminKeys: admins,
'obj.httpSafeOrigin = ' + (function () { inactiveTime: config.inactiveTime,
if (config.httpSafeOrigin) { return '"' + config.httpSafeOrigin + '"'; } supportMailbox: config.supportMailboxPublicKey
if (config.httpSafePort) { }, null, '\t'),
return "(function () { return window.location.origin.replace(/\:[0-9]+$/, ':" + 'obj.httpSafeOrigin = ' + (function () {
config.httpSafePort + "'); }())"; if (config.httpSafeOrigin) { return '"' + config.httpSafeOrigin + '"'; }
} if (config.httpSafePort) {
return 'window.location.origin'; return "(function () { return window.location.origin.replace(/\:[0-9]+$/, ':" +
}()), config.httpSafePort + "'); }())";
'return obj', }
'});' return 'window.location.origin';
].join(';\n')); }()),
}); 'return obj',
'});'
].join(';\n')
};
var cleanUp = {};
return function (req, res) {
var host = req.headers.host.replace(/\:[0-9]+/, '');
res.setHeader('Content-Type', 'text/javascript');
// don't cache anything if you're in dev mode
if (DEV_MODE) {
return void res.send(template(host));
}
// generate a lookup key for the cache
var cacheKey = host + ':' + cacheString();
// if there's nothing cached for that key...
if (!configCache[cacheKey]) {
// generate the response and cache it in memory
configCache[cacheKey] = template(host);
// and create a function to conditionally evict cache entries
// which have not been accessed in the last 20 seconds
cleanUp[cacheKey] = Util.throttle(function () {
delete cleanUp[cacheKey];
delete configCache[cacheKey];
}, 20000);
}
// successive calls to this function
cleanUp[cacheKey]();
return void res.send(configCache[cacheKey]);
};
}());
app.get('/api/config', serveConfig);
var four04_path = Path.resolve(__dirname + '/customize.dist/404.html'); var four04_path = Path.resolve(__dirname + '/customize.dist/404.html');
var custom_four04_path = Path.resolve(__dirname + '/customize/404.html'); var custom_four04_path = Path.resolve(__dirname + '/customize/404.html');

@ -2762,7 +2762,7 @@ define([
}); });
if (keys.length < 2) { return keys; } if (keys.length < 2) { return keys; }
var mult = asc ? 1 : -1; var mult = asc ? 1 : -1;
var getProp = function (el, prop) { var getProp = function (el) {
if (folder && root[el] && manager.isSharedFolder(root[el])) { if (folder && root[el] && manager.isSharedFolder(root[el])) {
var title = manager.getSharedFolderData(root[el]).title || el; var title = manager.getSharedFolderData(root[el]).title || el;
return title.toLowerCase(); return title.toLowerCase();
@ -2777,13 +2777,19 @@ define([
return hrefData.type; return hrefData.type;
} }
if (prop === 'atime' || prop === 'ctime') { if (prop === 'atime' || prop === 'ctime') {
return new Date(data[prop]); return typeof(data[prop]) === "number" ? data[prop] : new Date(data[prop]);
} }
return (manager.getTitle(id) || "").toLowerCase(); return (manager.getTitle(id) || "").toLowerCase();
}; };
var props = {};
keys.forEach(function (k) {
props[k] = getProp(k);
});
keys.sort(function(a, b) { keys.sort(function(a, b) {
if (getProp(a, prop) < getProp(b, prop)) { return mult * -1; } var _a = props[a];
if (getProp(a, prop) > getProp(b, prop)) { return mult * 1; } var _b = props[b];
if (_a < _b) { return mult * -1; }
if (_b > _a) { return mult; }
return 0; return 0;
}); });
return keys; return keys;

@ -720,13 +720,17 @@ define([
var fixTemplate = function () { var fixTemplate = function () {
if (sharedFolder) { return; } if (sharedFolder) { return; }
if (!Array.isArray(files[TEMPLATE])) { debug("TEMPLATE was not an array"); files[TEMPLATE] = []; } if (!Array.isArray(files[TEMPLATE])) { debug("TEMPLATE was not an array"); files[TEMPLATE] = []; }
files[TEMPLATE] = Util.deduplicateString(files[TEMPLATE].slice()); var dedup = Util.deduplicateString(files[TEMPLATE]);
var us = files[TEMPLATE]; if (dedup.length !== files[TEMPLATE].length) {
var rootFiles = exp.getFiles([ROOT]).slice(); files[TEMPLATE] = dedup;
}
var us = files[TEMPLATE].slice();
var rootFiles = exp.getFiles([ROOT]);
var toClean = []; var toClean = [];
us.forEach(function (el, idx) { us.forEach(function (el, idx) {
if (!exp.isFile(el, true) || rootFiles.indexOf(el) !== -1) { if (!exp.isFile(el, true) || rootFiles.indexOf(el) !== -1) {
toClean.push(el); toClean.push(el);
return;
} }
if (typeof el === "string") { if (typeof el === "string") {
// We have an old file (href) which is not in filesData: add it // We have an old file (href) which is not in filesData: add it
@ -735,6 +739,7 @@ define([
href: exp.cryptor.encrypt(el) href: exp.cryptor.encrypt(el)
}; };
us[idx] = id; us[idx] = id;
return;
} }
if (typeof el === "number") { if (typeof el === "number") {
var data = files[FILES_DATA][el]; var data = files[FILES_DATA][el];
@ -866,7 +871,7 @@ define([
var sf = files[SHARED_FOLDERS]; var sf = files[SHARED_FOLDERS];
var rootFiles = exp.getFiles([ROOT]); var rootFiles = exp.getFiles([ROOT]);
var root = exp.find([ROOT]); var root = exp.find([ROOT]);
var parsed, secret, el; var parsed /*, secret */, el;
for (var id in sf) { for (var id in sf) {
el = sf[id]; el = sf[id];
id = Number(id); id = Number(id);
@ -878,8 +883,7 @@ define([
// Fix undefined hash // Fix undefined hash
parsed = Hash.parsePadUrl(href || el.roHref); parsed = Hash.parsePadUrl(href || el.roHref);
secret = Hash.getSecrets('drive', parsed.hash, el.password); if (!parsed || !parsed.hash || parsed.hash === "undefined") {
if (!secret.keys) {
delete sf[id]; delete sf[id];
continue; continue;
} }

@ -158,10 +158,15 @@ define([
}); });
onError = function (e) { onError = function (e) {
// XXX if we included the max upload sizes in /api/config
// then we could check if a file is too large without going to the server...
queue.inProgress = false; queue.inProgress = false;
queue.next(); queue.next();
if (e === 'TOO_LARGE') { if (e === 'TOO_LARGE') {
$pv.text(Messages.upload_tooLargeBrief); $pv.text(Messages.upload_tooLargeBrief);
// XXX translate
// instead of "This file exceeds the maximum upload size"
// use "the maximum upload size allowed for your account"
return void UI.alert(Messages.upload_tooLarge); return void UI.alert(Messages.upload_tooLarge);
} }
if (e === 'NOT_ENOUGH_SPACE') { if (e === 'NOT_ENOUGH_SPACE') {

Loading…
Cancel
Save