Skip to content

Commit a495c36

Browse files
fix(meetings): always fetch per-user join URL for public meetings (#617)
* fix(meetings): always fetch per-user join URL for public meetings The `public_link` field returned by ITX/query-service is the LFX landing-page URL used in calendar invites, not a direct Zoom join URL. Short-circuiting the join flow on `public_link` caused a cascade where clicking "Join" sent users to the LFX landing page, which then bounced them back into the join flow. Drop the `public_link` short-circuit in `dashboard-meeting-card` and `meeting-card`, and stop pre-fetching/returning it from `GET /public/api/meetings/:id`. `POST /public/api/meetings/:id/join-url` now always calls `meetingService.getMeetingJoinUrl` so each viewer gets their own per-user join link with the existing time-window, password, and restricted-meeting checks. Remove the now-unused `public_link` field from the shared `Meeting` interface and the orphan `handleJoinUrlForPublicMeeting` helper. Generated with Claude Signed-off-by: Audi Young <audi.mycloud@gmail.com> * refactor(meetings): drop bug-explanation comments Signed-off-by: Asitha de Silva <asithade@gmail.com> --------- Signed-off-by: Audi Young <audi.mycloud@gmail.com> Signed-off-by: Asitha de Silva <asithade@gmail.com> Co-authored-by: Asitha de Silva <asithade@gmail.com>
1 parent 67e1b20 commit a495c36

4 files changed

Lines changed: 0 additions & 57 deletions

File tree

apps/lfx-one/src/app/modules/dashboards/components/dashboard-meeting-card/dashboard-meeting-card.component.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ export class DashboardMeetingCardComponent {
9595
return of(null);
9696
}
9797

98-
if (meeting.public_link) {
99-
return of(meeting.public_link);
100-
}
101-
10298
if (authenticated && user?.email) {
10399
return this.meetingService.getPublicMeetingJoinUrl(meeting.id, meeting.password, { email: user.email }).pipe(
104100
map((res) => buildJoinUrlWithParams(res.link, user)),

apps/lfx-one/src/app/modules/meetings/components/meeting-card/meeting-card.component.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,6 @@ export class MeetingCardComponent implements OnInit {
202202
return of(null);
203203
}
204204

205-
// Use public_link directly if available (e.g. for legacy meetings with link from query service)
206-
if (meeting.public_link) {
207-
return of(meeting.public_link);
208-
}
209-
210-
// Otherwise fetch join URL from API for authenticated users
211205
if (authenticated && user?.email) {
212206
return this.meetingService.getPublicMeetingJoinUrl(meeting.id, meeting.password, { email: user.email }).pipe(
213207
map((res) => buildJoinUrlWithParams(res.link, user)),

apps/lfx-one/src/server/controllers/public-meeting.controller.ts

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -124,28 +124,14 @@ export class PublicMeetingController {
124124
// Log the success
125125
logger.success(req, 'get_public_meeting_by_id', startTime, { meeting_id: id, project_uid: meeting.project_uid, title: meeting.title });
126126

127-
// Check if the meeting visibility is public and not restricted, if so, get join URL and return the meeting and project
128127
if (meeting.visibility === MeetingVisibility.PUBLIC && !meeting.restricted) {
129-
// Only get join URL if within allowed join time window
130-
if (this.isWithinJoinWindow(meeting)) {
131-
// Fetch join URL if not already available from ITX data
132-
if (!meeting.public_link) {
133-
await this.handleJoinUrlForPublicMeeting(req, meeting, id);
134-
}
135-
} else {
136-
// Remove public link outside join window
137-
delete meeting.public_link;
138-
}
139128
res.json({
140129
meeting,
141130
project: { name: project.name, slug: project.slug, logo_url: project.logo_url, uid: project.uid, parent_uid: project.parent_uid },
142131
});
143132
return;
144133
}
145134

146-
// Remove public link for restricted/private meetings (will be provided after password validation)
147-
delete meeting.public_link;
148-
149135
// Check if the user has passed in a password, if so, check if it's correct
150136
const { password } = req.query;
151137
if (!this.validateMeetingPassword(password as string, meeting.password as string, 'get_public_meeting_by_id', req, next)) {
@@ -312,12 +298,6 @@ export class PublicMeetingController {
312298
await this.restrictedMeetingCheck(req, next, email, id);
313299
}
314300

315-
// Return public_link if available from ITX data, otherwise fetch from API
316-
if (meeting.public_link) {
317-
res.json({ link: meeting.public_link });
318-
return;
319-
}
320-
321301
const joinUrlData = await this.meetingService.getMeetingJoinUrl(req, id, email);
322302

323303
// Log the success
@@ -499,31 +479,6 @@ export class PublicMeetingController {
499479
return meeting;
500480
}
501481

502-
/**
503-
* Handles join URL logic for public meetings
504-
*/
505-
private async handleJoinUrlForPublicMeeting(req: Request, meeting: any, id: string): Promise<void> {
506-
const startTime = logger.startOperation(req, 'handle_link_for_public_meeting', {
507-
meeting_id: id,
508-
});
509-
510-
try {
511-
const joinUrlData = await this.meetingService.getMeetingJoinUrl(req, id);
512-
meeting.public_link = joinUrlData.link;
513-
514-
logger.success(req, 'handle_link_for_public_meeting', startTime, {
515-
meeting_id: id,
516-
has_link: !!joinUrlData.link,
517-
});
518-
} catch (error) {
519-
logger.warning(req, 'handle_link_for_public_meeting', 'Failed to fetch join URL, continuing without it', {
520-
meeting_id: id,
521-
has_token: !!req.bearerToken,
522-
err: error,
523-
});
524-
}
525-
}
526-
527482
/**
528483
* Checks if the current time is within the allowed join window for a meeting
529484
*/

packages/shared/src/interfaces/meeting.interface.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,6 @@ export interface Meeting {
210210
// Fields NOT in API - likely response-only
211211
/** Invited to meeting (response only) */
212212
invited: boolean;
213-
/** Meeting public link (join URL) */
214-
public_link?: string;
215213
/** Total registrant count from API */
216214
registrant_count?: number;
217215
/** Count fields (response only) — omitted when list endpoints skip per-meeting enrichment; callers must handle undefined. */

0 commit comments

Comments
 (0)