What changed, and why it matters
This commit is a small code cleanup in BTCPay Server's admin translation pages. It changes how a helper service is passed into the controller, switching from method-level injection to constructor-level injection. There is no visible change in behavior, no new security feature, and no bug fix apparent from the diff.
No security action required. Treat as routine refactoring during normal review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The refactor moves LanguagePackUpdateService from [FromServices] parameters on three action methods (ListDictionaries, DownloadLanguagePack, UpdateLanguagePack) to a private readonly field set via the UIServerController constructor. All call sites are updated from local parameter languagePackUpdateService to the field _languagePackUpdateService. The change is purely structural and does not alter authorization, validation, caching logic, or external request handling.
Changed components
BTCPayServer/Controllers/UIServerController.Translations.csBTCPayServer/Controllers/UIServerController.csInspect captured patch +19 / −16
diff --git a/BTCPayServer/Controllers/UIServerController.Translations.cs b/BTCPayServer/Controllers/UIServerController.Translations.cs
index e2bd34a..aee99e1 100644
--- a/BTCPayServer/Controllers/UIServerController.Translations.cs
+++ b/BTCPayServer/Controllers/UIServerController.Translations.cs
@@ -14,24 +14,24 @@ namespace BTCPayServer.Controllers
public partial class UIServerController
{
[HttpGet("server/dictionaries")]
- public async Task<IActionResult> ListDictionaries([FromServices] LanguagePackUpdateService languagePackUpdateService)
+ public async Task<IActionResult> ListDictionaries()
{
var dictionaries = await _localizer.GetDictionaries();
var vm = new ListDictionariesViewModel();
var downloadableLanguages = LanguagePackUpdateService.GetDownloadableLanguages();
-
+
foreach (var dictionary in dictionaries)
{
var isSelected = _policiesSettings.LangDictionary == dictionary.DictionaryName ||
(_policiesSettings.LangDictionary is null && dictionary.Source == "Default");
var isDownloadedPack = downloadableLanguages.Contains(dictionary.DictionaryName);
var updateAvailable = false;
-
+
if (isDownloadedPack && dictionary.Source == "Custom")
{
- updateAvailable = await languagePackUpdateService.CheckForLanguagePackUpdateCached(dictionary.DictionaryName, dictionary.Metadata);
+ updateAvailable = await _languagePackUpdateService.CheckForLanguagePackUpdateCached(dictionary.DictionaryName, dictionary.Metadata);
}
-
+
var dict = new ListDictionariesViewModel.DictionaryViewModel
{
Editable = dictionary.Source == "Custom",
@@ -139,7 +139,7 @@ namespace BTCPayServer.Controllers
}
[HttpPost("server/dictionaries/download")]
- public async Task<IActionResult> DownloadLanguagePack(string language, [FromServices] LanguagePackUpdateService languagePackUpdateService)
+ public async Task<IActionResult> DownloadLanguagePack(string language)
{
if (string.IsNullOrEmpty(language))
{
@@ -170,16 +170,16 @@ namespace BTCPayServer.Controllers
{
TempData[WellKnownTempData.SuccessMessage] = StringLocalizer["Language pack '{0}' updated successfully", language].Value;
}
-
+
await _localizer.Save(existingDictionary, translations);
await _localizer.UpdateVersion(language, version);
- languagePackUpdateService.InvalidateCache(language);
+ _languagePackUpdateService.InvalidateCache(language);
return RedirectToAction(nameof(ListDictionaries));
}
[HttpPost("server/dictionaries/{dictionary}/update")]
[ValidateAntiForgeryToken]
- public async Task<IActionResult> UpdateLanguagePack(string dictionary, [FromServices] LanguagePackUpdateService languagePackUpdateService)
+ public async Task<IActionResult> UpdateLanguagePack(string dictionary)
{
var existingDictionary = await _localizer.GetDictionary(dictionary);
if (existingDictionary is null || !LanguagePackUpdateService.GetDownloadableLanguages().Contains(dictionary))
@@ -203,7 +203,7 @@ namespace BTCPayServer.Controllers
var translations = Translations.CreateFromJson(translationsJson);
await _localizer.Save(existingDictionary, translations);
await _localizer.UpdateVersion(dictionary, version);
- languagePackUpdateService.InvalidateCache(dictionary);
+ _languagePackUpdateService.InvalidateCache(dictionary);
TempData[WellKnownTempData.SuccessMessage] = StringLocalizer["Language pack '{0}' updated successfully", dictionary].Value;
return RedirectToAction(nameof(ListDictionaries));
}
@@ -214,18 +214,18 @@ namespace BTCPayServer.Controllers
{
throw new ArgumentException($"Language '{language}' is not a valid downloadable language pack.", nameof(language));
}
-
+
var fileName = Uri.EscapeDataString(language.ToLowerInvariant());
var url = $"https://raw.githubusercontent.com/btcpayserver/btcpayserver-translator/main/translations/{fileName}.json";
-
+
var httpClient = HttpClientFactory.CreateClient();
httpClient.Timeout = TimeSpan.FromSeconds(30);
-
+
var translationsJson = await httpClient.GetStringAsync(url);
-
+
var hash = System.Security.Cryptography.SHA256.HashData(System.Text.Encoding.UTF8.GetBytes(translationsJson));
var version = Convert.ToHexString(hash);
-
+
return (translationsJson, version);
}
diff --git a/BTCPayServer/Controllers/UIServerController.cs b/BTCPayServer/Controllers/UIServerController.cs
index a0d5e88..891ba86 100644
--- a/BTCPayServer/Controllers/UIServerController.cs
+++ b/BTCPayServer/Controllers/UIServerController.cs
@@ -70,6 +70,7 @@ namespace BTCPayServer.Controllers
private readonly UriResolver _uriResolver;
private readonly TransactionLinkProviders _transactionLinkProviders;
private readonly LocalizerService _localizer;
+ private readonly LanguagePackUpdateService _languagePackUpdateService;
private readonly EmailSenderFactory _emailSenderFactory;
public IStringLocalizer StringLocalizer { get; }
public ViewLocalizer ViewLocalizer { get; }
@@ -102,7 +103,8 @@ namespace BTCPayServer.Controllers
LocalizerService localizer,
IStringLocalizer stringLocalizer,
ViewLocalizer viewLocalizer,
- BTCPayServerEnvironment environment
+ BTCPayServerEnvironment environment,
+ LanguagePackUpdateService languagePackUpdateService
)
{
_policiesSettings = policiesSettings;
@@ -130,6 +132,7 @@ namespace BTCPayServer.Controllers
Html = html;
_transactionLinkProviders = transactionLinkProviders;
_localizer = localizer;
+ _languagePackUpdateService = languagePackUpdateService;
Environment = environment;
StringLocalizer = stringLocalizer;
ViewLocalizer = viewLocalizer;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.