feat: Ajout du bouton de suppression de compte et logique de chargement automatique

- Bouton rouge 'Supprimer' dans le menu burger avec confirmation sécurisée
- Fonction deleteAccount() qui nettoie complètement le compte (IndexedDB, localStorage, sessionStorage)
- Logique d'initialisation intelligente :
  - Si wallet existe et est appairé → redirection vers /account
  - Si wallet existe mais pas appairé → redirection vers /home pour pairing
  - Si aucun wallet → création d'un nouveau compte
- CSS pour le bouton de suppression avec style rouge distinctif
- Confirmation en deux étapes pour éviter les suppressions accidentelles
This commit is contained in:
NicolasCantu 2025-10-22 15:46:50 +02:00
parent 50f782908d
commit 08b47b17b8
4 changed files with 98 additions and 0 deletions

View File

@ -656,6 +656,17 @@ h1 {
border-bottom: none;
}
.delete-account-btn {
color: #f44336 !important;
font-weight: bold;
background-color: rgba(244, 67, 54, 0.1) !important;
}
.delete-account-btn:hover {
background-color: rgba(244, 67, 54, 0.2) !important;
color: #d32f2f !important;
}
.qr-code-scanner {
display: none;
}

View File

@ -30,6 +30,7 @@
<a onclick="navigate('signature')">Signatures</a>
<a onclick="navigate('process')">Process</a>
<a onclick="disconnect()">Disconnect</a>
<a onclick="deleteAccount()" class="delete-account-btn">🗑️ Supprimer</a>
</div>
</div>
</div>

View File

@ -144,9 +144,31 @@ export async function init(): Promise<void> {
console.log('🚀 ~ setTimeout ~ device:', device);
if (!device) {
// No wallet exists, create new account
console.log('🔍 No existing wallet found, creating new account...');
await services.createNewDevice();
} else {
// Wallet exists, restore it and check pairing
console.log('🔍 Existing wallet found, restoring account...');
services.restoreDevice(device);
// Check if device is paired
const isPaired = device.pairing_process_commitment !== null && device.pairing_process_commitment !== '';
console.log('🔍 Device pairing status:', isPaired ? 'Paired' : 'Not paired');
if (isPaired) {
// Device is paired, redirect to account page
console.log('✅ Device is paired, redirecting to account page...');
setTimeout(() => {
navigate('account');
}, 1000);
} else {
// Device exists but not paired, redirect to home for pairing
console.log('⚠️ Device exists but not paired, redirecting to home for pairing...');
setTimeout(() => {
navigate('home');
}, 1000);
}
}
// If we create a new device, we most probably don't have anything in db, but just in case
@ -979,6 +1001,30 @@ async function injectHeader() {
(window as any).navigate = navigate;
// Global function to delete account
(window as any).deleteAccount = async () => {
if (confirm('⚠️ Êtes-vous sûr de vouloir supprimer complètement votre compte ?\n\nCette action est IRRÉVERSIBLE et supprimera :\n• Tous vos processus\n• Toutes vos données\n• Votre wallet\n• Votre historique\n\nTapez "SUPPRIMER" pour confirmer.')) {
const confirmation = prompt('Tapez "SUPPRIMER" pour confirmer la suppression :');
if (confirmation === 'SUPPRIMER') {
try {
const services = await Services.getInstance();
await services.deleteAccount();
// Show success message
alert('✅ Compte supprimé avec succès !\n\nLa page va se recharger pour redémarrer l\'application.');
// Reload the page to restart the application
window.location.reload();
} catch (error) {
console.error('❌ Erreur lors de la suppression du compte:', error);
alert('❌ Erreur lors de la suppression du compte. Veuillez réessayer.');
}
} else {
alert('❌ Suppression annulée. Le texte de confirmation ne correspond pas.');
}
}
};
document.addEventListener('navigate', ((e: Event) => {
const event = e as CustomEvent<{page: string, processId?: string}>;
if (event.detail.page === 'chat') {

View File

@ -1118,6 +1118,46 @@ export default class Services {
}
}
async deleteAccount(): Promise<void> {
const db = await Database.getInstance();
try {
// Clear all stores
await db.clearStore('wallet');
await db.clearStore('processes');
await db.clearStore('shared_secrets');
await db.clearStore('unconfirmed_secrets');
await db.clearStore('diffs');
await db.clearStore('data');
await db.clearStore('labels');
// Clear localStorage
localStorage.clear();
sessionStorage.clear();
// Clear IndexedDB completely
await this.clearAllIndexedDB();
console.log('✅ Account completely deleted');
} catch (e) {
console.error('❌ Error deleting account:', e);
throw new Error(`Failed to delete account: ${e}`);
}
}
private async clearAllIndexedDB(): Promise<void> {
return new Promise((resolve, reject) => {
const deleteReq = indexedDB.deleteDatabase('4nk');
deleteReq.onsuccess = () => {
console.log('✅ IndexedDB database deleted');
resolve();
};
deleteReq.onerror = () => {
console.error('❌ Error deleting IndexedDB database');
reject(deleteReq.error);
};
});
}
async getMemberFromDevice(): Promise<string[] | null> {
try {
const device = await this.getDeviceFromDatabase();