mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-06-03 13:54:41 +00:00
Bump Next.js to 15.1.9 + doc nav handles in-page anchors + help_info_menu
Three changes that fold into the v1.2.2 release PR: 1. AppImage: bump Next.js 15.1.6 -> 15.1.9 (CVE-2025-55182) GHSA-9qr9-h5gf-34mp / React2Shell is a pre-auth RCE in React Server Components when Server Functions deserialize attacker payloads. The ProxMenux Monitor ships Next.js in `output: "export"` mode behind Flask on :8008, so there is no runtime Next.js server and no "use server" directive in the source tree — the exploitable path is not reachable. Bumping to 15.1.9 anyway because OpenVAS and similar scanners flag the version string from the JS bundle regardless of architecture; raising the floor removes false-positive noise across every install. Reported by @rost43 in #219. 2. web/components/ui/doc-navigation.tsx: handle sidebar entries that point to in-page anchors. The Storage Share Manager sidebar has entries for `/docs/storage-share#host` and `/docs/storage-share#lxc-net` as section headers, but usePathname() does not include the hash so every visit collapsed to the parent page. As a result Next/Previous on /docs/storage-share stayed stuck at #host, and Next from .../lxc-mount-points/ pointed back at #host instead of #lxc-net. Read window.location.hash on mount (and on hashchange) and try the pathname+hash match before falling back to the pathname-only lookup. SSR hydrates with an empty hash and refreshes once mounted — brief render before hydration is the same as the previous behaviour, so no regression. 3. scripts/help_info_menu.sh: user-side improvement (mirrored from develop). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
@@ -1 +1 @@
|
||||
097e2344675d4b21f1dd18c531c956c299a6507fbc3d0c9695418063581ba2b0
|
||||
149acc8644e7830ddccda97faa452f36f9a820c507e2c6b54fc9a7e51b9b4297
|
||||
|
||||
Generated
+4429
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,7 @@
|
||||
"geist": "^1.3.1",
|
||||
"input-otp": "1.4.1",
|
||||
"lucide-react": "^0.454.0",
|
||||
"next": "15.1.6",
|
||||
"next": "15.1.9",
|
||||
"next-themes": "^0.4.6",
|
||||
"react": "^19",
|
||||
"react-day-picker": "9.8.0",
|
||||
|
||||
+20
-20
@@ -186,12 +186,12 @@ show_vm_ct_commands() {
|
||||
echo -e " 9) ${GREEN}qm destroy <vmid>${NC} - $(translate 'Delete a VM (irreversible). Use the correct <vmid>')"
|
||||
echo -e "10) ${GREEN}pct destroy <ctid>${NC} - $(translate 'Delete a CT (irreversible). Use the correct <ctid>')"
|
||||
echo -e "11) ${GN}[Only with menu] Show CT users for permission mapping${NC} - $(translate 'root and real users only')"
|
||||
echo -e "12) ${GREEN}pct exec <ctid> -- getent passwd | column -t -s :${NC} - $(translate 'Show CT users in table format')"
|
||||
echo -e "13) ${GREEN}pct exec <ctid> -- ps aux --sort=-%mem | head${NC} - $(translate 'Top memory processes in CT')"
|
||||
echo -e "14) ${GREEN}cat /etc/pve/qemu-server/<vmid>.conf${NC} - $(translate 'View raw VM configuration file')"
|
||||
echo -e "15) ${GREEN}cat /etc/pve/lxc/<ctid>.conf${NC} - $(translate 'View raw CT configuration file')"
|
||||
echo -e "16) ${GREEN}nano /etc/pve/qemu-server/<vmid>.conf${NC} - $(translate 'Edit raw VM configuration file')"
|
||||
echo -e "17) ${GREEN}nano /etc/pve/lxc/<ctid>.conf${NC} - $(translate 'Edit raw CT configuration file')"
|
||||
echo -e "12) ${GREEN}pct exec <ctid> -- getent passwd | column -t -s :${NC} - $(translate 'Show CT users in table format')"
|
||||
echo -e "13) ${GREEN}pct exec <ctid> -- ps aux --sort=-%mem | head${NC} - $(translate 'Top memory processes in CT')"
|
||||
echo -e "14) ${GREEN}cat /etc/pve/qemu-server/<vmid>.conf${NC} - $(translate 'View raw VM configuration file')"
|
||||
echo -e "15) ${GREEN}cat /etc/pve/lxc/<ctid>.conf${NC} - $(translate 'View raw CT configuration file')"
|
||||
echo -e "16) ${GREEN}nano /etc/pve/qemu-server/<vmid>.conf${NC} - $(translate 'Edit raw VM configuration file')"
|
||||
echo -e "17) ${GREEN}nano /etc/pve/lxc/<ctid>.conf${NC} - $(translate 'Edit raw CT configuration file')"
|
||||
echo -e " ${DEF}0) $(translate ' Back to previous menu or Esc + Enter')"
|
||||
echo
|
||||
echo -en "${TAB}${BOLD}${YW}${HOLD}$(translate 'Enter a number, or write or paste a command: ') ${CL}"
|
||||
@@ -310,17 +310,17 @@ show_storage_commands() {
|
||||
echo -e "17) ${GREEN}pvesm status${NC} - $(translate 'Show status of all storage pools')"
|
||||
echo -e "18) ${GREEN}pvesm list <storage>${NC} - $(translate 'List content of specific storage')"
|
||||
echo -e "19) ${GREEN}pvesm scan <storage>${NC} - $(translate 'Scan storage for new content')"
|
||||
echo -e "20) ${GREEN}qm importdisk <vmid> <img> <storage>${NC} - $(translate 'Import disk image to VM')"
|
||||
echo -e "21) ${GREEN}qm set <vmid> -<bus><index> <disk>${NC} - $(translate 'Add physical disk to VM via') passthrough"
|
||||
echo -e "20) ${GREEN}qm importdisk <vmid> <img> <storage>${NC} - $(translate 'Import disk image to VM')"
|
||||
echo -e "21) ${GREEN}qm set <vmid> -<bus><index> <disk>${NC} - $(translate 'Add physical disk to VM via') passthrough"
|
||||
echo -e "22) ${GREEN}qemu-img convert -O <format> <input> <output>${NC} - $(translate 'Convert disk image format')"
|
||||
echo -e "23) ${GREEN}smartctl --scan${NC} - $(translate 'List SMART-capable devices')"
|
||||
echo -e "24) ${GREEN}smartctl -H /dev/<disk>${NC} - $(translate 'Quick health check (PASSED / FAILED)')"
|
||||
echo -e "25) ${GREEN}smartctl -a /dev/<disk>${NC} - $(translate 'Full SMART info and attributes')"
|
||||
echo -e "26) ${GREEN}smartctl -t short /dev/<disk>${NC} - $(translate 'Start short self-test (~2 min)')"
|
||||
echo -e "27) ${GREEN}smartctl -t long /dev/<disk>${NC} - $(translate 'Start long self-test (hours)')"
|
||||
echo -e "28) ${GREEN}smartctl -l selftest /dev/<disk>${NC} - $(translate 'View self-test log')"
|
||||
echo -e "29) ${GREEN}nvme list${NC} - $(translate 'List NVMe devices')"
|
||||
echo -e "30) ${GREEN}nvme smart-log /dev/<nvme>${NC} - $(translate 'NVMe-specific SMART log')"
|
||||
echo -e "23) ${GREEN}smartctl --scan${NC} - $(translate 'List SMART-capable devices')"
|
||||
echo -e "24) ${GREEN}smartctl -H /dev/<disk>${NC} - $(translate 'Quick health check (PASSED / FAILED)')"
|
||||
echo -e "25) ${GREEN}smartctl -a /dev/<disk>${NC} - $(translate 'Full SMART info and attributes')"
|
||||
echo -e "26) ${GREEN}smartctl -t short /dev/<disk>${NC} - $(translate 'Start short self-test (~2 min)')"
|
||||
echo -e "27) ${GREEN}smartctl -t long /dev/<disk>${NC} - $(translate 'Start long self-test (hours)')"
|
||||
echo -e "28) ${GREEN}smartctl -l selftest /dev/<disk>${NC} - $(translate 'View self-test log')"
|
||||
echo -e "29) ${GREEN}nvme list${NC} - $(translate 'List NVMe devices')"
|
||||
echo -e "30) ${GREEN}nvme smart-log /dev/<nvme>${NC} - $(translate 'NVMe-specific SMART log')"
|
||||
echo -e " ${DEF}0) $(translate ' Back to previous menu or Esc + Enter')"
|
||||
echo
|
||||
echo -en "${TAB}${BOLD}${YW}${HOLD}$(translate 'Enter a number, or write or paste a command: ') ${CL}"
|
||||
@@ -693,13 +693,13 @@ show_gpu_commands() {
|
||||
echo -e "${YELLOW}$(translate 'GPU/TPU Passthrough Commands')${NC}"
|
||||
echo -e "${TAB}${YW}$(translate 'Inspection commands run directly. Template commands [T] require parameter substitution.')${CL}"
|
||||
echo "------------------------------------------------------------"
|
||||
echo -e " 1) ${GREEN}lspci -nn | grep -iE 'VGA|3D|Display'${NC} - $(translate 'Detect GPUs in host')"
|
||||
echo -e " 2) ${GREEN}lspci -nnk | grep -A3 -Ei 'VGA|3D'${NC} - $(translate 'Show GPU kernel driver in use')"
|
||||
echo -e " 1) ${GREEN}lspci -nn | grep -iE 'VGA|3D|Display'${NC} - $(translate 'Detect GPUs in host')"
|
||||
echo -e " 2) ${GREEN}lspci -nnk | grep -A3 -Ei 'VGA|3D'${NC} - $(translate 'Show GPU kernel driver in use')"
|
||||
echo -e " 3) ${GREEN}cat /proc/cmdline${NC} - $(translate 'Check kernel params (IOMMU flags)')"
|
||||
echo -e " 4) ${GREEN}dmesg -T | grep -Ei 'DMAR|IOMMU|vfio|pcie'${NC} - $(translate 'Inspect passthrough/kernel events')"
|
||||
echo -e " 4) ${GREEN}dmesg -T | grep -Ei 'DMAR|IOMMU|vfio|pcie'${NC} - $(translate 'Inspect passthrough/kernel events')"
|
||||
echo -e " 5) ${GREEN}find /sys/kernel/iommu_groups -type l${NC} - $(translate 'List IOMMU group mapping')"
|
||||
echo -e " 6) ${GREEN}lsmod | grep -E 'vfio|nvidia|amdgpu|apex'${NC} - $(translate 'Check loaded GPU/TPU modules')"
|
||||
echo -e " 7) ${GREEN}grep -R \"vfio-pci|blacklist\" /etc/modprobe.d${NC} - $(translate 'Review passthrough config files')"
|
||||
echo -e " 7) ${GREEN}grep -R \"vfio-pci|blacklist\" /etc/modprobe.d${NC} - $(translate 'Review passthrough config files')"
|
||||
echo -e " 8) ${GREEN}nvidia-smi${NC} - $(translate 'Check NVIDIA driver and devices')"
|
||||
echo -e " 9) ${GREEN}qm config <vmid> | grep 'hostpci|bios'${NC} - [T] $(translate 'Check VM passthrough settings')"
|
||||
echo -e "10) ${GREEN}pct config <ctid> | grep 'dev|lxc.cgroup2'${NC} - [T] $(translate 'Check LXC GPU/TPU mapping')"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import { Link, usePathname } from "@/i18n/navigation"
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react"
|
||||
import { useTranslations } from "next-intl"
|
||||
import { useEffect, useState } from "react"
|
||||
import { sidebarItems } from "@/components/DocSidebar"
|
||||
|
||||
interface DocNavigationProps {
|
||||
@@ -55,6 +56,26 @@ export function DocNavigation({ className }: DocNavigationProps) {
|
||||
const tNav = useTranslations("docNav")
|
||||
const tSidebar = useTranslations("docSidebar")
|
||||
|
||||
// Capture the URL hash (`#host`, `#lxc-net`, …) on the client so we
|
||||
// can disambiguate Previous/Next when a single doc page hosts several
|
||||
// sidebar entries via in-page anchors (Storage Share Manager is the
|
||||
// canonical case: /docs/storage-share + /docs/storage-share#host +
|
||||
// /docs/storage-share#lxc-net are three distinct sidebar items but a
|
||||
// single physical page; usePathname() returns the same string for
|
||||
// all three because the fragment is not part of the path).
|
||||
//
|
||||
// SSR can't see the hash, so we hydrate with an empty string and
|
||||
// refresh on mount + on hashchange. The brief render before
|
||||
// hydration just shows the navigation as if the user were at the
|
||||
// parent page — same behaviour as before this fix, so no regression.
|
||||
const [hash, setHash] = useState("")
|
||||
useEffect(() => {
|
||||
const sync = () => setHash(window.location.hash || "")
|
||||
sync()
|
||||
window.addEventListener("hashchange", sync)
|
||||
return () => window.removeEventListener("hashchange", sync)
|
||||
}, [])
|
||||
|
||||
const tItem = (i18nKey: string | undefined, fallback: string) => {
|
||||
if (!i18nKey) return fallback
|
||||
try {
|
||||
@@ -102,9 +123,30 @@ export function DocNavigation({ className }: DocNavigationProps) {
|
||||
// bar showed "Next: Introduction" everywhere regardless of the route.
|
||||
const stripTrailingSlash = (s: string) => (s !== "/" ? s.replace(/\/+$/, "") : s)
|
||||
const normalizedPathname = stripTrailingSlash(pathname)
|
||||
const currentPageIndex = allPages.findIndex(
|
||||
(page) => stripTrailingSlash(page.href) === normalizedPathname,
|
||||
)
|
||||
|
||||
// Match attempt order:
|
||||
// 1. pathname + hash (e.g. /docs/storage-share#host) — exact match
|
||||
// against sidebar items that intentionally point to an in-page
|
||||
// anchor as the "current location" for navigation purposes.
|
||||
// 2. pathname alone — the regular case, no anchor in the URL.
|
||||
//
|
||||
// Without step 1, every anchor visit collapsed to the parent page
|
||||
// and Next/Previous walked from there — so on /docs/storage-share#host
|
||||
// the bottom bar offered the same #host as Next (no movement) and on
|
||||
// /docs/storage-share/lxc-mount-points/ Next pointed back at #host
|
||||
// because the entire flat list got indexed from position 0.
|
||||
const effectivePath = normalizedPathname + hash
|
||||
let currentPageIndex = -1
|
||||
if (hash) {
|
||||
currentPageIndex = allPages.findIndex(
|
||||
(page) => stripTrailingSlash(page.href) === effectivePath,
|
||||
)
|
||||
}
|
||||
if (currentPageIndex === -1) {
|
||||
currentPageIndex = allPages.findIndex(
|
||||
(page) => stripTrailingSlash(page.href) === normalizedPathname,
|
||||
)
|
||||
}
|
||||
|
||||
const prevPage = currentPageIndex > 0 ? allPages[currentPageIndex - 1] : null
|
||||
const nextPage = currentPageIndex < allPages.length - 1 ? allPages[currentPageIndex + 1] : null
|
||||
|
||||
Reference in New Issue
Block a user