mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-01-15 15:48:03 +00:00
Backport pull request #15254 from jellyfin/release-10.11.z
Update password reset to always return the same response structure
Original-merge: 4ad3141875
Merged-by: crobibero <cody@robibe.ro>
Backported-by: Joshua M. Boniface <joshua@boniface.me>
This commit is contained in:
committed by
Joshua M. Boniface
parent
4258df4485
commit
1ccd10863e
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -92,33 +93,38 @@ namespace Jellyfin.Server.Implementations.Users
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public async Task<ForgotPasswordResult> StartForgotPasswordProcess(User user, bool isInNetwork)
|
public async Task<ForgotPasswordResult> StartForgotPasswordProcess(User? user, string enteredUsername, bool isInNetwork)
|
||||||
{
|
{
|
||||||
byte[] bytes = new byte[4];
|
|
||||||
RandomNumberGenerator.Fill(bytes);
|
|
||||||
string pin = BitConverter.ToString(bytes);
|
|
||||||
|
|
||||||
DateTime expireTime = DateTime.UtcNow.AddMinutes(30);
|
DateTime expireTime = DateTime.UtcNow.AddMinutes(30);
|
||||||
string filePath = _passwordResetFileBase + user.Id + ".json";
|
var usernameHash = enteredUsername.ToUpperInvariant().GetMD5().ToString("N", CultureInfo.InvariantCulture);
|
||||||
SerializablePasswordReset spr = new SerializablePasswordReset
|
var pinFile = _passwordResetFileBase + usernameHash + ".json";
|
||||||
{
|
|
||||||
ExpirationDate = expireTime,
|
|
||||||
Pin = pin,
|
|
||||||
PinFile = filePath,
|
|
||||||
UserName = user.Username
|
|
||||||
};
|
|
||||||
|
|
||||||
FileStream fileStream = AsyncFile.Create(filePath);
|
if (user is not null && isInNetwork)
|
||||||
await using (fileStream.ConfigureAwait(false))
|
|
||||||
{
|
{
|
||||||
await JsonSerializer.SerializeAsync(fileStream, spr).ConfigureAwait(false);
|
byte[] bytes = new byte[4];
|
||||||
|
RandomNumberGenerator.Fill(bytes);
|
||||||
|
string pin = BitConverter.ToString(bytes);
|
||||||
|
|
||||||
|
SerializablePasswordReset spr = new SerializablePasswordReset
|
||||||
|
{
|
||||||
|
ExpirationDate = expireTime,
|
||||||
|
Pin = pin,
|
||||||
|
PinFile = pinFile,
|
||||||
|
UserName = user.Username
|
||||||
|
};
|
||||||
|
|
||||||
|
FileStream fileStream = AsyncFile.Create(pinFile);
|
||||||
|
await using (fileStream.ConfigureAwait(false))
|
||||||
|
{
|
||||||
|
await JsonSerializer.SerializeAsync(fileStream, spr).ConfigureAwait(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ForgotPasswordResult
|
return new ForgotPasswordResult
|
||||||
{
|
{
|
||||||
Action = ForgotPasswordAction.PinCode,
|
Action = ForgotPasswordAction.PinCode,
|
||||||
PinExpirationDate = expireTime,
|
PinExpirationDate = expireTime,
|
||||||
PinFile = filePath
|
PinFile = pinFile
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -508,23 +508,18 @@ namespace Jellyfin.Server.Implementations.Users
|
|||||||
public async Task<ForgotPasswordResult> StartForgotPasswordProcess(string enteredUsername, bool isInNetwork)
|
public async Task<ForgotPasswordResult> StartForgotPasswordProcess(string enteredUsername, bool isInNetwork)
|
||||||
{
|
{
|
||||||
var user = string.IsNullOrWhiteSpace(enteredUsername) ? null : GetUserByName(enteredUsername);
|
var user = string.IsNullOrWhiteSpace(enteredUsername) ? null : GetUserByName(enteredUsername);
|
||||||
|
var passwordResetProvider = GetPasswordResetProvider(user);
|
||||||
|
|
||||||
|
var result = await passwordResetProvider
|
||||||
|
.StartForgotPasswordProcess(user, enteredUsername, isInNetwork)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
if (user is not null && isInNetwork)
|
if (user is not null && isInNetwork)
|
||||||
{
|
{
|
||||||
var passwordResetProvider = GetPasswordResetProvider(user);
|
|
||||||
var result = await passwordResetProvider
|
|
||||||
.StartForgotPasswordProcess(user, isInNetwork)
|
|
||||||
.ConfigureAwait(false);
|
|
||||||
|
|
||||||
await UpdateUserAsync(user).ConfigureAwait(false);
|
await UpdateUserAsync(user).ConfigureAwait(false);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ForgotPasswordResult
|
return result;
|
||||||
{
|
|
||||||
Action = ForgotPasswordAction.InNetworkRequired,
|
|
||||||
PinFile = string.Empty
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -760,8 +755,13 @@ namespace Jellyfin.Server.Implementations.Users
|
|||||||
return GetAuthenticationProviders(user)[0];
|
return GetAuthenticationProviders(user)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
private IPasswordResetProvider GetPasswordResetProvider(User user)
|
private IPasswordResetProvider GetPasswordResetProvider(User? user)
|
||||||
{
|
{
|
||||||
|
if (user is null)
|
||||||
|
{
|
||||||
|
return _defaultPasswordResetProvider;
|
||||||
|
}
|
||||||
|
|
||||||
return GetPasswordResetProviders(user)[0];
|
return GetPasswordResetProviders(user)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
#nullable disable
|
|
||||||
|
|
||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@@ -15,11 +13,12 @@ namespace MediaBrowser.Controller.Authentication
|
|||||||
|
|
||||||
bool IsEnabled { get; }
|
bool IsEnabled { get; }
|
||||||
|
|
||||||
Task<ForgotPasswordResult> StartForgotPasswordProcess(User user, bool isInNetwork);
|
Task<ForgotPasswordResult> StartForgotPasswordProcess(User? user, string enteredUsername, bool isInNetwork);
|
||||||
|
|
||||||
Task<PinRedeemResult> RedeemPasswordResetPin(string pin);
|
Task<PinRedeemResult> RedeemPasswordResetPin(string pin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#nullable disable
|
||||||
public class PasswordPinCreationResult
|
public class PasswordPinCreationResult
|
||||||
{
|
{
|
||||||
public string PinFile { get; set; }
|
public string PinFile { get; set; }
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
#pragma warning disable CS1591
|
#pragma warning disable CS1591
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace MediaBrowser.Model.Users
|
namespace MediaBrowser.Model.Users
|
||||||
{
|
{
|
||||||
public enum ForgotPasswordAction
|
public enum ForgotPasswordAction
|
||||||
{
|
{
|
||||||
|
[Obsolete("Returning different actions represents a security concern.")]
|
||||||
ContactAdmin = 0,
|
ContactAdmin = 0,
|
||||||
PinCode = 1,
|
PinCode = 1,
|
||||||
|
[Obsolete("Returning different actions represents a security concern.")]
|
||||||
InNetworkRequired = 2
|
InNetworkRequired = 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user