relay: respect "local: true" filter

This commit is contained in:
Alex Gleason 2023-08-24 15:28:13 -05:00
parent a676b71d23
commit 658dd397f5
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
4 changed files with 46 additions and 7 deletions

27
src/filter.ts Normal file
View File

@ -0,0 +1,27 @@
import { type Event, matchFilters } from '@/deps.ts';
import type { DittoFilter } from '@/types.ts';
interface EventData {
isLocal: boolean;
}
function matchDittoFilter(filter: DittoFilter, event: Event, data: EventData): boolean {
if (filter.local && !data.isLocal) {
return false;
}
return matchFilters([filter], event);
}
function matchDittoFilters(filters: DittoFilter[], event: Event, data: EventData): boolean {
for (const filter of filters) {
if (matchDittoFilter(filter, event, data)) {
return true;
}
}
return false;
}
export { matchDittoFilters };

View File

@ -66,8 +66,8 @@ function trackRelays(event: Event) {
}
/** Distribute the event through active subscriptions. */
function streamOut(event: Event) {
for (const sub of Sub.matches(event)) {
async function streamOut(event: Event) {
for await (const sub of Sub.matches(event)) {
sub.socket.send(JSON.stringify(['EVENT', event]));
}
}

View File

@ -1,4 +1,6 @@
import { type Event, matchFilters } from '@/deps.ts';
import { type Event } from '@/deps.ts';
import { matchDittoFilters } from './filter.ts';
import { isEventLocal } from '@/utils.ts';
import type { DittoFilter } from '@/types.ts';
@ -18,7 +20,7 @@ interface Subscription {
* Subscriptions can be added, removed, and matched against events.
*
* ```ts
* for (const sub of Sub.matches(event)) {
* for await (const sub of Sub.matches(event)) {
* // Send event to sub.socket
* sub.socket.send(JSON.stringify(event));
* }
@ -53,16 +55,18 @@ class SubscriptionStore {
* Loop through matching subscriptions to stream out.
*
* ```ts
* for (const sub of Sub.matches(event)) {
* for await (const sub of Sub.matches(event)) {
* // Send event to sub.socket
* sub.socket.send(JSON.stringify(event));
* }
* ```
*/
*matches(event: Event): Iterable<Subscription> {
async *matches(event: Event) {
const isLocal = await isEventLocal(event);
for (const subs of this.#store.values()) {
for (const sub of subs.values()) {
if (matchFilters(sub.filters, event)) {
if (matchDittoFilters(sub.filters, event, { isLocal })) {
yield sub;
}
}

View File

@ -1,3 +1,4 @@
import { findUser } from '@/db/users.ts';
import { type Event, nip19, z } from '@/deps.ts';
import { lookupNip05Cached } from '@/nip05.ts';
import { getAuthor } from '@/queries.ts';
@ -101,11 +102,18 @@ function isFollowing(source: Event<3>, targetPubkey: string): boolean {
);
}
/** Check whether the event belongs to a local user. */
async function isEventLocal(event: Event) {
const user = await findUser({ pubkey: event.pubkey });
return !!user;
}
export {
bech32ToPubkey,
eventAge,
eventDateComparator,
findTag,
isEventLocal,
isFollowing,
isRelay,
lookupAccount,