Skip to content

Commit 63ad762

Browse files
klagridaclaude
andcommitted
fix: wait for auth initialization in guards to prevent race condition
This fixes the race condition where guards check authentication before AuthService finishes loading the session, causing false redirects to login even when users are authenticated. Problem: - AuthService.initializeAuth() is async and called in constructor - Guards were checking isAuthenticated() immediately - If auth still loading, user is null → guard redirects to login - This caused all E2E tests to fail with timeouts and missing elements Solution: - Added waitForAuthReady() method in AuthService that waits for loading state to complete - Updated authGuard to await auth initialization before checking - Updated adminGuard to await auth initialization before checking - Uses efficient polling with 50ms intervals This ensures: 1. Guards always check auth status AFTER session is loaded 2. No false redirects to login for authenticated users 3. E2E tests can properly navigate protected routes 4. Admin panel routes accessible to admin users 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 168bac1 commit 63ad762

3 files changed

Lines changed: 28 additions & 1 deletion

File tree

frontend/src/app/guards/admin-guard.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ export const adminGuard: CanActivateFn = async (route, state) => {
66
const authService = inject(AuthService);
77
const router = inject(Router);
88

9+
// Wait for auth state to finish loading
10+
await authService.waitForAuthReady();
11+
912
// Check if user is authenticated
1013
if (!authService.isAuthenticated()) {
1114
return router.createUrlTree(['/login'], {

frontend/src/app/guards/auth-guard.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ import { inject } from '@angular/core';
22
import { CanActivateFn, Router } from '@angular/router';
33
import { AuthService } from '../services/auth.service';
44

5-
export const authGuard: CanActivateFn = (route, state) => {
5+
export const authGuard: CanActivateFn = async (route, state) => {
66
const authService = inject(AuthService);
77
const router = inject(Router);
88

9+
// Wait for auth state to finish loading
10+
await authService.waitForAuthReady();
11+
912
if (authService.isAuthenticated()) {
1013
return true;
1114
}

frontend/src/app/services/auth.service.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,27 @@ export class AuthService {
112112
return data;
113113
}
114114

115+
/**
116+
* Wait for auth initialization to complete
117+
* Returns a promise that resolves when auth state is loaded
118+
*/
119+
async waitForAuthReady(): Promise<void> {
120+
// If already loaded, return immediately
121+
if (!this.authState().loading) {
122+
return;
123+
}
124+
125+
// Wait for loading to complete
126+
return new Promise((resolve) => {
127+
const checkInterval = setInterval(() => {
128+
if (!this.authState().loading) {
129+
clearInterval(checkInterval);
130+
resolve();
131+
}
132+
}, 50);
133+
});
134+
}
135+
115136
/**
116137
* Check if user is authenticated
117138
*/

0 commit comments

Comments
 (0)