diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts index 3d6d16f0..86811859 100644 --- a/app/api/auth/[...nextauth]/route.ts +++ b/app/api/auth/[...nextauth]/route.ts @@ -65,9 +65,6 @@ export const authOptions: NextAuthOptions = { }, callbacks: { async jwt({ token, account, profile }) { - // Log only non-sensitive information - console.log("JWT callback - processing token for user:", token.sub); - if (account && profile) { token.accessToken = account.access_token; token.refreshToken = account.refresh_token; @@ -84,11 +81,9 @@ export const authOptions: NextAuthOptions = { } try { - // Token has expired, try to refresh it const clientId = getRequiredEnvVar("KEYCLOAK_CLIENT_ID"); const clientSecret = getRequiredEnvVar("KEYCLOAK_CLIENT_SECRET"); - console.log("Attempting to refresh token for user:", token.sub); const response = await fetch( `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`, { @@ -108,7 +103,6 @@ export const authOptions: NextAuthOptions = { const tokens = await response.json(); if (!response.ok) { - console.error("Token refresh failed for user:", token.sub); throw new Error("RefreshAccessTokenError"); } @@ -117,27 +111,16 @@ export const authOptions: NextAuthOptions = { accessToken: tokens.access_token, refreshToken: tokens.refresh_token ?? token.refreshToken, accessTokenExpires: Date.now() + tokens.expires_in * 1000, - rocketChatToken: token.rocketChatToken || null, - rocketChatUserId: token.rocketChatUserId || null, }; } catch (error) { - console.error("Error refreshing token for user:", token.sub); - - // Return token with error flag - this will trigger a redirect to sign-in return { ...token, error: "RefreshAccessTokenError", - rocketChatToken: null, - rocketChatUserId: null, }; } }, async session({ session, token }) { - console.log("Session callback - processing session for user:", token.sub); - if (token.error) { - console.error("Token error detected for user:", token.sub); - // Force sign out if there was a refresh error throw new Error("RefreshAccessTokenError"); } @@ -151,38 +134,9 @@ export const authOptions: NextAuthOptions = { role: token.role ?? [], }; - // Add Rocket.Chat credentials to session - session.rocketChatToken = token.rocketChatToken || null; - session.rocketChatUserId = token.rocketChatUserId || null; - return session; } }, - events: { - async signOut({ token }) { - console.log("Sign out event - processing logout for user:", token.sub); - if (token.refreshToken) { - try { - await fetch( - `${process.env.KEYCLOAK_BASE_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/logout`, - { - method: "POST", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - }, - body: new URLSearchParams({ - client_id: getRequiredEnvVar("KEYCLOAK_CLIENT_ID"), - client_secret: getRequiredEnvVar("KEYCLOAK_CLIENT_SECRET"), - refresh_token: token.refreshToken as string, - }), - } - ); - } catch (error) { - console.error("Error during logout for user:", token.sub); - } - } - }, - }, pages: { signIn: '/signin', error: '/signin', diff --git a/app/api/emails/route.ts b/app/api/emails/route.ts index 8f26747e..9b9e98b0 100644 --- a/app/api/emails/route.ts +++ b/app/api/emails/route.ts @@ -6,51 +6,62 @@ export async function GET(req: NextRequest) { try { const session = await getServerSession(authOptions); - if (!session?.user?.email) { + if (!session?.user?.email || !session?.accessToken) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const nextcloudUrl = process.env.NEXTCLOUD_URL; - const clientId = process.env.NEXTCLOUD_CLIENT_ID; - const clientSecret = process.env.NEXTCLOUD_CLIENT_SECRET; - - if (!nextcloudUrl || !clientId || !clientSecret) { - console.error('Missing Nextcloud configuration'); + if (!nextcloudUrl) { + console.error('Missing Nextcloud URL'); return NextResponse.json( { error: 'Nextcloud configuration is missing' }, { status: 500 } ); } - // First, get a Nextcloud OIDC token using client credentials - const tokenResponse = await fetch(`${nextcloudUrl}/apps/oauth2/api/v1/token`, { - method: 'POST', + // First, try to get the user's Nextcloud ID using the OCS API + const userInfoResponse = await fetch(`${nextcloudUrl}/ocs/v2.php/cloud/user`, { headers: { - 'Content-Type': 'application/x-www-form-urlencoded', - 'Authorization': `Basic ${Buffer.from(`${clientId}:${clientSecret}`).toString('base64')}`, + 'Authorization': `Bearer ${session.accessToken}`, + 'Accept': 'application/json', + 'OCS-APIRequest': 'true', + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest', }, - body: new URLSearchParams({ - grant_type: 'client_credentials', - scope: 'ocs', - }), }); - if (!tokenResponse.ok) { - const errorData = await tokenResponse.json(); - console.error('Failed to get Nextcloud token:', { - status: tokenResponse.status, - statusText: tokenResponse.statusText, - error: errorData + if (!userInfoResponse.ok) { + console.error('Failed to get user info:', { + status: userInfoResponse.status, + statusText: userInfoResponse.statusText, + url: userInfoResponse.url, }); - return NextResponse.json({ error: 'Nextcloud authentication failed' }, { status: 401 }); + + if (userInfoResponse.status === 401) { + return NextResponse.json({ error: 'Nextcloud authentication failed' }, { status: 401 }); + } + + return NextResponse.json( + { error: "L'application Mail n'est pas disponible sur Nextcloud. Veuillez contacter votre administrateur." }, + { status: 404 } + ); } - const { access_token } = await tokenResponse.json(); + const userInfo = await userInfoResponse.json(); + const userId = userInfo?.ocs?.data?.id; - // Now try to access the Mail app using the Nextcloud token + if (!userId) { + console.error('Failed to get user ID from Nextcloud'); + return NextResponse.json( + { error: "L'application Mail n'est pas disponible sur Nextcloud. Veuillez contacter votre administrateur." }, + { status: 404 } + ); + } + + // Now try to access the Mail app using OCS API const response = await fetch(`${nextcloudUrl}/ocs/v2.php/apps/mail/api/v1/accounts`, { headers: { - 'Authorization': `Bearer ${access_token}`, + 'Authorization': `Bearer ${session.accessToken}`, 'Accept': 'application/json', 'OCS-APIRequest': 'true', 'Content-Type': 'application/json',