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