sign: ensure the NIP-46 result matches the template

This commit is contained in:
Alex Gleason 2023-09-02 20:09:28 -05:00
parent 007565b513
commit c8a5da086e
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 19 additions and 7 deletions

View File

@ -5,14 +5,14 @@ import { type Event, type EventTemplate, finishEvent, HTTPException } from '@/de
import { connectResponseSchema } from '@/schemas/nostr.ts'; import { connectResponseSchema } from '@/schemas/nostr.ts';
import { jsonSchema } from '@/schema.ts'; import { jsonSchema } from '@/schema.ts';
import { Sub } from '@/subs.ts'; import { Sub } from '@/subs.ts';
import { Time } from '@/utils.ts'; import { eventMatchesTemplate, Time } from '@/utils.ts';
import { createAdminEvent } from '@/utils/web.ts'; import { createAdminEvent } from '@/utils/web.ts';
/** /**
* Sign Nostr event using the app context. * Sign Nostr event using the app context.
* *
* - If a secret key is provided, it will be used to sign the event. * - If a secret key is provided, it will be used to sign the event.
* - If `X-Nostr-Sign` is passed, it will use a NIP-46 to sign the event. * - If `X-Nostr-Sign` is passed, it will use NIP-46 to sign the event.
*/ */
async function signEvent<K extends number = number>(event: EventTemplate<K>, c: AppContext): Promise<Event<K>> { async function signEvent<K extends number = number>(event: EventTemplate<K>, c: AppContext): Promise<Event<K>> {
const seckey = c.get('seckey'); const seckey = c.get('seckey');
@ -54,13 +54,14 @@ async function signNostrConnect<K extends number = number>(event: EventTemplate<
tags: [['p', pubkey]], tags: [['p', pubkey]],
}, c); }, c);
return awaitSignedEvent<K>(pubkey, messageId, c); return awaitSignedEvent<K>(pubkey, messageId, event, c);
} }
/** Wait for signed event to be sent through Nostr relay. */ /** Wait for signed event to be sent through Nostr relay. */
async function awaitSignedEvent<K extends number = number>( async function awaitSignedEvent<K extends number = number>(
pubkey: string, pubkey: string,
messageId: string, messageId: string,
template: EventTemplate<K>,
c: AppContext, c: AppContext,
): Promise<Event<K>> { ): Promise<Event<K>> {
const sub = Sub.sub(messageId, '1', [{ kinds: [24133], authors: [pubkey], '#p': [Conf.pubkey] }]); const sub = Sub.sub(messageId, '1', [{ kinds: [24133], authors: [pubkey], '#p': [Conf.pubkey] }]);
@ -79,12 +80,17 @@ async function awaitSignedEvent<K extends number = number>(
for await (const event of sub) { for await (const event of sub) {
if (event.kind === 24133) { if (event.kind === 24133) {
const decrypted = await decryptAdmin(event.pubkey, event.content); const decrypted = await decryptAdmin(event.pubkey, event.content);
const msg = jsonSchema.pipe(connectResponseSchema).parse(decrypted);
if (msg.id === messageId) { const result = jsonSchema
.pipe(connectResponseSchema)
.refine((msg) => msg.id === messageId)
.refine((msg) => eventMatchesTemplate(msg.result, template))
.safeParse(decrypted);
if (result.success) {
close(); close();
clearTimeout(timeout); clearTimeout(timeout);
return msg.result as Event<K>; return result.data.result as Event<K>;
} }
} }
} }

View File

@ -1,4 +1,4 @@
import { type Event, nip19, z } from '@/deps.ts'; import { type Event, type EventTemplate, getEventHash, nip19, z } from '@/deps.ts';
import { getAuthor } from '@/queries.ts'; import { getAuthor } from '@/queries.ts';
import { lookupNip05Cached } from '@/utils/nip05.ts'; import { lookupNip05Cached } from '@/utils/nip05.ts';
@ -106,11 +106,17 @@ function dedupeEvents<K extends number>(events: Event<K>[]): Event<K>[] {
return [...new Map(events.map((event) => [event.id, event])).values()]; return [...new Map(events.map((event) => [event.id, event])).values()];
} }
/** Ensure the template and event match on their shared keys. */
function eventMatchesTemplate(event: Event, template: EventTemplate): boolean {
return getEventHash(event) === getEventHash({ pubkey: event.pubkey, ...template });
}
export { export {
bech32ToPubkey, bech32ToPubkey,
dedupeEvents, dedupeEvents,
eventAge, eventAge,
eventDateComparator, eventDateComparator,
eventMatchesTemplate,
findTag, findTag,
isFollowing, isFollowing,
isRelay, isRelay,