77 lines
2.5 KiB
TypeScript
77 lines
2.5 KiB
TypeScript
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<void> {
|
|
this.checkSecurityConfigField('session.secret');
|
|
if (!config.get<boolean>('session.cookie.secure')) {
|
|
throw new SecurityError('Cannot set cookie secure field to false.');
|
|
}
|
|
}
|
|
|
|
public async initRoutes(router: Router): Promise<void> {
|
|
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();
|
|
});
|
|
}
|
|
}
|