diff --git a/src/pipeline.ts b/src/pipeline.ts index afbad7b5..9f99520b 100644 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -116,22 +116,8 @@ async function storeEvent(event: DittoEvent, signal?: AbortSignal): Promise { - await updateStats({ event, store, kysely: trx }); - await store.event(event, { signal }); - }); - } catch (e) { - if (e.message === 'Cannot add a deleted event') { - throw new RelayError('blocked', 'event deleted by user'); - } else if (e.message === 'Cannot replace an event with an older event') { - return; - } else if (e.message === 'ERROR The transaction "TRANSACTION_NAME" has been aborted') { - return; // useless error message, probably from deno-postgres - } else { - debug('ERROR', e.message); - } - } + await updateStats({ event, store, kysely }).catch(debug); + await store.event(event, { signal }); } /** Parse kind 0 metadata and track indexes in the database. */ diff --git a/src/storages/EventsDB.test.ts b/src/storages/EventsDB.test.ts index 74068e94..16b429d4 100644 --- a/src/storages/EventsDB.test.ts +++ b/src/storages/EventsDB.test.ts @@ -2,12 +2,14 @@ import { Database as Sqlite } from '@db/sqlite'; import { DenoSqlite3Dialect } from '@soapbox/kysely-deno-sqlite'; import { assertEquals, assertRejects } from '@std/assert'; import { Kysely } from 'kysely'; +import { generateSecretKey } from 'nostr-tools'; import { Conf } from '@/config.ts'; import { DittoDB } from '@/db/DittoDB.ts'; import { DittoTables } from '@/db/DittoTables.ts'; +import { RelayError } from '@/RelayError.ts'; import { EventsDB } from '@/storages/EventsDB.ts'; -import { eventFixture } from '@/test.ts'; +import { eventFixture, genEvent } from '@/test.ts'; /** Create in-memory database for testing. */ const createDB = async () => { @@ -141,17 +143,49 @@ Deno.test('admin can delete any event', async () => { assertEquals(await eventsDB.query([{ kinds: [1] }]), [two]); }); +Deno.test('throws a RelayError when inserting an event deleted by the admin', async () => { + const { eventsDB } = await createDB(); + + const event = genEvent(); + await eventsDB.event(event); + + const deletion = genEvent({ kind: 5, tags: [['e', event.id]] }, Conf.seckey); + await eventsDB.event(deletion); + + await assertRejects( + () => eventsDB.event(event), + RelayError, + 'event deleted by admin', + ); +}); + +Deno.test('throws a RelayError when inserting an event deleted by a user', async () => { + const { eventsDB } = await createDB(); + + const sk = generateSecretKey(); + + const event = genEvent({}, sk); + await eventsDB.event(event); + + const deletion = genEvent({ kind: 5, tags: [['e', event.id]] }, sk); + await eventsDB.event(deletion); + + await assertRejects( + () => eventsDB.event(event), + RelayError, + 'event deleted by user', + ); +}); + Deno.test('inserting replaceable events', async () => { const { eventsDB } = await createDB(); const event = await eventFixture('event-0'); await eventsDB.event(event); - await assertRejects(async () => { - const olderEvent = { ...event, id: '123', created_at: event.created_at - 1 }; - await eventsDB.event(olderEvent); - assertEquals(await eventsDB.query([{ kinds: [0], authors: [event.pubkey] }]), [event]); - }); + const olderEvent = { ...event, id: '123', created_at: event.created_at - 1 }; + await eventsDB.event(olderEvent); + assertEquals(await eventsDB.query([{ kinds: [0], authors: [event.pubkey] }]), [event]); const newerEvent = { ...event, id: '123', created_at: event.created_at + 1 }; await eventsDB.event(newerEvent); diff --git a/src/storages/EventsDB.ts b/src/storages/EventsDB.ts index 51a75af7..085a4270 100644 --- a/src/storages/EventsDB.ts +++ b/src/storages/EventsDB.ts @@ -59,7 +59,18 @@ class EventsDB implements NStore { } await this.deleteEventsAdmin(event); - await this.store.event(event); + + try { + await this.store.event(event); + } catch (e) { + if (e.message === 'Cannot add a deleted event') { + throw new RelayError('blocked', 'event deleted by user'); + } else if (e.message === 'Cannot replace an event with an older event') { + return; + } else { + this.console.debug('ERROR', e.message); + } + } } /** Check if an event has been deleted by the admin. */