import { Injectable } from '@angular/core'; import { MessageService } from './message.service'; import { HttpClient } from '@angular/common/http'; import { UserCreds } from './userCreds' import jwt_decode from 'jwt-decode' import { Observable, interval, Subject, Subscription } from 'rxjs' import { map, takeWhile } from 'rxjs/operators' import { authserviceBaseUrl, applicationId } from './config' interface TokenTuple { authToken: string refreshToken: string } @Injectable({ providedIn: 'root' }) export class TokenService { public static Id_AuthToken_Key : string = "id_authtoken"; public static Id_RefreshToken_Key : string = "id_refreshtoken"; private _expiryTime = new Subject() private subscription: Subscription constructor(private http: HttpClient, private messageService: MessageService) { } checkAuthenticated(): boolean { let result: boolean = false const token = localStorage.getItem(TokenService.Id_AuthToken_Key) if (token) { let expiration = jwt_decode(token)["exp"] if ((expiration * 1000) > Date.now()) { result = true } else { this.logout() } } return result } logout() : void { localStorage.removeItem(TokenService.Id_AuthToken_Key) localStorage.removeItem(TokenService.Id_RefreshToken_Key) this.messageService.add("Token removed from local storage") } get expiryTime(): Observable { return this._expiryTime } setExpiryTime(token: string) :void { let exp = jwt_decode(token)["exp"] let iat = jwt_decode(token)["iat"] let start = exp - iat if (this.subscription && !this.subscription.closed) { this.subscription.unsubscribe() } this.subscription = interval(1000).pipe(map(v => start - v)).pipe(takeWhile(v => v != 0)).subscribe(v => this._expiryTime.next(v)) } async login(login: string, password: string) : Promise { this.messageService.add(`TokenService: trying to login and obtain token`) const userCreds : UserCreds = { "application": applicationId, "login": login, "password": password } const tokenTuple: TokenTuple = await this.http.post( `${authserviceBaseUrl}/refreshable`, userCreds ).toPromise() localStorage.setItem(TokenService.Id_AuthToken_Key, tokenTuple.authToken) localStorage.setItem(TokenService.Id_RefreshToken_Key, tokenTuple.refreshToken) this.messageService.add("Token saved") this.setExpiryTime(tokenTuple.authToken) } async refresh() : Promise { try { this.messageService.add(`TokenService: trying to refresh tokens`) const refreshToken = localStorage.getItem(TokenService.Id_RefreshToken_Key) const tokenTuple: TokenTuple = await this.http.post( `${authserviceBaseUrl}/refresh`, refreshToken ).toPromise() localStorage.setItem(TokenService.Id_AuthToken_Key, tokenTuple.authToken) localStorage.setItem(TokenService.Id_RefreshToken_Key, tokenTuple.refreshToken) this.messageService.add("Token saved") this.setExpiryTime(tokenTuple.authToken) } catch (err) { this.messageService.add(`error when trying to refresh: ${ JSON.stringify(err, undefined, 4)}`) localStorage.removeItem(TokenService.Id_AuthToken_Key) localStorage.removeItem(TokenService.Id_RefreshToken_Key) this.messageService.add("Token removed from local storage") } } }