webcomponent: Added missing and necessary js file Update .gitignore to specify backend public directory exclusion webcomponent: Add error handling for invalid base URL in OpenViduMeet component webcomponent: Update Jest configuration for improved testing setup webcomponent: Enhance iframe attribute tests and add support for optional query parameters webcomponent: Refactor documentation copying in build_webcomponent_doc function for improved readability and add absolute path resolution Add E2EE_KEY property to WebComponentProperty enum for end-to-end encryption support meet.sh: Enhance build_rest_api_doc function with output file handling and user confirmation for overwriting frontend: replace removeRoomSecretGuard with removeQueryParamsGuard for enhanced query parameter management frontend: add E2EE key handling in room service and update query params guard Updated pnpm-lock.yaml Enables end-to-end encryption (E2EE) Adds E2EE functionality to meeting rooms. Significant changes: - Allows encryption of the participant name - Introduces setting and getting E2EE keys - Ensures recording is disabled when encryption is enabled webcomponent: Added e2e test for checking the e2ee funcionality frontend: Sanitize participant name before request for a token fix: clean up formatting in openvidu-meet.code-workspace
142 lines
4.4 KiB
TypeScript
142 lines
4.4 KiB
TypeScript
import { inject } from '@angular/core';
|
|
import { ActivatedRouteSnapshot, CanActivateFn } from '@angular/router';
|
|
import { ErrorReason } from '../models';
|
|
import { AppDataService, NavigationService, ParticipantService, RoomService, SessionStorageService } from '../services';
|
|
import { WebComponentProperty } from '@openvidu-meet/typings';
|
|
|
|
export const extractRoomQueryParamsGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => {
|
|
const navigationService = inject(NavigationService);
|
|
const roomService = inject(RoomService);
|
|
const participantService = inject(ParticipantService);
|
|
const sessionStorageService = inject(SessionStorageService);
|
|
|
|
const {
|
|
roomId,
|
|
secret: querySecret,
|
|
participantName,
|
|
leaveRedirectUrl,
|
|
showOnlyRecordings,
|
|
e2eeKey
|
|
} = extractParams(route);
|
|
const secret = querySecret || sessionStorageService.getRoomSecret();
|
|
|
|
// Handle leave redirect URL logic
|
|
handleLeaveRedirectUrl(leaveRedirectUrl);
|
|
|
|
if (!secret) {
|
|
// If no secret is provided, redirect to the error page
|
|
return navigationService.redirectToErrorPage(ErrorReason.MISSING_ROOM_SECRET);
|
|
}
|
|
|
|
roomService.setRoomId(roomId);
|
|
roomService.setRoomSecret(secret);
|
|
roomService.setE2EEKey(e2eeKey);
|
|
|
|
if (participantName) {
|
|
participantService.setParticipantName(participantName);
|
|
}
|
|
|
|
if (showOnlyRecordings === 'true') {
|
|
// Redirect to the room recordings page
|
|
return navigationService.createRedirectionTo(`room/${roomId}/recordings`, { secret });
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
export const extractRecordingQueryParamsGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => {
|
|
const navigationService = inject(NavigationService);
|
|
const roomService = inject(RoomService);
|
|
const sessionStorageService = inject(SessionStorageService);
|
|
|
|
const { roomId, secret: querySecret } = extractParams(route);
|
|
const secret = querySecret || sessionStorageService.getRoomSecret();
|
|
|
|
if (!secret) {
|
|
// If no secret is provided, redirect to the error page
|
|
return navigationService.redirectToErrorPage(ErrorReason.MISSING_ROOM_SECRET);
|
|
}
|
|
|
|
roomService.setRoomId(roomId);
|
|
roomService.setRoomSecret(secret);
|
|
|
|
return true;
|
|
};
|
|
|
|
const extractParams = ({ params, queryParams }: ActivatedRouteSnapshot) => ({
|
|
roomId: params['room-id'] as string,
|
|
secret: queryParams['secret'] as string,
|
|
participantName: queryParams[WebComponentProperty.PARTICIPANT_NAME] as string,
|
|
leaveRedirectUrl: queryParams[WebComponentProperty.LEAVE_REDIRECT_URL] as string,
|
|
showOnlyRecordings: (queryParams[WebComponentProperty.SHOW_ONLY_RECORDINGS] as string) || 'false',
|
|
e2eeKey: queryParams[WebComponentProperty.E2EE_KEY] as string
|
|
});
|
|
|
|
/**
|
|
* Handles the leave redirect URL logic with automatic referrer detection
|
|
*/
|
|
const handleLeaveRedirectUrl = (leaveRedirectUrl: string | undefined) => {
|
|
const navigationService = inject(NavigationService);
|
|
const appDataService = inject(AppDataService);
|
|
const isEmbeddedMode = appDataService.isEmbeddedMode();
|
|
|
|
// Explicit valid URL provided - use as is
|
|
if (leaveRedirectUrl && isValidUrl(leaveRedirectUrl)) {
|
|
navigationService.setLeaveRedirectUrl(leaveRedirectUrl);
|
|
return;
|
|
}
|
|
|
|
// Absolute path provided in embedded mode - construct full URL based on parent origin
|
|
if (isEmbeddedMode && leaveRedirectUrl?.startsWith('/')) {
|
|
const parentUrl = document.referrer;
|
|
const parentOrigin = new URL(parentUrl).origin;
|
|
navigationService.setLeaveRedirectUrl(parentOrigin + leaveRedirectUrl);
|
|
return;
|
|
}
|
|
|
|
// Auto-detect from referrer (only if no explicit URL provided and not embedded)
|
|
if (!leaveRedirectUrl && !isEmbeddedMode) {
|
|
const autoRedirectUrl = getAutoRedirectUrl();
|
|
if (autoRedirectUrl) {
|
|
navigationService.setLeaveRedirectUrl(autoRedirectUrl);
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Automatically detects if user came from another domain and returns appropriate redirect URL
|
|
*/
|
|
const getAutoRedirectUrl = (): string | null => {
|
|
try {
|
|
const referrer = document.referrer;
|
|
|
|
// No referrer means user typed URL directly or came from bookmark
|
|
if (!referrer) {
|
|
return null;
|
|
}
|
|
|
|
const referrerUrl = new URL(referrer);
|
|
const currentUrl = new URL(window.location.href);
|
|
|
|
// Check if referrer is from a different domain
|
|
if (referrerUrl.origin !== currentUrl.origin) {
|
|
console.log(`Auto-configuring leave redirect to referrer: ${referrer}`);
|
|
return referrer;
|
|
}
|
|
|
|
return null;
|
|
} catch (error) {
|
|
console.warn('Error detecting auto redirect URL:', error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const isValidUrl = (url: string) => {
|
|
try {
|
|
new URL(url);
|
|
return true;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
};
|