import { HttpClient } from '@angular/common/http'; import { Injectable, Signal, computed, effect, signal } from '@angular/core'; import { jwtDecode } from 'jwt-decode'; import { Observable, distinctUntilChanged, filter, from, lastValueFrom, map } from 'rxjs'; import urlcat from 'urlcat'; import { User } from '../../../../bizmatch-server/src/models/db.model'; import { JwtToken, KeycloakUser, ListingCriteria, ResponseUsersArray, StatesResult } from '../../../../bizmatch-server/src/models/main.model'; import { environment } from '../../environments/environment'; import { KeycloakService } from './keycloak.service'; @Injectable({ providedIn: 'root', }) export class UserService { private apiBaseUrl = environment.apiBaseUrl; // ----------------------------- // Keycloak services // ----------------------------- private user$ = new Observable(); private user: KeycloakUser; public $isLoggedIn: Signal; constructor(public keycloak: KeycloakService, private http: HttpClient) { this.user$ = from(this.keycloak.getToken()).pipe( filter(t => !!t), distinctUntilChanged(), map(t => this.map2User(t)), // tap(u => { // logger.info('Logged in user:', u); // this.analyticsService.identify(u); // }), ); this.$isLoggedIn = signal(false); this.$isLoggedIn = computed(() => { return keycloak.isLoggedIn(); }); effect(async () => { if (this.$isLoggedIn()) { this.updateTokenDetails(); } else { this.user = null; } }); } private async refreshToken(): Promise { try { await this.keycloak.updateToken(10); // Versuche, den Token zu erneuern await this.updateTokenDetails(); // Aktualisiere den Token und seine Details } catch (error) { console.error('Fehler beim Token-Refresh', error); } } private async updateTokenDetails(): Promise { const token = await this.keycloak.getToken(); this.user = this.map2User(token); } private map2User(jwt: string): KeycloakUser { const token = jwtDecode(jwt); return { id: token.user_id, firstName: token.given_name, lastName: token.family_name, email: token.email, }; } isLoggedIn(): boolean { return this.$isLoggedIn(); } getKeycloakUser(): KeycloakUser { return this.user; } getUserObservable(): Observable { return this.user$; } async getId(): Promise { if (sessionStorage.getItem('USERID')) { return sessionStorage.getItem('USERID'); } else { const user = await this.getByMail(this.user.email); sessionStorage.setItem('USERID', user.id); return user.id; } } logout() { sessionStorage.removeItem('USERID'); this.keycloak.logout(window.location.origin + '/home'); } async login(url: string) { await this.keycloak.login({ redirectUri: url, }); } getUserRoles() { return this.keycloak.getUserRoles(true); } hasAdminRole() { return this.keycloak.getUserRoles(true).includes('ADMIN'); } register(url: string) { this.keycloak.register({ redirectUri: url }); } // ----------------------------- // DB services // ----------------------------- async save(user: User): Promise { return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/user`, user)); } async getById(id: string): Promise { return await lastValueFrom(this.http.get(`${this.apiBaseUrl}/bizmatch/user/${id}`)); } async getByMail(mail: string): Promise { const url = urlcat(`${this.apiBaseUrl}/bizmatch/user`, { mail }); return await lastValueFrom(this.http.get(url)); } async search(criteria?: ListingCriteria): Promise { return await lastValueFrom(this.http.post(`${this.apiBaseUrl}/bizmatch/user/search`, criteria)); } async getAllStates(): Promise { return await lastValueFrom(this.http.get(`${this.apiBaseUrl}/bizmatch/user/states/all`)); } }