Support public software auto update URLs
This commit is contained in:
+38
-14
@@ -249,6 +249,22 @@ function publicPlayer(player) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPublicOrigin(req) {
|
||||||
|
const forwardedProto = String(req.get("x-forwarded-proto") || "").split(",")[0].trim();
|
||||||
|
const proto = forwardedProto || req.protocol || "http";
|
||||||
|
const forwardedHost = String(req.get("x-forwarded-host") || "").split(",")[0].trim();
|
||||||
|
const host = forwardedHost || req.get("host") || "";
|
||||||
|
return host ? `${proto}://${host}` : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function absoluteUrl(req, value) {
|
||||||
|
const url = String(value || "").trim();
|
||||||
|
if (!url || /^https?:\/\//i.test(url)) return url;
|
||||||
|
if (!url.startsWith("/")) return url;
|
||||||
|
const origin = getPublicOrigin(req);
|
||||||
|
return origin ? `${origin}${url}` : url;
|
||||||
|
}
|
||||||
|
|
||||||
function getPlayerSession(req) {
|
function getPlayerSession(req) {
|
||||||
const token = parseCookies(req)[playerSessionCookie];
|
const token = parseCookies(req)[playerSessionCookie];
|
||||||
if (!token) return null;
|
if (!token) return null;
|
||||||
@@ -410,6 +426,10 @@ function getProtectedDownloadUrl(item) {
|
|||||||
return resolveDownloadUrl(item) ? `/api/software/${encodeURIComponent(item.id)}/download` : "";
|
return resolveDownloadUrl(item) ? `/api/software/${encodeURIComponent(item.id)}/download` : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUpdateDownloadUrl(item) {
|
||||||
|
return resolveDownloadUrl(item) ? `/api/software/${encodeURIComponent(item.id)}/update-download` : "";
|
||||||
|
}
|
||||||
|
|
||||||
function getReleaseNotes(item, manifest) {
|
function getReleaseNotes(item, manifest) {
|
||||||
return manifest.release_notes || manifest.releaseNotes || manifest.changelog || item.changelog || "";
|
return manifest.release_notes || manifest.releaseNotes || manifest.changelog || item.changelog || "";
|
||||||
}
|
}
|
||||||
@@ -453,11 +473,12 @@ function applyVersionManifest(item, sourceManifest, mode = "auto") {
|
|||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildVersionManifest(item) {
|
function buildVersionManifest(item, req) {
|
||||||
const sourceManifest = item.versionManifest && typeof item.versionManifest === "object" ? item.versionManifest : {};
|
const sourceManifest = item.versionManifest && typeof item.versionManifest === "object" ? item.versionManifest : {};
|
||||||
const latestVersion = getLatestVersion(item);
|
const latestVersion = getLatestVersion(item);
|
||||||
const downloadUrl = getProtectedDownloadUrl(item);
|
const downloadUrl = absoluteUrl(req, getUpdateDownloadUrl(item));
|
||||||
const versionManifestUrl = `/api/software/${encodeURIComponent(item.id)}/version.json`;
|
const versionManifestUrl = `/api/software/${encodeURIComponent(item.id)}/version.json`;
|
||||||
|
const updateUrl = absoluteUrl(req, versionManifestUrl);
|
||||||
const releaseNotes = getReleaseNotes(item, sourceManifest);
|
const releaseNotes = getReleaseNotes(item, sourceManifest);
|
||||||
const minimumVersion = sourceManifest.min_supported_version || sourceManifest.minSupportedVersion || sourceManifest.minimumVersion || sourceManifest.minVersion || "";
|
const minimumVersion = sourceManifest.min_supported_version || sourceManifest.minSupportedVersion || sourceManifest.minimumVersion || sourceManifest.minVersion || "";
|
||||||
|
|
||||||
@@ -473,8 +494,8 @@ function buildVersionManifest(item) {
|
|||||||
size: sourceManifest.size || item.size || "",
|
size: sourceManifest.size || item.size || "",
|
||||||
sizeBytes: sourceManifest.sizeBytes ?? item.sizeBytes ?? 0,
|
sizeBytes: sourceManifest.sizeBytes ?? item.sizeBytes ?? 0,
|
||||||
sha256: sourceManifest.sha256 || item.sha256 || "",
|
sha256: sourceManifest.sha256 || item.sha256 || "",
|
||||||
updateUrl: versionManifestUrl,
|
updateUrl,
|
||||||
update_url: versionManifestUrl,
|
update_url: updateUrl,
|
||||||
downloadUrl,
|
downloadUrl,
|
||||||
download_url: downloadUrl,
|
download_url: downloadUrl,
|
||||||
fullInstallerUrl: downloadUrl,
|
fullInstallerUrl: downloadUrl,
|
||||||
@@ -485,13 +506,13 @@ function buildVersionManifest(item) {
|
|||||||
min_supported_version: minimumVersion,
|
min_supported_version: minimumVersion,
|
||||||
deltaUpdates: sourceManifest.deltaUpdates || sourceManifest.delta_updates || {},
|
deltaUpdates: sourceManifest.deltaUpdates || sourceManifest.delta_updates || {},
|
||||||
delta_updates: sourceManifest.delta_updates || sourceManifest.deltaUpdates || {},
|
delta_updates: sourceManifest.delta_updates || sourceManifest.deltaUpdates || {},
|
||||||
checkUpdateUrl: `/api/software/${encodeURIComponent(item.id)}/check-update`,
|
checkUpdateUrl: absoluteUrl(req, `/api/software/${encodeURIComponent(item.id)}/check-update`),
|
||||||
versionManifestUrl,
|
versionManifestUrl: updateUrl,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildUpdateCheck(item, currentVersion) {
|
function buildUpdateCheck(item, currentVersion, req) {
|
||||||
const manifest = buildVersionManifest(item);
|
const manifest = buildVersionManifest(item, req);
|
||||||
const latestVersion = manifest.version;
|
const latestVersion = manifest.version;
|
||||||
const comparison = compareVersions(currentVersion, latestVersion);
|
const comparison = compareVersions(currentVersion, latestVersion);
|
||||||
const minimumVersion = manifest.min_supported_version || manifest.minSupportedVersion || manifest.minimumVersion || manifest.minVersion || "";
|
const minimumVersion = manifest.min_supported_version || manifest.minSupportedVersion || manifest.minimumVersion || manifest.minVersion || "";
|
||||||
@@ -697,7 +718,7 @@ app.get("/api/software/:id/latest", async (req, res, next) => {
|
|||||||
res.status(404).json({ error: "Software not found" });
|
res.status(404).json({ error: "Software not found" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const manifest = buildVersionManifest(item);
|
const manifest = buildVersionManifest(item, req);
|
||||||
res.json({
|
res.json({
|
||||||
id: item.id,
|
id: item.id,
|
||||||
name: item.name,
|
name: item.name,
|
||||||
@@ -731,7 +752,7 @@ app.get("/api/software/:id/version.json", async (req, res, next) => {
|
|||||||
res.status(404).json({ error: "Software not found" });
|
res.status(404).json({ error: "Software not found" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.json(buildVersionManifest(item));
|
res.json(buildVersionManifest(item, req));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -751,7 +772,7 @@ app.get("/api/software/:id/check-update", async (req, res, next) => {
|
|||||||
res.status(404).json({ error: "Software not found" });
|
res.status(404).json({ error: "Software not found" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.json(buildUpdateCheck(item, currentVersion));
|
res.json(buildUpdateCheck(item, currentVersion, req));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
@@ -771,13 +792,13 @@ app.post("/api/software/:id/check-update", async (req, res, next) => {
|
|||||||
res.status(404).json({ error: "Software not found" });
|
res.status(404).json({ error: "Software not found" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
res.json(buildUpdateCheck(item, currentVersion));
|
res.json(buildUpdateCheck(item, currentVersion, req));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/api/software/:id/download", requirePlayer, async (req, res, next) => {
|
async function sendSoftwareDownload(req, res, next) {
|
||||||
try {
|
try {
|
||||||
const store = await readStore();
|
const store = await readStore();
|
||||||
const item = store.items.find((entry) => entry.id === req.params.id && entry.active !== false);
|
const item = store.items.find((entry) => entry.id === req.params.id && entry.active !== false);
|
||||||
@@ -810,7 +831,10 @@ app.get("/api/software/:id/download", requirePlayer, async (req, res, next) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
app.get("/api/software/:id/update-download", sendSoftwareDownload);
|
||||||
|
app.get("/api/software/:id/download", requirePlayer, sendSoftwareDownload);
|
||||||
|
|
||||||
app.get("/api/admin/software", requirePlayer, requireAdmin, async (req, res, next) => {
|
app.get("/api/admin/software", requirePlayer, requireAdmin, async (req, res, next) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user