**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.
183 lines
8.5 KiB
HTML
183 lines
8.5 KiB
HTML
<!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>
|