fix: normalize Resend API key configuration
All checks were successful
deploy-socialize / image (push) Successful in 57s
deploy-socialize / deploy (push) Successful in 23s

This commit is contained in:
2026-05-06 15:36:49 -04:00
parent 1ae3188d34
commit 7a862a202a
2 changed files with 22 additions and 3 deletions

View File

@@ -79,6 +79,7 @@ http://<this-machine-lan-ip>:8080
For preprod deployment, configure the `POSTGRES_PASSWORD`, `RESEND_API_KEY`, For preprod deployment, configure the `POSTGRES_PASSWORD`, `RESEND_API_KEY`,
`RESEND_FROM_EMAIL`, and `JWT_SIGNING_KEY` Gitea secrets. `RESEND_FROM_EMAIL`, and `JWT_SIGNING_KEY` Gitea secrets.
The deploy workflow writes the remote `.env` file before running the server deploy script. The deploy workflow writes the remote `.env` file before running the server deploy script.
Use the raw Resend API key value for `RESEND_API_KEY`, without a `Bearer ` prefix.
## Solution ## Solution

View File

@@ -20,18 +20,24 @@ public class ResendEmailSender : IEmailSender
_httpClient = httpClientFactory.CreateClient(); _httpClient = httpClientFactory.CreateClient();
_options = options.Value; _options = options.Value;
if (string.IsNullOrWhiteSpace(_options.ApiKey)) string apiKey = NormalizeApiKey(_options.ApiKey);
string fromEmail = _options.FromEmail?.Trim() ?? string.Empty;
if (string.IsNullOrWhiteSpace(apiKey))
{ {
throw new InvalidOperationException("Emailer:ApiKey is required when using Resend email delivery."); throw new InvalidOperationException("Emailer:ApiKey is required when using Resend email delivery.");
} }
if (string.IsNullOrWhiteSpace(_options.FromEmail)) if (string.IsNullOrWhiteSpace(fromEmail))
{ {
throw new InvalidOperationException("Emailer:FromEmail is required when using Resend email delivery."); throw new InvalidOperationException("Emailer:FromEmail is required when using Resend email delivery.");
} }
_options.ApiKey = apiKey;
_options.FromEmail = fromEmail;
_httpClient.DefaultRequestHeaders.Authorization = _httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", _options.ApiKey); new AuthenticationHeaderValue("Bearer", apiKey);
_httpClient.DefaultRequestHeaders.Accept.Add( _httpClient.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json")); new MediaTypeWithQualityHeaderValue("application/json"));
@@ -53,4 +59,16 @@ public class ResendEmailSender : IEmailSender
$"Resend email failed: {response.StatusCode} - {body}"); $"Resend email failed: {response.StatusCode} - {body}");
} }
} }
private static string NormalizeApiKey(string? apiKey)
{
string normalized = apiKey?.Trim().Trim('"', '\'') ?? string.Empty;
const string bearerPrefix = "Bearer ";
if (normalized.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase))
{
normalized = normalized[bearerPrefix.Length..].Trim();
}
return normalized;
}
} }