Skip to content

Commit

Permalink
Refactor Boilerplate signalr implementation (#8557)
Browse files Browse the repository at this point in the history
  • Loading branch information
ysmoradi committed Sep 14, 2024
1 parent a35c79a commit 2dada3c
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@
{
"condition": "(signalr != true)",
"exclude": [
"src/Server/Boilerplate.Server.Api/Hubs/**"
"src/Server/Boilerplate.Server.Api/Hubs/**",
"src/Client/Boilerplate.Client.Core/Components/SignalRHandler.cs"
]
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,4 @@
<div class="content-container danger-panel">
<DeleteAccountSection />
</div>
</div>

@*#if (signalr == true)*@
<BitSnackBar @ref="snackBar" />
@*#endif*@
</div>
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
//+:cnd:noEmit
//#if (signalr == true)
using Microsoft.AspNetCore.SignalR.Client;
//#endif
using Boilerplate.Shared.Dtos.Identity;
using Boilerplate.Shared.Controllers.Identity;

Expand All @@ -12,10 +9,6 @@ public partial class ProfilePage
{
private UserDto? user;
private bool isLoading;
//#if (signalr == true)
private HubConnection? hubConnection;
private BitSnackBar snackBar = default!;
//#endif

[AutoInject] private IUserController userController = default!;

Expand All @@ -35,40 +28,4 @@ protected override async Task OnInitAsync()

await base.OnInitAsync();
}

//#if (signalr == true)
protected async override Task OnAfterFirstRenderAsync()
{
await base.OnAfterFirstRenderAsync();

var access_token = await AuthTokenProvider.GetAccessTokenAsync();

hubConnection = new HubConnectionBuilder()
.WithUrl($"{Configuration.GetServerAddress()}/identity-hub?access_token={access_token}")
.Build();

hubConnection.On<UserSessionDto>("NewUserSession", async (userSession) =>
{
await snackBar.Info(Localizer[nameof(AppStrings.NewUserSessionSnackbarTitle)], Localizer[nameof(AppStrings.DeviceDetails), userSession.Device!]);

// The following code block is not required for Bit.BlazorUI components to perform UI changes. However, it may be necessary in other scenarios.
/*await InvokeAsync(async () =>
{
StateHasChanged();
});*/
});

await hubConnection.StartAsync();
}

protected override async ValueTask DisposeAsync(bool disposing)
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}

await base.DisposeAsync(disposing);
}
//#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
using Boilerplate.Shared.Dtos.Identity;
using Microsoft.AspNetCore.SignalR.Client;

namespace Boilerplate.Client.Core.Components;

public partial class SignalRHandler : AppComponentBase
{
[AutoInject] private MessageBoxService messageBoxService = default!;
[AutoInject] private AuthenticationManager authManager = default!;

private HubConnection? hubConnection;

protected async override Task OnAfterFirstRenderAsync()
{
await base.OnAfterFirstRenderAsync();

authManager.AuthenticationStateChanged += IsUserAuthenticated;

await ConnectSignalR();
}

private async void IsUserAuthenticated(Task<AuthenticationState> task)
{
try
{
await ConnectSignalR();
}
catch (Exception ex)
{
ExceptionHandler.Handle(ex);
}
}

private async Task ConnectSignalR()
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}

var access_token = await AuthTokenProvider.GetAccessTokenAsync();

hubConnection = new HubConnectionBuilder()
.WithUrl($"{Configuration.GetServerAddress()}/identity-hub?access_token={access_token}")
.Build();

hubConnection.On<string>("TwoFactorToken", async (token) =>
{
await messageBoxService.Show(Localizer[nameof(AppStrings.TwoFactorTokenPushText), token]);

// The following code block is not required for Bit.BlazorUI components to perform UI changes. However, it may be necessary in other scenarios.
/*await InvokeAsync(async () =>
{
StateHasChanged();
});*/

// You can also leverage IPubSubService to notify other components in the application.
});

await hubConnection.StartAsync(CurrentCancellationToken);
}

protected override async ValueTask DisposeAsync(bool disposing)
{
if (hubConnection is not null)
{
await hubConnection.DisposeAsync();
}

await base.DisposeAsync(disposing);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<CascadingAuthenticationState>
@*+:cnd:noEmit*@
<CascadingAuthenticationState>
<AuthenticationStateLogger />
@*#if (signalr == true)*@
<SignalRHandler />
@*#endif*@
<LayoutView Layout="@typeof(MainLayout)">
<Router AppAssembly="@GetType().Assembly"
AdditionalAssemblies="@(AssemblyLoadContext.Default.Assemblies.Where(asm => asm.GetName().Name?.Contains("Boilerplate") is true))">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public partial class IdentityController : AppControllerBase, IIdentityController
[AutoInject] private IOptionsMonitor<BearerTokenOptions> bearerTokenOptions = default!;
[AutoInject] private IUserClaimsPrincipalFactory<User> userClaimsPrincipalFactory = default!;
//#if (signalr == true)
[AutoInject] private IHubContext<IdentityHub> identityHubContext = default!;
[AutoInject] private IHubContext<AppHub> appHubContext = default!;
//#endif

//#if (captcha == "reCaptcha")
Expand Down Expand Up @@ -146,10 +146,6 @@ public async Task SignIn(SignInRequestDto request, CancellationToken cancellatio
var addUserSessionResult = await userManager.UpdateAsync(user);
if (addUserSessionResult.Succeeded is false)
throw new ResourceValidationException(addUserSessionResult.Errors.Select(e => new LocalizedString(e.Code, e.Description)).ToArray());

//#if (signalr == true)
await identityHubContext.Clients.User(user.Id.ToString()).SendAsync("NewUserSession", userSession, cancellationToken);
//#endif
}

/// <summary>
Expand Down Expand Up @@ -301,6 +297,10 @@ async Task SendSms()
}
}

//#if (signalr == true)
await appHubContext.Clients.User(user.Id.ToString()).SendAsync("TwoFactorToken", token, cancellationToken);
//#endif

await Task.WhenAll([SendEmail(), SendSms()]);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Boilerplate.Server.Api.Hubs;

[Authorize]
public partial class IdentityHub : Hub
[AllowAnonymous]
public partial class AppHub : Hub
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public static void ConfiureMiddlewares(this WebApplication app)
}).WithTags("Test");

//#if (signalr == true)
app.MapHub<Hubs.IdentityHub>("/identity-hub");
app.MapHub<Hubs.AppHub>("/identity-hub");
//#endif

app.MapControllers().RequireAuthorization();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ private static void ConfiureMiddlewares(this WebApplication app)
}).WithTags("Test");

//#if (signalr == true)
app.MapHub<Api.Hubs.IdentityHub>("/identity-hub");
app.MapHub<Api.Hubs.AppHub>("/identity-hub");
//#endif

app.MapControllers().RequireAuthorization();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,8 @@
</data>
<!--#endif-->
<!--#if (signalr == true) -->
<data name="NewUserSessionSnackbarTitle" xml:space="preserve">
<value>لاگین جدید</value>
</data>
<data name="DeviceDetails" xml:space="preserve">
<value>دستگاه: {0}</value>
<data name="TwoFactorTokenPushText" xml:space="preserve">
<value>{0} توکن احراز هویت مرحله دو شما است در Boilerplate.</value>
</data>
<!--#endif-->
<data name="FullName" xml:space="preserve">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,8 @@
</data>
<!--#endif-->
<!--#if (signalr == true) -->
<data name="NewUserSessionSnackbarTitle" xml:space="preserve">
<value>Nouvelle session !</value>
</data>
<data name="DeviceDetails" xml:space="preserve">
<value>Appareil : {0}</value>
<data name="TwoFactorTokenPushText" xml:space="preserve">
<value>{0} est votre jeton à deux facteurs dans Boilerplate.</value>
</data>
<!--#endif-->
<data name="FullName" xml:space="preserve">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,8 @@
</data>
<!--#endif-->
<!--#if (signalr == true) -->
<data name="NewUserSessionSnackbarTitle" xml:space="preserve">
<value>New session!</value>
</data>
<data name="DeviceDetails" xml:space="preserve">
<value>Device: {0}</value>
<data name="TwoFactorTokenPushText" xml:space="preserve">
<value>{0} is your two factor token in Boilerplate.</value>
</data>
<!--#endif-->
<data name="FullName" xml:space="preserve">
Expand Down

0 comments on commit 2dada3c

Please sign in to comment.