* Extended functionalities
* Added different UIs
This commit is contained in:
68
MealPlan.Api/Services/DbRefreshTokenStore.cs
Normal file
68
MealPlan.Api/Services/DbRefreshTokenStore.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using MealPlan.Api.Data;
|
||||
using MealPlan.Api.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace MealPlan.Api.Services;
|
||||
|
||||
/// <summary>Persists refresh tokens in PostgreSQL (survives API restarts).</summary>
|
||||
public class DbRefreshTokenStore : IRefreshTokenStore
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public DbRefreshTokenStore(IServiceScopeFactory scopeFactory) => _scopeFactory = scopeFactory;
|
||||
|
||||
public void Add(RefreshToken token)
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
db.RefreshTokens.Add(new RefreshTokenEntity
|
||||
{
|
||||
Token = token.Token,
|
||||
UserId = Guid.Parse(token.UserId),
|
||||
ExpiresAtUtc = token.ExpiresAtUtc,
|
||||
CreatedAtUtc = token.CreatedAtUtc,
|
||||
IsRevoked = false,
|
||||
});
|
||||
db.SaveChanges();
|
||||
}
|
||||
|
||||
public RefreshToken? Get(string token)
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
var entity = db.RefreshTokens.AsNoTracking().FirstOrDefault(t => t.Token == token);
|
||||
return entity is null ? null : Map(entity);
|
||||
}
|
||||
|
||||
public RefreshToken? Revoke(string token)
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
var entity = db.RefreshTokens.FirstOrDefault(t => t.Token == token);
|
||||
if (entity is null) return null;
|
||||
var wasActive = entity.IsActive;
|
||||
entity.IsRevoked = true;
|
||||
db.SaveChanges();
|
||||
return wasActive ? Map(entity) : null;
|
||||
}
|
||||
|
||||
public void RemoveExpired()
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
var cutoff = DateTime.UtcNow;
|
||||
db.RefreshTokens
|
||||
.Where(t => t.IsRevoked || t.ExpiresAtUtc <= cutoff)
|
||||
.ExecuteDelete();
|
||||
}
|
||||
|
||||
private static RefreshToken Map(RefreshTokenEntity entity) => new()
|
||||
{
|
||||
Token = entity.Token,
|
||||
UserId = entity.UserId.ToString(),
|
||||
ExpiresAtUtc = entity.ExpiresAtUtc,
|
||||
CreatedAtUtc = entity.CreatedAtUtc,
|
||||
IsRevoked = entity.IsRevoked,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user