# PS_Launcher — Côté serveur

Contenu de ce dossier à uploader **sous `www/PS_Launcher/`** sur le mutualisé OVH.

## Arborescence finale après upload

```
www/
└── PS_Launcher/
    ├── .htaccess
    ├── api/                     ← API consommée par le launcher
    │   ├── config.php           ← À CRÉER (copie de config.example.php)
    │   ├── index.php
    │   ├── lib/{Response,Db,Crypto}.php
    │   └── routes/{Manifest,Releasenotes,ValidateLicense}.php
    ├── admin/                   ← Backoffice web (auth par mot de passe)
    │   ├── .htaccess
    │   ├── index.php            (dashboard)
    │   ├── login.php / logout.php
    │   ├── licenses.php / versions.php / audit.php
    │   ├── lib/{Auth,Layout}.php
    │   └── assets/style.css
    ├── manifest/versions.json
    ├── releasenotes/1.4.X.md
    ├── builds/                  ← ZIPs uploadés en SFTP
    ├── migrations/001_init.sql  ← Schéma MySQL initial
    └── tools/
        ├── generate-keypair.php
        ├── issue-license.php
        └── sign-manifest.php
```

## Setup initial (à faire une fois)

### 1. Crée la base MySQL
Manager OVH → Hébergements → Bases de données → Créer. Note le DSN, user, password.

### 2. Joue le schéma
PhpMyAdmin (manager OVH) ou en SSH :
```bash
mysql -h <host> -u <user> -p <db> < www/PS_Launcher/migrations/001_init.sql
```

### 3. Configure le serveur
- Copie `api/config.example.php` → `api/config.php`
- Remplis la section `db`, `base_url`
- Génère les clés Ed25519 :
  ```bash
  cd ~/www/PS_Launcher
  php tools/generate-keypair.php
  ```
  Recopie `private_key_hex` et `public_key_hex` dans `api/config.php` section `ed25519`.
  Recopie aussi `public_key_hex` dans `src/PSLauncher.Core/Resources/server-pubkey.txt` côté projet C# et recompile le launcher.

### 4. Configure le mot de passe admin
```bash
php -r "echo password_hash('TonMotDePasseFort', PASSWORD_DEFAULT);"
```
Recopie le hash dans `api/config.php` → `admin_password_hash`.

### 5. Test la chaîne
```
https://tondomaine.com/PS_Launcher/api/health         → JSON status: ok
https://tondomaine.com/PS_Launcher/admin/login.php    → page de connexion admin
```

## Workflow de release (via le backoffice)

1. Connecte-toi sur `https://tondomaine.com/PS_Launcher/admin/`.
2. Onglet **Versions** → formulaire « Ajouter une version » : numéro, date min de license, release notes Markdown.
3. Upload le ZIP correspondant via SFTP dans `www/PS_Launcher/builds/proserve-{version}.zip`.
4. Bouton **🔁 Sync (sign-manifest)** : calcule SHA-256, met à jour `latest`, signe le manifest avec Ed25519.
5. Au prochain « Vérifier les MAJ » côté launcher, la nouvelle version apparaît.

## Workflow de release (alternative manuelle SSH)

```bash
# 1. Édite manifest/versions.json (ou utilise le backoffice)
# 2. Upload le ZIP en SFTP dans builds/
# 3. Resigne :
cd ~/www/PS_Launcher
php tools/sign-manifest.php
```

## Émettre une license

**Via le backoffice** (recommandé) : onglet **Licenses** → formulaire « Émettre ». La clé apparaît une seule fois — copie-la pour le client.

**Via SSH** :
```bash
php tools/issue-license.php "ACME Corp" 2027-12-31 1
```

## Convention du contenu du ZIP

Le client extrait le ZIP dans `installRoot/Proserve v{version}/`. Le ZIP peut soit contenir
un dossier racine `Proserve v{version}/`, soit le contenu directement — le launcher détecte
automatiquement le préfixe commun et le strippe.

## Test API depuis ton poste

```powershell
curl.exe https://tondomaine.com/PS_Launcher/api/health
curl.exe https://tondomaine.com/PS_Launcher/api/manifest
curl.exe https://tondomaine.com/PS_Launcher/api/releasenotes/1.4.6
```

## Sécurité

- `api/config.php` est gitignored. Ne jamais le commit.
- Toutes les URLs `/api/*` forcent HTTPS via `.htaccess`.
- Les routes /api/* renvoient toujours du JSON (pas de page Apache 500 HTML).
- L'admin est protégé par session + CSRF + mot de passe bcrypt.
- Les licenses sont stockées via UNIQUE en clair (pour la lookup constant-time côté serveur),
  mais ne sont jamais loguées en clair côté audit.
- Côté client : la clé license est chiffrée DPAPI scope CurrentUser dans `%LocalAppData%`.
- Les réponses serveur (manifest, validation license) sont signées Ed25519 — le launcher
  embarque la clé publique et refuse toute réponse mal signée.
