Make relay only return local events

This commit is contained in:
Alex Gleason 2023-08-12 14:32:57 -05:00
parent 3593d5420d
commit 075da543b0
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
2 changed files with 30 additions and 18 deletions

View File

@ -41,6 +41,7 @@ function prepareFilters(filters: ClientREQ[2][]): Filter[] {
return filters.map((filter) => ({ return filters.map((filter) => ({
...filter, ...filter,
limit: Math.min(filter.limit || FILTER_LIMIT, FILTER_LIMIT), limit: Math.min(filter.limit || FILTER_LIMIT, FILTER_LIMIT),
local: true,
})); }));
} }

View File

@ -50,7 +50,11 @@ function insertEvent(event: SignedEvent): Promise<void> {
}); });
} }
function getFilterQuery(filter: Filter) { interface DittoFilter<K extends number = number> extends Filter<K> {
local?: boolean;
}
function getFilterQuery(filter: DittoFilter) {
let query = db let query = db
.selectFrom('events') .selectFrom('events')
.select([ .select([
@ -62,24 +66,24 @@ function getFilterQuery(filter: Filter) {
'events.created_at', 'events.created_at',
'events.sig', 'events.sig',
]) ])
.orderBy('created_at', 'desc'); .orderBy('events.created_at', 'desc');
for (const key of Object.keys(filter)) { for (const key of Object.keys(filter)) {
switch (key as keyof Filter) { switch (key as keyof DittoFilter) {
case 'ids': case 'ids':
query = query.where('id', 'in', filter.ids!); query = query.where('events.id', 'in', filter.ids!);
break; break;
case 'kinds': case 'kinds':
query = query.where('kind', 'in', filter.kinds!); query = query.where('events.kind', 'in', filter.kinds!);
break; break;
case 'authors': case 'authors':
query = query.where('pubkey', 'in', filter.authors!); query = query.where('events.pubkey', 'in', filter.authors!);
break; break;
case 'since': case 'since':
query = query.where('created_at', '>=', filter.since!); query = query.where('events.created_at', '>=', filter.since!);
break; break;
case 'until': case 'until':
query = query.where('created_at', '<=', filter.until!); query = query.where('events.created_at', '<=', filter.until!);
break; break;
case 'limit': case 'limit':
query = query.limit(filter.limit!); query = query.limit(filter.limit!);
@ -89,19 +93,23 @@ function getFilterQuery(filter: Filter) {
if (key.startsWith('#')) { if (key.startsWith('#')) {
const tag = key.replace(/^#/, ''); const tag = key.replace(/^#/, '');
const value = filter[key as `#${string}`] as string[]; const value = filter[key as `#${string}`] as string[];
return query query = query
.leftJoin('tags', 'tags.event_id', 'events.id') .leftJoin('tags', 'tags.event_id', 'events.id')
.where('tags.tag', '=', tag) .where('tags.tag', '=', tag)
.where('tags.value_1', 'in', value) as typeof query; .where('tags.value_1', 'in', value) as typeof query;
} }
} }
if (filter.local) {
query = query.innerJoin('users', 'users.pubkey', 'events.pubkey');
}
return query; return query;
} }
async function getFilters<K extends number>(filters: [Filter<K>]): Promise<SignedEvent<K>[]>; async function getFilters<K extends number>(filters: [DittoFilter<K>]): Promise<SignedEvent<K>[]>;
async function getFilters(filters: Filter[]): Promise<SignedEvent[]>; async function getFilters(filters: DittoFilter[]): Promise<SignedEvent[]>;
async function getFilters(filters: Filter[]) { async function getFilters(filters: DittoFilter[]) {
const queries = filters const queries = filters
.map(getFilterQuery) .map(getFilterQuery)
.map((query) => query.execute()); .map((query) => query.execute());
@ -113,17 +121,20 @@ async function getFilters(filters: Filter[]) {
)); ));
} }
function getFilter<K extends number = number>(filter: Filter<K>): Promise<SignedEvent<K>[]> { function getFilter<K extends number = number>(filter: DittoFilter<K>): Promise<SignedEvent<K>[]> {
return getFilters<K>([filter]); return getFilters<K>([filter]);
} }
/** Returns whether the pubkey is followed by a local user. */ /** Returns whether the pubkey is followed by a local user. */
async function isLocallyFollowed(pubkey: string): Promise<boolean> { async function isLocallyFollowed(pubkey: string): Promise<boolean> {
const event = await getFilterQuery({ kinds: [3], '#p': [pubkey], limit: 1 }) return Boolean(
.innerJoin('users', 'users.pubkey', 'events.pubkey') await getFilterQuery({
.executeTakeFirst(); kinds: [3],
'#p': [pubkey],
return !!event; limit: 1,
local: true,
}).executeTakeFirst(),
);
} }
export { getFilter, getFilters, insertEvent, isLocallyFollowed }; export { getFilter, getFilters, insertEvent, isLocallyFollowed };