**Motivations:** - Partie connectée du skeleton accessible seulement si pairing satisfait + relais OK, avec page type skeleton (avatar, notifications). - Éviter « Aucun service disponible » : contrat présent en dur dans la page, transmis à l’iframe ; navigation évidente ou automatique vers login. - Sécuriser postMessage (origine UserWallet uniquement) ; déployer data sur le proxy et certificat data.certificator.4nkweb.com. - Vulgariser cryptographie (ECDH, AES-GCM, Schnorr, workflow, collecte signatures) ; documenter correctifs et architecture. **Root causes:** - Section connectée affichée sans vérifier pairing/relay ; possibilité de forger pairing-relay-status depuis la console. - Iframe masquée ou /login chargé avant réception du contrat → graphe vide, redirection vers /services. - Pas de contrôle d’origine sur les messages reçus ; pas de projet website-data ni config Nginx/certificat pour data. **Correctifs:** - Vérification msg.origin === USERWALLET_ORIGIN dans handleMessage (skeleton). - Si session mais pas pairingRelayStatus : afficher iframe pour réception du statut, message « Vérification du statut… ». - Contrat envoyé dès load iframe (init iframe.src = USERWALLET_ORIGIN) ; au clic « Se connecter », envoi contract + navigate-login (service, membre). - UserWallet : écoute navigate-login → navigation /login?service=&membre= ; LoginScreen avec service+membre en URL ne redirige plus vers /services, dispatch E_SELECT_SERVICE / E_SELECT_MEMBER. **Evolutions:** - Message pairing-relay-status (iframe → parent) ; canShowConnectedSection exige login + pairing OK + relay OK ; page connectée avec header avatar + icône notifications. - Skeleton : getLoginContext, sendNavigateLoginToIframe, onIframeLoad, loginRequested/iframeLoaded ; contrat envoyé avec serviceUuid, membreUuid. - UserWallet : PairingRelayStatusMessage, envoi depuis HomeScreen/LoginScreen ; type navigate-login, handleNavigateLogin dans useChannel. - Page cryptographie.html (workflow, algorithmes, collecte signatures) ; liens nav, build. - website-data (Vite, channel, config), start/service/install ; configure-nginx-proxy + Certbot pour data.certificator.4nkweb.com. - fixKnowledge (postmessage-origin, section-connectee-non-affichee) ; features (partie-connectee-pairing-relay, userwallet-iframe-key-isolation). **Pages affectées:** - website-skeleton (index, main, config, serviceContract, cryptographie, technique, membre, contrat, vite.config, README). - userwallet (HomeScreen, LoginScreen, useChannel, iframeChannel, relay, crypto, iframe, Pairing*, RelaySettings, WordInputGrid, syncUpdateGraph, specs/synthese). - website-data (nouveau), configure-nginx-proxy, docs DOMAINS_AND_PORTS README, features, fixKnowledge, userwallet features/docs.
7.6 KiB
7.6 KiB
Synthèse structurée – UserWallet & API Relay
Author: Équipe 4NK Date: 2026-01-26
1. userwallet/docs
ports.md
- UserWallet (Vite) : port 3018 (
vite.config.ts). - api-relay (Express) : port 3019 (ou
PORT), défaut 3019 dansindex.ts. Le README api-relay indique 3019. - Ports à éviter : 3007, 8080, 3015–3017.
specs.md
Spécification du login décentralisé (secp256k1, contrats, pairing mFA, relais) :
Complément : specs-champs-obligatoires-cnil.md — champs obligatoires / rôles (partage, RSSI, CNIL, cybersécurité, support N1/N2/N3, validation contrat, validation login, etc.) et attributs CNIL dans datajson (raisons_usage_tiers, raisons_partage_tiers, conditions_conservation, membre_miner_uuid pour les champs infogérant). Voir features/userwallet-membre-miner-infogerant.md.
- Modèle : messages publiés sans signatures ni clés ; signatures et clés publiées séparément ; tout adressé par hash canonique ; récupération par GET uniquement (pull).
- Objets : Service, Contrat, Champ, Action, ActionLogin, Membre, Pair, MessageBase, Hash, Signature, Validateurs, MsgChiffre, MsgSignature, MsgCle.
- Graphe : Service → Contrat → Champ → Action(login) → Membre → Pair ; contraintes « au moins 1 parent ».
- Pairing : UUID pair ↔ mots BIP32 ; pairing obligatoire pour login.
- Écrans : accueil, création/import identité, relais, pairing, sync, services, chemin login, challenge, signatures mFA, publication, résultat.
- Machine à états : S_INIT → S_HOME, S_SYNC_GLOBAL, S_PAIR_, S_LOGIN_, etc., avec erreurs récupérables / fatales.
storage.md
- Relais : stockage hybride (mémoire +
./data/messages.json). Messages,seenHashes, signatures et clés persistés. Sauvegarde à l’arrêt et périodique (SAVE_INTERVAL_SECONDS). - Front : LocalStorage (
userwallet_identity,userwallet_relays,userwallet_pairs; legacyuserwallet_keypair,userwallet_services). IndexedDB :hash_cache,userwallet_pairing_confirm. Protection par mot de passe (identité chiffrée). Graphe en mémoire uniquement (GraphResolver).
2. userwallet/ (frontend)
Stack
- React 18, React Router, Vite, TypeScript.
- Crypto :
@noble/secp256k1,@noble/hashes. - Pas de state global (hooks + services).
Structure
- /components : Home, CreateIdentity, ImportIdentity, Login, PairManagement, RelaySettings, Sync, ServiceList, ErrorDisplay, etc.
- /hooks : useIdentity, useChannel, useErrorHandler, useServices, etc.
- /services : GraphResolver, LoginBuilder, SyncService.
- /utils : relay, storage, identity, crypto, canonical, encryption, verification, cache, bip32, pairing, iframeChannel, etc.
- /types : identity, message, contract, auth, etc.
Points notables
- Identité : création (secp256k1), import (clé hex 64 car. ou phrase BIP39, dérivation m/44'/0'/0'/0/0 ; passphrase BIP39 non supportée). Protection par mot de passe (PBKDF2 + AES-GCM), déverrouillage (UnlockScreen), verrouillage manuel.
- Relais : config dans LocalStorage, test
/health, GET/POST messages/signatures/keys viautils/relay. - Pairing : BIP32 UUID ↔ 8 mots (BIP32-style),
PairConfigavecmembres_parents_uuid,is_local,can_sign,publicKey?(optionnel, ECDH). WordInputGrid pour saisie. Confirmation croisée « membre finaliser » (IndexedDB), statut « Connecté ». - Graphe : GraphResolver avec caches (services, contrats, champs, actions, membres, pairs),
resolveLoginPath, validation des parents. - Login : LoginBuilder (challenge, nonce, chiffrement « for all », preuve avec signatures), publication message → signatures → clés.
- Sync : SyncService, HashCache (IndexedDB),
markSeenBatch, déduplication, fetch clés/signatures, vérification hash/signatures/timestamp, mise à jour du graphe. Détection des confirmations de pairing au sync. Acceptation : une version d'objet (MessageAValider) n'est acceptée que si elle est signée par les validateurs conformément aux conditions de l'action de validation ; voirfeatures/userwallet-acceptation-version-validateurs.md. DH : DH systématique et flux scan → fetch par hash → déchiffrer (login + MsgCle, pairing obligatoire, sync scan-first ECDH) ; voirfeatures/userwallet-dh-systematique-scan-fetch.md. - Iframe : iframeChannel + useChannel ; messages
auth-request,auth-response,login-proof,service-status,error; postMessage vers parent avec'*'. - Export/import : identité, relais, pairs, hash_cache, pairing_confirm (IndexedDB). « Supprimer » global avec option export avant suppression.
- ESLint : config flat,
typescript-eslint, type-aware ; voirfeatures/userwallet-eslint-fix.md.
3. api-relay (backend relais)
Voir api-relay/docs/synthese.md et api-relay/README.md.
Stack
- Express, CORS, JSON. TypeScript, build ESM (
node dist/index.js). Pino, compression, rate limiting, validation POST.
Structure
- /routes : messages, signatures, keys, health, metrics, bloom.
- /services : StorageService (index
byService), RelayService. - /lib : logger, validate. /middleware : CORS, logging HTTP, compression, rate limit.
Endpoints
- GET /health :
{ status: 'ok', timestamp }. - GET /messages?start=&end=&service= : messages dans la fenêtre, indexés par
service_uuid. - POST /messages, GET /messages/:hash : idem.
- GET/POST /signatures, GET /signatures/:hash : idem.
- GET/POST /keys, GET /keys/:hash : idem.
- GET /metrics : Prometheus (
relay_storage_entriespar kind). - GET /bloom : Bloom filter (JSON) des hash vus.
Comportement
- Storage : messages, signatures, keys,
seenHashesen mémoire ; tout persisté dansmessages.json. Sauvegarde à l’arrêt et périodique (SAVE_INTERVAL_SECONDS). Déduplication par hash ; relais uniquement si!alreadySeenavantstoreMessage. - Config : PORT, HOST, STORAGE_PATH, PEER_RELAYS, BODY_LIMIT, REQUEST_TIMEOUT_MS, RATE_LIMIT_*, CORS_ORIGINS, LOG_LEVEL. Déploiement :
start.sh,api-relay.service(systemd).
4. Liens entre UserWallet et api-relay
- UserWallet appelle les endpoints du relais (messages, signatures, keys, health) via
utils/relay. - Types alignés : MsgChiffre, MsgSignature, MsgCle (structure équivalente, noms français).
- UserWallet utilise
datajson_public(services_uuid, types_uuid, timestamp, etc.) comme le relais. - Ports : front 3018, relais 3019 (voir
ports.md).
5. Synthèse
| Élément | userwallet | api-relay |
|---|---|---|
| Rôle | Front login décentralisé (secp256k1, contrats, pairing mFA) | Relais stockage + diffusion messages/signatures/clés |
| Port | 3018 | 3019 |
| Stockage | LocalStorage (identité, relais, pairs) ; IndexedDB (hash_cache, pairing_confirm) ; protection optionnelle | Mémoire + JSON (messages, seenHashes, signatures, keys) |
| Specs | Aligné avec specs.md (graphe, ordre message→sig→clés, pull-only) | Séparation messages / signatures / clés, dédup par hash |
Reste à faire (contrat & login) : voir features/userwallet-contrat-login-reste-a-faire.md (machine à états, écrans, anti-rejeu, validation, etc.).