diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index fad621877..29ef3b362 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -385,10 +385,6 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("123456"); s.ClickPagePrimary(); Assert.Contains("Account successfully created.", s.FindAlertMessage().Text); - - s.Driver.FindElement(By.Id("Email")).SendKeys(usr); - s.Driver.FindElement(By.Id("Password")).SendKeys("123456"); - s.Driver.FindElement(By.Id("LoginButton")).Click(); // We should be logged in now s.GoToHome(); diff --git a/BTCPayServer/Controllers/UIAccountController.cs b/BTCPayServer/Controllers/UIAccountController.cs index 5e43e201a..33d0d9c4d 100644 --- a/BTCPayServer/Controllers/UIAccountController.cs +++ b/BTCPayServer/Controllers/UIAccountController.cs @@ -650,6 +650,7 @@ namespace BTCPayServer.Controllers if (logon) { await _signInManager.SignInAsync(user, isPersistent: false); + _logger.LogInformation("User {Email} logged in", user.Email); return RedirectToLocal(returnUrl); } } @@ -793,7 +794,7 @@ namespace BTCPayServer.Controllers [HttpPost("/login/set-password")] [AllowAnonymous] [ValidateAntiForgeryToken] - public async Task SetPassword(SetPasswordViewModel model) + public async Task SetPassword(SetPasswordViewModel model, string returnUrl = null) { if (!ModelState.IsValid) { @@ -802,9 +803,11 @@ namespace BTCPayServer.Controllers var user = await _userManager.FindByEmailAsync(model.Email); var hasPassword = user != null && await _userManager.HasPasswordAsync(user); - if (!UserService.TryCanLogin(user, out _)) + var needsInitialPassword = user != null && !await _userManager.HasPasswordAsync(user); + // Let unapproved users set a password. Otherwise, don't reveal that the user does not exist. + if (!UserService.TryCanLogin(user, out var message) && !needsInitialPassword || user == null) { - // Don't reveal that the user does not exist + _logger.LogWarning("User {Email} tried to reset password, but failed: {Message}", user?.Email ?? "(NO EMAIL)", message); return RedirectToAction(nameof(Login)); } @@ -818,7 +821,19 @@ namespace BTCPayServer.Controllers ? StringLocalizer["Password successfully set."].Value : StringLocalizer["Account successfully created."].Value }); + if (!hasPassword) await FinalizeInvitationIfApplicable(user); + + // see if we can sign in user after accepting an invitation and setting the password + if (needsInitialPassword && UserService.TryCanLogin(user, out _)) + { + var signInResult = await _signInManager.PasswordSignInAsync(user.Email!, model.Password, true, true); + if (signInResult.Succeeded) + { + _logger.LogInformation("User {Email} logged in", user.Email); + return RedirectToLocal(returnUrl); + } + } return RedirectToAction(nameof(Login)); }