Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98b87de736 | ||
|
|
ae6f176f52 |
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
rsync -avz --chmod=644 --progress lite/{nostr-lite.js,nostr.bundle.js} ubuntu@laantungir.net:WWW/nostr-login-lite/
|
||||
rsync -avz --chmod=644 --progress lite/{nostr-lite.js,nostr.bundle.js} ubuntu@laantungir.net:html/nostr-login-lite/
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.1.7
|
||||
0.1.9
|
||||
|
||||
@@ -22,7 +22,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function createNostrLoginLiteBundle() {
|
||||
console.log('🔧 Creating NOSTR_LOGIN_LITE bundle for two-file architecture...');
|
||||
// console.log('🔧 Creating NOSTR_LOGIN_LITE bundle for two-file architecture...');
|
||||
|
||||
const outputPath = path.join(__dirname, 'nostr-lite.js');
|
||||
|
||||
@@ -56,10 +56,10 @@ if (typeof window !== 'undefined') {
|
||||
throw new Error('Missing dependency: nostr.bundle.js');
|
||||
}
|
||||
|
||||
console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓');
|
||||
console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools));
|
||||
console.log('NOSTR_LOGIN_LITE: NIP-06 available:', !!window.NostrTools.nip06);
|
||||
console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46);
|
||||
// console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓');
|
||||
// console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools));
|
||||
// console.log('NOSTR_LOGIN_LITE: NIP-06 available:', !!window.NostrTools.nip06);
|
||||
// console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46);
|
||||
}
|
||||
|
||||
// ======================================
|
||||
@@ -69,7 +69,7 @@ if (typeof window !== 'undefined') {
|
||||
`;
|
||||
|
||||
// Embed CSS themes
|
||||
console.log('🎨 Adding CSS-Only Theme System...');
|
||||
// console.log('🎨 Adding CSS-Only Theme System...');
|
||||
|
||||
const defaultThemeCssPath = path.join(__dirname, '../themes/default/theme.css');
|
||||
const darkThemeCssPath = path.join(__dirname, '../themes/dark/theme.css');
|
||||
@@ -109,7 +109,7 @@ if (typeof window !== 'undefined') {
|
||||
bundle += ` style.id = 'nl-theme-css';\n`;
|
||||
bundle += ` style.textContent = themeCss;\n`;
|
||||
bundle += ` document.head.appendChild(style);\n`;
|
||||
bundle += ` console.log('NOSTR_LOGIN_LITE: ' + themeName + ' theme CSS injected');\n`;
|
||||
bundle += ` // console.log('NOSTR_LOGIN_LITE: ' + themeName + ' theme CSS injected');\n`;
|
||||
bundle += ` }\n`;
|
||||
bundle += `}\n\n`;
|
||||
|
||||
@@ -127,7 +127,7 @@ if (typeof window !== 'undefined') {
|
||||
// Add Modal UI
|
||||
const modalPath = path.join(__dirname, 'ui/modal.js');
|
||||
if (fs.existsSync(modalPath)) {
|
||||
console.log('📄 Adding Modal UI...');
|
||||
// console.log('📄 Adding Modal UI...');
|
||||
|
||||
let modalContent = fs.readFileSync(modalPath, 'utf8');
|
||||
|
||||
@@ -139,12 +139,12 @@ if (typeof window !== 'undefined') {
|
||||
try {
|
||||
const version = fs.readFileSync(versionPath, 'utf8').trim();
|
||||
versionString = 'v' + version;
|
||||
console.log('🔢 Using version: ' + version);
|
||||
// console.log('🔢 Using version: ' + version);
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Could not read VERSION file, no version will be displayed');
|
||||
}
|
||||
} else {
|
||||
console.log('📋 No VERSION file found, no version will be displayed');
|
||||
// console.log('📋 No VERSION file found, no version will be displayed');
|
||||
}
|
||||
|
||||
// Keep modal title as just "Nostr Login" (no version injection)
|
||||
@@ -200,7 +200,7 @@ if (typeof window !== 'undefined') {
|
||||
}
|
||||
|
||||
// Add main library code
|
||||
console.log('📄 Adding Main Library...');
|
||||
// console.log('📄 Adding Main Library...');
|
||||
bundle += `
|
||||
// ======================================
|
||||
// FloatingTab Component (Recovered from git history)
|
||||
@@ -2260,9 +2260,9 @@ if (typeof window !== 'undefined') {
|
||||
_instance: nostrLite
|
||||
};
|
||||
|
||||
console.log('NOSTR_LOGIN_LITE: Library loaded and ready');
|
||||
console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize');
|
||||
console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions');
|
||||
// console.log('NOSTR_LOGIN_LITE: Library loaded and ready');
|
||||
// console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize');
|
||||
// console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions');
|
||||
console.warn('🔐 SECURITY: Unified plaintext storage enabled for maximum developer usability');
|
||||
} else {
|
||||
// Node.js environment
|
||||
@@ -2284,16 +2284,16 @@ if (typeof window !== 'undefined') {
|
||||
const hasNostrLite = bundle.includes('NOSTR_LOGIN_LITE');
|
||||
const hasThemeCss = bundle.includes('THEME_CSS');
|
||||
|
||||
console.log('\n📋 Bundle contents:');
|
||||
console.log(' Modal UI: ' + (hasModal ? '✅ Included' : '❌ Missing'));
|
||||
console.log(' NOSTR_LOGIN_LITE: ' + (hasNostrLite ? '✅ Included' : '❌ Missing'));
|
||||
console.log(' CSS-Only Themes: ' + (hasThemeCss ? '✅ Included' : '❌ Missing'));
|
||||
console.log(' Extension Bridge: ✅ Included');
|
||||
console.log(' Window.nostr facade: ✅ Included');
|
||||
// console.log('\n📋 Bundle contents:');
|
||||
// console.log(' Modal UI: ' + (hasModal ? '✅ Included' : '❌ Missing'));
|
||||
// console.log(' NOSTR_LOGIN_LITE: ' + (hasNostrLite ? '✅ Included' : '❌ Missing'));
|
||||
// console.log(' CSS-Only Themes: ' + (hasThemeCss ? '✅ Included' : '❌ Missing'));
|
||||
// console.log(' Extension Bridge: ✅ Included');
|
||||
// console.log(' Window.nostr facade: ✅ Included');
|
||||
|
||||
console.log('\n📋 Two-file architecture:');
|
||||
console.log(' 1. nostr.bundle.js (official nostr-tools - 220KB)');
|
||||
console.log(' 2. nostr-lite.js (NOSTR_LOGIN_LITE with CSS-only themes - ' + sizeKB + 'KB)');
|
||||
// console.log('\n📋 Two-file architecture:');
|
||||
// console.log(' 1. nostr.bundle.js (official nostr-tools - 220KB)');
|
||||
// console.log(' 2. nostr-lite.js (NOSTR_LOGIN_LITE with CSS-only themes - ' + sizeKB + 'KB)');
|
||||
|
||||
return bundle;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* Two-file architecture:
|
||||
* 1. Load nostr.bundle.js (official nostr-tools bundle)
|
||||
* 2. Load nostr-lite.js (this file - NOSTR_LOGIN_LITE library with CSS-only themes)
|
||||
* Generated on: 2025-10-01T14:18:10.269Z
|
||||
* Generated on: 2025-11-14T17:45:29.274Z
|
||||
*/
|
||||
|
||||
// Verify dependencies are loaded
|
||||
@@ -18,10 +18,10 @@ if (typeof window !== 'undefined') {
|
||||
throw new Error('Missing dependency: nostr.bundle.js');
|
||||
}
|
||||
|
||||
console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓');
|
||||
console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools));
|
||||
console.log('NOSTR_LOGIN_LITE: NIP-06 available:', !!window.NostrTools.nip06);
|
||||
console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46);
|
||||
// console.log('NOSTR_LOGIN_LITE: Dependencies verified ✓');
|
||||
// console.log('NOSTR_LOGIN_LITE: NostrTools available with keys:', Object.keys(window.NostrTools));
|
||||
// console.log('NOSTR_LOGIN_LITE: NIP-06 available:', !!window.NostrTools.nip06);
|
||||
// console.log('NOSTR_LOGIN_LITE: NIP-46 available:', !!window.NostrTools.nip46);
|
||||
}
|
||||
|
||||
// ======================================
|
||||
@@ -282,7 +282,7 @@ function injectThemeCSS(themeName = 'default') {
|
||||
style.id = 'nl-theme-css';
|
||||
style.textContent = themeCss;
|
||||
document.head.appendChild(style);
|
||||
console.log('NOSTR_LOGIN_LITE: ' + themeName + ' theme CSS injected');
|
||||
// console.log('NOSTR_LOGIN_LITE: ' + themeName + ' theme CSS injected');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -436,7 +436,7 @@ class Modal {
|
||||
modalContent.appendChild(modalHeader);
|
||||
// Add version element in bottom-right corner aligned with modal body
|
||||
const versionElement = document.createElement('div');
|
||||
versionElement.textContent = 'v0.1.7';
|
||||
versionElement.textContent = 'v0.1.9';
|
||||
versionElement.style.cssText = `
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
@@ -642,7 +642,7 @@ class Modal {
|
||||
}
|
||||
|
||||
_handleOptionClick(type) {
|
||||
console.log('Selected login type:', type);
|
||||
// console.log('Selected login type:', type);
|
||||
|
||||
// Handle different login types
|
||||
switch (type) {
|
||||
@@ -674,16 +674,16 @@ class Modal {
|
||||
// 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);
|
||||
// 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);
|
||||
// console.log('Modal: Using current window.nostr extension:', extension.constructor?.name);
|
||||
}
|
||||
|
||||
|
||||
if (!extension) {
|
||||
console.log('Modal: No extension detected yet, waiting for deferred detection...');
|
||||
// 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;
|
||||
@@ -694,24 +694,24 @@ class Modal {
|
||||
// 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);
|
||||
// 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);
|
||||
// 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');
|
||||
// console.log('Modal: No browser extension found after waiting 2 seconds');
|
||||
this._showExtensionRequired();
|
||||
}
|
||||
};
|
||||
@@ -722,7 +722,7 @@ class Modal {
|
||||
}
|
||||
|
||||
// Use the single detected extension directly - no choice UI
|
||||
console.log('Modal: Single extension mode - using extension directly');
|
||||
// console.log('Modal: Single extension mode - using extension directly');
|
||||
this._tryExtensionLogin(extension);
|
||||
}
|
||||
|
||||
@@ -746,9 +746,9 @@ class Modal {
|
||||
for (const location of locations) {
|
||||
try {
|
||||
const obj = location.getter();
|
||||
|
||||
console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name);
|
||||
|
||||
|
||||
// console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name);
|
||||
|
||||
if (obj && this._isRealExtension(obj) && !seenExtensions.has(obj)) {
|
||||
extensions.push({
|
||||
name: location.name,
|
||||
@@ -757,26 +757,26 @@ class Modal {
|
||||
extension: obj
|
||||
});
|
||||
seenExtensions.add(obj);
|
||||
console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`);
|
||||
// console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`);
|
||||
} else if (obj) {
|
||||
console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`);
|
||||
// console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`);
|
||||
}
|
||||
} catch (e) {
|
||||
// Location doesn't exist or can't be accessed
|
||||
console.log(`Modal: ${location.name} not accessible:`, e.message);
|
||||
// console.log(`Modal: ${location.name} not accessible:`, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Also check window.nostr but be extra careful to avoid our library
|
||||
console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name);
|
||||
|
||||
// console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name);
|
||||
|
||||
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');
|
||||
// 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);
|
||||
|
||||
// console.log('Modal: Preserved extension:', !!preservedExtension, preservedExtension?.constructor?.name);
|
||||
|
||||
if (preservedExtension && this._isRealExtension(preservedExtension) && !seenExtensions.has(preservedExtension)) {
|
||||
extensions.push({
|
||||
name: 'window.nostr.existingNostr',
|
||||
@@ -785,7 +785,7 @@ class Modal {
|
||||
extension: preservedExtension
|
||||
});
|
||||
seenExtensions.add(preservedExtension);
|
||||
console.log(`Modal: ✓ Detected preserved extension: ${preservedExtension.constructor?.name}`);
|
||||
// console.log(`Modal: ✓ Detected preserved extension: ${preservedExtension.constructor?.name}`);
|
||||
}
|
||||
}
|
||||
// Check if window.nostr is directly a real extension (not our facade)
|
||||
@@ -797,9 +797,9 @@ class Modal {
|
||||
extension: window.nostr
|
||||
});
|
||||
seenExtensions.add(window.nostr);
|
||||
console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`);
|
||||
// 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`);
|
||||
// console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - not a real extension`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -807,27 +807,27 @@ class Modal {
|
||||
}
|
||||
|
||||
_isRealExtension(obj) {
|
||||
console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj);
|
||||
console.log(`Modal: Object type: ${typeof obj}`);
|
||||
console.log(`Modal: Object truthy: ${!!obj}`);
|
||||
|
||||
// console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj);
|
||||
// console.log(`Modal: Object type: ${typeof obj}`);
|
||||
// console.log(`Modal: Object truthy: ${!!obj}`);
|
||||
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
console.log(`Modal: REJECT - Not an object`);
|
||||
// console.log(`Modal: REJECT - Not an object`);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`);
|
||||
console.log(`Modal: signEvent type: ${typeof obj.signEvent}`);
|
||||
|
||||
|
||||
// console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`);
|
||||
// console.log(`Modal: signEvent type: ${typeof obj.signEvent}`);
|
||||
|
||||
// Must have required Nostr methods
|
||||
if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') {
|
||||
console.log(`Modal: REJECT - Missing required methods`);
|
||||
// console.log(`Modal: REJECT - Missing required methods`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude NostrTools library object
|
||||
if (obj === window.NostrTools) {
|
||||
console.log(`Modal: REJECT - Is NostrTools object`);
|
||||
// console.log(`Modal: REJECT - Is NostrTools object`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -835,10 +835,10 @@ class Modal {
|
||||
// This is the key fix - match the comprehensive test's successful detection logic
|
||||
const constructorName = obj.constructor?.name;
|
||||
const objectKeys = Object.keys(obj);
|
||||
|
||||
console.log(`Modal: Constructor name: "${constructorName}"`);
|
||||
console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`);
|
||||
|
||||
|
||||
// console.log(`Modal: Constructor name: "${constructorName}"`);
|
||||
// console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`);
|
||||
|
||||
// COMPREHENSIVE TEST LOGIC - Accept anything with required methods that's not our specific library classes
|
||||
const isRealExtension = (
|
||||
typeof obj.getPublicKey === 'function' &&
|
||||
@@ -846,14 +846,14 @@ class Modal {
|
||||
constructorName !== 'WindowNostr' && // Our library class
|
||||
constructorName !== 'NostrLite' // Our main class
|
||||
);
|
||||
|
||||
console.log(`Modal: Using comprehensive test logic:`);
|
||||
console.log(` Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`);
|
||||
console.log(` Has signEvent: ${typeof obj.signEvent === 'function'}`);
|
||||
console.log(` Not WindowNostr: ${constructorName !== 'WindowNostr'}`);
|
||||
console.log(` Not NostrLite: ${constructorName !== 'NostrLite'}`);
|
||||
console.log(` Constructor: "${constructorName}"`);
|
||||
|
||||
|
||||
// console.log(`Modal: Using comprehensive test logic:`);
|
||||
// console.log(` Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`);
|
||||
// console.log(` Has signEvent: ${typeof obj.signEvent === 'function'}`);
|
||||
// console.log(` Not WindowNostr: ${constructorName !== 'WindowNostr'}`);
|
||||
// console.log(` Not NostrLite: ${constructorName !== 'NostrLite'}`);
|
||||
// console.log(` Constructor: "${constructorName}"`);
|
||||
|
||||
// Additional debugging for comparison
|
||||
const extensionPropChecks = {
|
||||
_isEnabled: !!obj._isEnabled,
|
||||
@@ -867,27 +867,27 @@ class Modal {
|
||||
version: !!obj.version,
|
||||
description: !!obj.description
|
||||
};
|
||||
|
||||
console.log(`Modal: Extension property analysis:`, extensionPropChecks);
|
||||
|
||||
|
||||
// console.log(`Modal: Extension property analysis:`, extensionPropChecks);
|
||||
|
||||
const hasExtensionProps = !!(
|
||||
obj._isEnabled || obj.enabled || obj.kind ||
|
||||
obj._eventEmitter || obj._scope || obj._requests || obj._pubkey ||
|
||||
obj.name || obj.version || obj.description
|
||||
);
|
||||
|
||||
|
||||
const underscoreKeys = objectKeys.filter(key => key.startsWith('_'));
|
||||
const hexToUint8Keys = objectKeys.filter(key => key.startsWith('_hex'));
|
||||
console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`);
|
||||
console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`);
|
||||
|
||||
console.log(`Modal: Additional analysis:`);
|
||||
console.log(` hasExtensionProps: ${hasExtensionProps}`);
|
||||
console.log(` hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`);
|
||||
|
||||
console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
|
||||
// console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`);
|
||||
// console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`);
|
||||
|
||||
// console.log(`Modal: Additional analysis:`);
|
||||
// console.log(` hasExtensionProps: ${hasExtensionProps}`);
|
||||
// console.log(` hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`);
|
||||
|
||||
// console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
// console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
|
||||
return isRealExtension;
|
||||
}
|
||||
|
||||
@@ -999,7 +999,7 @@ class Modal {
|
||||
// Get pubkey from extension
|
||||
const pubkey = await extensionObj.getPublicKey();
|
||||
console.log('Extension provided pubkey:', pubkey);
|
||||
|
||||
|
||||
// Set extension method with the extension object
|
||||
this._setAuthMethod('extension', { pubkey, extension: extensionObj });
|
||||
|
||||
@@ -1140,8 +1140,8 @@ class Modal {
|
||||
textarea.oninput();
|
||||
}
|
||||
|
||||
console.log('Generated new local secret key (nsec format)');
|
||||
|
||||
// console.log('Generated new local secret key (nsec format)');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to generate local key:', error);
|
||||
formatHint.textContent = '❌ Failed to generate key - NostrTools not available';
|
||||
@@ -1443,30 +1443,30 @@ class Modal {
|
||||
}
|
||||
|
||||
_setAuthMethod(method, options = {}) {
|
||||
console.log('Modal: _setAuthMethod called with:', method, options);
|
||||
|
||||
// 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');
|
||||
|
||||
// console.log('Modal: Extension method - NOT installing facade, leaving window.nostr as extension');
|
||||
|
||||
// Save extension authentication state using global setAuthState function
|
||||
if (typeof window.setAuthState === 'function') {
|
||||
console.log('Modal: Saving extension auth state to storage');
|
||||
// console.log('Modal: Saving extension auth state to storage');
|
||||
window.setAuthState({ method, ...options }, { isolateSession: this.options?.isolateSession });
|
||||
}
|
||||
|
||||
|
||||
// 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: Force-install facade with resilience
|
||||
console.log('Modal: Non-extension method - FORCE-INSTALLING facade with resilience:', method);
|
||||
// console.log('Modal: Non-extension method - FORCE-INSTALLING facade with resilience:', method);
|
||||
|
||||
// Store the current extension if any (for potential restoration later)
|
||||
const currentExtension = (window.nostr?.constructor?.name !== 'WindowNostr') ? window.nostr : null;
|
||||
@@ -1485,10 +1485,10 @@ class Modal {
|
||||
}
|
||||
|
||||
// IMMEDIATE FACADE INSTALLATION
|
||||
console.log('Modal: Installing WindowNostr facade immediately for method:', method);
|
||||
// console.log('Modal: Installing WindowNostr facade immediately for method:', method);
|
||||
const preservedExtension = nostrLiteInstance.preservedExtension || currentExtension;
|
||||
nostrLiteInstance._installFacade(preservedExtension, true);
|
||||
console.log('Modal: WindowNostr facade force-installed, current window.nostr:', window.nostr?.constructor?.name);
|
||||
// console.log('Modal: WindowNostr facade force-installed, current window.nostr:', window.nostr?.constructor?.name);
|
||||
|
||||
// DELAYED FACADE RESILIENCE - Reinstall after extension override attempts
|
||||
const forceReinstallFacade = () => {
|
||||
@@ -1513,9 +1513,9 @@ class Modal {
|
||||
};
|
||||
|
||||
// Schedule resilience checks at multiple intervals
|
||||
setTimeout(forceReinstallFacade, 100); // Quick check
|
||||
setTimeout(forceReinstallFacade, 500); // Main check
|
||||
setTimeout(forceReinstallFacade, 1500); // Final check
|
||||
// setTimeout(forceReinstallFacade, 100); // Quick check
|
||||
// setTimeout(forceReinstallFacade, 500); // Main check
|
||||
// setTimeout(forceReinstallFacade, 1500); // Final check
|
||||
|
||||
// Emit auth method selection
|
||||
const event = new CustomEvent('nlMethodSelected', {
|
||||
@@ -1702,7 +1702,7 @@ class Modal {
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.log('Bunker key validation failed:', error.message);
|
||||
// console.log('Bunker key validation failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1755,7 +1755,7 @@ class Modal {
|
||||
|
||||
async _performNip46Connect(bunkerPubkey) {
|
||||
try {
|
||||
console.log('Starting NIP-46 connection to bunker:', bunkerPubkey);
|
||||
// console.log('Starting NIP-46 connection to bunker:', bunkerPubkey);
|
||||
|
||||
// Check if nostr-tools NIP-46 is available
|
||||
if (!window.NostrTools?.nip46) {
|
||||
@@ -1763,41 +1763,41 @@ class Modal {
|
||||
}
|
||||
|
||||
// Use nostr-tools to parse bunker input - this handles all formats correctly
|
||||
console.log('Parsing bunker input with nostr-tools...');
|
||||
// console.log('Parsing bunker input with nostr-tools...');
|
||||
const bunkerPointer = await window.NostrTools.nip46.parseBunkerInput(bunkerPubkey);
|
||||
|
||||
if (!bunkerPointer) {
|
||||
throw new Error('Unable to parse bunker connection string or resolve NIP-05 identifier');
|
||||
}
|
||||
|
||||
console.log('Parsed bunker pointer:', bunkerPointer);
|
||||
// console.log('Parsed bunker pointer:', bunkerPointer);
|
||||
|
||||
// Create local client keypair for this session
|
||||
const localSecretKey = window.NostrTools.generateSecretKey();
|
||||
console.log('Generated local client keypair for NIP-46 session');
|
||||
// console.log('Generated local client keypair for NIP-46 session');
|
||||
|
||||
// Use nostr-tools BunkerSigner factory method (not constructor - it's private)
|
||||
console.log('Creating nip46 BunkerSigner...');
|
||||
// console.log('Creating nip46 BunkerSigner...');
|
||||
const signer = window.NostrTools.nip46.BunkerSigner.fromBunker(localSecretKey, bunkerPointer, {
|
||||
onauth: (url) => {
|
||||
console.log('Received auth URL from bunker:', url);
|
||||
// console.log('Received auth URL from bunker:', url);
|
||||
// Open auth URL in popup or redirect
|
||||
window.open(url, '_blank', 'width=600,height=800');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('NIP-46 BunkerSigner created successfully');
|
||||
// console.log('NIP-46 BunkerSigner created successfully');
|
||||
|
||||
// Skip ping test - NIP-46 works through relays, not direct connection
|
||||
// Try to connect directly (this may trigger auth flow)
|
||||
console.log('Attempting NIP-46 connect...');
|
||||
// console.log('Attempting NIP-46 connect...');
|
||||
await signer.connect();
|
||||
console.log('NIP-46 connect successful');
|
||||
// console.log('NIP-46 connect successful');
|
||||
|
||||
// Get the user's public key from the bunker
|
||||
console.log('Getting public key from bunker...');
|
||||
// console.log('Getting public key from bunker...');
|
||||
const userPubkey = await signer.getPublicKey();
|
||||
console.log('NIP-46 user public key:', userPubkey);
|
||||
// console.log('NIP-46 user public key:', userPubkey);
|
||||
|
||||
// Store the NIP-46 authentication info
|
||||
const nip46Info = {
|
||||
@@ -1811,7 +1811,7 @@ class Modal {
|
||||
}
|
||||
};
|
||||
|
||||
console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!');
|
||||
// console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!');
|
||||
|
||||
// Set as current auth method
|
||||
this._setAuthMethod('nip46', nip46Info);
|
||||
@@ -1984,8 +1984,8 @@ class Modal {
|
||||
textarea.oninput();
|
||||
}
|
||||
|
||||
console.log('Generated new seed phrase:', mnemonic.split(/\s+/).length, 'words');
|
||||
|
||||
// console.log('Generated new seed phrase:', mnemonic.split(/\s+/).length, 'words');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to generate seed phrase:', error);
|
||||
formatHint.textContent = '❌ Failed to generate seed phrase - NIP-06 not available';
|
||||
@@ -2002,7 +2002,7 @@ class Modal {
|
||||
}
|
||||
|
||||
const words = mnemonic.trim().split(/\s+/);
|
||||
|
||||
|
||||
// Must be 12 or 24 words
|
||||
if (words.length !== 12 && words.length !== 24) {
|
||||
return false;
|
||||
@@ -2012,7 +2012,7 @@ class Modal {
|
||||
window.NostrTools.nip06.privateKeyFromSeedWords(mnemonic, '', 0);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.log('Mnemonic validation failed:', error.message);
|
||||
// console.log('Mnemonic validation failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2054,7 +2054,7 @@ class Modal {
|
||||
throw new Error('Failed to derive any accounts from seed phrase');
|
||||
}
|
||||
|
||||
console.log(`Successfully derived ${accounts.length} accounts from seed phrase`);
|
||||
// console.log(`Successfully derived ${accounts.length} accounts from seed phrase`);
|
||||
this._showAccountSelection(accounts);
|
||||
|
||||
} catch (error) {
|
||||
@@ -2150,8 +2150,8 @@ class Modal {
|
||||
}
|
||||
|
||||
_selectAccount(account) {
|
||||
console.log('Selected account:', account.index, account.npub);
|
||||
|
||||
// console.log('Selected account:', account.index, account.npub);
|
||||
|
||||
// Use the same auth method as local keys, but with seedphrase identifier
|
||||
this._setAuthMethod('local', {
|
||||
secret: account.nsec,
|
||||
@@ -4271,9 +4271,9 @@ if (typeof window !== 'undefined') {
|
||||
_instance: nostrLite
|
||||
};
|
||||
|
||||
console.log('NOSTR_LOGIN_LITE: Library loaded and ready');
|
||||
console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize');
|
||||
console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions');
|
||||
// console.log('NOSTR_LOGIN_LITE: Library loaded and ready');
|
||||
// console.log('NOSTR_LOGIN_LITE: Use window.NOSTR_LOGIN_LITE.init(options) to initialize');
|
||||
// console.log('NOSTR_LOGIN_LITE: Detected', nostrLite.extensionBridge.getExtensionCount(), 'browser extensions');
|
||||
console.warn('🔐 SECURITY: Unified plaintext storage enabled for maximum developer usability');
|
||||
} else {
|
||||
// Node.js environment
|
||||
|
||||
198
lite/ui/modal.js
198
lite/ui/modal.js
@@ -330,7 +330,7 @@ class Modal {
|
||||
}
|
||||
|
||||
_handleOptionClick(type) {
|
||||
console.log('Selected login type:', type);
|
||||
// console.log('Selected login type:', type);
|
||||
|
||||
// Handle different login types
|
||||
switch (type) {
|
||||
@@ -362,16 +362,16 @@ class Modal {
|
||||
// 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);
|
||||
// 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);
|
||||
// console.log('Modal: Using current window.nostr extension:', extension.constructor?.name);
|
||||
}
|
||||
|
||||
|
||||
if (!extension) {
|
||||
console.log('Modal: No extension detected yet, waiting for deferred detection...');
|
||||
// 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;
|
||||
@@ -382,24 +382,24 @@ class Modal {
|
||||
// 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);
|
||||
// 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);
|
||||
// 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');
|
||||
// console.log('Modal: No browser extension found after waiting 2 seconds');
|
||||
this._showExtensionRequired();
|
||||
}
|
||||
};
|
||||
@@ -410,7 +410,7 @@ class Modal {
|
||||
}
|
||||
|
||||
// Use the single detected extension directly - no choice UI
|
||||
console.log('Modal: Single extension mode - using extension directly');
|
||||
// console.log('Modal: Single extension mode - using extension directly');
|
||||
this._tryExtensionLogin(extension);
|
||||
}
|
||||
|
||||
@@ -434,9 +434,9 @@ class Modal {
|
||||
for (const location of locations) {
|
||||
try {
|
||||
const obj = location.getter();
|
||||
|
||||
console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name);
|
||||
|
||||
|
||||
// console.log(`Modal: Checking ${location.name}:`, !!obj, obj?.constructor?.name);
|
||||
|
||||
if (obj && this._isRealExtension(obj) && !seenExtensions.has(obj)) {
|
||||
extensions.push({
|
||||
name: location.name,
|
||||
@@ -445,26 +445,26 @@ class Modal {
|
||||
extension: obj
|
||||
});
|
||||
seenExtensions.add(obj);
|
||||
console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`);
|
||||
// console.log(`Modal: ✓ Detected extension at ${location.name} (${obj.constructor?.name})`);
|
||||
} else if (obj) {
|
||||
console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`);
|
||||
// console.log(`Modal: ✗ Filtered out ${location.name} (${obj.constructor?.name})`);
|
||||
}
|
||||
} catch (e) {
|
||||
// Location doesn't exist or can't be accessed
|
||||
console.log(`Modal: ${location.name} not accessible:`, e.message);
|
||||
// console.log(`Modal: ${location.name} not accessible:`, e.message);
|
||||
}
|
||||
}
|
||||
|
||||
// Also check window.nostr but be extra careful to avoid our library
|
||||
console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name);
|
||||
|
||||
// console.log('Modal: Checking window.nostr:', !!window.nostr, window.nostr?.constructor?.name);
|
||||
|
||||
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');
|
||||
// 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);
|
||||
|
||||
// console.log('Modal: Preserved extension:', !!preservedExtension, preservedExtension?.constructor?.name);
|
||||
|
||||
if (preservedExtension && this._isRealExtension(preservedExtension) && !seenExtensions.has(preservedExtension)) {
|
||||
extensions.push({
|
||||
name: 'window.nostr.existingNostr',
|
||||
@@ -473,7 +473,7 @@ class Modal {
|
||||
extension: preservedExtension
|
||||
});
|
||||
seenExtensions.add(preservedExtension);
|
||||
console.log(`Modal: ✓ Detected preserved extension: ${preservedExtension.constructor?.name}`);
|
||||
// console.log(`Modal: ✓ Detected preserved extension: ${preservedExtension.constructor?.name}`);
|
||||
}
|
||||
}
|
||||
// Check if window.nostr is directly a real extension (not our facade)
|
||||
@@ -485,9 +485,9 @@ class Modal {
|
||||
extension: window.nostr
|
||||
});
|
||||
seenExtensions.add(window.nostr);
|
||||
console.log(`Modal: ✓ Detected extension at window.nostr: ${window.nostr.constructor?.name}`);
|
||||
// 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`);
|
||||
// console.log(`Modal: ✗ Filtered out window.nostr (${window.nostr.constructor?.name}) - not a real extension`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,27 +495,27 @@ class Modal {
|
||||
}
|
||||
|
||||
_isRealExtension(obj) {
|
||||
console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj);
|
||||
console.log(`Modal: Object type: ${typeof obj}`);
|
||||
console.log(`Modal: Object truthy: ${!!obj}`);
|
||||
|
||||
// console.log(`Modal: EXTENSIVE DEBUG - _isRealExtension called with:`, obj);
|
||||
// console.log(`Modal: Object type: ${typeof obj}`);
|
||||
// console.log(`Modal: Object truthy: ${!!obj}`);
|
||||
|
||||
if (!obj || typeof obj !== 'object') {
|
||||
console.log(`Modal: REJECT - Not an object`);
|
||||
// console.log(`Modal: REJECT - Not an object`);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`);
|
||||
console.log(`Modal: signEvent type: ${typeof obj.signEvent}`);
|
||||
|
||||
|
||||
// console.log(`Modal: getPublicKey type: ${typeof obj.getPublicKey}`);
|
||||
// console.log(`Modal: signEvent type: ${typeof obj.signEvent}`);
|
||||
|
||||
// Must have required Nostr methods
|
||||
if (typeof obj.getPublicKey !== 'function' || typeof obj.signEvent !== 'function') {
|
||||
console.log(`Modal: REJECT - Missing required methods`);
|
||||
// console.log(`Modal: REJECT - Missing required methods`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exclude NostrTools library object
|
||||
if (obj === window.NostrTools) {
|
||||
console.log(`Modal: REJECT - Is NostrTools object`);
|
||||
// console.log(`Modal: REJECT - Is NostrTools object`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -523,10 +523,10 @@ class Modal {
|
||||
// This is the key fix - match the comprehensive test's successful detection logic
|
||||
const constructorName = obj.constructor?.name;
|
||||
const objectKeys = Object.keys(obj);
|
||||
|
||||
console.log(`Modal: Constructor name: "${constructorName}"`);
|
||||
console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`);
|
||||
|
||||
|
||||
// console.log(`Modal: Constructor name: "${constructorName}"`);
|
||||
// console.log(`Modal: Object keys: [${objectKeys.join(', ')}]`);
|
||||
|
||||
// COMPREHENSIVE TEST LOGIC - Accept anything with required methods that's not our specific library classes
|
||||
const isRealExtension = (
|
||||
typeof obj.getPublicKey === 'function' &&
|
||||
@@ -534,14 +534,14 @@ class Modal {
|
||||
constructorName !== 'WindowNostr' && // Our library class
|
||||
constructorName !== 'NostrLite' // Our main class
|
||||
);
|
||||
|
||||
console.log(`Modal: Using comprehensive test logic:`);
|
||||
console.log(` Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`);
|
||||
console.log(` Has signEvent: ${typeof obj.signEvent === 'function'}`);
|
||||
console.log(` Not WindowNostr: ${constructorName !== 'WindowNostr'}`);
|
||||
console.log(` Not NostrLite: ${constructorName !== 'NostrLite'}`);
|
||||
console.log(` Constructor: "${constructorName}"`);
|
||||
|
||||
|
||||
// console.log(`Modal: Using comprehensive test logic:`);
|
||||
// console.log(` Has getPublicKey: ${typeof obj.getPublicKey === 'function'}`);
|
||||
// console.log(` Has signEvent: ${typeof obj.signEvent === 'function'}`);
|
||||
// console.log(` Not WindowNostr: ${constructorName !== 'WindowNostr'}`);
|
||||
// console.log(` Not NostrLite: ${constructorName !== 'NostrLite'}`);
|
||||
// console.log(` Constructor: "${constructorName}"`);
|
||||
|
||||
// Additional debugging for comparison
|
||||
const extensionPropChecks = {
|
||||
_isEnabled: !!obj._isEnabled,
|
||||
@@ -555,27 +555,27 @@ class Modal {
|
||||
version: !!obj.version,
|
||||
description: !!obj.description
|
||||
};
|
||||
|
||||
console.log(`Modal: Extension property analysis:`, extensionPropChecks);
|
||||
|
||||
|
||||
// console.log(`Modal: Extension property analysis:`, extensionPropChecks);
|
||||
|
||||
const hasExtensionProps = !!(
|
||||
obj._isEnabled || obj.enabled || obj.kind ||
|
||||
obj._eventEmitter || obj._scope || obj._requests || obj._pubkey ||
|
||||
obj.name || obj.version || obj.description
|
||||
);
|
||||
|
||||
|
||||
const underscoreKeys = objectKeys.filter(key => key.startsWith('_'));
|
||||
const hexToUint8Keys = objectKeys.filter(key => key.startsWith('_hex'));
|
||||
console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`);
|
||||
console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`);
|
||||
|
||||
console.log(`Modal: Additional analysis:`);
|
||||
console.log(` hasExtensionProps: ${hasExtensionProps}`);
|
||||
console.log(` hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`);
|
||||
|
||||
console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
|
||||
// console.log(`Modal: Underscore keys: [${underscoreKeys.join(', ')}]`);
|
||||
// console.log(`Modal: _hex* keys: [${hexToUint8Keys.join(', ')}]`);
|
||||
|
||||
// console.log(`Modal: Additional analysis:`);
|
||||
// console.log(` hasExtensionProps: ${hasExtensionProps}`);
|
||||
// console.log(` hasLibraryMethod (_hexToUint8Array): ${objectKeys.includes('_hexToUint8Array')}`);
|
||||
|
||||
// console.log(`Modal: COMPREHENSIVE TEST LOGIC RESULT: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
// console.log(`Modal: FINAL DECISION for ${constructorName}: ${isRealExtension ? 'ACCEPT' : 'REJECT'}`);
|
||||
|
||||
return isRealExtension;
|
||||
}
|
||||
|
||||
@@ -687,7 +687,7 @@ class Modal {
|
||||
// Get pubkey from extension
|
||||
const pubkey = await extensionObj.getPublicKey();
|
||||
console.log('Extension provided pubkey:', pubkey);
|
||||
|
||||
|
||||
// Set extension method with the extension object
|
||||
this._setAuthMethod('extension', { pubkey, extension: extensionObj });
|
||||
|
||||
@@ -828,8 +828,8 @@ class Modal {
|
||||
textarea.oninput();
|
||||
}
|
||||
|
||||
console.log('Generated new local secret key (nsec format)');
|
||||
|
||||
// console.log('Generated new local secret key (nsec format)');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to generate local key:', error);
|
||||
formatHint.textContent = '❌ Failed to generate key - NostrTools not available';
|
||||
@@ -1131,30 +1131,30 @@ class Modal {
|
||||
}
|
||||
|
||||
_setAuthMethod(method, options = {}) {
|
||||
console.log('Modal: _setAuthMethod called with:', method, options);
|
||||
|
||||
// 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');
|
||||
|
||||
// console.log('Modal: Extension method - NOT installing facade, leaving window.nostr as extension');
|
||||
|
||||
// Save extension authentication state using global setAuthState function
|
||||
if (typeof window.setAuthState === 'function') {
|
||||
console.log('Modal: Saving extension auth state to storage');
|
||||
// console.log('Modal: Saving extension auth state to storage');
|
||||
window.setAuthState({ method, ...options }, { isolateSession: this.options?.isolateSession });
|
||||
}
|
||||
|
||||
|
||||
// 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: Force-install facade with resilience
|
||||
console.log('Modal: Non-extension method - FORCE-INSTALLING facade with resilience:', method);
|
||||
// console.log('Modal: Non-extension method - FORCE-INSTALLING facade with resilience:', method);
|
||||
|
||||
// Store the current extension if any (for potential restoration later)
|
||||
const currentExtension = (window.nostr?.constructor?.name !== 'WindowNostr') ? window.nostr : null;
|
||||
@@ -1173,10 +1173,10 @@ class Modal {
|
||||
}
|
||||
|
||||
// IMMEDIATE FACADE INSTALLATION
|
||||
console.log('Modal: Installing WindowNostr facade immediately for method:', method);
|
||||
// console.log('Modal: Installing WindowNostr facade immediately for method:', method);
|
||||
const preservedExtension = nostrLiteInstance.preservedExtension || currentExtension;
|
||||
nostrLiteInstance._installFacade(preservedExtension, true);
|
||||
console.log('Modal: WindowNostr facade force-installed, current window.nostr:', window.nostr?.constructor?.name);
|
||||
// console.log('Modal: WindowNostr facade force-installed, current window.nostr:', window.nostr?.constructor?.name);
|
||||
|
||||
// DELAYED FACADE RESILIENCE - Reinstall after extension override attempts
|
||||
const forceReinstallFacade = () => {
|
||||
@@ -1201,9 +1201,9 @@ class Modal {
|
||||
};
|
||||
|
||||
// Schedule resilience checks at multiple intervals
|
||||
setTimeout(forceReinstallFacade, 100); // Quick check
|
||||
setTimeout(forceReinstallFacade, 500); // Main check
|
||||
setTimeout(forceReinstallFacade, 1500); // Final check
|
||||
// setTimeout(forceReinstallFacade, 100); // Quick check
|
||||
// setTimeout(forceReinstallFacade, 500); // Main check
|
||||
// setTimeout(forceReinstallFacade, 1500); // Final check
|
||||
|
||||
// Emit auth method selection
|
||||
const event = new CustomEvent('nlMethodSelected', {
|
||||
@@ -1390,7 +1390,7 @@ class Modal {
|
||||
|
||||
return false;
|
||||
} catch (error) {
|
||||
console.log('Bunker key validation failed:', error.message);
|
||||
// console.log('Bunker key validation failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1443,7 +1443,7 @@ class Modal {
|
||||
|
||||
async _performNip46Connect(bunkerPubkey) {
|
||||
try {
|
||||
console.log('Starting NIP-46 connection to bunker:', bunkerPubkey);
|
||||
// console.log('Starting NIP-46 connection to bunker:', bunkerPubkey);
|
||||
|
||||
// Check if nostr-tools NIP-46 is available
|
||||
if (!window.NostrTools?.nip46) {
|
||||
@@ -1451,41 +1451,41 @@ class Modal {
|
||||
}
|
||||
|
||||
// Use nostr-tools to parse bunker input - this handles all formats correctly
|
||||
console.log('Parsing bunker input with nostr-tools...');
|
||||
// console.log('Parsing bunker input with nostr-tools...');
|
||||
const bunkerPointer = await window.NostrTools.nip46.parseBunkerInput(bunkerPubkey);
|
||||
|
||||
if (!bunkerPointer) {
|
||||
throw new Error('Unable to parse bunker connection string or resolve NIP-05 identifier');
|
||||
}
|
||||
|
||||
console.log('Parsed bunker pointer:', bunkerPointer);
|
||||
// console.log('Parsed bunker pointer:', bunkerPointer);
|
||||
|
||||
// Create local client keypair for this session
|
||||
const localSecretKey = window.NostrTools.generateSecretKey();
|
||||
console.log('Generated local client keypair for NIP-46 session');
|
||||
// console.log('Generated local client keypair for NIP-46 session');
|
||||
|
||||
// Use nostr-tools BunkerSigner factory method (not constructor - it's private)
|
||||
console.log('Creating nip46 BunkerSigner...');
|
||||
// console.log('Creating nip46 BunkerSigner...');
|
||||
const signer = window.NostrTools.nip46.BunkerSigner.fromBunker(localSecretKey, bunkerPointer, {
|
||||
onauth: (url) => {
|
||||
console.log('Received auth URL from bunker:', url);
|
||||
// console.log('Received auth URL from bunker:', url);
|
||||
// Open auth URL in popup or redirect
|
||||
window.open(url, '_blank', 'width=600,height=800');
|
||||
}
|
||||
});
|
||||
|
||||
console.log('NIP-46 BunkerSigner created successfully');
|
||||
// console.log('NIP-46 BunkerSigner created successfully');
|
||||
|
||||
// Skip ping test - NIP-46 works through relays, not direct connection
|
||||
// Try to connect directly (this may trigger auth flow)
|
||||
console.log('Attempting NIP-46 connect...');
|
||||
// console.log('Attempting NIP-46 connect...');
|
||||
await signer.connect();
|
||||
console.log('NIP-46 connect successful');
|
||||
// console.log('NIP-46 connect successful');
|
||||
|
||||
// Get the user's public key from the bunker
|
||||
console.log('Getting public key from bunker...');
|
||||
// console.log('Getting public key from bunker...');
|
||||
const userPubkey = await signer.getPublicKey();
|
||||
console.log('NIP-46 user public key:', userPubkey);
|
||||
// console.log('NIP-46 user public key:', userPubkey);
|
||||
|
||||
// Store the NIP-46 authentication info
|
||||
const nip46Info = {
|
||||
@@ -1499,7 +1499,7 @@ class Modal {
|
||||
}
|
||||
};
|
||||
|
||||
console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!');
|
||||
// console.log('NOSTR_LOGIN_LITE NIP-46 connection established successfully!');
|
||||
|
||||
// Set as current auth method
|
||||
this._setAuthMethod('nip46', nip46Info);
|
||||
@@ -1672,8 +1672,8 @@ class Modal {
|
||||
textarea.oninput();
|
||||
}
|
||||
|
||||
console.log('Generated new seed phrase:', mnemonic.split(/\s+/).length, 'words');
|
||||
|
||||
// console.log('Generated new seed phrase:', mnemonic.split(/\s+/).length, 'words');
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to generate seed phrase:', error);
|
||||
formatHint.textContent = '❌ Failed to generate seed phrase - NIP-06 not available';
|
||||
@@ -1690,7 +1690,7 @@ class Modal {
|
||||
}
|
||||
|
||||
const words = mnemonic.trim().split(/\s+/);
|
||||
|
||||
|
||||
// Must be 12 or 24 words
|
||||
if (words.length !== 12 && words.length !== 24) {
|
||||
return false;
|
||||
@@ -1700,7 +1700,7 @@ class Modal {
|
||||
window.NostrTools.nip06.privateKeyFromSeedWords(mnemonic, '', 0);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.log('Mnemonic validation failed:', error.message);
|
||||
// console.log('Mnemonic validation failed:', error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1742,7 +1742,7 @@ class Modal {
|
||||
throw new Error('Failed to derive any accounts from seed phrase');
|
||||
}
|
||||
|
||||
console.log(`Successfully derived ${accounts.length} accounts from seed phrase`);
|
||||
// console.log(`Successfully derived ${accounts.length} accounts from seed phrase`);
|
||||
this._showAccountSelection(accounts);
|
||||
|
||||
} catch (error) {
|
||||
@@ -1838,8 +1838,8 @@ class Modal {
|
||||
}
|
||||
|
||||
_selectAccount(account) {
|
||||
console.log('Selected account:', account.index, account.npub);
|
||||
|
||||
// console.log('Selected account:', account.index, account.npub);
|
||||
|
||||
// Use the same auth method as local keys, but with seedphrase identifier
|
||||
this._setAuthMethod('local', {
|
||||
secret: account.nsec,
|
||||
|
||||
Reference in New Issue
Block a user