import connectSession from 'connect-redis' import redis from 'redis' import session from 'express-session' import favicon from 'serve-favicon' import bodyParser from 'body-parser' import express from 'express' import crypto from 'crypto' import path from 'path' import routes from './routes' import flash from '../scripts/flash' import config from '../scripts/load-config' import { init as initEmail } from './api/emailer' const app = express() const SessionStore = connectSession(session) app.enable('trust proxy', 1) app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.use(flash()) app.disable('x-powered-by') app.use(session({ key: config.server.session_key, secret: config.server.session_secret, store: new SessionStore({ client: redis.createClient(config.redis) }), resave: false, saveUninitialized: true, cookie: { secure: process.env.NODE_ENV !== 'development', maxAge: 2678400000 // 1 month } })) app.use((req, res, next) => { // Inject a cleaner version of the user's IP Address into the request let ipAddr = req.headers['x-forwarded-for'] || req.connection.remoteAddress if (ipAddr.indexOf('::ffff:') !== -1) { ipAddr = ipAddr.replace('::ffff:', '') } req.realIP = ipAddr // Make sure CSRF token is present in the session if (!req.session.csrf) { req.session.csrf = crypto.randomBytes(12).toString('hex') } // Add user and csrf token into rendering information res.locals = Object.assign(res.locals, { user: req.session.user || null, csrf: req.session.csrf }) // Add Piwik tracker if configured if (config.matomo && config.matomo.site_id) { res.locals.matomo = config.matomo } next() }) app.use(favicon(path.join(__dirname, '..', 'static', 'image', 'icynet.ico'))) module.exports = (args) => { app.set('view options', { layout: false }) app.set('view engine', 'pug') app.set('views', path.join(__dirname, '../views')) if (args.dev) { console.warn('Worker is in development mode') // Dev logger const morgan = require('morgan') app.use(morgan('dev')) } const staticAge = args.dev ? 1000 : 7 * 24 * 60 * 60 * 1000 // 1 week of cache in production // Static content directories, cache these requests. // It is also a good idea to use nginx to serve these directories in order to save on computing power app.use('/style', express.static(path.join(__dirname, '../build/style'), { maxAge: staticAge })) app.use('/script', express.static(path.join(__dirname, '../build/script'), { maxAge: staticAge })) app.use('/static', express.static(path.join(__dirname, '../static'), { maxAge: staticAge })) app.use('/usercontent', express.static(path.join(__dirname, '../usercontent'), { maxAge: staticAge })) app.use(routes) app.listen(args.port, args.host, () => { console.log('Listening on %s:%s', args.host, args.port) // Initialize the email transporter (if configured) initEmail() }) }