bridge-node-server/node_server/portal-router.js
Martin Donnelly 57bd6c8e6a init
2018-06-24 21:15:03 +01:00

125 lines
3.6 KiB
JavaScript

/*
* This file defines the routes for the web portal running on the api server
* It uses express router so it can be placed under any path, and will then
* assume everything else is under the root of that path.
* e.g. to place under /portal/ you would do:
*
* var appHttps = [main app setup]
* var portalRouterFactory = require(<this file>);
* var portalRouter = portalRouterFactory(<filesystem path to portal files>);
* appHttps.use('/portal/', portalRouter);
*/
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const compression = require('compression');
const RateLimit = require('express-rate-limit');
const helmet = require('helmet');
const config = require(global.configFile);
/**
* Content security policy options
*/
const cspOptions = {
directives: {
defaultSrc: ['\'self\''],
/**
* Image Sources:
* - self: image served from the exact domain and scheme
* - *.base.maps.api.here.com: map tile server for normal tiles
* - *.aerial.maps.api.here.com: map tile server for satellite tiles
* - data: images from data uris (used for profile pics etc.)
*/
imgSrc: [
'\'self\'',
'https://*.base.maps.api.here.com',
'https://*.aerial.maps.api.here.com',
'data:'
],
/**
* Frame Source:
* - www.comcarde.com for the framed updated terms and conditions
*/
frameSrc: ['https://www.comcarde.com'],
/**
* Connect Source
* - 'self': API requests, etc.
* - *.base.maps.api.here.com: copyright attribution info for normal tiles
* - *.aerial.maps.api.here.com: copyright attribution info for satellite tiles
*/
connectSrc: [
'\'self\'',
'https://*.base.maps.api.here.com',
'https://*.aerial.maps.api.here.com'
],
reportUri: '/api/v0/csp-report'
},
reportOnly: false
};
module.exports = (function() {
return function portalRouterFactory(filePath) {
const router = express.Router();
/* Body Parsers, including for application/csp-report */
router.use(bodyParser.json({type: 'application/json'}));
router.use(bodyParser.json({type: 'application/csp-report'}));
/*
* Rate Limiting
*/
const limiter = new RateLimit(config.rateLimits.portalStatic);
router.use(limiter);
/*
* Content Security Policy (CSP) headers
*/
router.use(helmet.contentSecurityPolicy(cspOptions));
/*
* Enable compression
*/
router.use(compression());
/*
* Serve basic available files
*/
router.use(express.static(filePath));
/*
* JSON translation files
*/
router.use(
express.static(path.resolve(filePath, './app/*/i18n/*.json'))
);
/*
* If the request looks like a request for a template, and the template
* doesn't exists, return a 404.
*/
router.use('/app/*', (req, res) => {
res.status(404).end();
});
/*
* Any other requests are guessed to be from the manipulated URLs for the
* pages in the web app. So we serve index.html in response to them, which
* will kickstart everything
*/
router.use(
'/*',
express.static(path.resolve(filePath, './index.html'))
);
/*
* Return the configured router
*/
return router;
};
})();