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 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,
|
public virtual async Task SendEmail(string storeId, SendEmailRequest request,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace BTCPayServer.Client
|
|||||||
await HandleResponse(response);
|
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)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
if (request == null)
|
if (request == null)
|
||||||
@@ -31,7 +31,7 @@ namespace BTCPayServer.Client
|
|||||||
using var response = await _httpClient.SendAsync(
|
using var response = await _httpClient.SendAsync(
|
||||||
CreateHttpRequest($"api/v1/stores/{storeId}/users", bodyPayload: request, method: HttpMethod.Post),
|
CreateHttpRequest($"api/v1/stores/{storeId}/users", bodyPayload: request, method: HttpMethod.Post),
|
||||||
token);
|
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();
|
var admin = tester.NewAccount();
|
||||||
await admin.GrantAccessAsync(true);
|
await admin.GrantAccessAsync(true);
|
||||||
var adminClient = await admin.CreateClient(Policies.Unrestricted);
|
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",
|
From = "admin@admin.com",
|
||||||
Subject = "subj",
|
Login = "admin@admin.com",
|
||||||
Email = "sdasdas"
|
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.Abstractions.Extensions;
|
||||||
using BTCPayServer.Client;
|
using BTCPayServer.Client;
|
||||||
using BTCPayServer.Client.Models;
|
using BTCPayServer.Client.Models;
|
||||||
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Services.Mails;
|
using BTCPayServer.Services.Mails;
|
||||||
|
using BTCPayServer.Services.Stores;
|
||||||
|
using BTCPayServer.Validation;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Cors;
|
using Microsoft.AspNetCore.Cors;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@@ -18,10 +21,12 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
public class GreenfieldStoreEmailController : Controller
|
public class GreenfieldStoreEmailController : Controller
|
||||||
{
|
{
|
||||||
private readonly EmailSenderFactory _emailSenderFactory;
|
private readonly EmailSenderFactory _emailSenderFactory;
|
||||||
|
private readonly StoreRepository _storeRepository;
|
||||||
|
|
||||||
public GreenfieldStoreEmailController(EmailSenderFactory emailSenderFactory)
|
public GreenfieldStoreEmailController(EmailSenderFactory emailSenderFactory, StoreRepository storeRepository)
|
||||||
{
|
{
|
||||||
_emailSenderFactory = emailSenderFactory;
|
_emailSenderFactory = emailSenderFactory;
|
||||||
|
_storeRepository = storeRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
[Authorize(Policy = Policies.CanModifyStoreSettings, AuthenticationSchemes = AuthenticationSchemes.Greenfield)]
|
||||||
@@ -43,5 +48,48 @@ namespace BTCPayServer.Controllers.GreenField
|
|||||||
emailSender.SendEmail(request.Email, request.Subject, request.Body);
|
emailSender.SendEmail(request.Email, request.Subject, request.Body);
|
||||||
return Ok();
|
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.Controllers.GreenField;
|
||||||
using BTCPayServer.Data;
|
using BTCPayServer.Data;
|
||||||
using BTCPayServer.Security.Greenfield;
|
using BTCPayServer.Security.Greenfield;
|
||||||
|
using BTCPayServer.Services.Mails;
|
||||||
using BTCPayServer.Services.Stores;
|
using BTCPayServer.Services.Stores;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
@@ -22,6 +23,8 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using NBitcoin;
|
using NBitcoin;
|
||||||
using NBXplorer.Models;
|
using NBXplorer.Models;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
using InvoiceData = BTCPayServer.Client.Models.InvoiceData;
|
using InvoiceData = BTCPayServer.Client.Models.InvoiceData;
|
||||||
using Language = BTCPayServer.Client.Models.Language;
|
using Language = BTCPayServer.Client.Models.Language;
|
||||||
using NotificationData = BTCPayServer.Client.Models.NotificationData;
|
using NotificationData = BTCPayServer.Client.Models.NotificationData;
|
||||||
@@ -40,7 +43,10 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
private readonly IOptionsMonitor<IdentityOptions> _identityOptions;
|
private readonly IOptionsMonitor<IdentityOptions> _identityOptions;
|
||||||
private readonly GreenfieldStoreOnChainPaymentMethodsController _chainPaymentMethodsController;
|
private readonly GreenfieldStoreOnChainPaymentMethodsController _chainPaymentMethodsController;
|
||||||
private readonly GreenfieldStoreOnChainWalletsController _storeOnChainWalletsController;
|
private readonly GreenfieldStoreOnChainWalletsController _storeOnChainWalletsController;
|
||||||
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController _storeLightningNetworkPaymentMethodsController;
|
|
||||||
|
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController
|
||||||
|
_storeLightningNetworkPaymentMethodsController;
|
||||||
|
|
||||||
private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController;
|
private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController;
|
||||||
private readonly GreenfieldHealthController _healthController;
|
private readonly GreenfieldHealthController _healthController;
|
||||||
private readonly GreenfieldPaymentRequestsController _paymentRequestController;
|
private readonly GreenfieldPaymentRequestsController _paymentRequestController;
|
||||||
@@ -58,6 +64,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
private readonly UIHomeController _homeController;
|
private readonly UIHomeController _homeController;
|
||||||
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
|
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
|
||||||
private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController;
|
private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController;
|
||||||
|
private readonly GreenfieldStoreUsersController _greenfieldStoreUsersController;
|
||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
public BTCPayServerClientFactory(StoreRepository storeRepository,
|
public BTCPayServerClientFactory(StoreRepository storeRepository,
|
||||||
@@ -82,6 +89,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
UIHomeController homeController,
|
UIHomeController homeController,
|
||||||
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
|
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
|
||||||
GreenfieldStoreEmailController greenfieldStoreEmailController,
|
GreenfieldStoreEmailController greenfieldStoreEmailController,
|
||||||
|
GreenfieldStoreUsersController greenfieldStoreUsersController,
|
||||||
IServiceProvider serviceProvider)
|
IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_storeRepository = storeRepository;
|
_storeRepository = storeRepository;
|
||||||
@@ -106,6 +114,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
_homeController = homeController;
|
_homeController = homeController;
|
||||||
_storePaymentMethodsController = storePaymentMethodsController;
|
_storePaymentMethodsController = storePaymentMethodsController;
|
||||||
_greenfieldStoreEmailController = greenfieldStoreEmailController;
|
_greenfieldStoreEmailController = greenfieldStoreEmailController;
|
||||||
|
_greenfieldStoreUsersController = greenfieldStoreUsersController;
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,12 +133,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
claims.AddRange((await _userManager.GetRolesAsync(user)).Select(s =>
|
claims.AddRange((await _userManager.GetRolesAsync(user)).Select(s =>
|
||||||
new Claim(_identityOptions.CurrentValue.ClaimsIdentity.RoleClaimType, s)));
|
new Claim(_identityOptions.CurrentValue.ClaimsIdentity.RoleClaimType, s)));
|
||||||
context.User =
|
context.User =
|
||||||
new ClaimsPrincipal(new ClaimsIdentity(claims, $"Local{GreenfieldConstants.AuthenticationType}WithUser"));
|
new ClaimsPrincipal(new ClaimsIdentity(claims,
|
||||||
|
$"Local{GreenfieldConstants.AuthenticationType}WithUser"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.User =
|
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)
|
if (storeIds?.Any() is true)
|
||||||
@@ -163,15 +174,16 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
_homeController,
|
_homeController,
|
||||||
_storePaymentMethodsController,
|
_storePaymentMethodsController,
|
||||||
_greenfieldStoreEmailController,
|
_greenfieldStoreEmailController,
|
||||||
|
_greenfieldStoreUsersController,
|
||||||
new LocalHttpContextAccessor() { HttpContext = context }
|
new LocalHttpContextAccessor() { HttpContext = context }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LocalHttpContextAccessor: IHttpContextAccessor
|
public class LocalHttpContextAccessor : IHttpContextAccessor
|
||||||
{
|
{
|
||||||
public HttpContext? HttpContext { get; set; }
|
public HttpContext? HttpContext { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LocalBTCPayServerClient : BTCPayServerClient
|
public class LocalBTCPayServerClient : BTCPayServerClient
|
||||||
{
|
{
|
||||||
@@ -185,7 +197,10 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
private readonly GreenfieldStoresController _storesController;
|
private readonly GreenfieldStoresController _storesController;
|
||||||
private readonly GreenfieldStoreLightningNodeApiController _storeLightningNodeApiController;
|
private readonly GreenfieldStoreLightningNodeApiController _storeLightningNodeApiController;
|
||||||
private readonly GreenfieldInternalLightningNodeApiController _lightningNodeApiController;
|
private readonly GreenfieldInternalLightningNodeApiController _lightningNodeApiController;
|
||||||
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController _storeLightningNetworkPaymentMethodsController;
|
|
||||||
|
private readonly GreenfieldStoreLightningNetworkPaymentMethodsController
|
||||||
|
_storeLightningNetworkPaymentMethodsController;
|
||||||
|
|
||||||
private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController;
|
private readonly GreenfieldStoreLNURLPayPaymentMethodsController _storeLnurlPayPaymentMethodsController;
|
||||||
private readonly GreenfieldInvoiceController _greenFieldInvoiceController;
|
private readonly GreenfieldInvoiceController _greenFieldInvoiceController;
|
||||||
private readonly GreenfieldServerInfoController _greenFieldServerInfoController;
|
private readonly GreenfieldServerInfoController _greenFieldServerInfoController;
|
||||||
@@ -194,6 +209,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
private readonly UIHomeController _homeController;
|
private readonly UIHomeController _homeController;
|
||||||
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
|
private readonly GreenfieldStorePaymentMethodsController _storePaymentMethodsController;
|
||||||
private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController;
|
private readonly GreenfieldStoreEmailController _greenfieldStoreEmailController;
|
||||||
|
private readonly GreenfieldStoreUsersController _greenfieldStoreUsersController;
|
||||||
|
|
||||||
public LocalBTCPayServerClient(
|
public LocalBTCPayServerClient(
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
@@ -216,6 +232,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
UIHomeController homeController,
|
UIHomeController homeController,
|
||||||
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
|
GreenfieldStorePaymentMethodsController storePaymentMethodsController,
|
||||||
GreenfieldStoreEmailController greenfieldStoreEmailController,
|
GreenfieldStoreEmailController greenfieldStoreEmailController,
|
||||||
|
GreenfieldStoreUsersController greenfieldStoreUsersController,
|
||||||
IHttpContextAccessor httpContextAccessor) : base(new Uri("https://dummy.local"), "", "")
|
IHttpContextAccessor httpContextAccessor) : base(new Uri("https://dummy.local"), "", "")
|
||||||
{
|
{
|
||||||
_chainPaymentMethodsController = chainPaymentMethodsController;
|
_chainPaymentMethodsController = chainPaymentMethodsController;
|
||||||
@@ -237,6 +254,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
_homeController = homeController;
|
_homeController = homeController;
|
||||||
_storePaymentMethodsController = storePaymentMethodsController;
|
_storePaymentMethodsController = storePaymentMethodsController;
|
||||||
_greenfieldStoreEmailController = greenfieldStoreEmailController;
|
_greenfieldStoreEmailController = greenfieldStoreEmailController;
|
||||||
|
_greenfieldStoreUsersController = greenfieldStoreUsersController;
|
||||||
|
|
||||||
var controllers = new[]
|
var controllers = new[]
|
||||||
{
|
{
|
||||||
@@ -244,14 +262,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
paymentRequestController, apiKeysController, notificationsController, usersController,
|
paymentRequestController, apiKeysController, notificationsController, usersController,
|
||||||
storeLightningNetworkPaymentMethodsController, greenFieldInvoiceController, storeWebhooksController,
|
storeLightningNetworkPaymentMethodsController, greenFieldInvoiceController, storeWebhooksController,
|
||||||
greenFieldServerInfoController, greenfieldPullPaymentController, storesController, homeController,
|
greenFieldServerInfoController, greenfieldPullPaymentController, storesController, homeController,
|
||||||
lightningNodeApiController, storeLightningNodeApiController as ControllerBase, storePaymentMethodsController,
|
lightningNodeApiController, storeLightningNodeApiController as ControllerBase,
|
||||||
greenfieldStoreEmailController
|
storePaymentMethodsController, greenfieldStoreEmailController, greenfieldStoreUsersController
|
||||||
};
|
};
|
||||||
|
|
||||||
var authoverride = new DefaultAuthorizationService(
|
var authoverride = new DefaultAuthorizationService(
|
||||||
serviceProvider.GetRequiredService<IAuthorizationPolicyProvider>(),
|
serviceProvider.GetRequiredService<IAuthorizationPolicyProvider>(),
|
||||||
new AuthHandlerProvider(
|
new AuthHandlerProvider(
|
||||||
serviceProvider.GetRequiredService<StoreRepository>(),
|
serviceProvider.GetRequiredService<StoreRepository>(),
|
||||||
serviceProvider.GetRequiredService<UserManager<ApplicationUser>>(),
|
serviceProvider.GetRequiredService<UserManager<ApplicationUser>>(),
|
||||||
httpContextAccessor
|
httpContextAccessor
|
||||||
),
|
),
|
||||||
@@ -259,16 +277,15 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
serviceProvider.GetRequiredService<IAuthorizationHandlerContextFactory>(),
|
serviceProvider.GetRequiredService<IAuthorizationHandlerContextFactory>(),
|
||||||
serviceProvider.GetRequiredService<IAuthorizationEvaluator>(),
|
serviceProvider.GetRequiredService<IAuthorizationEvaluator>(),
|
||||||
serviceProvider.GetRequiredService<IOptions<AuthorizationOptions>>()
|
serviceProvider.GetRequiredService<IOptions<AuthorizationOptions>>()
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
foreach (var controller in controllers)
|
foreach (var controller in controllers)
|
||||||
{
|
{
|
||||||
controller.ControllerContext.HttpContext = httpContextAccessor.HttpContext;
|
controller.ControllerContext.HttpContext = httpContextAccessor.HttpContext;
|
||||||
var authInterface = typeof(IAuthorizationService);
|
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);
|
fieldInfo.SetValue(controller, authoverride);
|
||||||
}
|
}
|
||||||
@@ -283,12 +300,14 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
private readonly UserManager<ApplicationUser> _userManager;
|
private readonly UserManager<ApplicationUser> _userManager;
|
||||||
private readonly StoreRepository _storeRepository;
|
private readonly StoreRepository _storeRepository;
|
||||||
|
|
||||||
public AuthHandlerProvider(StoreRepository storeRepository, UserManager<ApplicationUser> userManager, IHttpContextAccessor httpContextAccessor)
|
public AuthHandlerProvider(StoreRepository storeRepository, UserManager<ApplicationUser> userManager,
|
||||||
|
IHttpContextAccessor httpContextAccessor)
|
||||||
{
|
{
|
||||||
_storeRepository = storeRepository;
|
_storeRepository = storeRepository;
|
||||||
_userManager = userManager;
|
_userManager = userManager;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<IEnumerable<IAuthorizationHandler>> GetHandlersAsync(AuthorizationHandlerContext context)
|
public Task<IEnumerable<IAuthorizationHandler>> GetHandlersAsync(AuthorizationHandlerContext context)
|
||||||
{
|
{
|
||||||
return Task.FromResult<IEnumerable<IAuthorizationHandler>>(new IAuthorizationHandler[]
|
return Task.FromResult<IEnumerable<IAuthorizationHandler>>(new IAuthorizationHandler[]
|
||||||
@@ -297,6 +316,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override HttpRequestMessage CreateHttpRequest(string path,
|
protected override HttpRequestMessage CreateHttpRequest(string path,
|
||||||
Dictionary<string, object> queryPayload = null, HttpMethod method = null)
|
Dictionary<string, object> queryPayload = null, HttpMethod method = null)
|
||||||
{
|
{
|
||||||
@@ -511,7 +531,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
await _lightningNodeApiController.GetDepositAddress(cryptoCode));
|
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)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return GetFromActionResult<LightningPaymentData>(
|
return GetFromActionResult<LightningPaymentData>(
|
||||||
@@ -575,7 +596,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
public override Task<IEnumerable<OnChainPaymentMethodData>> GetStoreOnChainPaymentMethods(string storeId,
|
public override Task<IEnumerable<OnChainPaymentMethodData>> GetStoreOnChainPaymentMethods(string storeId,
|
||||||
bool? enabled, CancellationToken token)
|
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,
|
public override Task<OnChainPaymentMethodData> GetStoreOnChainPaymentMethod(string storeId,
|
||||||
@@ -596,17 +618,19 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return GetFromActionResult<OnChainPaymentMethodData>(
|
return GetFromActionResult<OnChainPaymentMethodData>(
|
||||||
await _chainPaymentMethodsController.UpdateOnChainPaymentMethod(storeId, cryptoCode, new UpdateOnChainPaymentMethodRequest(
|
await _chainPaymentMethodsController.UpdateOnChainPaymentMethod(storeId, cryptoCode,
|
||||||
enabled: paymentMethod.Enabled,
|
new UpdateOnChainPaymentMethodRequest(
|
||||||
label: paymentMethod.Label,
|
enabled: paymentMethod.Enabled,
|
||||||
accountKeyPath: paymentMethod.AccountKeyPath,
|
label: paymentMethod.Label,
|
||||||
derivationScheme: paymentMethod.DerivationScheme
|
accountKeyPath: paymentMethod.AccountKeyPath,
|
||||||
)));
|
derivationScheme: paymentMethod.DerivationScheme
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<OnChainPaymentMethodPreviewResultData> PreviewProposedStoreOnChainPaymentMethodAddresses(
|
public override Task<OnChainPaymentMethodPreviewResultData> PreviewProposedStoreOnChainPaymentMethodAddresses(
|
||||||
string storeId, string cryptoCode,
|
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>(
|
return Task.FromResult(GetFromActionResult<OnChainPaymentMethodPreviewResultData>(
|
||||||
_chainPaymentMethodsController.GetProposedOnChainPaymentMethodPreview(storeId, cryptoCode,
|
_chainPaymentMethodsController.GetProposedOnChainPaymentMethodPreview(storeId, cryptoCode,
|
||||||
@@ -618,7 +642,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return Task.FromResult(GetFromActionResult<OnChainPaymentMethodPreviewResultData>(
|
return Task.FromResult(GetFromActionResult<OnChainPaymentMethodPreviewResultData>(
|
||||||
_chainPaymentMethodsController.GetOnChainPaymentMethodPreview(storeId, cryptoCode, offset,
|
_chainPaymentMethodsController.GetOnChainPaymentMethodPreview(storeId, cryptoCode, offset,
|
||||||
amount)));
|
amount)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,7 +660,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
public override async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
public override async Task<PaymentRequestData> GetPaymentRequest(string storeId, string paymentRequestId,
|
||||||
CancellationToken token = default)
|
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,
|
public override async Task ArchivePaymentRequest(string storeId, string paymentRequestId,
|
||||||
@@ -882,7 +907,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
{
|
{
|
||||||
return GetFromActionResult<LightningNetworkPaymentMethodData>(await
|
return GetFromActionResult<LightningNetworkPaymentMethodData>(await
|
||||||
_storeLightningNetworkPaymentMethodsController.UpdateLightningNetworkPaymentMethod(storeId, cryptoCode,
|
_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,
|
public override async Task<IEnumerable<InvoiceData>> GetInvoices(string storeId, string[] orderId = null,
|
||||||
@@ -894,8 +920,7 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
int? skip = null,
|
int? skip = null,
|
||||||
int? take = null,
|
int? take = null,
|
||||||
CancellationToken token = default
|
CancellationToken token = default
|
||||||
|
)
|
||||||
)
|
|
||||||
{
|
{
|
||||||
return GetFromActionResult<IEnumerable<InvoiceData>>(
|
return GetFromActionResult<IEnumerable<InvoiceData>>(
|
||||||
await _greenFieldInvoiceController.GetInvoices(storeId, orderId,
|
await _greenFieldInvoiceController.GetInvoices(storeId, orderId,
|
||||||
@@ -980,7 +1005,8 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
|
|
||||||
public override Task<Language[]> GetAvailableLanguages(CancellationToken token = default)
|
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)
|
public override Task<PermissionMetadata[]> GetPermissionMetadata(CancellationToken token = default)
|
||||||
@@ -988,30 +1014,78 @@ namespace BTCPayServer.Controllers.Greenfield
|
|||||||
return Task.FromResult(GetFromActionResult<PermissionMetadata[]>(_homeController.Permissions()));
|
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));
|
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)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
return GetFromActionResult<OnChainPaymentMethodDataWithSensitiveData>(await _chainPaymentMethodsController.GenerateOnChainWallet(storeId, cryptoCode, new GenerateWalletRequest()
|
return GetFromActionResult<OnChainPaymentMethodDataWithSensitiveData>(
|
||||||
{
|
await _chainPaymentMethodsController.GenerateOnChainWallet(storeId, cryptoCode,
|
||||||
Passphrase = request.Passphrase,
|
new GenerateWalletRequest()
|
||||||
AccountNumber = request.AccountNumber,
|
{
|
||||||
ExistingMnemonic = request.ExistingMnemonic?.ToString(),
|
Passphrase = request.Passphrase,
|
||||||
WordCount = request.WordCount,
|
AccountNumber = request.AccountNumber,
|
||||||
WordList = request.WordList,
|
ExistingMnemonic = request.ExistingMnemonic?.ToString(),
|
||||||
SavePrivateKeys = request.SavePrivateKeys,
|
WordCount = request.WordCount,
|
||||||
ScriptPubKeyType = request.ScriptPubKeyType,
|
WordList = request.WordList,
|
||||||
ImportKeysToRPC = request.ImportKeysToRPC
|
SavePrivateKeys = request.SavePrivateKeys,
|
||||||
}));
|
ScriptPubKeyType = request.ScriptPubKeyType,
|
||||||
|
ImportKeysToRPC = request.ImportKeysToRPC
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
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));
|
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.Security.Cryptography.X509Certificates;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using BTCPayServer.Client.Models;
|
||||||
using MailKit.Net.Smtp;
|
using MailKit.Net.Smtp;
|
||||||
using MimeKit;
|
using MimeKit;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace BTCPayServer.Services.Mails
|
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()
|
public bool IsComplete()
|
||||||
{
|
{
|
||||||
return !string.IsNullOrWhiteSpace(Server) &&
|
return !string.IsNullOrWhiteSpace(Server) &&
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
<div asp-validation-summary="All" class="text-danger"></div>
|
<div asp-validation-summary="All" class="text-danger"></div>
|
||||||
}
|
}
|
||||||
<div class="form-group">
|
<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"/>
|
<input asp-for="Settings.Server" data-fill="server" class="form-control"/>
|
||||||
<span asp-validation-for="Settings.Server" class="text-danger"></span>
|
<span asp-validation-for="Settings.Server" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
<span asp-validation-for="Settings.Port" class="text-danger"></span>
|
<span asp-validation-for="Settings.Port" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<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"/>
|
<input asp-for="Settings.FromDisplay" class="form-control"/>
|
||||||
<small class="form-text text-muted">
|
<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.
|
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>
|
<span asp-validation-for="Settings.FromDisplay" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<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"/>
|
<input asp-for="Settings.From" class="form-control"/>
|
||||||
<span asp-validation-for="Settings.From" class="text-danger"></span>
|
<span asp-validation-for="Settings.From" class="text-danger"></span>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,9 +1,109 @@
|
|||||||
{
|
{
|
||||||
"paths": {
|
"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": {
|
"/api/v1/stores/{storeId}/email/send": {
|
||||||
"post": {
|
"post": {
|
||||||
"tags": [
|
"tags": [
|
||||||
"Stores"
|
"Stores (Email)"
|
||||||
],
|
],
|
||||||
"summary": "Send an email for a store",
|
"summary": "Send an email for a store",
|
||||||
"description": "Send an email using the store's SMTP server",
|
"description": "Send an email using the store's SMTP server",
|
||||||
@@ -63,12 +163,43 @@
|
|||||||
"description": "Body of the email to send as plain text."
|
"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": [
|
"tags": [
|
||||||
{
|
{
|
||||||
"name": "Store Email"
|
"name": "Stores (Email)"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
],
|
],
|
||||||
"summary": "Add a store user",
|
"summary": "Add a store user",
|
||||||
"description": "Add a store user",
|
"description": "Add a store user",
|
||||||
|
"operationId": "Stores_AddStoreUser",
|
||||||
"requestBody": {
|
"requestBody": {
|
||||||
"x-name": "request",
|
"x-name": "request",
|
||||||
"content": {
|
"content": {
|
||||||
@@ -66,7 +67,7 @@
|
|||||||
},
|
},
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "The user as added"
|
"description": "The user was added"
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": "A list of errors that occurred when creating the store",
|
"description": "A list of errors that occurred when creating the store",
|
||||||
@@ -108,6 +109,7 @@
|
|||||||
"Stores (Users)"
|
"Stores (Users)"
|
||||||
],
|
],
|
||||||
"summary": "Remove Store User",
|
"summary": "Remove Store User",
|
||||||
|
"operationId": "Stores_RemoveStoreUser",
|
||||||
"description": "Removes the specified store user. If there is no other owner, this endpoint will fail.",
|
"description": "Removes the specified store user. If there is no other owner, this endpoint will fail.",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user