diff --git a/src/backend.ts b/src/backend.ts index 7b41bce..3bf5629 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -3,6 +3,7 @@ import { dbi, DbKey, DbPending, DbPerm } from './db' import { Keys } from './keys' import NDK, { IEventHandlingStrategy, NDKEvent, NDKNip46Backend, NDKPrivateKeySigner, NDKSigner } from '@nostr-dev-kit/ndk' import { NOAUTHD_URL, WEB_PUSH_PUBKEY, NIP46_RELAYS } from './consts' +import { Nip04 } from './nip04' //import { PrivateKeySigner } from './signer' //const PERF_TEST = false @@ -35,6 +36,50 @@ interface IAllowCallbackParams { params?: any } +class Nip04KeyHandlingStrategy implements IEventHandlingStrategy { + + private privkey: string + private nip04 = new Nip04() + + constructor(privkey: string) { + this.privkey = privkey + } + + private async getKey( + backend: NDKNip46Backend, + id: string, + remotePubkey: string, + recipientPubkey: string + ) { + if ( + !(await backend.pubkeyAllowed({ + id, + pubkey: remotePubkey, + // @ts-ignore + method: "get_nip04_key", + params: recipientPubkey, + })) + ) { + backend.debug(`get_nip04_key request from ${remotePubkey} rejected`); + return undefined; + } + + return Buffer.from( + this.nip04.createKey(this.privkey, recipientPubkey) + ).toString('hex') + } + + async handle( + backend: NDKNip46Backend, + id: string, + remotePubkey: string, + params: string[] + ) { + const [recipientPubkey] = params + return await this.getKey(backend, id, remotePubkey, recipientPubkey) + } +} + class EventHandlingStrategyWrapper implements IEventHandlingStrategy { readonly npub: string readonly method: string @@ -69,10 +114,10 @@ class EventHandlingStrategyWrapper implements IEventHandlingStrategy { }) if (!allow) return undefined return this.body.handle(backend, id, remotePubkey, params) - .then(r => { - console.log(Date.now(), "req", id, "method", this.method, "result", r) - return r - }) + .then(r => { + console.log(Date.now(), "req", id, "method", this.method, "result", r) + return r + }) } } @@ -525,6 +570,9 @@ export class NoauthBackend { const backend = new NDKNip46Backend(ndk, sk, () => Promise.resolve(true)) this.keys.push({ npub, backend, signer, ndk, backoff }) + // new method + backend.handlers['get_nip04_key'] = new Nip04KeyHandlingStrategy(sk) + // assign our own permission callback for (const method in backend.handlers) { backend.handlers[method] = new EventHandlingStrategyWrapper(npub, method, backend.handlers[method], this.allowPermitCallback.bind(this)) diff --git a/src/nip04.ts b/src/nip04.ts index f121e94..a2ceeca 100644 --- a/src/nip04.ts +++ b/src/nip04.ts @@ -35,14 +35,19 @@ function getNormalizedX(key: Uint8Array): Uint8Array { export class Nip04 { private cache = new Map() - private async getKey(privkey: string, pubkey: string) { + public createKey(privkey: string, pubkey: string) { + const key = secp256k1.getSharedSecret(privkey, '02' + pubkey) + const normalizedKey = getNormalizedX(key) + return normalizedKey + } + + private async getKey(privkey: string, pubkey: string, extractable?: boolean) { const id = getPublicKey(privkey) + pubkey let cryptoKey = this.cache.get(id) if (cryptoKey) return cryptoKey - const key = secp256k1.getSharedSecret(privkey, '02' + pubkey) - const normalizedKey = getNormalizedX(key) - cryptoKey = await crypto.subtle.importKey('raw', normalizedKey, { name: 'AES-CBC' }, false, ['encrypt', 'decrypt']) + const key = this.createKey(privkey, pubkey) + cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'AES-CBC' }, !!extractable, ['encrypt', 'decrypt']) this.cache.set(id, cryptoKey) return cryptoKey }