import { HttpClient, HttpHeaders } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; import { Credential } from '@app/core/model/auth/credential'; import { LoginInfo } from '@app/core/model/auth/login-info'; import { Principal } from '@app/core/model/auth/principal'; import { ConfigurableProvider } from '@app/core/model/configurable-provider/configurableProvider'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseService } from '@common/base/base.service'; import { TranslateService } from '@ngx-translate/core'; import { environment } from 'environments/environment'; import { Observable, of as observableOf, throwError as observableThrowError } from 'rxjs'; import { catchError, map, takeUntil } from 'rxjs/operators'; import { ConfigurationService } from '../configuration/configuration.service'; @Injectable() export class AuthService extends BaseService { private actionUrl: string; private headers: HttpHeaders; constructor( private http: HttpClient, private snackBar: MatSnackBar, private language: TranslateService, private router: Router, private uiNotificationService: UiNotificationService, private configurationService: ConfigurationService ) { super(); this.headers = new HttpHeaders(); this.headers = this.headers.set('Content-Type', 'application/json'); this.headers = this.headers.set('Accept', 'application/json'); } private clear(): void { localStorage.removeItem('principal'); } public current(principal?: Principal): Principal { if (principal) { localStorage.setItem('principal', JSON.stringify(principal)); return principal; } const principalJson = localStorage.getItem('principal'); if (!principalJson) { return null; } const principalObj = JSON.parse(principalJson) as Principal; return principalObj; } //public login(credential: Credential): Observable { // const url = this.actionUrl + 'login'; // return this.http.post(url, credential, { headers: this.headers }) // .map((res: Response) => { // let principal = this.current(new JsonSerializer().fromJSONObject(res, Principal)); // //this.loginContextSubject.next(true); // return principal; // }) // .catch((error: any) => { // //this.loginContextSubject.next(false); // return Observable.throw(error); // }); //} public login(loginInfo: LoginInfo): Observable { this.actionUrl = this.configurationService.server + 'auth/'; const url = this.actionUrl + 'externallogin'; return this.http.post(url, loginInfo, { headers: this.headers }).pipe( map((res: any) => { const principal = this.current(res.payload); //this.loginContextSubject.next(true); return principal; }), catchError((error: any) => { //this.loginContextSubject.next(false); return observableThrowError(error); })); } public nativeLogin(credentials: Credential): Observable { this.actionUrl = this.configurationService.server + 'auth/'; const url = this.actionUrl + 'nativelogin'; return this.http.post(url, credentials, { headers: this.headers }).pipe( map((res: any) => { const principal = this.current(res.payload); //this.loginContextSubject.next(true); return principal; }), catchError((error: any) => { //this.loginContextSubject.next(false); return observableThrowError(error); })); } public logout(): void { this.actionUrl = this.configurationService.server + 'auth/'; const url = this.actionUrl + 'logout'; const principal = this.current(); this.clear(); if (!principal) { return; } let headers = this.headers; headers = headers.set('AuthToken', principal.token); this.http.post(url, null, { headers: headers }) .pipe(takeUntil(this._destroyed)) .subscribe( res => this.onLogOutSuccess(res), error => this.onLogOutError(error) ); } public me(): Observable { const url = this.actionUrl + '/me'; const principal = this.current(); if (!principal) { this.clear(); return observableOf(); } let headers = this.headers; headers = headers.set('AuthToken', principal.token); return this.http.post(url, null, { headers: headers }).pipe( map((res: any) => { const princ = this.current(res.payload); return princ; }), catchError((error: any) => { //console.warn('could not retrieve me info:\n', error); this.clear(); const princ = this.current(); this.router.navigate(['/login']); return observableOf(princ); })); } public onLogOutSuccess(logoutMessage: any) { this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-LOGOUT'), SnackBarNotificationLevel.Success); this.router.navigate(['/login']); } public onLogOutError(errorMessage: string) { this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-LOGOUT'), SnackBarNotificationLevel.Error); this.router.navigate(['/login']); } public getConfigurableProviders(): Observable { this.actionUrl = this.configurationService.server + 'auth/'; const url = this.actionUrl + 'configurableLogin'; return this.http.get(url, { headers: this.headers }).pipe( map((res: any) => { const providers = res.payload.providers; return providers; }) ); } }