diff --git a/lib/services/notifications/leantime-adapter.ts b/lib/services/notifications/leantime-adapter.ts index cd3f73a8..60cd1a29 100644 --- a/lib/services/notifications/leantime-adapter.ts +++ b/lib/services/notifications/leantime-adapter.ts @@ -1,5 +1,7 @@ import { Notification, NotificationCount } from '@/lib/types/notification'; import { NotificationAdapter } from './notification-adapter.interface'; +import { getServerSession } from 'next-auth'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; // Leantime notification type from their API interface LeantimeNotification { @@ -36,12 +38,12 @@ export class LeantimeAdapter implements NotificationAdapter { console.log(`[LEANTIME_ADAPTER] getNotifications called for userId: ${userId}, page: ${page}, limit: ${limit}`); try { - // First get the Leantime user ID from email - const email = await this.getUserEmail(userId); - console.log(`[LEANTIME_ADAPTER] Retrieved email for userId ${userId}:`, email || 'null'); + // Get the user's email directly from the session + const email = await this.getUserEmail(); + console.log(`[LEANTIME_ADAPTER] Retrieved email from session:`, email || 'null'); if (!email) { - console.error('[LEANTIME_ADAPTER] Could not get user email for userId:', userId); + console.error('[LEANTIME_ADAPTER] Could not get user email from session'); return []; } @@ -119,12 +121,12 @@ export class LeantimeAdapter implements NotificationAdapter { console.log(`[LEANTIME_ADAPTER] getNotificationCount called for userId: ${userId}`); try { - // First get the Leantime user ID from email - const email = await this.getUserEmail(userId); - console.log(`[LEANTIME_ADAPTER] Retrieved email for userId ${userId}:`, email || 'null'); + // Get the user's email directly from the session + const email = await this.getUserEmail(); + console.log(`[LEANTIME_ADAPTER] Retrieved email from session:`, email || 'null'); if (!email) { - console.error('[LEANTIME_ADAPTER] Could not get user email for userId:', userId); + console.error('[LEANTIME_ADAPTER] Could not get user email from session'); return this.getEmptyCount(); } @@ -227,30 +229,34 @@ export class LeantimeAdapter implements NotificationAdapter { }); if (!response.ok) { - console.error(`Failed to mark Leantime notification as read: ${response.status}`); + const errorText = await response.text(); + console.error('[LEANTIME_ADAPTER] Failed to mark Leantime notification as read:', { + status: response.status, + body: errorText.substring(0, 200) + (errorText.length > 200 ? '...' : '') + }); return false; } const data = await response.json(); return data.result === true; } catch (error) { - console.error('Error marking Leantime notification as read:', error); + console.error('[LEANTIME_ADAPTER] Error marking Leantime notification as read:', error); return false; } } async markAllAsRead(userId: string): Promise { try { - // First get the Leantime user ID from email - const email = await this.getUserEmail(userId); + // Get the user's email directly from the session + const email = await this.getUserEmail(); if (!email) { - console.error('Could not get user email for userId:', userId); + console.error('[LEANTIME_ADAPTER] Could not get user email from session'); return false; } const leantimeUserId = await this.getLeantimeUserId(email); if (!leantimeUserId) { - console.error('User not found in Leantime:', email); + console.error('[LEANTIME_ADAPTER] User not found in Leantime:', email); return false; } @@ -272,14 +278,18 @@ export class LeantimeAdapter implements NotificationAdapter { }); if (!response.ok) { - console.error(`Failed to mark all Leantime notifications as read: ${response.status}`); + const errorText = await response.text(); + console.error('[LEANTIME_ADAPTER] Failed to mark all Leantime notifications as read:', { + status: response.status, + body: errorText.substring(0, 200) + (errorText.length > 200 ? '...' : '') + }); return false; } const data = await response.json(); return data.result === true; } catch (error) { - console.error('Error marking all Leantime notifications as read:', error); + console.error('[LEANTIME_ADAPTER] Error marking all Leantime notifications as read:', error); return false; } } @@ -327,50 +337,21 @@ export class LeantimeAdapter implements NotificationAdapter { })); } - // Helper function to get user's email from ID (using existing method from your system) - private async getUserEmail(userId: string): Promise { - console.log(`[LEANTIME_ADAPTER] Getting email for userId: ${userId}`); + // Helper function to get user's email directly from the session + private async getUserEmail(): Promise { + console.log(`[LEANTIME_ADAPTER] Getting email from session`); try { - // Fetch from Keycloak similar to how other components do - const adminToken = await this.getAdminToken(); - console.log(`[LEANTIME_ADAPTER] Got admin token for Keycloak:`, adminToken ? 'token obtained' : 'failed to get token'); - - if (!adminToken) { - console.error('[LEANTIME_ADAPTER] Failed to get admin token for Keycloak'); + const session = await getServerSession(authOptions); + if (!session || !session.user?.email) { + console.error('[LEANTIME_ADAPTER] No session or email found'); return null; } - const keycloakUrl = `${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${userId}`; - console.log(`[LEANTIME_ADAPTER] Fetching user from Keycloak:`, keycloakUrl); - - const response = await fetch(keycloakUrl, { - headers: { - 'Authorization': `Bearer ${adminToken}` - } - }); - - console.log(`[LEANTIME_ADAPTER] Keycloak response status:`, response.status); - - if (!response.ok) { - const errorText = await response.text(); - console.error('[LEANTIME_ADAPTER] Failed to get user from Keycloak:', { - status: response.status, - body: errorText.substring(0, 200) + (errorText.length > 200 ? '...' : '') - }); - return null; - } - - const userData = await response.json(); - console.log(`[LEANTIME_ADAPTER] Got user data from Keycloak:`, { - id: userData.id, - email: userData.email, - username: userData.username - }); - - return userData.email || null; + console.log(`[LEANTIME_ADAPTER] Got email from session: ${session.user.email}`); + return session.user.email; } catch (error) { - console.error('[LEANTIME_ADAPTER] Error getting user email:', error); + console.error('[LEANTIME_ADAPTER] Error getting user email from session:', error); return null; } } @@ -467,48 +448,4 @@ export class LeantimeAdapter implements NotificationAdapter { return null; } } - - // Helper function to get admin token (similar to the user management API) - private async getAdminToken(): Promise { - console.log('[LEANTIME_ADAPTER] Getting admin token from Keycloak'); - - try { - const keycloakTokenUrl = `${process.env.KEYCLOAK_BASE_URL}/realms/master/protocol/openid-connect/token`; - console.log('[LEANTIME_ADAPTER] Keycloak token URL:', keycloakTokenUrl); - - const response = await fetch( - keycloakTokenUrl, - { - method: 'POST', - headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - }, - body: new URLSearchParams({ - grant_type: 'client_credentials', - client_id: process.env.KEYCLOAK_ADMIN_CLIENT_ID || '', - client_secret: process.env.KEYCLOAK_ADMIN_CLIENT_SECRET || '', - }), - } - ); - - console.log('[LEANTIME_ADAPTER] Keycloak token response status:', response.status); - - if (!response.ok) { - const errorText = await response.text(); - console.error('[LEANTIME_ADAPTER] Failed to get admin token:', { - status: response.status, - body: errorText.substring(0, 200) + (errorText.length > 200 ? '...' : '') - }); - return null; - } - - const tokenData = await response.json(); - console.log('[LEANTIME_ADAPTER] Successfully obtained admin token'); - - return tokenData.access_token; - } catch (error) { - console.error('[LEANTIME_ADAPTER] Error getting admin token:', error); - return null; - } - } } \ No newline at end of file