**Motivations:** - website-skeleton needs a real service contract with valid UUIDs and validators - Service wallet required for production use with configurable public key - Iframe styling needs improvement to remove scrollbars and match UserWallet theme **Root causes:** - DEFAULT_VALIDATEURS used placeholder public key that cannot verify signatures - No service wallet generation script for production deployment - Iframe had fixed height causing scrollbars and visual mismatch with dark theme **Correctifs:** - Created real service contract in src/serviceContract.ts with dedicated UUIDs (skeleton-service-uuid-4nkweb-2026) - Added service wallet generation script (generate-service-wallet.mjs) with .env and .env.private files - Improved iframe container styling: increased height (800px), dark background (#1a1a1a), better shadows, hidden scrollbars - Added .env.private to .gitignore for security **Evolutions:** - Service contract automatically loaded on startup and sent to UserWallet iframe - Public key configurable via VITE_SKELETON_SERVICE_PUBLIC_KEY environment variable - Added npm script 'generate-wallet' for easy wallet generation - Enhanced iframe visual integration with UserWallet dark theme **Pages affectées:** - website-skeleton/src/serviceContract.ts (new) - website-skeleton/src/config.ts - website-skeleton/src/main.ts - website-skeleton/generate-service-wallet.mjs (new) - website-skeleton/index.html - website-skeleton/package.json - website-skeleton/.gitignore - website-skeleton/.env (new) - website-skeleton/.env.private (new)
183 lines
8.3 KiB
HTML
183 lines
8.3 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></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></p>
|
||
</body>
|
||
</html>
|