const config = require('./config/config');
const express = require('express');
const helmet = require('helmet');
const compression = require('compression');
const path = require('path');
require('./config/mongo'); // don't much like this bare require

const app = express();

app.use(helmet());
app.use(compression());

// Add public API routes
const publicRoutes = require('./routes/public');
app.use('/api', publicRoutes);

// Serve the built admin UI from /admin
app.use('/admin', express.static(path.join(__dirname, 'www-admin')));
app.get('/admin/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'www-admin', 'index.html'));
});

// Serve the built UI from the root
app.use(express.static(path.join(__dirname, 'www')));
app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'www', 'index.html'));
});

// auto-init if this app is not being initialised by another module
if (!module.parent) {
  app.listen(config.app.port, () => {
    /* eslint-disable-next-line no-console */
    console.log(`Listening on port ${config.app.port}`);
  });
}

module.exports = app;

const config = require('./config/config');
const express = require('express');
const helmet = require('helmet');
const compression = require('compression');
const path = require('path');
require('./config/mongo'); // don't much like this bare require

const app = express();

// we can make some nicer assumptions about security if query values are only
// ever strings, not arrays or objects
app.set('query parser', 'simple');

app.use(helmet());
app.use(compression());

// Add public API routes
const publicRoutes = require('./routes/public');
app.use('/api', publicRoutes);

// Serve the built admin UI from /admin
app.use('/admin', express.static(path.join(__dirname, 'www-admin')));
app.get('/admin/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'www-admin', 'index.html'));
});

// Serve the built UI from the root
app.use(express.static(path.join(__dirname, 'www')));
app.get('/*', function(req, res) {
  res.sendFile(path.join(__dirname, 'www', 'index.html'));
});

// auto-init if this app is not being initialised by another module
if (!module.parent) {
  app.listen(config.app.port, () => {
    /* eslint-disable-next-line no-console */
    console.log(`Listening on port ${config.app.port}`);
  });
}

module.exports = app;

Use dumb query parsing to avoid a DoS attack where a { $regex } matcher with evil regex could be inserted into a query
Use dumb query parsing to avoid a DoS attack where a { $regex } matcher
with evil regex could be inserted into a query

http://localhost:8080/api/statistics/counters?area[$regex]=((\w%2B.%2B)%2B)%2BG

The URL would:

* Have its query value parsed as an object
* This was assumed to always be a string and so would be inserted into the search query
* A more complex query could be specified through this, such as a regex comparison
* The regex in the example above is very expensive and would cause MongoDB to lock at 100% CPU utilisation

Never parsing query values as objects avoids this.
