const { Middleware } = require('libflitter') const moment = require('moment') const uuid = require('uuid').v4 class TrustManager { assume_trust = false constructor(request, response) { this.request = request this.response = response this.init_store() } init_store() { if ( !Array.isArray(this.request.session.trust_tokens) ) { this.request.session.trust_tokens = [] } const now = moment() this.request.session.trust_tokens = this.request.session.trust_tokens.filter(x => { return moment(new Date(x.expires)) > now }) this.assume_trust = !!this.request.session.trust_assume_trust } assume() { this.request.session.trust_assume_trust = true this.assume_trust = true } unassume() { this.request.session.trust_assume_trust = false this.assume_trust = false this.purge() } init_flow(scope, next) { this.request.session.trust_flow = { scope, next, in_progress: false, requested: `${new Date}` } } has_flow() { const flow = this.request.session?.trust_flow return flow && flow.scope && flow.next && moment(new Date(flow.requested)) < moment(new Date(flow.requested)).add('20', 'minutes') } flow_scope() { if ( this.has_flow() ) { return this.request.session.trust_flow.scope } } flow() { if ( this.has_flow() ) { return this.request.session.trust_flow.next } } start() { delete this.request.session.user_id const grant_token = uuid() this.request.session.trust_flow.grant_token = grant_token this.request.session.trust_flow.in_progress = true this.request.session.trust_flow.started = `${new Date}` return grant_token } check_grant(grant_token) { return grant_token === this.request.session?.trust_flow?.grant_token } end() { const next = this.request.session?.trust_flow?.next delete this.request.session.trust_flow return next } in_progress() { const flow = this.request.session.trust_flow return flow && flow.in_progress && flow.started && moment(new Date(flow.started)) < moment(new Date(flow.started)).add('10', 'minutes') } has(scope) { return this.assume_trust || this.request.session.trust_tokens.some(x => x.scope === scope) } grant(scope) { this.request.session.trust_tokens.push({ scope, expires: moment().add('1', 'hour').toDate().toString(), }) } deplete(scope) { this.request.session.trust_tokens = this.request.session.trust_tokens.filter(x => x.scope !== scope) } purge() { this.end() this.request.session.trust_tokens = [] } } class TrustTokenUtilityMiddleware extends Middleware { async test(req, res, next, args = {}) { if ( req.session ) { req.trust = new TrustManager(req, res) } return next() } } module.exports = exports = TrustTokenUtilityMiddleware