2026-05-27 21:33:48 +03:30
|
|
|
using System.Text.Json;
|
|
|
|
|
using StackExchange.Redis;
|
|
|
|
|
|
|
|
|
|
namespace Meezi.API.Services;
|
|
|
|
|
|
|
|
|
|
public record RefreshTokenPayload(
|
|
|
|
|
string UserId,
|
|
|
|
|
string CafeId,
|
|
|
|
|
string Role,
|
|
|
|
|
string PlanTier,
|
|
|
|
|
string Language,
|
2026-05-31 11:06:24 +03:30
|
|
|
string Actor = Meezi.Core.Constants.MeeziActorKinds.Merchant,
|
|
|
|
|
string? ActiveBranchId = null);
|
2026-05-27 21:33:48 +03:30
|
|
|
|
|
|
|
|
public interface IRefreshTokenStore
|
|
|
|
|
{
|
|
|
|
|
Task StoreAsync(string refreshToken, RefreshTokenPayload payload, TimeSpan ttl, CancellationToken cancellationToken = default);
|
|
|
|
|
Task<RefreshTokenPayload?> GetAsync(string refreshToken, CancellationToken cancellationToken = default);
|
|
|
|
|
Task RevokeAsync(string refreshToken, CancellationToken cancellationToken = default);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class RedisRefreshTokenStore : IRefreshTokenStore
|
|
|
|
|
{
|
|
|
|
|
private readonly IConnectionMultiplexer _redis;
|
|
|
|
|
|
|
|
|
|
public RedisRefreshTokenStore(IConnectionMultiplexer redis)
|
|
|
|
|
{
|
|
|
|
|
_redis = redis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static string Key(string token) => $"refresh:{token}";
|
|
|
|
|
|
|
|
|
|
public async Task StoreAsync(string refreshToken, RefreshTokenPayload payload, TimeSpan ttl, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
var db = _redis.GetDatabase();
|
|
|
|
|
var json = JsonSerializer.Serialize(payload);
|
|
|
|
|
await db.StringSetAsync(Key(refreshToken), json, ttl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<RefreshTokenPayload?> GetAsync(string refreshToken, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
var db = _redis.GetDatabase();
|
|
|
|
|
var value = await db.StringGetAsync(Key(refreshToken));
|
|
|
|
|
if (value.IsNullOrEmpty)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return JsonSerializer.Deserialize<RefreshTokenPayload>(value.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task RevokeAsync(string refreshToken, CancellationToken cancellationToken = default)
|
|
|
|
|
{
|
|
|
|
|
var db = _redis.GetDatabase();
|
|
|
|
|
await db.KeyDeleteAsync(Key(refreshToken));
|
|
|
|
|
}
|
|
|
|
|
}
|