import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { BehaviorSubject, Observable, distinctUntilChanged, map, tap, } from 'rxjs'; import { User } from '../models/user.model'; import { Router } from '@angular/router'; import { JwtService } from './jwt.service'; @Injectable({ providedIn: 'root' }) export class UserService { private currnetUserSubject = new BehaviorSubject(null); public currentUser = this.currnetUserSubject .asObservable() .pipe(distinctUntilChanged()); public isAuthenticated = this.currentUser.pipe( map((user) => { return user !== null; }) ); constructor( private readonly http: HttpClient, private readonly router: Router, private readonly jwtService: JwtService ) {} login(credentials: { email: string; password: string; }): Observable<{ user: User }> { return this.http .post<{ user: User }>('/api/users/login', credentials) .pipe(tap(({ user }) => this.setAuth(user))); } register(credentials: { username: string; email: string; password: string; }): Observable<{ user: User }> { return this.http .post<{ user: User }>('/api/users', { user: credentials }) .pipe(tap(({ user }) => this.setAuth(user))); } logout(): void { this.purgeAuth(); void this.router.navigate(['/login']); } getCurrentUser(): Observable<{ user: User }> { return this.http.get<{ user: User }>('/api/user').pipe( tap({ next: ({ user }) => this.setAuth(user), error: () => this.purgeAuth(), }) ); } update(user: Partial): Observable<{ user: User }> { return this.http .put<{ user: User }>('/api/user', { user }) .pipe(tap(({ user }) => this.currnetUserSubject.next(user))); } setAuth(user: User): void { this.jwtService.saveToken(user.token); void this.currnetUserSubject.next(user); } purgeAuth(): void { this.jwtService.destroyToken(); this.currnetUserSubject.next(null); } }