#136: EMail Auth on different browsers ...
This commit is contained in:
parent
162c5b042f
commit
097a6cb360
|
|
@ -20,21 +20,31 @@ export class AuthController {
|
|||
}
|
||||
|
||||
try {
|
||||
// Schritt 1: Hole den Benutzer anhand der E-Mail-Adresse
|
||||
// Step 1: Get the user by email address
|
||||
const userRecord = await this.firebaseAdmin.auth().getUserByEmail(email);
|
||||
|
||||
if (userRecord.emailVerified) {
|
||||
return { message: 'Email is already verified' };
|
||||
// Even if already verified, we'll still return a valid token
|
||||
const customToken = await this.firebaseAdmin.auth().createCustomToken(userRecord.uid);
|
||||
return {
|
||||
message: 'Email is already verified',
|
||||
token: customToken,
|
||||
};
|
||||
}
|
||||
|
||||
// Schritt 2: Aktualisiere den Benutzerstatus
|
||||
// Hinweis: Wir können den oobCode nicht serverseitig validieren.
|
||||
// Wir nehmen an, dass der oobCode korrekt ist, da er von Firebase generiert wurde.
|
||||
// Step 2: Update the user status to set emailVerified to true
|
||||
await this.firebaseAdmin.auth().updateUser(userRecord.uid, {
|
||||
emailVerified: true,
|
||||
});
|
||||
|
||||
return { message: 'Email successfully verified' };
|
||||
// Step 3: Generate a custom Firebase token for the user
|
||||
// This token can be used on the client side to authenticate with Firebase
|
||||
const customToken = await this.firebaseAdmin.auth().createCustomToken(userRecord.uid);
|
||||
|
||||
return {
|
||||
message: 'Email successfully verified',
|
||||
token: customToken,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new HttpException(error.message || 'Failed to verify email', HttpStatus.BAD_REQUEST);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,35 @@
|
|||
<div class="container mx-auto p-4 text-center min-h-screen bg-gray-100">
|
||||
<div class="container mx-auto py-8 px-4 max-w-md">
|
||||
<div class="bg-white p-6 rounded-lg shadow-md text-center">
|
||||
<!-- Loading state -->
|
||||
<ng-container *ngIf="verificationStatus === 'pending'">
|
||||
<p class="text-lg text-gray-600">Verifying your email...</p>
|
||||
<div class="flex justify-center mb-4">
|
||||
<div class="w-10 h-10 border-4 border-blue-500 border-t-transparent rounded-full animate-spin"></div>
|
||||
</div>
|
||||
<p class="text-gray-700">Verifying your email address...</p>
|
||||
</ng-container>
|
||||
|
||||
<!-- Success state -->
|
||||
<ng-container *ngIf="verificationStatus === 'success'">
|
||||
<div class="flex justify-center mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-green-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-green-600 mb-5">Your email has been verified</h2>
|
||||
<!-- <p class="text-gray-700 mb-4">You can now sign in with your new account</p> -->
|
||||
<a routerLink="/account" class="inline-block px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors">Follow this link to access your Account Page </a>
|
||||
<p class="text-gray-700 mb-4">You will be redirected to your account page in 5 seconds</p>
|
||||
<a routerLink="/account" class="inline-block px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"> Go to Account Page Now </a>
|
||||
</ng-container>
|
||||
|
||||
<!-- Error state -->
|
||||
<ng-container *ngIf="verificationStatus === 'error'">
|
||||
<h2 class="text-2xl font-bold text-red-600 mb-2">Verification failed</h2>
|
||||
<p class="text-gray-700">{{ errorMessage }}</p>
|
||||
<div class="flex justify-center mb-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-red-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-red-600 mb-3">Verification Failed</h2>
|
||||
<p class="text-gray-700 mb-4">{{ errorMessage }}</p>
|
||||
<a routerLink="/login" class="inline-block px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"> Return to Login </a>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { CommonModule } from '@angular/common';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute, RouterModule } from '@angular/router';
|
||||
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { AuthService } from '../../services/auth.service';
|
||||
import { UserService } from '../../services/user.service';
|
||||
|
|
@ -16,7 +16,7 @@ export class EmailAuthorizedComponent implements OnInit {
|
|||
verificationStatus: 'pending' | 'success' | 'error' = 'pending';
|
||||
errorMessage: string | null = null;
|
||||
|
||||
constructor(private route: ActivatedRoute, private http: HttpClient, private authService: AuthService, private userService: UserService) {}
|
||||
constructor(private route: ActivatedRoute, private router: Router, private http: HttpClient, private authService: AuthService, private userService: UserService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
const oobCode = this.route.snapshot.queryParamMap.get('oobCode');
|
||||
|
|
@ -32,12 +32,32 @@ export class EmailAuthorizedComponent implements OnInit {
|
|||
}
|
||||
|
||||
private verifyEmail(oobCode: string, email: string): void {
|
||||
this.http.post(`${environment.apiBaseUrl}/bizmatch/auth/verify-email`, { oobCode, email }).subscribe({
|
||||
next: async () => {
|
||||
this.http.post<{ message: string; token: string }>(`${environment.apiBaseUrl}/bizmatch/auth/verify-email`, { oobCode, email }).subscribe({
|
||||
next: async response => {
|
||||
this.verificationStatus = 'success';
|
||||
//await this.authService.refreshToken();
|
||||
await this.authService.refreshUserClaims();
|
||||
|
||||
try {
|
||||
// Use the custom token from the server to sign in with Firebase
|
||||
await this.authService.signInWithCustomToken(response.token);
|
||||
|
||||
// Try to get user info
|
||||
try {
|
||||
const user = await this.userService.getByMail(email);
|
||||
console.log('User retrieved:', user);
|
||||
} catch (userError) {
|
||||
console.error('Error getting user:', userError);
|
||||
// Don't change verification status - it's still a success
|
||||
}
|
||||
|
||||
// Redirect to dashboard after a short delay
|
||||
setTimeout(() => {
|
||||
this.router.navigate(['/account']);
|
||||
}, 5000);
|
||||
} catch (authError) {
|
||||
console.error('Error signing in with custom token:', authError);
|
||||
// Keep success status for verification, but add warning about login
|
||||
this.errorMessage = 'Email verified, but there was an issue signing you in. Please try logging in manually.';
|
||||
}
|
||||
},
|
||||
error: err => {
|
||||
this.verificationStatus = 'error';
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
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, signInWithEmailAndPassword, signInWithPopup } from 'firebase/auth';
|
||||
import { GoogleAuthProvider, UserCredential, createUserWithEmailAndPassword, getAuth, signInWithCustomToken, signInWithEmailAndPassword, signInWithPopup } from 'firebase/auth';
|
||||
import { BehaviorSubject, Observable, catchError, firstValueFrom, map, of, shareReplay, take, tap } from 'rxjs';
|
||||
import { environment } from '../../environments/environment';
|
||||
import { MailService } from './mail.service';
|
||||
|
|
@ -274,4 +274,31 @@ export class AuthService {
|
|||
return await this.refreshToken();
|
||||
}
|
||||
}
|
||||
|
||||
// Add this new method to sign in with a custom token
|
||||
async signInWithCustomToken(token: string): Promise<void> {
|
||||
try {
|
||||
// Sign in to Firebase with the custom token
|
||||
const userCredential = await signInWithCustomToken(this.auth, token);
|
||||
|
||||
// Store the authentication token
|
||||
if (userCredential.user) {
|
||||
const idToken = await userCredential.user.getIdToken();
|
||||
localStorage.setItem('authToken', idToken);
|
||||
localStorage.setItem('refreshToken', userCredential.user.refreshToken);
|
||||
|
||||
if (userCredential.user.photoURL) {
|
||||
localStorage.setItem('photoURL', userCredential.user.photoURL);
|
||||
}
|
||||
|
||||
// Load user role from the token
|
||||
this.loadRoleFromToken();
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (error) {
|
||||
console.error('Error signing in with custom token:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue