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

233 lines
6.6 KiB
HTML

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>4NK un nouveau web - site d'exemple</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.5;
}
h1 {
font-size: 1.5rem;
margin-bottom: 1rem;
}
.button-group {
margin: 1rem 0;
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
button {
padding: 0.625rem 1.25rem;
font-size: 1rem;
border: 1px solid #ccc;
border-radius: 6px;
background: #fff;
cursor: pointer;
transition: all 0.2s;
min-height: 44px;
}
button:hover {
background: #f5f5f5;
border-color: #999;
}
button:active {
background: #e0e0e0;
}
button.primary {
background: #007bff;
color: white;
border-color: #007bff;
}
button.primary:hover {
background: #0056b3;
border-color: #0056b3;
}
button.danger {
background: #dc3545;
color: white;
border-color: #dc3545;
}
button.danger:hover {
background: #c82333;
border-color: #c82333;
}
#iframe-container {
margin: 1.5rem 0;
border-radius: 12px;
overflow: hidden;
background: #fff;
box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
border: 1px solid #e0e0e0;
}
.iframe-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 0.75rem 1rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.iframe-header-icon {
width: 24px;
height: 24px;
background: rgba(255,255,255,0.2);
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.iframe-header-title {
font-weight: 600;
font-size: 0.95rem;
}
.iframe-header-subtitle {
font-size: 0.8rem;
opacity: 0.85;
margin-left: auto;
}
#iframe-container iframe {
width: 100%;
height: 550px;
border: 0;
display: block;
background: #fafafa;
}
#connected-section {
padding: 0;
margin: 1rem 0;
}
.connected-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 0;
margin-bottom: 1rem;
border-bottom: 1px solid #e0e0e0;
}
.connected-avatar {
width: 48px;
height: 48px;
border-radius: 50%;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 1.25rem;
flex-shrink: 0;
}
.connected-notifications {
width: 44px;
height: 44px;
min-width: 44px;
min-height: 44px;
border: 1px solid #ccc;
border-radius: 8px;
background: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s;
}
.connected-notifications:hover {
background: #f5f5f5;
border-color: #999;
}
.connected-notifications svg {
width: 24px;
height: 24px;
}
#user-info {
margin: 1rem 0;
padding: 1rem;
background: white;
border-radius: 4px;
border: 1px solid #ddd;
}
@media (max-width: 768px) {
body {
padding: 0.75rem;
}
h1 {
font-size: 1.25rem;
}
#iframe-container {
margin: 1rem 0;
border-radius: 8px;
}
#iframe-container iframe {
height: 500px;
}
.iframe-header {
padding: 0.6rem 0.8rem;
}
.iframe-header-subtitle {
display: none;
}
button {
width: 100%;
margin-bottom: 0.5rem;
}
.button-group {
flex-direction: column;
}
}
@media (max-width: 480px) {
#iframe-container iframe {
height: 450px;
}
}
</style>
</head>
<body>
<h1>4NK un nouveau web - site d'exemple</h1>
<div id="login-section">
<p><a href="contrat.html">Le contrat</a> · <a href="membre.html">Qui êtes-vous ?</a> · <a href="technique.html">Réseau P2P</a> · <a href="cryptographie.html">Cryptographie</a></p>
<p id="waiting-status" style="display: none;" role="status" aria-live="polite">Vérification du statut pairing et relais…</p>
<div class="button-group">
<button type="button" id="btn-login" class="primary">Se connecter</button>
</div>
<div id="iframe-container" style="display: none;">
<div class="iframe-header">
<div class="iframe-header-icon">🔐</div>
<span class="iframe-header-title">UserWallet</span>
<span class="iframe-header-subtitle">Connexion sécurisée</span>
</div>
<iframe id="userwallet" title="UserWallet"></iframe>
</div>
</div>
<div id="connected-section" style="display: none;">
<header class="connected-header" aria-label="Zone connectée">
<div class="connected-avatar" aria-hidden="true" title="Avatar">👤</div>
<button type="button" class="connected-notifications" aria-label="Notifications" title="Notifications">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path>
<path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
</svg>
</button>
</header>
<h2>Vous êtes connecté</h2>
<div id="user-info"></div>
<p><a href="contrat.html">Le contrat</a> · <a href="membre.html">Qui êtes-vous ?</a> · <a href="technique.html">Réseau P2P</a> · <a href="cryptographie.html">Cryptographie</a></p>
<div class="button-group">
<button type="button" id="btn-logout" class="danger">Se déconnecter</button>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>