2020-06-29 04:44:35 +02:00
using System ;
2022-06-22 05:05:32 +02:00
using System.Collections.Generic ;
using System.ComponentModel.DataAnnotations ;
2022-06-23 06:41:52 +02:00
using System.Globalization ;
2019-01-06 15:53:37 +01:00
using System.Threading.Tasks ;
2022-02-21 15:46:43 +01:00
using BTCPayServer.Abstractions.Constants ;
2022-06-22 05:05:32 +02:00
using BTCPayServer.Abstractions.Extensions ;
using BTCPayServer.Abstractions.Models ;
using BTCPayServer.Client.Models ;
2019-01-06 15:53:37 +01:00
using BTCPayServer.Data ;
using BTCPayServer.Models.ServerViewModels ;
using BTCPayServer.Services.Mails ;
using Microsoft.AspNetCore.Mvc ;
2021-12-15 13:30:46 +01:00
using MimeKit ;
2019-01-06 15:53:37 +01:00
namespace BTCPayServer.Controllers
{
2022-01-07 04:32:00 +01:00
public partial class UIStoresController
2019-01-06 15:53:37 +01:00
{
2022-06-22 05:05:32 +02:00
[HttpGet("{storeId}/emails")]
public IActionResult StoreEmails ( string storeId )
{
var store = HttpContext . GetStoreData ( ) ;
if ( store = = null )
return NotFound ( ) ;
2023-01-06 14:18:07 +01:00
2022-06-22 05:05:32 +02:00
var blob = store . GetStoreBlob ( ) ;
var data = blob . EmailSettings ;
if ( data ? . IsComplete ( ) is not true )
{
TempData . SetStatusMessageModel ( new StatusMessageModel
{
Severity = StatusMessageModel . StatusSeverity . Warning ,
2023-01-06 14:18:07 +01:00
Html = $"You need to configure email settings before this feature works. <a class='alert-link' href='{Url.Action(" StoreEmailSettings ", new { storeId })}'>Configure now</a>."
2022-06-22 05:05:32 +02:00
} ) ;
}
var vm = new StoreEmailRuleViewModel { Rules = blob . EmailRules ? ? new List < StoreEmailRule > ( ) } ;
return View ( vm ) ;
}
2020-06-28 10:55:27 +02:00
2022-06-22 05:05:32 +02:00
[HttpPost("{storeId}/emails")]
public async Task < IActionResult > StoreEmails ( string storeId , StoreEmailRuleViewModel vm , string command )
{
vm . Rules ? ? = new List < StoreEmailRule > ( ) ;
if ( command . StartsWith ( "remove" , StringComparison . InvariantCultureIgnoreCase ) )
{
var item = command [ ( command . IndexOf ( ":" , StringComparison . InvariantCultureIgnoreCase ) + 1 ) . . ] ;
2022-06-23 06:41:52 +02:00
var index = int . Parse ( item , CultureInfo . InvariantCulture ) ;
2022-06-22 05:05:32 +02:00
vm . Rules . RemoveAt ( index ) ;
2023-01-06 14:18:07 +01:00
}
else if ( command = = "add" )
2022-06-22 05:05:32 +02:00
{
vm . Rules . Add ( new StoreEmailRule ( ) ) ;
2023-01-06 14:18:07 +01:00
2022-06-22 05:05:32 +02:00
return View ( vm ) ;
}
if ( ! ModelState . IsValid )
{
return View ( vm ) ;
}
2023-01-06 14:18:07 +01:00
2022-06-22 05:05:32 +02:00
var store = HttpContext . GetStoreData ( ) ;
if ( store = = null )
return NotFound ( ) ;
var blob = store . GetStoreBlob ( ) ;
blob . EmailRules = vm . Rules ;
store . SetStoreBlob ( blob ) ;
await _Repo . UpdateStore ( store ) ;
TempData . SetStatusMessageModel ( new StatusMessageModel
{
Severity = StatusMessageModel . StatusSeverity . Success ,
Message = "Store email rules saved"
} ) ;
2023-01-06 14:18:07 +01:00
return RedirectToAction ( "StoreEmails" , new { storeId } ) ;
2022-06-22 05:05:32 +02:00
}
public class StoreEmailRuleViewModel
{
public List < StoreEmailRule > Rules { get ; set ; }
}
2023-01-06 14:18:07 +01:00
2022-06-22 05:05:32 +02:00
public class StoreEmailRule
{
[Required]
public WebhookEventType Trigger { get ; set ; }
public bool CustomerEmail { get ; set ; }
public string To { get ; set ; }
public string Body { get ; set ; }
public string Subject { get ; set ; }
}
2023-01-06 14:18:07 +01:00
2022-06-22 05:05:32 +02:00
[HttpGet("{storeId}/email-settings")]
public IActionResult StoreEmailSettings ( )
2019-01-06 15:53:37 +01:00
{
var store = HttpContext . GetStoreData ( ) ;
if ( store = = null )
return NotFound ( ) ;
var data = store . GetStoreBlob ( ) . EmailSettings ? ? new EmailSettings ( ) ;
2020-10-05 08:42:19 +02:00
return View ( new EmailsViewModel ( data ) ) ;
2019-01-06 15:53:37 +01:00
}
2020-06-28 10:55:27 +02:00
2022-06-22 05:05:32 +02:00
[HttpPost("{storeId}/email-settings")]
public async Task < IActionResult > StoreEmailSettings ( string storeId , EmailsViewModel model , string command )
2019-01-06 15:53:37 +01:00
{
var store = HttpContext . GetStoreData ( ) ;
if ( store = = null )
return NotFound ( ) ;
2023-01-06 14:18:07 +01:00
2019-01-06 15:53:37 +01:00
if ( command = = "Test" )
{
try
{
2020-10-05 08:42:19 +02:00
if ( model . PasswordSet )
{
model . Settings . Password = store . GetStoreBlob ( ) . EmailSettings . Password ;
}
2022-06-23 06:41:52 +02:00
model . Settings . Validate ( "Settings." , ModelState ) ;
if ( string . IsNullOrEmpty ( model . TestEmail ) )
ModelState . AddModelError ( nameof ( model . TestEmail ) , new RequiredAttribute ( ) . FormatErrorMessage ( nameof ( model . TestEmail ) ) ) ;
if ( ! ModelState . IsValid )
2022-06-22 05:05:32 +02:00
return View ( model ) ;
2021-12-15 13:30:46 +01:00
using var client = await model . Settings . CreateSmtpClient ( ) ;
2022-06-23 06:41:52 +02:00
var message = model . Settings . CreateMailMessage ( MailboxAddress . Parse ( model . TestEmail ) , "BTCPay test" , "BTCPay test" , false ) ;
2021-12-15 13:30:46 +01:00
await client . SendAsync ( message ) ;
await client . DisconnectAsync ( true ) ;
2022-06-22 05:05:32 +02:00
TempData [ WellKnownTempData . SuccessMessage ] = $"Email sent to {model.TestEmail}. Please verify you received it." ;
2019-01-06 15:53:37 +01:00
}
catch ( Exception ex )
{
2019-10-31 04:29:59 +01:00
TempData [ WellKnownTempData . ErrorMessage ] = "Error: " + ex . Message ;
2019-01-06 15:53:37 +01:00
}
return View ( model ) ;
}
2022-06-22 05:05:32 +02:00
if ( command = = "ResetPassword" )
2020-10-05 08:42:19 +02:00
{
var storeBlob = store . GetStoreBlob ( ) ;
storeBlob . EmailSettings . Password = null ;
store . SetStoreBlob ( storeBlob ) ;
await _Repo . UpdateStore ( store ) ;
TempData [ WellKnownTempData . SuccessMessage ] = "Email server password reset" ;
2022-06-22 05:05:32 +02:00
return RedirectToAction ( nameof ( StoreEmailSettings ) , new { storeId } ) ;
2020-10-05 08:42:19 +02:00
}
2022-06-22 05:05:32 +02:00
else // if (command == "Save")
2019-01-06 15:53:37 +01:00
{
2022-06-23 06:41:52 +02:00
if ( model . Settings . From is not null & & ! MailboxAddressValidator . IsMailboxAddress ( model . Settings . From ) )
{
ModelState . AddModelError ( "Settings.From" , "Invalid email" ) ;
return View ( model ) ;
}
2019-01-06 15:53:37 +01:00
var storeBlob = store . GetStoreBlob ( ) ;
2022-06-22 05:05:32 +02:00
if ( new EmailsViewModel ( storeBlob . EmailSettings ) . PasswordSet & & storeBlob . EmailSettings ! = null )
2020-10-05 08:42:19 +02:00
{
model . Settings . Password = storeBlob . EmailSettings . Password ;
}
2019-01-06 15:53:37 +01:00
storeBlob . EmailSettings = model . Settings ;
store . SetStoreBlob ( storeBlob ) ;
await _Repo . UpdateStore ( store ) ;
2019-10-31 04:29:59 +01:00
TempData [ WellKnownTempData . SuccessMessage ] = "Email settings modified" ;
2022-06-22 05:05:32 +02:00
return RedirectToAction ( nameof ( StoreEmailSettings ) , new { storeId } ) ;
2019-01-06 15:53:37 +01:00
}
}
}
}