Fix set-avatar auth flow and API avatar upload stability

This commit is contained in:
Paul Schneider 2026-09-04 19:03:08 +01:00
commit 138467496f
10 changed files with 115 additions and 117 deletions

View file

@ -179,7 +179,7 @@ namespace Yavsc.Server.Helpers
/// <param name="contentType"></param>
/// <param name="token"></param>
/// <returns></returns> <summary>
///
///
/// </summary>
/// <param name="user"></param>
/// <param name="root"></param>
@ -244,8 +244,24 @@ namespace Yavsc.Server.Helpers
public static FileReceivedInfo ReceiveAvatar(this ApplicationUser user, IFormFile formFile)
{
if (user == null) throw new ArgumentNullException(nameof(user));
if (formFile == null) throw new ArgumentNullException(nameof(formFile));
var avatarsRequestPath = Config.AvatarsOptions?.RequestPath.ToUriComponent();
if (string.IsNullOrWhiteSpace(avatarsRequestPath))
{
avatarsRequestPath = Constants.AvatarsPath;
}
var avatarsDirectory = Config.SiteSetup?.Avatars;
if (string.IsNullOrWhiteSpace(avatarsDirectory))
{
avatarsDirectory = "avatars";
}
Directory.CreateDirectory(avatarsDirectory);
var item = new FileReceivedInfo
(Config.AvatarsOptions.RequestPath.ToUriComponent(),
(avatarsRequestPath,
user.UserName + ".png");
using (var org = formFile.OpenReadStream())
@ -256,15 +272,15 @@ namespace Yavsc.Server.Helpers
using var image = new MagickImage(org);
image.Resize(size);
image.Write(Path.Combine(Config.SiteSetup.Avatars, item.FileName));
image.Write(Path.Combine(avatarsDirectory, item.FileName));
size.X = 64;
size.Y = 64;
image.Resize(size);
image.Write(Path.Combine(Config.SiteSetup.Avatars, user.UserName + ".s.png"));
image.Write(Path.Combine(avatarsDirectory, user.UserName + ".s.png"));
size.X = 32;
size.Y = 32;
image.Resize(size);
image.Write(Path.Combine(Config.SiteSetup.Avatars, user.UserName + ".xs.png"));
image.Write(Path.Combine(avatarsDirectory, user.UserName + ".xs.png"));
}

View file

@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
@ -133,6 +134,23 @@ public static class ServiceExtensions
(_, _, _, _) => true
};
}
options.Events = new JwtBearerEvents
{
OnMessageReceived = context =>
{
// Fallback for clients that cannot reliably attach Authorization header
// on multipart uploads. Restrict query-token support to this endpoint only.
if (string.IsNullOrEmpty(context.Token)
&& context.Request.Path.Value?.Contains("/api/v1/account/set-avatar", StringComparison.OrdinalIgnoreCase) == true
&& context.Request.Query.TryGetValue("access_token", out var tokenValues))
{
context.Token = tokenValues.ToString();
}
return Task.CompletedTask;
}
};
});
return result;

View file

@ -5,7 +5,7 @@ namespace Yavsc
public class SiteSettings
{
public string Title { get; set; } = "Yavsc";
public string Slogan { get; set; } = "";
public string Banner { get; set; } = "";
@ -27,6 +27,10 @@ namespace Yavsc
/// <value></value>
public string ExternalUrl { get; set; } = "http://lua.pschneider.fr";
/// <summary>
/// Base URL of the API fronting this site.
/// </summary>
public string ApiUrl { get; set; } = "";
/// <summary>
/// Must be a fqdn.
/// </summary>
/// <returns></returns>