diff --git a/BTCPayServer/Controllers/UIServerController.Users.cs b/BTCPayServer/Controllers/UIServerController.Users.cs index 9e4ec9313..29167d991 100644 --- a/BTCPayServer/Controllers/UIServerController.Users.cs +++ b/BTCPayServer/Controllers/UIServerController.Users.cs @@ -10,10 +10,11 @@ using BTCPayServer.Data; using BTCPayServer.Events; using BTCPayServer.Models; using BTCPayServer.Models.ServerViewModels; -using BTCPayServer.Storage.Services; +using BTCPayServer.Services; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Routing; namespace BTCPayServer.Controllers { @@ -244,9 +245,6 @@ namespace BTCPayServer.Controllers return RedirectToAction(nameof(ListUsers)); } - - - [HttpGet("server/users/{userId}/toggle")] public async Task ToggleUser(string userId, bool enable) { @@ -278,6 +276,34 @@ namespace BTCPayServer.Controllers TempData[WellKnownTempData.SuccessMessage] = $"User {(enable? "enabled": "disabled")}"; return RedirectToAction(nameof(ListUsers)); } + + [HttpGet("server/users/{userId}/verification-email")] + public async Task SendVerificationEmail(string userId) + { + var user = userId == null ? null : await _UserManager.FindByIdAsync(userId); + if (user == null) + return NotFound(); + + return View("Confirm", new ConfirmModel("Send verification email", $"This will send a verification email to {user.Email}.", "Send")); + } + + [HttpPost("server/users/{userId}/verification-email")] + public async Task SendVerificationEmailPost(string userId) + { + var user = await _UserManager.FindByIdAsync(userId); + if (user == null) + { + throw new ApplicationException($"Unable to load user with ID '{userId}'."); + } + + var code = await _UserManager.GenerateEmailConfirmationTokenAsync(user); + var callbackUrl = _linkGenerator.EmailConfirmationLink(user.Id, code, Request.Scheme, Request.Host, Request.PathBase); + + (await _emailSenderFactory.GetEmailSender()).SendEmailConfirmation(user.Email, callbackUrl); + + TempData[WellKnownTempData.SuccessMessage] = "Verification email sent"; + return RedirectToAction(nameof(ListUsers)); + } } public class RegisterFromAdminViewModel diff --git a/BTCPayServer/Controllers/UIServerController.cs b/BTCPayServer/Controllers/UIServerController.cs index 8c18a9860..7a1cbd7f0 100644 --- a/BTCPayServer/Controllers/UIServerController.cs +++ b/BTCPayServer/Controllers/UIServerController.cs @@ -7,7 +7,6 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; -using System.Net.Mail; using System.Threading.Tasks; using BTCPayServer.Abstractions.Constants; using BTCPayServer.Abstractions.Extensions; @@ -62,6 +61,8 @@ namespace BTCPayServer.Controllers private readonly StoredFileRepository _StoredFileRepository; private readonly FileService _FileService; private readonly IEnumerable _StorageProviderServices; + private readonly LinkGenerator _linkGenerator; + private readonly EmailSenderFactory _emailSenderFactory; public UIServerController( UserManager userManager, @@ -81,7 +82,10 @@ namespace BTCPayServer.Controllers CheckConfigurationHostedService sshState, EventAggregator eventAggregator, IOptions externalServiceOptions, - Logs logs) + Logs logs, + LinkGenerator linkGenerator, + EmailSenderFactory emailSenderFactory + ) { _policiesSettings = policiesSettings; _Options = options; @@ -101,6 +105,8 @@ namespace BTCPayServer.Controllers _eventAggregator = eventAggregator; _externalServiceOptions = externalServiceOptions; Logs = logs; + _linkGenerator = linkGenerator; + _emailSenderFactory = emailSenderFactory; } [Route("server/maintenance")] diff --git a/BTCPayServer/Views/UIServer/ListUsers.cshtml b/BTCPayServer/Views/UIServer/ListUsers.cshtml index 2e2494338..22d5c9e9c 100644 --- a/BTCPayServer/Views/UIServer/ListUsers.cshtml +++ b/BTCPayServer/Views/UIServer/ListUsers.cshtml @@ -95,6 +95,10 @@ } + @if (!user.Verified && !user.Disabled) { + Resend verification email + - + } Edit - Remove - + +