From 6ae27be919808df935fb140fd56bb6ae010a219b Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 21 Dec 2022 15:48:14 -0800 Subject: add nostr message field to user profile page --- package.json | 1 + pnpm-lock.yaml | 30 ++++++++++++ src/lib/utils.js | 24 +++++++++ src/routes/(app)/[username]/+page.server.js | 9 +++- src/routes/(app)/[username]/+page.svelte | 60 ++++++++++++++++++++++- src/routes/(app)/[username]/+server.js | 6 +++ src/routes/(app)/[username]/generate/+page.svelte | 27 ++-------- 7 files changed, 129 insertions(+), 28 deletions(-) create mode 100644 src/routes/(app)/[username]/+server.js diff --git a/package.json b/package.json index dac10511..8e86dc1d 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "date-fns": "^2.29.3", "leaflet": "^1.9.3", "leaflet.markercluster": "^1.5.3", + "nostr": "^0.2.7", "postcss": "^8.4.19", "prettier": "^2.7.1", "prettier-plugin-svelte": "^2.8.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2353621a..af33679d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -15,6 +15,7 @@ specifiers: date-fns: ^2.29.3 leaflet: ^1.9.3 leaflet.markercluster: ^1.5.3 + nostr: ^0.2.7 postcss: ^8.4.19 prettier: ^2.7.1 prettier-plugin-svelte: ^2.8.1 @@ -49,6 +50,7 @@ devDependencies: date-fns: 2.29.3 leaflet: 1.9.3 leaflet.markercluster: 1.5.3_leaflet@1.9.3 + nostr: 0.2.7 postcss: 8.4.19 prettier: 2.7.1 prettier-plugin-svelte: 2.8.1_nryolsexf6k3znhuh4uzpugsem @@ -1529,6 +1531,11 @@ packages: hasBin: true dev: true + /noble-secp256k1/1.2.14: + resolution: {integrity: sha512-GSCXyoZBUaaPwVWdYncMEmzlSUjF9J/YeEHpklYJCyg8wPuJP3NzDx0BkiwArzINkdX2HJHvUJhL6vVWPOQQcg==} + deprecated: Switch to namespaced @noble/secp256k1 for security and feature updates + dev: true + /node-addon-api/2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} dev: true @@ -1585,6 +1592,16 @@ packages: engines: {node: '>=0.10.0'} dev: true + /nostr/0.2.7: + resolution: {integrity: sha512-Yq5tkiCTJtohs7H7Fx+Ki83bR8b3xapdwYi17HunhW5EQfZ9rI0cIXFyihj2ZRkv/0YYvVBiCp/KIaLYt5LyfQ==} + dependencies: + noble-secp256k1: 1.2.14 + ws: 8.11.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: true + /object-hash/3.0.0: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} @@ -2372,6 +2389,19 @@ packages: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true + /ws/8.11.0: + resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + /xtend/4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} diff --git a/src/lib/utils.js b/src/lib/utils.js index f59b6359..14646ad0 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -1,3 +1,5 @@ +import * as ecc from 'tiny-secp256k1'; +import { BIP32Factory } from 'bip32'; import { browser } from '$app/environment'; import { toast } from '@zerodevx/svelte-toast'; import { goto } from '$app/navigation'; @@ -168,3 +170,25 @@ export const wait = async (f, s = 300) => { if (i >= s) throw new Error('timeout'); return f(); }; + +export const stretch = async (password, salt) => + crypto.subtle.deriveKey( + { + name: 'PBKDF2', + salt, + iterations: 100000, + hash: 'SHA-256' + }, + await crypto.subtle.importKey( + 'raw', + new TextEncoder().encode(password), + { name: 'PBKDF2' }, + false, + ['deriveBits', 'deriveKey'] + ), + { name: 'AES-GCM', length: 256 }, + true, + ['encrypt', 'decrypt'] + ); + +export const bip32 = await BIP32Factory(ecc); diff --git a/src/routes/(app)/[username]/+page.server.js b/src/routes/(app)/[username]/+page.server.js index 01dfab5a..547f754f 100644 --- a/src/routes/(app)/[username]/+page.server.js +++ b/src/routes/(app)/[username]/+page.server.js @@ -1,14 +1,19 @@ import { get } from '$lib/utils'; import Qr from 'qrcode-base64'; -export async function load({ params, url }) { +export async function load({ params, parent, url }) { + let { user } = await parent(); + let pubkey; + if (user) ({ pubkey } = user); + else pubkey = params.username; + let { username } = params; let text = `${encodeURI(username)}@${url.hostname}`; let src = Qr.drawImg(text, { size: 300 }); let events = []; try { - events = await get(`/${username}/events`); + events = await get(`/${pubkey}/events`); } catch (e) { console.log(e); } diff --git a/src/routes/(app)/[username]/+page.svelte b/src/routes/(app)/[username]/+page.svelte index 78d84653..837257ef 100644 --- a/src/routes/(app)/[username]/+page.svelte +++ b/src/routes/(app)/[username]/+page.svelte @@ -1,12 +1,53 @@ @@ -69,9 +110,24 @@ -
+
+ {#if user.username === n} +
+ +
+ {/if} +
- + {#if events.length} + + {:else} +
You haven't posted anything yet
+ {/if}
diff --git a/src/routes/(app)/[username]/+server.js b/src/routes/(app)/[username]/+server.js new file mode 100644 index 00000000..d0b1242f --- /dev/null +++ b/src/routes/(app)/[username]/+server.js @@ -0,0 +1,6 @@ +import { auth, post } from '$lib/utils'; +import { json } from '@sveltejs/kit'; + +export async function POST({ cookies, request }) { + return json(post('/nostr/send', await request.json(), auth(cookies))); +} diff --git a/src/routes/(app)/[username]/generate/+page.svelte b/src/routes/(app)/[username]/generate/+page.svelte index ee67237c..fd6b6f7e 100644 --- a/src/routes/(app)/[username]/generate/+page.svelte +++ b/src/routes/(app)/[username]/generate/+page.svelte @@ -1,42 +1,20 @@