Files
luzadevandClaude Opus 4.7 2d8290579b 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>
2026-06-09 00:15:53 +02:00

216 lines
6.1 KiB
Markdown

# MusicTools — License & Update API
Backend Node.js per gestire attivazione licenze, validazione e distribuzione binari MusicTools.
## Stack
- **Node.js 20 + Express 4**
- **MariaDB 10.11** (locale, localhost:3306)
- **PM2** per process management
- **Apache 2.4** come reverse proxy verso `127.0.0.1:4002`
- **Resend** per email transazionali
- **Lemon Squeezy** per i pagamenti (webhook -> `/api/webhook/lemonsqueezy`)
Tutto gira sull'hosting esistente (`musictools@musictools.djluza.com`), zero costi aggiuntivi.
## Struttura
```
server/
src/
server.js # Express app
db.js # pool mysql2
license.js # activate / validate / deactivate
updates.js # /api/latest + /api/download
lemonsqueezy.js # webhook ordini
email.js # Resend client
jwt.js # JWT HS256 senza dipendenze
migrate.js # runner SQL idempotente
migrations/
0001_init.sql # schema licenses / activations / releases
ecosystem.config.cjs # PM2
.env.example
package.json
```
## Setup iniziale sul server
Una volta sola, da SSH `musictools@musictools.djluza.com`:
### 1) Crea database e utente MariaDB
Sul server (richiede root o l'utente master DB del tuo hosting — di solito Virtualmin lo crea per te dal pannello "Edit Databases"):
```sql
CREATE DATABASE musictools_licenses CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'musictools'@'localhost' IDENTIFIED BY 'PASSWORD_FORTE';
GRANT ALL PRIVILEGES ON musictools_licenses.* TO 'musictools'@'localhost';
FLUSH PRIVILEGES;
```
In alternativa via Virtualmin: **Edit Databases → Create a new database**, poi tab **Manage** → crea utente con password.
### 2) Clona o sincronizza il codice
Due opzioni:
**A. Via git** (consigliato):
```bash
cd ~
git clone https://github.com/luzadev/musicdownload.git app-src
ln -s app-src/server api
cd api
npm install --production
```
**B. Via rsync da locale** (più semplice se preferisci non lasciare codice client sul server):
```bash
# Da Mac:
rsync -avz --exclude node_modules /Users/luciano/Downloads/Progetti2026/MusicDownload/server/ musictools@musictools.djluza.com:~/api/
# Poi SSH e:
cd ~/api && npm install --production
```
### 3) Configura .env
```bash
cd ~/api
cp .env.example .env
nano .env # compila tutti i valori — vedi sotto
```
Per generare `JWT_SECRET`:
```bash
openssl rand -base64 32
```
### 4) Migrate
```bash
cd ~/api
npm run migrate
```
Output atteso:
```
[migrate] applico 0001_init.sql
[migrate] ok 0001_init.sql
[migrate] done
```
### 5) Avvia con PM2
```bash
cd ~/api
mkdir -p logs
pm2 start ecosystem.config.cjs
pm2 save
# Test:
curl -s http://127.0.0.1:4002/api/health
# -> {"ok":true,"version":"v1.5.2"}
```
### 6) Apache reverse proxy
Devi dire ad Apache che le richieste a `musictools.djluza.com/api/*` vanno a `127.0.0.1:4002`.
**Via Virtualmin** (consigliato):
1. Vai su **Webmin → Servers → Apache Webserver**
2. Clicca sul VirtualHost di `musictools.djluza.com` (porta 443)
3. Sezione **Aliases and redirects** o **Edit Directives**, aggiungi prima di `</VirtualHost>`:
```apache
# MusicTools API
ProxyPreserveHost On
ProxyRequests Off
# Webhook: passa raw body senza alterazioni
<Location /api/>
ProxyPass http://127.0.0.1:4002/api/
ProxyPassReverse http://127.0.0.1:4002/api/
</Location>
```
4. Apply changes.
**Verifica moduli Apache attivi** (da SSH se hai sudo):
```bash
apache2ctl -M | grep -E 'proxy|proxy_http'
# Devono comparire proxy_module e proxy_http_module
```
Se mancano, abilitali (sudo richiesto):
```bash
sudo a2enmod proxy proxy_http
sudo systemctl reload apache2
```
### 7) Verifica end-to-end
Da qualsiasi posto:
```bash
curl -s https://musictools.djluza.com/api/health
# -> {"ok":true,"version":"v1.5.2"}
```
## Workflow pubblicazione release
1. GitHub Actions builda i due zip (gia in place).
2. Carica gli zip sul server in `~/builds/<version>/`:
```bash
ssh musictools@musictools.djluza.com 'mkdir -p ~/builds/v1.5.3'
scp MusicTools-macOS.zip musictools@musictools.djluza.com:~/builds/v1.5.3/
scp MusicTools-Windows.zip musictools@musictools.djluza.com:~/builds/v1.5.3/
```
3. Inserisci il record in MariaDB:
```bash
ssh musictools@musictools.djluza.com 'mariadb musictools_licenses' <<SQL
INSERT INTO releases (version, platform, file_path, size_bytes, sha256, notes, published_at)
VALUES ('v1.5.3', 'macos', 'v1.5.3/MusicTools-macOS.zip', 12345, '<sha256>', 'Note...', UNIX_TIMESTAMP()),
('v1.5.3', 'windows', 'v1.5.3/MusicTools-Windows.zip', 67890, '<sha256>', 'Note...', UNIX_TIMESTAMP());
SQL
```
4. Aggiorna `LATEST_VERSION` nel `.env` e `pm2 reload musictools-api`.
In futuro: script o workflow GitHub Actions che fa tutto in automatico.
## Operazioni quotidiane
| Cosa | Comando |
|---|---|
| Reload codice dopo deploy | `pm2 reload musictools-api` |
| Vedere log live | `pm2 logs musictools-api` |
| Stato | `pm2 status` |
| Errori recenti | `pm2 logs musictools-api --err --lines 100` |
| Restart hard | `pm2 restart musictools-api` |
| Stop | `pm2 stop musictools-api` |
| Console DB | `mariadb -u musictools -p musictools_licenses` |
## Endpoints
| Metodo | Path | Auth | Descrizione |
|---|---|---|---|
| POST | `/api/license/activate` | — | Attiva licenza, ritorna JWT |
| POST | `/api/license/validate` | — (token nel body) | Rivalida + ruota token |
| POST | `/api/license/deactivate` | — (token nel body) | Libera uno slot |
| GET | `/api/latest?platform=…` | Bearer token (opzionale) | Versione + URL download firmato |
| GET | `/api/download?file=…&exp=…&sig=…` | Firma HMAC | Stream del binario |
| POST | `/api/webhook/lemonsqueezy` | X-Signature HMAC | Crea licenza dopo ordine |
| GET | `/api/health` | — | Healthcheck |
## Backup
Aggiungi un cronjob daily:
```bash
# crontab -e
0 4 * * * mariadb-dump musictools_licenses | gzip > ~/backups/musictools-$(date +\%F).sql.gz && find ~/backups -name 'musictools-*.sql.gz' -mtime +30 -delete
```
## Costi
- **Hosting**: gia pagato (server condiviso esistente)
- **Lemon Squeezy**: 5% + $0.50 per transazione = ~5 EUR su un acquisto da 39,90 EUR
- **Resend**: free fino a 3k email/mese (= ~3k licenze/mese, oltre serve piano $20)
- **Totale fisso**: 0 EUR/mese