Disallow cancelling payment request when "Allow payee to create invoices in their own denomination" is not enabled (#2843)

* Disallow cancelling payment request when "Allow payee to create invoices in their own denomination" is not enabled

close #2802

* Disallow cancelling pending invoice on BE

* Update non-JS version of payment request view to disallow cancelling

* Update CanCancelPaymentWhenPossible

* Fix typo
This commit is contained in:
Umar Bolatov
2021-09-16 18:24:48 -07:00
committed by GitHub
parent 603bd2692e
commit 5984edb7f4
3 changed files with 27 additions and 11 deletions

View File

@@ -189,10 +189,20 @@ namespace BTCPayServer.Tests
var response = Assert var response = Assert
.IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result) .IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result)
.RouteValues.First(); .RouteValues.First();
var invoiceId = response.Value.ToString();
await paymentRequestController.PayPaymentRequest(invoiceId, false);
Assert.IsType<BadRequestObjectResult>(await
paymentRequestController.CancelUnpaidPendingInvoice(invoiceId, false));
request.AllowCustomPaymentAmounts = true;
response = Assert
.IsType<RedirectToActionResult>(paymentRequestController.EditPaymentRequest(null, request).Result)
.RouteValues.First();
var paymentRequestId = response.Value.ToString(); var paymentRequestId = response.Value.ToString();
var invoiceId = Assert invoiceId = Assert
.IsType<OkObjectResult>(await paymentRequestController.PayPaymentRequest(paymentRequestId, false)) .IsType<OkObjectResult>(await paymentRequestController.PayPaymentRequest(paymentRequestId, false))
.Value .Value
.ToString(); .ToString();
@@ -224,12 +234,12 @@ namespace BTCPayServer.Tests
invoice = user.BitPay.GetInvoice(invoiceId, Facade.Merchant); invoice = user.BitPay.GetInvoice(invoiceId, Facade.Merchant);
//a hack to generate invoices for the payment request is to manually create an invocie with an order id that matches: //a hack to generate invoices for the payment request is to manually create an invoice with an order id that matches:
user.BitPay.CreateInvoice(new Invoice(1, "USD") user.BitPay.CreateInvoice(new Invoice(1, "USD")
{ {
OrderId = PaymentRequestRepository.GetOrderIdForPaymentRequest(paymentRequestId) OrderId = PaymentRequestRepository.GetOrderIdForPaymentRequest(paymentRequestId)
}); });
//shouldnt crash //shouldn't crash
await paymentRequestController.ViewPaymentRequest(paymentRequestId); await paymentRequestController.ViewPaymentRequest(paymentRequestId);
await paymentRequestController.CancelUnpaidPendingInvoice(paymentRequestId); await paymentRequestController.CancelUnpaidPendingInvoice(paymentRequestId);
} }

View File

@@ -299,6 +299,10 @@ namespace BTCPayServer.Controllers
return NotFound(); return NotFound();
} }
if (!result.AllowCustomPaymentAmounts) {
return BadRequest("Not allowed to cancel this invoice");
}
var invoices = result.Invoices.Where(requestInvoice => var invoices = result.Invoices.Where(requestInvoice =>
requestInvoice.State.Status == InvoiceStatusLegacy.New && !requestInvoice.Payments.Any()); requestInvoice.State.Status == InvoiceStatusLegacy.New && !requestInvoice.Payments.Any());

View File

@@ -126,7 +126,7 @@
<a class="btn btn-primary d-inline-block d-print-none w-100 text-nowrap @if (!(Model.AnyPendingInvoice && !Model.PendingInvoiceHasPayments)) { @("btn-lg") }" asp-action="PayPaymentRequest" asp-route-id="@Model.Id" data-test="pay-button"> <a class="btn btn-primary d-inline-block d-print-none w-100 text-nowrap @if (!(Model.AnyPendingInvoice && !Model.PendingInvoiceHasPayments)) { @("btn-lg") }" asp-action="PayPaymentRequest" asp-route-id="@Model.Id" data-test="pay-button">
Pay Invoice Pay Invoice
</a> </a>
if (Model.AnyPendingInvoice && !Model.PendingInvoiceHasPayments) if (Model.AnyPendingInvoice && !Model.PendingInvoiceHasPayments && Model.AllowCustomPaymentAmounts)
{ {
<form method="get" asp-action="CancelUnpaidPendingInvoice" asp-route-id="@Model.Id" class="mt-2 d-print-none"> <form method="get" asp-action="CancelUnpaidPendingInvoice" asp-route-id="@Model.Id" class="mt-2 d-print-none">
<button class="btn btn-outline-secondary w-100 text-nowrap" type="submit">Cancel Invoice</button> <button class="btn btn-outline-secondary w-100 text-nowrap" type="submit">Cancel Invoice</button>
@@ -169,18 +169,20 @@
</form> </form>
</template> </template>
<template v-else> <template v-else>
<button class="btn btn-primary w-100 d-flex d-print-none align-items-center justify-content-center text-nowrap" :class="{ 'btn-lg': !(srvModel.anyPendingInvoice && !srvModel.pendingInvoiceHasPayments)}" v-on:click="pay(null)" :disabled="loading" data-test="pay-button"> <button class="btn btn-primary w-100 d-flex d-print-none align-items-center justify-content-center text-nowrap" :class="{ 'btn-lg': !(srvModel.anyPendingInvoice && !srvModel.pendingInvoiceHasPayments) || !srvModel.allowCustomPaymentAmounts}" v-on:click="pay(null)" :disabled="loading" data-test="pay-button">
<div v-if="loading" class="spinner-grow spinner-grow-sm me-2" role="status"> <div v-if="loading" class="spinner-grow spinner-grow-sm me-2" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
<span>Pay Invoice</span> <span>Pay Invoice</span>
</button> </button>
@if (Model.AllowCustomPaymentAmounts) {
<button class="btn btn-outline-secondary mt-2 w-100 d-flex d-print-none align-items-center justify-content-center text-nowrap" v-if="srvModel.anyPendingInvoice && !srvModel.pendingInvoiceHasPayments" v-on:click="cancelPayment()" :disabled="loading"> <button class="btn btn-outline-secondary mt-2 w-100 d-flex d-print-none align-items-center justify-content-center text-nowrap" v-if="srvModel.anyPendingInvoice && !srvModel.pendingInvoiceHasPayments" v-on:click="cancelPayment()" :disabled="loading">
<span v-if="loading" class="spinner-grow spinner-grow-sm me-2" role="status"> <span v-if="loading" class="spinner-grow spinner-grow-sm me-2" role="status">
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</span> </span>
<span>Cancel Invoice</span> <span>Cancel Invoice</span>
</button> </button>
}
</template> </template>
</template> </template>
<template v-else> <template v-else>