import { NextResponse } from 'next/server'; import axios from 'axios'; const PROXMOX_WEB_URL = process.env.PROXMOX_WEB_URL || 'http://proxmox:8006'; const PROXMOX_API_URL = process.env.PROXMOX_API_URL; /** @param {import('next').Request} req */ export async function GET(req) { const url = new URL(req.url); const pathSegments = url.pathname.split('/api/proxy/')[1]; if (!pathSegments) { return NextResponse.json({ error: 'Invalid proxy path' }, { status: 400 }); } const proxmoxPath = `/${pathSegments}`; const targetUrl = `${PROXMOX_WEB_URL.replace(/\/+$/, '')}${proxmoxPath}`; const headers = { Authorization: `PVEAPIToken=${process.env.PROXMOX_TOKEN_ID}=${process.env.PROXMOX_TOKEN_SECRET}`, }; try { const res = await axios({ url: targetUrl, method: 'GET', headers, responseType: 'text' }); let body = res.data; // Rewrite relative URLs back through our proxy body = body.replace( /href="([^"]*)"/g, (_, href) => { if (href.startsWith('http') || href.startsWith('javascript:')) return `href="${href}"`; return `href="/api/proxy/${href}"`; }, ); body = body.replace( /src="([^"]*)"/g, (_, src) => { if (src.startsWith('http') || src.startsWith('data:') || src.startsWith('blob:')) return `src="${src}"`; return `src="/api/proxy/${src}"`; }, ); return new NextResponse(body, { status: res.status, headers: { 'Content-Type': res.headers['content-type'] || 'text/html', 'X-Frame-Options': 'SAMEORIGIN', }, }); } catch (err) { const msg = err.response?.data?.message || err.response?.data || err.message; return NextResponse.json({ error: msg }, { status: 502 }); } } /** @param {import('next').Request} req */ export async function POST(req) { const url = new URL(req.url); const pathSegments = url.pathname.split('/api/proxy/')[1]; if (!pathSegments) { return NextResponse.json({ error: 'Invalid proxy path' }, { status: 400 }); } const proxmoxPath = `/${pathSegments}`; const targetUrl = `${PROXMOX_WEB_URL.replace(/\/+$/, '')}${proxmoxPath}`; const headers = { Authorization: `PVEAPIToken=${process.env.PROXMOX_TOKEN_ID}=${process.env.PROXMOX_TOKEN_SECRET}`, 'Content-Type': 'application/x-www-form-urlencoded', }; const body = await req.text(); try { const res = await axios({ url: targetUrl, method: 'POST', headers, data: body, }); return NextResponse.json(res.data); } catch (err) { const msg = err.response?.data?.message || err.response?.data || err.message; return NextResponse.json({ error: msg }, { status: 502 }); } }