bizmatch-project/bizmatch/src/app/services/auth.service.ts

132 lines
4.9 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// auth.service.ts
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
import { FirebaseApp } from '@angular/fire/app';
import { GoogleAuthProvider, UserCredential, createUserWithEmailAndPassword, getAuth, sendEmailVerification, signInWithEmailAndPassword, signInWithPopup } from 'firebase/auth';
import { firstValueFrom } from 'rxjs';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root',
})
export class AuthService {
private app = inject(FirebaseApp);
private auth = getAuth(this.app);
private http = inject(HttpClient);
// Registrierung mit Email und Passwort
async registerWithEmail(email: string, password: string): Promise<UserCredential> {
const userCredential = await createUserWithEmailAndPassword(this.auth, email, password);
// E-Mail-Verifizierung senden
if (userCredential.user) {
await sendEmailVerification(userCredential.user);
}
// Token, RefreshToken und ggf. photoURL speichern
const token = await userCredential.user.getIdToken();
localStorage.setItem('authToken', token);
localStorage.setItem('refreshToken', userCredential.user.refreshToken);
if (userCredential.user.photoURL) {
localStorage.setItem('photoURL', userCredential.user.photoURL);
}
return userCredential;
}
// Login mit Email und Passwort
loginWithEmail(email: string, password: string): Promise<UserCredential> {
return signInWithEmailAndPassword(this.auth, email, password).then(async userCredential => {
if (userCredential.user) {
const token = await userCredential.user.getIdToken();
localStorage.setItem('authToken', token);
localStorage.setItem('refreshToken', userCredential.user.refreshToken);
if (userCredential.user.photoURL) {
localStorage.setItem('photoURL', userCredential.user.photoURL);
}
}
return userCredential;
});
}
// Login mit Google
loginWithGoogle(): Promise<UserCredential> {
const provider = new GoogleAuthProvider();
return signInWithPopup(this.auth, provider).then(async userCredential => {
if (userCredential.user) {
const token = await userCredential.user.getIdToken();
localStorage.setItem('authToken', token);
localStorage.setItem('refreshToken', userCredential.user.refreshToken);
if (userCredential.user.photoURL) {
localStorage.setItem('photoURL', userCredential.user.photoURL);
}
}
return userCredential;
});
}
// Logout: Token, RefreshToken und photoURL entfernen
logout(): Promise<void> {
localStorage.removeItem('authToken');
localStorage.removeItem('refreshToken');
localStorage.removeItem('photoURL');
return this.auth.signOut();
}
// Prüft, ob ein Token noch gültig ist (über die "exp"-Eigenschaft)
private isTokenValid(token: string): boolean {
try {
const payloadBase64 = token.split('.')[1];
const payloadJson = atob(payloadBase64.replace(/-/g, '+').replace(/_/g, '/'));
const payload = JSON.parse(payloadJson);
const exp = payload.exp;
const now = Math.floor(Date.now() / 1000);
return exp > now;
} catch (e) {
return false;
}
}
// Versucht, mit dem RefreshToken einen neuen Access Token zu erhalten
async refreshToken(): Promise<string | null> {
const storedRefreshToken = localStorage.getItem('refreshToken');
if (!storedRefreshToken) {
return null;
}
const apiKey = environment.firebaseConfig.apiKey; // Stelle sicher, dass dieser Wert in Deiner environment.ts gesetzt ist
const url = `https://securetoken.googleapis.com/v1/token?key=${apiKey}`;
const body = new HttpParams().set('grant_type', 'refresh_token').set('refresh_token', storedRefreshToken);
const headers = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
try {
const response: any = await firstValueFrom(this.http.post(url, body.toString(), { headers }));
// response enthält z.B. id_token, refresh_token, expires_in etc.
const newToken = response.id_token;
const newRefreshToken = response.refresh_token;
localStorage.setItem('authToken', newToken);
localStorage.setItem('refreshToken', newRefreshToken);
return newToken;
} catch (error) {
console.error('Error refreshing token:', error);
return null;
}
}
/**
* Gibt einen gültigen Token zurück.
* Falls der gespeicherte Token noch gültig ist, wird er zurückgegeben.
* Ansonsten wird versucht, einen neuen Token mit dem RefreshToken zu holen.
* Ist auch das nicht möglich, wird null zurückgegeben.
*/
async getToken(): Promise<string | null> {
const token = localStorage.getItem('authToken');
if (token && this.isTokenValid(token)) {
return token;
} else {
return await this.refreshToken();
}
}
}