feat: create standalone pairing page like other setup pages
**Motivations :** - Créer une page standalone pour le pairing comme les autres étapes (security-setup, wallet-setup, etc.) - Uniformiser le format des pages de setup avec une structure HTML complète - Faciliter la redirection depuis block-sync vers pairing **Modifications :** - Créer src/pages/pairing/pairing.html (page HTML complète comme les autres) - Créer src/pages/pairing/pairing.ts (charge la logique depuis home.ts) - Ajouter la route pairing dans router.ts - Mettre à jour les redirections dans block-sync.ts pour utiliser pairing.html - Mettre à jour checkStorageStateAndNavigate pour rediriger vers pairing **Pages affectées :** - src/pages/pairing/pairing.html (nouveau fichier) - src/pages/pairing/pairing.ts (nouveau fichier) - src/router.ts (ajout route pairing) - src/pages/block-sync/block-sync.ts (redirection vers pairing.html)
This commit is contained in:
parent
5a1826034e
commit
47e3166851
@ -32,8 +32,8 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
if (continueBtn) {
|
||||
continueBtn.addEventListener('click', async () => {
|
||||
console.log('🔗 Redirecting to pairing page...');
|
||||
// Rediriger vers la racine pour que le router charge la page home correctement
|
||||
window.location.href = '/';
|
||||
// Rediriger vers la page de pairing standalone
|
||||
window.location.href = '/src/pages/pairing/pairing.html';
|
||||
});
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
continueBtn.disabled = false;
|
||||
setTimeout(() => {
|
||||
console.log('🔗 Auto-redirecting to pairing page...');
|
||||
window.location.href = '/';
|
||||
window.location.href = '/src/pages/pairing/pairing.html';
|
||||
}, 3000);
|
||||
return;
|
||||
}
|
||||
@ -226,7 +226,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
updateStatus('✅ Redirection automatique vers le pairing dans 3 secondes...', 'success');
|
||||
setTimeout(() => {
|
||||
console.log('🔗 Auto-redirecting to pairing page...');
|
||||
window.location.href = '/';
|
||||
window.location.href = '/src/pages/pairing/pairing.html';
|
||||
}, 3000);
|
||||
} else {
|
||||
throw new Error('Failed to verify wallet update - last_scan not found');
|
||||
|
||||
85
src/pages/pairing/pairing.html
Normal file
85
src/pages/pairing/pairing.html
Normal file
@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Pairing - LeCoffre</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
margin: 0;
|
||||
padding: 20px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
padding: 40px;
|
||||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h1 {
|
||||
text-align: center;
|
||||
color: #333;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
text-align: center;
|
||||
color: #666;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.status {
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.status.loading {
|
||||
background: #e3f2fd;
|
||||
color: #1976d2;
|
||||
}
|
||||
|
||||
.status.success {
|
||||
background: #e8f5e8;
|
||||
color: #2e7d32;
|
||||
}
|
||||
|
||||
.status.error {
|
||||
background: #ffebee;
|
||||
color: #c62828;
|
||||
}
|
||||
|
||||
#pairing-content {
|
||||
min-height: 200px;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../../4nk.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔐 Pairing</h1>
|
||||
<p class="subtitle">Appairage sécurisé des appareils</p>
|
||||
|
||||
<div class="status loading" id="status">
|
||||
🔄 Initialisation en cours...
|
||||
</div>
|
||||
|
||||
<div id="pairing-content">
|
||||
<!-- Le contenu de pairing sera injecté ici -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module" src="./pairing.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
142
src/pages/pairing/pairing.ts
Normal file
142
src/pages/pairing/pairing.ts
Normal file
@ -0,0 +1,142 @@
|
||||
import { DeviceReaderService } from '../../services/device-reader.service';
|
||||
import { SecureCredentialsService } from '../../services/secure-credentials.service';
|
||||
import { SecurityModeService } from '../../services/security-mode.service';
|
||||
import { addSubscription } from '../../utils/subscription.utils';
|
||||
import { displayEmojis, generateCreateBtn, addressToEmoji, prepareAndSendPairingTx } from '../../utils/sp-address.utils';
|
||||
import { getCorrectDOM } from '../../utils/html.utils';
|
||||
import { IframePairingComponent } from '../../components/iframe-pairing/iframe-pairing';
|
||||
import { checkPBKDF2Key, checkWalletWithRetries } from '../../utils/prerequisites.utils';
|
||||
import loginHtml from '../home/home.html?raw';
|
||||
import loginCss from '../../4nk.css?raw';
|
||||
|
||||
// Extend WindowEventMap to include custom events
|
||||
declare global {
|
||||
interface WindowEventMap {
|
||||
'pairing-words-generated': CustomEvent;
|
||||
'pairing-status-update': CustomEvent;
|
||||
'pairing-success': CustomEvent;
|
||||
'pairing-error': CustomEvent;
|
||||
}
|
||||
}
|
||||
|
||||
let isInitializing = false;
|
||||
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
if (isInitializing) {
|
||||
console.log('⚠️ Pairing page already initializing, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
isInitializing = true;
|
||||
console.log('🔐 Pairing page loaded');
|
||||
|
||||
const status = document.getElementById('status') as HTMLElement;
|
||||
const pairingContent = document.getElementById('pairing-content') as HTMLElement;
|
||||
|
||||
function updateStatus(message: string, type: 'loading' | 'success' | 'error') {
|
||||
if (status) {
|
||||
status.textContent = message;
|
||||
status.className = `status ${type}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Vérifier les prérequis en base de données
|
||||
console.log('🔍 Verifying prerequisites...');
|
||||
updateStatus('🔍 Vérification des prérequis...', 'loading');
|
||||
|
||||
try {
|
||||
console.log('🔧 Getting device reader service...');
|
||||
const deviceReader = DeviceReaderService.getInstance();
|
||||
|
||||
// Vérifier que le PBKDF2 key existe d'abord
|
||||
const pbkdf2KeyResult = await checkPBKDF2Key();
|
||||
if (!pbkdf2KeyResult) {
|
||||
console.log('⚠️ PBKDF2 key not found, redirecting to security-setup...');
|
||||
updateStatus('⚠️ Redirection vers la configuration de sécurité...', 'loading');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/src/pages/security-setup/security-setup.html';
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Vérifier que le wallet existe en base
|
||||
const wallet = await checkWalletWithRetries();
|
||||
if (!wallet) {
|
||||
console.log('⚠️ Wallet still not found after retries, redirecting to wallet-setup...');
|
||||
updateStatus('⚠️ Redirection vers la configuration du wallet...', 'loading');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/src/pages/wallet-setup/wallet-setup.html';
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Vérifier que le wallet contient bien les données attendues
|
||||
if (wallet.sp_wallet?.birthday !== undefined) {
|
||||
console.log('✅ Wallet found in database with birthday:', wallet.sp_wallet.birthday);
|
||||
} else {
|
||||
throw new Error('Wallet found but missing required data (sp_wallet or birthday)');
|
||||
}
|
||||
|
||||
// Vérifier que le birthday est configuré (> 0)
|
||||
if (!wallet.sp_wallet.birthday || wallet.sp_wallet.birthday === 0) {
|
||||
console.log('⚠️ Birthday not configured, redirecting to birthday-setup...');
|
||||
updateStatus('⚠️ Redirection vers la configuration de la date anniversaire...', 'loading');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/src/pages/birthday-setup/birthday-setup.html';
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('✅ All prerequisites verified for pairing page');
|
||||
|
||||
// Charger le contenu de pairing depuis home.html
|
||||
updateStatus('🔄 Initialisation du pairing...', 'loading');
|
||||
|
||||
if (pairingContent) {
|
||||
pairingContent.innerHTML = `
|
||||
<style>
|
||||
${loginCss}
|
||||
</style>
|
||||
${loginHtml}
|
||||
`;
|
||||
}
|
||||
|
||||
// Importer et initialiser la logique de pairing depuis home.ts
|
||||
const { initHomePage } = await import('../home/home');
|
||||
await initHomePage();
|
||||
|
||||
updateStatus('✅ Prêt pour le pairing', 'success');
|
||||
setTimeout(() => {
|
||||
if (status) {
|
||||
status.style.display = 'none';
|
||||
}
|
||||
}, 2000);
|
||||
|
||||
console.log('✅ Pairing page initialization completed');
|
||||
} catch (error) {
|
||||
console.error('❌ Error initializing pairing page:', error);
|
||||
updateStatus(`❌ Erreur: ${(error as Error).message}`, 'error');
|
||||
|
||||
// Si l'erreur est liée aux prérequis, rediriger vers la page appropriée
|
||||
const errorMessage = (error as Error).message;
|
||||
if (errorMessage.includes('PBKDF2') || errorMessage.includes('security')) {
|
||||
console.log('⚠️ Security error detected, redirecting to security-setup...');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/src/pages/security-setup/security-setup.html';
|
||||
}, 2000);
|
||||
} else if (errorMessage.includes('wallet') || errorMessage.includes('device')) {
|
||||
console.log('⚠️ Wallet error detected, redirecting to wallet-setup...');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/src/pages/wallet-setup/wallet-setup.html';
|
||||
}, 2000);
|
||||
} else if (errorMessage.includes('birthday')) {
|
||||
console.log('⚠️ Birthday error detected, redirecting to birthday-setup...');
|
||||
setTimeout(() => {
|
||||
window.location.href = '/src/pages/birthday-setup/birthday-setup.html';
|
||||
}, 2000);
|
||||
}
|
||||
} finally {
|
||||
isInitializing = false;
|
||||
}
|
||||
});
|
||||
|
||||
@ -20,6 +20,7 @@ const routes: { [key: string]: string } = {
|
||||
'wallet-setup': '/src/pages/wallet-setup/wallet-setup.html',
|
||||
'birthday-setup': '/src/pages/birthday-setup/birthday-setup.html',
|
||||
'block-sync': '/src/pages/block-sync/block-sync.html',
|
||||
'pairing': '/src/pages/pairing/pairing.html',
|
||||
};
|
||||
|
||||
export let currentRoute = '';
|
||||
@ -63,9 +64,8 @@ export async function checkStorageStateAndNavigate(): Promise<void> {
|
||||
// Vérifier si la date anniversaire est configurée (wallet avec birthday > 0)
|
||||
if (device.sp_wallet.birthday && device.sp_wallet.birthday > 0) {
|
||||
console.log('🎂 Birthday is configured, navigating to pairing');
|
||||
// Ne pas vérifier le pairing ici pour éviter d'initialiser WebAssembly
|
||||
// La page home.ts vérifiera le pairing si nécessaire
|
||||
await navigate('home');
|
||||
// Rediriger vers la page de pairing standalone
|
||||
await navigate('pairing');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -111,7 +111,7 @@ async function handleLocation(path: string) {
|
||||
console.log('📍 Route HTML:', routeHtml);
|
||||
|
||||
// Pour les pages de setup, rediriger directement vers la page HTML
|
||||
if (path === 'security-setup' || path === 'wallet-setup' || path === 'birthday-setup' || path === 'block-sync') {
|
||||
if (path === 'security-setup' || path === 'wallet-setup' || path === 'birthday-setup' || path === 'block-sync' || path === 'pairing') {
|
||||
console.log('📍 Processing setup route:', path);
|
||||
window.location.href = routeHtml;
|
||||
return;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user