import { Injectable } from '@nestjs/common' ; import { Observable , of } from 'rxjs' ; import { map , switchMap } from 'rxjs/operators' ; import { CookieService } from '../cookie/cookie.service' ; import { ReqWithUser } from '../interfaces/req-with-user.interface' ; import { RedisService } from '../redis/redis.service' ; import { GoogleService } from './google/google.service' ; import { LocalService } from './local/local.service' ; import { AuthDTO , LoginDTO , SignupDTO } from './models' ; import { GoogleUser , UserDTO } from './user/models' ; import { UserService } from './user/user.service' ; const hour = 60 * 60 * 1000 ; const day = 24 * hour ; @ Injectable ( ) export class AuthService { constructor ( private readonly localService , private readonly googleService , private readonly cookieService , private readonly redis , private readonly userService ) { } getOauthLoginUrl ( type ) { let loginUrl ; switch ( type ) { case 'google' : loginUrl = this . googleService . getLoginUrl ( ) ; } return loginUrl ; } login ( req , login ) { return this . localService . login ( login ) . pipe ( switchMap ( ( user ) => { return this . setCookie ( req , user ) ; } ) ) ; } signup ( req , signup ) { return this . localService . signup ( signup ) . pipe ( switchMap ( ( user ) => { return this . setCookie ( req , user ) ; } ) ) ; } getGoogleUser ( req , code , state ) { return this . googleService . getUserProfile ( code , state ) . pipe ( switchMap ( ( user ) => { return this . setCookie ( req , user ) ; } ) ) ; } private setCookie < T extends AuthDTO > ( req , user ) { return this . redis . set ( this . cookieService . setCookie ( req , 'session.id' , undefined , { expires : new Date ( Date . now ( ) + hour / 60 ) , path : '/' , } ) , user . id , hour ) . pipe ( switchMap ( ( ) => { return this . redis . set ( this . cookieService . setCookie ( req , 'session.refresh' , undefined , { expires : new Date ( Date . now ( ) + 14 * day ) , path : '/' , } ) , user . id , ( 5 * hour ) / 60 ) ; } ) , map ( ( ) => user ) ) ; } private setSessionCookie ( req , user ) { return this . redis . set ( this . cookieService . setCookie ( req , 'session.id' , undefined , { expires : new Date ( Date . now ( ) + hour / 60 ) , path : '/' , } ) , user . id , hour ) . pipe ( map ( ( ) => user ) ) ; } refreshSession ( req , user ) { return this . setSessionCookie ( req , user ) ; } getUserByCookie ( cookie ) { return this . redis . get ( cookie ) . pipe ( switchMap ( ( userId ) => { if ( ! userId ) { return of ( undefined ) ; } return this . userService . getById ( { id : userId } ) ; } ) ) ; } }