Change key entry
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
rsync -avz --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:WWW/nostr-login-lite/
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.1.3
|
||||
0.1.4
|
||||
|
||||
@@ -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-09-21T15:22:26.408Z
|
||||
* Generated on: 2025-09-21T15:51:33.328Z
|
||||
*/
|
||||
|
||||
// Verify dependencies are loaded
|
||||
@@ -381,7 +381,7 @@ class Modal {
|
||||
`;
|
||||
|
||||
const modalTitle = document.createElement('h2');
|
||||
modalTitle.textContent = 'Nostr Login v0.1.3';
|
||||
modalTitle.textContent = 'Nostr Login v0.1.4';
|
||||
modalTitle.style.cssText = `
|
||||
margin: 0;
|
||||
font-size: 24px;
|
||||
@@ -997,62 +997,8 @@ class Modal {
|
||||
_showLocalKeyScreen() {
|
||||
this.modalBody.innerHTML = '';
|
||||
|
||||
const title = document.createElement('h3');
|
||||
title.textContent = 'Local Key';
|
||||
title.style.cssText = 'margin: 0 0 20px 0; font-size: 18px; font-weight: 600;';
|
||||
|
||||
const createButton = document.createElement('button');
|
||||
createButton.textContent = 'Create New Key';
|
||||
createButton.onclick = () => this._createLocalKey();
|
||||
createButton.style.cssText = this._getButtonStyle();
|
||||
|
||||
const importButton = document.createElement('button');
|
||||
importButton.textContent = 'Import Existing Key';
|
||||
importButton.onclick = () => this._showImportKeyForm();
|
||||
importButton.style.cssText = this._getButtonStyle() + 'margin-top: 12px;';
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.textContent = 'Back';
|
||||
backButton.onclick = () => this._renderLoginOptions();
|
||||
backButton.style.cssText = `
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
padding: 12px;
|
||||
background: #6b7280;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
this.modalBody.appendChild(title);
|
||||
this.modalBody.appendChild(createButton);
|
||||
this.modalBody.appendChild(importButton);
|
||||
this.modalBody.appendChild(backButton);
|
||||
}
|
||||
|
||||
_createLocalKey() {
|
||||
try {
|
||||
const sk = window.NostrTools.generateSecretKey();
|
||||
const pk = window.NostrTools.getPublicKey(sk);
|
||||
const nsec = window.NostrTools.nip19.nsecEncode(sk);
|
||||
const npub = window.NostrTools.nip19.npubEncode(pk);
|
||||
|
||||
this._showKeyDisplay(pk, nsec, 'created');
|
||||
} catch (error) {
|
||||
this._showError('Failed to create key: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
_showImportKeyForm() {
|
||||
this.modalBody.innerHTML = '';
|
||||
|
||||
const title = document.createElement('h3');
|
||||
title.textContent = 'Import Local Key';
|
||||
title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;';
|
||||
|
||||
const description = document.createElement('p');
|
||||
description.textContent = 'Enter your secret key in either nsec or hex format:';
|
||||
description.innerHTML = 'Enter your secret key in nsec or hex format, or <span id="generate-new" style="text-decoration: underline; cursor: pointer; color: var(--nl-primary-color);">generate new</span>.';
|
||||
description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;';
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
@@ -1074,10 +1020,40 @@ class Modal {
|
||||
const formatHint = document.createElement('div');
|
||||
formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;';
|
||||
|
||||
const importButton = document.createElement('button');
|
||||
importButton.textContent = 'Import Key';
|
||||
importButton.disabled = true;
|
||||
importButton.onclick = () => {
|
||||
if (!importButton.disabled) {
|
||||
this._importLocalKey(textarea.value);
|
||||
}
|
||||
};
|
||||
|
||||
// Set initial disabled state
|
||||
importButton.style.cssText = `
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: var(--nl-border-width) solid var(--nl-muted-color);
|
||||
border-radius: var(--nl-border-radius);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
cursor: not-allowed;
|
||||
transition: all 0.2s;
|
||||
font-family: var(--nl-font-family, 'Courier New', monospace);
|
||||
background: var(--nl-secondary-color);
|
||||
color: var(--nl-muted-color);
|
||||
`;
|
||||
|
||||
textarea.oninput = () => {
|
||||
const value = textarea.value.trim();
|
||||
if (!value) {
|
||||
formatHint.textContent = '';
|
||||
// Disable button
|
||||
importButton.disabled = true;
|
||||
importButton.style.borderColor = 'var(--nl-muted-color)';
|
||||
importButton.style.color = 'var(--nl-muted-color)';
|
||||
importButton.style.cursor = 'not-allowed';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1085,32 +1061,93 @@ class Modal {
|
||||
if (format === 'nsec') {
|
||||
formatHint.textContent = '✅ Valid nsec format detected';
|
||||
formatHint.style.color = '#059669';
|
||||
// Enable button
|
||||
importButton.disabled = false;
|
||||
importButton.style.borderColor = 'var(--nl-primary-color)';
|
||||
importButton.style.color = 'var(--nl-primary-color)';
|
||||
importButton.style.cursor = 'pointer';
|
||||
} else if (format === 'hex') {
|
||||
formatHint.textContent = '✅ Valid hex format detected';
|
||||
formatHint.style.color = '#059669';
|
||||
// Enable button
|
||||
importButton.disabled = false;
|
||||
importButton.style.borderColor = 'var(--nl-primary-color)';
|
||||
importButton.style.color = 'var(--nl-primary-color)';
|
||||
importButton.style.cursor = 'pointer';
|
||||
} else {
|
||||
formatHint.textContent = '❌ Invalid key format - must be nsec1... or 64-character hex';
|
||||
formatHint.style.color = '#dc2626';
|
||||
// Disable button
|
||||
importButton.disabled = true;
|
||||
importButton.style.borderColor = 'var(--nl-muted-color)';
|
||||
importButton.style.color = 'var(--nl-muted-color)';
|
||||
importButton.style.cursor = 'not-allowed';
|
||||
}
|
||||
};
|
||||
|
||||
const importButton = document.createElement('button');
|
||||
importButton.textContent = 'Import Key';
|
||||
importButton.onclick = () => this._importLocalKey(textarea.value);
|
||||
importButton.style.cssText = this._getButtonStyle();
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.textContent = 'Back';
|
||||
backButton.onclick = () => this._showLocalKeyScreen();
|
||||
backButton.onclick = () => this._renderLoginOptions();
|
||||
backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;';
|
||||
|
||||
this.modalBody.appendChild(title);
|
||||
this.modalBody.appendChild(description);
|
||||
this.modalBody.appendChild(textarea);
|
||||
this.modalBody.appendChild(formatHint);
|
||||
this.modalBody.appendChild(importButton);
|
||||
this.modalBody.appendChild(backButton);
|
||||
|
||||
// Add click handler for the "generate new" link
|
||||
const generateLink = document.getElementById('generate-new');
|
||||
if (generateLink) {
|
||||
generateLink.addEventListener('mouseenter', () => {
|
||||
generateLink.style.color = 'var(--nl-accent-color)';
|
||||
});
|
||||
generateLink.addEventListener('mouseleave', () => {
|
||||
generateLink.style.color = 'var(--nl-primary-color)';
|
||||
});
|
||||
generateLink.addEventListener('click', () => {
|
||||
this._generateNewLocalKey(textarea, formatHint);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_generateNewLocalKey(textarea, formatHint) {
|
||||
try {
|
||||
// Generate a new secret key using NostrTools
|
||||
const sk = window.NostrTools.generateSecretKey();
|
||||
const nsec = window.NostrTools.nip19.nsecEncode(sk);
|
||||
|
||||
// Set the generated key in the textarea
|
||||
textarea.value = nsec;
|
||||
|
||||
// Trigger the oninput event to properly validate and enable the button
|
||||
if (textarea.oninput) {
|
||||
textarea.oninput();
|
||||
}
|
||||
|
||||
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';
|
||||
formatHint.style.color = '#dc2626';
|
||||
}
|
||||
}
|
||||
|
||||
_createLocalKey() {
|
||||
try {
|
||||
const sk = window.NostrTools.generateSecretKey();
|
||||
const pk = window.NostrTools.getPublicKey(sk);
|
||||
const nsec = window.NostrTools.nip19.nsecEncode(sk);
|
||||
const npub = window.NostrTools.nip19.npubEncode(pk);
|
||||
|
||||
this._showKeyDisplay(pk, nsec, 'created');
|
||||
} catch (error) {
|
||||
this._showError('Failed to create key: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
_detectKeyFormat(keyValue) {
|
||||
const trimmed = keyValue.trim();
|
||||
|
||||
161
lite/ui/modal.js
161
lite/ui/modal.js
@@ -700,62 +700,8 @@ class Modal {
|
||||
_showLocalKeyScreen() {
|
||||
this.modalBody.innerHTML = '';
|
||||
|
||||
const title = document.createElement('h3');
|
||||
title.textContent = 'Local Key';
|
||||
title.style.cssText = 'margin: 0 0 20px 0; font-size: 18px; font-weight: 600;';
|
||||
|
||||
const createButton = document.createElement('button');
|
||||
createButton.textContent = 'Create New Key';
|
||||
createButton.onclick = () => this._createLocalKey();
|
||||
createButton.style.cssText = this._getButtonStyle();
|
||||
|
||||
const importButton = document.createElement('button');
|
||||
importButton.textContent = 'Import Existing Key';
|
||||
importButton.onclick = () => this._showImportKeyForm();
|
||||
importButton.style.cssText = this._getButtonStyle() + 'margin-top: 12px;';
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.textContent = 'Back';
|
||||
backButton.onclick = () => this._renderLoginOptions();
|
||||
backButton.style.cssText = `
|
||||
display: block;
|
||||
margin-top: 20px;
|
||||
padding: 12px;
|
||||
background: #6b7280;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
this.modalBody.appendChild(title);
|
||||
this.modalBody.appendChild(createButton);
|
||||
this.modalBody.appendChild(importButton);
|
||||
this.modalBody.appendChild(backButton);
|
||||
}
|
||||
|
||||
_createLocalKey() {
|
||||
try {
|
||||
const sk = window.NostrTools.generateSecretKey();
|
||||
const pk = window.NostrTools.getPublicKey(sk);
|
||||
const nsec = window.NostrTools.nip19.nsecEncode(sk);
|
||||
const npub = window.NostrTools.nip19.npubEncode(pk);
|
||||
|
||||
this._showKeyDisplay(pk, nsec, 'created');
|
||||
} catch (error) {
|
||||
this._showError('Failed to create key: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
_showImportKeyForm() {
|
||||
this.modalBody.innerHTML = '';
|
||||
|
||||
const title = document.createElement('h3');
|
||||
title.textContent = 'Import Local Key';
|
||||
title.style.cssText = 'margin: 0 0 16px 0; font-size: 18px; font-weight: 600;';
|
||||
|
||||
const description = document.createElement('p');
|
||||
description.textContent = 'Enter your secret key in either nsec or hex format:';
|
||||
description.innerHTML = 'Enter your secret key in nsec or hex format, or <span id="generate-new" style="text-decoration: underline; cursor: pointer; color: var(--nl-primary-color);">generate new</span>.';
|
||||
description.style.cssText = 'margin-bottom: 12px; color: #6b7280; font-size: 14px;';
|
||||
|
||||
const textarea = document.createElement('textarea');
|
||||
@@ -777,10 +723,40 @@ class Modal {
|
||||
const formatHint = document.createElement('div');
|
||||
formatHint.style.cssText = 'margin-bottom: 16px; font-size: 12px; color: #6b7280; min-height: 16px;';
|
||||
|
||||
const importButton = document.createElement('button');
|
||||
importButton.textContent = 'Import Key';
|
||||
importButton.disabled = true;
|
||||
importButton.onclick = () => {
|
||||
if (!importButton.disabled) {
|
||||
this._importLocalKey(textarea.value);
|
||||
}
|
||||
};
|
||||
|
||||
// Set initial disabled state
|
||||
importButton.style.cssText = `
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: var(--nl-border-width) solid var(--nl-muted-color);
|
||||
border-radius: var(--nl-border-radius);
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
cursor: not-allowed;
|
||||
transition: all 0.2s;
|
||||
font-family: var(--nl-font-family, 'Courier New', monospace);
|
||||
background: var(--nl-secondary-color);
|
||||
color: var(--nl-muted-color);
|
||||
`;
|
||||
|
||||
textarea.oninput = () => {
|
||||
const value = textarea.value.trim();
|
||||
if (!value) {
|
||||
formatHint.textContent = '';
|
||||
// Disable button
|
||||
importButton.disabled = true;
|
||||
importButton.style.borderColor = 'var(--nl-muted-color)';
|
||||
importButton.style.color = 'var(--nl-muted-color)';
|
||||
importButton.style.cursor = 'not-allowed';
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -788,32 +764,93 @@ class Modal {
|
||||
if (format === 'nsec') {
|
||||
formatHint.textContent = '✅ Valid nsec format detected';
|
||||
formatHint.style.color = '#059669';
|
||||
// Enable button
|
||||
importButton.disabled = false;
|
||||
importButton.style.borderColor = 'var(--nl-primary-color)';
|
||||
importButton.style.color = 'var(--nl-primary-color)';
|
||||
importButton.style.cursor = 'pointer';
|
||||
} else if (format === 'hex') {
|
||||
formatHint.textContent = '✅ Valid hex format detected';
|
||||
formatHint.style.color = '#059669';
|
||||
// Enable button
|
||||
importButton.disabled = false;
|
||||
importButton.style.borderColor = 'var(--nl-primary-color)';
|
||||
importButton.style.color = 'var(--nl-primary-color)';
|
||||
importButton.style.cursor = 'pointer';
|
||||
} else {
|
||||
formatHint.textContent = '❌ Invalid key format - must be nsec1... or 64-character hex';
|
||||
formatHint.style.color = '#dc2626';
|
||||
// Disable button
|
||||
importButton.disabled = true;
|
||||
importButton.style.borderColor = 'var(--nl-muted-color)';
|
||||
importButton.style.color = 'var(--nl-muted-color)';
|
||||
importButton.style.cursor = 'not-allowed';
|
||||
}
|
||||
};
|
||||
|
||||
const importButton = document.createElement('button');
|
||||
importButton.textContent = 'Import Key';
|
||||
importButton.onclick = () => this._importLocalKey(textarea.value);
|
||||
importButton.style.cssText = this._getButtonStyle();
|
||||
|
||||
const backButton = document.createElement('button');
|
||||
backButton.textContent = 'Back';
|
||||
backButton.onclick = () => this._showLocalKeyScreen();
|
||||
backButton.onclick = () => this._renderLoginOptions();
|
||||
backButton.style.cssText = this._getButtonStyle('secondary') + 'margin-top: 12px;';
|
||||
|
||||
this.modalBody.appendChild(title);
|
||||
this.modalBody.appendChild(description);
|
||||
this.modalBody.appendChild(textarea);
|
||||
this.modalBody.appendChild(formatHint);
|
||||
this.modalBody.appendChild(importButton);
|
||||
this.modalBody.appendChild(backButton);
|
||||
|
||||
// Add click handler for the "generate new" link
|
||||
const generateLink = document.getElementById('generate-new');
|
||||
if (generateLink) {
|
||||
generateLink.addEventListener('mouseenter', () => {
|
||||
generateLink.style.color = 'var(--nl-accent-color)';
|
||||
});
|
||||
generateLink.addEventListener('mouseleave', () => {
|
||||
generateLink.style.color = 'var(--nl-primary-color)';
|
||||
});
|
||||
generateLink.addEventListener('click', () => {
|
||||
this._generateNewLocalKey(textarea, formatHint);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_generateNewLocalKey(textarea, formatHint) {
|
||||
try {
|
||||
// Generate a new secret key using NostrTools
|
||||
const sk = window.NostrTools.generateSecretKey();
|
||||
const nsec = window.NostrTools.nip19.nsecEncode(sk);
|
||||
|
||||
// Set the generated key in the textarea
|
||||
textarea.value = nsec;
|
||||
|
||||
// Trigger the oninput event to properly validate and enable the button
|
||||
if (textarea.oninput) {
|
||||
textarea.oninput();
|
||||
}
|
||||
|
||||
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';
|
||||
formatHint.style.color = '#dc2626';
|
||||
}
|
||||
}
|
||||
|
||||
_createLocalKey() {
|
||||
try {
|
||||
const sk = window.NostrTools.generateSecretKey();
|
||||
const pk = window.NostrTools.getPublicKey(sk);
|
||||
const nsec = window.NostrTools.nip19.nsecEncode(sk);
|
||||
const npub = window.NostrTools.nip19.npubEncode(pk);
|
||||
|
||||
this._showKeyDisplay(pk, nsec, 'created');
|
||||
} catch (error) {
|
||||
this._showError('Failed to create key: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
_detectKeyFormat(keyValue) {
|
||||
const trimmed = keyValue.trim();
|
||||
|
||||
Reference in New Issue
Block a user