openvidu/frontend/projects/shared-meet-components/src/lib/guards/replace-moderator-secret.guard.ts

74 lines
2.7 KiB
TypeScript

import { inject } from '@angular/core';
import { Location } from '@angular/common';
import { CanActivateFn, NavigationEnd } from '@angular/router';
import { Router } from '@angular/router';
import { ContextService, HttpService, SessionStorageService } from '../services';
import { filter, take } from 'rxjs';
/**
* Guard that replaces the moderator secret in the URL with the publisher secret.
*
* This guard checks if the current participant is a moderator. If so, it retrieves the moderator and publisher secrets
* for the current room and updates the session storage with the moderator secret. It then replaces the secret in the URL
* with the publisher secret.
*
* @param route - The activated route snapshot.
* @param state - The router state snapshot.
* @returns A promise that resolves to `true` if the operation is successful, otherwise `false`.
*
* @throws Will log an error and return `false` if an error occurs during the process.
*/
export const replaceModeratorSecretGuard: CanActivateFn = (route, _state) => {
const httpService = inject(HttpService);
const contextService = inject(ContextService);
const router = inject(Router);
const location: Location = inject(Location);
const sessionStorageService = inject(SessionStorageService);
try {
router.events
.pipe(
filter((event) => event instanceof NavigationEnd),
take(1)
)
.subscribe(async () => {
if (contextService.isModeratorParticipant()) {
const roomId = contextService.getRoomId();
const { moderatorSecret, publisherSecret } = await getUrlSecret(httpService, roomId);
sessionStorageService.setModeratorSecret(roomId, moderatorSecret);
// Replace secret in URL by the publisher secret
const queryParams = { ...route.queryParams, secret: publisherSecret };
const urlTree = router.createUrlTree([], { queryParams, queryParamsHandling: 'merge' });
const newUrl = router.serializeUrl(urlTree);
location.replaceState(newUrl);
}
});
return true;
} catch (error) {
console.error('error', error);
return false;
}
};
const getUrlSecret = async (
httpService: HttpService,
roomId: string
): Promise<{ moderatorSecret: string; publisherSecret: string }> => {
const { moderatorRoomUrl, publisherRoomUrl } = await httpService.getRoom(roomId);
const extractSecret = (urlString: string, type: string): string => {
const url = new URL(urlString);
const secret = url.searchParams.get('secret');
if (!secret) throw new Error(`${type} secret not found`);
return secret;
};
const publisherSecret = extractSecret(publisherRoomUrl, 'Publisher');
const moderatorSecret = extractSecret(moderatorRoomUrl, 'Moderator');
return { publisherSecret, moderatorSecret };
};