Merge remote-tracking branch 'upstream/master' into security-path-traversal-fixes

# Conflicts:
#	Jellyfin.Api/Controllers/HlsSegmentController.cs
#	Jellyfin.Api/Controllers/PluginsController.cs
This commit is contained in:
Shadowghost
2026-07-21 07:14:47 +02:00
79 changed files with 1930 additions and 518 deletions
@@ -616,6 +616,12 @@ namespace Jellyfin.Server.Implementations.Users
.SetProperty(f => f.LastActivityDate, date)
.SetProperty(f => f.LastLoginDate, date))
.ConfigureAwait(false);
// ExecuteUpdateAsync bypasses the change tracker, so keep the
// returned entity in sync. Otherwise SessionManager.LogSessionActivity
// saves this (stale) entity in full and reverts LastLoginDate.
user.LastActivityDate = date;
user.LastLoginDate = date;
}
await dbContext.Users
@@ -883,8 +889,20 @@ namespace Jellyfin.Server.Implementations.Users
var dbContext = await _dbProvider.CreateDbContextAsync().ConfigureAwait(false);
await using (dbContext.ConfigureAwait(false))
{
dbContext.Remove(user.ProfileImage);
await dbContext.SaveChangesAsync().ConfigureAwait(false);
// Remove the tracked profile image loaded from the database instead of the
// detached instance on the passed in user. That instance can carry a stale,
// never-persisted (temporary) key, which makes EF Core throw when it is marked
// for deletion, leaving the profile image impossible to clear or replace.
var dbUser = await UserQuery(dbContext)
.AsTracking()
.FirstOrDefaultAsync(u => u.Id == user.Id)
.ConfigureAwait(false);
if (dbUser?.ProfileImage is not null)
{
dbContext.Remove(dbUser.ProfileImage);
dbUser.ProfileImage = null;
await dbContext.SaveChangesAsync().ConfigureAwait(false);
}
}
user.ProfileImage = null;