import { Injectable } from '@angular/core' ; import { StorageType } from './storage-type.enum' ; import { Subscriber , Observable } from 'rxjs' ; import { StorageService } from './storage-service' ; import { ConfigService } from './config.service' ; @ Injectable ( ) export class SharedService { public tokenName = this . config . options . tokenPrefix ? [ this . config . options . tokenPrefix , this . config . options . tokenName ] . join ( this . config . options . tokenSeparator ) : this . config . options . tokenName ; constructor ( private storage , private config ) { } public getToken ( ) { return this . storage . get ( this . tokenName ) ; } public getPayload ( token = this . getToken ( ) ) { if ( token && token . split ( '.' ) . length === 3 ) { try { const base64Url = token . split ( '.' ) [ 1 ] ; const base64 = base64Url . replace ( /-/g , '+' ) . replace ( /_/g , '/' ) ; return JSON . parse ( this . b64DecodeUnicode ( base64 ) ) ; } catch ( e ) { return undefined ; } } } public setToken ( response ) { if ( ! response ) { return ; } let token ; if ( typeof response === 'string' ) { token = response ; } else { token = this . config . options . resolveToken ( response , this . config . options ) ; } if ( token ) { const expDate = this . getExpirationDate ( token ) ; this . storage . set ( this . tokenName , token , expDate ? expDate . toUTCString ( ) : '' ) ; } } public removeToken ( ) { this . storage . remove ( this . tokenName ) ; } public isAuthenticated ( token = this . getToken ( ) ) { if ( token ) { if ( token . split ( '.' ) . length === 3 ) { try { const base64Url = token . split ( '.' ) [ 1 ] ; const base64 = base64Url . replace ( /-/g , '+' ) . replace ( /_/g , '/' ) ; const exp = JSON . parse ( this . b64DecodeUnicode ( base64 ) ) . exp ; if ( exp ) { const isExpired = Math . round ( new Date ( ) . getTime ( ) / 1000 ) >= exp ; if ( isExpired ) { this . storage . remove ( this . tokenName ) ; return false ; } else { return true ; } } } catch ( e ) { return true ; } } return true ; } return false ; } public getExpirationDate ( token = this . getToken ( ) ) { const payload = this . getPayload ( token ) ; if ( payload && payload . exp && Math . round ( new Date ( ) . getTime ( ) / 1000 ) < payload . exp ) { const date = new Date ( 0 ) ; date . setUTCSeconds ( payload . exp ) ; return date ; } return null ; } public logout ( ) { return Observable . create ( ( observer ) => { this . storage . remove ( this . tokenName ) ; observer . next ( ) ; observer . complete ( ) ; } ) ; } public setStorageType ( type ) { return this . storage . updateStorageType ( type ) ; } private b64DecodeUnicode ( str ) { return decodeURIComponent ( Array . prototype . map . call ( atob ( str ) , c => '%' + ( '00' + c . charCodeAt ( 0 ) . toString ( 16 ) ) . slice ( - 2 ) ) . join ( '' ) ) ; } }