Add JWT, OTP, and caching features

Upgraded projects to .NET 9.0 and added new projects `KBR.Cache`, `KBR.Shared`, and `KBR.Shared.Lite` to the solution. Introduced JWT authentication and OTP handling with new models, services, and configuration options. Updated database schema with new entities `Users` and `RefreshTokens`, and added migrations for schema changes. Implemented caching strategies using `AppDistributedCache` with support for in-memory, SQL Server, and Redis. Enhanced email handling with `MailHelpers` for domain replacement. Updated controllers, repositories, and configuration files to support new features.
This commit is contained in:
2025-11-22 06:52:59 +05:30
parent 912457755e
commit 3a7edb23c7
68 changed files with 13506 additions and 147 deletions
@@ -0,0 +1,28 @@
using KBR.Shared.Lite.Extensions;
namespace KBR.Shared.Cache
{
public static class CacheExtensions
{
public static byte[] ToByteArray(this object obj)
{
if (obj is not null)
{
return JsonExtensions.ToUtf8Bytes(obj);
}
return Array.Empty<byte>();
}
public static T? FromByteArray<T>(this byte[] byteArray)
where T : class
{
if (byteArray is null)
{
return default;
}
return JsonExtensions.ToObject<T>(byteArray);
}
}
}
+21
View File
@@ -0,0 +1,21 @@
using KBR.Shared.Cache.Models;
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Shared.Cache
{
public static class CacheHelpers
{
private static readonly string _userSessions = nameof(_userSessions);
private static string UserSessionsKey(string key) => $"{_userSessions}-{key}";
public static async Task SetUserSessionsCacheAsync(IAppDistributedCache cache, string userId, UserSessionModel sessions, CancellationToken cancellationToken = default)
{
await cache.SetAsync(UserSessionsKey(userId), sessions, GetOptions(), cancellationToken);
}
private static DistributedCacheEntryOptions GetOptions()
{
return new DistributedCacheEntryOptions { AbsoluteExpiration = DateTime.MaxValue };
}
}
}
@@ -0,0 +1,27 @@
using Microsoft.Extensions.Caching.Distributed;
namespace KBR.Shared.Cache
{
public interface IAppDistributedCache
{
T Get<T>(string key)
where T : class;
Task<T> GetAsync<T>(string key, CancellationToken cancellationToken = default)
where T : class;
void Remove(string key);
Task RemoveAsync(string key, CancellationToken cancellationToken = default);
void Set<T>(string key, T obj, DistributedCacheEntryOptions? options = default);
Task SetAsync<T>(string key, T obj, DistributedCacheEntryOptions? options = default, CancellationToken cancellationToken = default);
TItem GetOrCreate<TItem>(string key, Func<TItem> factory)
where TItem : class;
Task<TItem> GetOrCreateAsync<TItem>(string key, Func<Task<TItem>> factory, CancellationToken cancellationToken = default)
where TItem : class;
}
}
@@ -0,0 +1,15 @@
namespace KBR.Shared.Cache.Models
{
public class UserSessionModel
{
public UserSessionModel()
{
Alive = new();
Killed = new();
}
public List<string> Alive { get; set; }
public List<string> Killed { get; set; }
}
}