feat: add server-side version update check
Logs current version on startup and checks GitHub for newer releases. Only runs in production, output stays in server logs (no client exposure).
This commit is contained in:
@@ -131,6 +131,7 @@ Stalwart is a mail server written in Rust with native JMAP support, not IMAP/SMT
|
|||||||
- Runtime environment variables (no rebuild needed)
|
- Runtime environment variables (no rebuild needed)
|
||||||
- Health check endpoint
|
- Health check endpoint
|
||||||
- Structured logging (text/JSON)
|
- Structured logging (text/JSON)
|
||||||
|
- Update check on startup (server logs only, no client exposure)
|
||||||
|
|
||||||
## Tech stack
|
## Tech stack
|
||||||
|
|
||||||
|
|||||||
@@ -233,6 +233,7 @@ This document tracks the development status and planned features for JMAP Webmai
|
|||||||
- [x] Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) with multi-arch support (amd64/arm64)
|
- [x] Pre-built Docker image on [Docker Hub](https://hub.docker.com/r/rootfr/jmap-webmail) and [GHCR](https://ghcr.io/root-fr/jmap-webmail) with multi-arch support (amd64/arm64)
|
||||||
- [x] GitHub Actions CI/CD for automated image publishing on releases
|
- [x] GitHub Actions CI/CD for automated image publishing on releases
|
||||||
- [x] CVE remediation: remove npm from production image, upgrade Alpine packages
|
- [x] CVE remediation: remove npm from production image, upgrade Alpine packages
|
||||||
|
- [x] Server-side update check (logs newer version availability on startup)
|
||||||
|
|
||||||
## Planned Features
|
## Planned Features
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { readFileSync } from "fs";
|
||||||
|
|
||||||
|
const VERSION_CHECK_URL =
|
||||||
|
"https://raw.githubusercontent.com/root-fr/jmap-webmail/main/VERSION";
|
||||||
|
|
||||||
|
const SEMVER_RE = /^\d+\.\d+\.\d+$/;
|
||||||
|
|
||||||
|
function compareVersions(current: string, remote: string): number {
|
||||||
|
const a = current.split(".").map(Number);
|
||||||
|
const b = remote.split(".").map(Number);
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if ((b[i] ?? 0) > (a[i] ?? 0)) return 1;
|
||||||
|
if ((b[i] ?? 0) < (a[i] ?? 0)) return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function register() {
|
||||||
|
const pkg = JSON.parse(
|
||||||
|
readFileSync(`${process.cwd()}/package.json`, "utf-8")
|
||||||
|
);
|
||||||
|
const current: string = pkg.version ?? "0.0.0";
|
||||||
|
console.info(`JMAP Webmail v${current}`);
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== "production") return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch(VERSION_CHECK_URL, {
|
||||||
|
cache: "no-store",
|
||||||
|
signal: AbortSignal.timeout(5000),
|
||||||
|
});
|
||||||
|
if (!res.ok) return;
|
||||||
|
const remote = (await res.text()).trim();
|
||||||
|
if (!SEMVER_RE.test(remote)) return;
|
||||||
|
if (compareVersions(current, remote) > 0) {
|
||||||
|
console.info(
|
||||||
|
`Update available: v${remote} — https://github.com/root-fr/jmap-webmail`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// Network unavailable — not critical
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,9 @@ import createNextIntlPlugin from "next-intl/plugin";
|
|||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
output: "standalone",
|
output: "standalone",
|
||||||
|
turbopack: {
|
||||||
|
root: import.meta.dirname,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const withNextIntl = createNextIntlPlugin();
|
const withNextIntl = createNextIntlPlugin();
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jmap-webmail",
|
"name": "jmap-webmail",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"description": "A modern JMAP webmail client built for Stalwart Mail Server",
|
"description": "A modern JMAP webmail client built for Stalwart Mail Server",
|
||||||
"author": "Matthieu MALVACHE <matthieu@root.cloud>",
|
"author": "Matthieu MALVACHE <matthieu@root.cloud>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
Reference in New Issue
Block a user