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() const allowed = route.startsWith('/assets') || config.allowed_routes.includes(route.toLowerCase().trim()) if ( allowed ) return true for ( const allowed_route of config.allowed_routes ) { console.log('comparing', allowed_route, 'to', route) const allowed_parts = allowed_route.split('/') const parts = route.split('/') let matches = true for ( let i = 0; i < allowed_parts.length; i += 1 ) { if ( allowed_parts[i] !== parts[i] && allowed_parts[i] !== '*' ) { matches = false } } if ( matches ) { console.log('allows true') return true } } console.log('allows false') return false } } class TrapsMiddleware extends Middleware { static get services() { return [...super.services, 'models', 'configs'] } async test(req, res, next, args = {}) { const Setting = this.models.get('Setting') req.trap = new TrapUtility(req, res, this.configs.get('traps.types')) if ( !req.trap.has_trap() && req.user && !req.user.email_verified && (await Setting.get('auth.require_email_verify')) ) { req.session.email_verify_flow = req.originalUrl await req.trap.begin('verify_email', { session_only: false }) } 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