import { Injectable , Inject , } from '@angular/core' ; import { Actions , Effect , ofType , } from '@ngrx/effects' ; import { of , Observable , EMPTY , } from 'rxjs' ; import { switchMap , map , catchError , mapTo , tap , switchMapTo , } from 'rxjs/operators' ; import { DaffLoginInfo , DaffAuthToken , DaffAccountRegistration , DAFF_AUTH_ERROR_MATCHER , DaffAuthStorageService , } from '@daffodil/auth' ; import { DaffRegisterDriver , DaffRegisterServiceInterface , DaffLoginDriver , DaffLoginServiceInterface , DaffAuthDriver , DaffAuthServiceInterface , } from '@daffodil/auth/driver' ; import { DaffError } from '@daffodil/core' ; import { ErrorTransformer } from '@daffodil/core/state' ; import { DaffAuthActionTypes , DaffAuthLogin , DaffAuthLoginSuccess , DaffAuthLoginFailure , DaffAuthRegister , DaffAuthRegisterSuccess , DaffAuthRegisterFailure , DaffAuthCheckSuccess , DaffAuthCheckFailure , DaffAuthCheck , DaffAuthLogoutSuccess , DaffAuthLogoutFailure , DaffAuthLogout , DaffAuthGuardCheckCompletion , DaffAuthGuardCheck , DaffAuthStorageFailure , } from '../actions/auth.actions' ; @ Injectable ( ) export class DaffAuthEffects < T extends DaffLoginInfo , U extends DaffAuthToken , S extends DaffAccountRegistration > { constructor ( private actions$ , @ Inject ( DaffRegisterDriver ) private registerDriver , @ Inject ( DaffLoginDriver ) private loginDriver , @ Inject ( DaffAuthDriver ) private authDriver , @ Inject ( DAFF_AUTH_ERROR_MATCHER ) private errorMatcher , private storage ) { } @ Effect ( ) check$ : Observable < DaffAuthCheckSuccess | DaffAuthCheckFailure > = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthCheckAction ) , switchMap ( ( action ) => this . checkToken ( ) . pipe ( mapTo ( new DaffAuthCheckSuccess ( ) ) , catchError ( ( error ) => of ( new DaffAuthCheckFailure ( this . errorMatcher ( error ) ) ) ) ) ) ) ; @ Effect ( ) login$ : Observable < DaffAuthLoginSuccess < U > | DaffAuthLoginFailure > = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthLoginAction ) , switchMap ( ( action ) => this . loginDriver . login ( action . loginInfo ) . pipe ( map ( ( resp ) => new DaffAuthLoginSuccess < U > ( resp ) ) , catchError ( ( error ) => of ( new DaffAuthLoginFailure ( this . errorMatcher ( error ) ) ) ) ) ) ) ; @ Effect ( { dispatch : false , } ) storeAuthToken$ = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthLoginSuccessAction ) , tap ( ( action ) => { this . storage . setAuthToken ( action . auth . token ) ; } ) , switchMapTo ( EMPTY ) , catchError ( ( error ) => of ( new DaffAuthStorageFailure ( this . errorMatcher ( error ) ) ) ) ) ; @ Effect ( ) logout$ : Observable < DaffAuthLogoutSuccess | DaffAuthLogoutFailure > = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthLogoutAction ) , switchMap ( ( action ) => this . loginDriver . logout ( ) . pipe ( mapTo ( new DaffAuthLogoutSuccess ( ) ) , catchError ( ( error ) => of ( new DaffAuthLogoutFailure ( this . errorMatcher ( error ) ) ) ) ) ) ) ; @ Effect ( ) loginAfterRegister$ : Observable < DaffAuthLogin < T > > = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthRegisterSuccessAction ) , map ( ( action ) => new DaffAuthLogin ( action . loginInfo ) ) ) ; @ Effect ( ) register$ : Observable < any > = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthRegisterAction ) , switchMap ( ( action ) => this . registerDriver . register ( action . registration ) . pipe ( map ( ( resp ) => new DaffAuthRegisterSuccess < T > ( resp ) ) , catchError ( ( error ) => of ( new DaffAuthRegisterFailure ( this . errorMatcher ( error ) ) ) ) ) ) ) ; @ Effect ( ) guardCheck$ : Observable < DaffAuthGuardCheckCompletion > = this . actions$ . pipe ( ofType ( DaffAuthActionTypes . AuthGuardCheckAction ) , switchMap ( ( action ) => this . checkToken ( ) . pipe ( mapTo ( new DaffAuthGuardCheckCompletion ( true ) ) , catchError ( ( error ) => of ( new DaffAuthGuardCheckCompletion ( false ) ) ) ) ) ) ; private checkToken ( ) { return this . authDriver . check ( ) ; } }