From 0ab1441fe4e38cb4afe07381e2b2f5dab97bb74c Mon Sep 17 00:00:00 2001 From: alma Date: Fri, 2 May 2025 10:32:19 +0200 Subject: [PATCH] courrier msft oauth --- app/api/proxy/[...path]/route.ts | 126 +++++++++++++++++++++++++++ app/components/responsive-iframe.tsx | 9 +- app/parole/page.tsx | 5 +- 3 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 app/api/proxy/[...path]/route.ts diff --git a/app/api/proxy/[...path]/route.ts b/app/api/proxy/[...path]/route.ts new file mode 100644 index 00000000..525745d8 --- /dev/null +++ b/app/api/proxy/[...path]/route.ts @@ -0,0 +1,126 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { getServerSession } from 'next-auth/next'; +import { authOptions } from '@/app/api/auth/[...nextauth]/route'; + +// Map of service prefixes to their base URLs +const SERVICE_URLS: Record = { + 'parole': process.env.NEXT_PUBLIC_IFRAME_PAROLE_URL || '', + 'alma': process.env.NEXT_PUBLIC_IFRAME_AI_ASSISTANT_URL || '', + 'crm': process.env.NEXT_PUBLIC_IFRAME_MEDIATIONS_URL || '', + 'vision': process.env.NEXT_PUBLIC_IFRAME_CONFERENCE_URL || '', + 'showcase': process.env.NEXT_PUBLIC_IFRAME_SHOWCASE_URL || '', + 'agilite': process.env.NEXT_PUBLIC_IFRAME_AGILITY_URL || '', + 'dossiers': process.env.NEXT_PUBLIC_IFRAME_DRIVE_URL || '', + 'the-message': process.env.NEXT_PUBLIC_IFRAME_THEMESSAGE_URL || '', + 'qg': process.env.NEXT_PUBLIC_IFRAME_MISSIONVIEW_URL || '' +}; + +export async function GET( + request: NextRequest, + { params }: { params: { path: string[] } } +) { + // Get the service prefix (first part of the path) + const serviceName = params.path[0]; + const restOfPath = params.path.slice(1).join('/'); + + // Get the base URL for this service + const baseUrl = SERVICE_URLS[serviceName]; + if (!baseUrl) { + return NextResponse.json({ error: 'Service not found' }, { status: 404 }); + } + + // Get the user's session + const session = await getServerSession(authOptions); + if (!session) { + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); + } + + // Get authentication token from session + const accessToken = session.accessToken; + if (!accessToken) { + return NextResponse.json({ error: 'No access token available' }, { status: 401 }); + } + + try { + // Extract search parameters + const searchParams = new URL(request.url).searchParams.toString(); + const targetUrl = `${baseUrl}/${restOfPath}${searchParams ? `?${searchParams}` : ''}`; + + // Forward the request to the target service with the authentication token + const response = await fetch(targetUrl, { + headers: { + 'Authorization': `Bearer ${accessToken}`, + // Add other headers as needed by your services + } + }); + + // Get response data + const data = await response.arrayBuffer(); + + // Create response with the same status and headers + const newResponse = new NextResponse(data, { + status: response.status, + statusText: response.statusText, + headers: { + 'Content-Type': response.headers.get('Content-Type') || 'application/octet-stream', + // Add other headers as needed + } + }); + + return newResponse; + } catch (error) { + console.error('Proxy error:', error); + return NextResponse.json({ error: 'Proxy error' }, { status: 500 }); + } +} + +export async function POST( + request: NextRequest, + { params }: { params: { path: string[] } } +) { + // Similar implementation as GET but for POST requests + // This is a simplified version - you'd need to handle the request body + + const serviceName = params.path[0]; + const restOfPath = params.path.slice(1).join('/'); + + const baseUrl = SERVICE_URLS[serviceName]; + if (!baseUrl) { + return NextResponse.json({ error: 'Service not found' }, { status: 404 }); + } + + const session = await getServerSession(authOptions); + if (!session || !session.accessToken) { + return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); + } + + try { + const searchParams = new URL(request.url).searchParams.toString(); + const targetUrl = `${baseUrl}/${restOfPath}${searchParams ? `?${searchParams}` : ''}`; + + // Get the request body + const body = await request.arrayBuffer(); + + const response = await fetch(targetUrl, { + method: 'POST', + headers: { + 'Authorization': `Bearer ${session.accessToken}`, + 'Content-Type': request.headers.get('Content-Type') || 'application/json', + }, + body: body + }); + + const data = await response.arrayBuffer(); + + return new NextResponse(data, { + status: response.status, + statusText: response.statusText, + headers: { + 'Content-Type': response.headers.get('Content-Type') || 'application/octet-stream', + } + }); + } catch (error) { + console.error('Proxy error:', error); + return NextResponse.json({ error: 'Proxy error' }, { status: 500 }); + } +} \ No newline at end of file diff --git a/app/components/responsive-iframe.tsx b/app/components/responsive-iframe.tsx index c9185864..70bf24b5 100644 --- a/app/components/responsive-iframe.tsx +++ b/app/components/responsive-iframe.tsx @@ -7,11 +7,16 @@ interface ResponsiveIframeProps { className?: string; allow?: string; style?: React.CSSProperties; + token?: string; } -export function ResponsiveIframe({ src, className = '', allow, style }: ResponsiveIframeProps) { +export function ResponsiveIframe({ src, className = '', allow, style, token }: ResponsiveIframeProps) { const iframeRef = useRef(null); + const fullSrc = token ? + `${src}${src.includes('?') ? '&' : '?'}token=${encodeURIComponent(token)}` : + src; + useEffect(() => { const iframe = iframeRef.current; if (!iframe) return; @@ -58,7 +63,7 @@ export function ResponsiveIframe({ src, className = '', allow, style }: Responsi