diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..2375b78 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "trailingComma": "es5", + "tabWidth": 4, + "semi": true, + "singleQuote": true, + "arrowParens": "avoid" +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cac0e10 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/Shared (Extension)/Resources/background.js b/Shared (Extension)/Resources/background.js index d244b94..7d86548 100644 --- a/Shared (Extension)/Resources/background.js +++ b/Shared (Extension)/Resources/background.js @@ -1,90 +1,98 @@ -import { generatePrivateKey, getPublicKey, signEvent, nip04, nip19 } from "nostr-tools"; +import { + generatePrivateKey, + getPublicKey, + signEvent, + nip04, + nip19, +} from 'nostr-tools'; const storage = browser.storage.local; -browser.runtime.onInstalled.addListener(async ({reason}) => { +browser.runtime.onInstalled.addListener(async ({ reason }) => { // I would like to be able to skip this for development purposes - let ignoreHook = (await storage.get('ignoreInstallHook')).ignoreInstallHook + let ignoreHook = (await storage.get('ignoreInstallHook')).ignoreInstallHook; if (ignoreHook === true) { return; } if (['install'].includes(reason)) { - browser.tabs.create({ - url: 'https://ursus.camp/nostore' - }) + browser.tabs.create({ + url: 'https://ursus.camp/nostore', + }); } }); -browser.runtime.onMessage.addListener(async (message, _sender, sendResponse) => { - console.log(message); +browser.runtime.onMessage.addListener( + async (message, _sender, sendResponse) => { + console.log(message); - switch (message.kind) { - case 'init': - await initialize(); - break; - case 'setProfileIndex': - await setProfileIndex(message.payload); - break; - case 'getProfileIndex': - let profileIndex = await getProfileIndex(); - sendResponse(profileIndex); - break; - case 'getNsecKey': - let nsecKey = await getNsecKey(); - sendResponse(nsecKey); - break; - case 'getNpubKey': - let npubKey = await getNpubKey(); - sendResponse(npubKey); - break; - case 'getPubKey': - let pubKey = await getPubKey(); - sendResponse(pubKey); - break; - case 'getHosts': - let hosts = await getHosts(); - sendResponse(hosts); - break; - case 'getName': - let name = await getName(); - sendResponse(name); - break; - case 'getProfileNames': - let profileNames = await getProfileNames(); - sendResponse(profileNames); - break; - case 'newProfile': - let newIndex = await newProfile(); - sendResponse(newIndex); - break; - case 'saveProfile': - await saveProfile(message.payload); - break; - case 'clearData': - await browser.storage.local.clear(); - break; - case 'deleteProfile': - await deleteProfile(); - break; - case 'signEvent': - let event = await signEvent_(message.payload); - sendResponse(event); - break; - case 'nip04.encrypt': - let cipherText = await nip04Encrypt(message.payload); - sendResponse(cipherText); - break; - case 'nip04.decrypt': - let plainText = await nip04Decrypt(message.payload); - sendResponse(plainText); - break; - case 'getRelays': - sendResponse({}); - break; - default: - break; + switch (message.kind) { + case 'init': + await initialize(); + break; + case 'setProfileIndex': + await setProfileIndex(message.payload); + break; + case 'getProfileIndex': + let profileIndex = await getProfileIndex(); + sendResponse(profileIndex); + break; + case 'getNsecKey': + let nsecKey = await getNsecKey(); + sendResponse(nsecKey); + break; + case 'getNpubKey': + let npubKey = await getNpubKey(); + sendResponse(npubKey); + break; + case 'getPubKey': + let pubKey = await getPubKey(); + sendResponse(pubKey); + break; + case 'getHosts': + let hosts = await getHosts(); + sendResponse(hosts); + break; + case 'getName': + let name = await getName(); + sendResponse(name); + break; + case 'getProfileNames': + let profileNames = await getProfileNames(); + sendResponse(profileNames); + break; + case 'newProfile': + let newIndex = await newProfile(); + sendResponse(newIndex); + break; + case 'saveProfile': + await saveProfile(message.payload); + break; + case 'clearData': + await browser.storage.local.clear(); + break; + case 'deleteProfile': + await deleteProfile(); + break; + case 'signEvent': + let event = await signEvent_(message.payload); + sendResponse(event); + break; + case 'nip04.encrypt': + let cipherText = await nip04Encrypt(message.payload); + sendResponse(cipherText); + break; + case 'nip04.decrypt': + let plainText = await nip04Decrypt(message.payload); + sendResponse(plainText); + break; + case 'getRelays': + sendResponse({}); + break; + default: + break; + } } -}); +); async function get(item) { return (await storage.get(item))[item]; @@ -93,7 +101,7 @@ async function get(item) { async function getOrSetDefault(key, def) { let val = (await storage.get(key))[key]; if (val == null || val == undefined) { - await storage.set({[key]: def}); + await storage.set({ [key]: def }); return def; } @@ -102,7 +110,9 @@ async function getOrSetDefault(key, def) { async function initialize() { await getOrSetDefault('profileIndex', 0); - await getOrSetDefault('profiles', [{name: 'Default', privKey: generatePrivateKey(), hosts: []}]); + await getOrSetDefault('profiles', [ + { name: 'Default', privKey: generatePrivateKey(), hosts: [] }, + ]); } async function getNsecKey() { @@ -145,7 +155,7 @@ async function getProfileNames() { } async function setProfileIndex(profileIndex) { - await storage.set({profileIndex}); + await storage.set({ profileIndex }); } async function getProfileIndex() { @@ -162,9 +172,13 @@ async function currentProfile() { async function newProfile() { let profiles = await get('profiles'); - const newProfile = {name: 'New Profile', privKey: generatePrivateKey(), hosts: []}; + const newProfile = { + name: 'New Profile', + privKey: generatePrivateKey(), + hosts: [], + }; profiles.push(newProfile); - await storage.set({profiles}); + await storage.set({ profiles }); return profiles.length - 1; } @@ -175,7 +189,7 @@ async function saveProfile(profile) { let index = await getProfileIndex(); let profiles = await get('profiles'); profiles[index] = profile; - await storage.set({profiles}); + await storage.set({ profiles }); } async function deleteProfile() { @@ -183,22 +197,22 @@ async function deleteProfile() { let profiles = await get('profiles'); profiles.splice(index, 1); let profileIndex = Math.max(index - 1, 0); - await storage.set({profiles, profileIndex}); + await storage.set({ profiles, profileIndex }); } async function signEvent_(event) { - event = {...event}; + event = { ...event }; let privKey = await getPrivKey(); event.sig = signEvent(event, privKey); return event; } -async function nip04Encrypt({pubKey, plainText}) { +async function nip04Encrypt({ pubKey, plainText }) { let privKey = await getPrivKey(); return nip04.encrypt(privKey, pubKey, plainText); } -async function nip04Decrypt({pubKey, cipherText}) { +async function nip04Decrypt({ pubKey, cipherText }) { let privKey = await getPrivKey(); return nip04.decrypt(privKey, pubKey, cipherText); -} \ No newline at end of file +} diff --git a/Shared (Extension)/Resources/content.js b/Shared (Extension)/Resources/content.js index ff988ab..7dfd747 100644 --- a/Shared (Extension)/Resources/content.js +++ b/Shared (Extension)/Resources/content.js @@ -2,16 +2,20 @@ let script = document.createElement('script'); script.setAttribute('src', browser.runtime.getURL('nostr.build.js')); document.body.appendChild(script); -window.addEventListener('message', async (message) => { - const validEvents = ['getPubKey', 'signEvent', 'getRelays', 'nip04.encrypt', 'nip04.decrypt']; - let {kind, reqId, payload} = message.data; - if (!validEvents.includes(kind)) - return; - - console.log(`Event ${reqId}: Content script received message kind ${kind}, payload: `, payload); - payload = await browser.runtime.sendMessage({kind, payload}); +window.addEventListener('message', async message => { + const validEvents = [ + 'getPubKey', + 'signEvent', + 'getRelays', + 'nip04.encrypt', + 'nip04.decrypt', + ]; + let { kind, reqId, payload } = message.data; + if (!validEvents.includes(kind)) return; - kind = `return_${kind}`; + payload = await browser.runtime.sendMessage({ kind, payload }); - window.postMessage({kind, reqId, payload}, '*'); -}); \ No newline at end of file + kind = `return_${kind}`; + + window.postMessage({ kind, reqId, payload }, '*'); +}); diff --git a/Shared (Extension)/Resources/nostr.js b/Shared (Extension)/Resources/nostr.js index 8684c09..f302f14 100644 --- a/Shared (Extension)/Resources/nostr.js +++ b/Shared (Extension)/Resources/nostr.js @@ -4,7 +4,7 @@ window.nostr = { async getPublicKey() { return await this.broadcast('getPubKey'); }, - + async signEvent(event) { return await this.broadcast('signEvent', event); }, @@ -16,7 +16,7 @@ window.nostr = { // This is here for Alby comatibility. This is not part of the NIP-07 standard. // I have found at least one site, nostr.band, which expects it to be present. async enable() { - return {enabled: true} + return { enabled: true }; }, broadcast(kind, payload) { @@ -24,30 +24,40 @@ window.nostr = { return new Promise((resolve, _reject) => { this.requests[reqId] = resolve; console.log(`Event ${reqId}: ${kind}, payload: `, payload); - window.postMessage({kind, reqId, payload}, '*'); + window.postMessage({ kind, reqId, payload }, '*'); }); }, - nip04: { async encrypt(pubKey, plainText) { - return await window.nostr.broadcast('nip04.encrypt', {pubKey, plainText}); + return await window.nostr.broadcast('nip04.encrypt', { + pubKey, + plainText, + }); }, async decrypt(pubKey, cipherText) { - return await window.nostr.broadcast('nip04.decrypt', {pubKey, cipherText}); - } - } -} + return await window.nostr.broadcast('nip04.decrypt', { + pubKey, + cipherText, + }); + }, + }, +}; -window.addEventListener('message', (message) => { - const validEvents = ['getPubKey', 'signEvent', 'getRelays', 'nip04.encrypt', 'nip04.decrypt'].map(e => `return_${e}`); - let {kind, reqId, payload} = message.data; +window.addEventListener('message', message => { + const validEvents = [ + 'getPubKey', + 'signEvent', + 'getRelays', + 'nip04.encrypt', + 'nip04.decrypt', + ].map(e => `return_${e}`); + let { kind, reqId, payload } = message.data; + + if (!validEvents.includes(kind)) return; - if (!validEvents.includes(kind)) - return; - console.log(`Event ${reqId}: Received payload:`, payload); window.nostr.requests[reqId](payload); delete window.nostr.requests[reqId]; -}); \ No newline at end of file +}); diff --git a/Shared (Extension)/Resources/popup.html b/Shared (Extension)/Resources/popup.html index 313ad9a..ec938fc 100644 --- a/Shared (Extension)/Resources/popup.html +++ b/Shared (Extension)/Resources/popup.html @@ -1,11 +1,13 @@ +
+