Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Laura Hausmann
961aee7dbf
wip 2024-10-28 14:57:58 +01:00
Laura Hausmann
c4449dd25e
[backend/masto-client] Don't deliver push notifications that mention blocked/muted users 2024-10-28 14:52:37 +01:00
3 changed files with 33 additions and 11 deletions

View file

@ -1,3 +1,5 @@
using EntityFrameworkCore.Projectables;
namespace Iceshrimp.Backend.Core.Extensions;
public static class EnumerableExtensions
@ -37,15 +39,11 @@ public static class EnumerableExtensions
foreach (var task in tasks) await task;
}
public static bool IsDisjoint<T>(this IEnumerable<T> x, IEnumerable<T> y)
{
return x.All(item => !y.Contains(item));
}
[Projectable]
public static bool IsDisjoint<T>(this IEnumerable<T> x, IEnumerable<T> y) => x.All(item => !y.Contains(item));
public static bool Intersects<T>(this IEnumerable<T> x, IEnumerable<T> y)
{
return x.Any(y.Contains);
}
[Projectable]
public static bool Intersects<T>(this IEnumerable<T> x, IEnumerable<T> y) => x.Any(y.Contains);
public static bool IsEquivalent<T>(this IEnumerable<T> x, IEnumerable<T> y)
{

View file

@ -427,6 +427,7 @@ public static class QueryableExtensions
p.IsRequested(user), p.IsRequestedBy(user)));
}
[SuppressMessage("ReSharper", "EntityFramework.UnsupportedServerSideFunctionCall")]
public static IQueryable<Notification> FilterHiddenNotifications(
this IQueryable<Notification> query, User user, DatabaseContext db
)
@ -435,7 +436,9 @@ public static class QueryableExtensions
var mutes = db.Mutings.Where(i => i.Muter == user).Select(p => p.MuteeId);
var hidden = blocks.Concat(mutes);
return query.Where(p => !hidden.Contains(p.NotifierId) && (p.Note == null || !hidden.Contains(p.Note.Id)));
return query.Where(p => !hidden.Contains(p.NotifierId) &&
(p.Note == null ||
hidden.IsDisjoint(p.Note.Mentions.Concat(new[] { p.Note.User.Id }))));
}
public static IQueryable<Note> FilterHiddenConversations(this IQueryable<Note> query, User user, DatabaseContext db)
@ -696,6 +699,16 @@ public static class QueryableExtensions
return query.FilterByPublicTimelineRequest(request);
}
public static bool IsDisjoint<T>(this IQueryable<T> x, IQueryable<T> y)
{
return x.All(item => !y.Contains(item));
}
public static bool Intersects<T>(this IQueryable<T> x, IQueryable<T> y)
{
return x.Any(y.Contains);
}
#pragma warning disable CS8602 // Dereference of a possibly null reference.
// Justification: in the context of nullable EF navigation properties, null values are ignored and therefore irrelevant.
// Source: https://learn.microsoft.com/en-us/ef/core/miscellaneous/nullable-reference-types#navigating-and-including-nullable-relationships
@ -712,7 +725,7 @@ public static class QueryableExtensions
{
return query.Include(p => p.UserProfile);
}
public static IQueryable<Bite> IncludeCommonProperties(this IQueryable<Bite> query)
{
return query.Include(p => p.TargetNote)

View file

@ -50,7 +50,18 @@ public class PushService(
var skip = await db.Blockings.AnyAsync(p => p.Blocker == notification.Notifiee &&
p.Blockee == notification.Notifier) ||
await db.Mutings.AnyAsync(p => p.Muter == notification.Notifiee &&
p.Mutee == notification.Notifier);
p.Mutee == notification.Notifier) ||
(notification.Note is { } note &&
(await db.Mutings.AnyAsync(p => p.Muter == notification.Notifiee &&
note.Mentions
.Prepend(note.Reply != null ? note.Reply.UserId : null)
.NotNull()
.Contains(p.MuteeId)) ||
await db.Blockings.AnyAsync(p => p.Blocker == notification.Notifiee &&
note.Mentions
.Prepend(note.Reply != null ? note.Reply.UserId : null)
.NotNull()
.Contains(p.BlockeeId))));
if (skip)
{