# Accès privé par cPanel, remplacé

> **Ce dispositif n'est plus celui en place.** L'accès est désormais géré par
> l'application elle-même : connexion par lien envoyé par email, allowlist portée
> par la table `user`. Voir la section *Authentification* de
> [la procédure de déploiement](./deploiement-o2switch.md).
>
> Ce document est conservé parce qu'il reste exact et que le dispositif reste
> valable comme repli. Il a fonctionné : la Confidentialité du répertoire
> s'applique bien aux requêtes transmises à Passenger. Son seul défaut tenait à
> sa page d'erreur, LiteSpeed servait `/401.shtml` à travers l'application, qui
> répondait 404, et ce 404 écrasait le 401 au point que le navigateur ne
> demandait jamais d'identifiants. La ligne
> `ErrorDocument 401 "Authentification requise"` dans le `.htaccess` du docroot
> corrige cela, un document d'erreur donné sous forme de chaîne étant servi par
> le serveur web sans jamais passer par Passenger.
>
> **À retirer** tant que l'authentification applicative est en place : deux
> protections superposées demanderaient deux mots de passe pour une seule porte.

## Le dispositif d'origine

Le blocage vit sur le serveur web, avant Passenger et donc avant Next.js. Aucune
route de l'application ne peut être oubliée, puisque aucune n'est jointe sans
identifiant valide. L'application elle-même ne contient aucun code d'accès :
c'est tout l'intérêt du dispositif.

Compte cPanel : `mixq8738`. Répertoire protégé : `advmfrkb.elevaseo.app`.

## Mise en place, par cPanel

Utiliser **Confidentialité du répertoire**, et non une édition manuelle du
`.htaccess`. cPanel écrit le bloc d'authentification, gère le fichier de mots de
passe hors du docroot, et laisse intactes les directives Passenger qui font
tourner l'application Node. Une édition à la main de ce même fichier risque de
les écraser, ce qui met le site hors service.

1. **Confidentialité du répertoire** → sélectionner `advmfrkb.elevaseo.app`.
2. Cocher **Protéger ce répertoire par mot de passe**.
3. Nom du répertoire protégé : `Base de connaissance ADVMFR`. C'est le texte que
   le navigateur affiche dans sa fenêtre de demande, il est vu par les lecteurs.
4. Enregistrer.
5. Créer **un utilisateur par personne** dans la section du dessous. Un identifiant
   par lecteur, jamais un identifiant partagé : retirer quelqu'un revient alors à
   supprimer sa ligne, sans changer le mot de passe de tous les autres.

## À vérifier avant de considérer que c'est fait

L'application Node est servie par Passenger derrière LiteSpeed. LiteSpeed honore
bien la protection de répertoire, mais **il reste à confirmer qu'elle couvre les
requêtes transmises à Node**, et pas seulement les fichiers statiques. C'est le
seul point de ce dispositif qui ne peut pas être établi à l'avance, et c'est
celui qui décide si le contenu est réellement fermé.

```bash
# Sans identifiant : doit refuser
curl -sI https://advmfrkb.elevaseo.app/docs | head -1

# Avec un identifiant valide : doit servir
curl -sI -u <utilisateur> https://advmfrkb.elevaseo.app/docs | head -1
```

Attendu : `401` puis `200`.

Les deux comptent. Un dispositif qui refuse tout le monde n'est pas plus utile
qu'un dispositif qui ne refuse personne, et un `200` sur la première commande
signifie que la base de connaissance est publique malgré la protection affichée
par cPanel. Dans ce cas, **retirer le site de la ligne** et revenir sur le sujet.

Vérifier aussi une route non-HTML, qui emprunte un chemin différent :

```bash
curl -sI https://advmfrkb.elevaseo.app/llms-full.txt | head -1
```

Cette route sert le texte intégral de toute la base. Elle doit répondre `401`.

## HTTPS

En Basic Auth, l'identifiant voyage encodé en base64, qui n'est pas un
chiffrement : une seule requête servie en clair suffit à le livrer. Vérifier dans
**Domaines** que **Forcer la redirection HTTPS** est actif pour
`advmfrkb.elevaseo.app`.

S'il ne l'est pas et ne peut pas l'être, ajouter ces quatre lignes **au début** du
`.htaccess` du docroot, sans toucher au reste du fichier :

```apache
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
```

## Retirer quelqu'un

Supprimer son utilisateur dans **Confidentialité du répertoire**. L'effet est
immédiat : il n'y a aucune session à révoquer, chaque requête est
ré-authentifiée.

## Limites assumées

- **Pas de déconnexion.** Le navigateur conserve l'identifiant pour toute
  l'origine jusqu'à sa fermeture ; Basic Auth n'a pas de mécanisme de sortie.
- **L'application ne sait pas qui lit.** Aucun contenu ne peut être réservé à une
  partie des lecteurs : c'est tout ou rien, et cela restera vrai tant que l'accès
  est géré au niveau du serveur.
- **Changer un mot de passe** se fait dans cPanel puis se communique à la
  personne ; il n'y a pas de réinitialisation en autonomie.

Ces trois limites sont le prix payé pour n'avoir ni base de données, ni service
d'envoi d'emails, ni code d'authentification à maintenir. Si l'une devient
gênante, l'implémentation par magic link dort sur la branche
`feature/auth-magic-link` : deux commits, base MySQL et instance Better Auth
générée par son CLI officiel.
