From fecbb8ff500644ca78bb7849980dd5b17df0c733 Mon Sep 17 00:00:00 2001 From: OFF0 Date: Tue, 6 Dec 2022 22:03:00 +0100 Subject: [PATCH] feed: show picture (kind 0) with noyx Loading images from random url leaks meta data to other servers. Enabled showing kind 0 picture from noxy (nostr proxy), see https://git.qcode.ch/nostr/noxy Only href that are a valid url and use http(s) should be allowed to prevent malicious urls such as 'javascript:alert(1)'. Kept the fallback to the speak bubble if there is no kind 0 event for this pubkey or picture is missing. --- src/cards.css | 3 +++ src/main.js | 28 ++++++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/cards.css b/src/cards.css index af579e2..6f677ab 100644 --- a/src/cards.css +++ b/src/cards.css @@ -31,6 +31,9 @@ position: relative; z-index: 2; } +.mbox-img img { + max-width: 100%; +} .mbox-updated-contact .mbox-img, .mbox-recommend-server .mbox-img { diff --git a/src/main.js b/src/main.js index d4bedaa..f5d7f4f 100644 --- a/src/main.js +++ b/src/main.js @@ -52,7 +52,7 @@ const subscription = pool.sub({ // '32e1827635450ebb3c5a7d12c1f8e7b2b514439ac10a67eef3d9fd9c5c68e245', // jb55 // ], // since: new Date(Date.now() - (24 * 60 * 60 * 1000)), - limit: 500, + limit: 750, } }); @@ -318,11 +318,24 @@ function handleMetadata(evt, relay) { } } +const getNoxyUrl = (id, relay, url) => { + if (!isHttpUrl(url)) { + return false; + } + const picture = new URL('https://noxy.nostr.ch/data'); + picture.searchParams.set('id', id); + picture.searchParams.set('relay', relay); + picture.searchParams.set('url', url); + return picture.href; +} + function setMetadata(evt, relay, content) { const user = userList.find(u => u.pubkey === evt.pubkey); + const picture = getNoxyUrl(evt.id, relay, content.picture); if (!user) { userList.push({ metadata: {[relay]: content}, + ...(content.picture && {picture}), pubkey: evt.pubkey, }); } else { @@ -331,6 +344,9 @@ function setMetadata(evt, relay, content) { timestamp: evt.created_at, ...content, }; + if (!user.picture) { + user.picture = picture; + } // no support (yet) for other picture from same pubkey on different relays } // if (tempContactList[relay]) { // const updates = tempContactList[relay].filter(update => update.pubkey === evt.pubkey); @@ -340,6 +356,14 @@ function setMetadata(evt, relay, content) { // } } +function isHttpUrl(string) { + try { + return ['http:', 'https:'].includes(new URL(string).protocol); + } catch (err) { + return false; + } +} + const getHost = (url) => { try { return new URL(url).host; @@ -351,7 +375,7 @@ const getHost = (url) => { function getMetadata(evt, relay) { const host = getHost(relay); const user = userList.find(user => user.pubkey === evt.pubkey); - const userImg = /*user?.metadata[relay]?.picture || */'assets/bubble.svg'; // TODO: enable pic once we have proxy + const userImg = user?.picture || 'assets/bubble.svg'; const userName = user?.metadata[relay]?.name || evt.pubkey.slice(0, 8); const userAbout = user?.metadata[relay]?.about || ''; const img = elem('img', {