mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-17 22:14:26 +01:00
Add Greenfield Store Email API
This commit is contained in:
@@ -7,6 +7,24 @@ namespace BTCPayServer.Client
|
||||
{
|
||||
public partial class BTCPayServerClient
|
||||
{
|
||||
public virtual async Task<EmailSettingsData> GetStoreEmailSettings(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/email", method: HttpMethod.Get),
|
||||
token);
|
||||
return await HandleResponse<EmailSettingsData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId, EmailSettingsData request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/email", bodyPayload: request, method: HttpMethod.Put),
|
||||
token);
|
||||
return await HandleResponse<EmailSettingsData>(response);
|
||||
}
|
||||
|
||||
public virtual async Task SendEmail(string storeId, SendEmailRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace BTCPayServer.Client
|
||||
await HandleResponse(response);
|
||||
}
|
||||
|
||||
public virtual async Task<StoreData> AddStoreUser(string storeId, StoreUserData request,
|
||||
public virtual async Task AddStoreUser(string storeId, StoreUserData request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
if (request == null)
|
||||
@@ -31,7 +31,7 @@ namespace BTCPayServer.Client
|
||||
using var response = await _httpClient.SendAsync(
|
||||
CreateHttpRequest($"api/v1/stores/{storeId}/users", bodyPayload: request, method: HttpMethod.Post),
|
||||
token);
|
||||
return await HandleResponse<StoreData>(response);
|
||||
await HandleResponse(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
BTCPayServer.Client/Models/EmailSettingsData.cs
Normal file
33
BTCPayServer.Client/Models/EmailSettingsData.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace BTCPayServer.Client.Models;
|
||||
|
||||
public class EmailSettingsData
|
||||
{
|
||||
public string Server
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public int? Port
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string Login
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string FromDisplay
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public string From
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
@@ -2292,13 +2292,27 @@ namespace BTCPayServer.Tests
|
||||
var admin = tester.NewAccount();
|
||||
await admin.GrantAccessAsync(true);
|
||||
var adminClient = await admin.CreateClient(Policies.Unrestricted);
|
||||
await adminClient.UpdateStoreEmailSettings(admin.StoreId,
|
||||
new EmailSettingsData());
|
||||
|
||||
await adminClient.SendEmail(admin.StoreId, new SendEmailRequest()
|
||||
var data = new EmailSettingsData()
|
||||
{
|
||||
Body = "lol",
|
||||
Subject = "subj",
|
||||
Email = "sdasdas"
|
||||
});
|
||||
From = "admin@admin.com",
|
||||
Login = "admin@admin.com",
|
||||
Password = "admin@admin.com",
|
||||
Port = 1234,
|
||||
Server = "admin.com",
|
||||
};
|
||||
await adminClient.UpdateStoreEmailSettings(admin.StoreId, data);
|
||||
var s = await adminClient.GetStoreEmailSettings(admin.StoreId);
|
||||
Assert.Equal(JsonConvert.SerializeObject(s), JsonConvert.SerializeObject(data));
|
||||
await AssertValidationError(new[] { nameof(EmailSettingsData.From) },
|
||||
async () => await adminClient.UpdateStoreEmailSettings(admin.StoreId,
|
||||
new EmailSettingsData() { From = "ass" }));
|
||||
|
||||
|
||||
await adminClient.SendEmail(admin.StoreId,
|
||||
new SendEmailRequest() { Body = "lol", Subject = "subj", Email = "sdasdas" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,10 @@ using BTCPayServer.Abstractions.Constants;
|
||||
using BTCPayServer.Abstractions.Extensions;
|
||||
using BTCPayServer.Client;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Services.Mails;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using BTCPayServer.Validation;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Cors;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
@@ -18,10 +21,12 @@ namespace BTCPayServer.Controllers.GreenField
|
||||
public class GreenfieldStoreEmailController : Controller
|
||||
{
|
||||
private readonly EmailSenderFactory _emailSenderFactory;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
|
||||
public GreenfieldStoreEmailController(EmailSenderFactory emailSenderFactory)
|
||||
public GreenfieldStoreEmailController(EmailSenderFactory emailSenderFactory, StoreRepository storeRepository)
|
||||
{
|
||||
_emailSenderFactory = emailSenderFactory;
|
||||
_storeRepository = storeRepository;
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
@@ -43,5 +48,48 @@ namespace BTCPayServer.Controllers.GreenField
|
||||
emailSender.SendEmail(request.Email, request.Subject, request.Body);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[HttpGet("~/api/v1/stores/{storeId}/email")]
|
||||
public IActionResult GetStoreEmailSettings()
|
||||
{
|
||||
|
||||
var store = HttpContext.GetStoreData();
|
||||
return store == null ? StoreNotFound() : Ok(FromModel(store));
|
||||
}
|
||||
|
||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||
[HttpPut("~/api/v1/stores/{storeId}/email")]
|
||||
public async Task<IActionResult> UpdateStoreEmailSettings(string storeId, EmailSettings request)
|
||||
{
|
||||
var store = HttpContext.GetStoreData();
|
||||
if (store == null)
|
||||
{
|
||||
return StoreNotFound();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(request.From) && !EmailValidator.IsEmail(request.From))
|
||||
{
|
||||
request.AddModelError(e => e.From,
|
||||
"Invalid email address", this);
|
||||
return this.CreateValidationError(ModelState);
|
||||
}
|
||||
var blob = store.GetStoreBlob();
|
||||
blob.EmailSettings = request;
|
||||
if (store.SetStoreBlob(blob))
|
||||
{
|
||||
await _storeRepository.UpdateStore(store);
|
||||
}
|
||||
|
||||
return Ok(FromModel(store));
|
||||
}
|
||||
private EmailSettings FromModel(Data.StoreData data)
|
||||
{
|
||||
return data.GetStoreBlob().EmailSettings??new();
|
||||
}
|
||||
private IActionResult StoreNotFound()
|
||||
{
|
||||
return this.CreateAPIError(404, "store-not-found", "The store was not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Controllers.GreenField;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Security.Greenfield;
|
||||
using BTCPayServer.Services.Mails;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
@@ -22,6 +23,8 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NBitcoin;
|
||||
using NBXplorer.Models;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using InvoiceData = BTCPayServer.Client.Models.InvoiceData;
|
||||
using Language = BTCPayServer.Client.Models.Language;
|
||||
using NotificationData = BTCPayServer.Client.Models.NotificationData;
|
||||
@@ -40,7 +43,10 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly IOptionsMonitor<IdentityOptions> _identityOptions;
|
||||
private readonly GreenfieldStoreOnChainPaymentMethodsController _chainPaymentMethodsController;
|
||||
private readonly GreenfieldStoreOnChainWalletsController _storeOnChainWalletsController;
|
||||
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController _storeLightningNetworkPaymentMethodsController;
|
||||
|
||||
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController
|
||||
_storeLightningNetworkPaymentMethodsController;
|
||||
|
||||
private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController;
|
||||
private readonly GreenfieldHealthController _healthController;
|
||||
private readonly GreenfieldPaymentRequestsController _paymentRequestController;
|
||||
@@ -58,6 +64,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly UIHomeController _homeController;
|
||||
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
|
||||
private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController;
|
||||
private readonly GreenfieldStoreUsersController _greenfieldStoreUsersController;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public BTCPayServerClientFactory(StoreRepository storeRepository,
|
||||
@@ -82,6 +89,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
UIHomeController homeController,
|
||||
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
|
||||
GreenfieldStoreEmailController greenfieldStoreEmailController,
|
||||
GreenfieldStoreUsersController greenfieldStoreUsersController,
|
||||
IServiceProvider serviceProvider)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
@@ -106,6 +114,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
_homeController = homeController;
|
||||
_storePaymentMethodsController = storePaymentMethodsController;
|
||||
_greenfieldStoreEmailController = greenfieldStoreEmailController;
|
||||
_greenfieldStoreUsersController = greenfieldStoreUsersController;
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
@@ -124,12 +133,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
claims.AddRange((await _userManager.GetRolesAsync(user)).Select(s =>
|
||||
new Claim(_identityOptions.CurrentValue.ClaimsIdentity.RoleClaimType, s)));
|
||||
context.User =
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims, $"Local{GreenfieldConstants.AuthenticationType}WithUser"));
|
||||
new ClaimsPrincipal(new ClaimsIdentity(claims,
|
||||
$"Local{GreenfieldConstants.AuthenticationType}WithUser"));
|
||||
}
|
||||
else
|
||||
{
|
||||
context.User =
|
||||
new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>(), $"Local{GreenfieldConstants.AuthenticationType}"));
|
||||
new ClaimsPrincipal(new ClaimsIdentity(new List<Claim>(),
|
||||
$"Local{GreenfieldConstants.AuthenticationType}"));
|
||||
}
|
||||
|
||||
if (storeIds?.Any() is true)
|
||||
@@ -163,12 +174,13 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
_homeController,
|
||||
_storePaymentMethodsController,
|
||||
_greenfieldStoreEmailController,
|
||||
_greenfieldStoreUsersController,
|
||||
new LocalHttpContextAccessor() { HttpContext = context }
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalHttpContextAccessor: IHttpContextAccessor
|
||||
public class LocalHttpContextAccessor : IHttpContextAccessor
|
||||
{
|
||||
public HttpContext? HttpContext { get; set; }
|
||||
}
|
||||
@@ -185,7 +197,10 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly GreenfieldStoresController _storesController;
|
||||
private readonly GreenfieldStoreLightningNodeApiController _storeLightningNodeApiController;
|
||||
private readonly GreenfieldInternalLightningNodeApiController _lightningNodeApiController;
|
||||
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController _storeLightningNetworkPaymentMethodsController;
|
||||
|
||||
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController
|
||||
_storeLightningNetworkPaymentMethodsController;
|
||||
|
||||
private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController;
|
||||
private readonly GreenfieldInvoiceController _greenFieldInvoiceController;
|
||||
private readonly GreenfieldServerInfoController _greenFieldServerInfoController;
|
||||
@@ -194,6 +209,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly UIHomeController _homeController;
|
||||
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
|
||||
private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController;
|
||||
private readonly GreenfieldStoreUsersController _greenfieldStoreUsersController;
|
||||
|
||||
public LocalBTCPayServerClient(
|
||||
IServiceProvider serviceProvider,
|
||||
@@ -216,6 +232,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
UIHomeController homeController,
|
||||
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
|
||||
GreenfieldStoreEmailController greenfieldStoreEmailController,
|
||||
GreenfieldStoreUsersController greenfieldStoreUsersController,
|
||||
IHttpContextAccessor httpContextAccessor) : base(new Uri("https://dummy.local"), "", "")
|
||||
{
|
||||
_chainPaymentMethodsController = chainPaymentMethodsController;
|
||||
@@ -237,6 +254,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
_homeController = homeController;
|
||||
_storePaymentMethodsController = storePaymentMethodsController;
|
||||
_greenfieldStoreEmailController = greenfieldStoreEmailController;
|
||||
_greenfieldStoreUsersController = greenfieldStoreUsersController;
|
||||
|
||||
var controllers = new[]
|
||||
{
|
||||
@@ -244,8 +262,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
paymentRequestController, apiKeysController, notificationsController, usersController,
|
||||
storeLightningNetworkPaymentMethodsController, greenFieldInvoiceController, storeWebhooksController,
|
||||
greenFieldServerInfoController, greenfieldPullPaymentController, storesController, homeController,
|
||||
lightningNodeApiController, storeLightningNodeApiController as ControllerBase, storePaymentMethodsController,
|
||||
greenfieldStoreEmailController
|
||||
lightningNodeApiController, storeLightningNodeApiController as ControllerBase,
|
||||
storePaymentMethodsController, greenfieldStoreEmailController, greenfieldStoreUsersController
|
||||
};
|
||||
|
||||
var authoverride = new DefaultAuthorizationService(
|
||||
@@ -259,8 +277,6 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
serviceProvider.GetRequiredService<IAuthorizationHandlerContextFactory>(),
|
||||
serviceProvider.GetRequiredService<IAuthorizationEvaluator>(),
|
||||
serviceProvider.GetRequiredService<IOptions<AuthorizationOptions>>()
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
@@ -268,7 +284,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
controller.ControllerContext.HttpContext = httpContextAccessor.HttpContext;
|
||||
var authInterface = typeof(IAuthorizationService);
|
||||
foreach (FieldInfo fieldInfo in controller.GetType().GetFields().Where(info => authInterface.IsAssignableFrom(info.FieldType)))
|
||||
foreach (FieldInfo fieldInfo in controller.GetType().GetFields()
|
||||
.Where(info => authInterface.IsAssignableFrom(info.FieldType)))
|
||||
{
|
||||
fieldInfo.SetValue(controller, authoverride);
|
||||
}
|
||||
@@ -283,12 +300,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly StoreRepository _storeRepository;
|
||||
|
||||
public AuthHandlerProvider(StoreRepository storeRepository, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor)
|
||||
public AuthHandlerProvider(StoreRepository storeRepository, UserManager<ApplicationUser> userManager,
|
||||
IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
_userManager = userManager;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<IAuthorizationHandler>> GetHandlersAsync(AuthorizationHandlerContext context)
|
||||
{
|
||||
return Task.FromResult<IEnumerable<IAuthorizationHandler>>(new IAuthorizationHandler[]
|
||||
@@ -297,6 +316,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
protected override HttpRequestMessage CreateHttpRequest(string path,
|
||||
Dictionary<string, object> queryPayload = null, HttpMethod method = null)
|
||||
{
|
||||
@@ -511,7 +531,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
await _lightningNodeApiController.GetDepositAddress(cryptoCode));
|
||||
}
|
||||
|
||||
public override async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode, PayLightningInvoiceRequest request,
|
||||
public override async Task<LightningPaymentData> PayLightningInvoice(string cryptoCode,
|
||||
PayLightningInvoiceRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<LightningPaymentData>(
|
||||
@@ -575,7 +596,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
public override Task<IEnumerable<OnChainPaymentMethodData>> GetStoreOnChainPaymentMethods(string storeId,
|
||||
bool? enabled, CancellationToken token)
|
||||
{
|
||||
return Task.FromResult(GetFromActionResult(_chainPaymentMethodsController.GetOnChainPaymentMethods(storeId, enabled)));
|
||||
return Task.FromResult(
|
||||
GetFromActionResult(_chainPaymentMethodsController.GetOnChainPaymentMethods(storeId, enabled)));
|
||||
}
|
||||
|
||||
public override Task<OnChainPaymentMethodData> GetStoreOnChainPaymentMethod(string storeId,
|
||||
@@ -596,7 +618,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<OnChainPaymentMethodData>(
|
||||
await _chainPaymentMethodsController.UpdateOnChainPaymentMethod(storeId, cryptoCode, new UpdateOnChainPaymentMethodRequest(
|
||||
await _chainPaymentMethodsController.UpdateOnChainPaymentMethod(storeId, cryptoCode,
|
||||
new UpdateOnChainPaymentMethodRequest(
|
||||
enabled: paymentMethod.Enabled,
|
||||
label: paymentMethod.Label,
|
||||
accountKeyPath: paymentMethod.AccountKeyPath,
|
||||
@@ -606,7 +629,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
|
||||
public override Task<OnChainPaymentMethodPreviewResultData> PreviewProposedStoreOnChainPaymentMethodAddresses(
|
||||
string storeId, string cryptoCode,
|
||||
UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0, int amount = 10, CancellationToken token = default)
|
||||
UpdateOnChainPaymentMethodRequest paymentMethod, int offset = 0, int amount = 10,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return Task.FromResult(GetFromActionResult<OnChainPaymentMethodPreviewResultData>(
|
||||
_chainPaymentMethodsController.GetProposedOnChainPaymentMethodPreview(storeId, cryptoCode,
|
||||
@@ -636,7 +660,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
public override async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<PaymentRequestData>(await _paymentRequestController.GetPaymentRequest(storeId, paymentRequestId));
|
||||
return GetFromActionResult<PaymentRequestData>(
|
||||
await _paymentRequestController.GetPaymentRequest(storeId, paymentRequestId));
|
||||
}
|
||||
|
||||
public override async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
||||
@@ -882,7 +907,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
{
|
||||
return GetFromActionResult<LightningNetworkPaymentMethodData>(await
|
||||
_storeLightningNetworkPaymentMethodsController.UpdateLightningNetworkPaymentMethod(storeId, cryptoCode,
|
||||
new UpdateLightningNetworkPaymentMethodRequest(paymentMethod.ConnectionString, paymentMethod.Enabled)));
|
||||
new UpdateLightningNetworkPaymentMethodRequest(paymentMethod.ConnectionString,
|
||||
paymentMethod.Enabled)));
|
||||
}
|
||||
|
||||
public override async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
||||
@@ -894,7 +920,6 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
int? skip = null,
|
||||
int? take = null,
|
||||
CancellationToken token = default
|
||||
|
||||
)
|
||||
{
|
||||
return GetFromActionResult<IEnumerable<InvoiceData>>(
|
||||
@@ -980,7 +1005,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
|
||||
public override Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
||||
{
|
||||
return Task.FromResult(_homeController.LanguageService.GetLanguages().Select(language => new Language(language.Code, language.DisplayName)).ToArray());
|
||||
return Task.FromResult(_homeController.LanguageService.GetLanguages()
|
||||
.Select(language => new Language(language.Code, language.DisplayName)).ToArray());
|
||||
}
|
||||
|
||||
public override Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
||||
@@ -988,15 +1014,19 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
return Task.FromResult(GetFromActionResult<PermissionMetadata[]>(_homeController.Permissions()));
|
||||
}
|
||||
|
||||
public override async Task<Dictionary<string, GenericPaymentMethodData>> GetStorePaymentMethods(string storeId, bool? enabled = null, CancellationToken token = default)
|
||||
public override async Task<Dictionary<string, GenericPaymentMethodData>> GetStorePaymentMethods(string storeId,
|
||||
bool? enabled = null, CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult(await _storePaymentMethodsController.GetStorePaymentMethods(storeId, enabled));
|
||||
}
|
||||
|
||||
public override async Task<OnChainPaymentMethodDataWithSensitiveData> GenerateOnChainWallet(string storeId, string cryptoCode, GenerateOnChainWalletRequest request,
|
||||
public override async Task<OnChainPaymentMethodDataWithSensitiveData> GenerateOnChainWallet(string storeId,
|
||||
string cryptoCode, GenerateOnChainWalletRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<OnChainPaymentMethodDataWithSensitiveData>(await _chainPaymentMethodsController.GenerateOnChainWallet(storeId, cryptoCode, new GenerateWalletRequest()
|
||||
return GetFromActionResult<OnChainPaymentMethodDataWithSensitiveData>(
|
||||
await _chainPaymentMethodsController.GenerateOnChainWallet(storeId, cryptoCode,
|
||||
new GenerateWalletRequest()
|
||||
{
|
||||
Passphrase = request.Passphrase,
|
||||
AccountNumber = request.AccountNumber,
|
||||
@@ -1009,9 +1039,53 @@ namespace BTCPayServer.Controllers.Greenfield
|
||||
}));
|
||||
}
|
||||
|
||||
public override async Task SendEmail(string storeId, SendEmailRequest request, CancellationToken token = default)
|
||||
public override async Task SendEmail(string storeId, SendEmailRequest request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
HandleActionResult(await _greenfieldStoreEmailController.SendEmailFromStore(storeId, request));
|
||||
}
|
||||
|
||||
public override Task<EmailSettingsData> GetStoreEmailSettings(string storeId, CancellationToken token = default)
|
||||
{
|
||||
return Task.FromResult(
|
||||
GetFromActionResult<EmailSettingsData>(_greenfieldStoreEmailController.GetStoreEmailSettings()));
|
||||
}
|
||||
|
||||
public override async Task<EmailSettingsData> UpdateStoreEmailSettings(string storeId,
|
||||
EmailSettingsData request, CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<EmailSettingsData>(
|
||||
await _greenfieldStoreEmailController.UpdateStoreEmailSettings(storeId,
|
||||
JObject.FromObject(request).ToObject<EmailSettings>()));
|
||||
}
|
||||
|
||||
public override async Task<ApplicationUserData[]> GetUsers(CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult(await _usersController.GetUsers());
|
||||
}
|
||||
|
||||
public override Task<IEnumerable<StoreUserData>> GetStoreUsers(string storeId,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return Task.FromResult(
|
||||
GetFromActionResult<IEnumerable<StoreUserData>>(_greenfieldStoreUsersController.GetStoreUsers()));
|
||||
}
|
||||
|
||||
public override async Task AddStoreUser(string storeId, StoreUserData request,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
HandleActionResult(await _greenfieldStoreUsersController.AddStoreUser(storeId, request));
|
||||
}
|
||||
|
||||
public override async Task RemoveStoreUser(string storeId, string userId, CancellationToken token = default)
|
||||
{
|
||||
HandleActionResult(await _greenfieldStoreUsersController.RemoveStoreUser(storeId, userId));
|
||||
}
|
||||
|
||||
public override async Task<ApplicationUserData> GetUserByIdOrEmail(string idOrEmail,
|
||||
CancellationToken token = default)
|
||||
{
|
||||
return GetFromActionResult<ApplicationUserData>(await _usersController.GetUser(idOrEmail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,48 +4,15 @@ using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using MailKit.Net.Smtp;
|
||||
using MimeKit;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace BTCPayServer.Services.Mails
|
||||
{
|
||||
public class EmailSettings
|
||||
public class EmailSettings :EmailSettingsData
|
||||
{
|
||||
[Display(Name = "SMTP Server")]
|
||||
public string Server
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public int? Port
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string Login
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string Password
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Display(Name = "Sender's display name")]
|
||||
public string FromDisplay
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[EmailAddress]
|
||||
[Display(Name = "Sender's email address")]
|
||||
public string From
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public bool IsComplete()
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(Server) &&
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Server" class="form-label"></label>
|
||||
<label asp-for="Settings.Server" class="form-label">SMTP Server</label>
|
||||
<input asp-for="Settings.Server" data-fill="server" class="form-control"/>
|
||||
<span asp-validation-for="Settings.Server" class="text-danger"></span>
|
||||
</div>
|
||||
@@ -38,7 +38,7 @@
|
||||
<span asp-validation-for="Settings.Port" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.FromDisplay" class="form-label"></label>
|
||||
<label asp-for="Settings.FromDisplay" class="form-label">Sender's display name</label>
|
||||
<input asp-for="Settings.FromDisplay" class="form-control"/>
|
||||
<small class="form-text text-muted">
|
||||
Some email providers (like Gmail) don't allow you to set your display name, so this setting may not have any effect.
|
||||
@@ -46,7 +46,7 @@
|
||||
<span asp-validation-for="Settings.FromDisplay" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.From" class="form-label"></label>
|
||||
<label asp-for="Settings.From" class="form-label">Sender's email address</label>
|
||||
<input asp-for="Settings.From" class="form-control"/>
|
||||
<span asp-validation-for="Settings.From" class="text-danger"></span>
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,109 @@
|
||||
{
|
||||
"paths": {
|
||||
"/api/v1/stores/{storeId}/email": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Stores (Email)"
|
||||
],
|
||||
"summary": "Get store email settings",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "storeId",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"description": "The store to fetch",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"description": "View email settings of the specified store",
|
||||
"operationId": "Stores_GetStoreEmailSettings",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "specified store email settings",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/EmailSettingsData"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "If you are authenticated but forbidden to view the specified store"
|
||||
},
|
||||
"404": {
|
||||
"description": "The key is not found for this store"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"API_Key": [
|
||||
"btcpay.store.canmodifystoresettings"
|
||||
],
|
||||
"Basic": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"Stores (Email)"
|
||||
],
|
||||
"summary": "Update store email settings",
|
||||
"description": "Update a store's email settings",
|
||||
"operationId": "Stores_UpdateStoreEmailSettings",
|
||||
"requestBody": {
|
||||
"x-name": "request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/EmailSettingsData"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true,
|
||||
"x-position": 1
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The settings were updated",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/EmailSettingsData"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "A list of errors that occurred when updating the settings",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ValidationProblemDetails"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"403": {
|
||||
"description": "If you are authenticated but forbidden to modify the store"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"API_Key": [
|
||||
"btcpay.store.canmodifystoresettings"
|
||||
],
|
||||
"Basic": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v1/stores/{storeId}/email/send": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"Stores"
|
||||
"Stores (Email)"
|
||||
],
|
||||
"summary": "Send an email for a store",
|
||||
"description": "Send an email using the store's SMTP server",
|
||||
@@ -63,12 +163,43 @@
|
||||
"description": "Body of the email to send as plain text."
|
||||
}
|
||||
}
|
||||
},
|
||||
"EmailSettingsData": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"server": {
|
||||
"type": "string",
|
||||
"description": "Smtp server host"
|
||||
},
|
||||
"port": {
|
||||
"type": "number",
|
||||
"description": "Smtp server port"
|
||||
},
|
||||
"login": {
|
||||
"type": "string",
|
||||
"description": "Smtp server username"
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"description": "Smtp server password"
|
||||
},
|
||||
"from": {
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
"description": "Email to send from"
|
||||
},
|
||||
"fromDisplay": {
|
||||
"type": "string",
|
||||
"description": "The name of the sender"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
{
|
||||
"name": "Store Email"
|
||||
"name": "Stores (Email)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
],
|
||||
"summary": "Add a store user",
|
||||
"description": "Add a store user",
|
||||
"operationId": "Stores_AddStoreUser",
|
||||
"requestBody": {
|
||||
"x-name": "request",
|
||||
"content": {
|
||||
@@ -66,7 +67,7 @@
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The user as added"
|
||||
"description": "The user was added"
|
||||
},
|
||||
"400": {
|
||||
"description": "A list of errors that occurred when creating the store",
|
||||
@@ -108,6 +109,7 @@
|
||||
"Stores (Users)"
|
||||
],
|
||||
"summary": "Remove Store User",
|
||||
"operationId": "Stores_RemoveStoreUser",
|
||||
"description": "Removes the specified store user. If there is no other owner, this endpoint will fail.",
|
||||
"parameters": [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user