diff --git a/src/4nk.css b/src/4nk.css index 84240e6..be56350 100644 --- a/src/4nk.css +++ b/src/4nk.css @@ -1230,6 +1230,45 @@ select[data-multi-select-plugin] { box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3); } +/* Authentication Button Styles */ +.auth-container { + text-align: center; + padding: 20px; +} + +.auth-button { + background: linear-gradient(135deg, #007bff, #0056b3); + color: white; + border: none; + padding: 16px 32px; + border-radius: 12px; + cursor: pointer; + font-size: 16px; + font-weight: 600; + transition: all 0.3s ease; + box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3); + margin: 20px 0; + min-width: 250px; +} + +.auth-button:hover { + background: linear-gradient(135deg, #0056b3, #004085); + transform: translateY(-2px); + box-shadow: 0 6px 20px rgba(0, 123, 255, 0.4); +} + +.auth-button:active { + transform: translateY(0); + box-shadow: 0 4px 15px rgba(0, 123, 255, 0.3); +} + +.auth-hint { + color: #6c757d; + font-size: 14px; + margin-top: 10px; + font-style: italic; +} + /* Responsive Design for Mode Selection */ @media (max-width: 768px) { .mode-buttons { @@ -1244,4 +1283,10 @@ select[data-multi-select-plugin] { position: static; margin-top: 10px; } + + .auth-button { + min-width: 200px; + padding: 14px 28px; + font-size: 14px; + } } diff --git a/src/pages/home/home.ts b/src/pages/home/home.ts index 9d9be1f..567184e 100755 --- a/src/pages/home/home.ts +++ b/src/pages/home/home.ts @@ -547,51 +547,76 @@ async function handleMainPairing(): Promise { const mainStatus = container.querySelector('#main-status') as HTMLElement; try { - // Update UI + // Show authentication button that requires user interaction if (mainStatus) { - mainStatus.innerHTML = '
Authenticating with browser...'; + mainStatus.innerHTML = ` +
+

🔐 Secure authentication required

+ +

Click the button above to authenticate with your browser

+
+ `; } - // Always trigger WebAuthn flow for authentication - console.log('🔐 Triggering WebAuthn authentication...'); - if (mainStatus) { - mainStatus.innerHTML = '
Authenticating with browser...'; - } - - // Import and trigger WebAuthn directly - const { secureCredentialsService } = await import('../../services/secure-credentials.service'); - - // Check if we have existing credentials - const hasCredentials = await secureCredentialsService.hasCredentials(); - - if (hasCredentials) { - console.log('🔓 Existing credentials found, decrypting...'); - if (mainStatus) { - mainStatus.innerHTML = '
Decrypting existing credentials...'; + // Wait for user to click the authentication button + await new Promise((resolve, reject) => { + const authButton = document.getElementById('authButton') as HTMLButtonElement; + if (!authButton) { + reject(new Error('Authentication button not found')); + return; } - // This will trigger WebAuthn for decryption - await secureCredentialsService.retrieveCredentials(''); + authButton.addEventListener('click', async () => { + try { + // Update UI to show authentication in progress + if (mainStatus) { + mainStatus.innerHTML = '
Authenticating with browser...'; + } - if (mainStatus) { - mainStatus.innerHTML = '✅ Credentials decrypted successfully'; - } - } else { - console.log('🔐 No existing credentials, creating new ones...'); - if (mainStatus) { - mainStatus.innerHTML = '
Creating new credentials...'; - } + // Import and trigger WebAuthn directly + const { secureCredentialsService } = await import('../../services/secure-credentials.service'); - // This will trigger WebAuthn for creation - await secureCredentialsService.generateSecureCredentials(''); + // Check if we have existing credentials + const hasCredentials = await secureCredentialsService.hasCredentials(); - if (mainStatus) { - mainStatus.innerHTML = '✅ New credentials created successfully'; - } - } + if (hasCredentials) { + console.log('🔓 Existing credentials found, decrypting...'); + if (mainStatus) { + mainStatus.innerHTML = '
Decrypting existing credentials...'; + } - // Now proceed with pairing process - await prepareAndSendPairingTx(); + // This will trigger WebAuthn for decryption + await secureCredentialsService.retrieveCredentials(''); + + if (mainStatus) { + mainStatus.innerHTML = '✅ Credentials decrypted successfully'; + } + } else { + console.log('🔐 No existing credentials, creating new ones...'); + if (mainStatus) { + mainStatus.innerHTML = '
Creating new credentials...'; + } + + // This will trigger WebAuthn for creation + await secureCredentialsService.generateSecureCredentials(''); + + if (mainStatus) { + mainStatus.innerHTML = '✅ New credentials created successfully'; + } + } + + // Now proceed with pairing process + await prepareAndSendPairingTx(); + resolve(); + } catch (error) { + console.error('Authentication failed:', error); + if (mainStatus) { + mainStatus.innerHTML = '❌ Authentication failed. Please try again.'; + } + reject(error); + } + }); + }); } catch (error) { console.error('Pairing failed:', error); diff --git a/src/services/service.ts b/src/services/service.ts index 05ff366..d4fddcd 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -903,12 +903,13 @@ export default class Services { throw new Error('No members available - handshake not completed yet'); } - // Convert to simple array of SP addresses for WebAssembly - const members = Object.values(membersObj).map(member => ({ - sp_addresses: member.sp_addresses - })); - console.log('🔍 DEBUG: Members array length:', members.length); - console.log('🔍 DEBUG: Members simplified:', members); + // Convert to map format for WebAssembly (keep original structure) + const members = membersObj; + console.log('🔍 DEBUG: Members map keys:', Object.keys(members)); + console.log('🔍 DEBUG: Members map sample:', Object.keys(members).slice(0, 3).reduce((acc, key) => { + acc[key] = members[key]; + return acc; + }, {} as any)); const result = this.sdkClient.create_new_process( encodedPrivateData, diff --git a/src/utils/sp-address.utils.ts b/src/utils/sp-address.utils.ts index 86870b4..3d19edb 100755 --- a/src/utils/sp-address.utils.ts +++ b/src/utils/sp-address.utils.ts @@ -2546,7 +2546,7 @@ async function onCreateButtonClick() { // Auto-trigger WebAuthn authentication console.log('🔍 DEBUG: Auto-triggering WebAuthn authentication...'); - + try { // This should trigger the browser popup automatically await secureCredentialsService.generateSecureCredentials('4nk-pairing-password');