diff --git a/BTCPayServer.Client/Permissions.cs b/BTCPayServer.Client/Permissions.cs index 29c65bc7a..86a834c66 100644 --- a/BTCPayServer.Client/Permissions.cs +++ b/BTCPayServer.Client/Permissions.cs @@ -33,6 +33,7 @@ namespace BTCPayServer.Client public const string CanManageUsers = "btcpay.server.canmanageusers"; public const string CanDeleteUser = "btcpay.user.candeleteuser"; public const string CanManagePullPayments = "btcpay.store.canmanagepullpayments"; + public const string CanArchivePullPayments = "btcpay.store.canarchivepullpayments"; public const string CanCreatePullPayments = "btcpay.store.cancreatepullpayments"; public const string CanCreateNonApprovedPullPayments = "btcpay.store.cancreatenonapprovedpullpayments"; public const string CanViewCustodianAccounts = "btcpay.store.canviewcustodianaccounts"; @@ -69,6 +70,7 @@ namespace BTCPayServer.Client yield return CanViewLightningInvoiceInStore; yield return CanCreateLightningInvoiceInStore; yield return CanManagePullPayments; + yield return CanArchivePullPayments; yield return CanCreatePullPayments; yield return CanCreateNonApprovedPullPayments; yield return CanViewCustodianAccounts; @@ -253,7 +255,7 @@ namespace BTCPayServer.Client Policies.CanUseLightningNodeInStore); PolicyHasChild(policyMap,Policies.CanManageUsers, Policies.CanCreateUser); - PolicyHasChild(policyMap,Policies.CanManagePullPayments, Policies.CanCreatePullPayments); + PolicyHasChild(policyMap,Policies.CanManagePullPayments, Policies.CanCreatePullPayments, Policies.CanArchivePullPayments); PolicyHasChild(policyMap,Policies.CanCreatePullPayments, Policies.CanCreateNonApprovedPullPayments); PolicyHasChild(policyMap,Policies.CanModifyPaymentRequests, Policies.CanViewPaymentRequests); PolicyHasChild(policyMap,Policies.CanModifyProfile, Policies.CanViewProfile); diff --git a/BTCPayServer.Tests/GreenfieldAPITests.cs b/BTCPayServer.Tests/GreenfieldAPITests.cs index b865a00ca..47e8117dd 100644 --- a/BTCPayServer.Tests/GreenfieldAPITests.cs +++ b/BTCPayServer.Tests/GreenfieldAPITests.cs @@ -885,7 +885,7 @@ namespace BTCPayServer.Tests TestLogs.LogInformation("Can't archive without knowing the walletId"); var ex = await AssertAPIError("missing-permission", async () => await client.ArchivePullPayment("lol", result.Id)); - Assert.Equal("btcpay.store.canmanagepullpayments", ((GreenfieldPermissionAPIError)ex.APIError).MissingPermission); + Assert.Equal("btcpay.store.canarchivepullpayments", ((GreenfieldPermissionAPIError)ex.APIError).MissingPermission); TestLogs.LogInformation("Can't archive without permission"); await AssertAPIError("unauthenticated", async () => await unauthenticated.ArchivePullPayment(storeId, result.Id)); await client.ArchivePullPayment(storeId, result.Id); diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 0b72390d2..9828db62e 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -38,6 +38,7 @@ using OpenQA.Selenium.Support.Extensions; using OpenQA.Selenium.Support.UI; using Xunit; using Xunit.Abstractions; +using Xunit.Sdk; namespace BTCPayServer.Tests { @@ -926,7 +927,8 @@ namespace BTCPayServer.Tests Policies.CanModifyStoreSettings, Policies.CanCreateNonApprovedPullPayments, Policies.CanCreatePullPayments, - Policies.CanManagePullPayments + Policies.CanManagePullPayments, + Policies.CanArchivePullPayments, }); AssertPermissions(pageSource, false, new[] @@ -1848,6 +1850,7 @@ namespace BTCPayServer.Tests TestUtils.Eventually(() => { s.Driver.Navigate().Refresh(); + s.Driver.WaitWalletTransactionsLoaded(); Assert.Contains("transaction-label", s.Driver.PageSource); var labels = s.Driver.FindElements(By.CssSelector("#WalletTransactionsList tr:first-child div.transaction-label")); Assert.Equal(2, labels.Count); @@ -2017,10 +2020,7 @@ namespace BTCPayServer.Tests Assert.Contains(bolt, s.Driver.PageSource); } - - //auto-approve pull payments - s.GoToStore(StoreNavPages.PullPayments); s.Driver.FindElement(By.Id("NewPullPayment")).Click(); s.Driver.FindElement(By.Id("Name")).SendKeys("PP1"); @@ -2050,6 +2050,8 @@ namespace BTCPayServer.Tests s.FindAlertMessage(StatusMessageModel.StatusSeverity.Success); s.Driver.FindElement(By.LinkText("View")).Click(); s.Driver.FindElement(By.CssSelector("#lnurlwithdraw-button")).Click(); + s.Driver.WaitForElement(By.Id("qr-code-data-input")); + var lnurl = new Uri(LNURL.LNURL.Parse(s.Driver.FindElement(By.Id("qr-code-data-input")).GetAttribute("value"), out _).ToString().Replace("https", "http")); s.Driver.FindElement(By.CssSelector("button[data-bs-dismiss='modal']")).Click(); var info = Assert.IsType(await LNURL.LNURL.FetchInformation(lnurl, s.Server.PayTester.HttpClient)); diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs index f2167241d..7efad4560 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldPullPaymentController.cs @@ -442,7 +442,7 @@ namespace BTCPayServer.Controllers.Greenfield } [HttpDelete("~/api/v1/stores/{storeId}/pull-payments/{pullPaymentId}")] - [Authorize(Policy = Policies.CanManagePullPayments, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] + [Authorize(Policy = Policies.CanArchivePullPayments, AuthenticationSchemes = AuthenticationSchemes.Greenfield)] public async Task ArchivePullPayment(string storeId, string pullPaymentId) { using var ctx = _dbContextFactory.CreateContext(); diff --git a/BTCPayServer/Controllers/UIManageController.APIKeys.cs b/BTCPayServer/Controllers/UIManageController.APIKeys.cs index 0276fa9b1..314a7b177 100644 --- a/BTCPayServer/Controllers/UIManageController.APIKeys.cs +++ b/BTCPayServer/Controllers/UIManageController.APIKeys.cs @@ -544,6 +544,8 @@ namespace BTCPayServer.Controllers {$"{Policies.CanViewPaymentRequests}:", ("View your payment requests", "Allows viewing the selected stores' payment requests.")}, {Policies.CanManagePullPayments, ("Manage your pull payments", "Allows viewing, modifying, deleting and creating pull payments on all your stores.")}, {$"{Policies.CanManagePullPayments}:", ("Manage selected stores' pull payments", "Allows viewing, modifying, deleting and creating pull payments on the selected stores.")}, + {Policies.CanArchivePullPayments, ("Archive your pull payments", "Allows deleting pull payments on all your stores.")}, + {$"{Policies.CanArchivePullPayments}:", ("Archive selected stores' pull payments", "Allows deleting pull payments on the selected stores.")}, {Policies.CanCreatePullPayments, ("Create pull payments", "Allows creating pull payments on all your stores.")}, {$"{Policies.CanCreatePullPayments}:", ("Create pull payments in selected stores", "Allows creating pull payments on the selected stores.")}, {Policies.CanCreateNonApprovedPullPayments, ("Create non-approved pull payments", "Allows creating pull payments without automatic approval on all your stores.")}, diff --git a/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs b/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs index 486732dc2..8d868e6c2 100644 --- a/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs +++ b/BTCPayServer/Controllers/UIStorePullPaymentsController.PullPayments.cs @@ -256,7 +256,7 @@ namespace BTCPayServer.Controllers } [HttpGet("stores/{storeId}/pull-payments/{pullPaymentId}/archive")] - [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] + [Authorize(Policy = Policies.CanArchivePullPayments, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public IActionResult ArchivePullPayment(string storeId, string pullPaymentId) { @@ -265,11 +265,11 @@ namespace BTCPayServer.Controllers } [HttpPost("stores/{storeId}/pull-payments/{pullPaymentId}/archive")] - [Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)] + [Authorize(Policy = Policies.CanArchivePullPayments, AuthenticationSchemes = AuthenticationSchemes.Cookie)] public async Task ArchivePullPaymentPost(string storeId, string pullPaymentId) { - await _pullPaymentService.Cancel(new HostedServices.PullPaymentHostedService.CancelRequest(pullPaymentId)); + await _pullPaymentService.Cancel(new PullPaymentHostedService.CancelRequest(pullPaymentId)); TempData.SetStatusMessageModel(new StatusMessageModel() { Message = "Pull payment archived", diff --git a/BTCPayServer/Views/Shared/ShowQR.cshtml b/BTCPayServer/Views/Shared/ShowQR.cshtml index 378e39b06..76627dc8a 100644 --- a/BTCPayServer/Views/Shared/ShowQR.cshtml +++ b/BTCPayServer/Views/Shared/ShowQR.cshtml @@ -25,7 +25,7 @@ -

+
@@ -34,6 +34,9 @@
+ - - - + + + - } - + } + - + + diff --git a/BTCPayServer/Views/UIStorePullPayments/PullPayments.cshtml b/BTCPayServer/Views/UIStorePullPayments/PullPayments.cshtml index 1ea56502e..a13e94bc5 100644 --- a/BTCPayServer/Views/UIStorePullPayments/PullPayments.cshtml +++ b/BTCPayServer/Views/UIStorePullPayments/PullPayments.cshtml @@ -71,7 +71,7 @@ { @state } @@ -100,8 +100,9 @@ } } - - +
+
+ - - - @foreach (var pp in Model.PullPayments) - { - - - - - - + @foreach (var pp in Model.PullPayments) + { + + + - - } - -
Refunded Actions
@pp.StartDate.ToBrowserDate() - - @pp.Name - - @pp.AutoApproveClaims -
-
-
-
-
-
-
- - Payouts - - @if (!pp.Archived) - { - - - - Archive + +
@pp.StartDate.ToBrowserDate() + + @pp.Name - } - - - - View - -
- + + @pp.AutoApproveClaims + +
+
+
+
+
+
+ + + + Payouts + + @if (!pp.Archived) + { + - + + Archive + + } + - + + View + + + + } + + + diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.json index 5c2cff55f..f65ee5769 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.json @@ -120,7 +120,7 @@ "securitySchemes": { "API_Key": { "type": "apiKey", - "description": "BTCPay Server supports authenticating and authorizing users through an API Key that is generated by them. Send the API Key as a header value to Authorization with the format: `token {token}`. For a smoother experience, you can generate a url that redirects users to an API key creation screen.\n\n The following permissions are available to the context of the user creating the API Key:\n\n* `unrestricted`: Unrestricted access\n* `btcpay.user.candeleteuser`: Delete user\n* `btcpay.user.canviewprofile`: View your profile\n* `btcpay.user.canmodifyprofile`: Manage your profile\n* `btcpay.user.canmanagenotificationsforuser`: Manage your notifications\n* `btcpay.user.canviewnotificationsforuser`: View your notifications\n\nThe following permissions are available if the user is an administrator:\n\n* `btcpay.server.canviewusers`: View users\n* `btcpay.server.cancreateuser`: Create new users\n* `btcpay.server.canmanageusers`: Manage users\n* `btcpay.server.canmodifyserversettings`: Manage your server\n* `btcpay.server.canuseinternallightningnode`: Use the internal lightning node\n* `btcpay.server.canviewlightninginvoiceinternalnode`: View invoices from internal lightning node\n* `btcpay.server.cancreatelightninginvoiceinternalnode`: Create invoices with internal lightning node\n\nThe following permissions applies to all stores of the user, you can limit to a specific store with the following format: `btcpay.store.cancreateinvoice:6HSHAEU4iYWtjxtyRs9KyPjM9GAQp8kw2T9VWbGG1FnZ`:\n\n* `btcpay.store.canmodifystoresettings`: Modify your stores\n* `btcpay.store.canviewcustodianaccounts`: View exchange accounts linked to your stores\n* `btcpay.store.canmanagecustodianaccounts`: Manage exchange accounts linked to your stores\n* `btcpay.store.candeposittocustodianaccount`: Deposit funds to exchange accounts linked to your stores\n* `btcpay.store.canwithdrawfromcustodianaccount`: Withdraw funds from exchange accounts to your store\n* `btcpay.store.cantradecustodianaccount`: Trade funds on your store's exchange accounts\n* `btcpay.store.webhooks.canmodifywebhooks`: Modify stores webhooks\n* `btcpay.store.canviewstoresettings`: View your stores\n* `btcpay.store.cancreateinvoice`: Create an invoice\n* `btcpay.store.canviewinvoices`: View invoices\n* `btcpay.store.canmodifyinvoices`: Modify invoices\n* `btcpay.store.canmodifypaymentrequests`: Modify your payment requests\n* `btcpay.store.canviewpaymentrequests`: View your payment requests\n* `btcpay.store.canmanagepullpayments`: Manage your pull payments\n* `btcpay.store.cancreatepullpayments`: Create pull payments\n* `btcpay.store.cancreatenonapprovedpullpayments`: Create non-approved pull payments\n* `btcpay.store.canuselightningnode`: Use the lightning nodes associated with your stores\n* `btcpay.store.canviewlightninginvoice`: View the lightning invoices associated with your stores\n* `btcpay.store.cancreatelightninginvoice`: Create invoices from the lightning nodes associated with your stores\n\nNote that API Keys only limits permission of a user and can never expand it. If an API Key has the permission `btcpay.server.canmodifyserversettings` but that the user account creating this API Key is not administrator, the API Key will not be able to modify the server settings.\nSome permissions may include other permissions, see [this operation](#operation/permissionsMetadata).\n", + "description": "BTCPay Server supports authenticating and authorizing users through an API Key that is generated by them. Send the API Key as a header value to Authorization with the format: `token {token}`. For a smoother experience, you can generate a url that redirects users to an API key creation screen.\n\n The following permissions are available to the context of the user creating the API Key:\n\n* `unrestricted`: Unrestricted access\n* `btcpay.user.candeleteuser`: Delete user\n* `btcpay.user.canviewprofile`: View your profile\n* `btcpay.user.canmodifyprofile`: Manage your profile\n* `btcpay.user.canmanagenotificationsforuser`: Manage your notifications\n* `btcpay.user.canviewnotificationsforuser`: View your notifications\n\nThe following permissions are available if the user is an administrator:\n\n* `btcpay.server.canviewusers`: View users\n* `btcpay.server.cancreateuser`: Create new users\n* `btcpay.server.canmanageusers`: Manage users\n* `btcpay.server.canmodifyserversettings`: Manage your server\n* `btcpay.server.canuseinternallightningnode`: Use the internal lightning node\n* `btcpay.server.canviewlightninginvoiceinternalnode`: View invoices from internal lightning node\n* `btcpay.server.cancreatelightninginvoiceinternalnode`: Create invoices with internal lightning node\n\nThe following permissions applies to all stores of the user, you can limit to a specific store with the following format: `btcpay.store.cancreateinvoice:6HSHAEU4iYWtjxtyRs9KyPjM9GAQp8kw2T9VWbGG1FnZ`:\n\n* `btcpay.store.canmodifystoresettings`: Modify your stores\n* `btcpay.store.canviewcustodianaccounts`: View exchange accounts linked to your stores\n* `btcpay.store.canmanagecustodianaccounts`: Manage exchange accounts linked to your stores\n* `btcpay.store.candeposittocustodianaccount`: Deposit funds to exchange accounts linked to your stores\n* `btcpay.store.canwithdrawfromcustodianaccount`: Withdraw funds from exchange accounts to your store\n* `btcpay.store.cantradecustodianaccount`: Trade funds on your store's exchange accounts\n* `btcpay.store.webhooks.canmodifywebhooks`: Modify stores webhooks\n* `btcpay.store.canviewstoresettings`: View your stores\n* `btcpay.store.cancreateinvoice`: Create an invoice\n* `btcpay.store.canviewinvoices`: View invoices\n* `btcpay.store.canmodifyinvoices`: Modify invoices\n* `btcpay.store.canmodifypaymentrequests`: Modify your payment requests\n* `btcpay.store.canviewpaymentrequests`: View your payment requests\n* `btcpay.store.canmanagepullpayments`: Manage your pull payments\n* `btcpay.store.canarchivepullpayments`: Archive your pull payments\n* `btcpay.store.cancreatepullpayments`: Create pull payments\n* `btcpay.store.cancreatenonapprovedpullpayments`: Create non-approved pull payments\n* `btcpay.store.canuselightningnode`: Use the lightning nodes associated with your stores\n* `btcpay.store.canviewlightninginvoice`: View the lightning invoices associated with your stores\n* `btcpay.store.cancreatelightninginvoice`: Create invoices from the lightning nodes associated with your stores\n\nNote that API Keys only limits permission of a user and can never expand it. If an API Key has the permission `btcpay.server.canmodifyserversettings` but that the user account creating this API Key is not administrator, the API Key will not be able to modify the server settings.\nSome permissions may include other permissions, see [this operation](#operation/permissionsMetadata).\n", "name": "Authorization", "in": "header" }, diff --git a/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json b/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json index 5c2ae81a9..cb22dbb6a 100644 --- a/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json +++ b/BTCPayServer/wwwroot/swagger/v1/swagger.template.pull-payments.json @@ -243,7 +243,7 @@ "security": [ { "API_Key": [ - "btcpay.store.canmanagepullpayments" + "btcpay.store.canarchivepullpayments" ], "Basic": [] }