import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { catchError, Observable, of, switchMap, throwError } from 'rxjs'; import { AuthUtils } from 'app/core/auth/auth.utils'; import { WebSessionStorageService } from 'app/core/web-storage/services/web-session-storage.service'; import { IdentityService } from 'app/modules/polyglot/identity/services/identity.service'; import { MemberService } from 'app/modules/polyglot/member/services/member.service'; import { MemberInfo } from 'app/shared/models/member-info'; @Injectable() export class AuthService { private _authenticated: boolean = false; /** * Constructor */ constructor( private _httpClient: HttpClient, private _identityService: IdentityService, private _memberService: MemberService, private __webSessionStorageService: WebSessionStorageService ) {} // ----------------------------------------------------------------------------------------------------- // @ Accessors // ----------------------------------------------------------------------------------------------------- /** * Setter & getter for access token */ get accessToken(): string { return localStorage.getItem('accessToken') ?? ''; } set accessToken(token: string) { localStorage.setItem('accessToken', token); } set memberInfo(memberInfo: MemberInfo) { const info = JSON.stringify(memberInfo); localStorage.setItem('memberInfo', info); } get memberInfo(): MemberInfo { const info = localStorage.getItem('memberInfo') ?? ''; let result = {} as MemberInfo; if (info !== '') { result = JSON.parse(info) as MemberInfo; } return result; } // ----------------------------------------------------------------------------------------------------- // @ Public methods // ----------------------------------------------------------------------------------------------------- /** * Forgot password * * @param email */ forgotPassword(email: string): Observable { return this._httpClient.post('api/auth/forgot-password', email); } /** * Reset password * * @param password */ resetPassword(password: string): Observable { return this._httpClient.post('api/auth/reset-password', password); } /** * Sign in * * @param credentials */ signIn(credentials: { username: string; password: string }): Promise { return new Promise((resolve, reject) => { // Throw error, if the user is already logged in if (this._authenticated) { return reject('User is already logged in.'); } this._identityService .signinWithoutSecurityCode(credentials.username, credentials.password) .then((res) => { this.__webSessionStorageService.set( 'accessToken', res.getAccessToken() ); this.memberInfo = { username: credentials.username, } as MemberInfo; // Store the access token in the local storage this.accessToken = res.getAccessToken(); // Set the authenticated flag to true this._authenticated = true; resolve(); }) .catch((e) => { reject(e); }); }); } /** * Sign in using the access token */ signInUsingToken(): Observable { // Renew token return this._httpClient .post('api/auth/refresh-access-token', { accessToken: this.accessToken, }) .pipe( catchError(() => // Return false of(false) ), switchMap((response: any) => { // Store the access token in the local storage this.accessToken = response.accessToken; // Set the authenticated flag to true this._authenticated = true; // Return true return of(true); }) ); } /** * Sign out */ signOut(): Observable { // Remove the access token from the local storage localStorage.removeItem('accessToken'); localStorage.removeItem('memberInfo'); // Set the authenticated flag to false this._authenticated = false; // Return the observable return of(true); } /** * Sign up * * @param user */ signUp(user: { name: string; email: string; password: string; company: string; }): Observable { return this._httpClient.post('api/auth/sign-up', user); } /** * Unlock session * * @param credentials */ unlockSession(credentials: { email: string; password: string; }): Observable { return this._httpClient.post('api/auth/unlock-session', credentials); } /** * Check the authentication status */ check(): Observable { // Check if the user is logged in if (this._authenticated) { return of(true); } // Check the access token availability if (!this.accessToken) { return of(false); } // Check the access token expire date if (AuthUtils.isTokenExpired(this.accessToken)) { return of(false); } // If the access token exists and it didn't expire, sign in using it // return this.signInUsingToken(); return of(true); } }