fix(federation): 🔒 Enforce content filters for remote content as well

This commit is contained in:
Jesse Wierzbinski 2025-05-28 02:59:26 +02:00
parent c737aeba8e
commit 710f965144
No known key found for this signature in database
2 changed files with 70 additions and 9 deletions

View file

@ -500,9 +500,14 @@ export class Note extends BaseInterface<typeof Notes, NoteTypeWithRelations> {
); );
const emojis = await Promise.all( const emojis = await Promise.all(
extensions?.["pub.versia:custom_emojis"]?.emojis.map((emoji) => extensions?.["pub.versia:custom_emojis"]?.emojis
Emoji.fetchFromRemote(emoji, instance), .filter(
) ?? [], (e) =>
!config.validation.filters.emoji_shortcode.some(
(filter) => filter.test(e.name),
),
)
.map((emoji) => Emoji.fetchFromRemote(emoji, instance)) ?? [],
); );
const mentions = ( const mentions = (

View file

@ -181,9 +181,7 @@ export class InboxProcessor {
try { try {
await new EntitySorter(this.body) await new EntitySorter(this.body)
.on(VersiaEntities.Note, async (n) => { .on(VersiaEntities.Note, (n) => InboxProcessor.processNote(n))
await Note.fromVersia(n);
})
.on(VersiaEntities.Follow, (f) => .on(VersiaEntities.Follow, (f) =>
InboxProcessor.processFollowRequest(f), InboxProcessor.processFollowRequest(f),
) )
@ -199,9 +197,7 @@ export class InboxProcessor {
.on(VersiaEntities.Delete, (d) => .on(VersiaEntities.Delete, (d) =>
InboxProcessor.processDelete(d), InboxProcessor.processDelete(d),
) )
.on(VersiaEntities.User, async (u) => { .on(VersiaEntities.User, (u) => InboxProcessor.processUser(u))
await User.fromVersia(u);
})
.on(VersiaEntities.Share, async (s) => .on(VersiaEntities.Share, async (s) =>
InboxProcessor.processShare(s), InboxProcessor.processShare(s),
) )
@ -213,6 +209,66 @@ export class InboxProcessor {
} }
} }
/**
* Handles Note entity processing
*
* @param {VersiaNote} note - The Note entity to process.
* @returns {Promise<void>}
*/
private static async processNote(note: VersiaEntities.Note): Promise<void> {
// If note has a blocked word
if (
Object.values(note.content?.data ?? {})
.flatMap((c) => c.content)
.some((content) =>
config.validation.filters.note_content.some((filter) =>
filter.test(content),
),
)
) {
// Drop silently
return;
}
await Note.fromVersia(note);
}
/**
* Handles User entity processing.
*
* @param {VersiaUser} user - The User entity to process.
* @returns {Promise<void>}
*/
private static async processUser(user: VersiaEntities.User): Promise<void> {
if (
config.validation.filters.username.some((filter) =>
filter.test(user.data.username),
) ||
(user.data.display_name &&
config.validation.filters.displayname.some((filter) =>
filter.test(user.data.display_name ?? ""),
))
) {
// Drop silently
return;
}
if (
Object.values(user.bio?.data ?? {})
.flatMap((c) => c.content)
.some((content) =>
config.validation.filters.bio.some((filter) =>
filter.test(content),
),
)
) {
// Drop silently
return;
}
await User.fromVersia(user);
}
/** /**
* Handles Follow entity processing. * Handles Follow entity processing.
* *