diff --git a/Refresh.Common/Extensions/StringExtensions.cs b/Refresh.Common/Extensions/StringExtensions.cs new file mode 100644 index 00000000..0e93ed44 --- /dev/null +++ b/Refresh.Common/Extensions/StringExtensions.cs @@ -0,0 +1,9 @@ +namespace Refresh.Common.Extensions; + +public static class StringExtensions +{ + public static bool IsBlankHash(this string? hash) + { + return string.IsNullOrWhiteSpace(hash) || hash == "0"; + } +} \ No newline at end of file diff --git a/Refresh.Database/GameDatabaseContext.Assets.cs b/Refresh.Database/GameDatabaseContext.Assets.cs index 2e548c3c..a208e34b 100644 --- a/Refresh.Database/GameDatabaseContext.Assets.cs +++ b/Refresh.Database/GameDatabaseContext.Assets.cs @@ -10,7 +10,7 @@ public partial class GameDatabaseContext // Assets public GameAsset? GetAssetFromHash(string hash) { - if (hash == "0" || hash.StartsWith('g')) return null; + if (hash.IsBlankHash() || hash.StartsWith('g')) return null; return this.GameAssetsIncluded .FirstOrDefault(a => a.AssetHash == hash); diff --git a/Refresh.Interfaces.APIv3/Endpoints/UserApiEndpoints.cs b/Refresh.Interfaces.APIv3/Endpoints/UserApiEndpoints.cs index f13fe7a2..fd930258 100644 --- a/Refresh.Interfaces.APIv3/Endpoints/UserApiEndpoints.cs +++ b/Refresh.Interfaces.APIv3/Endpoints/UserApiEndpoints.cs @@ -62,14 +62,43 @@ public ApiResponse UpdateUser(RequestContext contex GameUser user, ApiUpdateUserRequest body, IDataStore dataStore, DataContext dataContext, IntegrationConfig integrationConfig, SmtpService smtpService) { - if (body.IconHash != null && database.GetAssetFromHash(body.IconHash) == null) - return ApiNotFoundError.Instance; - - if (body.VitaIconHash != null && database.GetAssetFromHash(body.VitaIconHash) == null) - return ApiNotFoundError.Instance; - - if (body.BetaIconHash != null && database.GetAssetFromHash(body.BetaIconHash) == null) - return ApiNotFoundError.Instance; + // If any icon is requested to be reset, force its hash to be a specific value, + // to not allow uncontrolled values which would still count as blank/empty hash (e.g. unlimited whitespaces) + if (body.IconHash != null) + { + if (body.IconHash.IsBlankHash()) + { + body.IconHash = "0"; + } + else if (database.GetAssetFromHash(body.IconHash) == null) + { + return ApiNotFoundError.Instance; + } + } + + if (body.VitaIconHash != null) + { + if (body.VitaIconHash.IsBlankHash()) + { + body.VitaIconHash = "0"; + } + else if (database.GetAssetFromHash(body.VitaIconHash) == null) + { + return ApiNotFoundError.Instance; + } + } + + if (body.BetaIconHash != null) + { + if (body.BetaIconHash.IsBlankHash()) + { + body.BetaIconHash = "0"; + } + else if (database.GetAssetFromHash(body.BetaIconHash) == null) + { + return ApiNotFoundError.Instance; + } + } if (body.EmailAddress != null && !smtpService.CheckEmailDomainValidity(body.EmailAddress)) return ApiValidationError.EmailDoesNotActuallyExistError; diff --git a/Refresh.Interfaces.Game/Endpoints/UserEndpoints.cs b/Refresh.Interfaces.Game/Endpoints/UserEndpoints.cs index a679dd19..89af490f 100644 --- a/Refresh.Interfaces.Game/Endpoints/UserEndpoints.cs +++ b/Refresh.Interfaces.Game/Endpoints/UserEndpoints.cs @@ -115,14 +115,17 @@ public SerializedFriendsList GetFriends(RequestContext context, GameDatabaseCont return null; } } - else + else if (data.IconHash.IsBlankHash()) + { + // Force hash to be a specific value if the icon is supposed to be reset/default to a PSN avatar, + // to not allow uncontrolled values which would still count as blank/empty hash (e.g. unlimited whitespaces) + data.IconHash = "0"; + } + else if (!dataContext.DataStore.ExistsInStore(data.IconHash)) { //If the asset does not exist on the server, block the request - if (!dataContext.DataStore.ExistsInStore(data.IconHash)) - { - dataContext.Database.AddErrorNotification("Profile update failed", "Your avatar failed to update because the asset was missing on the server.", user); - return null; - } + dataContext.Database.AddErrorNotification("Profile update failed", "Your avatar failed to update because the asset was missing on the server.", user); + return null; } }