import { HttpClient } from '@angular/common/http'; import { inject, Injectable } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; import { BehaviorSubject, Observable, tap, of, catchError } from 'rxjs'; import { IUser } from '../../model/interface/user.interface'; import { environment } from '../../../environments/environment'; import { HotToastService } from '@ngxpert/hot-toast'; import { ApiService } from '../../shared/api.service'; @Injectable({ providedIn: 'root' }) export class AuthService { private accessTokenSubject = new BehaviorSubject(null); private refreshToken: string | null = null; private http: HttpClient = inject(HttpClient); private router: Router = inject(Router); private toast: HotToastService = inject(HotToastService); private api: ApiService = inject(ApiService); private _user: IUser | null = null; constructor() { const token = localStorage.getItem('accessToken_vault'); const refresh = localStorage.getItem('refreshToken_vault'); this.accessTokenSubject.next(token); this.refreshToken = refresh; } get user(): IUser { return this._user!; } get isAdmin(): boolean { return this.user != null && this.user.role == 'admin'; } async getMe() { if (!this.getAccessToken()) { return false; } const user = await this.api.getMe(); if (user) { this._user = user; return Promise.resolve(true); } return Promise.resolve(false) // return new Promise(resolve => { // this.http.get('/api/auth/me').subscribe({ // next: user => { // this._user = user; // resolve(true) // }, // error: () => { // resolve(false) // } // }) // }) } authenticateWithCode(authcode: string) { return new Promise(resolve => { this.http.post('/api/auth/auth-code', { code: authcode }).subscribe({ next: user => { this.setTokens({ accessToken: user.accessToken, refreshToken: user.refreshToken}); this._user = user; return resolve(true) }, error: () => { this.toast.error('Login nicht erfolgreich!'); return resolve(null); } }) }) } get authenticated(): boolean { return this._user != null; } login(credentials: { username: string; password: string }): Observable { return this.http.post('/api/auth/login', credentials).pipe( tap(tokens => { this.setTokens(tokens); }) ); } private setTokens(tokens: { accessToken: string; refreshToken: string }) { this.accessTokenSubject.next(tokens.accessToken); this.refreshToken = tokens.refreshToken; localStorage.setItem('accessToken_vault', tokens.accessToken); localStorage.setItem('refreshToken_vault', tokens.refreshToken); } getAccessToken(): string | null { return this.accessTokenSubject.value; } refreshAccessToken(): Observable { if (!this.refreshToken) { return of(null); } return this.http.post('/api/auth/refresh', { refreshToken: this.refreshToken }).pipe( tap(tokens => { this.setTokens(tokens); }), catchError(() => { this.logout(); return of(null); }) ); } logout() { this.accessTokenSubject.next(null); this.refreshToken = null; localStorage.removeItem('accessToken_vault'); localStorage.removeItem('refreshToken_vault'); this.router.navigateByUrl('/login'); this.toast.show('Du wurdest ausgeloggt.') } public routeToLogin() { const url = `https://valgard.xyz/authorize?client_id=ffc46841-26f8-4946-a57a-5a9f8f21bc13&redirect_uri=${encodeURIComponent(environment.location)}&response_type=code&scope=profile`; location.href = url; } }