mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 18:11:36 +01:00
57544068e9
* Store rule emails in HTML + Test rule emails * Store rule emails in HTML + Test rule emails * Update BTCPayServer/Controllers/UIStoresController.Email.cs Thanks ! Co-authored-by: Andrew Camilleri <evilkukka@gmail.com> * change in StoreEmails() to work properly with add commande * CanSetupEmailServer() : Remove Bosy sendkeys that doesn't work with new HTML control * Update test for new HTML control * better command treatment --------- Co-authored-by: nisaba <infos@nisaba.solutions> Co-authored-by: Andrew Camilleri <evilkukka@gmail.com>
209 lines
8.4 KiB
C#
209 lines
8.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel.DataAnnotations;
|
|
using System.Globalization;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Abstractions.Constants;
|
|
using BTCPayServer.Abstractions.Extensions;
|
|
using BTCPayServer.Abstractions.Models;
|
|
using BTCPayServer.Client.Models;
|
|
using BTCPayServer.Data;
|
|
using BTCPayServer.Models.ServerViewModels;
|
|
using BTCPayServer.Services.Mails;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using MimeKit;
|
|
|
|
namespace BTCPayServer.Controllers
|
|
{
|
|
public partial class UIStoresController
|
|
{
|
|
[HttpGet("{storeId}/emails")]
|
|
public IActionResult StoreEmails(string storeId)
|
|
{
|
|
var store = HttpContext.GetStoreData();
|
|
if (store == null)
|
|
return NotFound();
|
|
|
|
var blob = store.GetStoreBlob();
|
|
var data = blob.EmailSettings;
|
|
if (data?.IsComplete() is not true)
|
|
{
|
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
|
{
|
|
Severity = StatusMessageModel.StatusSeverity.Warning,
|
|
Html = $"You need to configure email settings before this feature works. <a class='alert-link' href='{Url.Action("StoreEmailSettings", new { storeId })}'>Configure now</a>."
|
|
});
|
|
}
|
|
|
|
var vm = new StoreEmailRuleViewModel { Rules = blob.EmailRules ?? new List<StoreEmailRule>() };
|
|
return View(vm);
|
|
}
|
|
|
|
[HttpPost("{storeId}/emails")]
|
|
public async Task<IActionResult> StoreEmails(string storeId, StoreEmailRuleViewModel vm, string command)
|
|
{
|
|
vm.Rules ??= new List<StoreEmailRule>();
|
|
int index = 0;
|
|
var indSep = command.IndexOf(":", StringComparison.InvariantCultureIgnoreCase);
|
|
if (indSep > 0)
|
|
{
|
|
var item = command[(indSep + 1)..];
|
|
index = int.Parse(item, CultureInfo.InvariantCulture);
|
|
}
|
|
|
|
if (command.StartsWith("remove", StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
vm.Rules.RemoveAt(index);
|
|
}
|
|
else if (command == "add")
|
|
{
|
|
vm.Rules.Add(new StoreEmailRule());
|
|
|
|
return View(vm);
|
|
}
|
|
if (!ModelState.IsValid)
|
|
{
|
|
return View(vm);
|
|
}
|
|
|
|
var store = HttpContext.GetStoreData();
|
|
|
|
if (store == null)
|
|
return NotFound();
|
|
var blob = store.GetStoreBlob();
|
|
|
|
if (command.StartsWith("test", StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
var rule = vm.Rules[index];
|
|
if (string.IsNullOrEmpty(rule.Subject) || string.IsNullOrEmpty(rule.Body) || string.IsNullOrEmpty(rule.To))
|
|
{
|
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
|
{
|
|
Severity = StatusMessageModel.StatusSeverity.Warning,
|
|
Message = "Please fill all required fields before testing"
|
|
});
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
var emailSettings = blob.EmailSettings;
|
|
using var client = await emailSettings.CreateSmtpClient();
|
|
var message = emailSettings.CreateMailMessage(MailboxAddress.Parse(rule.To), "(test) " + rule.Subject, rule.Body, true);
|
|
await client.SendAsync(message);
|
|
await client.DisconnectAsync(true);
|
|
TempData[WellKnownTempData.SuccessMessage] = $"Rule email saved and sent to {rule.To}. Please verify you received it.";
|
|
|
|
blob.EmailRules = vm.Rules;
|
|
store.SetStoreBlob(blob);
|
|
await _Repo.UpdateStore(store);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TempData[WellKnownTempData.ErrorMessage] = "Error: " + ex.Message;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// UPDATE
|
|
blob.EmailRules = vm.Rules;
|
|
store.SetStoreBlob(blob);
|
|
await _Repo.UpdateStore(store);
|
|
TempData.SetStatusMessageModel(new StatusMessageModel
|
|
{
|
|
Severity = StatusMessageModel.StatusSeverity.Success,
|
|
Message = "Store email rules saved"
|
|
});
|
|
}
|
|
return RedirectToAction("StoreEmails", new { storeId });
|
|
}
|
|
|
|
public class StoreEmailRuleViewModel
|
|
{
|
|
public List<StoreEmailRule> Rules { get; set; }
|
|
}
|
|
|
|
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; }
|
|
}
|
|
|
|
[HttpGet("{storeId}/email-settings")]
|
|
public IActionResult StoreEmailSettings()
|
|
{
|
|
var store = HttpContext.GetStoreData();
|
|
if (store == null)
|
|
return NotFound();
|
|
var data = store.GetStoreBlob().EmailSettings ?? new EmailSettings();
|
|
return View(new EmailsViewModel(data));
|
|
}
|
|
|
|
[HttpPost("{storeId}/email-settings")]
|
|
public async Task<IActionResult> StoreEmailSettings(string storeId, EmailsViewModel model, string command)
|
|
{
|
|
var store = HttpContext.GetStoreData();
|
|
if (store == null)
|
|
return NotFound();
|
|
|
|
if (command == "Test")
|
|
{
|
|
try
|
|
{
|
|
if (model.PasswordSet)
|
|
{
|
|
model.Settings.Password = store.GetStoreBlob().EmailSettings.Password;
|
|
}
|
|
model.Settings.Validate("Settings.", ModelState);
|
|
if (string.IsNullOrEmpty(model.TestEmail))
|
|
ModelState.AddModelError(nameof(model.TestEmail), new RequiredAttribute().FormatErrorMessage(nameof(model.TestEmail)));
|
|
if (!ModelState.IsValid)
|
|
return View(model);
|
|
using var client = await model.Settings.CreateSmtpClient();
|
|
var message = model.Settings.CreateMailMessage(MailboxAddress.Parse(model.TestEmail), "BTCPay test", "BTCPay test", false);
|
|
await client.SendAsync(message);
|
|
await client.DisconnectAsync(true);
|
|
TempData[WellKnownTempData.SuccessMessage] = $"Email sent to {model.TestEmail}. Please verify you received it.";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
TempData[WellKnownTempData.ErrorMessage] = "Error: " + ex.Message;
|
|
}
|
|
return View(model);
|
|
}
|
|
if (command == "ResetPassword")
|
|
{
|
|
var storeBlob = store.GetStoreBlob();
|
|
storeBlob.EmailSettings.Password = null;
|
|
store.SetStoreBlob(storeBlob);
|
|
await _Repo.UpdateStore(store);
|
|
TempData[WellKnownTempData.SuccessMessage] = "Email server password reset";
|
|
return RedirectToAction(nameof(StoreEmailSettings), new { storeId });
|
|
}
|
|
else // if (command == "Save")
|
|
{
|
|
if (model.Settings.From is not null && !MailboxAddressValidator.IsMailboxAddress(model.Settings.From))
|
|
{
|
|
ModelState.AddModelError("Settings.From", "Invalid email");
|
|
return View(model);
|
|
}
|
|
var storeBlob = store.GetStoreBlob();
|
|
if (new EmailsViewModel(storeBlob.EmailSettings).PasswordSet && storeBlob.EmailSettings != null)
|
|
{
|
|
model.Settings.Password = storeBlob.EmailSettings.Password;
|
|
}
|
|
storeBlob.EmailSettings = model.Settings;
|
|
store.SetStoreBlob(storeBlob);
|
|
await _Repo.UpdateStore(store);
|
|
TempData[WellKnownTempData.SuccessMessage] = "Email settings modified";
|
|
return RedirectToAction(nameof(StoreEmailSettings), new { storeId });
|
|
}
|
|
}
|
|
}
|
|
}
|