Files
IKAR/ikar_server/src/Ikar.Server/Infrastructure/Admin/AdminPages.cs
T
sevenhill b4c27da560
Tests / test (push) Canceled after 0s
Native crypto / native-crypto (push) Canceled after 0s
Release (main) / android (oneme) (push) Canceled after 0s
Release (main) / android (qlyra) (push) Canceled after 0s
Release (main) / windows (push) Canceled after 0s
Release (main) / linux (push) Canceled after 0s
Release (main) / macos (push) Canceled after 0s
Release (main) / ios (push) Canceled after 0s
Release (main) / release (push) Canceled after 0s
Add full IKAR administration console with secure session controls
2026-10-07 23:42:02 +03:00

51 lines
3.0 KiB
C#

using Ikar.Server.Data.Entities;
using Ikar.Shared;
using Microsoft.EntityFrameworkCore;
namespace Ikar.Server.Infrastructure.Admin;
public sealed record AdminPage<T>(IReadOnlyList<T> Items, int Total, int Page, int PageSize);
public sealed partial class AdminService
{
private static IQueryable<User> FilterUsers(IQueryable<User> query, string? status) => status switch {
"blocked" => query.Where(x => x.IsBlocked), "active" => query.Where(x => !x.IsBlocked),
"bots" => query.Where(x => x.IsBot), "people" => query.Where(x => !x.IsBot), _ => query };
public async Task<AdminPage<AdminUserDto>> UserPageAsync(string? q, string? status, int page, int size, CancellationToken ct)
{
page = Math.Clamp(page, 1, 1000000); size = Math.Clamp(size, 1, 100);
var query = FilterUsers(dbContext.Users.AsNoTracking(), status);
if (!string.IsNullOrWhiteSpace(q)) {
var normalized = q.Trim().ToUpperInvariant(); var like = $"%{q.Trim()}%";
query = query.Where(x => x.NormalizedUsername.Contains(normalized) || EF.Functions.Like(x.DisplayName, like) || x.PhoneNumber != null && EF.Functions.Like(x.PhoneNumber, like));
}
return new(await GetUsersAsync(q, ct, page, size, status), await query.CountAsync(ct), page, size);
}
private static IQueryable<Chat> FilterChatAttention(IQueryable<Chat> query, string? attention) => attention switch {
"pending" => query.Where(x => x.JoinRequests.Any(r => r.Status == ChatJoinRequestStatus.Pending)),
"protected" => query.Where(x => x.HasProtectedContent || x.Messages.Any(m => m.HasProtectedContent)),
"topics" => query.Where(x => x.TopicsEnabled || x.Topics.Any()), _ => query };
public async Task<AdminPage<AdminChatDto>> ChatPageAsync(string? q, string? type, int page, int size, CancellationToken ct, string? attention = null)
{
page = Math.Clamp(page, 1, 1000000); size = Math.Clamp(size, 1, 100);
var query = BuildChatsQuery(q);
if (Enum.TryParse<ChatType>(type, true, out var kind)) query = query.Where(x => x.Type == kind);
query = FilterChatAttention(query, attention);
return new(await GetChatsAsync(q, ct, page, size, type, attention), await query.CountAsync(ct), page, size);
}
public async Task<AdminPage<AdminAttachmentDto>> AttachmentPageAsync(string? q, int page, int size, CancellationToken ct)
{
page = Math.Clamp(page, 1, 1000000); size = Math.Clamp(size, 1, 100);
var query = dbContext.MessageAttachments.AsNoTracking();
if (!string.IsNullOrWhiteSpace(q)) {
var like = $"%{q.Trim()}%";
query = query.Where(x => EF.Functions.Like(x.OriginalFileName, like) || EF.Functions.Like(x.ContentType, like) || EF.Functions.Like(x.Message.Sender.DisplayName, like) || x.Message.Chat.Title != null && EF.Functions.Like(x.Message.Chat.Title, like));
}
return new(await GetAttachmentsAsync(q, ct, page, size), await query.CountAsync(ct), page, size);
}
}