mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
New: Require password confirmation when setting or changing password
(cherry picked from commit b248163df598dc611ee919d525eb7357256d73d5)
This commit is contained in:
@@ -34,7 +34,8 @@ function AuthenticationRequiredModalContent(props) {
|
|||||||
authenticationMethod,
|
authenticationMethod,
|
||||||
authenticationRequired,
|
authenticationRequired,
|
||||||
username,
|
username,
|
||||||
password
|
password,
|
||||||
|
passwordConfirmation
|
||||||
} = settings;
|
} = settings;
|
||||||
|
|
||||||
const authenticationEnabled = authenticationMethod && authenticationMethod.value !== 'none';
|
const authenticationEnabled = authenticationMethod && authenticationMethod.value !== 'none';
|
||||||
@@ -120,6 +121,18 @@ function AuthenticationRequiredModalContent(props) {
|
|||||||
{...password}
|
{...password}
|
||||||
/>
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('PasswordConfirmation')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.PASSWORD}
|
||||||
|
name="passwordConfirmation"
|
||||||
|
onChange={onInputChange}
|
||||||
|
helpTextWarning={passwordConfirmation?.value ? undefined : translate('AuthenticationRequiredPasswordConfirmationHelpTextWarning')}
|
||||||
|
{...passwordConfirmation}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
</div> :
|
</div> :
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@@ -124,6 +124,7 @@ class SecuritySettings extends Component {
|
|||||||
authenticationRequired,
|
authenticationRequired,
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
|
passwordConfirmation,
|
||||||
apiKey,
|
apiKey,
|
||||||
certificateValidation
|
certificateValidation
|
||||||
} = settings;
|
} = settings;
|
||||||
@@ -193,6 +194,21 @@ class SecuritySettings extends Component {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
authenticationEnabled ?
|
||||||
|
<FormGroup>
|
||||||
|
<FormLabel>{translate('PasswordConfirmation')}</FormLabel>
|
||||||
|
|
||||||
|
<FormInputGroup
|
||||||
|
type={inputTypes.PASSWORD}
|
||||||
|
name="passwordConfirmation"
|
||||||
|
onChange={onInputChange}
|
||||||
|
{...passwordConfirmation}
|
||||||
|
/>
|
||||||
|
</FormGroup> :
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<FormLabel>{translate('ApiKey')}</FormLabel>
|
<FormLabel>{translate('ApiKey')}</FormLabel>
|
||||||
|
|
||||||
|
@@ -77,6 +77,7 @@
|
|||||||
"AuthenticationMethodHelpTextWarning": "Please select a valid authentication method",
|
"AuthenticationMethodHelpTextWarning": "Please select a valid authentication method",
|
||||||
"AuthenticationRequired": "Authentication Required",
|
"AuthenticationRequired": "Authentication Required",
|
||||||
"AuthenticationRequiredHelpText": "Change which requests authentication is required for. Do not change unless you understand the risks.",
|
"AuthenticationRequiredHelpText": "Change which requests authentication is required for. Do not change unless you understand the risks.",
|
||||||
|
"AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirm new password",
|
||||||
"AuthenticationRequiredPasswordHelpTextWarning": "Enter a new password",
|
"AuthenticationRequiredPasswordHelpTextWarning": "Enter a new password",
|
||||||
"AuthenticationRequiredUsernameHelpTextWarning": "Enter a new username",
|
"AuthenticationRequiredUsernameHelpTextWarning": "Enter a new username",
|
||||||
"AuthenticationRequiredWarning": "To prevent remote access without authentication, {appName} now requires authentication to be enabled. You can optionally disable authentication from local addresses.",
|
"AuthenticationRequiredWarning": "To prevent remote access without authentication, {appName} now requires authentication to be enabled. You can optionally disable authentication from local addresses.",
|
||||||
@@ -376,6 +377,7 @@
|
|||||||
"PageSizeHelpText": "Number of items to show on each page",
|
"PageSizeHelpText": "Number of items to show on each page",
|
||||||
"Parameters": "Parameters",
|
"Parameters": "Parameters",
|
||||||
"Password": "Password",
|
"Password": "Password",
|
||||||
|
"PasswordConfirmation": "Password Confirmation",
|
||||||
"Peers": "Peers",
|
"Peers": "Peers",
|
||||||
"PendingChangesDiscardChanges": "Discard changes and leave",
|
"PendingChangesDiscardChanges": "Discard changes and leave",
|
||||||
"PendingChangesMessage": "You have unsaved changes, are you sure you want to leave this page?",
|
"PendingChangesMessage": "You have unsaved changes, are you sure you want to leave this page?",
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
using FluentValidation.Validators;
|
using FluentValidation.Validators;
|
||||||
using NzbDrone.Common.Disk;
|
using NzbDrone.Common.Disk;
|
||||||
|
|
||||||
namespace NzbDrone.Core.Validation.Paths
|
namespace NzbDrone.Core.Validation.Paths
|
||||||
|
@@ -47,6 +47,9 @@ namespace Prowlarr.Api.V1.Config
|
|||||||
SharedValidator.RuleFor(c => c.Password).NotEmpty().When(c => c.AuthenticationMethod == AuthenticationType.Basic ||
|
SharedValidator.RuleFor(c => c.Password).NotEmpty().When(c => c.AuthenticationMethod == AuthenticationType.Basic ||
|
||||||
c.AuthenticationMethod == AuthenticationType.Forms);
|
c.AuthenticationMethod == AuthenticationType.Forms);
|
||||||
|
|
||||||
|
SharedValidator.RuleFor(c => c.PasswordConfirmation)
|
||||||
|
.Must((resource, p) => IsMatchingPassword(resource)).WithMessage("Must match Password");
|
||||||
|
|
||||||
SharedValidator.RuleFor(c => c.SslPort).ValidPort().When(c => c.EnableSsl);
|
SharedValidator.RuleFor(c => c.SslPort).ValidPort().When(c => c.EnableSsl);
|
||||||
SharedValidator.RuleFor(c => c.SslPort).NotEqual(c => c.Port).When(c => c.EnableSsl);
|
SharedValidator.RuleFor(c => c.SslPort).NotEqual(c => c.Port).When(c => c.EnableSsl);
|
||||||
|
|
||||||
@@ -81,6 +84,23 @@ namespace Prowlarr.Api.V1.Config
|
|||||||
return cert != null;
|
return cert != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsMatchingPassword(HostConfigResource resource)
|
||||||
|
{
|
||||||
|
var user = _userService.FindUser();
|
||||||
|
|
||||||
|
if (user != null && user.Password == resource.Password)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resource.Password == resource.PasswordConfirmation)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public override HostConfigResource GetResourceById(int id)
|
public override HostConfigResource GetResourceById(int id)
|
||||||
{
|
{
|
||||||
return GetHostConfig();
|
return GetHostConfig();
|
||||||
@@ -94,11 +114,10 @@ namespace Prowlarr.Api.V1.Config
|
|||||||
resource.Id = 1;
|
resource.Id = 1;
|
||||||
|
|
||||||
var user = _userService.FindUser();
|
var user = _userService.FindUser();
|
||||||
if (user != null)
|
|
||||||
{
|
resource.Username = user?.Username ?? string.Empty;
|
||||||
resource.Username = user.Username;
|
resource.Password = user?.Password ?? string.Empty;
|
||||||
resource.Password = user.Password;
|
resource.PasswordConfirmation = string.Empty;
|
||||||
}
|
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ namespace Prowlarr.Api.V1.Config
|
|||||||
public bool AnalyticsEnabled { get; set; }
|
public bool AnalyticsEnabled { get; set; }
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
|
public string PasswordConfirmation { get; set; }
|
||||||
public string LogLevel { get; set; }
|
public string LogLevel { get; set; }
|
||||||
public string ConsoleLogLevel { get; set; }
|
public string ConsoleLogLevel { get; set; }
|
||||||
public string Branch { get; set; }
|
public string Branch { get; set; }
|
||||||
|
Reference in New Issue
Block a user