**Motivations:** - Consigner l'état actuel du dépôt (cron, service-login-verify, website-skeleton, userwallet, docs). - Centraliser les modifications en attente. **Root causes:** - N/A (commit groupé). **Correctifs:** - N/A. **Evolutions:** - Cron quotidien restart services : script local sans SSH, systemd (bitcoin-signet, bitcoin, APIs, dashboard, userwallet, website-skeleton) + Docker (mempool, bitcoin-signet-instance). - Feature cron-restart-services-local : documentation et règle scripts locaux / pas d'SSH. - service-login-verify : module vérification login (buildAllowedPubkeys, verifyLoginProof, nonceCache). - website-skeleton : app iframe UserWallet, config, systemd unit. - userwallet : collectSignatures, relay. - docs : DOMAINS_AND_PORTS, README, WEBSITE_SKELETON ; features userwallet-contrat-login, timeouts-backoff, service-login-verify. **Pages affectées:** - data/restart-services-cron.sh, data/restart-services.log, data/sync-utxos.log - features/cron-restart-services-local.md, features/service-login-verify.md, features/userwallet-contrat-login-reste-a-faire.md, features/userwallet-timeouts-backoff.md - docs/DOMAINS_AND_PORTS.md, docs/README.md, docs/WEBSITE_SKELETON.md - configure-nginx-proxy.sh - service-login-verify/ (src, dist, node_modules) - userwallet/src/utils/collectSignatures.ts, userwallet/src/utils/relay.ts - website-skeleton/
4.6 KiB
4.6 KiB
Côté service – Acceptation de session et politique anti-rejeu (3.7)
Author: Équipe 4NK
Date: 2026-01-26
Explication
Rôle du « service »
Le service est l’application parente qui embarque UserWallet en iframe. C’est elle qui consomme le login : elle reçoit la preuve de login (login-proof) via postMessage, doit l’accepter ou refuser pour ouvrir une session, sans serveur central.
- UserWallet (iframe) envoie
{ type: 'login-proof', payload: LoginProof }au parent. - Le parent écoute
window.addEventListener('message', ...), filtreevent.data?.type === 'login-proof', puis vérifie la preuve avant d’accepter la session.
Acceptation de session
Le service doit vérifier la preuve en s’appuyant uniquement sur contrats + signatures :
- Graphe contractuel : le service dispose du contrat (et contrats fils) du service, fourni par channel message ou contrat par défaut. Il peut en déduire l’action login, les membres, les validateurs.
- Clés autorisées : à partir des validateurs de l’action login (
membres_du_role[].signatures_obligatoires[].cle_publique), construire l’ensemble descle_publiqueautorisées à signer. (Résolutionpair_uuid→ clé non utilisée côté service si seules lescle_publiqueexplicites sont présentes.) - Vérification crypto : pour chaque signature de la preuve, vérifier qu’elle signe bien
hash-nonce(hash du challenge + nonce) avec lacle_publiqueindiquée (secp256k1). - Conformité validateurs : toutes les signatures doivent provenir de clés autorisées ; au moins une signature valide est requise.
- Anti-rejeu : nonce unique (cache
nonce_vus), fenêtre temporelle sur letimestampdu challenge.
Aucune autorité centrale : la décision d’accepter ou refuser la session repose uniquement sur ces vérifications locales.
Politique anti-rejeu
- Nonce unique : chaque preuve utilise un nonce. Le service maintient un cache des nonces déjà vus (ex.
NonceCache). Si un nonce est rejoué dans la fenêtre TTL, la preuve est refusée (X_NONCE_REUSED). - Fenêtre timestamp : le
timestampdu challenge doit être dans une fenêtre acceptable (ex. ±5 min). Sinon refus (X_TIMESTAMP_OUT_OF_WINDOW). - Cache
nonce_vus: persistance optionnelle (mémoire, IndexedDB, Redis, etc.). Le package fournit un cache en mémoire avec TTL configurable ; le service peut le remplacer par un stockage adapté.
Implémentation
Le package service-login-verify fournit :
verifyLoginProof(proof, context): vérification complète (crypto, clés autorisées, timestamp, nonce).NonceCache: cache anti-rejeu en mémoire (TTL configurable).buildAllowedPubkeysFromValidateurs(validateurs): extraction descle_publiquedepuis les validateurs de l’action login.
Le service (parent) :
- Reçoit contrat + contrats fils (channel ou défaut).
- Extrait l’action login et ses validateurs, construit
allowedPubkeysviabuildAllowedPubkeysFromValidateurs. - Maintient une
NonceCache(ou équivalent). - À réception de
login-proof, appelleverifyLoginProof(proof, { allowedPubkeys, nonceCache, timestampWindowMs }). - Si
accept: true→ ouvrir la session ; sinon → refuser et optionnellement informer l’utilisateur (ex. viapostMessagevers l’iframe).
Limites
- Validateurs sans
cle_publique(uniquementpair_uuid) : le service ne peut pas vérifier les clés autorisées. Il faut au moins unecle_publiquedanssignatures_obligatoirespour une vérification stricte côté service. - Le service ne déchiffre pas le challenge ; il vérifie uniquement les signatures et l’anti-rejeu.
Utilisation
import {
verifyLoginProof,
NonceCache,
buildAllowedPubkeysFromValidateurs,
} from 'service-login-verify';
const nonceCache = new NonceCache(3600000);
const allowedPubkeys = buildAllowedPubkeysFromValidateurs(actionLogin.validateurs_action);
window.addEventListener('message', (event) => {
if (event.data?.type !== 'login-proof') return;
const result = verifyLoginProof(event.data.payload, {
allowedPubkeys,
nonceCache,
timestampWindowMs: 300000,
});
if (result.accept) {
// ouvrir session
} else {
// refuser (result.reason)
}
});
Références
features/userwallet-contrat-login-reste-a-faire.md(§ 3.7)userwallet/docs/specs.md(graphe, validateurs, anti-rejeu)service-login-verify/: implémentation (package à la racine du dépôt).website-skeleton/: squelette de site qui intègre l’iframe et vérifie les preuves.