Branding updates for 2.0 (#5947)

* Remove deprecated CSS options

Closes #5945.

* Greenfield: Add brandColor to store APIs

Closes #5946.

* Migrate file IDs to URLs

Closes #5953.

* Greenfield: Add CSS and logo URL to store settings API

Closes #5945.

* Add migration test

* Store and Server branding can reference file's via fileid:ID

* Add PaymentSoundUrl to Store API

---------

Co-authored-by: nicolas.dorier <nicolas.dorier@gmail.com>
This commit is contained in:
d11n
2024-05-09 02:18:02 +02:00
committed by GitHub
parent eba3475a1b
commit 4c303d358b
66 changed files with 526 additions and 605 deletions

View File

@@ -65,6 +65,7 @@ namespace BTCPayServer.Controllers
private readonly IFileService _fileService;
private readonly IEnumerable<IStorageProviderService> _StorageProviderServices;
private readonly LinkGenerator _linkGenerator;
private readonly UriResolver _uriResolver;
private readonly EmailSenderFactory _emailSenderFactory;
private readonly TransactionLinkProviders _transactionLinkProviders;
@@ -88,6 +89,7 @@ namespace BTCPayServer.Controllers
IOptions<ExternalServicesOptions> externalServiceOptions,
Logs logs,
LinkGenerator linkGenerator,
UriResolver uriResolver,
EmailSenderFactory emailSenderFactory,
IHostApplicationLifetime applicationLifetime,
IHtmlHelper html,
@@ -113,6 +115,7 @@ namespace BTCPayServer.Controllers
_externalServiceOptions = externalServiceOptions;
Logs = logs;
_linkGenerator = linkGenerator;
_uriResolver = uriResolver;
_emailSenderFactory = emailSenderFactory;
ApplicationLifetime = applicationLifetime;
Html = html;
@@ -1025,9 +1028,8 @@ namespace BTCPayServer.Controllers
ContactUrl = server.ContactUrl,
CustomTheme = theme.CustomTheme,
CustomThemeExtension = theme.CustomThemeExtension,
CustomThemeCssUri = theme.CustomThemeCssUri,
CustomThemeFileId = theme.CustomThemeFileId,
LogoFileId = theme.LogoFileId
CustomThemeCssUrl = await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), theme.CustomThemeCssUrl),
LogoUrl = await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), theme.LogoUrl)
};
return View(vm);
}
@@ -1046,8 +1048,8 @@ namespace BTCPayServer.Controllers
if (userId is null)
return NotFound();
vm.LogoFileId = theme.LogoFileId;
vm.CustomThemeFileId = theme.CustomThemeFileId;
vm.LogoUrl = await _uriResolver.Resolve(this.Request.GetAbsoluteRootUri(), theme.LogoUrl);
vm.CustomThemeCssUrl = await _uriResolver.Resolve(this.Request.GetAbsoluteRootUri(), theme.CustomThemeCssUrl);
if (server.ServerName != vm.ServerName)
{
@@ -1072,17 +1074,12 @@ namespace BTCPayServer.Controllers
{
if (vm.CustomThemeFile.ContentType.Equals("text/css", StringComparison.InvariantCulture))
{
// delete existing file
if (!string.IsNullOrEmpty(theme.CustomThemeFileId))
{
await _fileService.RemoveFile(theme.CustomThemeFileId, userId);
}
// add new file
try
{
var storedFile = await _fileService.AddFile(vm.CustomThemeFile, userId);
vm.CustomThemeFileId = theme.CustomThemeFileId = storedFile.Id;
theme.CustomThemeCssUrl = new UnresolvedUri.FileIdUri(storedFile.Id);
vm.CustomThemeCssUrl = await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), theme.CustomThemeCssUrl);
settingsChanged = true;
}
catch (Exception e)
@@ -1095,10 +1092,12 @@ namespace BTCPayServer.Controllers
ModelState.AddModelError(nameof(vm.CustomThemeFile), "The uploaded theme file needs to be a CSS file");
}
}
else if (RemoveCustomThemeFile && !string.IsNullOrEmpty(theme.CustomThemeFileId))
else if (RemoveCustomThemeFile && theme.CustomThemeCssUrl is not null)
{
await _fileService.RemoveFile(theme.CustomThemeFileId, userId);
vm.CustomThemeFileId = theme.CustomThemeFileId = null;
vm.CustomThemeCssUrl = null;
theme.CustomThemeCssUrl = null;
theme.CustomTheme = false;
theme.CustomThemeExtension = ThemeExtension.Custom;
settingsChanged = true;
}
@@ -1122,16 +1121,12 @@ namespace BTCPayServer.Controllers
else
{
vm.LogoFile = formFile;
// delete existing file
if (!string.IsNullOrEmpty(theme.LogoFileId))
{
await _fileService.RemoveFile(theme.LogoFileId, userId);
}
// add new file
try
{
var storedFile = await _fileService.AddFile(vm.LogoFile, userId);
vm.LogoFileId = theme.LogoFileId = storedFile.Id;
theme.LogoUrl = new UnresolvedUri.FileIdUri(storedFile.Id);
vm.LogoUrl = await _uriResolver.Resolve(Request.GetAbsoluteRootUri(), theme.LogoUrl);
settingsChanged = true;
}
catch (Exception e)
@@ -1141,29 +1136,19 @@ namespace BTCPayServer.Controllers
}
}
}
else if (RemoveLogoFile && !string.IsNullOrEmpty(theme.LogoFileId))
else if (RemoveLogoFile && theme.LogoUrl is not null)
{
await _fileService.RemoveFile(theme.LogoFileId, userId);
vm.LogoFileId = theme.LogoFileId = null;
vm.LogoUrl = null;
theme.LogoUrl = null;
settingsChanged = true;
}
if (vm.CustomTheme && !string.IsNullOrEmpty(vm.CustomThemeCssUri) && !Uri.IsWellFormedUriString(vm.CustomThemeCssUri, UriKind.RelativeOrAbsolute))
{
ModelState.AddModelError(nameof(theme.CustomThemeCssUri), "Please provide a non-empty theme URI");
}
else if (theme.CustomThemeCssUri != vm.CustomThemeCssUri)
{
theme.CustomThemeCssUri = vm.CustomThemeCssUri;
settingsChanged = true;
}
if (theme.CustomThemeExtension != vm.CustomThemeExtension)
if (vm.CustomTheme && theme.CustomThemeExtension != vm.CustomThemeExtension)
{
// Require a custom theme to be defined in that case
if (string.IsNullOrEmpty(vm.CustomThemeCssUri) && string.IsNullOrEmpty(theme.CustomThemeFileId))
if (string.IsNullOrEmpty(vm.CustomThemeCssUrl) && theme.CustomThemeCssUrl is null)
{
ModelState.AddModelError(nameof(vm.CustomThemeFile), "Please provide a custom theme");
ModelState.AddModelError(nameof(vm.CustomThemeCssUrl), "Please provide a custom theme");
}
else
{
@@ -1172,7 +1157,7 @@ namespace BTCPayServer.Controllers
}
}
if (theme.CustomTheme != vm.CustomTheme)
if (theme.CustomTheme != vm.CustomTheme && !RemoveCustomThemeFile)
{
theme.CustomTheme = vm.CustomTheme;
settingsChanged = true;
@@ -1182,6 +1167,7 @@ namespace BTCPayServer.Controllers
{
await _SettingsRepository.UpdateSetting(theme);
TempData[WellKnownTempData.SuccessMessage] = "Settings updated successfully";
return RedirectToAction(nameof(Branding));
}
return View(vm);