shoc-backend/Api.SeaHavenIndustries/Helper/VendorPortalTokenService.cs

93 lines
3.2 KiB
C#
Raw Normal View History

using System.Security.Cryptography;
using Data.SeaHavenIndustries;
using Microsoft.EntityFrameworkCore;
namespace Api.SeaHavenIndustries.Helper
{
public class VendorPortalTokenService
{
private readonly ApplicationDbContext _db;
private readonly int _lifetimeDays;
public VendorPortalTokenService(ApplicationDbContext db, IConfiguration config)
{
_db = db;
_lifetimeDays = config.GetValue<int?>("VendorPortal:TokenLifetimeDays") ?? 365;
}
public async Task<VendorAccessToken> GetOrCreateActiveTokenAsync(int vendorId)
{
var now = DateTime.UtcNow;
var existing = await _db.VendorAccessTokens
.Where(t => t.VendorId == vendorId
&& t.RevokedAt == null
&& t.ExpiresAt > now
&& (t.IsDeleted == null || t.IsDeleted == false))
.OrderByDescending(t => t.IssuedAt)
.FirstOrDefaultAsync();
if (existing != null) return existing;
var token = new VendorAccessToken
{
VendorId = vendorId,
Token = GenerateToken(),
IssuedAt = now,
ExpiresAt = now.AddDays(_lifetimeDays),
CreatedDate = now
};
_db.VendorAccessTokens.Add(token);
await _db.SaveChangesAsync();
return token;
}
public async Task<Vendor?> ResolveVendorAsync(string? token)
{
if (string.IsNullOrWhiteSpace(token)) return null;
var now = DateTime.UtcNow;
var record = await _db.VendorAccessTokens
.Include(t => t.Vendor)
.FirstOrDefaultAsync(t => t.Token == token
&& t.RevokedAt == null
&& t.ExpiresAt > now
&& (t.IsDeleted == null || t.IsDeleted == false));
if (record?.Vendor == null) return null;
record.LastUsedAt = now;
await _db.SaveChangesAsync();
return record.Vendor;
}
public async Task<VendorAccessToken> RotateAsync(int vendorId)
{
var now = DateTime.UtcNow;
var active = await _db.VendorAccessTokens
.Where(t => t.VendorId == vendorId && t.RevokedAt == null)
.ToListAsync();
foreach (var t in active) t.RevokedAt = now;
await _db.SaveChangesAsync();
return await GetOrCreateActiveTokenAsync(vendorId);
}
public async Task RevokeAllAsync(int vendorId)
{
var now = DateTime.UtcNow;
var active = await _db.VendorAccessTokens
.Where(t => t.VendorId == vendorId && t.RevokedAt == null)
.ToListAsync();
foreach (var t in active) t.RevokedAt = now;
await _db.SaveChangesAsync();
}
private static string GenerateToken()
{
var bytes = RandomNumberGenerator.GetBytes(32);
return Convert.ToBase64String(bytes)
.Replace("+", "-")
.Replace("/", "_")
.TrimEnd('=');
}
}
}