diff --git a/src/app.ts b/src/app.ts index 4cf6afee..776de8de 100644 --- a/src/app.ts +++ b/src/app.ts @@ -115,7 +115,7 @@ app.post('/oauth/revoke', emptyObjectController); app.post('/oauth/authorize', oauthAuthorizeController); app.get('/oauth/authorize', oauthController); -app.post('/api/v1/accounts', requireProof(), createAccountController); +app.post('/api/v1/accounts', requireProof({ pow: 20 }), createAccountController); app.get('/api/v1/accounts/verify_credentials', requirePubkey, verifyCredentialsController); app.patch( '/api/v1/accounts/update_credentials', diff --git a/src/utils.ts b/src/utils.ts index 11ef0ea5..1f10cd3b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -107,9 +107,31 @@ function dedupeEvents(events: Event[]): Event[] { return [...new Map(events.map((event) => [event.id, event])).values()]; } +/** Return a copy of the event with the given tags removed. */ +function stripTags(event: E, tags: string[] = []): E { + if (!tags.length) return event; + return { + ...event, + tags: event.tags.filter(([name]) => !tags.includes(name)), + }; +} + /** 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 }); + const whitelist = ['nonce']; + + event = stripTags(event, whitelist); + template = stripTags(template, whitelist); + + if (template.created_at > event.created_at) { + return false; + } + + return getEventHash(event) === getEventHash({ + pubkey: event.pubkey, + ...template, + created_at: event.created_at, + }); } /** Test whether the value is a Nostr ID. */