# API Relay - Serveur de relais pour UserWallet **Author:** Équipe 4NK **Date:** 2026-01-25 **Version:** 1.0 ## Objectif Créer un serveur de relais séparé pour stocker et relayer les messages du système de login décentralisé UserWallet. Le relais respecte la séparation stricte entre messages, signatures et clés de déchiffrement. ## Impacts ### Fonctionnels - Stockage des messages chiffrés (sans signatures ni clés) - Stockage séparé des signatures - Stockage séparé des clés de déchiffrement - Relais entre pairs (inter-relay) - Déduplication par hash pour éviter les doublons - Endpoints REST pour GET/POST ### Techniques - Serveur Express.js avec TypeScript - Stockage en mémoire avec sauvegarde optionnelle sur disque - Architecture modulaire avec services et routes séparés - Support de la configuration via variables d'environnement ### Sécurité - Déduplication par hash pour éviter les attaques de rejeu - Séparation stricte des messages, signatures et clés - Pas de fusion automatique lors des GET (respect de la spécification) ## Modifications ### Structure du projet ``` api-relay/ ├── src/ │ ├── routes/ │ │ ├── messages.ts # Routes pour les messages chiffrés │ │ ├── signatures.ts # Routes pour les signatures │ │ ├── keys.ts # Routes pour les clés de déchiffrement │ │ └── health.ts # Route de santé │ ├── services/ │ │ ├── storage.ts # Service de stockage │ │ └── relay.ts # Service de relais entre pairs │ ├── types/ │ │ └── message.ts # Types pour messages, signatures, clés │ └── index.ts # Point d'entrée du serveur (config via env) ├── package.json ├── tsconfig.json └── eslint.config.mjs ``` ### Fonctionnalités implémentées 1. **Stockage** - Stockage en mémoire des messages, signatures et clés - Persistance sur disque (`messages.json`) : messages, seenHashes, signatures, clés - Sauvegarde à l’arrêt et périodique (voir `SAVE_INTERVAL_SECONDS`) - Déduplication par hash - Indexation par hash pour accès rapide 2. **Endpoints REST** **Messages :** - `GET /messages?start=&end=&service=` - Récupérer les messages dans une fenêtre temporelle - `POST /messages` - Publier un message chiffré - `GET /messages/:hash` - Récupérer un message par hash **Signatures :** - `GET /signatures/:hash` - Récupérer les signatures pour un message - `POST /signatures` - Publier une signature **Clés :** - `GET /keys/:hash` - Récupérer les clés de déchiffrement pour un message - `POST /keys` - Publier une clé de déchiffrement **Santé :** - `GET /health` - Vérification de santé 3. **Relais entre pairs** - Configuration de relais pairs via variable d'environnement - Relais automatique des messages, signatures et clés - Déduplication pour éviter les boucles de relais 4. **Filtrage** - Filtrage par fenêtre temporelle (start/end) - Filtrage optionnel par service UUID - Tri par timestamp ### Services #### StorageService - Gestion du stockage en mémoire - Déduplication par hash - Méthodes pour messages, signatures et clés - Sauvegarde/chargement depuis disque (messages, seenHashes, signatures, clés) ; sauvegarde périodique configurable #### RelayService - Relais des messages vers les pairs configurés - Gestion des erreurs de réseau - Évite les boucles grâce à la déduplication ## Modalités de déploiement ### Prérequis - Node.js 18+ - npm ou yarn ### Installation ```bash cd api-relay npm install ``` ### Configuration Variables d'environnement : - `PORT` : Port d'écoute (défaut: 3019) - `HOST` : Adresse d'écoute (défaut: 0.0.0.0) - `STORAGE_PATH` : Chemin de stockage (défaut: ./data) - `PEER_RELAYS` : Liste de relais pairs séparés par virgule - `SAVE_INTERVAL_SECONDS` : Sauvegarde périodique en secondes (défaut: 300, 0 = désactivé) Exemple : ```bash PORT=3019 \ HOST=0.0.0.0 \ STORAGE_PATH=./data \ PEER_RELAYS=http://relay1:3019,http://relay2:3019 \ npm run dev ``` ### Développement ```bash npm run dev ``` Le serveur sera accessible sur `http://localhost:3019` ### Build de production ```bash npm run build npm start ``` ### Déploiement Le serveur peut être déployé sur n'importe quelle plateforme supportant Node.js : - Serveur dédié - Docker - Cloud (AWS, GCP, Azure, etc.) ## Modalités d'analyse ### Vérification du fonctionnement 1. **Test de santé** ```bash curl http://localhost:3019/health ``` 2. **Test de publication de message** ```bash curl -X POST http://localhost:3019/messages \ -H "Content-Type: application/json" \ -d '{ "hash": "abc123", "message_chiffre": "encrypted_data", "datajson_public": { "services_uuid": ["service-1"], "types_uuid": ["type-1"], "timestamp": 1234567890 } }' ``` 3. **Test de récupération de messages** ```bash curl "http://localhost:3019/messages?start=0&end=9999999999" ``` 4. **Test de publication de signature** ```bash curl -X POST http://localhost:3019/signatures \ -H "Content-Type: application/json" \ -d '{ "signature": { "hash": "abc123", "cle_publique": "pubkey", "signature": "sig", "nonce": "nonce123" } }' ``` 5. **Test de récupération de signatures** ```bash curl http://localhost:3019/signatures/abc123 ``` ### Logs et debugging - Les erreurs sont loggées dans la console avec `console.error` - Les opérations importantes sont loggées avec `console.log` - Utiliser les DevTools ou un logger structuré en production ### Tests de performance - Tester avec un volume important de messages - Vérifier la déduplication fonctionne correctement - Vérifier le relais entre pairs fonctionne - Mesurer la latence des opérations ## Évolutions futures possibles - **Base de données** : Remplacer le stockage en mémoire par une base de données (SQLite, PostgreSQL) - **Authentification** : Ajouter une authentification pour les endpoints POST - **Rate limiting** : Limiter le nombre de requêtes par IP - **Compression** : Compresser les messages stockés - **Indexation avancée** : Indexer par service UUID, type UUID pour des requêtes plus rapides - **Bloom filter** : Implémenter un Bloom filter pour la déduplication à grande échelle - **Merkle trees** : Support des arbres de Merkle pour la synchronisation efficace - **WebSocket** : Support WebSocket pour les notifications en temps réel (optionnel, car le modèle est pull-only) - **Métriques** : Exposer des métriques (Prometheus, etc.) - **Logging structuré** : Utiliser un logger structuré (Winston, Pino, etc.)