Eve-Relay/src/dbEvents/deletionEvent.ts
2025-06-04 12:43:23 +02:00

143 lines
4.3 KiB
TypeScript

import type { Database } from '@db/sqlite';
import type * as nostrTools from '@nostr/tools';
import { isAddressableEvent, isReplaceableEvent } from '../utils/eventTypes.ts';
import { log } from '../utils/logs.ts';
import { parseATagQuery } from '../utils/parseATagQuery.ts';
import { sql } from '../utils/queries.ts';
export function handleDeletionEvent(
db: Database,
deletionEvent: nostrTools.VerifiedEvent,
encryptedEvent: nostrTools.VerifiedEvent,
ccnPubkey: string,
): void {
log.debug('start', {
tag: 'handleDeletionEvent',
decryptId: deletionEvent.id,
encryptedId: encryptedEvent.id,
kind: deletionEvent.kind,
ccnPubkey,
});
try {
db.run('BEGIN TRANSACTION');
log.debug('begin transaction', { tag: 'handleDeletionEvent' });
sql`
INSERT INTO events (id, original_id, pubkey, created_at, kind, content, sig, first_seen, ccn_pubkey) VALUES (
${deletionEvent.id},
${encryptedEvent.id},
${deletionEvent.pubkey},
${deletionEvent.created_at},
${deletionEvent.kind},
${deletionEvent.content},
${deletionEvent.sig},
unixepoch(),
${ccnPubkey}
)
`(db);
if (deletionEvent.tags) {
for (let i = 0; i < deletionEvent.tags.length; i++) {
const tag = sql`
INSERT INTO event_tags(event_id, tag_name, tag_index) VALUES (
${deletionEvent.id},
${deletionEvent.tags[i][0]},
${i}
) RETURNING tag_id
`(db)[0];
for (let j = 1; j < deletionEvent.tags[i].length; j++) {
sql`
INSERT INTO event_tags_values(tag_id, value_position, value) VALUES (
${tag.tag_id},
${j},
${deletionEvent.tags[i][j]}
)
`(db);
}
}
}
for (const tag of deletionEvent.tags) {
if (tag[0] === 'e' && tag[1]) {
sql`
UPDATE events
SET deleted = 1
WHERE id = ${tag[1]}
AND pubkey = ${deletionEvent.pubkey}
AND ccn_pubkey = ${ccnPubkey}
`(db);
log.debug('deleted event by id', {
tag: 'handleDeletionEvent',
eventId: tag[1],
});
} else if (tag[0] === 'a' && tag[1]) {
const { kind, pubkey, dTag } = parseATagQuery(tag[1]);
if (!kind || !pubkey) continue;
if (pubkey !== deletionEvent.pubkey) continue;
if (isReplaceableEvent(kind)) {
sql`
UPDATE events
SET deleted = 1
WHERE kind = ${kind}
AND pubkey = ${pubkey}
AND ccn_pubkey = ${ccnPubkey}
AND created_at <= ${deletionEvent.created_at}
`(db);
log.debug('deleted replaceable event', {
tag: 'handleDeletionEvent',
kind,
pubkey,
});
} else if (isAddressableEvent(kind) && dTag) {
sql`
UPDATE events
SET deleted = 1
WHERE kind = ${kind}
AND pubkey = ${pubkey}
AND ccn_pubkey = ${ccnPubkey}
AND created_at <= ${deletionEvent.created_at}
AND id IN (
SELECT event_id FROM event_tags
WHERE tag_name = 'd'
AND tag_id IN (
SELECT tag_id FROM event_tags_values
WHERE value_position = 1 AND value = ${dTag}
)
)
`(db);
log.debug('deleted addressable event', {
tag: 'handleDeletionEvent',
kind,
pubkey,
dTag,
});
}
} else if (tag[0] === 'k') {
sql`
UPDATE events
SET deleted = 1
WHERE kind = ${tag[1]}
AND pubkey = ${deletionEvent.pubkey}
AND ccn_pubkey = ${ccnPubkey}
AND created_at <= ${deletionEvent.created_at}
`(db);
log.debug('deleted events of kind', {
tag: 'handleDeletionEvent',
kind: tag[1],
});
}
}
db.run('COMMIT TRANSACTION');
log.debug('committed transaction', { tag: 'handleDeletionEvent' });
} catch (e) {
db.run('ROLLBACK TRANSACTION');
log.error('transaction rolled back', {
tag: 'handleDeletionEvent',
error: e,
});
throw e;
}
log.debug('end', { tag: 'handleDeletionEvent', id: deletionEvent.id });
}