Merge pull request 'Endpoints changed and added for Groups' (#7) from endpoints_groups into 1.12.0-server
Reviewed-on: #7
This commit was merged in pull request #7.
This commit is contained in:
Submodule LightlessAPI updated: fd4cd52d2e...69055b0f32
@@ -10,41 +10,24 @@ namespace LightlessSyncServer.Hubs
|
|||||||
public partial class LightlessHub
|
public partial class LightlessHub
|
||||||
{
|
{
|
||||||
public Task Client_DownloadReady(Guid requestId) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_DownloadReady(Guid requestId) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupChangePermissions(GroupPermissionDto groupPermission) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupChangePermissions(GroupPermissionDto groupPermission) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupDelete(GroupDto groupDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupDelete(GroupDto groupDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupPairChangeUserInfo(GroupPairUserInfoDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupPairChangeUserInfo(GroupPairUserInfoDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupPairJoined(GroupPairFullInfoDto groupPairInfoDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupPairJoined(GroupPairFullInfoDto groupPairInfoDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupPairLeft(GroupPairDto groupPairDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupPairLeft(GroupPairDto groupPairDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_GroupSendFullInfo(GroupFullInfoDto groupInfo) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupSendFullInfo(GroupFullInfoDto groupInfo) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
public Task Client_GroupSendProfile(GroupProfileDto groupProfile) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
public Task Client_GroupSendInfo(GroupInfoDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_GroupSendInfo(GroupInfoDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_ReceiveServerMessage(MessageSeverity messageSeverity, string message) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_ReceiveServerMessage(MessageSeverity messageSeverity, string message) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UpdateSystemInfo(SystemInfoDto systemInfo) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UpdateSystemInfo(SystemInfoDto systemInfo) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserAddClientPair(UserPairDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserAddClientPair(UserPairDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserReceiveCharacterData(OnlineUserCharaDataDto dataDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserReceiveCharacterData(OnlineUserCharaDataDto dataDto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserReceiveUploadStatus(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserReceiveUploadStatus(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserRemoveClientPair(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserRemoveClientPair(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserSendOffline(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserSendOffline(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserSendOnline(OnlineUserIdentDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserSendOnline(OnlineUserIdentDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserUpdateOtherPairPermissions(UserPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserUpdateOtherPairPermissions(UserPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserUpdateProfile(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserUpdateProfile(UserDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|
||||||
public Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserUpdateSelfPairPermissions(UserPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
public Task Client_UserUpdateDefaultPermissions(DefaultPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UserUpdateDefaultPermissions(DefaultPermissionsDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
public Task Client_UpdateUserIndividualPairStatusDto(UserIndividualPairStatusDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
public Task Client_UpdateUserIndividualPairStatusDto(UserIndividualPairStatusDto dto) => throw new PlatformNotSupportedException("Calling clientside method on server not supported");
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public partial class LightlessHub
|
|||||||
group.PreferDisableAnimations = dto.Permissions.HasFlag(GroupPermissions.PreferDisableAnimations);
|
group.PreferDisableAnimations = dto.Permissions.HasFlag(GroupPermissions.PreferDisableAnimations);
|
||||||
group.PreferDisableVFX = dto.Permissions.HasFlag(GroupPermissions.PreferDisableVFX);
|
group.PreferDisableVFX = dto.Permissions.HasFlag(GroupPermissions.PreferDisableVFX);
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToList();
|
var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToList();
|
||||||
await Clients.Users(groupPairs).Client_GroupChangePermissions(new GroupPermissionDto(dto.Group, dto.Permissions)).ConfigureAwait(false);
|
await Clients.Users(groupPairs).Client_GroupChangePermissions(new GroupPermissionDto(dto.Group, dto.Permissions)).ConfigureAwait(false);
|
||||||
@@ -137,7 +137,7 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
var allUserPairs = await GetAllPairInfo(pair.GroupUserUID).ConfigureAwait(false);
|
var allUserPairs = await GetAllPairInfo(pair.GroupUserUID).ConfigureAwait(false);
|
||||||
|
|
||||||
var sharedData = await DbContext.CharaDataAllowances.Where(u => u.AllowedGroup != null && u.AllowedGroupGID == dto.GID && u.ParentUploaderUID == pair.GroupUserUID).ToListAsync().ConfigureAwait(false);
|
var sharedData = await DbContext.CharaDataAllowances.Where(u => u.AllowedGroup != null && u.AllowedGroupGID == dto.GID && u.ParentUploaderUID == pair.GroupUserUID).ToListAsync(cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
DbContext.CharaDataAllowances.RemoveRange(sharedData);
|
DbContext.CharaDataAllowances.RemoveRange(sharedData);
|
||||||
|
|
||||||
foreach (var groupUserPair in groupPairs.Where(p => !string.Equals(p.GroupUserUID, pair.GroupUserUID, StringComparison.Ordinal)))
|
foreach (var groupUserPair in groupPairs.Where(p => !string.Equals(p.GroupUserUID, pair.GroupUserUID, StringComparison.Ordinal)))
|
||||||
@@ -153,25 +153,26 @@ public partial class LightlessHub
|
|||||||
public async Task<GroupJoinDto> GroupCreate()
|
public async Task<GroupJoinDto> GroupCreate()
|
||||||
{
|
{
|
||||||
_logger.LogCallInfo();
|
_logger.LogCallInfo();
|
||||||
var existingGroupsByUser = await DbContext.Groups.CountAsync(u => u.OwnerUID == UserUID).ConfigureAwait(false);
|
var existingGroupsByUser = await DbContext.Groups.CountAsync(u => u.OwnerUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var existingJoinedGroups = await DbContext.GroupPairs.CountAsync(u => u.GroupUserUID == UserUID).ConfigureAwait(false);
|
var existingJoinedGroups = await DbContext.GroupPairs.CountAsync(u => u.GroupUserUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (existingGroupsByUser >= _maxExistingGroupsByUser || existingJoinedGroups >= _maxJoinedGroupsByUser)
|
if (existingGroupsByUser >= _maxExistingGroupsByUser || existingJoinedGroups >= _maxJoinedGroupsByUser)
|
||||||
{
|
{
|
||||||
throw new System.Exception($"Max groups for user is {_maxExistingGroupsByUser}, max joined groups is {_maxJoinedGroupsByUser}.");
|
throw new System.Exception($"Max groups for user is {_maxExistingGroupsByUser}, max joined groups is {_maxJoinedGroupsByUser}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var gid = StringUtils.GenerateRandomString(12);
|
var gid = StringUtils.GenerateRandomString(12);
|
||||||
while (await DbContext.Groups.AnyAsync(g => g.GID == "MSS-" + gid).ConfigureAwait(false))
|
while (await DbContext.Groups.AnyAsync(g => g.GID == "LSS-" + gid, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
gid = StringUtils.GenerateRandomString(12);
|
gid = StringUtils.GenerateRandomString(12);
|
||||||
}
|
}
|
||||||
gid = "MSS-" + gid;
|
gid = "LSS-" + gid;
|
||||||
|
|
||||||
var passwd = StringUtils.GenerateRandomString(16);
|
var passwd = StringUtils.GenerateRandomString(16);
|
||||||
using var sha = SHA256.Create();
|
using var sha = SHA256.Create();
|
||||||
var hashedPw = StringUtils.Sha256String(passwd);
|
var hashedPw = StringUtils.Sha256String(passwd);
|
||||||
|
var currentTime = DateTime.UtcNow;
|
||||||
|
|
||||||
UserDefaultPreferredPermission defaultPermissions = await DbContext.UserDefaultPreferredPermissions.SingleAsync(u => u.UserUID == UserUID).ConfigureAwait(false);
|
UserDefaultPreferredPermission defaultPermissions = await DbContext.UserDefaultPreferredPermissions.SingleAsync(u => u.UserUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
Group newGroup = new()
|
Group newGroup = new()
|
||||||
{
|
{
|
||||||
@@ -181,7 +182,8 @@ public partial class LightlessHub
|
|||||||
OwnerUID = UserUID,
|
OwnerUID = UserUID,
|
||||||
PreferDisableAnimations = defaultPermissions.DisableGroupAnimations,
|
PreferDisableAnimations = defaultPermissions.DisableGroupAnimations,
|
||||||
PreferDisableSounds = defaultPermissions.DisableGroupSounds,
|
PreferDisableSounds = defaultPermissions.DisableGroupSounds,
|
||||||
PreferDisableVFX = defaultPermissions.DisableGroupVFX
|
PreferDisableVFX = defaultPermissions.DisableGroupVFX,
|
||||||
|
CreatedDate = currentTime,
|
||||||
};
|
};
|
||||||
|
|
||||||
GroupPair initialPair = new()
|
GroupPair initialPair = new()
|
||||||
@@ -189,6 +191,8 @@ public partial class LightlessHub
|
|||||||
GroupGID = newGroup.GID,
|
GroupGID = newGroup.GID,
|
||||||
GroupUserUID = UserUID,
|
GroupUserUID = UserUID,
|
||||||
IsPinned = true,
|
IsPinned = true,
|
||||||
|
JoinedGroupOn = currentTime,
|
||||||
|
FromFinder = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
GroupPairPreferredPermission initialPrefPermissions = new()
|
GroupPairPreferredPermission initialPrefPermissions = new()
|
||||||
@@ -197,20 +201,20 @@ public partial class LightlessHub
|
|||||||
GroupGID = newGroup.GID,
|
GroupGID = newGroup.GID,
|
||||||
DisableSounds = defaultPermissions.DisableGroupSounds,
|
DisableSounds = defaultPermissions.DisableGroupSounds,
|
||||||
DisableAnimations = defaultPermissions.DisableGroupAnimations,
|
DisableAnimations = defaultPermissions.DisableGroupAnimations,
|
||||||
DisableVFX = defaultPermissions.DisableGroupAnimations
|
DisableVFX = defaultPermissions.DisableGroupAnimations,
|
||||||
};
|
};
|
||||||
|
|
||||||
await DbContext.Groups.AddAsync(newGroup).ConfigureAwait(false);
|
await DbContext.Groups.AddAsync(newGroup, _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
await DbContext.GroupPairs.AddAsync(initialPair).ConfigureAwait(false);
|
await DbContext.GroupPairs.AddAsync(initialPair, _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
await DbContext.GroupPairPreferredPermissions.AddAsync(initialPrefPermissions).ConfigureAwait(false);
|
await DbContext.GroupPairPreferredPermissions.AddAsync(initialPrefPermissions, _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
var self = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
var self = await DbContext.Users.SingleAsync(u => u.UID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(newGroup.ToGroupData(), self.ToUserData(),
|
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(newGroup.ToGroupData(), self.ToUserData(),
|
||||||
newGroup.ToEnum(), initialPrefPermissions.ToEnum(), initialPair.ToEnum(), new(StringComparer.Ordinal)))
|
newGroup.ToEnum(), initialPrefPermissions.ToEnum(), initialPair.ToEnum(), new(StringComparer.Ordinal)))
|
||||||
.ConfigureAwait(false);
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(gid));
|
_logger.LogCallInfo(LightlessHubLogger.Args(gid));
|
||||||
|
|
||||||
return new GroupJoinDto(newGroup.ToGroupData(), passwd, initialPrefPermissions.ToEnum());
|
return new GroupJoinDto(newGroup.ToGroupData(), passwd, initialPrefPermissions.ToEnum());
|
||||||
@@ -264,10 +268,10 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success"));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success"));
|
||||||
|
|
||||||
var groupPairs = await DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).ToListAsync().ConfigureAwait(false);
|
var groupPairs = await DbContext.GroupPairs.Where(p => p.GroupGID == dto.Group.GID).ToListAsync(cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
DbContext.RemoveRange(groupPairs);
|
DbContext.RemoveRange(groupPairs);
|
||||||
DbContext.Remove(group);
|
DbContext.Remove(group);
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
await Clients.Users(groupPairs.Select(g => g.GroupUserUID)).Client_GroupDelete(new GroupDto(group.ToGroupData())).ConfigureAwait(false);
|
await Clients.Users(groupPairs.Select(g => g.GroupUserUID)).Client_GroupDelete(new GroupDto(group.ToGroupData())).ConfigureAwait(false);
|
||||||
|
|
||||||
@@ -280,9 +284,9 @@ public partial class LightlessHub
|
|||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||||
|
|
||||||
var (userHasRights, group) = await TryValidateGroupModeratorOrOwner(dto.GID).ConfigureAwait(false);
|
var (userHasRights, group) = await TryValidateGroupModeratorOrOwner(dto.GID).ConfigureAwait(false);
|
||||||
if (!userHasRights) return new List<BannedGroupUserDto>();
|
if (!userHasRights) return [];
|
||||||
|
|
||||||
var banEntries = await DbContext.GroupBans.Include(b => b.BannedUser).Where(g => g.GroupGID == dto.Group.GID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
var banEntries = await DbContext.GroupBans.Include(b => b.BannedUser).Where(g => g.GroupGID == dto.Group.GID).AsNoTracking().ToListAsync(cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
List<BannedGroupUserDto> bannedGroupUsers = banEntries.Select(b =>
|
List<BannedGroupUserDto> bannedGroupUsers = banEntries.Select(b =>
|
||||||
new BannedGroupUserDto(group.ToGroupData(), b.BannedUser.ToUserData(), b.BannedReason, b.BannedOn,
|
new BannedGroupUserDto(group.ToGroupData(), b.BannedUser.ToUserData(), b.BannedReason, b.BannedOn,
|
||||||
@@ -300,14 +304,14 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||||
|
|
||||||
var group = await DbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false);
|
var group = await DbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var groupGid = group?.GID ?? string.Empty;
|
var groupGid = group?.GID ?? string.Empty;
|
||||||
var existingPair = await DbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID).ConfigureAwait(false);
|
var existingPair = await DbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var hashedPw = StringUtils.Sha256String(dto.Password);
|
var hashedPw = StringUtils.Sha256String(dto.Password);
|
||||||
var existingUserCount = await DbContext.GroupPairs.AsNoTracking().CountAsync(g => g.GroupGID == groupGid).ConfigureAwait(false);
|
var existingUserCount = await DbContext.GroupPairs.AsNoTracking().CountAsync(g => g.GroupGID == groupGid, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var joinedGroups = await DbContext.GroupPairs.CountAsync(g => g.GroupUserUID == UserUID).ConfigureAwait(false);
|
var joinedGroups = await DbContext.GroupPairs.CountAsync(g => g.GroupUserUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var isBanned = await DbContext.GroupBans.AnyAsync(g => g.GroupGID == groupGid && g.BannedUserUID == UserUID).ConfigureAwait(false);
|
var isBanned = await DbContext.GroupBans.AnyAsync(g => g.GroupGID == groupGid && g.BannedUserUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var oneTimeInvite = await DbContext.GroupTempInvites.SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.Invite == hashedPw).ConfigureAwait(false);
|
var oneTimeInvite = await DbContext.GroupTempInvites.SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.Invite == hashedPw, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
if (group == null
|
if (group == null
|
||||||
|| (!string.Equals(group.HashedPassword, hashedPw, StringComparison.Ordinal) && oneTimeInvite == null)
|
|| (!string.Equals(group.HashedPassword, hashedPw, StringComparison.Ordinal) && oneTimeInvite == null)
|
||||||
@@ -333,7 +337,7 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||||
|
|
||||||
var group = await DbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid).ConfigureAwait(false);
|
var group = await DbContext.Groups.Include(g => g.Owner).AsNoTracking().SingleOrDefaultAsync(g => g.GID == aliasOrGid || g.Alias == aliasOrGid, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var groupGid = group?.GID ?? string.Empty;
|
var groupGid = group?.GID ?? string.Empty;
|
||||||
var existingPair = await DbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID).ConfigureAwait(false);
|
var existingPair = await DbContext.GroupPairs.AsNoTracking().SingleOrDefaultAsync(g => g.GroupGID == groupGid && g.GroupUserUID == UserUID).ConfigureAwait(false);
|
||||||
var hashedPw = dto.Password.Length == 64 && dto.Password.All(IsHex)
|
var hashedPw = dto.Password.Length == 64 && dto.Password.All(IsHex)
|
||||||
@@ -366,9 +370,11 @@ public partial class LightlessHub
|
|||||||
{
|
{
|
||||||
GroupGID = group.GID,
|
GroupGID = group.GID,
|
||||||
GroupUserUID = UserUID,
|
GroupUserUID = UserUID,
|
||||||
|
JoinedGroupOn = DateTime.UtcNow,
|
||||||
|
FromFinder = dto.Finder
|
||||||
};
|
};
|
||||||
|
|
||||||
var preferredPermissions = await DbContext.GroupPairPreferredPermissions.SingleOrDefaultAsync(u => u.UserUID == UserUID && u.GroupGID == group.GID).ConfigureAwait(false);
|
var preferredPermissions = await DbContext.GroupPairPreferredPermissions.SingleOrDefaultAsync(u => u.UserUID == UserUID && u.GroupGID == group.GID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (preferredPermissions == null)
|
if (preferredPermissions == null)
|
||||||
{
|
{
|
||||||
GroupPairPreferredPermission newPerms = new()
|
GroupPairPreferredPermission newPerms = new()
|
||||||
@@ -378,7 +384,7 @@ public partial class LightlessHub
|
|||||||
DisableSounds = dto.GroupUserPreferredPermissions.IsDisableSounds(),
|
DisableSounds = dto.GroupUserPreferredPermissions.IsDisableSounds(),
|
||||||
DisableVFX = dto.GroupUserPreferredPermissions.IsDisableVFX(),
|
DisableVFX = dto.GroupUserPreferredPermissions.IsDisableVFX(),
|
||||||
DisableAnimations = dto.GroupUserPreferredPermissions.IsDisableAnimations(),
|
DisableAnimations = dto.GroupUserPreferredPermissions.IsDisableAnimations(),
|
||||||
IsPaused = false
|
IsPaused = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
DbContext.Add(newPerms);
|
DbContext.Add(newPerms);
|
||||||
@@ -393,13 +399,13 @@ public partial class LightlessHub
|
|||||||
DbContext.Update(preferredPermissions);
|
DbContext.Update(preferredPermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
await DbContext.GroupPairs.AddAsync(newPair).ConfigureAwait(false);
|
await DbContext.GroupPairs.AddAsync(newPair, _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(aliasOrGid, "Success"));
|
_logger.LogCallInfo(LightlessHubLogger.Args(aliasOrGid, "Success"));
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
var groupInfos = await DbContext.GroupPairs.Where(u => u.GroupGID == group.GID && (u.IsPinned || u.IsModerator)).ToListAsync().ConfigureAwait(false);
|
var groupInfos = await DbContext.GroupPairs.Where(u => u.GroupGID == group.GID && (u.IsPinned || u.IsModerator)).ToListAsync(cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(group.ToGroupData(), group.Owner.ToUserData(),
|
await Clients.User(UserUID).Client_GroupSendFullInfo(new GroupFullInfoDto(group.ToGroupData(), group.Owner.ToUserData(),
|
||||||
group.ToEnum(), preferredPermissions.ToEnum(), newPair.ToEnum(),
|
group.ToEnum(), preferredPermissions.ToEnum(), newPair.ToEnum(),
|
||||||
groupInfos.ToDictionary(u => u.GroupUserUID, u => u.ToEnum(), StringComparer.Ordinal))).ConfigureAwait(false);
|
groupInfos.ToDictionary(u => u.GroupUserUID, u => u.ToEnum(), StringComparer.Ordinal))).ConfigureAwait(false);
|
||||||
@@ -527,7 +533,7 @@ public partial class LightlessHub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -613,7 +619,6 @@ public partial class LightlessHub
|
|||||||
return new GroupJoinInfoDto(group.ToGroupData(), group.Owner.ToUserData(), group.ToEnum(), true);
|
return new GroupJoinInfoDto(group.ToGroupData(), group.Owner.ToUserData(), group.ToEnum(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task GroupLeave(GroupDto dto)
|
public async Task GroupLeave(GroupDto dto)
|
||||||
{
|
{
|
||||||
@@ -632,8 +637,8 @@ public partial class LightlessHub
|
|||||||
.Where(g => g.GroupGID == dto.Group.GID)
|
.Where(g => g.GroupGID == dto.Group.GID)
|
||||||
.ToListAsync().ConfigureAwait(false);
|
.ToListAsync().ConfigureAwait(false);
|
||||||
var usersToPrune = allGroupUsers.Where(p => !p.IsPinned && !p.IsModerator
|
var usersToPrune = allGroupUsers.Where(p => !p.IsPinned && !p.IsModerator
|
||||||
&& p.GroupUserUID != UserUID
|
&& !string.Equals(p.GroupUserUID, UserUID, StringComparison.Ordinal)
|
||||||
&& p.Group.OwnerUID != p.GroupUserUID
|
&& !string.Equals(p.Group.OwnerUID, p.GroupUserUID, StringComparison.Ordinal)
|
||||||
&& p.GroupUser.LastLoggedIn.AddDays(days) < DateTime.UtcNow);
|
&& p.GroupUser.LastLoggedIn.AddDays(days) < DateTime.UtcNow);
|
||||||
|
|
||||||
if (!execute) return usersToPrune.Count();
|
if (!execute) return usersToPrune.Count();
|
||||||
@@ -646,7 +651,7 @@ public partial class LightlessHub
|
|||||||
.Client_GroupPairLeft(new GroupPairDto(dto.Group, pair.GroupUser.ToUserData())).ConfigureAwait(false);
|
.Client_GroupPairLeft(new GroupPairDto(dto.Group, pair.GroupUser.ToUserData())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
return usersToPrune.Count();
|
return usersToPrune.Count();
|
||||||
}
|
}
|
||||||
@@ -670,15 +675,15 @@ public partial class LightlessHub
|
|||||||
var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == group.GID).AsNoTracking().ToList();
|
var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == group.GID).AsNoTracking().ToList();
|
||||||
await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairLeft(dto).ConfigureAwait(false);
|
await Clients.Users(groupPairs.Select(p => p.GroupUserUID)).Client_GroupPairLeft(dto).ConfigureAwait(false);
|
||||||
|
|
||||||
var sharedData = await DbContext.CharaDataAllowances.Where(u => u.AllowedGroup != null && u.AllowedGroupGID == dto.GID && u.ParentUploaderUID == dto.UID).ToListAsync().ConfigureAwait(false);
|
var sharedData = await DbContext.CharaDataAllowances.Where(u => u.AllowedGroup != null && u.AllowedGroupGID == dto.GID && u.ParentUploaderUID == dto.UID).ToListAsync(cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
DbContext.CharaDataAllowances.RemoveRange(sharedData);
|
DbContext.CharaDataAllowances.RemoveRange(sharedData);
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
var userIdent = await GetUserIdent(dto.User.UID).ConfigureAwait(false);
|
var userIdent = await GetUserIdent(dto.User.UID).ConfigureAwait(false);
|
||||||
if (userIdent == null)
|
if (userIdent == null)
|
||||||
{
|
{
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -691,6 +696,75 @@ public partial class LightlessHub
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Identified")]
|
||||||
|
public async Task<GroupProfileDto> GroupGetProfile(GroupDto dto)
|
||||||
|
{
|
||||||
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||||
|
|
||||||
|
var cancellationToken = _contextAccessor.HttpContext.RequestAborted;
|
||||||
|
|
||||||
|
var data = await DbContext.GroupProfiles
|
||||||
|
.FirstOrDefaultAsync(g => g.GroupGID == dto.Group.GID, cancellationToken)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
var profileDto = new GroupProfileDto(dto.Group, Description: null, Tags: null, PictureBase64: null);
|
||||||
|
|
||||||
|
if (data is not null)
|
||||||
|
{
|
||||||
|
profileDto = profileDto with
|
||||||
|
{
|
||||||
|
Description = data.Description,
|
||||||
|
Tags = data.Tags,
|
||||||
|
PictureBase64 = data.Base64GroupProfileImage,
|
||||||
|
};
|
||||||
|
|
||||||
|
await Clients.User(UserUID)
|
||||||
|
.Client_GroupSendProfile(profileDto)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return profileDto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Authorize(Policy = "Identified")]
|
||||||
|
public async Task GroupSetProfile(GroupProfileDto dto)
|
||||||
|
{
|
||||||
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||||
|
|
||||||
|
if (dto.Group == null) return;
|
||||||
|
|
||||||
|
var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false);
|
||||||
|
if (!hasRights) return;
|
||||||
|
|
||||||
|
var groupProfileDb = await DbContext.GroupProfiles
|
||||||
|
.FirstOrDefaultAsync(g => g.GroupGID == dto.Group.GID,
|
||||||
|
_contextAccessor.HttpContext.RequestAborted)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (groupProfileDb != null)
|
||||||
|
{
|
||||||
|
groupProfileDb.Description = dto.Description;
|
||||||
|
groupProfileDb.Tags = dto.Tags;
|
||||||
|
groupProfileDb.Base64GroupProfileImage = dto.PictureBase64;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var groupProfile = new GroupProfile
|
||||||
|
{
|
||||||
|
GroupGID = dto.Group.GID,
|
||||||
|
Description = dto.Description,
|
||||||
|
Tags = dto.Tags,
|
||||||
|
Base64GroupProfileImage = dto.PictureBase64,
|
||||||
|
};
|
||||||
|
|
||||||
|
await DbContext.GroupProfiles.AddAsync(groupProfile,
|
||||||
|
_contextAccessor.HttpContext.RequestAborted)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
public async Task GroupSetUserInfo(GroupPairUserInfoDto dto)
|
public async Task GroupSetUserInfo(GroupPairUserInfoDto dto)
|
||||||
{
|
{
|
||||||
@@ -720,9 +794,9 @@ public partial class LightlessHub
|
|||||||
userPair.IsModerator = false;
|
userPair.IsModerator = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
var groupPairs = await DbContext.GroupPairs.AsNoTracking().Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToListAsync().ConfigureAwait(false);
|
var groupPairs = await DbContext.GroupPairs.AsNoTracking().Where(p => p.GroupGID == dto.Group.GID).Select(p => p.GroupUserUID).ToListAsync(cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
await Clients.Users(groupPairs).Client_GroupPairChangeUserInfo(new GroupPairUserInfoDto(dto.Group, dto.User, userPair.ToEnum())).ConfigureAwait(false);
|
await Clients.Users(groupPairs).Client_GroupPairChangeUserInfo(new GroupPairUserInfoDto(dto.Group, dto.User, userPair.ToEnum())).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -731,17 +805,48 @@ public partial class LightlessHub
|
|||||||
{
|
{
|
||||||
_logger.LogCallInfo();
|
_logger.LogCallInfo();
|
||||||
|
|
||||||
var groups = await DbContext.GroupPairs.Include(g => g.Group).Include(g => g.Group.Owner).Where(g => g.GroupUserUID == UserUID).AsNoTracking().ToListAsync().ConfigureAwait(false);
|
var ct = _contextAccessor.HttpContext.RequestAborted;
|
||||||
var preferredPermissions = (await DbContext.GroupPairPreferredPermissions.Where(u => u.UserUID == UserUID).ToListAsync().ConfigureAwait(false))
|
|
||||||
.Where(u => groups.Exists(k => string.Equals(k.GroupGID, u.GroupGID, StringComparison.Ordinal)))
|
|
||||||
.ToDictionary(u => groups.First(f => string.Equals(f.GroupGID, u.GroupGID, StringComparison.Ordinal)), u => u);
|
|
||||||
var groupInfos = await DbContext.GroupPairs.Where(u => groups.Select(g => g.GroupGID).Contains(u.GroupGID) && (u.IsPinned || u.IsModerator))
|
|
||||||
.ToListAsync().ConfigureAwait(false);
|
|
||||||
|
|
||||||
return preferredPermissions.Select(g => new GroupFullInfoDto(g.Key.Group.ToGroupData(), g.Key.Group.Owner.ToUserData(),
|
var result = await (
|
||||||
g.Key.Group.ToEnum(), g.Value.ToEnum(), g.Key.ToEnum(),
|
from gp in DbContext.GroupPairs
|
||||||
groupInfos.Where(i => string.Equals(i.GroupGID, g.Key.GroupGID, StringComparison.Ordinal))
|
.Include(gp => gp.Group)
|
||||||
.ToDictionary(i => i.GroupUserUID, i => i.ToEnum(), StringComparer.Ordinal))).ToList();
|
.ThenInclude(g => g.Owner)
|
||||||
|
join pp in DbContext.GroupPairPreferredPermissions
|
||||||
|
on new { gp.GroupGID, UserUID } equals new { pp.GroupGID, pp.UserUID }
|
||||||
|
where gp.GroupUserUID == UserUID
|
||||||
|
select new
|
||||||
|
{
|
||||||
|
GroupPair = gp,
|
||||||
|
PreferredPermission = pp,
|
||||||
|
GroupInfos = DbContext.GroupPairs
|
||||||
|
.Where(x => x.GroupGID == gp.GroupGID && (x.IsPinned || x.IsModerator))
|
||||||
|
.Select(x => new { x.GroupUserUID, EnumValue = x.ToEnum() })
|
||||||
|
.ToList(),
|
||||||
|
})
|
||||||
|
.AsNoTracking()
|
||||||
|
.ToListAsync(ct)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
_logger.LogCallInfo(LightlessHubLogger.Args(result));
|
||||||
|
|
||||||
|
List<GroupFullInfoDto> List = [.. result.Select(r =>
|
||||||
|
{
|
||||||
|
var groupInfoDict = r.GroupInfos
|
||||||
|
.ToDictionary(x => x.GroupUserUID, x => x.EnumValue, StringComparer.Ordinal);
|
||||||
|
|
||||||
|
|
||||||
|
_logger.LogCallInfo(LightlessHubLogger.Args(r));
|
||||||
|
|
||||||
|
return new GroupFullInfoDto(
|
||||||
|
r.GroupPair.Group.ToGroupData(),
|
||||||
|
r.GroupPair.Group.Owner.ToUserData(),
|
||||||
|
r.GroupPair.Group.ToEnum(),
|
||||||
|
r.PreferredPermission.ToEnum(),
|
||||||
|
r.GroupPair.ToEnum(),
|
||||||
|
groupInfoDict
|
||||||
|
);
|
||||||
|
}),];
|
||||||
|
return List;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = "Identified")]
|
[Authorize(Policy = "Identified")]
|
||||||
@@ -752,11 +857,11 @@ public partial class LightlessHub
|
|||||||
var (userHasRights, _) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false);
|
var (userHasRights, _) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false);
|
||||||
if (!userHasRights) return;
|
if (!userHasRights) return;
|
||||||
|
|
||||||
var banEntry = await DbContext.GroupBans.SingleOrDefaultAsync(g => g.GroupGID == dto.Group.GID && g.BannedUserUID == dto.User.UID).ConfigureAwait(false);
|
var banEntry = await DbContext.GroupBans.SingleOrDefaultAsync(g => g.GroupGID == dto.Group.GID && g.BannedUserUID == dto.User.UID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (banEntry == null) return;
|
if (banEntry == null) return;
|
||||||
|
|
||||||
DbContext.Remove(banEntry);
|
DbContext.Remove(banEntry);
|
||||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
await DbContext.SaveChangesAsync(_contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success"));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public partial class LightlessHub
|
|||||||
if (string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal) || string.IsNullOrWhiteSpace(dto.User.UID)) return;
|
if (string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal) || string.IsNullOrWhiteSpace(dto.User.UID)) return;
|
||||||
|
|
||||||
// grab other user, check if it exists and if a pair already exists
|
// grab other user, check if it exists and if a pair already exists
|
||||||
var otherUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == uid || u.Alias == uid).ConfigureAwait(false);
|
var otherUser = await DbContext.Users.SingleOrDefaultAsync(u => u.UID == uid || u.Alias == uid, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (otherUser == null)
|
if (otherUser == null)
|
||||||
{
|
{
|
||||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Warning, $"Cannot pair with {dto.User.UID}, UID does not exist").ConfigureAwait(false);
|
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Warning, $"Cannot pair with {dto.User.UID}, UID does not exist").ConfigureAwait(false);
|
||||||
@@ -48,7 +48,7 @@ public partial class LightlessHub
|
|||||||
var existingEntry =
|
var existingEntry =
|
||||||
await DbContext.ClientPairs.AsNoTracking()
|
await DbContext.ClientPairs.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(p =>
|
.FirstOrDefaultAsync(p =>
|
||||||
p.User.UID == UserUID && p.OtherUserUID == otherUser.UID).ConfigureAwait(false);
|
p.User.UID == UserUID && p.OtherUserUID == otherUser.UID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
if (existingEntry != null)
|
if (existingEntry != null)
|
||||||
{
|
{
|
||||||
@@ -57,11 +57,11 @@ public partial class LightlessHub
|
|||||||
}
|
}
|
||||||
|
|
||||||
// grab self create new client pair and save
|
// grab self create new client pair and save
|
||||||
var user = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
var user = await DbContext.Users.SingleAsync(u => u.UID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success"));
|
_logger.LogCallInfo(LightlessHubLogger.Args(dto, "Success"));
|
||||||
|
|
||||||
ClientPair wl = new ClientPair()
|
ClientPair wl = new()
|
||||||
{
|
{
|
||||||
OtherUser = otherUser,
|
OtherUser = otherUser,
|
||||||
User = user,
|
User = user,
|
||||||
@@ -73,7 +73,7 @@ public partial class LightlessHub
|
|||||||
var permissions = existingData?.OwnPermissions;
|
var permissions = existingData?.OwnPermissions;
|
||||||
if (permissions == null || !permissions.Sticky)
|
if (permissions == null || !permissions.Sticky)
|
||||||
{
|
{
|
||||||
var ownDefaultPermissions = await DbContext.UserDefaultPreferredPermissions.AsNoTracking().SingleOrDefaultAsync(f => f.UserUID == UserUID).ConfigureAwait(false);
|
var ownDefaultPermissions = await DbContext.UserDefaultPreferredPermissions.AsNoTracking().SingleOrDefaultAsync(f => f.UserUID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
permissions = new UserPermissionSet()
|
permissions = new UserPermissionSet()
|
||||||
{
|
{
|
||||||
@@ -86,7 +86,7 @@ public partial class LightlessHub
|
|||||||
Sticky = true
|
Sticky = true
|
||||||
};
|
};
|
||||||
|
|
||||||
var existingDbPerms = await DbContext.Permissions.SingleOrDefaultAsync(u => u.UserUID == UserUID && u.OtherUserUID == otherUser.UID).ConfigureAwait(false);
|
var existingDbPerms = await DbContext.Permissions.SingleOrDefaultAsync(u => u.UserUID == UserUID && u.OtherUserUID == otherUser.UID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (existingDbPerms == null)
|
if (existingDbPerms == null)
|
||||||
{
|
{
|
||||||
await DbContext.Permissions.AddAsync(permissions).ConfigureAwait(false);
|
await DbContext.Permissions.AddAsync(permissions).ConfigureAwait(false);
|
||||||
@@ -460,7 +460,7 @@ public partial class LightlessHub
|
|||||||
{
|
{
|
||||||
_logger.LogCallInfo();
|
_logger.LogCallInfo();
|
||||||
|
|
||||||
var userEntry = await DbContext.Users.SingleAsync(u => u.UID == UserUID).ConfigureAwait(false);
|
var userEntry = await DbContext.Users.SingleAsync(u => u.UID == UserUID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
var secondaryUsers = await DbContext.Auth.Include(u => u.User).Where(u => u.PrimaryUserUID == UserUID).Select(c => c.User).ToListAsync().ConfigureAwait(false);
|
var secondaryUsers = await DbContext.Auth.Include(u => u.User).Where(u => u.PrimaryUserUID == UserUID).Select(c => c.User).ToListAsync().ConfigureAwait(false);
|
||||||
foreach (var user in secondaryUsers)
|
foreach (var user in secondaryUsers)
|
||||||
{
|
{
|
||||||
@@ -513,7 +513,7 @@ public partial class LightlessHub
|
|||||||
return new UserProfileDto(user.User, false, null, null, "Due to the pause status you cannot access this users profile.");
|
return new UserProfileDto(user.User, false, null, null, "Due to the pause status you cannot access this users profile.");
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.User.UID).ConfigureAwait(false);
|
var data = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == user.User.UID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (data == null) return new UserProfileDto(user.User, false, null, null, null);
|
if (data == null) return new UserProfileDto(user.User, false, null, null, null);
|
||||||
|
|
||||||
if (data.FlaggedForReport) return new UserProfileDto(user.User, true, null, null, "This profile is flagged for report and pending evaluation");
|
if (data.FlaggedForReport) return new UserProfileDto(user.User, true, null, null, "This profile is flagged for report and pending evaluation");
|
||||||
@@ -614,7 +614,7 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
// check if client pair even exists
|
// check if client pair even exists
|
||||||
ClientPair callerPair =
|
ClientPair callerPair =
|
||||||
await DbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID).ConfigureAwait(false);
|
await DbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == UserUID && w.OtherUserUID == dto.User.UID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
if (callerPair == null) return;
|
if (callerPair == null) return;
|
||||||
|
|
||||||
var pairData = await GetPairInfo(UserUID, dto.User.UID).ConfigureAwait(false);
|
var pairData = await GetPairInfo(UserUID, dto.User.UID).ConfigureAwait(false);
|
||||||
@@ -665,7 +665,7 @@ public partial class LightlessHub
|
|||||||
|
|
||||||
if (!string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) throw new HubException("Cannot modify profile data for anyone but yourself");
|
if (!string.Equals(dto.User.UID, UserUID, StringComparison.Ordinal)) throw new HubException("Cannot modify profile data for anyone but yourself");
|
||||||
|
|
||||||
var existingData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID).ConfigureAwait(false);
|
var existingData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID, cancellationToken: _contextAccessor.HttpContext.RequestAborted).ConfigureAwait(false);
|
||||||
|
|
||||||
if (existingData?.FlaggedForReport ?? false)
|
if (existingData?.FlaggedForReport ?? false)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public static class Extensions
|
|||||||
{
|
{
|
||||||
public static GroupData ToGroupData(this Group group)
|
public static GroupData ToGroupData(this Group group)
|
||||||
{
|
{
|
||||||
return new GroupData(group.GID, group.Alias);
|
return new GroupData(group.GID, group.Alias, group.CreatedDate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UserData ToUserData(this GroupPair pair)
|
public static UserData ToUserData(this GroupPair pair)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ public class LightlessDbContext : DbContext
|
|||||||
public DbSet<CharaDataOriginalFile> CharaDataOriginalFiles { get; set; }
|
public DbSet<CharaDataOriginalFile> CharaDataOriginalFiles { get; set; }
|
||||||
public DbSet<CharaDataPose> CharaDataPoses { get; set; }
|
public DbSet<CharaDataPose> CharaDataPoses { get; set; }
|
||||||
public DbSet<CharaDataAllowance> CharaDataAllowances { get; set; }
|
public DbSet<CharaDataAllowance> CharaDataAllowances { get; set; }
|
||||||
|
public DbSet<GroupProfile> GroupProfiles { get; set; }
|
||||||
|
|
||||||
protected override void OnModelCreating(ModelBuilder mb)
|
protected override void OnModelCreating(ModelBuilder mb)
|
||||||
{
|
{
|
||||||
@@ -70,6 +71,14 @@ public class LightlessDbContext : DbContext
|
|||||||
mb.Entity<BannedRegistrations>().ToTable("banned_registrations");
|
mb.Entity<BannedRegistrations>().ToTable("banned_registrations");
|
||||||
mb.Entity<Group>().ToTable("groups");
|
mb.Entity<Group>().ToTable("groups");
|
||||||
mb.Entity<Group>().HasIndex(c => c.OwnerUID);
|
mb.Entity<Group>().HasIndex(c => c.OwnerUID);
|
||||||
|
mb.Entity<Group>()
|
||||||
|
.Property(g => g.CreatedDate)
|
||||||
|
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||||
|
mb.Entity<Group>()
|
||||||
|
.HasOne(g => g.Profile)
|
||||||
|
.WithOne(p => p.Group)
|
||||||
|
.HasForeignKey<GroupProfile>(p => p.GroupGID)
|
||||||
|
.IsRequired(false);
|
||||||
mb.Entity<GroupPair>().ToTable("group_pairs");
|
mb.Entity<GroupPair>().ToTable("group_pairs");
|
||||||
mb.Entity<GroupPair>().HasKey(u => new { u.GroupGID, u.GroupUserUID });
|
mb.Entity<GroupPair>().HasKey(u => new { u.GroupGID, u.GroupUserUID });
|
||||||
mb.Entity<GroupPair>().HasIndex(c => c.GroupUserUID);
|
mb.Entity<GroupPair>().HasIndex(c => c.GroupUserUID);
|
||||||
@@ -78,6 +87,9 @@ public class LightlessDbContext : DbContext
|
|||||||
mb.Entity<GroupBan>().HasKey(u => new { u.GroupGID, u.BannedUserUID });
|
mb.Entity<GroupBan>().HasKey(u => new { u.GroupGID, u.BannedUserUID });
|
||||||
mb.Entity<GroupBan>().HasIndex(c => c.BannedUserUID);
|
mb.Entity<GroupBan>().HasIndex(c => c.BannedUserUID);
|
||||||
mb.Entity<GroupBan>().HasIndex(c => c.GroupGID);
|
mb.Entity<GroupBan>().HasIndex(c => c.GroupGID);
|
||||||
|
mb.Entity<GroupProfile>().ToTable("group_profiles");
|
||||||
|
mb.Entity<GroupProfile>().HasKey(u => u.GroupGID);
|
||||||
|
mb.Entity<GroupProfile>().HasIndex(c => c.GroupGID);
|
||||||
mb.Entity<GroupTempInvite>().ToTable("group_temp_invites");
|
mb.Entity<GroupTempInvite>().ToTable("group_temp_invites");
|
||||||
mb.Entity<GroupTempInvite>().HasKey(u => new { u.GroupGID, u.Invite });
|
mb.Entity<GroupTempInvite>().HasKey(u => new { u.GroupGID, u.Invite });
|
||||||
mb.Entity<GroupTempInvite>().HasIndex(c => c.GroupGID);
|
mb.Entity<GroupTempInvite>().HasIndex(c => c.GroupGID);
|
||||||
|
|||||||
1151
LightlessSyncServer/LightlessSyncShared/Migrations/20250916200240_AddGroupProfilesAndDates.Designer.cs
generated
Normal file
1151
LightlessSyncServer/LightlessSyncShared/Migrations/20250916200240_AddGroupProfilesAndDates.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,79 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace LightlessSyncServer.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddGroupProfilesAndDates : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "created_date",
|
||||||
|
table: "groups",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: false,
|
||||||
|
defaultValueSql: "CURRENT_TIMESTAMP");
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<bool>(
|
||||||
|
name: "from_finder",
|
||||||
|
table: "group_pairs",
|
||||||
|
type: "boolean",
|
||||||
|
nullable: false,
|
||||||
|
defaultValue: false);
|
||||||
|
|
||||||
|
migrationBuilder.AddColumn<DateTime>(
|
||||||
|
name: "joined_group_on",
|
||||||
|
table: "group_pairs",
|
||||||
|
type: "timestamp with time zone",
|
||||||
|
nullable: true);
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "group_profiles",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
group_gid = table.Column<string>(type: "character varying(20)", nullable: false),
|
||||||
|
description = table.Column<string>(type: "text", nullable: true),
|
||||||
|
tags = table.Column<string>(type: "text", nullable: true),
|
||||||
|
base64group_profile_image = table.Column<string>(type: "text", nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("pk_group_profiles", x => x.group_gid);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "fk_group_profiles_groups_group_gid",
|
||||||
|
column: x => x.group_gid,
|
||||||
|
principalTable: "groups",
|
||||||
|
principalColumn: "gid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "ix_group_profiles_group_gid",
|
||||||
|
table: "group_profiles",
|
||||||
|
column: "group_gid");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "group_profiles");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "created_date",
|
||||||
|
table: "groups");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "from_finder",
|
||||||
|
table: "group_pairs");
|
||||||
|
|
||||||
|
migrationBuilder.DropColumn(
|
||||||
|
name: "joined_group_on",
|
||||||
|
table: "group_pairs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
1155
LightlessSyncServer/LightlessSyncShared/Migrations/20250917004805_AddProfilesToGroup.Designer.cs
generated
Normal file
1155
LightlessSyncServer/LightlessSyncShared/Migrations/20250917004805_AddProfilesToGroup.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
|||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
|
|
||||||
|
namespace LightlessSyncServer.Migrations
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
public partial class AddProfilesToGroup : Migration
|
||||||
|
{
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_group_profiles_groups_group_gid",
|
||||||
|
table: "group_profiles");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_group_profiles_groups_group_gid",
|
||||||
|
table: "group_profiles",
|
||||||
|
column: "group_gid",
|
||||||
|
principalTable: "groups",
|
||||||
|
principalColumn: "gid");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropForeignKey(
|
||||||
|
name: "fk_group_profiles_groups_group_gid",
|
||||||
|
table: "group_profiles");
|
||||||
|
|
||||||
|
migrationBuilder.AddForeignKey(
|
||||||
|
name: "fk_group_profiles_groups_group_gid",
|
||||||
|
table: "group_profiles",
|
||||||
|
column: "group_gid",
|
||||||
|
principalTable: "groups",
|
||||||
|
principalColumn: "gid",
|
||||||
|
onDelete: ReferentialAction.Cascade);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -430,6 +430,12 @@ namespace LightlessSyncServer.Migrations
|
|||||||
.HasColumnType("character varying(50)")
|
.HasColumnType("character varying(50)")
|
||||||
.HasColumnName("alias");
|
.HasColumnName("alias");
|
||||||
|
|
||||||
|
b.Property<DateTime>("CreatedDate")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("created_date")
|
||||||
|
.HasDefaultValueSql("CURRENT_TIMESTAMP");
|
||||||
|
|
||||||
b.Property<string>("HashedPassword")
|
b.Property<string>("HashedPassword")
|
||||||
.HasColumnType("text")
|
.HasColumnType("text")
|
||||||
.HasColumnName("hashed_password");
|
.HasColumnName("hashed_password");
|
||||||
@@ -510,6 +516,10 @@ namespace LightlessSyncServer.Migrations
|
|||||||
.HasColumnType("character varying(10)")
|
.HasColumnType("character varying(10)")
|
||||||
.HasColumnName("group_user_uid");
|
.HasColumnName("group_user_uid");
|
||||||
|
|
||||||
|
b.Property<bool>("FromFinder")
|
||||||
|
.HasColumnType("boolean")
|
||||||
|
.HasColumnName("from_finder");
|
||||||
|
|
||||||
b.Property<bool>("IsModerator")
|
b.Property<bool>("IsModerator")
|
||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("is_moderator");
|
.HasColumnName("is_moderator");
|
||||||
@@ -518,6 +528,10 @@ namespace LightlessSyncServer.Migrations
|
|||||||
.HasColumnType("boolean")
|
.HasColumnType("boolean")
|
||||||
.HasColumnName("is_pinned");
|
.HasColumnName("is_pinned");
|
||||||
|
|
||||||
|
b.Property<DateTime?>("JoinedGroupOn")
|
||||||
|
.HasColumnType("timestamp with time zone")
|
||||||
|
.HasColumnName("joined_group_on");
|
||||||
|
|
||||||
b.HasKey("GroupGID", "GroupUserUID")
|
b.HasKey("GroupGID", "GroupUserUID")
|
||||||
.HasName("pk_group_pairs");
|
.HasName("pk_group_pairs");
|
||||||
|
|
||||||
@@ -568,6 +582,34 @@ namespace LightlessSyncServer.Migrations
|
|||||||
b.ToTable("group_pair_preferred_permissions", (string)null);
|
b.ToTable("group_pair_preferred_permissions", (string)null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("LightlessSyncShared.Models.GroupProfile", b =>
|
||||||
|
{
|
||||||
|
b.Property<string>("GroupGID")
|
||||||
|
.HasMaxLength(20)
|
||||||
|
.HasColumnType("character varying(20)")
|
||||||
|
.HasColumnName("group_gid");
|
||||||
|
|
||||||
|
b.Property<string>("Base64GroupProfileImage")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("base64group_profile_image");
|
||||||
|
|
||||||
|
b.Property<string>("Description")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("description");
|
||||||
|
|
||||||
|
b.Property<string>("Tags")
|
||||||
|
.HasColumnType("text")
|
||||||
|
.HasColumnName("tags");
|
||||||
|
|
||||||
|
b.HasKey("GroupGID")
|
||||||
|
.HasName("pk_group_profiles");
|
||||||
|
|
||||||
|
b.HasIndex("GroupGID")
|
||||||
|
.HasDatabaseName("ix_group_profiles_group_gid");
|
||||||
|
|
||||||
|
b.ToTable("group_profiles", (string)null);
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("LightlessSyncShared.Models.GroupTempInvite", b =>
|
modelBuilder.Entity("LightlessSyncShared.Models.GroupTempInvite", b =>
|
||||||
{
|
{
|
||||||
b.Property<string>("GroupGID")
|
b.Property<string>("GroupGID")
|
||||||
@@ -1010,6 +1052,16 @@ namespace LightlessSyncServer.Migrations
|
|||||||
b.Navigation("User");
|
b.Navigation("User");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("LightlessSyncShared.Models.GroupProfile", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("LightlessSyncShared.Models.Group", "Group")
|
||||||
|
.WithOne("Profile")
|
||||||
|
.HasForeignKey("LightlessSyncShared.Models.GroupProfile", "GroupGID")
|
||||||
|
.HasConstraintName("fk_group_profiles_groups_group_gid");
|
||||||
|
|
||||||
|
b.Navigation("Group");
|
||||||
|
});
|
||||||
|
|
||||||
modelBuilder.Entity("LightlessSyncShared.Models.GroupTempInvite", b =>
|
modelBuilder.Entity("LightlessSyncShared.Models.GroupTempInvite", b =>
|
||||||
{
|
{
|
||||||
b.HasOne("LightlessSyncShared.Models.Group", "Group")
|
b.HasOne("LightlessSyncShared.Models.Group", "Group")
|
||||||
@@ -1089,6 +1141,11 @@ namespace LightlessSyncServer.Migrations
|
|||||||
|
|
||||||
b.Navigation("Poses");
|
b.Navigation("Poses");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("LightlessSyncShared.Models.Group", b =>
|
||||||
|
{
|
||||||
|
b.Navigation("Profile");
|
||||||
|
});
|
||||||
#pragma warning restore 612, 618
|
#pragma warning restore 612, 618
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ public class Group
|
|||||||
public User Owner { get; set; }
|
public User Owner { get; set; }
|
||||||
[MaxLength(50)]
|
[MaxLength(50)]
|
||||||
public string Alias { get; set; }
|
public string Alias { get; set; }
|
||||||
|
public GroupProfile? Profile { get; set; }
|
||||||
public bool InvitesEnabled { get; set; }
|
public bool InvitesEnabled { get; set; }
|
||||||
public string HashedPassword { get; set; }
|
public string HashedPassword { get; set; }
|
||||||
public bool PreferDisableSounds { get; set; }
|
public bool PreferDisableSounds { get; set; }
|
||||||
public bool PreferDisableAnimations { get; set; }
|
public bool PreferDisableAnimations { get; set; }
|
||||||
public bool PreferDisableVFX { get; set; }
|
public bool PreferDisableVFX { get; set; }
|
||||||
|
public DateTime CreatedDate { get; set; } = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ public class GroupPair
|
|||||||
public User GroupUser { get; set; }
|
public User GroupUser { get; set; }
|
||||||
public bool IsPinned { get; set; }
|
public bool IsPinned { get; set; }
|
||||||
public bool IsModerator { get; set; }
|
public bool IsModerator { get; set; }
|
||||||
|
public bool FromFinder { get; set; } = false;
|
||||||
|
public DateTime? JoinedGroupOn { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace LightlessSyncShared.Models;
|
||||||
|
public class GroupProfile
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
[MaxLength(20)]
|
||||||
|
public string GroupGID { get; set; }
|
||||||
|
public Group Group { get; set; }
|
||||||
|
public string Description { get; set; }
|
||||||
|
public string Tags { get; set; }
|
||||||
|
public string Base64GroupProfileImage { get; set; }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user