2021-04-18 17:53:57 -07:00
#nullable enable
2020-09-19 16:53:45 +02:00
using System.Linq ;
2022-01-11 11:48:03 +09:00
using System.Threading ;
2020-09-18 17:20:31 +02:00
using System.Threading.Tasks ;
2022-02-21 15:46:43 +01:00
using BTCPayServer.Abstractions.Constants ;
2022-07-15 05:38:33 +02:00
using BTCPayServer.Abstractions.Models ;
2024-03-14 10:25:40 +01:00
using BTCPayServer.Client ;
2021-12-31 16:59:02 +09:00
using BTCPayServer.Client.Models ;
2020-09-18 17:20:31 +02:00
using BTCPayServer.Data ;
using BTCPayServer.Models.StoreViewModels ;
2024-03-14 10:25:40 +01:00
using Microsoft.AspNetCore.Authorization ;
2020-09-18 17:20:31 +02:00
using Microsoft.AspNetCore.Mvc ;
2020-11-06 20:42:26 +09:00
using NBitcoin ;
using NBitcoin.DataEncoders ;
2020-09-18 17:20:31 +02:00
2024-04-04 11:00:18 +02:00
namespace BTCPayServer.Controllers ;
public partial class UIStoresController
2020-09-18 17:20:31 +02:00
{
2024-04-04 11:00:18 +02:00
private async Task < Data . WebhookDeliveryData ? > LastDeliveryForWebhook ( string webhookId )
2020-09-18 17:20:31 +02:00
{
2024-04-04 11:00:18 +02:00
return ( await _storeRepo . GetWebhookDeliveries ( CurrentStore . Id , webhookId , 1 ) ) . ToList ( ) . FirstOrDefault ( ) ;
}
2021-07-12 05:58:11 -07:00
2024-04-04 11:00:18 +02:00
[HttpGet("{storeId}/webhooks")]
public async Task < IActionResult > Webhooks ( )
{
var webhooks = await _storeRepo . GetWebhooks ( CurrentStore . Id ) ;
return View ( nameof ( Webhooks ) , new WebhooksViewModel
2020-11-06 20:42:26 +09:00
{
2024-04-04 11:00:18 +02:00
Webhooks = webhooks . Select ( async w = >
2020-11-06 20:42:26 +09:00
{
2021-12-31 16:59:02 +09:00
var lastDelivery = await LastDeliveryForWebhook ( w . Id ) ;
var lastDeliveryBlob = lastDelivery ? . GetBlob ( ) ;
return new WebhooksViewModel . WebhookViewModel ( )
{
Id = w . Id ,
Url = w . GetBlob ( ) . Url ,
LastDeliveryErrorMessage = lastDeliveryBlob ? . ErrorMessage ,
LastDeliveryTimeStamp = lastDelivery ? . Timestamp ,
LastDeliverySuccessful = lastDeliveryBlob = = null ? true : lastDeliveryBlob . Status = = WebhookDeliveryStatus . HttpSuccess ,
} ;
}
2024-04-04 11:00:18 +02:00
) . Select ( t = > t . Result ) . ToArray ( )
} ) ;
}
2020-11-06 20:42:26 +09:00
2024-04-04 11:00:18 +02:00
[HttpGet("{storeId}/webhooks/new")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public IActionResult NewWebhook ( )
{
return View ( nameof ( ModifyWebhook ) , new EditWebhookViewModel
2020-11-06 20:42:26 +09:00
{
2024-04-04 11:00:18 +02:00
Active = true ,
Everything = true ,
IsNew = true ,
Secret = Encoders . Base58 . EncodeData ( RandomUtils . GetBytes ( 20 ) )
} ) ;
}
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
[HttpGet("{storeId}/webhooks/{webhookId}/remove")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > DeleteWebhook ( string webhookId )
{
var webhook = await _storeRepo . GetWebhook ( CurrentStore . Id , webhookId ) ;
if ( webhook is null )
return NotFound ( ) ;
2020-11-06 20:42:26 +09:00
2024-04-04 11:00:18 +02:00
return View ( "Confirm" , new ConfirmModel ( "Delete webhook" , "This webhook will be removed from this store. Are you sure?" , "Delete" ) ) ;
}
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
[HttpPost("{storeId}/webhooks/{webhookId}/remove")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > DeleteWebhookPost ( string webhookId )
{
var webhook = await _storeRepo . GetWebhook ( CurrentStore . Id , webhookId ) ;
if ( webhook is null )
return NotFound ( ) ;
2020-11-06 20:42:26 +09:00
2024-04-04 11:00:18 +02:00
await _storeRepo . DeleteWebhook ( CurrentStore . Id , webhookId ) ;
TempData [ WellKnownTempData . SuccessMessage ] = "Webhook successfully deleted" ;
return RedirectToAction ( nameof ( Webhooks ) , new { storeId = CurrentStore . Id } ) ;
}
2020-11-06 20:42:26 +09:00
2024-04-04 11:00:18 +02:00
[HttpPost("{storeId}/webhooks/new")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > NewWebhook ( string storeId , EditWebhookViewModel viewModel )
{
if ( ! ModelState . IsValid )
return View ( nameof ( ModifyWebhook ) , viewModel ) ;
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
await _storeRepo . CreateWebhook ( CurrentStore . Id , viewModel . CreateBlob ( ) ) ;
TempData [ WellKnownTempData . SuccessMessage ] = "The webhook has been created" ;
return RedirectToAction ( nameof ( Webhooks ) , new { storeId } ) ;
}
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
[HttpGet("{storeId}/webhooks/{webhookId}")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > ModifyWebhook ( string webhookId )
{
var webhook = await _storeRepo . GetWebhook ( CurrentStore . Id , webhookId ) ;
if ( webhook is null )
return NotFound ( ) ;
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
var blob = webhook . GetBlob ( ) ;
var deliveries = await _storeRepo . GetWebhookDeliveries ( CurrentStore . Id , webhookId , 20 ) ;
return View ( nameof ( ModifyWebhook ) , new EditWebhookViewModel ( blob )
2020-11-06 20:42:26 +09:00
{
2024-04-04 11:00:18 +02:00
Deliveries = deliveries
. Select ( s = > new DeliveryViewModel ( s ) ) . ToList ( )
} ) ;
}
2020-11-06 20:42:26 +09:00
2024-04-04 11:00:18 +02:00
[HttpPost("{storeId}/webhooks/{webhookId}")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > ModifyWebhook ( string webhookId , EditWebhookViewModel viewModel )
{
var webhook = await _storeRepo . GetWebhook ( CurrentStore . Id , webhookId ) ;
if ( webhook is null )
return NotFound ( ) ;
if ( ! ModelState . IsValid )
return View ( nameof ( ModifyWebhook ) , viewModel ) ;
await _storeRepo . UpdateWebhook ( CurrentStore . Id , webhookId , viewModel . CreateBlob ( ) ) ;
TempData [ WellKnownTempData . SuccessMessage ] = "The webhook has been updated" ;
return RedirectToAction ( nameof ( Webhooks ) , new { storeId = CurrentStore . Id } ) ;
}
2021-04-18 17:53:57 -07:00
2024-04-04 11:00:18 +02:00
[HttpGet("{storeId}/webhooks/{webhookId}/test")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > TestWebhook ( string webhookId )
{
var webhook = await _storeRepo . GetWebhook ( CurrentStore . Id , webhookId ) ;
if ( webhook is null )
return NotFound ( ) ;
2021-04-18 17:53:57 -07:00
2024-04-04 11:00:18 +02:00
return View ( nameof ( TestWebhook ) ) ;
}
2021-04-25 20:09:26 -07:00
2024-04-04 11:00:18 +02:00
[HttpPost("{storeId}/webhooks/{webhookId}/test")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > TestWebhook ( string webhookId , TestWebhookViewModel viewModel , CancellationToken cancellationToken )
{
var result = await _webhookNotificationManager . TestWebhook ( CurrentStore . Id , webhookId , viewModel . Type , cancellationToken ) ;
2021-04-18 22:52:08 -07:00
2024-04-04 11:00:18 +02:00
if ( result . Success )
{
TempData [ WellKnownTempData . SuccessMessage ] = $"{viewModel.Type} event delivered successfully! Delivery ID is {result.DeliveryId}" ;
2021-04-18 17:53:57 -07:00
}
2024-04-04 11:00:18 +02:00
else
2020-11-06 20:42:26 +09:00
{
2024-04-04 11:00:18 +02:00
TempData [ WellKnownTempData . ErrorMessage ] = $"{viewModel.Type} event could not be delivered. Error message received: {(result.ErrorMessage ?? " unknown ")}" ;
}
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
return View ( nameof ( TestWebhook ) ) ;
}
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
[HttpPost("{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/redeliver")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > RedeliverWebhook ( string webhookId , string deliveryId )
{
var delivery = await _storeRepo . GetWebhookDelivery ( CurrentStore . Id , webhookId , deliveryId ) ;
if ( delivery is null )
return NotFound ( ) ;
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
var newDeliveryId = await _webhookNotificationManager . Redeliver ( deliveryId ) ;
if ( newDeliveryId is null )
return NotFound ( ) ;
2021-02-23 16:51:58 +01:00
2024-04-04 11:00:18 +02:00
TempData [ WellKnownTempData . SuccessMessage ] = "Successfully planned a redelivery" ;
return RedirectToAction ( nameof ( ModifyWebhook ) ,
new
{
storeId = CurrentStore . Id ,
webhookId
} ) ;
}
[HttpGet("{storeId}/webhooks/{webhookId}/deliveries/{deliveryId}/request")]
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Cookie)]
public async Task < IActionResult > WebhookDelivery ( string webhookId , string deliveryId )
{
var delivery = await _storeRepo . GetWebhookDelivery ( CurrentStore . Id , webhookId , deliveryId ) ;
if ( delivery is null )
return NotFound ( ) ;
return File ( delivery . GetBlob ( ) . Request , "application/json" ) ;
2020-09-18 17:20:31 +02:00
}
}