initial commit

This commit is contained in:
2026-07-21 14:35:37 +07:00
commit 0027997ff9
798 changed files with 59083 additions and 0 deletions
@@ -0,0 +1,10 @@
namespace Indotalent.Infrastructure.Authentication.Identity;
public class CookieSettings
{
public string Name { get; set; } = string.Empty;
public string LoginPath { get; set; } = string.Empty;
public string LogoutPath { get; set; } = string.Empty;
public string AccessDeniedPath { get; set; } = string.Empty;
public int ExpireDays { get; set; }
}
@@ -0,0 +1,26 @@
using Indotalent.Data.Entities;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using System.Security.Claims;
namespace Indotalent.Infrastructure.Authentication.Identity;
public class CustomClaimsPrincipalFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
public CustomClaimsPrincipalFactory(
UserManager<ApplicationUser> userManager,
RoleManager<IdentityRole> roleManager,
IOptions<IdentityOptions> optionsAccessor)
: base(userManager, roleManager, optionsAccessor)
{
}
protected override async Task<ClaimsIdentity> GenerateClaimsAsync(ApplicationUser user)
{
var identity = await base.GenerateClaimsAsync(user);
identity.AddClaim(new Claim(ClaimTypes.GivenName, user.FullName ?? string.Empty));
return identity;
}
}
@@ -0,0 +1,8 @@
namespace Indotalent.Infrastructure.Authentication.Identity;
public class DefaultAdminSettings
{
public string Email { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public string FullName { get; set; } = string.Empty;
}
@@ -0,0 +1,16 @@
using Indotalent.Data.Entities;
namespace Indotalent.Infrastructure.Authentication.Identity;
public static class DefaultUserConfig
{
public static ApplicationUser GetAdminUser(DefaultAdminSettings settings) => new()
{
FullName = settings.FullName,
UserName = settings.Email,
Email = settings.Email,
EmailConfirmed = true,
CreatedAt = DateTime.Now,
IsActive = true
};
}
@@ -0,0 +1,56 @@
using Indotalent.Data.Entities;
using Indotalent.Infrastructure.Authentication.Identity;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Components.Server;
using Microsoft.AspNetCore.Identity;
using System.Security.Claims;
internal sealed class IdentityRevalidatingAuthenticationStateProvider : RevalidatingServerAuthenticationStateProvider
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly TokenProvider _tokenProvider;
public IdentityRevalidatingAuthenticationStateProvider(
ILoggerFactory loggerFactory,
IServiceScopeFactory scopeFactory,
IHttpContextAccessor httpContextAccessor,
TokenProvider tokenProvider)
: base(loggerFactory)
{
_scopeFactory = scopeFactory;
_httpContextAccessor = httpContextAccessor;
_tokenProvider = tokenProvider;
var context = httpContextAccessor.HttpContext;
if (context != null)
{
var token = context.Request.Cookies["X-Auth-Token"];
var refreshToken = context.Request.Cookies["X-Refresh-Token"];
if (!string.IsNullOrEmpty(token))
{
_tokenProvider.Token = token;
}
if (!string.IsNullOrEmpty(refreshToken))
{
_tokenProvider.RefreshToken = refreshToken;
}
}
}
protected override TimeSpan RevalidationInterval => TimeSpan.FromMinutes(30);
protected override async Task<bool> ValidateAuthenticationStateAsync(
AuthenticationState authenticationState, CancellationToken cancellationToken)
{
await using var scopeAsync = _scopeFactory.CreateAsyncScope();
var userManager = scopeAsync.ServiceProvider.GetRequiredService<UserManager<ApplicationUser>>();
return await ValidateSecurityStampAsync(userManager, authenticationState.User);
}
private async Task<bool> ValidateSecurityStampAsync(UserManager<ApplicationUser> userManager, ClaimsPrincipal principal)
{
var user = await userManager.GetUserAsync(principal);
return user != null;
}
}
@@ -0,0 +1,24 @@
using Indotalent.Infrastructure.Authentication.Firebase;
using Indotalent.Infrastructure.Authentication.Keycloak;
using Microsoft.Extensions.Options;
namespace Indotalent.Infrastructure.Authentication.Identity;
public class IdentityService(IOptions<IdentitySettingsModel> options)
{
private readonly IdentitySettingsModel _settings = options.Value;
public IdentitySettingsModel GetConfiguration() => _settings;
public DefaultAdminSettings GetDefaultAdmin() => _settings.DefaultAdmin;
public PasswordSettings GetPasswordPolicy() => _settings.Password;
public CookieSettings GetCookieSettings() => _settings.Cookies;
public SignInSettings GetSignInSettings() => _settings.SignIn;
public FirebaseSettingsModel GetFirebaseSettings() => _settings.SsoFirebase;
public KeycloakSettingsModel GetKeycloakSettings() => _settings.SsoKeycloak;
}
@@ -0,0 +1,14 @@
using Indotalent.Infrastructure.Authentication.Firebase;
using Indotalent.Infrastructure.Authentication.Keycloak;
namespace Indotalent.Infrastructure.Authentication.Identity;
public class IdentitySettingsModel
{
public PasswordSettings Password { get; set; } = new();
public CookieSettings Cookies { get; set; } = new();
public DefaultAdminSettings DefaultAdmin { get; set; } = new();
public SignInSettings SignIn { get; set; } = new();
public FirebaseSettingsModel SsoFirebase { get; set; } = new();
public KeycloakSettingsModel SsoKeycloak { get; set; } = new();
}
@@ -0,0 +1,9 @@
namespace Indotalent.Infrastructure.Authentication.Identity;
public class JwtSettingsModel
{
public string Key { get; set; } = string.Empty;
public string Issuer { get; set; } = string.Empty;
public string Audience { get; set; } = string.Empty;
public int DurationInMinutes { get; set; }
}
@@ -0,0 +1,11 @@
namespace Indotalent.Infrastructure.Authentication.Identity;
public class PasswordSettings
{
public bool RequireDigit { get; set; }
public int RequiredLength { get; set; }
public bool RequireNonAlphanumeric { get; set; }
public bool RequireUppercase { get; set; }
public bool RequireLowercase { get; set; }
public int RequiredUniqueChars { get; set; }
}
@@ -0,0 +1,6 @@
namespace Indotalent.Infrastructure.Authentication.Identity;
public class SignInSettings
{
public bool RequireConfirmedAccount { get; set; }
}
@@ -0,0 +1,7 @@
namespace Indotalent.Infrastructure.Authentication.Identity;
public class TokenProvider
{
public string? Token { get; set; }
public string? RefreshToken { get; set; }
}