mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 14:34:23 +01:00
Onboarding: Invite new users (#5714)
* Server Users: More precise message when inviting users This lets the admin who invited a new user know whether or not an email has been sent. If the SMTP server hasn't been set up, they need to share the invite link with the user. * Onboarding: Invite new users - Separates the user self-registration and invite cases - Adds invitation email for users created by the admin - Adds invitation tokens to verify user was invited - Adds handler action for invite links - Refactors `UserEventHostedService` * Remove duplicate status message from views that use the wizard layout * Auto-approve users created by an admin * Notify admins via email if a new account requires approval * Update wording * Fix update user error * Fix redirect to email confirmation in invite action * Fix precondition checks after signup * Improve admin notification Send notification only if the user does not require email confirmation or when they confirmed their email address. Rationale: We want to inform admins only about qualified users and not annoy them with bot registrations. * Allow approval alongside resending confirm email * Use user email in log messages instead of ID * Prevent unnecessary notification after email confirmation * Use ApplicationUser type explicitly * Fix after rebase * Refactoring: Do not subclass UserRegisteredEvent
This commit is contained in:
@@ -4,11 +4,9 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Events;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Storage.Services;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@@ -22,7 +20,6 @@ namespace BTCPayServer.Services
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly StoredFileRepository _storedFileRepository;
|
||||
private readonly FileService _fileService;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly EventAggregator _eventAggregator;
|
||||
private readonly ApplicationDbContextFactory _applicationDbContextFactory;
|
||||
private readonly ILogger<UserService> _logger;
|
||||
@@ -32,7 +29,6 @@ namespace BTCPayServer.Services
|
||||
StoredFileRepository storedFileRepository,
|
||||
FileService fileService,
|
||||
EventAggregator eventAggregator,
|
||||
StoreRepository storeRepository,
|
||||
ApplicationDbContextFactory applicationDbContextFactory,
|
||||
ILogger<UserService> logger)
|
||||
{
|
||||
@@ -40,7 +36,6 @@ namespace BTCPayServer.Services
|
||||
_storedFileRepository = storedFileRepository;
|
||||
_fileService = fileService;
|
||||
_eventAggregator = eventAggregator;
|
||||
_storeRepository = storeRepository;
|
||||
_applicationDbContextFactory = applicationDbContextFactory;
|
||||
_logger = logger;
|
||||
}
|
||||
@@ -124,12 +119,12 @@ namespace BTCPayServer.Services
|
||||
var succeeded = await userManager.UpdateAsync(user) is { Succeeded: true };
|
||||
if (succeeded)
|
||||
{
|
||||
_logger.LogInformation("User {UserId} is now {Status}", user.Id, approved ? "approved" : "unapproved");
|
||||
_eventAggregator.Publish(new UserApprovedEvent { User = user, Approved = approved, RequestUri = requestUri });
|
||||
_logger.LogInformation("User {Email} is now {Status}", user.Email, approved ? "approved" : "unapproved");
|
||||
_eventAggregator.Publish(new UserApprovedEvent { User = user, RequestUri = requestUri });
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError("Failed to {Action} user {UserId}", approved ? "approve" : "unapprove", user.Id);
|
||||
_logger.LogError("Failed to {Action} user {Email}", approved ? "approve" : "unapprove", user.Email);
|
||||
}
|
||||
|
||||
return succeeded;
|
||||
@@ -152,11 +147,11 @@ namespace BTCPayServer.Services
|
||||
var res = await userManager.SetLockoutEndDateAsync(user, lockedOutDeadline);
|
||||
if (res.Succeeded)
|
||||
{
|
||||
_logger.LogInformation($"User {user.Id} is now {(lockedOutDeadline is null ? "unlocked" : "locked")}");
|
||||
_logger.LogInformation("User {Email} is now {Status}", user.Email, (lockedOutDeadline is null ? "unlocked" : "locked"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError($"Failed to set lockout for user {user.Id}");
|
||||
_logger.LogError("Failed to set lockout for user {Email}", user.Email);
|
||||
}
|
||||
|
||||
return res.Succeeded;
|
||||
@@ -195,11 +190,11 @@ namespace BTCPayServer.Services
|
||||
|
||||
if (res.Succeeded)
|
||||
{
|
||||
_logger.LogInformation($"Successfully set admin status for user {user.Id}");
|
||||
_logger.LogInformation("Successfully set admin status for user {Email}", user.Email);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError($"Error setting admin status for user {user.Id}");
|
||||
_logger.LogError("Error setting admin status for user {Email}", user.Email);
|
||||
}
|
||||
|
||||
return res.Succeeded;
|
||||
@@ -224,11 +219,11 @@ namespace BTCPayServer.Services
|
||||
var res = await userManager.DeleteAsync(user);
|
||||
if (res.Succeeded)
|
||||
{
|
||||
_logger.LogInformation($"User {user.Id} was successfully deleted");
|
||||
_logger.LogInformation("User {Email} was successfully deleted", user.Email);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.LogError($"Failed to delete user {user.Id}");
|
||||
_logger.LogError("Failed to delete user {Email}", user.Email);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user