- TypeScript 97.5%
- CSS 1.5%
- HTML 0.7%
- Dockerfile 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Une carte placee dans une grille est plancheee par sa taille min-content (min-width:auto par defaut). Les identifiants Matrix rendus en nowrap par `truncate` portaient cette min-content a ~600px : la carte debordait de la colonne et le conteneur de contenu devenait scrollable horizontalement. `min-w-0` sur `.card` retablit le troncage prevu. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
| server | ||
| web | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
Architect
Console d'administration web pour un serveur Matrix Synapse. Interface mobile-first (navigation basse sur téléphone, barre latérale sur ordinateur), thème clair/sombre, et un petit backend Node qui garde le token d'administration hors du navigateur.
Fonctionnalités
| Domaine | Ce que vous pouvez faire |
|---|---|
| Tableau de bord | Comptes locaux / désactivés / admins, salons, signalements, jetons valides, serveurs fédérés, tâches de fond, derniers comptes créés, salons les plus actifs |
| Utilisateurs | Recherche et filtres, création de compte, édition (nom, admin, verrouillage), réinitialisation de mot de passe, désactivation (avec ou sans effacement), réactivation, shadow ban, token de connexion temporaire, appareils, salons rejoints, médias |
| Salons | Recherche et tri, détails complets, membres, événements d'état, blocage, promotion d'un administrateur, quarantaine des médias, suppression asynchrone avec suivi d'état |
| Modération | Liste et détail des signalements (JSON de l'événement inclus), suppression d'un signalement |
| Jetons d'inscription | Création (aléatoire ou choisi), quota d'utilisations, expiration, suppression |
| Fédération | État des destinations, détail des échecs, salons partagés, réinitialisation de connexion |
| Médias | Occupation disque par utilisateur, purge du cache distant, suppression des médias locaux antérieurs à une date |
| Notices serveur | Envoi d'un message officiel à un utilisateur |
| Réglages | Version de Synapse, migrations de schéma en cours (activation/suspension), informations de session |
Architecture
navigateur ──cookie httpOnly──▶ backend Architect ──access_token──▶ Synapse
(React) (Express, port 8788) (_synapse/admin)
- Le token d'accès admin ne quitte jamais le serveur : le navigateur ne reçoit qu'un
identifiant de session opaque dans un cookie
httpOnly/SameSite=Lax. - Le proxy n'accepte que les endpoints d'une liste blanche (server/src/allowlist.ts), vérifiée sans décodage d'URL.
- Les avatars et miniatures transitent aussi par le proxy, ce qui rend l'API media authentifiée (Matrix 1.11+) transparente pour le navigateur.
- Les sessions sont en mémoire : un redémarrage du backend déconnecte les admins.
Démarrage rapide
pnpm install
cp .env.example .env # renseignez SYNAPSE_URL
pnpm dev # API sur :8788, interface sur :5173
Ouvrez http://localhost:5173 et connectez-vous avec un compte administrateur du serveur
(admin: true dans la table users de Synapse). Un compte non-admin est refusé avec un
message explicite.
Deux modes de connexion :
- Mot de passe — login
m.login.passwordclassique ; - Token d'accès — pour un compte admin passant par un SSO. Architect ne révoque pas ce token à la déconnexion (il ne l'a pas créé).
Configuration
Variables lues depuis .env à la racine ou server/.env :
| Variable | Défaut | Rôle |
|---|---|---|
SYNAPSE_URL |
— | URL du port client de Synapse. Si définie, l'URL est verrouillée et le champ disparaît de l'écran de connexion. Si absente, chaque admin saisit l'URL — pratique en développement, à éviter en production (le proxy accepterait n'importe quelle cible). |
PORT |
8788 |
Port d'écoute du backend |
SESSION_IDLE_MINUTES |
720 |
Expiration d'une session admin inactive |
TRUST_PROXY |
false |
À passer à true derrière nginx/Traefik (cookies Secure, IP clientes) |
WEB_DIR |
web/dist |
Emplacement du bundle React servi en production |
UPSTREAM_TIMEOUT_MS |
30000 |
Délai maximal d'une requête vers Synapse |
Production
pnpm build # compile l'interface puis le backend
pnpm start # un seul process sert l'API et le SPA sur $PORT
Exemple de bloc nginx :
location / {
proxy_pass http://127.0.0.1:8788;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Avec TRUST_PROXY=true, le cookie de session passe automatiquement en Secure dès que
la requête arrive en HTTPS.
Docker Compose (recommandé)
cp .env.example .env # renseignez SYNAPSE_URL
docker compose up -d # build + démarrage
docker compose logs -f # suivi
docker compose down # arrêt
Le service écoute par défaut sur 127.0.0.1:8788 uniquement : placez un reverse proxy
HTTPS devant (voir le bloc nginx ci-dessus) et passez TRUST_PROXY=true. Pour publier le
port sur le réseau sans proxy, mettez BIND_ADDR=0.0.0.0 dans .env.
Les variables du tableau ci-dessus sont reprises depuis .env, plus un réglage propre à
Compose : BIND_ADDR (interface d'écoute). SYNAPSE_URL est obligatoire — le déploiement
échoue avec un message explicite si elle manque, plutôt que de démarrer un proxy sans cible
verrouillée. Après un git pull, docker compose up -d --build reconstruit l'image.
Le conteneur tourne en utilisateur non privilégié, système de fichiers en lecture seule et sans aucune capability : Architect n'écrit rien sur disque, aucun volume n'est nécessaire.
Portainer (stack depuis ce dépôt Git)
.env n'est pas versionné : renseignez les variables dans l'écran Environment variables
de la stack (au minimum SYNAPSE_URL, en général aussi TRUST_PROXY=true). Le fichier
Compose les lit par interpolation, il ne dépend d'aucun .env présent dans le clone.
Pensez à BIND_ADDR=0.0.0.0 si votre reverse proxy n'est pas sur l'hôte Docker lui-même.
Docker (sans Compose)
docker build -t architect .
docker run -d --name architect -p 8788:8788 \
-e SYNAPSE_URL=https://matrix.example.com \
-e TRUST_PROXY=true \
architect
Sécurité
- Cookie
httpOnly,SameSite=Lax,Secureautomatique en HTTPS. - En-tête
X-Architectexigé sur toute requête mutante (anti-CSRF supplémentaire). - 12 tentatives de connexion maximum par IP et par tranche de 5 minutes.
- Vérification du statut administrateur à la connexion, pas seulement de l'authentification.
- Aucune donnée persistée sur disque par Architect.
Exposez cette console derrière HTTPS et, idéalement, derrière une restriction d'accès (VPN, filtrage IP, authentification supplémentaire) : elle donne un contrôle total sur le homeserver.
Structure
server/src
index.ts Application Express, service du SPA
env.ts Configuration et normalisation de l'URL du homeserver
sessions.ts Sessions admin en mémoire
synapse.ts Client HTTP vers Synapse et normalisation des erreurs
allowlist.ts Endpoints Admin API autorisés
middleware.ts Session, anti-CSRF, limitation de débit, erreurs
routes/ auth, proxy, dashboard (agrégation), media (streaming)
web/src
components/ui/ Design system (boutons, feuilles, toasts, badges…)
components/ AppShell (navigation), AuthProvider
lib/ Client API, formatage, hooks, types
pages/ Une page par écran
Compatibilité
Testé avec l'Admin API de Synapse 1.9x et suivantes. Les endpoints absents d'une version plus ancienne dégradent l'affichage (carte vide) sans casser la page : le tableau de bord interroge chaque compteur indépendamment.