From be13ecf73f5dea8625998062dfe379e4a3f92162 Mon Sep 17 00:00:00 2001 From: OFF0 Date: Sun, 6 Nov 2022 23:10:42 +0100 Subject: [PATCH] setting: add import and generate private key Added a new tab for settings to create a private key. The key is only set in local storage but not used yet. --- src/form.css | 60 +++++++++++++++++++++++++++++++++++++++++++++ src/index.html | 17 +++++++++++++ src/main.css | 7 ++++++ src/main.js | 66 +++++++++++++++++++++++++++++++++++++++++++++++--- src/tabs.css | 5 ++-- 5 files changed, 148 insertions(+), 7 deletions(-) create mode 100644 src/form.css diff --git a/src/form.css b/src/form.css new file mode 100644 index 0000000..d228053 --- /dev/null +++ b/src/form.css @@ -0,0 +1,60 @@ +form { + max-width: 64ch; +} + +button, +input, +textarea { + font-family: monospace; +} + +label { + display: block; + margin-bottom: .5rem; + padding-left: 0; + text-indent: 0; +} + +input[type="text"] { + display: block; + margin-bottom: 1rem; + padding: .5rem; + width: 100%; +} + +input[type="password"] { + display: block; + margin-bottom: 1rem; + padding: .5rem; + width: 100%; +} + +button { + background-color: var(--bgcolor-accent); + border: none; + color: white; + cursor: pointer; + padding: .5rem 1rem; +} + +button:disabled { + background-color: var(--bgcolor-inactive); + cursor: default; +} + +.buttons { + align-items: center; + display: flex; + justify-content: flex-end; + height: 2rem; +} + +.inline-text, +.inline-error { + display: inline-block; + padding: 0 1ch; +} + +.inline-error { + color: var(--color-danger); +} diff --git a/src/index.html b/src/index.html index e58131b..9774a3b 100644 --- a/src/index.html +++ b/src/index.html @@ -40,6 +40,23 @@ +
+ + +
+ + + + +
+ + + or + +
+
+
+ diff --git a/src/main.css b/src/main.css index 3fb1b7b..99bc7d9 100644 --- a/src/main.css +++ b/src/main.css @@ -1,10 +1,16 @@ @import "tabs.css"; @import "cards.css"; +@import "form.css"; + +:root { + --color-danger: #e00; +} @media (prefers-color-scheme: light) { html { --bgcolor: #fff7e9; --bgcolor-accent: #ff731d; + --bgcolor-inactive: #737373; --fgcolor: #1746a2; --fgcolor-accent: #5f9df7; } @@ -14,6 +20,7 @@ html { --bgcolor: #191919; --bgcolor-accent: #2d4263; + --bgcolor-inactive: #535353; --fgcolor: #c84b31; --fgcolor-accent: #ecdbba; } diff --git a/src/main.js b/src/main.js index c57ce91..f4302d5 100644 --- a/src/main.js +++ b/src/main.js @@ -1,4 +1,4 @@ -import {relayPool} from 'nostr-tools'; +import {relayPool, generatePrivateKey, getPublicKey} from 'nostr-tools'; import {elem} from './domutil.js'; const pool = relayPool(); @@ -18,7 +18,6 @@ const userList = []; function onEvent(evt, relay) { switch (evt.kind) { case 0: - // console.log(`event.kind=0 from ${relay}`, evt); try { const content = JSON.parse(evt.content); setMetadata(userList, relay, evt, content); @@ -33,7 +32,7 @@ function onEvent(evt, relay) { renderRecommendServer(evt, relay); break; default: - // console.log(`add support for ${evt.kind}`, evt) + console.log(`TODO: add support for event kind ${evt.kind}`, evt) } } @@ -109,6 +108,65 @@ function setMetadata(userList, relay, evt, content) { timestamp: evt.created_at, ...content, }; - console.log('update existing user', user); } } + +// settings + +const form = document.querySelector('form[name="settings"]'); +const privateKeyInput = form.querySelector('#privatekey'); +const pubKeyInput = form.querySelector('#pubkey'); +const keyError = form.querySelector('#keyError'); +const generateBtn = form.querySelector('button[name="generate"]'); +const importBtn = form.querySelector('button[name="import"]'); + +generateBtn.addEventListener('click', (evt) => { + evt.preventDefault(); + const privateKey = generatePrivateKey(); + const pubKey = getPublicKey(privateKey); + if (validKeys(privateKey, pubKey)) { + localStorage.setItem('privateKey', privateKey); + localStorage.setItem('pubKey', pubKey); + privateKeyInput.value = privateKey; + pubKeyInput.value = pubKey; + } +}); + +privateKeyInput.value = localStorage.getItem('privateKey'); +pubKeyInput.value = localStorage.getItem('pubKey'); + +importBtn.addEventListener('click', (evt) => { + evt.preventDefault(); + const privateKey = privateKeyInput.value; + const pubKey = pubKeyInput.value; + if (validKeys(privateKey, pubKey)) { + localStorage.setItem('privateKey', privateKey); + localStorage.setItem('pubKey', pubKey); + } +}); + +form.addEventListener('input', () => validKeys(privateKeyInput.value, pubKeyInput.value)); + +function validKeys(privateKey, pubKey) { + if (pubKey && privateKey) { + try { + if (getPublicKey(privateKey) === pubKey) { + keyError.hidden = true; + keyError.textContent = ''; + importBtn.removeAttribute('disabled'); + return true; + } else { + keyError.textContent = 'private key does not correspond to public key!' + } + } catch (e) { + keyError.textContent = `not a valid private key: ${e.message || e}`; + } + } + keyError.hidden = false; + importBtn.setAttribute('disabled', true); + return false; +} + +document.body.addEventListener('keyup', () => { + console.log(document.activeElemen) +}); diff --git a/src/tabs.css b/src/tabs.css index 50ce201..c9c5295 100644 --- a/src/tabs.css +++ b/src/tabs.css @@ -7,10 +7,9 @@ float: left; } -.tab label { +.tab > label { cursor: pointer; font-size: 1.1em; - border-radius: 5px 5px 0 0; padding: .5em 1em; } @@ -49,6 +48,6 @@ left: 0; right: 0; bottom: 0; - padding: 5px; + padding: 1rem 0; opacity: 0; }