From 966e598f100295164c832b4c7053aec546ab8427 Mon Sep 17 00:00:00 2001 From: d11n Date: Thu, 6 Jul 2023 04:01:36 +0200 Subject: [PATCH] Apps: Add direct file upload in item editor (#5140) --- BTCPayServer/Controllers/UIAppsController.cs | 48 ++++++++++++++++++- .../Controllers/UICrowdfundController.cs | 2 +- .../Controllers/UIPointOfSaleController.cs | 1 + .../Views/Shared/TemplateEditor.cshtml | 40 ++++++++++++++-- 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/BTCPayServer/Controllers/UIAppsController.cs b/BTCPayServer/Controllers/UIAppsController.cs index 08e10e405..b2f2ace75 100644 --- a/BTCPayServer/Controllers/UIAppsController.cs +++ b/BTCPayServer/Controllers/UIAppsController.cs @@ -1,6 +1,9 @@ +using System; using System.Linq; using System.Threading.Tasks; using BTCPayServer.Abstractions.Constants; +using BTCPayServer.Abstractions.Contracts; +using BTCPayServer.Abstractions.Extensions; using BTCPayServer.Abstractions.Models; using BTCPayServer.Client; using BTCPayServer.Data; @@ -8,6 +11,7 @@ using BTCPayServer.Models.AppViewModels; using BTCPayServer.Services.Apps; using BTCPayServer.Services.Stores; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Rendering; @@ -21,17 +25,20 @@ namespace BTCPayServer.Controllers public UIAppsController( UserManager userManager, StoreRepository storeRepository, + IFileService fileService, AppService appService, IHtmlHelper html) { _userManager = userManager; _storeRepository = storeRepository; + _fileService = fileService; _appService = appService; Html = html; } private readonly UserManager _userManager; private readonly StoreRepository _storeRepository; + private readonly IFileService _fileService; private readonly AppService _appService; public string CreatedAppId { get; set; } @@ -184,13 +191,50 @@ namespace BTCPayServer.Controllers return RedirectToAction(nameof(UIStoresController.Dashboard), "UIStores", new { storeId = app.StoreDataId }); } + [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] + [HttpPost("{appId}/upload-file")] + [IgnoreAntiforgeryToken] + public async Task FileUpload(IFormFile file) + { + var app = GetCurrentApp(); + var userId = GetUserId(); + if (app is null || userId is null) + return NotFound(); + + if (!file.ContentType.StartsWith("image/", StringComparison.InvariantCulture)) + { + return Json(new { error = "The file needs to be an image" }); + } + if (file.Length > 500_000) + { + return Json(new { error = "The image file size should be less than 0.5MB" }); + } + var formFile = await file.Bufferize(); + if (!FileTypeDetector.IsPicture(formFile.Buffer, formFile.FileName)) + { + return Json(new { error = "The file needs to be an image" }); + } + try + { + var storedFile = await _fileService.AddFile(file, userId); + var fileId = storedFile.Id; + var fileUrl = await _fileService.GetFileUrl(Request.GetAbsoluteRootUri(), fileId); + return Json(new { fileId, fileUrl }); + } + catch (Exception e) + { + return Json(new { error = $"Could not save file: {e.Message}" }); + } + } + async Task GetStoreDefaultCurrentIfEmpty(string storeId, string currency) { if (string.IsNullOrWhiteSpace(currency)) { - currency = (await _storeRepository.FindStore(storeId)).GetStoreBlob().DefaultCurrency; + var store = await _storeRepository.FindStore(storeId); + currency = store?.GetStoreBlob().DefaultCurrency; } - return currency.Trim().ToUpperInvariant(); + return currency?.Trim().ToUpperInvariant(); } private string GetUserId() => _userManager.GetUserId(User); diff --git a/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs b/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs index ce54157b2..64d9e3ac6 100644 --- a/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs +++ b/BTCPayServer/Plugins/Crowdfund/Controllers/UICrowdfundController.cs @@ -17,7 +17,6 @@ using BTCPayServer.Services.Rates; using BTCPayServer.Services.Stores; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using NBitpayClient; @@ -267,6 +266,7 @@ namespace BTCPayServer.Plugins.Crowdfund.Controllers if (app == null) return NotFound(); + vm.AppId = app.Id; vm.TargetCurrency = await GetStoreDefaultCurrentIfEmpty(app.StoreDataId, vm.TargetCurrency); if (_currencies.GetCurrencyData(vm.TargetCurrency, false) == null) ModelState.AddModelError(nameof(vm.TargetCurrency), "Invalid currency"); diff --git a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs index 2503f98bf..d1ba1c0ea 100644 --- a/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs +++ b/BTCPayServer/Plugins/PointOfSale/Controllers/UIPointOfSaleController.cs @@ -566,6 +566,7 @@ namespace BTCPayServer.Plugins.PointOfSale.Controllers if (app == null) return NotFound(); + vm.Id = app.Id; if (!ModelState.IsValid) return View("PointOfSale/UpdatePointOfSale", vm); diff --git a/BTCPayServer/Views/Shared/TemplateEditor.cshtml b/BTCPayServer/Views/Shared/TemplateEditor.cshtml index 143e375c4..83dc3485e 100644 --- a/BTCPayServer/Views/Shared/TemplateEditor.cshtml +++ b/BTCPayServer/Views/Shared/TemplateEditor.cshtml @@ -43,8 +43,13 @@
- + +
+ + +
+
@@ -142,6 +147,7 @@