Riscrivi backend per hosting Node/MariaDB/PM2 (no Cloudflare)
L'utente ha un hosting Virtualmin esistente (musictools.djluza.com)
con Apache + Node 20 + MariaDB + PM2. Tutta l'infrastruttura
Cloudflare (Workers/D1/R2/Pages) e' rimpiazzata con un backend
Express che gira sul server gia' presente, a costo zero.
Cambia:
- server/src/*.ts (Workers) -> server/src/*.js (Node ESM puro)
- D1 (sqlite) -> MariaDB 10.11 via mysql2/promise
- R2 (storage) -> filesystem locale ~/builds/ + signed URL HMAC
- wrangler.toml -> ecosystem.config.cjs (PM2)
- Aggiunto src/migrate.js: runner SQL idempotente
Endpoints invariati - l'app desktop non vede differenze:
- POST /api/license/{activate,validate,deactivate}
- GET /api/latest, /api/download
- POST /api/webhook/lemonsqueezy
- GET /api/health
README riscritto con istruzioni complete: creazione DB,
deploy via rsync/git, config Apache reverse proxy via
Virtualmin, gestione PM2, backup, workflow release.
Email rimane su Resend (deliverability) - free tier sufficiente.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
1 parent
339dd4f3cc
commit
2d8290579b
22 files changed
+892
-790
No files matched your search
@@ -0,0 +1,62 @@
|
||||
import "dotenv/config";
|
||||
import express from "express";
|
||||
|
||||
import * as license from "./license.js";
|
||||
import * as updates from "./updates.js";
|
||||
import * as ls from "./lemonsqueezy.js";
|
||||
|
||||
const app = express();
|
||||
|
||||
// L'app sta dietro Apache reverse proxy: fidati di X-Forwarded-* dal localhost.
|
||||
app.set("trust proxy", "loopback");
|
||||
app.disable("x-powered-by");
|
||||
|
||||
// CORS minimale (solo per /api/*)
|
||||
app.use("/api", (req, res, next) => {
|
||||
res.set("Access-Control-Allow-Origin", "*");
|
||||
res.set("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
|
||||
res.set("Access-Control-Allow-Headers", "Content-Type,Authorization");
|
||||
if (req.method === "OPTIONS") return res.status(204).end();
|
||||
next();
|
||||
});
|
||||
|
||||
// Health check (no body parser necessario)
|
||||
app.get("/api/health", (_req, res) => {
|
||||
res.json({ ok: true, version: process.env.LATEST_VERSION || "" });
|
||||
});
|
||||
|
||||
// WEBHOOK Lemon Squeezy: deve ricevere il body RAW per verificare la firma.
|
||||
// Va registrato PRIMA del json parser globale.
|
||||
app.post(
|
||||
"/api/webhook/lemonsqueezy",
|
||||
express.raw({ type: "application/json", limit: "1mb" }),
|
||||
ls.webhook,
|
||||
);
|
||||
|
||||
// JSON parser per tutti gli altri endpoint
|
||||
app.use(express.json({ limit: "128kb" }));
|
||||
|
||||
// Licenze
|
||||
app.post("/api/license/activate", license.activate);
|
||||
app.post("/api/license/validate", license.validate);
|
||||
app.post("/api/license/deactivate", license.deactivate);
|
||||
|
||||
// Aggiornamenti + download firmato
|
||||
app.get("/api/latest", updates.latest);
|
||||
app.get("/api/download", updates.download);
|
||||
|
||||
// 404 JSON solo per /api/*
|
||||
app.use("/api", (_req, res) => res.status(404).json({ error: "Not found" }));
|
||||
|
||||
// Error handler
|
||||
app.use((err, _req, res, _next) => {
|
||||
console.error("[unhandled]", err);
|
||||
if (res.headersSent) return;
|
||||
res.status(500).json({ error: "Internal error" });
|
||||
});
|
||||
|
||||
const PORT = Number(process.env.PORT || 4002);
|
||||
const HOST = process.env.HOST || "127.0.0.1";
|
||||
app.listen(PORT, HOST, () => {
|
||||
console.log(`[musictools-api] listening on ${HOST}:${PORT}`);
|
||||
});
|
||||
Reference in new issue
Block a user