< Summary

Information
Class: Chronicis.Client.Services.UserInfo
Assembly: Chronicis.Client
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Client/Services/AuthService.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 4
Coverable lines: 4
Total lines: 82
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Auth0UserId()100%210%
get_Email()100%210%
get_DisplayName()100%210%
get_AvatarUrl()100%210%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Client/Services/AuthService.cs

#LineLine coverage
 1using System.Security.Claims;
 2using Microsoft.AspNetCore.Components.Authorization;
 3
 4namespace Chronicis.Client.Services;
 5
 6/// <summary>
 7/// User information retrieved from Auth0
 8/// </summary>
 9public class UserInfo
 10{
 011    public string Auth0UserId { get; set; } = string.Empty;
 012    public string Email { get; set; } = string.Empty;
 013    public string DisplayName { get; set; } = string.Empty;
 014    public string? AvatarUrl { get; set; }
 15}
 16
 17/// <summary>
 18/// Implementation of authentication service using ASP.NET Core authentication
 19/// </summary>
 20public class AuthService : IAuthService
 21{
 22    private readonly AuthenticationStateProvider _authenticationStateProvider;
 23    private UserInfo? _cachedUser;
 24
 25    public AuthService(AuthenticationStateProvider authenticationStateProvider)
 26    {
 27        _authenticationStateProvider = authenticationStateProvider;
 28    }
 29
 30    public async Task<UserInfo?> GetCurrentUserAsync()
 31    {
 32        if (_cachedUser != null)
 33        {
 34            return _cachedUser;
 35        }
 36
 37        var authState = await _authenticationStateProvider.GetAuthenticationStateAsync();
 38        var user = authState.User;
 39
 40        if (!user.Identity?.IsAuthenticated ?? true)
 41        {
 42            return null;
 43        }
 44
 45        const string customNamespace = "https://chronicis.app";
 46
 47        // Extract claims from Auth0 token
 48        var auth0UserId = user.FindFirst(ClaimTypes.NameIdentifier)?.Value
 49                         ?? user.FindFirst("sub")?.Value
 50                         ?? "";
 51
 52        var email = user.FindFirst($"{customNamespace}/email")?.Value
 53                   ?? user.FindFirst(ClaimTypes.Email)?.Value
 54                   ?? user.FindFirst("email")?.Value
 55                   ?? "";
 56
 57        var displayName = user.FindFirst($"{customNamespace}/name")?.Value
 58                         ?? user.FindFirst(ClaimTypes.Name)?.Value
 59                         ?? user.FindFirst("name")?.Value
 60                         ?? user.FindFirst("preferred_username")?.Value
 61                         ?? "Unknown User";
 62
 63        var avatarUrl = user.FindFirst($"{customNamespace}/picture")?.Value
 64                       ?? user.FindFirst("picture")?.Value;
 65
 66        _cachedUser = new UserInfo
 67        {
 68            Auth0UserId = auth0UserId,
 69            Email = email,
 70            DisplayName = displayName,
 71            AvatarUrl = avatarUrl
 72        };
 73
 74        return _cachedUser;
 75    }
 76
 77    public async Task<bool> IsAuthenticatedAsync()
 78    {
 79        var authState = await _authenticationStateProvider.GetAuthenticationStateAsync();
 80        return authState.User.Identity?.IsAuthenticated ?? false;
 81    }
 82}