fix switch club and RefreshSign
This commit is contained in:
parent
7a5580e57d
commit
3b65f9f1cd
|
|
@ -52,6 +52,15 @@ namespace Koogle.Application.DTOs
|
||||||
public string ConfirmPassword { get; set; } = "";
|
public string ConfirmPassword { get; set; } = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// From DTO for switching session from one club to another
|
||||||
|
/// </summary>
|
||||||
|
public class SwitchClubFormDto
|
||||||
|
{
|
||||||
|
public Guid UserProfileId { get; set; }
|
||||||
|
|
||||||
|
public Guid ClubId { get; set; }
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DTO for user registration.
|
/// DTO for user registration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -709,6 +709,22 @@ public class UserService : IUserService
|
||||||
|
|
||||||
profile.CurrentClubId = clubId;
|
profile.CurrentClubId = clubId;
|
||||||
await _appDb.SaveChangesAsync(ct);
|
await _appDb.SaveChangesAsync(ct);
|
||||||
|
|
||||||
|
// Refresh signin to update claims with new club
|
||||||
|
var identityUser = await _userManager.FindByIdAsync(profile.IdentityUserId.ToString());
|
||||||
|
if (identityUser != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await _signInManager.RefreshSignInAsync(identityUser);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
|
@using System.Net
|
||||||
@using Fluxor
|
@using Fluxor
|
||||||
|
@using Koogle.Application.DTOs
|
||||||
@using Koogle.Web.Store.AuthState
|
@using Koogle.Web.Store.AuthState
|
||||||
@using Koogle.Application.Interfaces
|
@using Koogle.Application.Interfaces
|
||||||
|
|
||||||
@inject IState<AuthState> AuthState
|
@inject IState<AuthState> AuthState
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
|
@inject HttpClient HttpClient;
|
||||||
|
@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Antiforgery
|
||||||
|
@inject IHttpContextAccessor HttpContextAccessor
|
||||||
|
@inject IDispatcher Dispatcher
|
||||||
|
|
||||||
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
@inherits Fluxor.Blazor.Web.Components.FluxorComponent
|
||||||
|
|
||||||
|
|
@ -22,10 +28,10 @@
|
||||||
@foreach (var club in AuthState.Value.AvailableClubs)
|
@foreach (var club in AuthState.Value.AvailableClubs)
|
||||||
{
|
{
|
||||||
<MudMenuItem OnClick="@(() => SwitchClubAsync(club.ClubId))"
|
<MudMenuItem OnClick="@(() => SwitchClubAsync(club.ClubId))"
|
||||||
Disabled="@(club.ClubId == AuthState.Value.CurrentClub?.ClubId)">
|
Disabled="@(club.ClubId == AuthState.Value.CurrentClub?.ClubId)">
|
||||||
@if (club.ClubId == AuthState.Value.CurrentClub?.ClubId)
|
@if (club.ClubId == AuthState.Value.CurrentClub?.ClubId)
|
||||||
{
|
{
|
||||||
<MudIcon Icon="@Icons.Material.Filled.Check" Size="Size.Small" Class="mr-2" />
|
<MudIcon Icon="@Icons.Material.Filled.Check" Size="Size.Small" Class="mr-2"/>
|
||||||
}
|
}
|
||||||
@club.ClubName
|
@club.ClubName
|
||||||
</MudMenuItem>
|
</MudMenuItem>
|
||||||
|
|
@ -47,23 +53,64 @@ else if (AuthState.Value.IsAuthenticated && AuthState.Value.HasNoClub)
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string _antiToken;
|
||||||
|
|
||||||
|
protected override void OnAfterRender(bool firstRender)
|
||||||
|
{
|
||||||
|
if (firstRender)
|
||||||
|
{
|
||||||
|
var http = HttpContextAccessor.HttpContext!;
|
||||||
|
var tokens = Antiforgery.GetAndStoreTokens(http);
|
||||||
|
_antiToken = tokens.RequestToken!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SwitchClubAsync(Guid clubId)
|
private async Task SwitchClubAsync(Guid clubId)
|
||||||
{
|
{
|
||||||
if (AuthState.Value.CurrentUser == null)
|
if (AuthState.Value.CurrentUser == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var model = new SwitchClubFormDto()
|
||||||
|
{
|
||||||
|
ClubId = clubId,
|
||||||
|
UserProfileId = AuthState.Value.CurrentUser.ProfileId
|
||||||
|
};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var success = await UserService.SwitchClubAsync(AuthState.Value.CurrentUser.ProfileId, clubId);
|
HttpClient.DefaultRequestHeaders.Remove("RequestVerificationToken");
|
||||||
if (success)
|
HttpClient.DefaultRequestHeaders.Add(
|
||||||
{
|
"RequestVerificationToken",
|
||||||
// Force page reload to refresh claims
|
_antiToken
|
||||||
NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
|
);
|
||||||
}
|
|
||||||
|
var basepath = NavigationManager.BaseUri;
|
||||||
|
var url = $"{basepath}auth/switch-club";
|
||||||
|
await HttpClient.PostAsJsonAsync(url, model);
|
||||||
|
|
||||||
|
// Dispatcher.Dispatch(new AuthState.InitializeAuthSuccessAction(model.UserProfileId, model.ClubId, roles));
|
||||||
|
|
||||||
|
|
||||||
|
NavigationManager.NavigateTo("/dashboard", forceLoad: true);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Club switch failed: {ex.Message}");
|
Console.WriteLine(e);
|
||||||
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// var success = await UserService.SwitchClubAsync(AuthState.Value.CurrentUser.ProfileId, clubId);
|
||||||
|
// if (success)
|
||||||
|
// {
|
||||||
|
// // Force page reload to refresh claims
|
||||||
|
// NavigationManager.NavigateTo(NavigationManager.Uri, forceLoad: true);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"Club switch failed: {ex.Message}");
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using Koogle.Web.Store.AuthState;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using static QRCoder.PayloadGenerator;
|
||||||
|
|
||||||
namespace Koogle.Web.Controllers
|
namespace Koogle.Web.Controllers
|
||||||
{
|
{
|
||||||
|
|
@ -18,7 +19,8 @@ namespace Koogle.Web.Controllers
|
||||||
/// Aus dem Grund werden Login/Logout Aktionen hier im MVC Controller mit einem "normalen" Post-Request abgewickelt.
|
/// Aus dem Grund werden Login/Logout Aktionen hier im MVC Controller mit einem "normalen" Post-Request abgewickelt.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[Microsoft.AspNetCore.Mvc.Route("auth")]
|
[Microsoft.AspNetCore.Mvc.Route("auth")]
|
||||||
public class AuthController(IDispatcher dispatcher, IUserService userService, IEmailService emailService) : Controller
|
public class AuthController(IDispatcher dispatcher, IUserService userService, IEmailService emailService)
|
||||||
|
: Controller
|
||||||
{
|
{
|
||||||
private readonly IDispatcher _dispatcher = dispatcher;
|
private readonly IDispatcher _dispatcher = dispatcher;
|
||||||
private readonly IUserService _userService = userService;
|
private readonly IUserService _userService = userService;
|
||||||
|
|
@ -37,6 +39,7 @@ namespace Koogle.Web.Controllers
|
||||||
// (club-setup if no clubs, dashboard otherwise)
|
// (club-setup if no clubs, dashboard otherwise)
|
||||||
return LocalRedirect(result.RedirectUrl ?? "/dashboard");
|
return LocalRedirect(result.RedirectUrl ?? "/dashboard");
|
||||||
}
|
}
|
||||||
|
|
||||||
return LocalRedirect("/account/login?error=true");
|
return LocalRedirect("/account/login?error=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,8 +70,10 @@ namespace Koogle.Web.Controllers
|
||||||
// If invite token was provided, redirect to join page
|
// If invite token was provided, redirect to join page
|
||||||
if (!string.IsNullOrWhiteSpace(input.InviteToken))
|
if (!string.IsNullOrWhiteSpace(input.InviteToken))
|
||||||
{
|
{
|
||||||
return LocalRedirect($"/account/login?registered=true&invite={Uri.EscapeDataString(input.InviteToken)}");
|
return LocalRedirect(
|
||||||
|
$"/account/login?registered=true&invite={Uri.EscapeDataString(input.InviteToken)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
return LocalRedirect("/account/login?registered=true");
|
return LocalRedirect("/account/login?registered=true");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,7 +98,8 @@ namespace Koogle.Web.Controllers
|
||||||
if (token != null)
|
if (token != null)
|
||||||
{
|
{
|
||||||
var baseUrl = $"{Request.Scheme}://{Request.Host}";
|
var baseUrl = $"{Request.Scheme}://{Request.Host}";
|
||||||
var resetUrl = $"{baseUrl}/account/reset-password?email={Uri.EscapeDataString(email)}&token={Uri.EscapeDataString(token)}";
|
var resetUrl =
|
||||||
|
$"{baseUrl}/account/reset-password?email={Uri.EscapeDataString(email)}&token={Uri.EscapeDataString(token)}";
|
||||||
await _emailService.SendPasswordResetEmailAsync(email, resetUrl);
|
await _emailService.SendPasswordResetEmailAsync(email, resetUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +116,8 @@ namespace Koogle.Web.Controllers
|
||||||
// Validate password confirmation
|
// Validate password confirmation
|
||||||
if (input.NewPassword != input.ConfirmPassword)
|
if (input.NewPassword != input.ConfirmPassword)
|
||||||
{
|
{
|
||||||
return LocalRedirect($"/account/reset-password?email={Uri.EscapeDataString(input.Email)}&token={Uri.EscapeDataString(input.Token)}&error=PasswordMismatch");
|
return LocalRedirect(
|
||||||
|
$"/account/reset-password?email={Uri.EscapeDataString(input.Email)}&token={Uri.EscapeDataString(input.Token)}&error=PasswordMismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
var dto = new ResetPasswordDto
|
var dto = new ResetPasswordDto
|
||||||
|
|
@ -127,9 +134,20 @@ namespace Koogle.Web.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
var errors = string.Join(",", result.Errors.Select(e => e.Code));
|
var errors = string.Join(",", result.Errors.Select(e => e.Code));
|
||||||
return LocalRedirect($"/account/reset-password?email={Uri.EscapeDataString(input.Email)}&token={Uri.EscapeDataString(input.Token)}&error={errors}");
|
return LocalRedirect(
|
||||||
|
$"/account/reset-password?email={Uri.EscapeDataString(input.Email)}&token={Uri.EscapeDataString(input.Token)}&error={errors}");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handles switch club.
|
||||||
|
/// </summary>
|
||||||
|
[HttpPost("switch-club")]
|
||||||
|
//[ValidateAntiForgeryToken]
|
||||||
|
public async Task<IActionResult> SwitchClub([FromBody] SwitchClubFormDto input)
|
||||||
|
{
|
||||||
|
await _userService.SwitchClubAsync(input.UserProfileId, input.ClubId);
|
||||||
|
return LocalRedirect($"/dashboard");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.3 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1016 KiB |
Loading…
Reference in New Issue