[backend/masto-api] Enforce renote/reply visibility for notifications
This commit is contained in:
parent
4d7d8ee34e
commit
b4fea308f7
4 changed files with 46 additions and 12 deletions
|
@ -50,6 +50,7 @@ public class NotificationController(DatabaseContext db, NotificationRenderer not
|
|||
.FilterBlocked(p => p.Notifier, user)
|
||||
.FilterBlocked(p => p.Note, user)
|
||||
.Paginate(query, ControllerContext)
|
||||
.PrecomputeNoteVisibilities(user)
|
||||
.RenderAllForMastodonAsync(notificationRenderer, user);
|
||||
|
||||
//TODO: handle mutes
|
||||
|
@ -69,12 +70,13 @@ public class NotificationController(DatabaseContext db, NotificationRenderer not
|
|||
.IncludeCommonProperties()
|
||||
.Where(p => p.Notifiee == user && p.Id == id)
|
||||
.EnsureNoteVisibilityFor(p => p.Note, user)
|
||||
.PrecomputeNoteVisibilities(user)
|
||||
.FirstOrDefaultAsync() ??
|
||||
throw GracefulException.RecordNotFound();
|
||||
|
||||
//TODO: handle reply/renote visibility
|
||||
|
||||
var res = await notificationRenderer.RenderAsync(notification, user);
|
||||
var res = await notificationRenderer.RenderAsync(notification.EnforceRenoteReplyVisibility(p => p.Note), user);
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
|
|
|
@ -18,19 +18,14 @@ public class NotificationRenderer(NoteRenderer noteRenderer, UserRenderer userRe
|
|||
? notification.Note?.Renote
|
||||
: notification.Note;
|
||||
|
||||
if (notification.Note != null && targetNote == null)
|
||||
throw new Exception("targetNote must not be null at this stage");
|
||||
|
||||
var note = notification.Note != null
|
||||
? statuses?.FirstOrDefault(p => p.Id == targetNote!.Id) ??
|
||||
await noteRenderer.RenderAsync(targetNote!, user, accounts)
|
||||
var note = targetNote != null
|
||||
? statuses?.FirstOrDefault(p => p.Id == targetNote.Id) ??
|
||||
await noteRenderer.RenderAsync(targetNote, user, accounts)
|
||||
: null;
|
||||
|
||||
var notifier = accounts?.FirstOrDefault(p => p.Id == dbNotifier.Id) ??
|
||||
await userRenderer.RenderAsync(dbNotifier);
|
||||
|
||||
//TODO: specially handle quotes
|
||||
|
||||
var res = new NotificationEntity
|
||||
{
|
||||
Id = notification.Id,
|
||||
|
|
|
@ -125,4 +125,10 @@ public class Notification : IEntity
|
|||
[Column("id")]
|
||||
[StringLength(32)]
|
||||
public string Id { get; set; } = null!;
|
||||
|
||||
public Notification WithPrecomputedNoteVisibilities(bool reply, bool renote)
|
||||
{
|
||||
Note = Note?.WithPrecomputedVisibilities(reply, renote);
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -176,6 +176,16 @@ public static class QueryableExtensions
|
|||
p.Renote.IsVisibleFor(user)));
|
||||
}
|
||||
|
||||
public static IQueryable<Notification> PrecomputeNoteVisibilities(this IQueryable<Notification> query, User user)
|
||||
{
|
||||
return query.Select(p => p.WithPrecomputedNoteVisibilities(p.Note != null &&
|
||||
p.Note.Reply != null &&
|
||||
p.Note.Reply.IsVisibleFor(user),
|
||||
p.Note != null &&
|
||||
p.Note.Renote != null &&
|
||||
p.Note.Renote.IsVisibleFor(user)));
|
||||
}
|
||||
|
||||
public static IQueryable<User> PrecomputeRelationshipData(this IQueryable<User> query, User user)
|
||||
{
|
||||
return query.Select(p => p.WithPrecomputedBlockStatus(p.IsBlocking(user), p.IsBlockedBy(user))
|
||||
|
@ -248,13 +258,32 @@ public static class QueryableExtensions
|
|||
return list.Select(EnforceRenoteReplyVisibility);
|
||||
}
|
||||
|
||||
public static T EnforceRenoteReplyVisibility<T>(this T source, Expression<Func<T, Note?>> predicate)
|
||||
{
|
||||
var note = predicate.Compile().Invoke(source);
|
||||
if (note == null) return source;
|
||||
if (!note.PrecomputedIsReplyVisible ?? false)
|
||||
note.Reply = null;
|
||||
if (!note.PrecomputedIsRenoteVisible ?? false)
|
||||
note.Renote = null;
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> EnforceRenoteReplyVisibility<T>(
|
||||
this IEnumerable<T> list, Expression<Func<T, Note?>> predicate
|
||||
)
|
||||
{
|
||||
return list.Select(p => EnforceRenoteReplyVisibility(p, predicate));
|
||||
}
|
||||
|
||||
public static async Task<List<StatusEntity>> RenderAllForMastodonAsync(
|
||||
this IQueryable<Note> notes, NoteRenderer renderer, User? user
|
||||
)
|
||||
{
|
||||
var list = (await notes.ToListAsync())
|
||||
.EnforceRenoteReplyVisibility()
|
||||
.ToList();
|
||||
.EnforceRenoteReplyVisibility()
|
||||
.ToList();
|
||||
return (await renderer.RenderManyAsync(list, user)).ToList();
|
||||
}
|
||||
|
||||
|
@ -270,7 +299,9 @@ public static class QueryableExtensions
|
|||
this IQueryable<Notification> notifications, NotificationRenderer renderer, User user
|
||||
)
|
||||
{
|
||||
var list = await notifications.ToListAsync();
|
||||
var list = (await notifications.ToListAsync())
|
||||
.EnforceRenoteReplyVisibility(p => p.Note)
|
||||
.ToList();
|
||||
return (await renderer.RenderManyAsync(list, user)).ToList();
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue