Compare commits

...

13 Commits

Author SHA1 Message Date
0f95f26c1c Implemented match group instead of tinkering with the URL string
We're using regex already anyways, so might as well take advantage of matching groups. Group 1 will always be the country code and group 2 always the ID
2025-11-01 22:47:05 +01:00
8e36b062fd Updated Lodestone URL regex
Made it match the lodestone URL scheme exactly, with optional trailing "/" and nothing before or after the URL
2025-11-01 22:29:09 +01:00
ee69df8081 Merge pull request 'Fixed some issues on group/user profiles' (#25) from syncshells-images-combined into master
Reviewed-on: #25
Reviewed-by: defnotken <defnotken@noreply.git.lightless-sync.org>
2025-10-27 20:19:27 +01:00
f29c874515 Merge branch 'master' into syncshells-images-combined 2025-10-27 20:19:03 +01:00
cake
b84d6c35d6 Moved notification on groups on new ones, Fixed new creation of profiles. 2025-10-27 19:08:25 +01:00
bd03fa6762 Syncshells Fix -
Reviewed-on: #24
written by: Abel / Cake
2025-10-26 19:48:18 +01:00
cake
8cde3b4933 Fixed image update from dto 2025-10-26 18:59:20 +01:00
defnotken
0c357aaf7c Merge remote-tracking branch 'origin/fix-images' into syncshells-images-combined 2025-10-26 12:31:34 -05:00
cake
ae09d79577 fix image results 2025-10-26 17:43:49 +01:00
azyges
cc24dc067e fix moderators + profiles 2025-10-27 00:59:56 +09:00
6ac56d38c0 Merge pull request 'lets try this' (#23) from sql-thing into master
Reviewed-on: #23
Reviewed-by: defnotken <defnotken@noreply.git.lightless-sync.org>
2025-10-21 23:26:14 +02:00
defnotken
b7f7381dec lets try this 2025-10-21 16:16:45 -05:00
1ce7a718bb Merge pull request 'Banner Support for profiles, Some cleanup/refactoring. Country for metrics.' (#22) from server-changes into master
Reviewed-on: #22
Reviewed-by: defnotken <defnotken@noreply.git.lightless-sync.org>
2025-10-21 22:50:54 +02:00
6 changed files with 45 additions and 38 deletions

View File

@@ -211,7 +211,8 @@ public partial class LightlessHub
if (isOwnerResult.ReferredGroup == null) return (false, null);
var groupPairSelf = await DbContext.GroupPairs.SingleOrDefaultAsync(g => g.GroupGID == gid || g.Group.Alias == gid && g.GroupUserUID == UserUID).ConfigureAwait(false);
var groupPairSelf = await DbContext.GroupPairs.SingleOrDefaultAsync(
g => (g.GroupGID == gid || g.Group.Alias == gid) && g.GroupUserUID == UserUID).ConfigureAwait(false);
if (groupPairSelf == null || !groupPairSelf.IsModerator) return (false, null);
return (true, isOwnerResult.ReferredGroup);

View File

@@ -799,12 +799,12 @@ public partial class LightlessHub
if (!hasRights) return;
var groupProfileDb = await DbContext.GroupProfiles
.FirstOrDefaultAsync(g => g.Group.GID == dto.Group.GID || g.Group.Alias == dto.Group.GID,
cancellationToken)
.Include(g => g.Group)
.FirstOrDefaultAsync(g => g.GroupGID == dto.Group.GID, cancellationToken)
.ConfigureAwait(false);
ImageCheckService.ImageLoadResult profileResult = null;
ImageCheckService.ImageLoadResult bannerResult = null;
ImageCheckService.ImageLoadResult profileResult = new();
ImageCheckService.ImageLoadResult bannerResult = new();
//Avatar image validation
if (!string.IsNullOrEmpty(dto.PictureBase64))
@@ -830,40 +830,46 @@ public partial class LightlessHub
}
}
var sanitizedProfileImage = profileResult?.Base64Image;
var sanitizedBannerImage = bannerResult?.Base64Image;
if (groupProfileDb == null)
{
groupProfileDb = new GroupProfile
{
GroupGID = dto.Group.GID,
Group = group,
ProfileDisabled = false,
IsNSFW = dto.IsNsfw ?? false,
};
groupProfileDb.UpdateProfileFromDto(dto, profileResult.Base64Image, bannerResult.Base64Image);
groupProfileDb.UpdateProfileFromDto(dto, sanitizedProfileImage, sanitizedBannerImage);
await DbContext.GroupProfiles.AddAsync(groupProfileDb, cancellationToken).ConfigureAwait(false);
}
else
{
groupProfileDb.Group ??= group;
if (groupProfileDb?.ProfileDisabled ?? false)
{
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
return;
}
groupProfileDb.UpdateProfileFromDto(dto, profileResult.Base64Image, bannerResult.Base64Image);
groupProfileDb.UpdateProfileFromDto(dto, sanitizedProfileImage, sanitizedBannerImage);
}
var userIds = await DbContext.GroupPairs
.Where(p => p.GroupGID == groupProfileDb.GroupGID)
.Select(p => p.GroupUserUID)
.ToListAsync(cancellationToken)
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);
if (userIds.Count > 0)
{
var profileDto = groupProfileDb.ToDTO();
await Clients.Users(userIds).Client_GroupSendProfile(profileDto)
.ConfigureAwait(false);
}
}
await DbContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

View File

@@ -1128,7 +1128,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");
var existingData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
var profileData = await DbContext.UserProfileData.SingleOrDefaultAsync(u => u.UserUID == dto.User.UID, cancellationToken: RequestAbortedToken).ConfigureAwait(false);
ImageCheckService.ImageLoadResult profileResult = new();
ImageCheckService.ImageLoadResult bannerResult = new();
@@ -1157,35 +1157,33 @@ public partial class LightlessHub
}
}
if (existingData != null)
if (profileData != null)
{
if (existingData.FlaggedForReport)
if (profileData.FlaggedForReport)
{
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile is currently flagged for report and cannot be edited").ConfigureAwait(false);
return;
}
if (existingData.ProfileDisabled)
if (profileData.ProfileDisabled)
{
await Clients.Caller.Client_ReceiveServerMessage(MessageSeverity.Error, "Your profile was permanently disabled and cannot be edited").ConfigureAwait(false);
return;
}
existingData.UpdateProfileFromDto(dto, profileResult.Base64Image, bannerResult.Base64Image);
profileData.UpdateProfileFromDto(dto, profileResult.Base64Image, bannerResult.Base64Image);
}
else
{
UserProfileData newUserProfileData = new()
profileData = new()
{
UserUID = dto.User.UID,
Base64ProfileImage = dto.ProfilePictureBase64 ?? null,
UserDescription = dto.Description ?? null,
IsNSFW = dto.IsNSFW ?? false,
};
existingData.UpdateProfileFromDto(dto, profileResult.Base64Image, bannerResult.Base64Image);
profileData.UpdateProfileFromDto(dto, profileResult.Base64Image, bannerResult.Base64Image);
await DbContext.UserProfileData.AddAsync(newUserProfileData, cancellationToken).ConfigureAwait(false);
await DbContext.UserProfileData.AddAsync(profileData, cancellationToken).ConfigureAwait(false);
}

View File

@@ -17,22 +17,22 @@ public static class Extensions
if (profile == null || dto == null) return;
profile.Base64GroupProfileImage = string.IsNullOrWhiteSpace(base64PictureString) ? null : base64PictureString;
profile.Base64GroupBannerImage = string.IsNullOrWhiteSpace(base64BannerString) ? null : base64BannerString;
if (base64PictureString != null) profile.Base64GroupProfileImage = base64PictureString;
if (base64BannerString != null) profile.Base64GroupBannerImage = base64BannerString;
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, string? base64PictureString, string? base64BannerString = null)
public static void UpdateProfileFromDto(this UserProfileData profile, UserProfileDto dto, string? base64PictureString = null, string? base64BannerString = null)
{
ArgumentNullException.ThrowIfNull(profile);
ArgumentNullException.ThrowIfNull(dto);
if (profile == null || dto == null) return;
profile.Base64ProfileImage = string.IsNullOrWhiteSpace(base64PictureString) ? null : base64PictureString;
profile.Base64BannerImage = string.IsNullOrWhiteSpace(base64BannerString) ? null : base64BannerString;
if (base64PictureString != null) profile.Base64ProfileImage = base64PictureString;
if (base64BannerString != null) profile.Base64BannerImage = base64BannerString;
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;
@@ -45,7 +45,8 @@ public static class Extensions
return new GroupProfileDto(Group: null, Description: null, Tags: null, PictureBase64: null, BannerBase64: null, IsNsfw: false, IsDisabled: false);
}
var groupData = groupProfile.Group?.ToGroupData();
var groupData = groupProfile.Group?.ToGroupData()
?? (!string.IsNullOrWhiteSpace(groupProfile.GroupGID) ? new GroupData(groupProfile.GroupGID) : null);
return new GroupProfileDto(
groupData,

View File

@@ -329,13 +329,12 @@ public partial class LightlessWizardModule : InteractionModuleBase
private int? ParseCharacterIdFromLodestoneUrl(string lodestoneUrl)
{
var regex = new Regex(@"https:\/\/(na|eu|de|fr|jp)\.finalfantasyxiv\.com\/lodestone\/character\/\d+");
var regex = new Regex(@"^https:\/\/(na|eu|de|fr|jp)\.finalfantasyxiv\.com\/lodestone\/character\/(\d{8})/?$");
var matches = regex.Match(lodestoneUrl);
var isLodestoneUrl = matches.Success;
if (!isLodestoneUrl || matches.Groups.Count < 1) return null;
var stringId = matches.Groups[2].ToString();
lodestoneUrl = matches.Groups[0].ToString();
var stringId = lodestoneUrl.Split('/', StringSplitOptions.RemoveEmptyEntries).Last();
if (!int.TryParse(stringId, out int lodestoneId))
{
return null;

View File

@@ -16,7 +16,9 @@ namespace LightlessSyncServer.Migrations
type: "integer[]",
nullable: true);
migrationBuilder.Sql("UPDATE group_profiles SET tags = NULL;");
migrationBuilder.Sql(
"ALTER TABLE group_profiles ALTER COLUMN tags TYPE integer[] USING string_to_array(tags, ',')::integer[];"
);
migrationBuilder.AlterColumn<int[]>(
name: "tags",