import { inject } from '@angular/core'; import { ActivatedRouteSnapshot, Router, RouterStateSnapshot, CanActivateFn, UrlTree, RedirectCommand } from '@angular/router'; import { ContextService, HttpService, SessionStorageService } from '../services'; /** * Guard to validate the access to a room. */ export const validateRoomAccessGuard: CanActivateFn = async ( _route: ActivatedRouteSnapshot, state: RouterStateSnapshot ) => { const httpService = inject(HttpService); const contextService = inject(ContextService); const router = inject(Router); const sessionStorageService = inject(SessionStorageService); const roomId = contextService.getRoomId(); const participantName = contextService.getParticipantName(); const secret = contextService.getSecret(); const storageSecret = sessionStorageService.getModeratorSecret(roomId); try { // Generate a participant token const response = await httpService.generateParticipantToken({ roomId, participantName, secret: storageSecret || secret }); contextService.setParticipantToken(response.token); return true; } catch (error: any) { console.error('Error generating participant token:', error); switch (error.status) { case 400: // Invalid secret return redirectToErrorPage(router, 'invalid-secret'); case 404: // Room not found return redirectToErrorPage(router, 'invalid-room'); case 409: // Participant already exists. // Send a timestamp to force update the query params and show the error message in participant name input form const participantNameRoute = router.createUrlTree([`room/${roomId}/participant-name`], { queryParams: { originUrl: state.url, accessError: 'participant-exists', t: Date.now() } }); return new RedirectCommand(participantNameRoute, { skipLocationChange: true }); default: return redirectToErrorPage(router, 'internal-error'); } } }; const redirectToErrorPage = (router: Router, reason: string): UrlTree => { return router.createUrlTree(['error'], { queryParams: { reason } }); };