diff --git a/apps/lfx-pcc/src/app/modules/meeting/meeting.component.html b/apps/lfx-pcc/src/app/modules/meeting/meeting.component.html index 0906ed82..ab835bcf 100644 --- a/apps/lfx-pcc/src/app/modules/meeting/meeting.component.html +++ b/apps/lfx-pcc/src/app/modules/meeting/meeting.component.html @@ -178,9 +178,7 @@

{{ user.name }}

Ready to join as {{ user.name }} - Join Meeting +
@@ -261,9 +259,7 @@

Enter your information

Meeting invites and updates will be sent to your email

- Join Meeting +
diff --git a/apps/lfx-pcc/src/app/modules/meeting/meeting.component.ts b/apps/lfx-pcc/src/app/modules/meeting/meeting.component.ts index e6ea52d4..687860df 100644 --- a/apps/lfx-pcc/src/app/modules/meeting/meeting.component.ts +++ b/apps/lfx-pcc/src/app/modules/meeting/meeting.component.ts @@ -154,7 +154,7 @@ export class MeetingComponent { private initializeReturnTo(): Signal { return computed(() => { - return `${environment.urls.home}/meeting/${this.meeting().uid}`; + return `${environment.urls.home}/meetings/${this.meeting().uid}`; }); } } diff --git a/apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-committee-modal/meeting-committee-modal.component.ts b/apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-committee-modal/meeting-committee-modal.component.ts index cf825302..c4950f87 100644 --- a/apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-committee-modal/meeting-committee-modal.component.ts +++ b/apps/lfx-pcc/src/app/modules/project/meetings/components/meeting-committee-modal/meeting-committee-modal.component.ts @@ -166,7 +166,7 @@ export class MeetingCommitteeModalComponent { // If no changes, just close const currentIds = this.meeting.committees?.map((c) => c.uid) || []; - const currentVotingStatuses = this.meeting.committees?.map((c) => c.allowed_voting_statuses) || []; + const currentVotingStatuses = this.meeting.committees?.flatMap((c) => c.allowed_voting_statuses || []) || []; if ( JSON.stringify(selectedIds.sort()) === JSON.stringify(currentIds.sort()) && JSON.stringify(selectedVotingStatuses.sort()) === JSON.stringify(currentVotingStatuses.sort()) diff --git a/apps/lfx-pcc/src/server/controllers/meeting.controller.ts b/apps/lfx-pcc/src/server/controllers/meeting.controller.ts index 84dadb43..1dd92034 100644 --- a/apps/lfx-pcc/src/server/controllers/meeting.controller.ts +++ b/apps/lfx-pcc/src/server/controllers/meeting.controller.ts @@ -38,11 +38,10 @@ export class MeetingController { const counts = await Promise.all( meetings.map(async (m) => { const registrants = await this.meetingService.getMeetingRegistrants(req, m.uid); - const directRegistrants = registrants.filter((r) => r.type === 'direct').length ?? 0; const committeeMembers = registrants.filter((r) => r.type === 'committee').length ?? 0; return { - individual_registrants_count: directRegistrants, + individual_registrants_count: registrants.length - committeeMembers, committee_members_count: committeeMembers, }; }) @@ -101,10 +100,9 @@ export class MeetingController { // TODO: Remove this once we have a way to get the registrants count try { const registrants = await this.meetingService.getMeetingRegistrants(req, meeting.uid); - const directRegistrants = registrants.filter((r) => r.type === 'direct').length ?? 0; const committeeMembers = registrants.filter((r) => r.type === 'committee').length ?? 0; - meeting.individual_registrants_count = directRegistrants; + meeting.individual_registrants_count = registrants.length - committeeMembers; meeting.committee_members_count = committeeMembers; } catch (error) { // Log the error diff --git a/apps/lfx-pcc/src/server/services/access-check.service.ts b/apps/lfx-pcc/src/server/services/access-check.service.ts index 3c2ee321..c34e8e24 100644 --- a/apps/lfx-pcc/src/server/services/access-check.service.ts +++ b/apps/lfx-pcc/src/server/services/access-check.service.ts @@ -85,7 +85,7 @@ export class AccessCheckService { userAccessInfo.push({ resourceId: resource.id, username, hasAccess }); } - req.log.info( + req.log.debug( Logger.sanitize({ operation: 'check_access', request_count: resources.length, diff --git a/apps/lfx-pcc/src/server/services/meeting.service.ts b/apps/lfx-pcc/src/server/services/meeting.service.ts index 64f24049..391772f5 100644 --- a/apps/lfx-pcc/src/server/services/meeting.service.ts +++ b/apps/lfx-pcc/src/server/services/meeting.service.ts @@ -387,11 +387,16 @@ export class MeetingService { // Get each committee const committees = await Promise.all( uniqueCommitteeUids.map(async (uid) => { - const committee = await this.committeeService.getCommitteeById(req, uid); - return { - uid: committee.uid, - name: committee.name, - }; + try { + const committee = await this.committeeService.getCommitteeById(req, uid); + return { uid: committee.uid, name: committee.name }; + } catch (error) { + req.log.warn( + { operation: 'get_meeting_committees', committee_uid: uid, error: error instanceof Error ? error.message : String(error) }, + 'Committee enrichment failed; continuing without name' + ); + return { uid, name: undefined }; + } }) ); diff --git a/docs/architecture/backend/public-meetings.md b/docs/architecture/backend/public-meetings.md index c88c29f0..da307941 100644 --- a/docs/architecture/backend/public-meetings.md +++ b/docs/architecture/backend/public-meetings.md @@ -76,7 +76,7 @@ The meeting routes are configured to allow public access: ```typescript // apps/lfx-pcc/src/app/app.routes.ts { - path: 'meeting/:id', + path: 'meetings/:id', loadComponent: () => import('./modules/meetings/meeting.component').then(m => m.MeetingComponent), } ``` @@ -119,7 +119,7 @@ The protected routes middleware allows public meeting routes to bypass authentic **Location**: `apps/lfx-pcc/src/server/middleware/protected-routes.middleware.ts` -- Uses an explicit allowlist for prefixes: `/public/api/meetings` (API) and SPA route `/meeting/:id` +- Uses an explicit allowlist for prefixes: `/public/api/meetings` (API) and SPA route `/meetings/:id` - Bypasses only user–session auth for those allowlisted routes; server-to-server (M2M) calls still require auth - Applies standard authentication to all other routes (avoid loose regexes like `/meeting.*`) - Add unit tests verifying that only those exact prefixes bypass auth and that all similar prefixes remain protected