frontend: simplify authentication guards, and refactor logout and getUserRoles method in AuthService and associated code

This commit is contained in:
juancarmore 2025-05-31 00:18:08 +02:00
parent 1a94a24329
commit 56f0f05d5f
4 changed files with 20 additions and 42 deletions

View File

@ -12,38 +12,18 @@ import { AuthService, ContextService, HttpService, SessionStorageService } from
export const checkUserAuthenticatedGuard: CanActivateFn = async ( export const checkUserAuthenticatedGuard: CanActivateFn = async (
route: ActivatedRouteSnapshot, route: ActivatedRouteSnapshot,
_state: RouterStateSnapshot state: RouterStateSnapshot
) => { ) => {
const authService = inject(AuthService); const authService = inject(AuthService);
const router = inject(Router); const router = inject(Router);
// Check if the route allows skipping authentication
const { checkSkipAuth } = route.data;
if (checkSkipAuth) {
const contextService = inject(ContextService);
const isAuthRequired = await contextService.isAuthRequiredToCreateRooms();
if (!isAuthRequired) {
return true;
}
}
// Check if user is authenticated // Check if user is authenticated
const isAuthenticated = await authService.isUserAuthenticated(); const isAuthenticated = await authService.isUserAuthenticated();
if (!isAuthenticated) { if (!isAuthenticated) {
// Redirect to the login page specified in the route data when user is not authenticated // Redirect to the login page
const { redirectToWhenUnauthorized } = route.data; return router.createUrlTree(['login'], {
return router.createUrlTree([redirectToWhenUnauthorized]); queryParams: { redirectTo: state.url }
} });
// Check if the user has the expected roles
const { expectedRoles } = route.data;
const userRole = await authService.getUserRole();
if (!expectedRoles.includes(userRole)) {
// Redirect to the page specified in the route data when user has an invalid role
const { redirectToWhenInvalidRole } = route.data;
return router.createUrlTree([redirectToWhenInvalidRole]);
} }
// Allow access to the requested page // Allow access to the requested page
@ -85,7 +65,7 @@ export const checkParticipantRoleAndAuthGuard: CanActivateFn = async (
} }
} }
const authMode = await contextService.getAuthModeToEnterRoom(); const authMode = await contextService.getAuthModeToAccessRoom();
// If the user is a moderator and the room requires authentication for moderators only, // If the user is a moderator and the room requires authentication for moderators only,
// or if the room requires authentication for all users, // or if the room requires authentication for all users,
@ -122,9 +102,8 @@ export const checkUserNotAuthenticatedGuard: CanActivateFn = async (
// Check if user is not authenticated // Check if user is not authenticated
const isAuthenticated = await authService.isUserAuthenticated(); const isAuthenticated = await authService.isUserAuthenticated();
if (isAuthenticated) { if (isAuthenticated) {
// Redirect to the page specified in the route data // Redirect to the console page
const { redirectTo } = route.data; return router.createUrlTree(['console']);
return router.createUrlTree([redirectTo]);
} }
// Allow access to the requested page // Allow access to the requested page

View File

@ -25,15 +25,14 @@ export const httpInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, ne
console.log('Access token refreshed'); console.log('Access token refreshed');
return next(req); return next(req);
}), }),
catchError((error: HttpErrorResponse) => { catchError(async (error: HttpErrorResponse) => {
if (error.url?.includes('/auth/refresh')) { if (error.url?.includes('/auth/refresh')) {
console.error('Error refreshing access token'); console.error('Error refreshing access token');
// If the original request was not to the profile endpoint, logout and redirect to the login page // If the original request was not to the profile endpoint, logout and redirect to the login page
if (!requestUrl.includes('/profile')) { if (!requestUrl.includes('/profile')) {
console.log('Logging out...'); console.log('Logging out...');
const redirectTo = pageUrl.startsWith('/console') ? 'console/login' : 'login'; await authService.logout(pageUrl);
authService.logout(redirectTo, pageUrl);
} }
throw firstError; throw firstError;

View File

@ -24,6 +24,6 @@ export class ConsoleComponent {
constructor(private authService: AuthService) {} constructor(private authService: AuthService) {}
async logout() { async logout() {
await this.authService.logout('console/login'); await this.authService.logout();
} }
} }

View File

@ -32,17 +32,17 @@ export class AuthService {
return from(this.httpService.refreshToken()); return from(this.httpService.refreshToken());
} }
async logout(redirectTo?: string, redirectToAfterLogin?: string) { async logout(redirectToAfterLogin?: string) {
try { try {
await this.httpService.logout(); await this.httpService.logout();
this.user = null; this.user = null;
if (redirectTo) { // Redirect to login page with a query parameter if provided
const queryParams = redirectToAfterLogin // to redirect to the original page after login
? { queryParams: { redirectTo: redirectToAfterLogin } } const queryParams = redirectToAfterLogin
: undefined; ? { queryParams: { redirectTo: redirectToAfterLogin } }
this.router.navigate([redirectTo], queryParams); : undefined;
} this.router.navigate(['login'], queryParams);
} catch (error) { } catch (error) {
console.error((error as HttpErrorResponse).error.message); console.error((error as HttpErrorResponse).error.message);
} }
@ -58,9 +58,9 @@ export class AuthService {
return this.user?.username; return this.user?.username;
} }
async getUserRole(): Promise<UserRole | undefined> { async getUserRoles(): Promise<UserRole[] | undefined> {
await this.getAuthenticatedUser(); await this.getAuthenticatedUser();
return this.user?.role; return this.user?.roles;
} }
private async getAuthenticatedUser(force = false) { private async getAuthenticatedUser(force = false) {