import { AuthenticationStrategy , UserProfileFactory , } from '@loopback/authentication' ; import { HttpErrors , RedirectRoute , Request } from '@loopback/rest' ; import { UserProfile } from '@loopback/security' ; import { Strategy , AuthenticateOptions } from 'passport' ; const passportRequestMixin = require ( 'passport/lib/http/request' ) ; /**
 * Adapter class to invoke passport-strategy
 *   1. provides express dependencies to the passport strategies
 *   2. provides shimming of requests for passport authentication
 *   3. provides life-cycle similar to express to the passport-strategy
 *   4. provides state methods to the strategy instance
 * see: https://github.com/jaredhanson/passport
 */ export class StrategyAdapter < U > implements AuthenticationStrategy { param strategy instance of a class which implements a
     *  http .
      constructor ( private readonly strategy , readonly name , private userProfileFactory = ( u ) => { return u as UserProfile ; } ) { } param request param options authenticate ( request , options ? ) { const userProfileFactory = this . userProfileFactory ; return new Promise < UserProfile | RedirectRoute > ( ( resolve , reject ) => { for ( const key in passportRequestMixin ) { ( request as any ) [ key ] = passportRequestMixin [ key ] ; } const strategy = Object . create ( this . strategy ) ; strategy . success = function ( user ) { const userProfile = userProfileFactory ( user as U ) ; resolve ( userProfile ) ; } ; strategy . fail = function ( challenge ) { reject ( new HttpErrors . Unauthorized ( challenge ) ) ; } ; strategy . error = function ( error ) { reject ( new HttpErrors . InternalServerError ( error ) ) ; } ; strategy . redirect = function ( url , status ) { const redirectOptions = new RedirectRoute ( '' , url , status ) ; resolve ( redirectOptions ) ; } ; strategy . authenticate ( request , options ) ; } ) ; } }