Selaa lähdekoodia

Testato e consolidato README.md, commentato tipo di card mai usato

main
Lorenzo Pollutri 2 viikkoa sitten
vanhempi
commit
8ab766b8d9
4 muutettua tiedostoa jossa 19 lisäystä ja 13 poistoa
  1. +12
    -11
      README.md
  2. +1
    -1
      lib/config.ts
  3. +1
    -1
      lib/validation.ts
  4. +5
    -0
      types/index.ts

+ 12
- 11
README.md Näytä tiedosto

@@ -15,7 +15,7 @@ CMS per portali captive: gestione di card informative, gallerie, flip-book e con
7. [Limiti di testo](#limiti-di-testo)
8. [Sicurezza degli input](#sicurezza-degli-input)
9. [Struttura dei dati (`data/`)](#struttura-dei-dati-data)
10. [Stato zero, rilasci e aggiornamenti del codice](#stato-zero-rilasci-e-aggiornamenti-del-codice)
10. [Stato zero e compatibilità tra versioni](#stato-zero-e-compatibilità-tra-versioni)
11. [Backup e ripristino](#backup-e-ripristino)
12. [Factory Preset (developer)](#factory-preset-developer)
13. [Font](#font)
@@ -159,6 +159,7 @@ portal: {
image: 25 MB,
pdf: 20 MB,
video: 1 GB,
font: 5 MB,
```

Per cambiare un qualunque limite: modifica il numero in `lib/config.ts` e ricostruisci. Il valore è condiviso tra interfaccia (contatore / `maxLength`), validazione server e check di upload — un solo punto di verità.
@@ -275,7 +276,7 @@ Copiare via questa cartella = backup completo. Sostituirla = ripristino completo

---

## Stato zero, rilasci e aggiornamenti del codice
## Stato zero e compatibilità tra versioni

### Cosa costituisce lo "stato zero"
Lo stato applicativo (i dati) è **solo** il contenuto di `data/`: `cards.txt`, `portals.txt`, `uploads/`, `fonts/`. Tutto il resto — codice sorgente, `node_modules`, e gli asset di default in `public/` (es. `hero-bg.jpg`, `logo.png`) — **non** fa parte dello stato dati: arriva con il rilascio del software. "Azzerare" il CPC significa quindi sostituire `data/` con uno stato noto.
@@ -285,8 +286,8 @@ Lo stato applicativo (i dati) è **solo** il contenuto di `data/`: `cards.txt`,
- **Aggiornamento del codice**: si sostituisce tutto **tranne** `data/`. I contenuti restano al loro posto.
- Da CLI un reset conservativo è: `mv data data.old && <estrai-l-archivio-dei-contenuti>`. È l'equivalente del `tar zxf` citato dal QA — vedi nota su ZIP vs tar nella sezione [Backup](#backup-e-ripristino).

### Compatibilità dei contenuti dopo un update del codice
I contenuti salvati da versioni precedenti continuano a funzionare: in lettura vengono adattati al volo (es. il vecchio `extraImages: string[]` viene convertito in `extraMedia: MediaItem[]` in [`lib/db.ts`](lib/db.ts)). **Convenzione per future modifiche di schema:** aggiungere il branch di migrazione nella lettura (`getCards`/`getPortals`), senza mai rcompattare i dati legacy in scrittura senza un fallback in lettura — così un archivio di contenuti vecchio resta sempre ripristinabile.
### Compatibilità dei contenuti tra versioni
I contenuti salvati da versioni precedenti continuano a funzionare: in lettura vengono adattati al volo (es. il vecchio `extraImages: string[]` viene convertito in `extraMedia: MediaItem[]` in [`lib/db.ts`](lib/db.ts)). **Convenzione per future modifiche di schema:** aggiungere il branch di migrazione nella lettura (`getCards`/`getPortals`), senza mai ricompattare i dati legacy in scrittura senza un fallback in lettura — così un archivio di contenuti vecchio resta sempre ripristinabile. La procedura operativa di aggiornamento è descritta in [Aggiornamento](#aggiornamento).

### Far accompagnare lo stato zero ai rilasci
Per avere uno stato di partenza noto su ogni macchina nuova, includere nel pacchetto di rilascio un `factory/preset.zip` curato (vedi [Factory Preset](#factory-preset-developer)). Su una macchina nuova, il ripristino di quel preset porta allo stato zero ufficiale.
@@ -298,8 +299,8 @@ Per avere uno stato di partenza noto su ogni macchina nuova, includere nel pacch
Disponibile dall'admin in **Settings → Backup & Restore**.

### Dall'interfaccia
- **Save backup (ZIP)** — scarica `interceptor-backup-YYYYMMDD-hhmmss.zip` con card, configurazione, media e font (esclude i file temporanei).
- **Restore from ZIP** — carica uno zip; dopo conferma sovrascrive lo stato attuale e ricarica la pagina. La cartella `data/` precedente viene conservata come `data.bak-<timestamp>/` come rete di sicurezza.
- **Save backup (ZIP)** — scarica `interceptor-backup-YYYYMMDD-hhmmss.zip` con card, configurazione, media e font (esclude i file temporanei).
- **Restore from ZIP** — carica uno zip; dopo conferma sovrascrive lo stato attuale e ricarica la pagina. La cartella `data/` precedente viene conservata come `data.bak-<timestamp>/` come rete di sicurezza.

### Da riga di comando (Linux)

@@ -324,7 +325,7 @@ Lo zip così prodotto è caricabile direttamente dal pulsante "Restore from ZIP"

## Factory Preset (developer)

Stato "di fabbrica" ripristinabile con un click. Pensato per preparare preset standard (es. banner + icona + una card di redirect) da distribuire a più macchine MajorNet.
Stato "di fabbrica" ripristinabile con un click. Pensato per preparare preset standard (es. banner + icona + una card di redirect) da distribuire a più MajorNet.

**La sezione è sempre visibile in admin.** Il bottone "Factory Reset" e lo stato del preset corrente sono mostrati sempre (è un'operazione lecita per qualunque amministratore). Il bottone "Save as Factory Preset (dev)" — che riscrive il preset di fabbrica — è invece **gated** da `FACTORY_PRESET_SAVE_ENABLED = true` in `lib/config.ts` (default `false`): tienilo attivo solo sulla macchina di sviluppo dove prepari/aggiorni il preset. Gli endpoint API restano comunque attivi a prescindere dal flag.

@@ -587,18 +588,18 @@ Apri il file vhost (quello con i segnaposto `@@@REDIRECT@@@`, `@@@DIRECTORY@@@`,

L'amministratore è identificato dal **`preferred_username` Keycloak**, controllato nei `<Location>` Apache. Per gestire più amministratori:

1. **In Keycloak** (Admin Console → Users): crea/verifica gli utenti con gli username che vuoi promuovere ad admin (es. `admin`, `alice`, `bob`). Imposta le credenziali normalmente.
1. **In Keycloak** (Admin Console → Users): crea/verifica gli utenti con gli username che vuoi promuovere ad admin (es. `admin`, `pollutri`, `russi`). Imposta le credenziali normalmente.
2. **In Apache** (in tutti i blocchi `<Location "/cards/admin">`, `<Location "/cards/api/...">`): usa un blocco **`<RequireAny>`** con **una riga `Require claim` per ogni username**:
```apache
<RequireAny>
Require claim preferred_username:admin
Require claim preferred_username:alice
Require claim preferred_username:bob
Require claim preferred_username:pollutri
Require claim preferred_username:russi
</RequireAny>
```
3. **Reload Apache**: `apachectl configtest && systemctl reload apache2`.

> ⚠ **Non usare la forma compatta `Require claim preferred_username:admin alice bob`** sulla stessa riga: su alcune versioni di `mod_auth_openidc` (incluse quelle in uso sui server MajorNet) il parser dei valori space-separated è buggy e finisce per accettare solo il primo username. Il blocco `<RequireAny>` con una riga `Require claim` per username delega la OR-logic ad Apache (`mod_authz_core`) e funziona affidabilmente. Stesso schema anche dentro `<LimitExcept GET HEAD>`.
> ⚠ **Non usare la forma compatta `Require claim preferred_username:admin pollutri russi`** sulla stessa riga: su alcune versioni di `mod_auth_openidc` (incluse quelle in uso sui server MajorNet) il parser dei valori space-separated è buggy e finisce per accettare solo il primo username. Il blocco `<RequireAny>` con una riga `Require claim` per username delega la OR-logic ad Apache (`mod_authz_core`) e funziona affidabilmente. Stesso schema anche dentro `<LimitExcept GET HEAD>`.

**Rimuovere un admin**: togli la riga `Require claim preferred_username:<username>` corrispondente da `<RequireAny>` (e ricarica Apache), oppure disabilita l'utente direttamente in Keycloak.



+ 1
- 1
lib/config.ts Näytä tiedosto

@@ -7,7 +7,7 @@ export const BASE_PATH = '/cards';

export const EXTERNAL_LINK_ENABLED = true;

// Mostra il bottone "Salva stato attuale come Factory Preset" nell'admin.
// Mostra il bottone "Save as Factory Preset (dev)" nell'admin.
// È una funzione developer: tienila a false in produzione, true solo sulla macchina
// dove serve preparare/aggiornare il preset di fabbrica.
// Il bottone "Factory Reset" e lo stato del preset restano comunque sempre visibili


+ 1
- 1
lib/validation.ts Näytä tiedosto

@@ -9,7 +9,7 @@ const VALID_CARD_TYPES: readonly CardType[] = [
'INFO_PAGE',
'EXTERNAL_LINK',
'IMAGE_GALLERY',
'SERVICE_REQUEST',
'SERVICE_REQUEST', // non esposto in admin né effettivamente utilizzato (vedi nota in types/index.ts)
'BOOK',
'FULLSCREEN_LOCK',
] as const;


+ 5
- 0
types/index.ts Näytä tiedosto

@@ -1,3 +1,8 @@
// NOTE: 'SERVICE_REQUEST' è presente nel type union ma non viene MAI esposto in admin
// (manca dal dropdown del Card Type) né mai emerso/utilizzato a runtime: nessuna card
// di questo tipo viene creata. Lo lasciamo per retro-compatibilità con eventuali
// cards.txt di vecchie installazioni che lo contenessero. Per rimuoverlo del tutto
// andrebbe tolto anche da VALID_CARD_TYPES in lib/validation.ts.
export type CardType = 'INFO_PAGE' | 'EXTERNAL_LINK' | 'IMAGE_GALLERY' | 'SERVICE_REQUEST' | 'BOOK' | 'FULLSCREEN_LOCK';

export type MediaItem = {


Ladataan…
Peruuta
Tallenna