Files
keyvault/client/src/app/core/auth/auth.service.ts
2026-02-19 12:21:30 +01:00

134 lines
3.8 KiB
TypeScript

import { HttpClient } from '@angular/common/http';
import { inject, Injectable } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { BehaviorSubject, Observable, tap, of, catchError } from 'rxjs';
import { IUser } from '../../model/interface/user.interface';
import { environment } from '../../../environments/environment';
import { HotToastService } from '@ngxpert/hot-toast';
import { ApiService } from '../../shared/api.service';
@Injectable({
providedIn: 'root'
})
export class AuthService {
private accessTokenSubject = new BehaviorSubject<string | null>(null);
private refreshToken: string | null = null;
private http: HttpClient = inject(HttpClient);
private router: Router = inject(Router);
private toast: HotToastService = inject(HotToastService);
private api: ApiService = inject(ApiService);
private _user: IUser | null = null;
constructor() {
const token = localStorage.getItem('accessToken_vault');
const refresh = localStorage.getItem('refreshToken_vault');
this.accessTokenSubject.next(token);
this.refreshToken = refresh;
}
get user(): IUser {
return this._user!;
}
get isAdmin(): boolean {
return this.user != null && this.user.role == 'admin';
}
async getMe() {
if (!this.getAccessToken()) {
return false;
}
const user = await this.api.getMe();
if (user) {
this._user = user;
return Promise.resolve(true);
}
return Promise.resolve(false)
// return new Promise(resolve => {
// this.http.get<IUser>('/api/auth/me').subscribe({
// next: user => {
// this._user = user;
// resolve(true)
// },
// error: () => {
// resolve(false)
// }
// })
// })
}
authenticateWithCode(authcode: string) {
return new Promise(resolve => {
this.http.post<IUser>('/api/auth/auth-code', { code: authcode }).subscribe({
next: user => {
this.setTokens({ accessToken: user.accessToken, refreshToken: user.refreshToken});
this._user = user;
return resolve(true)
},
error: () => {
this.toast.error('Login nicht erfolgreich!');
return resolve(null);
}
})
})
}
get authenticated(): boolean {
return this._user != null;
}
login(credentials: { username: string; password: string }): Observable<any> {
return this.http.post<any>('/api/auth/login', credentials).pipe(
tap(tokens => {
this.setTokens(tokens);
})
);
}
private setTokens(tokens: { accessToken: string; refreshToken: string }) {
this.accessTokenSubject.next(tokens.accessToken);
this.refreshToken = tokens.refreshToken;
localStorage.setItem('accessToken_vault', tokens.accessToken);
localStorage.setItem('refreshToken_vault', tokens.refreshToken);
}
getAccessToken(): string | null {
return this.accessTokenSubject.value;
}
refreshAccessToken(): Observable<any> {
if (!this.refreshToken) {
return of(null);
}
return this.http.post<any>('/api/auth/refresh', { refreshToken: this.refreshToken }).pipe(
tap(tokens => {
this.setTokens(tokens);
}),
catchError(() => {
this.logout();
return of(null);
})
);
}
logout() {
this.accessTokenSubject.next(null);
this.refreshToken = null;
localStorage.removeItem('accessToken_vault');
localStorage.removeItem('refreshToken_vault');
this.router.navigateByUrl('/login');
this.toast.show('Du wurdest ausgeloggt.')
}
public routeToLogin() {
const url = `https://valgard.xyz/authorize?client_id=ffc46841-26f8-4946-a57a-5a9f8f21bc13&redirect_uri=${encodeURIComponent(environment.location)}&response_type=code&scope=profile`;
location.href = url;
}
}