using Fitness_core_BE.Auth; using Fitness_core_BE.Helpers; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.SignalR; namespace Fitness_core_BE.Hubs { /// /// Tenant-isolated browser channel for device inventory, attendance, and access /// state notifications. The client id is always resolved from the authenticated /// user and is never accepted from the browser. /// [Authorize(AuthenticationSchemes = UserJwtDefaults.AuthenticationScheme)] public sealed class AccessHub : Hub { private readonly UserRoleHelper _userRoleHelper; public AccessHub(UserRoleHelper userRoleHelper) { _userRoleHelper = userRoleHelper; } public static string ClientGroup(Guid clientId) => $"access-client-{clientId:N}"; public override async Task OnConnectedAsync() { var userIdValue = Context.User?.FindFirst("UserId")?.Value; if (!Guid.TryParse(userIdValue, out var userId)) throw new HubException("Authenticated user id is missing."); var clientId = await _userRoleHelper.GetClientId(userId); await Groups.AddToGroupAsync(Context.ConnectionId, ClientGroup(clientId)); await base.OnConnectedAsync(); } } }