Refactor token handling in ConfirmAsync method for improved backward compatibility and introduce FindTokenAsync helper method
This commit is contained in:
parent
e4af8f067f
commit
db50810d15
@ -74,10 +74,12 @@ public sealed class NewsletterService : INewsletterService
|
|||||||
|
|
||||||
public async Task<SubscriptionDto?> ConfirmAsync(string token)
|
public async Task<SubscriptionDto?> ConfirmAsync(string token)
|
||||||
{
|
{
|
||||||
var tokenHash = HashToken(token, ConfirmTokenPurpose);
|
var confirmToken = await FindTokenAsync(token, ConfirmTokenPurpose);
|
||||||
var confirmToken = await _dbContext.UnsubscribeTokens
|
if (confirmToken is null && token.Contains(' '))
|
||||||
.Include(t => t.Subscription)
|
{
|
||||||
.FirstOrDefaultAsync(t => t.TokenHash == tokenHash && t.ConsumedAt == null);
|
// Backward compatibility: legacy Base64 tokens may decode '+' as space in query string.
|
||||||
|
confirmToken = await FindTokenAsync(token.Replace(' ', '+'), ConfirmTokenPurpose);
|
||||||
|
}
|
||||||
|
|
||||||
if (confirmToken?.Subscription is null)
|
if (confirmToken?.Subscription is null)
|
||||||
{
|
{
|
||||||
@ -170,7 +172,7 @@ public sealed class NewsletterService : INewsletterService
|
|||||||
private static string CreateToken()
|
private static string CreateToken()
|
||||||
{
|
{
|
||||||
var bytes = RandomNumberGenerator.GetBytes(32);
|
var bytes = RandomNumberGenerator.GetBytes(32);
|
||||||
return Convert.ToBase64String(bytes);
|
return Convert.ToBase64String(bytes).TrimEnd('=').Replace('+', '-').Replace('/', '_');
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string HashToken(string token, string purpose)
|
private static string HashToken(string token, string purpose)
|
||||||
@ -200,4 +202,12 @@ public sealed class NewsletterService : INewsletterService
|
|||||||
subscription.Preferences.RootElement.Clone(),
|
subscription.Preferences.RootElement.Clone(),
|
||||||
subscription.CreatedAt);
|
subscription.CreatedAt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Task<UnsubscribeToken?> FindTokenAsync(string token, string purpose)
|
||||||
|
{
|
||||||
|
var tokenHash = HashToken(token, purpose);
|
||||||
|
return _dbContext.UnsubscribeTokens
|
||||||
|
.Include(t => t.Subscription)
|
||||||
|
.FirstOrDefaultAsync(t => t.TokenHash == tokenHash && t.ConsumedAt == null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user