60 lines
1.8 KiB
TypeScript
60 lines
1.8 KiB
TypeScript
import { inject, Injectable } from '@angular/core';
|
|
import { HttpClient } from '@angular/common/http';
|
|
import { BehaviorSubject, catchError, EMPTY, Observable, tap } from 'rxjs';
|
|
import { User } from '../model/User';
|
|
|
|
@Injectable({
|
|
providedIn: 'root',
|
|
})
|
|
export class UserService {
|
|
private http: HttpClient = inject(HttpClient);
|
|
private currentUserSubject = new BehaviorSubject<User | null>(null);
|
|
public currentUser$ = this.currentUserSubject.asObservable();
|
|
|
|
constructor() {
|
|
this.getCurrentUser().subscribe();
|
|
}
|
|
|
|
public getUser(id: string): Observable<User | null> {
|
|
return this.http.get<User | null>(`/backend/user/${id}`).pipe(
|
|
catchError(() => EMPTY),
|
|
tap((user) => this.currentUserSubject.next(user))
|
|
);
|
|
}
|
|
|
|
public getCurrentUser(): Observable<User | null> {
|
|
return this.http.get<User | null>('/backend/user').pipe(
|
|
catchError(() => EMPTY),
|
|
tap((user) => this.currentUserSubject.next(user))
|
|
);
|
|
}
|
|
|
|
public refreshCurrentUser(): void {
|
|
this.getCurrentUser().subscribe();
|
|
}
|
|
|
|
public createUser(id: string, username: string): Observable<User> {
|
|
return this.http
|
|
.post<User>('/backend/user', {
|
|
authentikId: id,
|
|
username: username,
|
|
})
|
|
.pipe(tap((user) => this.currentUserSubject.next(user)));
|
|
}
|
|
|
|
public getOrCreateUser(profile: Record<string, unknown>): Observable<User> {
|
|
const info = profile['info'] as Record<string, unknown> | undefined;
|
|
const id = (info?.['sub'] as string) || (profile['sub'] as string);
|
|
const username =
|
|
(info?.['preferred_username'] as string) ||
|
|
(profile['preferred_username'] as string) ||
|
|
(profile['email'] as string) ||
|
|
(profile['name'] as string);
|
|
|
|
if (!id || !username) {
|
|
throw new Error('Invalid user profile data');
|
|
}
|
|
|
|
return this.createUser(id, username);
|
|
}
|
|
}
|