import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable, tap } from 'rxjs'; import { Router } from '@angular/router'; import { LoginRequest } from '../model/auth/LoginRequest'; import { RegisterRequest } from '../model/auth/RegisterRequest'; import { AuthResponse } from '../model/auth/AuthResponse'; import { User } from '../model/User'; import { environment } from '@environments/environment'; const TOKEN_KEY = 'token'; const USER_KEY = 'user'; @Injectable({ providedIn: 'root', }) export class AuthService { private authUrl = `${environment.apiUrl}/auth`; private userUrl = `${environment.apiUrl}/users`; userSubject: BehaviorSubject; constructor( private http: HttpClient, private router: Router ) { this.userSubject = new BehaviorSubject(this.getUserFromStorage()); if (this.getToken()) { this.loadCurrentUser(); } } public get currentUserValue(): User | null { return this.userSubject.value; } login(loginRequest: LoginRequest): Observable { return this.http.post(`${this.authUrl}/login`, loginRequest).pipe( tap((response) => { this.setToken(response.token); this.loadCurrentUser(); }) ); } register(registerRequest: RegisterRequest): Observable { return this.http.post(`${this.authUrl}/register`, registerRequest); } logout(): void { localStorage.removeItem(TOKEN_KEY); localStorage.removeItem(USER_KEY); this.userSubject.next(null); this.router.navigate(['/']); } isLoggedIn(): boolean { return !!this.getToken(); } getToken(): string | null { return localStorage.getItem(TOKEN_KEY); } public loadCurrentUser(): void { this.http.get(`${this.userUrl}/me`).subscribe({ next: (user) => { this.setUser(user); }, error: () => { this.logout(); }, }); } private setToken(token: string): void { localStorage.setItem(TOKEN_KEY, token); } private setUser(user: User): void { localStorage.setItem(USER_KEY, JSON.stringify(user)); this.userSubject.next(user); } private getUserFromStorage(): User | null { const user = localStorage.getItem(USER_KEY); return user ? JSON.parse(user) : null; } getUser(): User | null { return this.currentUserValue; } }