Konstantinos Spartalis hace 1 mes
padre
commit
ae5faa75fa
Se han modificado 3 ficheros con 100 adiciones y 45 borrados
  1. 19 17
      backend/routes/main.js
  2. 77 0
      backend/routes/version.js
  3. 4 28
      frontend/src/components/SiteFooter.tsx

+ 19 - 17
backend/routes/main.js

@@ -14,11 +14,12 @@ import schemaRoutes from "./schema.js";
 import settingsRoutes from "./settings.js";
 import tokensRoutes from "./tokens.js";
 import usersRoutes from "./users.js";
+import versionRoutes from "./version.js";
 
 const router = express.Router({
-	caseSensitive: true,
-	strict: true,
-	mergeParams: true,
+    caseSensitive: true,
+    strict: true,
+    mergeParams: true,
 });
 
 /**
@@ -26,18 +27,18 @@ const router = express.Router({
  * GET /api
  */
 router.get("/", async (_, res /*, next*/) => {
-	const version = pjson.version.split("-").shift().split(".");
-	const setup = await isSetup();
+    const version = pjson.version.split("-").shift().split(".");
+    const setup = await isSetup();
 
-	res.status(200).send({
-		status: "OK",
-		setup,
-		version: {
-			major: Number.parseInt(version.shift(), 10),
-			minor: Number.parseInt(version.shift(), 10),
-			revision: Number.parseInt(version.shift(), 10),
-		},
-	});
+    res.status(200).send({
+        status: "OK",
+        setup,
+        version: {
+            major: Number.parseInt(version.shift(), 10),
+            minor: Number.parseInt(version.shift(), 10),
+            revision: Number.parseInt(version.shift(), 10),
+        },
+    });
 });
 
 router.use("/schema", schemaRoutes);
@@ -46,6 +47,7 @@ router.use("/users", usersRoutes);
 router.use("/audit-log", auditLogRoutes);
 router.use("/reports", reportsRoutes);
 router.use("/settings", settingsRoutes);
+router.use("/version", versionRoutes);
 router.use("/nginx/proxy-hosts", proxyHostsRoutes);
 router.use("/nginx/redirection-hosts", redirectionHostsRoutes);
 router.use("/nginx/dead-hosts", deadHostsRoutes);
@@ -59,8 +61,8 @@ router.use("/nginx/certificates", certificatesHostsRoutes);
  * ALL /api/*
  */
 router.all(/(.+)/, (req, _, next) => {
-	req.params.page = req.params["0"];
-	next(new errs.ItemNotFoundError(req.params.page));
+    req.params.page = req.params["0"];
+    next(new errs.ItemNotFoundError(req.params.page));
 });
 
-export default router;
+export default router;

+ 77 - 0
backend/routes/version.js

@@ -0,0 +1,77 @@
+import express from "express";
+import { debug, express as logger } from "../logger.js";
+import pjson from "../package.json" with { type: "json" };
+
+const router = express.Router({
+    caseSensitive: true,
+    strict: true,
+    mergeParams: true,
+});
+
+/**
+ * /api/version/check
+ */
+router
+    .route("/check")
+    .options((_, res) => {
+        res.sendStatus(204);
+    })
+
+    /**
+     * GET /api/version/check
+     *
+     * Check for available updates
+     */
+    .get(async (req, res, next) => {
+        try {
+            const response = await fetch(
+                "https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest"
+            );
+
+            if (!response.ok) {
+                throw new Error(`GitHub API returned ${response.status}`);
+            }
+
+            const data = await response.json();
+            const latestVersion = data.tag_name;
+
+            const version = pjson.version.split("-").shift().split(".");
+            const currentVersion = `v${version[0]}.${version[1]}.${version[2]}`;
+
+            res.status(200).send({
+                current: currentVersion,
+                latest: latestVersion,
+                updateAvailable: compareVersions(currentVersion, latestVersion),
+            });
+        } catch (error) {
+            debug(logger, `${req.method.toUpperCase()} ${req.path}: ${error}`);
+            res.status(200).send({
+                current: null,
+                latest: null,
+                updateAvailable: false,
+            });
+        }
+    });
+
+/**
+ * Compare two version strings
+ *
+ */
+function compareVersions(current, latest) {
+    const cleanCurrent = current.replace(/^v/, "");
+    const cleanLatest = latest.replace(/^v/, "");
+
+    const currentParts = cleanCurrent.split(".").map(Number);
+    const latestParts = cleanLatest.split(".").map(Number);
+
+    for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
+        const curr = currentParts[i] || 0;
+        const lat = latestParts[i] || 0;
+
+        if (lat > curr) return true;
+        if (lat < curr) return false;
+    }
+    return false;
+}
+
+export default router;

+ 4 - 28
frontend/src/components/SiteFooter.tsx

@@ -2,23 +2,6 @@ import { useCallback, useEffect, useState } from "react";
 import { useHealth } from "src/hooks";
 import { T } from "src/locale";
 
-const compareVersions = (current: string, latest: string): boolean => {
-    const cleanCurrent = current.replace(/^v/, "");
-    const cleanLatest = latest.replace(/^v/, "");
-
-    const currentParts = cleanCurrent.split(".").map(Number);
-    const latestParts = cleanLatest.split(".").map(Number);
-
-    for (let i = 0; i < Math.max(currentParts.length, latestParts.length); i++) {
-        const curr = currentParts[i] || 0;
-        const lat = latestParts[i] || 0;
-
-        if (lat > curr) return true;
-        if (lat < curr) return false;
-    }
-    return false;
-};
-
 export function SiteFooter() {
     const health = useHealth();
     const [latestVersion, setLatestVersion] = useState<string | null>(null);
@@ -35,18 +18,11 @@ export function SiteFooter() {
     useEffect(() => {
         const checkForUpdates = async () => {
             try {
-                const response = await fetch(
-                    "https://api.github.com/repos/NginxProxyManager/nginx-proxy-manager/releases/latest"
-                );
+                const response = await fetch("/api/version/check");
                 if (response.ok) {
                     const data = await response.json();
-                    const latest = data.tag_name;
-                    setLatestVersion(latest);
-
-                    const currentVersion = getVersion();
-                    if (currentVersion && compareVersions(currentVersion, latest)) {
-                        setIsNewVersionAvailable(true);
-                    }
+                    setLatestVersion(data.latest);
+                    setIsNewVersionAvailable(data.updateAvailable);
                 }
             } catch (error) {
                 console.debug("Could not check for updates:", error);
@@ -56,7 +32,7 @@ export function SiteFooter() {
         if (health.data) {
             checkForUpdates();
         }
-    }, [health.data, getVersion]);
+    }, [health.data]);
 
     return (
         <footer className="footer d-print-none py-3">