From fd675573fc33dba142c122902d9ff52bf3a24457 Mon Sep 17 00:00:00 2001 From: juancarmore Date: Tue, 10 Feb 2026 11:17:13 +0100 Subject: [PATCH] frontend: update meeting URL handling to use access URL and improve error handling in lobby service --- .../services/meeting-context.service.ts | 17 +++++------ .../meeting/services/meeting-lobby.service.ts | 29 +++++++++++++++---- .../meeting/services/meeting.service.ts | 5 ++-- .../src/lib/domains/rooms/models/index.ts | 1 + .../room-wizard/room-wizard.component.ts | 8 ++--- 5 files changed, 40 insertions(+), 20 deletions(-) diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-context.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-context.service.ts index 7d1cd922..e6f78ec3 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-context.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-context.service.ts @@ -133,7 +133,7 @@ export class MeetingContextService { setMeetRoom(room: MeetRoom): void { this._meetRoom.set(room); this.setRoomId(room.roomId); - this.setMeetingUrl(room.roomId); + this.setMeetingUrl(room.accessUrl); } /** @@ -163,15 +163,13 @@ export class MeetingContextService { } /** - * Updates the meeting URL based on room ID - * @param roomId The room ID + * Updates the meeting URL based on room access URL + * @param accessUrl The room access URL */ - private setMeetingUrl(roomId: string): void { - const hostname = window.location.origin.replace('http://', '').replace('https://', ''); - const basePath = this.appConfigService.basePath; - // Remove trailing slash from base path for URL construction - const basePathForUrl = basePath.endsWith('/') ? basePath.slice(0, -1) : basePath; - const meetingUrl = roomId ? `${hostname}${basePathForUrl}/room/${roomId}` : ''; + private setMeetingUrl(accessUrl: string): void { + // Construct the meeting URL using the access URL without the protocol + const url = new URL(accessUrl); + const meetingUrl = `${url.host}${url.pathname}`; this._meetingUrl.set(meetingUrl); } @@ -180,6 +178,7 @@ export class MeetingContextService { * @param key The E2EE key */ setE2eeKey(key: string): void { + this.sessionStorageService.setE2EEKey(key); this._e2eeKey.set(key); } diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts index ef063081..d634f5b1 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting-lobby.service.ts @@ -148,7 +148,7 @@ export class MeetingLobbyService { const [room] = await Promise.all([ this.roomService.getRoom(roomId, { - fields: ['roomName', 'status', 'config'], + fields: ['roomName', 'status', 'config', 'accessUrl'], expand: ['config'] }), this.setBackButtonText(), @@ -353,7 +353,7 @@ export class MeetingLobbyService { const roomMemberToken = await this.roomMemberService.generateToken( roomId!, { - secret: roomSecret!, + secret: roomSecret, joinMeeting: true, participantName: this.participantName() }, @@ -363,15 +363,34 @@ export class MeetingLobbyService { this.setParticipantName(updatedName); this._state.update((state) => ({ ...state, roomMemberToken })); } catch (error: any) { - this.log.e('Error generating room member token:', error); + this.log.e('Error generating room member token for joining meeting:', error); + const message = error?.error?.message || error.message || 'Unknown error'; switch (error.status) { case 400: // Invalid secret await this.navigationService.redirectToErrorPage(NavigationErrorReason.INVALID_ROOM_SECRET, true); break; + case 403: + // Insufficient permissions or anonymous access disabled + if (message.includes('Anonymous access')) { + await this.navigationService.redirectToErrorPage( + NavigationErrorReason.ANONYMOUS_ACCESS_DISABLED, + true + ); + } else { + await this.navigationService.redirectToErrorPage( + NavigationErrorReason.FORBIDDEN_ROOM_ACCESS, + true + ); + } + break; case 404: - // Room not found - await this.navigationService.redirectToErrorPage(NavigationErrorReason.INVALID_ROOM, true); + // Room or member not found + if (message.includes('Room member')) { + await this.navigationService.redirectToErrorPage(NavigationErrorReason.INVALID_MEMBER, true); + } else { + await this.navigationService.redirectToErrorPage(NavigationErrorReason.INVALID_ROOM, true); + } break; case 409: // Room is closed diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting.service.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting.service.ts index 260c9134..0b374003 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting.service.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/meeting/services/meeting.service.ts @@ -21,8 +21,9 @@ export class MeetingService { /** * Copies the meeting speaker link to the clipboard. */ - copyMeetingSpeakerLink({ accessUrl }: MeetRoom): void { - this.clipboard.copy(accessUrl); + copyMeetingSpeakerLink(room: MeetRoom): void { + const speakerLink = room.anonymous.speaker.accessUrl; + this.clipboard.copy(speakerLink); this.notificationService.showSnackbar('Speaker link copied to clipboard'); } diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/index.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/index.ts index 55e362d1..7096a67e 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/index.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/models/index.ts @@ -1 +1,2 @@ +export * from './room-request'; export * from './wizard.model'; diff --git a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts index 69d44ca7..5ddadb78 100644 --- a/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts +++ b/meet-ce/frontend/projects/shared-meet-components/src/lib/domains/rooms/pages/room-wizard/room-wizard.component.ts @@ -136,9 +136,9 @@ export class RoomWizardComponent implements OnInit { // Create room with basic config including e2ee: false (default settings) const { accessUrl } = await this.roomService.createRoom({ roomName }, { fields: ['accessUrl'] }); - // Extract the path and query parameters from the moderator URL and navigate to it + // Extract the path from the access URL and navigate to it const url = new URL(accessUrl); - const pathWithParams = url.pathname + url.search + url.hash; + const pathWithParams = url.pathname; await this.navigationService.redirectTo(pathWithParams); } catch (error) { const errorMessage = `Failed to create room ${roomName}`; @@ -167,9 +167,9 @@ export class RoomWizardComponent implements OnInit { // Create new room const { accessUrl } = await this.roomService.createRoom(roomOptions, { fields: ['accessUrl'] }); - // Extract the path and query parameters from the moderator URL and navigate to it + // Extract the path from the access URL and navigate to it const url = new URL(accessUrl); - const pathWithParams = url.pathname + url.search + url.hash; + const pathWithParams = url.pathname; await this.navigationService.redirectTo(pathWithParams); } } catch (error) {