import {Request} from '../../http/lifecycle/Request' import {ResponseObject, Route} from '../../http/routing/Route' import {GuestRequiredMiddleware} from '../middleware/GuestRequiredMiddleware' import {AuthRequiredMiddleware} from '../middleware/AuthRequiredMiddleware' import {Inject, Injectable} from '../../di' import {SecurityContext} from '../context/SecurityContext' import {redirect} from '../../http/response/RedirectResponseFactory' import {RequestLocalStorage} from '../../http/RequestLocalStorage' import {Session} from '../../http/session/Session' export interface LoginProviderConfig { default: boolean, allow?: { login?: boolean, registration?: boolean, }, } @Injectable() export abstract class LoginProvider { @Inject() protected readonly request!: RequestLocalStorage protected get security(): SecurityContext { return this.request.get().make(SecurityContext) } constructor( protected name: string, protected config: TConfig, ) {} public routes(): void { Route.get('login') .alias(`@auth:${this.name}:login`) .pipe(line => line.when(this.config.default, route => route.alias('@auth:login'))) .pre(GuestRequiredMiddleware) .passingRequest() .handledBy(this.login.bind(this)) Route.any('logout') .alias(`@auth:${this.name}:logout`) .pipe(line => line.when(this.config.default, route => route.alias('@auth:logout'))) .pre(AuthRequiredMiddleware) .passingRequest() .handledBy(this.logout.bind(this)) Route.get('register') .alias(`@auth:${this.name}:register`) .pipe(line => line.when(this.config.default, route => route.alias('@auth:register'))) .pre(GuestRequiredMiddleware) .passingRequest() .handledBy(this.registration.bind(this)) } public abstract login(request: Request): ResponseObject public abstract logout(request: Request): ResponseObject public registration(request: Request): ResponseObject { return this.login(request) } protected redirectToIntendedRoute(): ResponseObject { const intent = this.request .get() .make(Session) .safe('@extollo:auth.intention') .or('/') .string() return redirect(intent) } }