# UserWallet – Validation et conformité (3.5) **Author:** Équipe 4NK **Date:** 2026-01-26 ## Objectif Renforcer la validation : validateurs stricts, clé autorisée, version des contrats (specs). ## Impacts - **Clé autorisée** : vérification stricte des signatures avant publication login ; rejet si `cle_publique` non autorisée par les validateurs (X_PUBKEY_NOT_AUTHORIZED). - **Version contrats** : contrats en version non supportée exclus du graphe (sync) ; affichage de la version dans le chemin login. ## Modifications **Vérification stricte** - `utils/verification.ts` : `filterSignaturesByAuthorizedPubkeys`, `verifyMessageSignaturesStrict`. Garde `verifyMessageSignatures` (crypto seule) pour usage générique. - `utils/loginValidation.ts` : `buildAllowedPubkeys` (depuis requirements + pairs ; clé locale pour pair local), `checkCardinalitySupported` (refus si `cardinalite_minimale > 1`), **`checkDependenciesSatisfied`** (membres des `dependances` doivent avoir ≥1 sig dans la preuve via pair du membre). - `LoginScreen` : avant publish, `checkCardinalitySupported`, **`checkDependenciesSatisfied`** (sinon DEPENDENCIES_UNSATISFIED) ; `buildAllowedPubkeys` ; `verifyMessageSignaturesStrict` ; si sig non autorisée → X_PUBKEY_NOT_AUTHORIZED. **Version contrats** - `utils/contractVersion.ts` : `SUPPORTED_CONTRACT_VERSIONS` (ex. `['1.0']`), `isContractVersionSupported(version)`. - `SyncService.updateGraph` : pour chaque message de type contrat, test `isContractVersionSupported` ; si non supporté, log warning et skip (contrat isolé, non ajouté au graphe). - `LoginPath` : ajout de `contrat_version?: string`. `GraphResolver.resolveLoginPath` renseigne `contrat_version` dès qu’un contrat est résolu. - `LoginScreen` : affichage « Version contrat » dans la section chemin lorsque `contrat_version` est défini. ## Modalités de déploiement Déploiement classique du front userwallet. ## Modalités d’analyse - Contrat en base avec `version` non supportée → sync : log « Contrat … version … not supported, skipped », absent du graphe. - Login path résolu avec contrat → « Version contrat » affiché. - Preuve avec signature dont `cle_publique` hors validateurs (requirements ou résolution pairs) → X_PUBKEY_NOT_AUTHORIZED avant publish. - Requirement avec `cardinalite_minimale > 1` → CARDINALITY_UNSUPPORTED avant publish. - `dependances` non satisfaites (membre requis sans signature) → DEPENDENCIES_UNSATISFIED avant publish. ## Cardinalite_minimale — explication **Ce que ça veut dire** Dans les validateurs, un requirement peut avoir `cardinalite_minimale` (ex. 1, 2, …). Cela impose **au moins N signatures** pour ce requirement, en général venant de **N pairs distincts** du même membre (mFA). Ex. : « il faut 2 signatures du membre X » → 2 pairs (2 devices) doivent signer. **Pourquoi c’est refusé aujourd’hui** Le flux login ne produit **qu’une seule signature par requirement** (un pair par requirement). Si `cardinalite_minimale > 1`, on exigerait plusieurs sigs pour le même requirement, ce qui n’est pas implémenté. D’où le refus : avant publish, `checkCardinalitySupported` vérifie que tout requirement a `cardinalite_minimale` ≤ 1 ; sinon → CARDINALITY_UNSUPPORTED. **Implémenté (collecte distante 2 devices)** - Device 1 signe localement, publie message + sigs, puis **boucle de collecte** (fetch sigs par hash sur les relais) jusqu’à avoir assez de pairs distincts par membre (`hasEnoughSignatures`). - Device 2 ouvre `/login-sign?hash=...&nonce=...` (lien ou QR affiché pendant la collecte), signe `hash-nonce` avec son pair local, poste sa signature sur les relais. - Device 1 récupère ainsi les sigs du 2ᵉ appareil, finalise la preuve, vérifie (dépendances, clés autorisées), marque le nonce, envoie la preuve au parent. Voir `features/userwallet-collecte-distante-2-devices.md`. ## Références - `features/userwallet-contrat-login-reste-a-faire.md` (§ 3.5) - `userwallet/docs/specs.md` (validateurs, version)