import config from "config"; import flash from "connect-flash"; import {Router} from "express"; import session from "express-session"; import ApplicationComponent from "../ApplicationComponent.js"; import SecurityError from "../SecurityError.js"; import RedisComponent from "./RedisComponent.js"; export default class SessionComponent extends ApplicationComponent { private readonly storeComponent: RedisComponent; public constructor(storeComponent: RedisComponent) { super(); this.storeComponent = storeComponent; } public async checkSecuritySettings(): Promise { this.checkSecurityConfigField('session.secret'); if (!config.get('session.cookie.secure')) { throw new SecurityError('Cannot set cookie secure field to false.'); } } public async initRoutes(router: Router): Promise { router.use(session({ saveUninitialized: true, secret: config.get('session.secret'), store: this.storeComponent.getStore(), resave: false, cookie: { httpOnly: false, secure: config.get('session.cookie.secure'), sameSite: 'strict', }, rolling: true, })); router.use(flash()); router.use((req, res, next) => { // Request session getters req.getSessionOptional = () => { return req.session; }; req.getSession = () => { const session = req.getSessionOptional(); if (!session) throw new Error('Session not initialized.'); return session; }; // Session persistence const session = req.getSession(); if (session.persistent) { session.cookie.maxAge = config.get('session.cookie.maxAge'); } else { session.cookie.maxAge = session.cookie.expires = undefined; } // Views session local res.locals.session = session; // Views flash function res.setLazyLocal('flash', () => { return { info: req.flash('info'), success: req.flash('success'), warning: req.flash('warning'), error: req.flash('error'), 'error-alert': req.flash('error-alert'), }; }); next(); }); } }