import { camelCase, mapKeys } from 'lodash-es'; import * as jwt from 'jsrsasign'; import { Injectable } from '@angular/core'; // import {ConfigService} from './config/config.service'; @Injectable() export class AuthTokenService { private ACCESS_TOKEN_STORAGE_KEY = 'accessToken'; private EXPIRES_AT_STORAGE_KEY = 'accessExpiresAt'; private REFRESH_TOKEN_STORAGE_KEY = 'refreshToken'; private EXPIRES_AT_REFRESH_KEY = 'refreshExpiresAt'; private CLIENT_ID_KEY = 'clientId'; public PUBLIC_CERTIFICATE_KEY = 'publicCertificate'; public PUBLIC_CERTIFICATE_ALG = 'publicCertificateAlg'; public getAccessToken() { return localStorage.getItem(this.ACCESS_TOKEN_STORAGE_KEY); } public getRefreshToken() { return localStorage.getItem(this.REFRESH_TOKEN_STORAGE_KEY); } public getClientId() { return localStorage.getItem(this.CLIENT_ID_KEY); } public isValidToken(token: string) { const pubCertificate = this.getPublicCertificate(); if (!pubCertificate || !token) return false; const pubKey = jwt.KEYUTIL.getKey(pubCertificate); const isValid = jwt.KJUR.jws.JWS.verifyJWT(token, pubKey, { alg: ['RS256', this.getPublicCertificateAlg()] }); const expiresInAMinute = this.decodeToken(token).token.exp < Date.now() / 1000 - 60; return isValid && !expiresInAMinute; } /** * Gets the value of the tokens unless it has expired (in which case return null) */ public getValidAccessToken() { const accessToken = this.getAccessToken(); const validToken = this.isValidToken(accessToken) ? accessToken : null; return validToken; } public getValidRefreshToken() { const refreshToken = this.getRefreshToken(); return this.isValidToken(refreshToken) ? refreshToken : null; } public getPublicCertificate() { return localStorage.getItem(this.PUBLIC_CERTIFICATE_KEY) || null; } public getPublicCertificateAlg() { return localStorage.getItem(this.PUBLIC_CERTIFICATE_ALG) || null; } /** * Transform the value obtained from the parameter into its camelCase version */ private camelCaseObj(obj: object) { return mapKeys(obj, (value: string, key: string) => camelCase(key)); } /** * Decodes the token given as a parameter, with the formated version */ public decodeToken(token: string) { const jwtParse = jwt.KJUR.jws.JWS.parse; const { payloadObj, headerObj } = jwtParse(token); const formattedToken = this.camelCaseObj(payloadObj); const formattedHeader = this.camelCaseObj(headerObj); return { token: formattedToken, header: formattedHeader }; } /** * Stores access token in local storage * @param token */ public setTokens(authResult: any) { const decodedAccessToken = this.decodeToken(authResult.access_token); const decodedRefreshToken = this.decodeToken(authResult.refresh_token); localStorage.setItem( this.ACCESS_TOKEN_STORAGE_KEY, authResult.access_token ); localStorage.setItem( this.EXPIRES_AT_STORAGE_KEY, JSON.stringify(decodedAccessToken.token.exp * 1000) ); localStorage.setItem( this.REFRESH_TOKEN_STORAGE_KEY, authResult.refresh_token ); localStorage.setItem( this.EXPIRES_AT_REFRESH_KEY, JSON.stringify(decodedRefreshToken.token.exp * 1000) ); } /** * Sets the respective public certificate */ public setPublicCertificate(certificate: any) { localStorage.setItem(this.PUBLIC_CERTIFICATE_KEY, certificate.value); localStorage.setItem(this.PUBLIC_CERTIFICATE_ALG, certificate.alg); } /** * Returns the expiry time of the token */ public getExpiresAccessTime() { return JSON.parse(localStorage.getItem(this.EXPIRES_AT_STORAGE_KEY)); } /** * Purges the session (removes token and expiry time) */ public resetLocalStorage() { localStorage.clear(); } public setClientId(clientId: string) { localStorage.setItem(this.CLIENT_ID_KEY, clientId); } }