frontend: Refactor guards to return UrlTree or RedirectCommand when needing to redirect to another route

This commit is contained in:
juancarmore 2025-03-27 19:28:29 +01:00
parent 72b8a9d12f
commit 23cdea5ca1
7 changed files with 38 additions and 32 deletions

View File

@ -3,7 +3,7 @@ import { ActivatedRouteSnapshot, CanActivateFn, RouterStateSnapshot } from '@ang
import { WebComponentManagerService, ContextService } from '../services';
import { ApplicationMode } from 'projects/shared-meet-components/src/public-api';
export const applicationModeGuard: CanActivateFn = async (
export const applicationModeGuard: CanActivateFn = (
_route: ActivatedRouteSnapshot,
_state: RouterStateSnapshot
) => {

View File

@ -1,7 +1,6 @@
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router';
import { AuthService } from '../services';
import { UserRole } from '@lib/typings/ce';
import { AuthService, ContextService } from '../services';
export const checkUserAuthenticatedGuard: CanActivateFn = async (
route: ActivatedRouteSnapshot,
@ -10,24 +9,33 @@ export const checkUserAuthenticatedGuard: CanActivateFn = async (
const authService = inject(AuthService);
const router = inject(Router);
// Check if admin is authenticated
// 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
const isAuthenticated = await authService.isUserAuthenticated();
if (!isAuthenticated) {
// Redirect to the login page specified in the route data when user is not authenticated
const { redirectToUnauthorized } = route.data;
router.navigate([redirectToUnauthorized]);
return false;
return router.createUrlTree([redirectToUnauthorized]);
}
// Check if the user has the expected roles
const { expectedRoles } = route.data;
const userRole = authService.isAdmin() ? UserRole.ADMIN : UserRole.USER;
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 { redirectToInvalidRole } = route.data;
router.navigate([redirectToInvalidRole]);
return false;
return router.createUrlTree([redirectToInvalidRole]);
}
// Allow access to the requested page
@ -46,8 +54,7 @@ export const checkUserNotAuthenticatedGuard: CanActivateFn = async (
if (isAuthenticated) {
// Redirect to the page specified in the route data
const { redirectTo } = route.data;
router.navigate([redirectTo]);
return false;
return router.createUrlTree([redirectTo]);
}
// Allow access to the requested page

View File

@ -1,9 +1,9 @@
import { inject } from '@angular/core';
import { CanActivateFn } from '@angular/router';
import { CanActivateFn, RedirectCommand } from '@angular/router';
import { Router } from '@angular/router';
import { ContextService } from '../services';
export const checkParticipantNameGuard: CanActivateFn = async (route, state) => {
export const checkParticipantNameGuard: CanActivateFn = (route, state) => {
const router = inject(Router);
const contextService = inject(ContextService);
const roomName = route.params['room-name'];
@ -12,8 +12,10 @@ export const checkParticipantNameGuard: CanActivateFn = async (route, state) =>
// Check if participant name exists in the service
if (!hasParticipantName) {
// Redirect to a page where the participant can input their participant name
return router.navigate([`room/${roomName}/participant-name`], {
queryParams: { originUrl: state.url, t: Date.now() },
const participantNameRoute = router.createUrlTree([`room/${roomName}/participant-name`], {
queryParams: { originUrl: state.url, t: Date.now() }
});
return new RedirectCommand(participantNameRoute, {
skipLocationChange: true
});
}

View File

@ -18,7 +18,7 @@ import { filter, take } from 'rxjs';
*
* @throws Will log an error and return `false` if an error occurs during the process.
*/
export const replaceModeratorSecretGuard: CanActivateFn = async (route, state) => {
export const replaceModeratorSecretGuard: CanActivateFn = (route, _state) => {
const httpService = inject(HttpService);
const contextService = inject(ContextService);
const router = inject(Router);

View File

@ -1,6 +1,6 @@
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from '@angular/router';
import { ContextService } from 'shared-meet-components';
import { ContextService } from '../services';
export const checkRoomCreatorEnabledGuard: CanActivateFn = async (
_route: ActivatedRouteSnapshot,
@ -11,8 +11,7 @@ export const checkRoomCreatorEnabledGuard: CanActivateFn = async (
const isRoomCreatorEnabled = await contextService.canUsersCreateRooms();
if (!isRoomCreatorEnabled) {
router.navigate(['room-creator-disabled']);
return false;
return router.createUrlTree(['room-creator-disabled']);
}
return true;

View File

@ -1,5 +1,5 @@
import { inject } from '@angular/core';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, CanActivateFn } from '@angular/router';
import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, CanActivateFn, UrlTree, RedirectCommand } from '@angular/router';
import { ContextService, HttpService, SessionStorageService } from '../services';
/**
@ -7,7 +7,7 @@ import { ContextService, HttpService, SessionStorageService } from '../services'
*/
export const validateRoomAccessGuard: CanActivateFn = async (
_route: ActivatedRouteSnapshot,
_state: RouterStateSnapshot
state: RouterStateSnapshot
) => {
const httpService = inject(HttpService);
const contextService = inject(ContextService);
@ -34,22 +34,20 @@ export const validateRoomAccessGuard: CanActivateFn = async (
case 409:
// Participant already exists.
// Send a timestamp to force update the query params and show the error message in participant name input form
await router.navigate([`${roomName}/participant-name`], {
queryParams: { originUrl: _state.url, accessError: 'participant-exists', t: Date.now() },
const participantNameRoute = router.createUrlTree([`room/${roomName}/participant-name`], {
queryParams: { originUrl: state.url, accessError: 'participant-exists', t: Date.now() }
});
return new RedirectCommand(participantNameRoute, {
skipLocationChange: true
});
break;
case 406:
await redirectToUnauthorized(router, 'unauthorized-participant');
break;
return redirectToUnauthorized(router, 'unauthorized-participant');
default:
await redirectToUnauthorized(router, 'invalid-room');
return redirectToUnauthorized(router, 'invalid-room');
}
return false;
}
};
const redirectToUnauthorized = async (router: Router, reason: string): Promise<boolean> => {
await router.navigate(['unauthorized'], { queryParams: { reason } });
return false;
const redirectToUnauthorized = (router: Router, reason: string): UrlTree => {
return router.createUrlTree(['unauthorized'], { queryParams: { reason } });
};

View File

@ -171,7 +171,7 @@ export class ContextService {
return this.context.globalPreferences!.securityPreferences.roomCreationPolicy.allowRoomCreation;
}
async requireAuthenticationForRoomCreation(): Promise<boolean> {
async isAuthRequiredToCreateRooms(): Promise<boolean> {
await this.getGlobalPreferences();
return this.context.globalPreferences!.securityPreferences.roomCreationPolicy.requireAuthentication;
}