diff --git a/src/app/api/lxc/route.js b/src/app/api/lxc/route.js index d66ecf3..fd65095 100644 --- a/src/app/api/lxc/route.js +++ b/src/app/api/lxc/route.js @@ -17,7 +17,7 @@ export async function GET(_req) { ...lxcs.map((lxc) => ({ ...lxc, node: node.name, - consoleUrl: `${PROXMOX_WEB_URL}/?console=lxc&novnc=1&node=${encodeURIComponent(node.name)}&vmid=${lxc.vmid}&token=${encodeURIComponent(PROXMOX_CONSOLE_TOKEN)}`, + consoleUrl: `${PROXMOX_WEB_URL}/?console=lxc&vmid=${lxc.vmid}&node=${encodeURIComponent(node.name)}&resize=scale&xtermjs=1`, })), ); } catch { /* skip node */ } diff --git a/src/app/api/vms/route.js b/src/app/api/vms/route.js index abac524..8acabb7 100644 --- a/src/app/api/vms/route.js +++ b/src/app/api/vms/route.js @@ -17,7 +17,7 @@ export async function GET(_req) { ...vms.map((vm) => ({ ...vm, node: node.name, - consoleUrl: `${PROXMOX_WEB_URL}/?console=qemu&novnc=1&node=${encodeURIComponent(node.name)}&vmid=${vm.vmid}&token=${encodeURIComponent(PROXMOX_CONSOLE_TOKEN)}`, + consoleUrl: `${PROXMOX_WEB_URL}/?console=qemu&vmid=${vm.vmid}&node=${encodeURIComponent(node.name)}&resize=scale&novnc=1`, })), ); } catch { /* skip node */ } diff --git a/src/app/api/vnc/route.js b/src/app/api/vnc/route.js deleted file mode 100644 index 69a7308..0000000 --- a/src/app/api/vnc/route.js +++ /dev/null @@ -1,45 +0,0 @@ -import { NextResponse } from 'next/server'; -import axios from 'axios'; - -const PROXMOX_API_URL = process.env.PROXMOX_API_URL; -const PROXMOX_WEB_URL = process.env.PROXMOX_WEB_URL || PROXMOX_API_URL?.replace('/api2/json', ''); - -/** @param {import('next').Request} req */ -export async function GET(req) { - const url = new URL(req.url); - const node = url.searchParams.get('node'); - const vmid = url.searchParams.get('vmid'); - const type = url.searchParams.get('type'); - - if (!node || !vmid || !type) { - return NextResponse.json({ error: 'Missing node, vmid, or type' }, { status: 400 }); - } - - try { - const ticketRes = await axios({ - url: `${PROXMOX_API_URL}/nodes/${node}/${type}/${vmid}/vncproxy`, - method: 'POST', - headers: { - Authorization: `PVEAPIToken=${process.env.PROXMOX_TOKEN_ID}=${process.env.PROXMOX_TOKEN_SECRET}`, - 'Content-Type': 'application/json', - }, - data: JSON.stringify({ websocket: 0 }), - }); - - const ticket = ticketRes.data?.ticket; - - if (!ticket) { - return NextResponse.json( - { error: 'No VNC ticket returned from Proxmox API' }, - { status: 502 }, - ); - } - - const consoleUrl = `${PROXMOX_WEB_URL}/?vncticket=${encodeURIComponent(ticket)}&novnc=1&node=${encodeURIComponent(node)}&vmid=${vmid}`; - - return NextResponse.json({ consoleUrl }); - } catch (err) { - const msg = err.response?.data?.message || err.response?.data || err.message; - return NextResponse.json({ error: msg }, { status: 502 }); - } -} diff --git a/src/components/ConsolePanel.js b/src/components/ConsolePanel.js deleted file mode 100644 index d1ece79..0000000 --- a/src/components/ConsolePanel.js +++ /dev/null @@ -1,43 +0,0 @@ -'use client'; - -import { useState } from 'react'; - -/** - * @param {{ vmid: number; name: string; node: string; type: string; consoleUrl: string }} vm - * @param {() => void} onClose - * @returns {import('react').ReactNode} - */ -export default function ConsolePanel({ vm, onClose }) { - const [loading, setLoading] = useState(true); - - return ( -
- {/* Header */} -
-
- Console - - ({vm.type.toUpperCase()} {vm.vmid} on {vm.node}) - -
-
- {loading && Loading…} - -
-
- {/* Frame */} -