mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-20 02:28:31 +01:00
371b33a2e1
* This refactors the email sending so that all the logic related to users and emails are now contained in one location. * The Reset password screen has been updated from its ugly plain self to use the same layout as the login. * An admin can now create a new account without specifying a password. A link is generated that can be given to the intended user to configure the password. If emails are configured, it also sends an email * An admin can now create accounts that still require the user to verify their if the setting is enabled from the server settings. A link is generated that can be given to the intended user to configure the password. If emails are configured, it also sends an email. * The above features can be used in conjunction: An email will have to verify their email through a link. Once verified, the user is redirected to setting the password. * When an email has been verified OR a password has been set, users are now redirected to the login page with the email filled in and a success status message shown instead of a dedicated thank you page.
93 lines
4.5 KiB
C#
93 lines
4.5 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Data;
|
|
using BTCPayServer.Events;
|
|
using BTCPayServer.Logging;
|
|
using BTCPayServer.Services;
|
|
using BTCPayServer.Services.Mails;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Routing;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace BTCPayServer.HostedServices
|
|
{
|
|
public class UserEventHostedService : EventHostedServiceBase
|
|
{
|
|
private readonly UserManager<ApplicationUser> _userManager;
|
|
private readonly EmailSenderFactory _emailSenderFactory;
|
|
private readonly LinkGenerator _generator;
|
|
|
|
public UserEventHostedService(EventAggregator eventAggregator, UserManager<ApplicationUser> userManager,
|
|
EmailSenderFactory emailSenderFactory, LinkGenerator generator) : base(eventAggregator)
|
|
{
|
|
_userManager = userManager;
|
|
_emailSenderFactory = emailSenderFactory;
|
|
_generator = generator;
|
|
}
|
|
|
|
protected override void SubscribeToEvents()
|
|
{
|
|
Subscribe<UserRegisteredEvent>();
|
|
Subscribe<UserPasswordResetRequestedEvent>();
|
|
}
|
|
|
|
protected override async Task ProcessEvent(object evt, CancellationToken cancellationToken)
|
|
{
|
|
string code;
|
|
string callbackUrl;
|
|
UserPasswordResetRequestedEvent userPasswordResetRequestedEvent;
|
|
switch (evt)
|
|
{
|
|
case UserRegisteredEvent userRegisteredEvent:
|
|
Logs.PayServer.LogInformation(
|
|
$"A new user just registered {userRegisteredEvent.User.Email} {(userRegisteredEvent.Admin ? "(admin)" : "")}");
|
|
if (!userRegisteredEvent.User.EmailConfirmed && userRegisteredEvent.User.RequiresEmailConfirmation)
|
|
{
|
|
code = await _userManager.GenerateEmailConfirmationTokenAsync(userRegisteredEvent.User);
|
|
callbackUrl = _generator.EmailConfirmationLink(userRegisteredEvent.User.Id, code,
|
|
userRegisteredEvent.RequestUri.Scheme,
|
|
new HostString(userRegisteredEvent.RequestUri.Host, userRegisteredEvent.RequestUri.Port),
|
|
userRegisteredEvent.RequestUri.PathAndQuery);
|
|
userRegisteredEvent.CallbackUrlGenerated?.SetResult(new Uri(callbackUrl));
|
|
_emailSenderFactory.GetEmailSender()
|
|
.SendEmailConfirmation(userRegisteredEvent.User.Email, callbackUrl);
|
|
}
|
|
else if (!await _userManager.HasPasswordAsync(userRegisteredEvent.User))
|
|
{
|
|
userPasswordResetRequestedEvent = new UserPasswordResetRequestedEvent()
|
|
{
|
|
CallbackUrlGenerated = userRegisteredEvent.CallbackUrlGenerated,
|
|
User = userRegisteredEvent.User,
|
|
RequestUri = userRegisteredEvent.RequestUri
|
|
};
|
|
goto passwordSetter;
|
|
}
|
|
else
|
|
{
|
|
userRegisteredEvent.CallbackUrlGenerated?.SetResult(null);
|
|
}
|
|
|
|
break;
|
|
case UserPasswordResetRequestedEvent userPasswordResetRequestedEvent2:
|
|
userPasswordResetRequestedEvent = userPasswordResetRequestedEvent2;
|
|
passwordSetter:
|
|
code = await _userManager.GeneratePasswordResetTokenAsync(userPasswordResetRequestedEvent.User);
|
|
var newPassword = await _userManager.HasPasswordAsync(userPasswordResetRequestedEvent.User);
|
|
callbackUrl = _generator.ResetPasswordCallbackLink(userPasswordResetRequestedEvent.User.Id, code,
|
|
userPasswordResetRequestedEvent.RequestUri.Scheme,
|
|
new HostString(userPasswordResetRequestedEvent.RequestUri.Host,
|
|
userPasswordResetRequestedEvent.RequestUri.Port),
|
|
userPasswordResetRequestedEvent.RequestUri.PathAndQuery);
|
|
userPasswordResetRequestedEvent.CallbackUrlGenerated?.SetResult(new Uri(callbackUrl));
|
|
_emailSenderFactory.GetEmailSender()
|
|
.SendSetPasswordConfirmation(userPasswordResetRequestedEvent.User.Email, callbackUrl,
|
|
newPassword);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|