From a17b1afaa4f34814b3e125252c71e74a998bbe3d Mon Sep 17 00:00:00 2001 From: Mauricio Zanetti Salomao Date: Mon, 13 Oct 2025 11:25:56 -0300 Subject: [PATCH 1/3] feat(profile.controller): enhance authentication token handling and user metadata retrieval - Updated the profile controller to retrieve the authentication token from the request, improving error handling when the token is missing. - Adjusted the getUserInfo method to use the token for fetching user data from NATS, ensuring a more reliable user profile retrieval process. Jira Ticket: https://linuxfoundation.atlassian.net/browse/LFXV2-643 Generated with [Cursor](https://cursor.com/) Signed-off-by: Mauricio Zanetti Salomao --- .../src/server/controllers/profile.controller.ts | 16 +++++++++++++++- apps/lfx-one/src/server/server.ts | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/apps/lfx-one/src/server/controllers/profile.controller.ts b/apps/lfx-one/src/server/controllers/profile.controller.ts index ed8ca066..9b9502f8 100644 --- a/apps/lfx-one/src/server/controllers/profile.controller.ts +++ b/apps/lfx-one/src/server/controllers/profile.controller.ts @@ -46,12 +46,26 @@ export class ProfileController { return next(validationError); } + // Get the bearer token from the request (set by auth middleware) or OIDC access token + const token = req.bearerToken || req.oidc?.accessToken?.access_token; + if (!token) { + Logger.error(req, 'get_current_user_profile', startTime, new Error('No authentication token found')); + + const validationError = ServiceValidationError.forField('token', 'Authentication token required', { + operation: 'get_current_user_profile', + service: 'profile_controller', + path: req.path, + }); + + return next(validationError); + } + let combinedProfile: CombinedProfile | null = null; // Step 1: Try to get user metadata from NATS first (authoritative source) let natsUserData: UserMetadata | null = null; try { - const natsResponse = await this.userService.getUserInfo(req, userId); + const natsResponse = await this.userService.getUserInfo(req, token); req.log.info({ userId, natsSuccess: natsResponse.success }, 'Fetched user data from NATS'); if (natsResponse.success && natsResponse.data) { diff --git a/apps/lfx-one/src/server/server.ts b/apps/lfx-one/src/server/server.ts index 256776fa..1b229dd2 100644 --- a/apps/lfx-one/src/server/server.ts +++ b/apps/lfx-one/src/server/server.ts @@ -160,7 +160,7 @@ const authConfig: ConfigParams = { authorizationParams: { response_type: 'code', audience: process.env['PCC_AUTH0_AUDIENCE'] || 'https://example.com', - scope: 'openid email profile access:api offline_access', + scope: 'openid email profile access:api offline_access update:current_user_metadata read:current_user', }, clientSecret: process.env['PCC_AUTH0_CLIENT_SECRET'] || 'bar', routes: { From 5a9ae5f1c1e1e5f40a4ce04eea33e91d4026dd60 Mon Sep 17 00:00:00 2001 From: Mauricio Zanetti Salomao Date: Mon, 13 Oct 2025 12:33:48 -0300 Subject: [PATCH 2/3] fix(server): update Auth0 audience URL for authentication - Changed the audience parameter in the Auth0 configuration to point to the correct development URL for user authentication. Jira Ticket: https://linuxfoundation.atlassian.net/browse/LFXV2-643 Signed-off-by: Mauricio Zanetti Salomao --- apps/lfx-one/src/server/server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/lfx-one/src/server/server.ts b/apps/lfx-one/src/server/server.ts index 1b229dd2..a703276d 100644 --- a/apps/lfx-one/src/server/server.ts +++ b/apps/lfx-one/src/server/server.ts @@ -159,7 +159,7 @@ const authConfig: ConfigParams = { secret: process.env['PCC_AUTH0_SECRET'] || 'sufficiently-long-string', authorizationParams: { response_type: 'code', - audience: process.env['PCC_AUTH0_AUDIENCE'] || 'https://example.com', + audience: 'https://linuxfoundation-dev.auth0.com/api/v2/', scope: 'openid email profile access:api offline_access update:current_user_metadata read:current_user', }, clientSecret: process.env['PCC_AUTH0_CLIENT_SECRET'] || 'bar', From b5c6fde16a4d17d1ba0a5d99a7ecb0154392fe68 Mon Sep 17 00:00:00 2001 From: Mauricio Zanetti Salomao Date: Mon, 13 Oct 2025 14:07:36 -0300 Subject: [PATCH 3/3] feat(profile.controller): enhance user profile retrieval from Auth0 - Updated the profile controller to handle cases where a Supabase user is not found, returning minimal user data from Auth0 instead. - Improved logging to indicate when Auth0 user data is being returned. - Simplified the merging of user profile data by directly assigning the profile from Supabase or returning null if not available. Jira Ticket: https://linuxfoundation.atlassian.net/browse/LFXV2-643 Generated with [Cursor](https://cursor.com/) Signed-off-by: Mauricio Zanetti Salomao --- .../server/controllers/profile.controller.ts | 53 +++++++++++++------ 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/apps/lfx-one/src/server/controllers/profile.controller.ts b/apps/lfx-one/src/server/controllers/profile.controller.ts index 9b9502f8..9780a43f 100644 --- a/apps/lfx-one/src/server/controllers/profile.controller.ts +++ b/apps/lfx-one/src/server/controllers/profile.controller.ts @@ -86,13 +86,43 @@ export class ProfileController { const user = await this.supabaseService.getUser(userId); if (!user) { - const validationError = ServiceValidationError.forField('user_id', 'User profile not found', { - operation: 'get_current_user_profile', - service: 'profile_controller', - path: req.path, + // If no Supabase user, return Auth0 user data only (from NATS) + req.log.info({ userId }, 'No Supabase user found, returning Auth0 user data only'); + + const auth0User = natsUserData; + if (!auth0User) { + const validationError = ServiceValidationError.forField('user_id', 'User profile not found', { + operation: 'get_current_user_profile', + service: 'profile_controller', + path: req.path, + }); + return next(validationError); + } + + // Build minimal user from Auth0 data + const minimalUser = { + id: userId, + username: userId, + email: (auth0User as any).email || '', + first_name: (auth0User as any).given_name || '', + last_name: (auth0User as any).family_name || '', + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + }; + + combinedProfile = { + user: minimalUser, + profile: natsUserData || null, + }; + + Logger.success(req, 'get_current_user_profile', startTime, { + user_id: userId, + source: 'auth0_only', + has_nats_data: !!natsUserData, }); - return next(validationError); + res.json(combinedProfile); + return; } // Step 3: Merge NATS data into Supabase user if available @@ -108,18 +138,9 @@ export class ProfileController { profile: null, }; - // Step 4: Get profile details from Supabase + // Step 4: Get profile details from Supabase (optional) const profile = await this.supabaseService.getProfile(user.id); - - // If no profile details exist, create them - if (!profile) { - await this.supabaseService.createProfileIfNotExists(user.id); - // Refetch the combined profile with the newly created profile - const updatedProfile = await this.supabaseService.getProfile(user.id); - combinedProfile.profile = updatedProfile || null; - } else { - combinedProfile.profile = profile; - } + combinedProfile.profile = profile || null; // Step 5: Merge NATS metadata into profile if available if (natsUserData && combinedProfile.profile) {