diff --git a/src/proxyauth.js b/src/proxyauth.js index d8dd643fb..94b2ec7a9 100644 --- a/src/proxyauth.js +++ b/src/proxyauth.js @@ -134,7 +134,7 @@ async function login(req, res, next) { const dashboardFqdn = (await dashboard.getLocation()).fqdn; - if (req.query.redirect) { + if (typeof req.query.redirect === 'string') { res.cookie('cloudronProxyAuthRedirect', req.query.redirect, { httpOnly: true, maxAge: constants.DEFAULT_TOKEN_EXPIRATION_MSECS, @@ -146,7 +146,7 @@ async function login(req, res, next) { } async function callback(req, res, next) { - if (!req.query.code) return next(new HttpError(400, 'missing query argument "code"')); + if (typeof req.query.code !== 'string') return next(new HttpError(400, 'missing query argument "code"')); debug(`callback: with code ${req.query.code}`); diff --git a/src/routes/accesscontrol.js b/src/routes/accesscontrol.js index df0198fd5..39d8323d1 100644 --- a/src/routes/accesscontrol.js +++ b/src/routes/accesscontrol.js @@ -43,9 +43,9 @@ async function tokenAuth(req, res, next) { let accessToken; // this determines the priority - if (req.body && req.body.access_token) accessToken = req.body.access_token; - if (req.query && req.query.access_token) accessToken = req.query.access_token; - if (req.headers && req.headers.authorization) { + if (req.body?.access_token) accessToken = req.body.access_token; + if (typeof req.query?.access_token === 'string') accessToken = req.query.access_token; + if (req.headers?.authorization) { const parts = req.headers.authorization.split(' '); if (parts.length == 2) { const [scheme, credentials] = parts; diff --git a/src/routes/apps.js b/src/routes/apps.js index 002c4a3e7..a82e56d5d 100644 --- a/src/routes/apps.js +++ b/src/routes/apps.js @@ -127,7 +127,9 @@ async function listByUser(req, res, next) { async function getAppIcon(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); - const [error, icon] = await safe(apps.getIcon(req.resources.app, { original: req.query.original })); + const original = typeof req.query.original === 'string' ? (req.query.original === '1' || req.query.original === 'true') : false; + + const [error, icon] = await safe(apps.getIcon(req.resources.app, { original })); if (error) return next(BoxError.toHttpError(error)); res.send(icon); @@ -721,7 +723,7 @@ async function update(req, res, next) { async function getLogStream(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a valid number')); if (req.headers.accept !== 'text/event-stream') return next(new HttpError(400, 'This API call requires EventStream')); @@ -756,13 +758,13 @@ async function getLogStream(req, res, next) { async function getLogs(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number')); const options = { lines, follow: false, - format: req.query.format || 'json' + format: typeof req.query.format === 'string' ? req.query.format : 'json' }; const [error, logStream] = await safe(apps.getLogs(req.resources.app, options)); @@ -826,13 +828,13 @@ async function startExec(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); assert.strictEqual(typeof req.params.execId, 'string'); - const columns = req.query.columns ? parseInt(req.query.columns, 10) : null; + const columns = typeof req.query.columns === 'string' ? parseInt(req.query.columns, 10) : null; if (isNaN(columns)) return next(new HttpError(400, 'columns must be a number')); - const rows = req.query.rows ? parseInt(req.query.rows, 10) : null; + const rows = typeof req.query.rows === 'string' ? parseInt(req.query.rows, 10) : null; if (isNaN(rows)) return next(new HttpError(400, 'rows must be a number')); - const tty = req.query.tty === 'true'; + const tty = typeof req.query.tty === 'string' ? (req.query.tty === '1' || req.query.tty === 'true') : false; if (safe.query(req.resources.app, 'manifest.addons.docker') && req.user.role !== users.ROLE_OWNER) return next(new HttpError(403, '"owner" role is requied to exec app with docker addon')); @@ -861,13 +863,13 @@ async function startExecWebSocket(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); assert.strictEqual(typeof req.params.execId, 'string'); - const columns = req.query.columns ? parseInt(req.query.columns, 10) : null; + const columns = typeof req.query.columns === 'string' ? parseInt(req.query.columns, 10) : null; if (isNaN(columns)) return next(new HttpError(400, 'columns must be a number')); - const rows = req.query.rows ? parseInt(req.query.rows, 10) : null; + const rows = typeof req.query.rows === 'string' ? parseInt(req.query.rows, 10) : null; if (isNaN(rows)) return next(new HttpError(400, 'rows must be a number')); - const tty = req.query.tty === 'true' ? true : false; + const tty = typeof req.query.tty === 'string' ? (req.query.tty === '1' || req.query.tty === 'true') : false; // in a badly configured reverse proxy, we might be here without an upgrade if (req.headers['upgrade'] !== 'websocket') return next(new HttpError(404, 'exec requires websocket')); @@ -912,10 +914,10 @@ async function getExec(req, res, next) { async function listBackups(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); const [error, result] = await safe(apps.listBackups(req.resources.app, page, perPage)); @@ -1032,10 +1034,10 @@ async function setUpstreamUri(req, res, next) { async function listEventlog(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); const [error, eventlogs] = await safe(apps.listEventlog(req.resources.app, page, perPage)); @@ -1070,12 +1072,13 @@ async function getTask(req, res, next) { async function getMetrics(req, res, next) { assert.strictEqual(typeof req.resources.app, 'object'); - if (!req.query.fromSecs || !parseInt(req.query.fromSecs)) return next(new HttpError(400, 'fromSecs must be a number')); - if (!req.query.intervalSecs || !parseInt(req.query.intervalSecs)) return next(new HttpError(400, 'intervalSecs must be a number')); + if (typeof req.query.fromSecs !== 'string' || !parseInt(req.query.fromSecs)) return next(new HttpError(400, 'fromSecs must be a number')); + if (typeof req.query.intervalSecs !== 'string' || !parseInt(req.query.intervalSecs)) return next(new HttpError(400, 'intervalSecs must be a number')); const fromSecs = parseInt(req.query.fromSecs); const intervalSecs = parseInt(req.query.intervalSecs); - const noNullPoints = !!req.query.noNullPoints; + const noNullPoints = typeof req.query.noNullPoints === 'string' ? (req.query.noNullPoints === '1' || req.query.noNullPoints === 'true') : false; + const [error, result] = await safe(metrics.get({ fromSecs, noNullPoints, intervalSecs, appIds: [req.resources.app.id] })); if (error) return next(new HttpError(500, error)); diff --git a/src/routes/archives.js b/src/routes/archives.js index 800dabc52..1ece74981 100644 --- a/src/routes/archives.js +++ b/src/routes/archives.js @@ -32,10 +32,10 @@ async function load(req, res, next) { } async function list(req, res, next) { - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); const [error, result] = await safe(archives.list(page, perPage)); @@ -54,7 +54,9 @@ async function getIcon(req, res, next) { assert.strictEqual(typeof req.params.id, 'string'); assert.strictEqual(typeof req.resources.archive, 'object'); - const [error, icon] = await safe(archives.getIcon(req.params.id, { original: req.query.original })); + const original = typeof req.query.original === 'string' ? (req.query.original === '1' || req.query.original === 'true') : false; + + const [error, icon] = await safe(archives.getIcon(req.params.id, { original })); if (error) return next(BoxError.toHttpError(error)); res.send(icon); diff --git a/src/routes/backups.js b/src/routes/backups.js index 358a6e14a..85301068f 100644 --- a/src/routes/backups.js +++ b/src/routes/backups.js @@ -25,10 +25,10 @@ const assert = require('assert'), safe = require('safetydance'); async function list(req, res, next) { - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); const [error, result] = await safe(backups.getByIdentifierAndStatePaged(backups.BACKUP_IDENTIFIER_BOX, backups.BACKUP_STATE_NORMAL, page, perPage)); diff --git a/src/routes/domains.js b/src/routes/domains.js index 56c7922e8..4bb5e4b21 100644 --- a/src/routes/domains.js +++ b/src/routes/domains.js @@ -145,7 +145,7 @@ async function del(req, res, next) { async function checkDnsRecords(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - if (!('subdomain' in req.query)) return next(new HttpError(400, 'subdomain is required')); + if (typeof req.query.subdomain !=='string') return next(new HttpError(400, 'subdomain is required')); let [error, result] = await safe(domains.get(req.params.domain)); if (error) return next(BoxError.toHttpError(error)); diff --git a/src/routes/eventlog.js b/src/routes/eventlog.js index f313d7757..daeabb642 100644 --- a/src/routes/eventlog.js +++ b/src/routes/eventlog.js @@ -20,17 +20,17 @@ async function get(req, res, next) { } async function list(req, res, next) { - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); if (req.query.actions && typeof req.query.actions !== 'string') return next(new HttpError(400, 'actions must be a comma separated string')); if (req.query.action && typeof req.query.action !== 'string') return next(new HttpError(400, 'action must be a string')); if (req.query.search && typeof req.query.search !== 'string') return next(new HttpError(400, 'search must be a string')); - const actions = req.query.actions ? req.query.actions.split(',').map(function (s) { return s.trim(); }) : []; + const actions = typeof req.query.actions === 'string' ? req.query.actions.split(',').map(function (s) { return s.trim(); }) : []; if (req.query.action) actions.push(req.query.action); const [error, eventlogs] = await safe(eventlog.listPaged(actions, req.query.search || null, page, perPage)); diff --git a/src/routes/mail.js b/src/routes/mail.js index 341d7067c..cda0d16c7 100644 --- a/src/routes/mail.js +++ b/src/routes/mail.js @@ -138,10 +138,10 @@ async function sendTestMail(req, res, next) { async function listMailboxes(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a positive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a positive number')); if (req.query.search && typeof req.query.search !== 'string') return next(new HttpError(400, 'search must be a string')); @@ -269,10 +269,10 @@ async function setBanner(req, res, next) { async function getLists(req, res, next) { assert.strictEqual(typeof req.params.domain, 'string'); - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a positive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a positive number')); if (req.query.search && typeof req.query.search !== 'string') return next(new HttpError(400, 'search must be a string')); diff --git a/src/routes/notifications.js b/src/routes/notifications.js index 4643b0566..5f0e6831e 100644 --- a/src/routes/notifications.js +++ b/src/routes/notifications.js @@ -33,10 +33,10 @@ function get(req, res, next) { } async function list(req, res, next) { - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); if (req.query.acknowledged && !(req.query.acknowledged === 'true' || req.query.acknowledged === 'false')) return next(new HttpError(400, 'acknowledged must be a true or false')); diff --git a/src/routes/services.js b/src/routes/services.js index 3a7d634ad..2da556139 100644 --- a/src/routes/services.js +++ b/src/routes/services.js @@ -60,13 +60,13 @@ async function configure(req, res, next) { async function getLogs(req, res, next) { assert.strictEqual(typeof req.params.service, 'string'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number')); const options = { lines: lines, follow: false, - format: req.query.format || 'json' + format: typeof req.query.format === 'string' ? req.query.format : 'json' }; const [error, logStream] = await safe(services.getServiceLogs(req.params.service, options)); @@ -86,7 +86,7 @@ async function getLogs(req, res, next) { async function getLogStream(req, res, next) { assert.strictEqual(typeof req.params.service, 'string'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a valid number')); if (req.headers.accept !== 'text/event-stream') return next(new HttpError(400, 'This API call requires EventStream')); @@ -139,12 +139,12 @@ async function rebuild(req, res, next) { async function getMetrics(req, res, next) { assert.strictEqual(typeof req.params.service, 'string'); - if (!req.query.fromSecs || !parseInt(req.query.fromSecs)) return next(new HttpError(400, 'fromSecs must be a number')); - if (!req.query.intervalSecs || !parseInt(req.query.intervalSecs)) return next(new HttpError(400, 'intervalSecs must be a number')); + if (typeof req.query.fromSecs !== 'string' || !parseInt(req.query.fromSecs)) return next(new HttpError(400, 'fromSecs must be a number')); + if (typeof req.query.intervalSecs !== 'string' || !parseInt(req.query.intervalSecs)) return next(new HttpError(400, 'intervalSecs must be a number')); const fromSecs = parseInt(req.query.fromSecs); const intervalSecs = parseInt(req.query.intervalSecs); - const noNullPoints = !!req.query.noNullPoints; + const noNullPoints = typeof req.query.noNullPoints === 'string' ? (req.query.noNullPoints === '1' || req.query.noNullPoints === 'true') : false; const [error, result] = await safe(metrics.get({ fromSecs, intervalSecs, noNullPoints, serviceIds: [req.params.service] })); if (error) return next(new HttpError(500, error)); diff --git a/src/routes/system.js b/src/routes/system.js index 02f763fd2..590488e77 100644 --- a/src/routes/system.js +++ b/src/routes/system.js @@ -60,13 +60,13 @@ async function getMemory(req, res, next) { async function getLogs(req, res, next) { assert.strictEqual(typeof req.params.unit, 'string'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number')); const options = { lines: lines, follow: false, - format: req.query.format || 'json' + format: typeof req.query.format === 'string' ? req.query.format : 'json' }; const [error, logStream] = await safe(system.getLogs(req.params.unit, options)); @@ -85,7 +85,7 @@ async function getLogs(req, res, next) { async function getLogStream(req, res, next) { assert.strictEqual(typeof req.params.unit, 'string'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a valid number')); function sse(id, data) { return 'id: ' + id + '\ndata: ' + data + '\n\n'; } @@ -95,7 +95,7 @@ async function getLogStream(req, res, next) { const options = { lines: lines, follow: true, - format: req.query.format || 'json' + format: typeof req.query.format === 'string' ? req.query.format : 'json' }; const [error, logStream] = await safe(system.getLogs(req.params.unit, options)); @@ -119,12 +119,12 @@ async function getLogStream(req, res, next) { } async function getMetrics(req, res, next) { - if (!req.query.fromSecs || !parseInt(req.query.fromSecs, 10)) return next(new HttpError(400, 'fromSecs must be a number')); - if (!req.query.intervalSecs || !parseInt(req.query.intervalSecs, 10)) return next(new HttpError(400, 'intervalSecs must be a number')); + if (typeof req.query.fromSecs !== 'string' || !parseInt(req.query.fromSecs, 10)) return next(new HttpError(400, 'fromSecs must be a number')); + if (typeof req.query.intervalSecs !== 'string' || !parseInt(req.query.intervalSecs, 10)) return next(new HttpError(400, 'intervalSecs must be a number')); const fromSecs = parseInt(req.query.fromSecs, 10); const intervalSecs = parseInt(req.query.intervalSecs, 10); - const noNullPoints = !!req.query.noNullPoints; + const noNullPoints = typeof req.query.noNullPoints === 'string' ? (req.query.noNullPoints === '1' || req.query.noNullPoints === 'true') : false; const system = req.query.system === 'true'; const appIds = 'appId' in req.query ? (Array.isArray(req.query.appId) ? req.query.appId : [ req.query.appId ]) : []; const serviceIds = 'serviceId' in req.query ? (Array.isArray(req.query.serviceId) ? req.query.serviceId : [ req.query.serviceId ]) : []; diff --git a/src/routes/tasks.js b/src/routes/tasks.js index 131a889a7..8f46bb4ac 100644 --- a/src/routes/tasks.js +++ b/src/routes/tasks.js @@ -37,10 +37,10 @@ async function get(req, res, next) { } async function list(req, res, next) { - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined'? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string'? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); if (req.query.type && typeof req.query.type !== 'string') return next(new HttpError(400, 'type must be a string')); @@ -63,13 +63,13 @@ async function stopTask(req, res, next) { async function getLogs(req, res, next) { assert.strictEqual(typeof req.resources.task, 'object'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a number')); const options = { lines: lines, follow: false, - format: req.query.format || 'json' + format: typeof req.query.format === 'string' ? req.query.format : 'json' }; const [error, logStream] = await safe(tasks.getLogs(req.resources.task, options)); @@ -89,7 +89,7 @@ async function getLogs(req, res, next) { async function getLogStream(req, res, next) { assert.strictEqual(typeof req.resources.task, 'object'); - const lines = 'lines' in req.query ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id + const lines = typeof req.query.lines === 'string' ? parseInt(req.query.lines, 10) : 10; // we ignore last-event-id if (isNaN(lines)) return next(new HttpError(400, 'lines must be a valid number')); function sse(id, data) { return 'id: ' + id + '\ndata: ' + data + '\n\n'; } diff --git a/src/routes/users.js b/src/routes/users.js index 763089e0f..111bd5656 100644 --- a/src/routes/users.js +++ b/src/routes/users.js @@ -155,15 +155,15 @@ async function updateProfile(req, res, next) { } async function list(req, res, next) { - const page = typeof req.query.page !== 'undefined' ? parseInt(req.query.page) : 1; + const page = typeof req.query.page === 'string' ? parseInt(req.query.page) : 1; if (!page || page < 0) return next(new HttpError(400, 'page query param has to be a postive number')); - const perPage = typeof req.query.per_page !== 'undefined' ? parseInt(req.query.per_page) : 25; + const perPage = typeof req.query.per_page === 'string' ? parseInt(req.query.per_page) : 25; if (!perPage || perPage < 0) return next(new HttpError(400, 'per_page query param has to be a postive number')); if (req.query.search && typeof req.query.search !== 'string') return next(new HttpError(400, 'search must be a string')); - const active = typeof req.query.active !== 'undefined' ? ((req.query.active === '1' || req.query.active === 'true') ? true : false) : null; + const active = typeof req.query.active === 'string' ? ((req.query.active === '1' || req.query.active === 'true') ? true : false) : null; const [error, results] = await safe(users.listPaged(req.query.search || null, active, page, perPage)); if (error) return next(BoxError.toHttpError(error)); diff --git a/src/server.js b/src/server.js index baa985d8d..58c3dca54 100644 --- a/src/server.js +++ b/src/server.js @@ -31,8 +31,8 @@ function notFoundHandler(req, res, next) { async function initializeExpressSync() { const app = express(); - // disable slowloris prevention: https://github.com/nodejs/node/issues/47421 - const httpServer = http.createServer({ headersTimeout: 0, requestTimeout: 0 }, app); // see also nginx client_header_timeout (30s) + // disable slowloris prevention: https://github.com/nodejs/node/issues/47421 . duplicate headers are discarded for the standard headers (https://nodejs.org/api/http.html#messageheaders) + const httpServer = http.createServer({ headersTimeout: 0, requestTimeout: 0, joinDuplicateHeaders: false }, app); // see also nginx client_header_timeout (30s) const wsServer = new ws.Server({ noServer: true }); // in noServer mode, we have to handle 'upgrade' and call handleUpgrade @@ -45,6 +45,7 @@ async function initializeExpressSync() { app.set('json spaces', 2); // pretty json app.enable('trust proxy'); // trust the X-Forwarded-* headers + app.set('query parser', 'simple'); // uses the built-in querystring module for query parsing. req.query always has strings or array of strings const router = new express.Router(); router.del = router.delete; // amend router.del for readability further on