import { Injectable, computed, inject, signal } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Router } from '@angular/router'; import { Observable, tap } from 'rxjs'; interface TokenResponse { token: string; email: string; } /** JWT in localStorage; who is logged in. */ @Injectable({ providedIn: 'root' }) export class AuthService { private http = inject(HttpClient); private router = inject(Router); readonly email = signal(read('email')); readonly loggedIn = computed(() => this.email() !== null && read('token') !== null); login(email: string, password: string): Observable { return this.http.post('/api/login', { email, password }).pipe(tap(r => this.store(r))); } register(email: string, password: string, displayName: string): Observable { return this.http.post('/api/register', { email, password, displayName }).pipe(tap(r => this.store(r))); } token(): string | null { return read('token'); } logout(): void { this.clear(); this.router.navigate(['/login']); } clear(): void { try { localStorage.removeItem('token'); localStorage.removeItem('email'); } catch { /* storage blocked */ } this.email.set(null); } private store(response: TokenResponse): void { try { localStorage.setItem('token', response.token); localStorage.setItem('email', response.email); } catch { /* storage blocked: logged in for this tab only */ } this.email.set(response.email); } } function read(key: string): string | null { try { return localStorage.getItem(key); } catch { return null; } }