diff options
Diffstat (limited to 'src/lib/nostr.ts')
| -rw-r--r-- | src/lib/nostr.ts | 42 |
1 files changed, 30 insertions, 12 deletions
diff --git a/src/lib/nostr.ts b/src/lib/nostr.ts index bfaa14c1..2e993f9d 100644 --- a/src/lib/nostr.ts +++ b/src/lib/nostr.ts @@ -8,7 +8,7 @@ import { signer as $signer, } from "$lib/store"; import { post, wait } from "$lib/utils"; -import { bytesToHex } from "@noble/hashes/utils"; +import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js"; import { type EventTemplate, finalizeEvent, @@ -20,6 +20,7 @@ import { import { decrypt as nip44decrypt, getConversationKey } from "nostr-tools/nip44"; import { Relay } from "nostr-tools/relay"; import { get } from "svelte/store"; +import cookies from "js-cookie"; import { decrypt as nip49decrypt, @@ -72,12 +73,22 @@ export const getPrivateKey = async (user: User): Promise<Uint8Array> => { } } - const { nsec } = user; + // /me no longer returns the encrypted key; /login decrypts it into the + // sk cookie instead. user.nsec is only present on a fresh login response. + // Sessions without either (nostr or older logins) fetch it with the + // password. + const sk = browser && cookies.get("sk"); + let { nsec } = user; - if (nsec) { + if (!sk && !nsec && user.hasnsec) + ({ nsec } = await post("/nsec", { password: await getPassword() })); + + if (sk) { + k = hexToBytes(sk); + } else if (nsec) { k = nip49decrypt(nsec, await getPassword()); } else { - throw new Error("nsec not available"); + throw new Error("Log in again with your password to unlock your nostr key"); } localStorage.setItem("nsec", nip19.nsecEncode(k)); @@ -105,7 +116,7 @@ export const encryptNsec = async (nsec: string) => { }; export const sign = async (event, user) => { - if (user?.nsec && !get($signer)?.ready) { + if ((user?.hasnsec || user?.nsec) && !get($signer)?.ready) { const sk = await getPrivateKey(user); $signer.set({ @@ -117,8 +128,14 @@ export const sign = async (event, user) => { eventToSign.set(event); let unsubscribe; - const { method, params } = await new Promise((r) => { - unsubscribe = $signer.subscribe((v) => v?.ready && r(v)); + const { method, params } = await new Promise((r, j) => { + unsubscribe = $signer.subscribe((v) => { + if (v === "cancel") { + j("cancelled"); + $signer.set(undefined); + } + v?.ready && r(v); + }); }); await unsubscribe(); const signedEvent = await signingMethods[method](event, params); @@ -148,7 +165,8 @@ const signingMethods = { params: [JSON.stringify(event)], }; - const content = await nip04.encrypt(sk, pk, JSON.stringify(signEvent)); + const skBytes = hexToBytes(sk); + const content = await nip04.encrypt(skBytes, pk, JSON.stringify(signEvent)); const signedSignEvent = finalizeEvent( { @@ -158,7 +176,7 @@ const signingMethods = { content, tags: [["p", pk]], }, - sk, + skBytes, ); const relay = await Relay.connect(nostrConnectRelay); @@ -171,9 +189,9 @@ const signingMethods = { try { let response; try { - response = JSON.parse(await nip04.decrypt(sk, pk, event.content)); + response = JSON.parse(await nip04.decrypt(hexToBytes(sk), pk, event.content)); } catch (e) { - const ck = await getConversationKey(sk, pk); + const ck = await getConversationKey(hexToBytes(sk), pk); response = JSON.parse(await nip44decrypt(event.content, ck)); } @@ -187,7 +205,7 @@ const signingMethods = { }, async nsec(event, { sk }) { - return finalizeEvent(event, sk); + return finalizeEvent(event, hexToBytes(sk)); }, async extension(event) { |
