diff --git a/src/4nk.css b/src/4nk.css
index 53a2968..84240e6 100644
--- a/src/4nk.css
+++ b/src/4nk.css
@@ -1181,6 +1181,55 @@ select[data-multi-select-plugin] {
right: 0;
}
+/* Status Container - Match button width */
+.status-container {
+ width: 100%;
+ margin: 20px 0;
+}
+
+.status-indicator {
+ width: 100%;
+ text-align: center;
+ padding: 15px;
+ background: #f8f9fa;
+ border: 1px solid #e9ecef;
+ border-radius: 8px;
+ font-size: 14px;
+ color: #495057;
+}
+
+/* Account Actions */
+.account-actions {
+ margin-top: 30px;
+ padding-top: 20px;
+ border-top: 1px solid #e9ecef;
+ text-align: center;
+}
+
+.danger-btn {
+ background: #dc3545;
+ color: white;
+ border: none;
+ padding: 12px 24px;
+ border-radius: 8px;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 500;
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
+}
+
+.danger-btn:hover {
+ background: #c82333;
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(220, 53, 69, 0.4);
+}
+
+.danger-btn:active {
+ transform: translateY(0);
+ box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
+}
+
/* Responsive Design for Mode Selection */
@media (max-width: 768px) {
.mode-buttons {
diff --git a/src/pages/home/home.html b/src/pages/home/home.html
index 6cc37aa..1bd4749 100755
--- a/src/pages/home/home.html
+++ b/src/pages/home/home.html
@@ -16,6 +16,10 @@
+
+
+
+
diff --git a/src/pages/home/home.ts b/src/pages/home/home.ts
index 70144ff..5180d93 100755
--- a/src/pages/home/home.ts
+++ b/src/pages/home/home.ts
@@ -120,6 +120,9 @@ export async function initHomePage(): Promise {
// Set up main pairing interface
setupMainPairing();
+
+ // Set up account actions
+ setupAccountActions();
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
container.querySelectorAll('.tab').forEach(tab => {
@@ -520,10 +523,10 @@ export function setupIframePairingButtons() {
// Main Pairing Interface
export function setupMainPairing(): void {
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
-
+
const mainPairingButton = container.querySelector('#mainPairingButton') as HTMLButtonElement;
const mainStatus = container.querySelector('#main-status') as HTMLElement;
-
+
if (mainPairingButton) {
mainPairingButton.addEventListener('click', async () => {
await handleMainPairing();
@@ -535,7 +538,7 @@ async function handleMainPairing(): Promise {
const container = getCorrectDOM('login-4nk-component') as HTMLElement;
const mainStatus = container.querySelector('#main-status') as HTMLElement;
const mainPairingButton = container.querySelector('#mainPairingButton') as HTMLButtonElement;
-
+
try {
// Update UI
if (mainStatus) {
@@ -550,16 +553,16 @@ async function handleMainPairing(): Promise {
const service = await Services.getInstance();
const { secureCredentialsService } = await import('../../services/secure-credentials.service');
const hasCredentials = await secureCredentialsService.hasCredentials();
-
+
if (hasCredentials) {
// Existing pairing - decrypt credentials
console.log('🔓 Existing credentials found, decrypting...');
if (mainStatus) {
mainStatus.innerHTML = 'Decrypting existing credentials...';
}
-
+
await secureCredentialsService.retrieveCredentials(''); // Empty password for WebAuthn
-
+
if (mainStatus) {
mainStatus.innerHTML = '✅ Credentials decrypted successfully';
}
@@ -569,31 +572,130 @@ async function handleMainPairing(): Promise {
if (mainStatus) {
mainStatus.innerHTML = 'Creating new secure pairing...';
}
-
+
// This will trigger the WebAuthn flow and create new credentials
await prepareAndSendPairingTx();
-
+
if (mainStatus) {
mainStatus.innerHTML = '✅ New pairing created successfully';
}
}
-
+
// Re-enable button
if (mainPairingButton) {
mainPairingButton.disabled = false;
mainPairingButton.textContent = 'Authenticate with Browser';
}
-
+
} catch (error) {
console.error('Pairing failed:', error);
-
+
if (mainStatus) {
mainStatus.innerHTML = '❌ Authentication failed';
}
-
+
if (mainPairingButton) {
mainPairingButton.disabled = false;
mainPairingButton.textContent = 'Authenticate with Browser';
}
}
}
+
+// Account Actions
+export function setupAccountActions(): void {
+ const container = getCorrectDOM('login-4nk-component') as HTMLElement;
+
+ const deleteAccountButton = container.querySelector('#deleteAccountButton') as HTMLButtonElement;
+
+ if (deleteAccountButton) {
+ deleteAccountButton.addEventListener('click', async () => {
+ await handleDeleteAccount();
+ });
+ }
+}
+
+async function handleDeleteAccount(): Promise {
+ const container = getCorrectDOM('login-4nk-component') as HTMLElement;
+ const mainStatus = container.querySelector('#main-status') as HTMLElement;
+
+ // Confirmation dialog
+ const confirmed = confirm(
+ '⚠️ WARNING: This will permanently delete your account and all associated data.\n\n' +
+ 'This action cannot be undone!\n\n' +
+ 'Are you sure you want to delete your account?'
+ );
+
+ if (!confirmed) {
+ return;
+ }
+
+ // Double confirmation
+ const doubleConfirmed = confirm(
+ '🚨 FINAL WARNING: You are about to permanently delete your account.\n\n' +
+ 'All your data, credentials, and pairings will be lost forever.\n\n' +
+ 'Type "DELETE" to confirm (case sensitive):'
+ );
+
+ if (doubleConfirmed) {
+ const userInput = prompt('Type "DELETE" to confirm account deletion:');
+ if (userInput !== 'DELETE') {
+ if (mainStatus) {
+ mainStatus.innerHTML = '❌ Account deletion cancelled - confirmation text did not match';
+ }
+ return;
+ }
+ } else {
+ return;
+ }
+
+ try {
+ if (mainStatus) {
+ mainStatus.innerHTML = 'Deleting account and all data...';
+ }
+
+ // Get services
+ const service = await Services.getInstance();
+ const { secureCredentialsService } = await import('../../services/secure-credentials.service');
+
+ // Delete all credentials
+ await secureCredentialsService.deleteCredentials();
+
+ // Clear all local storage
+ localStorage.clear();
+ sessionStorage.clear();
+
+ // Clear IndexedDB
+ if ('indexedDB' in window) {
+ const databases = await indexedDB.databases();
+ for (const db of databases) {
+ if (db.name) {
+ indexedDB.deleteDatabase(db.name);
+ }
+ }
+ }
+
+ // Clear service worker caches
+ if ('caches' in window) {
+ const cacheNames = await caches.keys();
+ await Promise.all(
+ cacheNames.map(cacheName => caches.delete(cacheName))
+ );
+ }
+
+ if (mainStatus) {
+ mainStatus.innerHTML = '✅ Account and all data deleted successfully';
+ }
+
+ // Reload the page to start fresh
+ setTimeout(() => {
+ window.location.reload();
+ }, 2000);
+
+ } catch (error) {
+ console.error('Account deletion failed:', error);
+
+ if (mainStatus) {
+ mainStatus.innerHTML = '❌ Failed to delete account';
+ }
+ }
+}