Merge branch 'master' into authorization-shard
This commit is contained in:
Submodule LightlessAPI updated: 418e647ef8...0bc7abb274
@@ -9,6 +9,8 @@ using LightlessSyncShared.Utils;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace LightlessSyncServer.Hubs;
|
||||
@@ -745,18 +747,39 @@ public partial class LightlessHub
|
||||
|
||||
var cancellationToken = RequestAbortedToken;
|
||||
|
||||
var data = await DbContext.GroupProfiles
|
||||
.FirstOrDefaultAsync(g => g.Group.GID == dto.Group.GID || g.Group.Alias == dto.Group.GID, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
var profileDto = new GroupProfileDto(dto.Group, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
||||
|
||||
if (data is not null)
|
||||
if (dto?.Group == null)
|
||||
{
|
||||
profileDto = data.ToDTO();
|
||||
_logger.LogCallWarning(LightlessHubLogger.Args("GroupGetProfile: dto.Group is null"));
|
||||
return new GroupProfileDto(Group: null, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
||||
}
|
||||
|
||||
return profileDto;
|
||||
var data = await DbContext.GroupProfiles
|
||||
.Include(gp => gp.Group)
|
||||
.FirstOrDefaultAsync(
|
||||
g => g.Group.GID == dto.Group.GID || g.Group.Alias == dto.Group.AliasOrGID,
|
||||
cancellationToken
|
||||
)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (data == null)
|
||||
{
|
||||
return new GroupProfileDto(dto.Group, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
||||
}
|
||||
|
||||
if (data.ProfileDisabled)
|
||||
{
|
||||
return new GroupProfileDto(Group: dto.Group, Description: "This profile was permanently disabled", Tags: [], PictureBase64: null, IsNsfw: false, IsDisabled: true);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return data.ToDTO();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogCallWarning(LightlessHubLogger.Args(ex, "GroupGetProfile: failed to map GroupProfileDto for {Group}", dto.Group.GID ?? dto.Group.AliasOrGID));
|
||||
return new GroupProfileDto(dto.Group, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
@@ -764,6 +787,8 @@ public partial class LightlessHub
|
||||
{
|
||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||
|
||||
var cancellationToken = RequestAbortedToken;
|
||||
|
||||
if (dto.Group == null) return;
|
||||
|
||||
var (hasRights, group) = await TryValidateGroupModeratorOrOwner(dto.Group.GID).ConfigureAwait(false);
|
||||
@@ -771,57 +796,79 @@ public partial class LightlessHub
|
||||
|
||||
var groupProfileDb = await DbContext.GroupProfiles
|
||||
.FirstOrDefaultAsync(g => g.Group.GID == dto.Group.GID || g.Group.Alias == dto.Group.GID,
|
||||
RequestAbortedToken)
|
||||
cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (groupProfileDb != null)
|
||||
|
||||
if (!string.IsNullOrEmpty(dto.PictureBase64))
|
||||
{
|
||||
var groupPairs = DbContext.GroupPairs.Where(p => p.GroupGID == groupProfileDb.GroupGID).Select(p => p.GroupUserUID).ToList();
|
||||
|
||||
if (string.Equals("", dto.PictureBase64, StringComparison.OrdinalIgnoreCase))
|
||||
byte[] imageData;
|
||||
try
|
||||
{
|
||||
groupProfileDb.Base64GroupProfileImage = null;
|
||||
imageData = Convert.FromBase64String(dto.PictureBase64);
|
||||
}
|
||||
else if (dto.PictureBase64 != null)
|
||||
catch (FormatException)
|
||||
{
|
||||
groupProfileDb.Base64GroupProfileImage = dto.PictureBase64;
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "The provided image is not a valid Base64 string.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dto.Tags != null)
|
||||
MemoryStream ms = new(imageData);
|
||||
await using (ms.ConfigureAwait(false))
|
||||
{
|
||||
groupProfileDb.Tags = dto.Tags;
|
||||
}
|
||||
var format = await Image.DetectFormatAsync(ms, RequestAbortedToken).ConfigureAwait(false);
|
||||
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is not in PNG format").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
using var image = Image.Load<Rgba32>(imageData);
|
||||
|
||||
if (dto.Description != null)
|
||||
if (image.Width > 512 || image.Height > 512 || (imageData.Length > 2000 * 1024))
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is larger than 512x512 or more than 2MiB").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (groupProfileDb == null)
|
||||
{
|
||||
groupProfileDb = new GroupProfile
|
||||
{
|
||||
groupProfileDb.Description = dto.Description;
|
||||
}
|
||||
GroupGID = dto.Group.GID,
|
||||
ProfileDisabled = false,
|
||||
IsNSFW = dto.IsNsfw ?? false,
|
||||
};
|
||||
|
||||
if (dto.IsNsfw != null)
|
||||
{
|
||||
groupProfileDb.IsNSFW = dto.IsNsfw.Value;
|
||||
}
|
||||
|
||||
await Clients.Users(groupPairs).Client_GroupSendProfile(groupProfileDb.ToDTO()).ConfigureAwait(false);
|
||||
groupProfileDb.UpdateProfileFromDto(dto);
|
||||
await DbContext.GroupProfiles.AddAsync(groupProfileDb, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
var groupProfile = new GroupProfile
|
||||
if (groupProfileDb?.ProfileDisabled ?? false)
|
||||
{
|
||||
GroupGID = dto.Group.GID,
|
||||
Description = dto.Description,
|
||||
Tags = dto.Tags,
|
||||
Base64GroupProfileImage = dto.PictureBase64,
|
||||
IsNSFW = false,
|
||||
ProfileDisabled = false,
|
||||
};
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
await DbContext.GroupProfiles.AddAsync(groupProfile,
|
||||
RequestAbortedToken)
|
||||
groupProfileDb.UpdateProfileFromDto(dto);
|
||||
|
||||
var userIds = await DbContext.GroupPairs
|
||||
.Where(p => p.GroupGID == groupProfileDb.GroupGID)
|
||||
.Select(p => p.GroupUserUID)
|
||||
.ToListAsync(cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (userIds.Count > 0)
|
||||
{
|
||||
var profileDto = groupProfileDb.ToDTO();
|
||||
await Clients.Users(userIds).Client_GroupSendProfile(profileDto)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
await DbContext.SaveChangesAsync(RequestAbortedToken).ConfigureAwait(false);
|
||||
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
|
||||
@@ -826,16 +826,16 @@ public partial class LightlessHub
|
||||
|
||||
if (!allUserPairs.Contains(user.User.UID, StringComparer.Ordinal) && !string.Equals(user.User.UID, UserUID, StringComparison.Ordinal))
|
||||
{
|
||||
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, cancellationToken: RequestAbortedToken).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.ProfileDisabled) return new UserProfileDto(user.User, true, null, null, "This profile was permanently disabled");
|
||||
if (data.FlaggedForReport) return new UserProfileDto(user.User, true, null, null, "This profile is flagged for report and pending evaluation", []);
|
||||
if (data.ProfileDisabled) return new UserProfileDto(user.User, true, null, null, "This profile was permanently disabled", []);
|
||||
|
||||
return new UserProfileDto(user.User, false, data.IsNSFW, data.Base64ProfileImage, data.UserDescription);
|
||||
return new UserProfileDto(user.User, false, data.IsNSFW, data.Base64ProfileImage, data.UserDescription, data.Tags);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
@@ -913,20 +913,20 @@ public partial class LightlessHub
|
||||
|
||||
if (profile == null)
|
||||
{
|
||||
return new UserProfileDto(userData, false, null, null, null);
|
||||
return new UserProfileDto(userData, false, null, null, null, []);
|
||||
}
|
||||
|
||||
if (profile.FlaggedForReport)
|
||||
{
|
||||
return new UserProfileDto(userData, true, null, null, "This profile is flagged for report and pending evaluation");
|
||||
return new UserProfileDto(userData, true, null, null, "This profile is flagged for report and pending evaluation", []);
|
||||
}
|
||||
|
||||
if (profile.ProfileDisabled)
|
||||
{
|
||||
return new UserProfileDto(userData, true, null, null, "This profile was permanently disabled");
|
||||
return new UserProfileDto(userData, true, null, null, "This profile was permanently disabled", []);
|
||||
}
|
||||
|
||||
return new UserProfileDto(userData, false, profile.IsNSFW, profile.Base64ProfileImage, profile.UserDescription);
|
||||
return new UserProfileDto(userData, false, profile.IsNSFW, profile.Base64ProfileImage, profile.UserDescription, profile.Tags);
|
||||
}
|
||||
|
||||
[Authorize(Policy = "Identified")]
|
||||
@@ -1126,76 +1126,78 @@ public partial class LightlessHub
|
||||
{
|
||||
_logger.LogCallInfo(LightlessHubLogger.Args(dto));
|
||||
|
||||
var cancellationToken = RequestAbortedToken;
|
||||
|
||||
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, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
|
||||
|
||||
if (existingData?.FlaggedForReport ?? false)
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile is currently flagged for report and cannot be edited").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (existingData?.ProfileDisabled ?? false)
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
//Image Check of size/format
|
||||
if (!string.IsNullOrEmpty(dto.ProfilePictureBase64))
|
||||
{
|
||||
byte[] imageData = Convert.FromBase64String(dto.ProfilePictureBase64);
|
||||
using MemoryStream ms = new(imageData);
|
||||
var format = await Image.DetectFormatAsync(ms).ConfigureAwait(false);
|
||||
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
||||
byte[] imageData;
|
||||
try
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is not in PNG format").ConfigureAwait(false);
|
||||
imageData = Convert.FromBase64String(dto.ProfilePictureBase64);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "The provided image is not a valid Base64 string.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
using var image = Image.Load<Rgba32>(imageData);
|
||||
|
||||
if (image.Width > 256 || image.Height > 256 || (imageData.Length > 250 * 1024))
|
||||
MemoryStream ms = new(imageData);
|
||||
await using (ms.ConfigureAwait(false))
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is larger than 256x256 or more than 250KiB.").ConfigureAwait(false);
|
||||
return;
|
||||
var format = await Image.DetectFormatAsync(ms, RequestAbortedToken).ConfigureAwait(false);
|
||||
if (!format.FileExtensions.Contains("png", StringComparer.OrdinalIgnoreCase))
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is not in PNG format").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
using var image = Image.Load<Rgba32>(imageData);
|
||||
|
||||
if (image.Width > 512 || image.Height > 512 || (imageData.Length > 2000 * 1024))
|
||||
{
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your provided image file is larger than 512x512 or more than 2MiB.").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (existingData != null)
|
||||
{
|
||||
if (string.Equals("", dto.ProfilePictureBase64, StringComparison.OrdinalIgnoreCase))
|
||||
if (existingData.FlaggedForReport)
|
||||
{
|
||||
existingData.Base64ProfileImage = null;
|
||||
}
|
||||
else if (dto.ProfilePictureBase64 != null)
|
||||
{
|
||||
existingData.Base64ProfileImage = dto.ProfilePictureBase64;
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile is currently flagged for report and cannot be edited").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dto.IsNSFW != null)
|
||||
if (existingData.ProfileDisabled)
|
||||
{
|
||||
existingData.IsNSFW = dto.IsNSFW.Value;
|
||||
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dto.Description != null)
|
||||
{
|
||||
existingData.UserDescription = dto.Description;
|
||||
}
|
||||
existingData.UpdateProfileFromDto(dto);
|
||||
}
|
||||
else
|
||||
{
|
||||
UserProfileData userProfileData = new()
|
||||
UserProfileData newUserProfileData = new()
|
||||
{
|
||||
UserUID = dto.User.UID,
|
||||
Base64ProfileImage = dto.ProfilePictureBase64 ?? null,
|
||||
UserDescription = dto.Description ?? null,
|
||||
IsNSFW = dto.IsNSFW ?? false
|
||||
IsNSFW = dto.IsNSFW ?? false,
|
||||
};
|
||||
|
||||
await DbContext.UserProfileData.AddAsync(userProfileData).ConfigureAwait(false);
|
||||
newUserProfileData.UpdateProfileFromDto(dto);
|
||||
|
||||
await DbContext.UserProfileData.AddAsync(newUserProfileData, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await DbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
|
||||
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var allPairedUsers = await GetAllPairedUnpausedUsers().ConfigureAwait(false);
|
||||
var pairs = await GetOnlineUsers(allPairedUsers).ConfigureAwait(false);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using LightlessSync.API.Data.Enum;
|
||||
using LightlessSync.API.Data.Extensions;
|
||||
using LightlessSync.API.Dto.Group;
|
||||
using LightlessSync.API.Dto.User;
|
||||
using LightlessSyncShared.Models;
|
||||
using static LightlessSyncServer.Hubs.LightlessHub;
|
||||
|
||||
@@ -9,23 +10,85 @@ namespace LightlessSyncServer.Utils;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static void UpdateProfileFromDto(this GroupProfile profile, GroupProfileDto dto)
|
||||
{
|
||||
if (profile == null || dto == null) return;
|
||||
|
||||
profile.Base64GroupProfileImage = string.IsNullOrWhiteSpace(dto.PictureBase64) ? null : dto.PictureBase64;
|
||||
if (dto.Tags != null) profile.Tags = dto.Tags;
|
||||
if (dto.Description != null) profile.Description = dto.Description;
|
||||
if (dto.IsNsfw.HasValue) profile.IsNSFW = dto.IsNsfw.Value;
|
||||
}
|
||||
|
||||
public static void UpdateProfileFromDto(this UserProfileData profile, UserProfileDto dto)
|
||||
{
|
||||
if (profile == null || dto == null) return;
|
||||
|
||||
profile.Base64ProfileImage = string.IsNullOrWhiteSpace(dto.ProfilePictureBase64) ? null : dto.ProfilePictureBase64;
|
||||
if (dto.Tags != null) profile.Tags = dto.Tags;
|
||||
if (dto.Description != null) profile.UserDescription = dto.Description;
|
||||
if (dto.IsNSFW.HasValue) profile.IsNSFW = dto.IsNSFW.Value;
|
||||
}
|
||||
|
||||
public static GroupProfileDto ToDTO(this GroupProfile groupProfile)
|
||||
{
|
||||
return new GroupProfileDto(groupProfile.Group.ToGroupData(), groupProfile.Description, groupProfile.Tags, groupProfile.Base64GroupProfileImage, groupProfile.IsNSFW, groupProfile.ProfileDisabled);
|
||||
if (groupProfile == null)
|
||||
{
|
||||
return new GroupProfileDto(Group: null, Description: null, Tags: null, PictureBase64: null, IsNsfw: false, IsDisabled: false);
|
||||
}
|
||||
|
||||
var groupData = groupProfile.Group?.ToGroupData();
|
||||
|
||||
return new GroupProfileDto(
|
||||
groupData,
|
||||
groupProfile.Description,
|
||||
groupProfile.Tags,
|
||||
groupProfile.Base64GroupProfileImage,
|
||||
groupProfile.IsNSFW,
|
||||
groupProfile.ProfileDisabled
|
||||
);
|
||||
}
|
||||
|
||||
public static UserProfileDto ToDTO(this UserProfileData userProfileData)
|
||||
{
|
||||
if (userProfileData == null)
|
||||
{
|
||||
return new UserProfileDto(User: null, Disabled: false, IsNSFW: null, ProfilePictureBase64: null, Description: null, Tags: []);
|
||||
}
|
||||
|
||||
var userData = userProfileData.User?.ToUserData();
|
||||
|
||||
return new UserProfileDto(
|
||||
userData,
|
||||
userProfileData.ProfileDisabled,
|
||||
userProfileData.IsNSFW,
|
||||
userProfileData.Base64ProfileImage,
|
||||
userProfileData.UserDescription,
|
||||
userProfileData.Tags
|
||||
);
|
||||
}
|
||||
|
||||
public static GroupData ToGroupData(this Group group)
|
||||
{
|
||||
if (group == null)
|
||||
return null;
|
||||
|
||||
return new GroupData(group.GID, group.Alias, group.CreatedDate);
|
||||
}
|
||||
|
||||
public static UserData ToUserData(this GroupPair pair)
|
||||
{
|
||||
if (pair == null)
|
||||
return null;
|
||||
|
||||
return new UserData(pair.GroupUser.UID, pair.GroupUser.Alias);
|
||||
}
|
||||
|
||||
public static UserData ToUserData(this User user)
|
||||
{
|
||||
if (user == null)
|
||||
return null;
|
||||
|
||||
return new UserData(user.UID, user.Alias);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace LightlessSyncServer.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddAndChangeTagsUserGroupProfile : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int[]>(
|
||||
name: "tags",
|
||||
table: "user_profile_data",
|
||||
type: "integer[]",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.Sql("UPDATE group_profiles SET tags = NULL;");
|
||||
|
||||
migrationBuilder.AlterColumn<int[]>(
|
||||
name: "tags",
|
||||
table: "group_profiles",
|
||||
type: "integer[]",
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "text",
|
||||
oldNullable: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "tags",
|
||||
table: "user_profile_data");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "tags",
|
||||
table: "group_profiles",
|
||||
type: "text",
|
||||
nullable: true,
|
||||
oldClrType: typeof(int[]),
|
||||
oldType: "integer[]",
|
||||
oldNullable: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -605,8 +605,8 @@ namespace LightlessSyncServer.Migrations
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("profile_disabled");
|
||||
|
||||
b.Property<string>("Tags")
|
||||
.HasColumnType("text")
|
||||
b.PrimitiveCollection<int[]>("Tags")
|
||||
.HasColumnType("integer[]")
|
||||
.HasColumnName("tags");
|
||||
|
||||
b.HasKey("GroupGID")
|
||||
@@ -840,6 +840,10 @@ namespace LightlessSyncServer.Migrations
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("profile_disabled");
|
||||
|
||||
b.PrimitiveCollection<int[]>("Tags")
|
||||
.HasColumnType("integer[]")
|
||||
.HasColumnName("tags");
|
||||
|
||||
b.Property<string>("UserDescription")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("user_description");
|
||||
|
||||
@@ -13,7 +13,7 @@ public class GroupProfile
|
||||
public string GroupGID { get; set; }
|
||||
public Group Group { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Tags { get; set; }
|
||||
public int[] Tags { get; set; }
|
||||
public string Base64GroupProfileImage { get; set; }
|
||||
public bool IsNSFW { get; set; } = false;
|
||||
public bool ProfileDisabled { get; set; } = false;
|
||||
|
||||
@@ -12,6 +12,7 @@ public class UserProfileData
|
||||
public User User { get; set; }
|
||||
|
||||
public string UserDescription { get; set; }
|
||||
public int[] Tags { get; set; }
|
||||
|
||||
[Required]
|
||||
[Key]
|
||||
|
||||
Reference in New Issue
Block a user