Removed interference with extensions. Had to go back to only allowing handling single extension.

This commit is contained in:
Your Name
2025-09-16 11:55:47 -04:00
parent 77ea4a8e67
commit 995c3f526c
3 changed files with 595 additions and 123 deletions

View File

@@ -332,23 +332,62 @@ class Modal {
}
_handleExtension() {
// Detect all available real extensions
const availableExtensions = this._detectAllExtensions();
// SIMPLIFIED ARCHITECTURE: Check for single extension at window.nostr or preserved extension
let extension = null;
console.log(`Modal: Found ${availableExtensions.length} extensions:`, availableExtensions.map(e => e.displayName));
if (availableExtensions.length === 0) {
console.log('Modal: No real extensions found');
this._showExtensionRequired();
} else if (availableExtensions.length === 1) {
// Single extension - use it directly without showing choice UI
console.log('Modal: Single extension detected, using it directly:', availableExtensions[0].displayName);
this._tryExtensionLogin(availableExtensions[0].extension);
} else {
// Multiple extensions - show choice UI
console.log('Modal: Multiple extensions detected, showing choice UI for', availableExtensions.length, 'extensions');
this._showExtensionChoice(availableExtensions);
// Check if NostrLite instance has a preserved extension (real extension detected at init)
if (window.NOSTR_LOGIN_LITE?._instance?.preservedExtension) {
extension = window.NOSTR_LOGIN_LITE._instance.preservedExtension;
console.log('Modal: Using preserved extension:', extension.constructor?.name);
}
// Otherwise check current window.nostr
else if (window.nostr && this._isRealExtension(window.nostr)) {
extension = window.nostr;
console.log('Modal: Using current window.nostr extension:', extension.constructor?.name);
}
if (!extension) {
console.log('Modal: No extension detected yet, waiting for deferred detection...');
// DEFERRED EXTENSION CHECK: Extensions like nos2x might load after our library
let attempts = 0;
const maxAttempts = 10; // Try for 2 seconds
const checkForExtension = () => {
attempts++;
// Check again for preserved extension (might be set by deferred detection)
if (window.NOSTR_LOGIN_LITE?._instance?.preservedExtension) {
extension = window.NOSTR_LOGIN_LITE._instance.preservedExtension;
console.log('Modal: Found preserved extension after waiting:', extension.constructor?.name);
this._tryExtensionLogin(extension);
return;
}
// Check current window.nostr again
if (window.nostr && this._isRealExtension(window.nostr)) {
extension = window.nostr;
console.log('Modal: Found extension at window.nostr after waiting:', extension.constructor?.name);
this._tryExtensionLogin(extension);
return;
}
// Keep trying or give up
if (attempts < maxAttempts) {
setTimeout(checkForExtension, 200);
} else {
console.log('Modal: No browser extension found after waiting 2 seconds');
this._showExtensionRequired();
}
};
// Start checking after a brief delay
setTimeout(checkForExtension, 200);
return;
}
// Use the single detected extension directly - no choice UI
console.log('Modal: Single extension mode - using extension directly');
this._tryExtensionLogin(extension);
}
_detectAllExtensions() {
@@ -394,17 +433,38 @@ class Modal {
// Also check window.nostr but be extra careful to avoid our library
console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name);
if (window.nostr && this._isRealExtension(window.nostr) && !seenExtensions.has(window.nostr)) {
extensions.push({
name: 'window.nostr',
displayName: 'Extension (window.nostr)',
icon: '🔑',
extension: window.nostr
});
seenExtensions.add(window.nostr);
console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`);
} else if (window.nostr) {
console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - likely our library`);
if (window.nostr) {
// Check if window.nostr is our WindowNostr facade with a preserved extension
if (window.nostr.constructor?.name === 'WindowNostr' && window.nostr.existingNostr) {
console.log('Modal: Found WindowNostr facade, checking existingNostr for preserved extension');
const preservedExtension = window.nostr.existingNostr;
console.log('Modal: Preserved extension:', !!preservedExtension, preservedExtension?.constructor?.name);
if (preservedExtension && this._isRealExtension(preservedExtension) && !seenExtensions.has(preservedExtension)) {
extensions.push({
name: 'window.nostr.existingNostr',
displayName: 'Extension (preserved by WindowNostr)',
icon: '🔑',
extension: preservedExtension
});
seenExtensions.add(preservedExtension);
console.log(`Modal: ✓ Detected preserved extension: ${preservedExtension.constructor?.name}`);
}
}
// Check if window.nostr is directly a real extension (not our facade)
else if (this._isRealExtension(window.nostr) && !seenExtensions.has(window.nostr)) {
extensions.push({
name: 'window.nostr',
displayName: 'Extension (window.nostr)',
icon: '🔑',
extension: window.nostr
});
seenExtensions.add(window.nostr);
console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`);
} else {
console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - not a real extension`);
}
}
return extensions;
@@ -994,6 +1054,63 @@ class Modal {
}
_setAuthMethod(method, options = {}) {
// SINGLE-EXTENSION ARCHITECTURE: Handle method switching
console.log('Modal: _setAuthMethod called with:', method, options);
// CRITICAL: Never install facade for extension methods - leave window.nostr as the extension
if (method === 'extension') {
console.log('Modal: Extension method - NOT installing facade, leaving window.nostr as extension');
// Emit auth method selection directly for extension
const event = new CustomEvent('nlMethodSelected', {
detail: { method, ...options }
});
window.dispatchEvent(event);
this.close();
return;
}
// For non-extension methods, we need to ensure WindowNostr facade is available
console.log('Modal: Non-extension method detected:', method);
// Check if we have a preserved extension but no WindowNostr facade installed
const hasPreservedExtension = !!window.NOSTR_LOGIN_LITE?._instance?.preservedExtension;
const hasWindowNostrFacade = window.nostr?.constructor?.name === 'WindowNostr';
console.log('Modal: Method switching check:');
console.log(' method:', method);
console.log(' hasPreservedExtension:', hasPreservedExtension);
console.log(' hasWindowNostrFacade:', hasWindowNostrFacade);
console.log(' current window.nostr constructor:', window.nostr?.constructor?.name);
// If we have a preserved extension but no facade, install facade for method switching
if (hasPreservedExtension && !hasWindowNostrFacade) {
console.log('Modal: Installing WindowNostr facade for method switching (non-extension authentication)');
// Get the NostrLite instance and install facade with preserved extension
const nostrLiteInstance = window.NOSTR_LOGIN_LITE?._instance;
if (nostrLiteInstance && typeof nostrLiteInstance._installFacade === 'function') {
const preservedExtension = nostrLiteInstance.preservedExtension;
console.log('Modal: Installing facade with preserved extension:', preservedExtension?.constructor?.name);
nostrLiteInstance._installFacade(preservedExtension);
console.log('Modal: WindowNostr facade installed for method switching');
} else {
console.error('Modal: Cannot access NostrLite instance or _installFacade method');
}
}
// If no extension at all, ensure facade is installed for local/NIP-46/readonly methods
else if (!hasPreservedExtension && !hasWindowNostrFacade) {
console.log('Modal: Installing WindowNostr facade for non-extension methods (no extension detected)');
const nostrLiteInstance = window.NOSTR_LOGIN_LITE?._instance;
if (nostrLiteInstance && typeof nostrLiteInstance._installFacade === 'function') {
nostrLiteInstance._installFacade();
console.log('Modal: WindowNostr facade installed for non-extension methods');
}
}
// Emit auth method selection
const event = new CustomEvent('nlMethodSelected', {
detail: { method, ...options }
@@ -1027,8 +1144,13 @@ class Modal {
title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;';
const message = document.createElement('p');
message.textContent = 'Please install a Nostr browser extension like Alby or getflattr and refresh the page.';
message.style.cssText = 'margin-bottom: 20px; color: #6b7280;';
message.innerHTML = `
Please install a Nostr browser extension and refresh the page.<br><br>
<strong>Important:</strong> If you have multiple extensions installed, please disable all but one to avoid conflicts.
<br><br>
Popular extensions: Alby, nos2x, Flamingo
`;
message.style.cssText = 'margin-bottom: 20px; color: #6b7280; font-size: 14px; line-height: 1.4;';
const backButton = document.createElement('button');
backButton.textContent = 'Back';
@@ -1071,27 +1193,11 @@ class Modal {
box-sizing: border-box;
`;
const urlLabel = document.createElement('label');
urlLabel.textContent = 'Remote URL (optional):';
urlLabel.style.cssText = 'display: block; margin-bottom: 8px; font-weight: 500;';
const urlInput = document.createElement('input');
urlInput.type = 'url';
urlInput.placeholder = 'ws://localhost:8080 (default)';
urlInput.style.cssText = `
width: 100%;
padding: 12px;
border: 1px solid #d1d5db;
border-radius: 6px;
margin-bottom: 16px;
box-sizing: border-box;
`;
// Users will enter the bunker URL manually from their bunker setup
// Users will enter the complete bunker connection string with relay info
const connectButton = document.createElement('button');
connectButton.textContent = 'Connect to Bunker';
connectButton.onclick = () => this._handleNip46Connect(pubkeyInput.value, urlInput.value);
connectButton.onclick = () => this._handleNip46Connect(pubkeyInput.value);
connectButton.style.cssText = this._getButtonStyle();
const backButton = document.createElement('button');
@@ -1101,8 +1207,6 @@ class Modal {
formGroup.appendChild(label);
formGroup.appendChild(pubkeyInput);
formGroup.appendChild(urlLabel);
formGroup.appendChild(urlInput);
this.modalBody.appendChild(title);
this.modalBody.appendChild(description);
@@ -1111,17 +1215,17 @@ class Modal {
this.modalBody.appendChild(backButton);
}
_handleNip46Connect(bunkerPubkey, bunkerUrl) {
_handleNip46Connect(bunkerPubkey) {
if (!bunkerPubkey || !bunkerPubkey.length) {
this._showError('Bunker pubkey is required');
return;
}
this._showNip46Connecting(bunkerPubkey, bunkerUrl);
this._performNip46Connect(bunkerPubkey, bunkerUrl);
this._showNip46Connecting(bunkerPubkey);
this._performNip46Connect(bunkerPubkey);
}
_showNip46Connecting(bunkerPubkey, bunkerUrl) {
_showNip46Connecting(bunkerPubkey) {
this.modalBody.innerHTML = '';
const title = document.createElement('h3');
@@ -1139,9 +1243,8 @@ class Modal {
bunkerInfo.style.cssText = 'background: #f1f5f9; padding: 12px; border-radius: 6px; margin-bottom: 20px; font-size: 14px;';
bunkerInfo.innerHTML = `
<strong>Connecting to bunker:</strong><br>
Pubkey: <code style="word-break: break-all;">${displayPubkey}</code><br>
Relay: <code style="word-break: break-all;">${bunkerUrl || 'ws://localhost:8080'}</code><br>
<small style="color: #6b7280;">If this relay is offline, the bunker server may be unavailable.</small>
Connection: <code style="word-break: break-all;">${displayPubkey}</code><br>
<small style="color: #6b7280;">Connection string contains all necessary relay information.</small>
`;
const connectingDiv = document.createElement('div');
@@ -1158,9 +1261,9 @@ class Modal {
this.modalBody.appendChild(connectingDiv);
}
async _performNip46Connect(bunkerPubkey, bunkerUrl) {
async _performNip46Connect(bunkerPubkey) {
try {
console.log('Starting NIP-46 connection to bunker:', bunkerPubkey, bunkerUrl);
console.log('Starting NIP-46 connection to bunker:', bunkerPubkey);
// Check if nostr-tools NIP-46 is available
if (!window.NostrTools?.nip46) {