const { Middleware } = require('libflitter') class TrapUtility { constructor(req, res, configs) { this.request = req this.session = req.session this.response = res this.user = req.user this.configs = configs } async begin(trap_name, { session_only = false }) { if ( session_only || !this.user ) { this.session.trap = trap_name } else { this.user.trap = trap_name await this.user.save() } if ( this.config().assume_trust ) this.request.trust.assume() } redirect() { if ( this.config().assume_trust ) this.request.trust.assume() return this.response.redirect(this.config().redirect_to) } async end() { if ( this.config().assume_trust ) this.request.trust.unassume() if ( this.user ) { this.user.trap = '' await this.user.save() } this.session.trap = '' } has_trap(name = '') { if ( name ) return (this.user && this.user.trap === name) || this.session.trap === name return (this.user && this.user.trap) || this.session.trap } get_trap() { if ( this.session.trap ) return this.session.trap else if ( this.user ) return this.user.trap } trap_exists(name) { return !!this.configs[name] } config() { return this.configs[this.get_trap()] } allows(route) { const config = this.config() return route.startsWith('/assets') || config.allowed_routes.includes(route.toLowerCase().trim()) } } class TrapsMiddleware extends Middleware { static get services() { return [...super.services, 'models', 'configs'] } async test(req, res, next, args = {}) { req.trap = new TrapUtility(req, res, this.configs.get('traps.types')) if ( !req.trap.has_trap() ) return next() else if ( req.trap.allows(req.path) ) return next() else return req.trap.redirect() } } module.exports = exports = TrapsMiddleware