Files
talk/app.js
T
2019-12-12 22:50:00 +00:00

133 lines
3.5 KiB
JavaScript

const express = require('express');
const nunjucks = require('nunjucks');
const cons = require('consolidate');
const trace = require('./middleware/trace');
const logging = require('./middleware/logging');
const path = require('path');
const merge = require('lodash/merge');
const helmet = require('helmet');
const plugins = require('./services/plugins');
const { HELMET_CONFIGURATION } = require('./config');
const { MOUNT_PATH } = require('./url');
const routes = require('./routes');
const debug = require('debug')('talk:app');
const {
ENABLE_TRACING,
APOLLO_ENGINE_KEY,
PORT,
TRUST_PROXY,
} = require('./config');
const app = express();
// Add the trace middleware first, it will create a request ID for each request
// downstream.
app.use(trace);
//==============================================================================
// PLUGIN PRE APPLICATION MIDDLEWARE
//==============================================================================
// Inject server route plugins.
plugins.get('server', 'app').forEach(({ plugin, app: callback }) => {
debug(`added plugin '${plugin.name}'`);
// Pass the app to the plugin to mount it's routes.
callback(app);
});
//==============================================================================
// APPLICATION WIDE MIDDLEWARE
//==============================================================================
// Add the logging middleware only if we aren't testing.
if (process.env.NODE_ENV !== 'test') {
app.use(logging.log);
}
if (ENABLE_TRACING && APOLLO_ENGINE_KEY) {
const { Engine } = require('apollo-engine');
const engine = new Engine({
engineConfig: {
apiKey: APOLLO_ENGINE_KEY,
},
graphqlPort: PORT,
endpoint: `${MOUNT_PATH}api/v1/graph/ql`,
});
engine.start();
app.use(engine.expressMiddleware());
}
// Trust the first proxy in front of us, this will enable us to trust the fact
// that SSL was terminated correctly.
app.set(
'trust proxy',
(function() {
if (!TRUST_PROXY) {
return null;
}
const lowercase = TRUST_PROXY.toLowerCase();
if (lowercase === 'true' || lowercase === 'false') {
return lowercase === 'true';
}
const parsed = Number(TRUST_PROXY);
if (!isNaN(parsed)) {
return parsed;
}
return TRUST_PROXY;
})()
);
// Enable a suite of security good practices through helmet. We disable
// frameguard to allow crossdomain injection of the embed.
app.use(
helmet(
merge(HELMET_CONFIGURATION, {
frameguard: false,
})
)
);
//==============================================================================
// VIEW CONFIGURATION
//==============================================================================
// configure the default views directory.
const views = path.join(__dirname, 'views');
app.set('views', views);
// reconfigure nunjucks.
cons.requires.nunjucks = nunjucks.configure(views, {
autoescape: true,
trimBlocks: true,
lstripBlocks: true,
watch: process.env.NODE_ENV === 'development',
});
// assign the nunjucks engine to .njk files.
app.engine('njk', cons.nunjucks);
// assign the ejs engine to .ejs and .html files.
app.engine('ejs', cons.ejs);
app.engine('html', cons.ejs);
// set .ejs as the default extension.
app.set('view engine', 'ejs');
//==============================================================================
// ROUTES
//==============================================================================
debug(`mounting routes on the ${MOUNT_PATH} path`);
// Actually apply the routes.
app.use(MOUNT_PATH, routes);
module.exports = app;