WebUI
La WebUI est la nouvelle application web de SAINet. Elle parle directement au serveur SAINet par son point d’entrée EPS
(/SNV4SRV-ws-war/EPS) et se déploie séparément du serveur. L’objectif de cette documentation, dédiée aux utilisateurs de type
Super-administrateurs, est d’exprimer les étapes pour déployer la WebUI et la maintenir alignée sur la version du serveur SAINet.
Le compte de service permet à la WebUI de vérifier périodiquement (sans attendre qu’un utilisateur se connecte) si une nouvelle version est disponible. Sans compte de service, la vérification se fait à la connexion d’un utilisateur (voir Mises à jour automatiques).
Créer dans SYS02 un utilisateur de type USER, dont le mot de passe est à jour (non marqué comme devant être changé), sans authentification
à deux facteurs, et lui donner uniquement les accès suivants (par exemple via un groupe dédié créé en SYS03, SYS04 et SYS07) :
| Tâche | Accès | Remarques |
|---|---|---|
SYS00 |
Accès en lecture et exécution. | Accès obligatoire pour la connexion. |
SYS46 |
Accès en lecture. | Accès obligatoire pour télécharger le package de la WebUI. |
Ne jamais donner le rôle SUPERADMIN à ce compte : il n’en a pas besoin et ses identifiants sont stockés dans l’environnement de la WebUI.
Une image docker est disponible. Cette image s’appelle saierp/webui. La version de l’image dépend du serveur pointé. Par exemple,
pour un serveur en version 4.13, l’image sera saierp/webui:4.13.
Afin de pouvoir déployer l’image, il est nécessaire d’avoir docker installé sur la machine.
Créer un fichier docker-compose.yml avec le contenu suivant :
services:
sainet_webui:
restart: always
image: saierp/webui:4.13
environment:
- SAINET_URL=https://my-sainet-server.ch/SNV4SRV-ws-war/EPS
- SAINET_SCREEN_KEY=<cle>
- SAINET_NPM_AUTH_TOKEN=123456789=
- SAINET_USER=webui
- SAINET_PASS=example
volumes:
- "./webui/app:/usr/src/webui"
- "./webui/data:/data"
ports:
- "<port>:3000"
Le <port> correspond au port externe d’écoute de l’image docker. En interne, le port 3000 est utilisé.
Deux volumes persistants sont nécessaires :
/usr/src/webui: l’application (app), sa sauvegarde (app.old) et le dossier des mises à jour (update) ;/data: les données de la WebUI (packages téléchargés du serveur dans/data/packages).
L’image ne contient pas la WebUI compilée : elle est compilée au démarrage du conteneur (npm ci --omit=dev puis npm run build). Le conteneur doit donc pouvoir accéder au registre npm de SAI ERP (npm.admin.sai-erp.net) avec le token SAINET_NPM_AUTH_TOKEN, ce qui vaut aussi pour Windows.
Variables principales :
| Variable | Requis | Valeur | Définition |
|---|---|---|---|
SAINET_URL |
oui | https://<host>/SNV4SRV-ws-war/EPS |
Le point d’entrée EPS du serveur SAINet. |
SAINET_SCREEN_KEY |
oui | string |
Clé HMAC des jetons d’intégrité des écrans (au moins 32 octets aléatoires, par exemple openssl rand -base64 48). |
SAINET_NPM_AUTH_TOKEN |
oui | string |
Token d’authentification pour que la WebUI puisse être compilée (également lors des mises à jour). Cette valeur est fournie par SAI ERP. |
SAINET_USER |
string |
Utilisateur du compte de service. | |
SAINET_PASS |
string |
Mot de passe du compte de service. |
Variables complémentaires :
| Variable | Type | Définition |
|---|---|---|
SAINET_AUTO_UPDATE |
0 ou 1 |
Active la mise à jour automatique. Par défaut 1 avec Docker et Windows (service.bat), 0 sinon. |
SAINET_ENCODING |
ISO-8859-1 ou UTF-8 |
Force l’encodage des échanges avec le serveur SAINet. Par défaut (variable absente), la WebUI utilise le client_encoding du healthcheck du serveur et le garde jusqu’à son redémarrage. Dans les deux cas, la WebUI interroge à chaque démarrage le healthcheck <scheme>://<host>[:<port>]/healthcheck (origine de SAINET_URL, port compris) : il doit être joignable depuis la WebUI, directement sur le serveur SAINet (côté intranet) et non à travers le relais de la WebUI. Si SAINET_URL est absente ou invalide, si SAINET_ENCODING a une valeur invalide, si le healthcheck ne peut pas être lu (URL incorrecte, serveur arrêté) ou si, sans SAINET_ENCODING, il ne contient pas de client_encoding, la WebUI s’arrête avec le code de sortie 1 et un message sur la sortie d’erreur. Avec Docker (restart: always), le conteneur redémarre jusqu’à ce que le serveur soit disponible ; sous Windows, service.bat ne relance pas la WebUI (il sort avec le code 1) : c’est au gestionnaire du service de la redémarrer. |
SAINET_DOWNLOAD_FOLDER |
string |
Chemin absolu du dossier des mises à jour. Obligatoire pour la mise à jour automatique. Par défaut /usr/src/webui/update en Docker. |
SAINET_PACKAGES_DIR |
string |
Chemin absolu des packages téléchargés du serveur. Par défaut /data/packages en Docker. |
SAINET_AUTO_UPDATE_COOLDOWN |
integer |
Délai minimal (en ms) entre deux téléchargements de la mise à jour. Par défaut 3 600 000 (1h). |
SAINET_AUTO_UPDATE_INTERVAL |
integer |
Délai (en ms) entre deux vérifications de version. Par défaut 900 000 (15 min). |
SAINET_ROOT_DIR |
string |
Chemin d’installation de la WebUI. Par défaut /usr/src/webui en Docker. Sous Windows (service.bat), cette variable est obligatoire. |
SAINET_NODE_OPTIONS |
options | Liste d’options à passer à la commande node. Par défaut, --max-old-space-size=512. |
PORT |
integer |
Le port interne d’écoute. Par défaut 3000. |
HOSTNAME |
string |
L’adresse d’écoute. Par défaut 0.0.0.0 en Docker. |
La liste complète des variables de configuration figure dans le fichier .env.example de la WebUI.
Un proxy inverse HTTPS (Apache, Traefik) est obligatoire devant la WebUI, qui s’attend à des requêtes HTTP. Il doit transmettre le header Host, X-Forwarded-Proto avec la valeur https, et ajouter l’adresse IP du client au header X-Forwarded-For. X-Forwarded-Host et X-Forwarded-Proto doivent être écrasés par le proxy et non repris tels que le client les envoie : la WebUI s’en sert pour son contrôle de même origine et les transmet au serveur SAINet (CORS, redirections). La mise en tampon des réponses doit être désactivée. La WebUI recopie X-Forwarded-For vers le serveur SAINet sans y ajouter elle-même d’adresse IP : le serveur retient la dernière valeur du header pour la limitation des tentatives de connexion, qui doit donc être celle posée par le proxy.
Les sessions des utilisateurs sont conservées en mémoire : une seule instance de la WebUI doit être déployée.
Le déploiement visé est une WebUI publique et un serveur SAINet accessible uniquement depuis l’intranet. Pour que l’aide en ligne et l’API restent
disponibles dans ce cas, la WebUI relaie vers le serveur SAINet (origine de SAINET_URL) exactement les chemins suivants :
| Chemin | Accès | Description |
|---|---|---|
/help/** |
Session WebUI requise. | Aide en ligne. Le jeton d’aide est posé côté serveur Node par la WebUI et n’est jamais exposé au navigateur. |
/healthcheck |
Public, sans authentification. | État de l’instance du serveur SAINet, utilisable pour le monitoring. Répond à GET et HEAD (sondes de monitoring) et ne renvoie que le type de contenu et le cache, sans les autres en-têtes du serveur. |
/api/v1/** |
Transparent. | API REST-JSON : l’authentification est celle du client de l’API, la WebUI n’intervient pas. Le corps des requêtes est limité à 32 Mo (même plafond que les envois de fichiers de la WebUI) : au-delà, la WebUI répond 413. |
Aucun autre chemin n’est relayé : le point d’entrée EPS, la couche mobile, /metrics, /installer, /login, /logout et la racine statique du serveur
ne sont servis que par le serveur SAINet. Un lien vers l’un de ces chemins dans une aide lue via la WebUI donne donc une erreur 404.
Le healthcheck lu par la WebUI à son démarrage (voir SAINET_ENCODING) est toujours lu sur l’origine de SAINET_URL, c’est-à-dire côté intranet, et non via le relais /healthcheck.
Les URLs d’aide et d’API à communiquer aux utilisateurs sont alors celles de l’hôte de la WebUI (par exemple https://<hôte WebUI>/api/v1).
La WebUI est livrée dans le package SAINet sous forme de sources (webui.zip). Elle reste alignée sur le serveur de la manière suivante :
- La version de référence est celle du fichier
webui.versiondu package SAINet. La WebUI la compare à la version de la WebUI installée et la lit via SYS46 (avec le compte de service ou l’utilisateur connecté). - Avec un compte de service, la vérification est faite au démarrage du conteneur Docker, avant le lancement de la WebUI : une mise à jour
disponible est téléchargée et appliquée avant d’accepter les premières connexions. Elle est ensuite périodique (toutes les
SAINET_AUTO_UPDATE_INTERVAL). Sans compte de service, la vérification a lieu à la connexion d’un utilisateur, au plus une fois par intervalle. Dans ce cas, l’utilisateur doit avoir un accès en lecture àSYS46, sans quoi la vérification échoue (sans impact sur sa connexion). - Si les versions diffèrent, le package est téléchargé (au plus une fois par
SAINET_AUTO_UPDATE_COOLDOWN) dans<update>/webui.zip, puis la WebUI s’arrête. Le zip des sources est téléchargeable par tout compte ayant un droit de lecture surSYS46: il ne contient que les sources du produit, sans secret. Le conteneur (ou le service Windows) applique alors le package, recompile l’application et la relance. - Pendant la recompilation, une page « Redémarrage en cours » est servie et se rafraîchit toute seule toutes les 5 secondes.
- Si la nouvelle version ne peut être ni extraite ni compilée, la version précédente (
app.old) est restaurée et la version en échec est mémorisée dans<update>/failed.version: elle ne sera pas retéléchargée en boucle. Pour forcer un nouvel essai, supprimer<update>/failed.version(ou<update>/update.timepour ignorer le délai entre deux téléchargements).
Les sessions étant en mémoire, tous les utilisateurs sont déconnectés à chaque mise à jour.
Au premier démarrage, et à chaque nouvelle image, la WebUI est compilée deux fois : une première fois depuis les sources embarquées dans l’image, puis une seconde fois depuis la version du serveur, téléchargée dès la première vérification.
La procédure pour installer la WebUI en tant que service sur Windows :
- Installer la dernière version LTS de NodeJS (
npmetnodedoivent être disponibles dans la variable d’environnementPATH). - Installer sevenzip (
7zdoit être disponible dans la variable d’environnementPATH). - Extraire le package
webui.zip(fourni dans le package SAINet) dans un sous-dossierapp(par exempleD:/sainet/webui/app). - Copier les fichiers
app/windows/env.bat,app/windows/service.batau même niveau que le répertoireapp(ils doivent être dehors du répertoire ;maintenance.mjsest lu directement dansapp/docker). - Mettre à jour les variables dans
env.bat(notammentSAINET_NPM_AUTH_TOKEN, nécessaire à la compilation). - Créer un service en redémarrage automatique avec nssm (voir ici) en pointant le fichier
<webui>/service.bat. - Le dossier d’exécution (« Startup directory ») du service doit être
<webui>(mettre le chemin complet), c’est-à-dire le dossier qui contientenv.batetservice.bat.
service.bat appelle env.bat par un chemin relatif : sans le réglage du dossier d’exécution indiqué ci-dessus, le service démarre par défaut dans System32, où env.bat n’est pas trouvé, ce qui fait échouer le démarrage.
Il est possible de tester le démarrage de la WebUI en lançant la commande suivante dans une console :
cd <webui>
service.bat