const { Middleware } = require('libflitter') const { Injectable } = require('flitter-di') const SAMLParticipantWrapper = require('samlp/lib/sessionParticipants/index') class SessionParticipantStore extends Injectable { static get services() { return ['models'] } constructor(request, participants = []) { super() this.request = request this.participants = participants this.SessionParticipant = this.models.get('saml:SessionParticipant') } async issue({ service_provider }) { const sp = new this.SessionParticipant({ service_provider_id: service_provider.id, name_id: this.request.user.uid.toLowerCase(), // session_index: this.get_index(), slo_url: service_provider.slo_url, // TODO sp_cert, }) await sp.save() this.participants.push(sp) this.flush_participants() return sp.session_index } flush_participants() { this.request.session.saml_participant_uuids = this.participants.map(x => x.uuid) } get_index() { const i = this.request.session.saml_next_index || 0 this.request.session.saml_next_index = i + 1 return i } async clear() { for ( const p of this.participants ) { p.active = false await p.save() } this.participants = [] this.flush_participants() } async wrapper() { const participants = [] for ( const p of this.participants ) { const sp = await this.models.get('saml:ServiceProvider').findById(p.service_provider_id) participants.push({ serviceProviderId: sp.entity_id, nameId: p.name_id, nameIdFormat: p.name_id_format, sessionIndex: p.session_index, serviceProviderLogoutURL: p.slo_url, // TODO cert }) } return new SAMLParticipantWrapper(participants) } } class SAMLUtilityMiddleware extends Middleware { static get services() { return [...super.services, 'models', 'app'] } async test(req, res, next, { flush = false }) { const SessionParticipant = this.models.get('saml:SessionParticipant') const di = this.app.di() if ( !req.saml ) req.saml = {} if ( !Array.isArray(req.session.saml_participant_uuids) || flush ) { req.saml.participants = di.make(SessionParticipantStore, req) } else { const sps = await SessionParticipant.find({ uuid: { $in: req.session.saml_participant_uuids } }) req.saml.participants = di.make(SessionParticipantStore, req, sps) } next() } } module.exports = exports = SAMLUtilityMiddleware