Notify about user changes

This commit is contained in:
Dennis Reimann 2024-07-30 23:48:48 +02:00
parent b27afb9eed
commit 0993f788a1
No known key found for this signature in database
GPG key ID: 5009E1797F03F8D0
6 changed files with 66 additions and 5 deletions

View file

@ -80,6 +80,9 @@ public class BTCPayAppState : IHostedService
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<NewOnChainTransactionEvent>(OnNewTransaction)); _compositeDisposable.Add(_eventAggregator.SubscribeAsync<NewOnChainTransactionEvent>(OnNewTransaction));
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<UserNotificationsUpdatedEvent>(UserNotificationsUpdatedEvent)); _compositeDisposable.Add(_eventAggregator.SubscribeAsync<UserNotificationsUpdatedEvent>(UserNotificationsUpdatedEvent));
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<InvoiceEvent>(InvoiceChangedEvent)); _compositeDisposable.Add(_eventAggregator.SubscribeAsync<InvoiceEvent>(InvoiceChangedEvent));
// User events
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<UserUpdatedEvent>(UserUpdatedEvent));
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<UserDeletedEvent>(UserDeletedEvent));
// Store events // Store events
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<StoreCreatedEvent>(StoreCreatedEvent)); _compositeDisposable.Add(_eventAggregator.SubscribeAsync<StoreCreatedEvent>(StoreCreatedEvent));
_compositeDisposable.Add(_eventAggregator.SubscribeAsync<StoreUpdatedEvent>(StoreUpdatedEvent)); _compositeDisposable.Add(_eventAggregator.SubscribeAsync<StoreUpdatedEvent>(StoreUpdatedEvent));
@ -91,6 +94,18 @@ public class BTCPayAppState : IHostedService
return Task.CompletedTask; return Task.CompletedTask;
} }
private async Task UserUpdatedEvent(UserUpdatedEvent arg)
{
var ev = new ServerEvent("user-updated") { UserId = arg.User.Id };
await _hubContext.Clients.Group(arg.User.Id).NotifyServerEvent(ev);
}
private async Task UserDeletedEvent(UserDeletedEvent arg)
{
var ev = new ServerEvent("user-deleted") { UserId = arg.User.Id };
await _hubContext.Clients.Group(arg.User.Id).NotifyServerEvent(ev);
}
private async Task InvoiceChangedEvent(InvoiceEvent arg) private async Task InvoiceChangedEvent(InvoiceEvent arg)
{ {
var ev = new ServerEvent("invoice-updated") { StoreId = arg.Invoice.StoreId, InvoiceId = arg.InvoiceId }; var ev = new ServerEvent("invoice-updated") { StoreId = arg.Invoice.StoreId, InvoiceId = arg.InvoiceId };

View file

@ -220,6 +220,10 @@ namespace BTCPayServer.Controllers.Greenfield
ModelState.AddModelError(string.Empty, error.Description); ModelState.AddModelError(string.Empty, error.Description);
} }
} }
else
{
_eventAggregator.Publish(new UserUpdatedEvent(user));
}
} }
if (!ModelState.IsValid) if (!ModelState.IsValid)
@ -259,7 +263,7 @@ namespace BTCPayServer.Controllers.Greenfield
blob.ImageUrl = fileIdUri.ToString(); blob.ImageUrl = fileIdUri.ToString();
user.SetBlob(blob); user.SetBlob(blob);
await _userManager.UpdateAsync(user); await _userManager.UpdateAsync(user);
_eventAggregator.Publish(new UserUpdatedEvent(user));
var model = await FromModel(user); var model = await FromModel(user);
return Ok(model); return Ok(model);
} }
@ -287,6 +291,7 @@ namespace BTCPayServer.Controllers.Greenfield
blob.ImageUrl = null; blob.ImageUrl = null;
user.SetBlob(blob); user.SetBlob(blob);
await _userManager.UpdateAsync(user); await _userManager.UpdateAsync(user);
_eventAggregator.Publish(new UserUpdatedEvent(user));
} }
return Ok(); return Ok();
} }
@ -447,6 +452,7 @@ namespace BTCPayServer.Controllers.Greenfield
// Ok, this user is an admin but there are other admins as well so safe to delete // Ok, this user is an admin but there are other admins as well so safe to delete
await _userService.DeleteUserAndAssociatedData(user); await _userService.DeleteUserAndAssociatedData(user);
_eventAggregator.Publish(new UserDeletedEvent(user));
return Ok(); return Ok();
} }

View file

@ -6,6 +6,7 @@ using BTCPayServer.Abstractions.Contracts;
using BTCPayServer.Abstractions.Extensions; using BTCPayServer.Abstractions.Extensions;
using BTCPayServer.Client; using BTCPayServer.Client;
using BTCPayServer.Data; using BTCPayServer.Data;
using BTCPayServer.Events;
using BTCPayServer.Fido2; using BTCPayServer.Fido2;
using BTCPayServer.Models; using BTCPayServer.Models;
using BTCPayServer.Models.ManageViewModels; using BTCPayServer.Models.ManageViewModels;
@ -45,6 +46,7 @@ namespace BTCPayServer.Controllers
private readonly UserService _userService; private readonly UserService _userService;
private readonly UriResolver _uriResolver; private readonly UriResolver _uriResolver;
private readonly IFileService _fileService; private readonly IFileService _fileService;
private readonly EventAggregator _eventAggregator;
readonly StoreRepository _StoreRepository; readonly StoreRepository _StoreRepository;
public UIManageController( public UIManageController(
@ -63,8 +65,8 @@ namespace BTCPayServer.Controllers
UriResolver uriResolver, UriResolver uriResolver,
IFileService fileService, IFileService fileService,
UserLoginCodeService userLoginCodeService, UserLoginCodeService userLoginCodeService,
IHtmlHelper htmlHelper IHtmlHelper htmlHelper,
) EventAggregator eventAggregator)
{ {
_userManager = userManager; _userManager = userManager;
_signInManager = signInManager; _signInManager = signInManager;
@ -82,6 +84,7 @@ namespace BTCPayServer.Controllers
_uriResolver = uriResolver; _uriResolver = uriResolver;
_fileService = fileService; _fileService = fileService;
_StoreRepository = storeRepository; _StoreRepository = storeRepository;
_eventAggregator = eventAggregator;
} }
[HttpGet] [HttpGet]
@ -207,9 +210,9 @@ namespace BTCPayServer.Controllers
return View(model); return View(model);
} }
if (needUpdate is true) if (needUpdate && await _userManager.UpdateAsync(user) is { Succeeded: true })
{ {
needUpdate = await _userManager.UpdateAsync(user) is { Succeeded: true }; _eventAggregator.Publish(new UserUpdatedEvent(user));
TempData[WellKnownTempData.SuccessMessage] = "Your profile has been updated"; TempData[WellKnownTempData.SuccessMessage] = "Your profile has been updated";
} }
else else
@ -348,6 +351,7 @@ namespace BTCPayServer.Controllers
} }
await _userService.DeleteUserAndAssociatedData(user); await _userService.DeleteUserAndAssociatedData(user);
_eventAggregator.Publish(new UserDeletedEvent(user));
TempData[WellKnownTempData.SuccessMessage] = "Account successfully deleted."; TempData[WellKnownTempData.SuccessMessage] = "Account successfully deleted.";
await _signInManager.SignOutAsync(); await _signInManager.SignOutAsync();
return RedirectToAction(nameof(UIAccountController.Login), "UIAccount"); return RedirectToAction(nameof(UIAccountController.Login), "UIAccount");

View file

@ -0,0 +1,12 @@
using BTCPayServer.Data;
namespace BTCPayServer.Events;
public class UserDeletedEvent(ApplicationUser user) : UserEvent(user)
{
protected override string ToString()
{
return $"{base.ToString()} has been deleted";
}
}

View file

@ -0,0 +1,13 @@
using BTCPayServer.Data;
namespace BTCPayServer.Events;
public class UserEvent(ApplicationUser user)
{
public ApplicationUser User { get; } = user;
protected new virtual string ToString()
{
return $"UserEvent: User \"{user.Email}\" ({user.Id})";
}
}

View file

@ -0,0 +1,11 @@
using BTCPayServer.Data;
namespace BTCPayServer.Events;
public class UserUpdatedEvent(ApplicationUser user) : UserEvent(user)
{
protected override string ToString()
{
return $"{base.ToString()} has been updated";
}
}