ncantu f9fe0e3419 Website-skeleton partie connectée, contrat en dur, navigate-login; UserWallet pairing-relay-status, redirect; website-data, proxy data, cryptographie, fixKnowledge
**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.
2026-01-29 00:55:58 +01:00

183 lines
8.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Qui êtes-vous ? 4NK un nouveau web</title>
<style>
* { box-sizing: border-box; }
body {
font-family: system-ui, -apple-system, sans-serif;
max-width: 900px;
margin: 0 auto;
padding: 1rem;
line-height: 1.6;
color: #333;
}
h1 { font-size: 1.5rem; margin-bottom: 1rem; color: #222; }
h2 { font-size: 1.2rem; margin-top: 1.5rem; margin-bottom: 0.5rem; color: #333; }
p { margin: 0.75rem 0; }
ul { margin: 0.5rem 0; padding-left: 1.5rem; }
li { margin: 0.4rem 0; }
a { color: #007bff; }
a:hover { text-decoration: underline; }
.highlight { background: #e8f4fd; padding: 1rem; border-radius: 8px; border-left: 4px solid #007bff; margin: 1rem 0; }
.warning { background: #fff3cd; padding: 1rem; border-radius: 8px; border-left: 4px solid #ffc107; margin: 1rem 0; }
details { margin: 1rem 0; }
summary { cursor: pointer; font-weight: 600; color: #555; }
.meta { font-family: ui-monospace, monospace; font-size: 0.85rem; color: #666; background: #f5f5f5; padding: 0.2em 0.4em; border-radius: 4px; word-break: break-all; }
details h3 { font-size: 0.95rem; margin-top: 1rem; margin-bottom: 0.5rem; font-weight: 600; color: #555; }
#user-pairs-info ul { list-style: none; padding-left: 0; }
#user-pairs-info li { background: #f9f9f9; padding: 0.75rem; border-radius: 6px; margin: 0.5rem 0; border: 1px solid #e0e0e0; }
@media (max-width: 768px) {
body { padding: 0.75rem; }
h1 { font-size: 1.25rem; }
}
</style>
</head>
<body>
<h1>Qui êtes-vous ?</h1>
<p><a href="index.html">← Retour à l'accueil</a> · <a href="contrat.html">Voir le contrat</a> · <a href="technique.html">Réseau P2P</a> · <a href="cryptographie.html">Cryptographie</a></p>
<div class="highlight">
<strong>En résumé :</strong> Vous êtes un <strong>membre</strong> qui peut avoir plusieurs appareils (Pairs).
Chaque appareil possède ses propres clés et peut signer selon <strong>vos règles</strong>.
Vos données sont stockées selon les membres du contrat — vous gardez le contrôle total.
</div>
<h2>Vous êtes le « membre connecté »</h2>
<p>
Quand vous vous connectez à ce service, vous devenez un <strong>membre</strong>.
Contrairement aux sites classiques où vos identifiants sont stockés sur un serveur distant,
ici votre identité reste <strong>chez vous</strong>.
</p>
<h2>Un membre = plusieurs appareils</h2>
<p>
Un membre n'est pas limité à un seul appareil. Vous pouvez avoir <strong>plusieurs appareils</strong>
(ordinateur, téléphone, tablette) qui forment ensemble votre identité :
</p>
<ul>
<li>Chaque appareil s'appelle un « <strong>Pair</strong> » (device).</li>
<li>Chaque Pair possède <strong>sa propre paire de clés</strong> cryptographiques.</li>
<li>Tous vos Pairs peuvent signer en votre nom, selon les règles que <strong>vous</strong> définissez.</li>
</ul>
<p>
<em>Exemple :</em> Vous pouvez configurer votre ordinateur principal et votre téléphone comme deux Pairs.
Si l'un est perdu, vous gardez l'accès via l'autre.
</p>
<h2>Vous définissez les règles</h2>
<p>
Chaque membre a un <strong>contrat</strong> qui définit les règles de signature et de validation.
C'est <strong>vous</strong> qui contrôlez ces règles :
</p>
<ul>
<li><strong>Quels Pairs peuvent signer</strong> — vous décidez quels appareils sont autorisés.</li>
<li><strong>Combien de signatures sont requises</strong> — une seule, ou plusieurs pour plus de sécurité.</li>
<li><strong>Pour quelles actions</strong> — certaines actions peuvent nécessiter plus de validations.</li>
</ul>
<div class="highlight">
<strong>Exemple :</strong> Vous pouvez exiger qu'une action sensible (comme un paiement) soit signée
par <strong>2 de vos 3 appareils</strong> — c'est le principe du « multi-signature ».
</div>
<h2>Où sont stockées vos données ?</h2>
<p>
Les données du service sont stockées selon les <strong>membres définis dans le contrat</strong>.
Chaque membre a ses propres données, séparées des autres :
</p>
<ul>
<li><strong>Vos clés privées</strong> — sur vos appareils (Pairs), jamais sur le serveur.</li>
<li><strong>Vos données utilisateur</strong> — associées à votre identité de membre.</li>
<li><strong>Les preuves de signature</strong> — vérifiables publiquement, liées à vos Pairs.</li>
</ul>
<h2>Votre appareil = votre coffre-fort</h2>
<p>
Chaque appareil (Pair) joue le rôle de <strong>coffre-fort numérique</strong> :
</p>
<ul>
<li><strong>Vos clés de sécurité</strong> sont créées directement dans votre navigateur (dans la fenêtre de connexion).</li>
<li><strong>Elles ne quittent jamais votre appareil</strong> — elles sont stockées localement (IndexedDB).</li>
<li><strong>Personne d'autre n'y a accès</strong>, pas même le service.</li>
</ul>
<h2>Comment ça fonctionne ?</h2>
<ol>
<li>Vous cliquez sur « Se connecter ».</li>
<li>Une fenêtre s'ouvre (UserWallet) où vous déverrouillez votre identité.</li>
<li>Votre appareil <strong>signe</strong> une preuve que c'est bien vous (comme une signature manuscrite, mais numérique).</li>
<li>Le service vérifie cette preuve et vous donne accès.</li>
</ol>
<p>
À aucun moment vos clés secrètes ne sont transmises — seule la <strong>preuve</strong> de votre identité l'est.
</p>
<div class="warning">
<strong>Important :</strong> Si vous perdez l'accès à votre appareil (panne, vol, perte),
vous perdez vos clés. Pensez à configurer un second appareil ou une sauvegarde.
</div>
<h2>Quelle différence avec un mot de passe classique ?</h2>
<ul>
<li><strong>Mot de passe classique</strong> : stocké sur le serveur du site → risque de fuite en cas de piratage.</li>
<li><strong>Ici</strong> : vos clés restent sur votre appareil → même si le service est piraté, vos clés sont en sécurité.</li>
</ul>
<details>
<summary>Détails techniques (pour les curieux)</summary>
<ul>
<li>Vos clés utilisent la cryptographie <strong>secp256k1</strong> (la même que Bitcoin).</li>
<li>Elles sont stockées dans <strong>IndexedDB</strong> de votre navigateur.</li>
<li>La connexion utilise l'authentification multi-facteur (<strong>MFA</strong>).</li>
<li>Le service possède son propre portefeuille (wallet) séparé du vôtre, jamais exposé.</li>
</ul>
<h3>Vos Pairs et clés publiques</h3>
<div id="user-pairs-info">
<p><em>Non connecté — connectez-vous pour voir vos Pairs.</em></p>
</div>
</details>
<script>
(function() {
const SESSION_STORAGE_KEY = 'website-skeleton-session';
const container = document.getElementById('user-pairs-info');
if (!container) return;
const stored = sessionStorage.getItem(SESSION_STORAGE_KEY);
if (!stored) return;
try {
const session = JSON.parse(stored);
if (!session || !session.proof || !session.proof.signatures) return;
const signatures = session.proof.signatures;
if (signatures.length === 0) {
container.innerHTML = '<p><em>Aucun Pair enregistré.</em></p>';
return;
}
let html = '<ul>';
signatures.forEach(function(sig, index) {
const pairUuid = sig.pair_uuid || 'Non spécifié';
const pubKey = sig.cle_publique || 'Non disponible';
html += '<li>';
html += '<strong>Pair ' + (index + 1) + '</strong><br>';
html += 'UUID : <span class="meta">' + pairUuid + '</span><br>';
html += 'Clé publique : <span class="meta">' + pubKey + '</span>';
html += '</li>';
});
html += '</ul>';
container.innerHTML = html;
} catch (e) {
// Session parsing error - keep default message
}
})();
</script>
<p><a href="index.html">← Retour à l'accueil</a> · <a href="contrat.html">Voir le contrat</a> · <a href="technique.html">Réseau P2P</a> · <a href="cryptographie.html">Cryptographie</a></p>
</body>
</html>