mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2024-11-19 01:43:50 +01:00
Can configure multiple dynamic dns
This commit is contained in:
parent
db57b5ae80
commit
63472d54d7
@ -146,6 +146,9 @@
|
||||
<Content Update="Views\Home\BitpayTranslator.cshtml">
|
||||
<Pack>$(IncludeRazorContentInPack)</Pack>
|
||||
</Content>
|
||||
<Content Update="Views\Server\DynamicDnsServices.cshtml">
|
||||
<Pack>$(IncludeRazorContentInPack)</Pack>
|
||||
</Content>
|
||||
<Content Update="Views\Server\LightningChargeServices.cshtml">
|
||||
<Pack>$(IncludeRazorContentInPack)</Pack>
|
||||
</Content>
|
||||
|
@ -548,7 +548,7 @@ namespace BTCPayServer.Controllers
|
||||
result.OtherExternalServices.Add(new ServicesViewModel.OtherExternalService()
|
||||
{
|
||||
Name = "Dynamic DNS",
|
||||
Link = this.Url.Action(nameof(DynamicDnsService))
|
||||
Link = this.Url.Action(nameof(DynamicDnsServices))
|
||||
});
|
||||
foreach (var torService in _torServices.Services)
|
||||
{
|
||||
@ -806,37 +806,99 @@ namespace BTCPayServer.Controllers
|
||||
return RedirectToAction(nameof(Service), new { cryptoCode = cryptoCode, serviceName = serviceName, nonce = nonce });
|
||||
}
|
||||
|
||||
|
||||
[Route("server/services/dynamic-dns")]
|
||||
public async Task<IActionResult> DynamicDnsService()
|
||||
public async Task<IActionResult> DynamicDnsServices()
|
||||
{
|
||||
var settings = (await _SettingsRepository.GetSettingAsync<DynamicDnsSettings>()) ?? new DynamicDnsSettings();
|
||||
return View(settings.Services.Select(s => new DynamicDnsViewModel()
|
||||
{
|
||||
Settings = s
|
||||
}).ToArray());
|
||||
}
|
||||
[Route("server/services/dynamic-dns/{hostname}")]
|
||||
public async Task<IActionResult> DynamicDnsServices(string hostname)
|
||||
{
|
||||
var settings = (await _SettingsRepository.GetSettingAsync<DynamicDnsSettings>()) ?? new DynamicDnsSettings();
|
||||
var service = settings.Services.FirstOrDefault(s => s.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase));
|
||||
if (service == null)
|
||||
return NotFound();
|
||||
var vm = new DynamicDnsViewModel();
|
||||
vm.Settings = settings;
|
||||
return View(vm);
|
||||
vm.Modify = true;
|
||||
vm.Settings = service;
|
||||
return View(nameof(DynamicDnsService), vm);
|
||||
}
|
||||
[Route("server/services/dynamic-dns")]
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> DynamicDnsService(DynamicDnsViewModel viewModel, string command = null)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(viewModel);
|
||||
}
|
||||
if (command == "Save")
|
||||
{
|
||||
var settings = (await _SettingsRepository.GetSettingAsync<DynamicDnsSettings>()) ?? new DynamicDnsSettings();
|
||||
var i = settings.Services.FindIndex(d => d.Hostname.Equals(viewModel.Settings.Hostname, StringComparison.OrdinalIgnoreCase));
|
||||
if (i != -1)
|
||||
{
|
||||
ModelState.AddModelError(nameof(viewModel.Settings.Hostname), "This hostname already exists");
|
||||
return View(viewModel);
|
||||
}
|
||||
string errorMessage = await viewModel.Settings.SendUpdateRequest(HttpClientFactory.CreateClient());
|
||||
if (errorMessage == null)
|
||||
{
|
||||
StatusMessage = $"The Dynamic DNS has been successfully queried, your configuration is saved";
|
||||
viewModel.Settings.LastUpdated = DateTimeOffset.UtcNow;
|
||||
settings.Services.Add(viewModel.Settings);
|
||||
await _SettingsRepository.UpdateSetting(settings);
|
||||
return RedirectToAction(nameof(DynamicDnsServices));
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, errorMessage);
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return View(new DynamicDnsViewModel() { Settings = new DynamicDnsService() });
|
||||
}
|
||||
}
|
||||
[Route("server/services/dynamic-dns/{hostname}")]
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> DynamicDnsService(DynamicDnsViewModel viewModel, string hostname, string command = null)
|
||||
{
|
||||
var settings = (await _SettingsRepository.GetSettingAsync<DynamicDnsSettings>()) ?? new DynamicDnsSettings();
|
||||
|
||||
var i = settings.Services.FindIndex(d => d.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase));
|
||||
if (i == -1)
|
||||
return NotFound();
|
||||
if (viewModel.Settings.Password == null)
|
||||
viewModel.Settings.Password = settings.Services[i].Password;
|
||||
if (!viewModel.Settings.Enabled)
|
||||
{
|
||||
StatusMessage = $"The Dynamic DNS service has been disabled";
|
||||
viewModel.Settings.LastUpdated = null;
|
||||
await _SettingsRepository.UpdateSetting(viewModel.Settings);
|
||||
return RedirectToAction();
|
||||
}
|
||||
string errorMessage = await viewModel.Settings.SendUpdateRequest(HttpClientFactory.CreateClient());
|
||||
if (errorMessage == null)
|
||||
{
|
||||
StatusMessage = $"The Dynamic DNS has been successfully queried, your configuration is saved";
|
||||
viewModel.Settings.LastUpdated = DateTimeOffset.UtcNow;
|
||||
await _SettingsRepository.UpdateSetting(viewModel.Settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusMessage = errorMessage;
|
||||
string errorMessage = await viewModel.Settings.SendUpdateRequest(HttpClientFactory.CreateClient());
|
||||
if (errorMessage == null)
|
||||
{
|
||||
StatusMessage = $"The Dynamic DNS has been successfully queried, your configuration is saved";
|
||||
viewModel.Settings.LastUpdated = DateTimeOffset.UtcNow;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, errorMessage);
|
||||
return View(viewModel);
|
||||
}
|
||||
}
|
||||
return RedirectToAction();
|
||||
settings.Services[i] = viewModel.Settings;
|
||||
await _SettingsRepository.UpdateSetting(settings);
|
||||
this.RouteData.Values.Remove(nameof(hostname));
|
||||
return RedirectToAction(nameof(DynamicDnsServices));
|
||||
}
|
||||
|
||||
[Route("server/services/ssh")]
|
||||
|
@ -35,27 +35,30 @@ namespace BTCPayServer.HostedServices
|
||||
using (var timeout = CancellationTokenSource.CreateLinkedTokenSource(Cancellation))
|
||||
{
|
||||
var settings = await SettingsRepository.GetSettingAsync<DynamicDnsSettings>();
|
||||
if (settings?.Enabled is true && (settings.LastUpdated is null ||
|
||||
(DateTimeOffset.UtcNow - settings.LastUpdated) > Period))
|
||||
foreach (var service in settings.Services)
|
||||
{
|
||||
timeout.CancelAfter(TimeSpan.FromSeconds(20.0));
|
||||
try
|
||||
if (service?.Enabled is true && (service.LastUpdated is null ||
|
||||
(DateTimeOffset.UtcNow - service.LastUpdated) > Period))
|
||||
{
|
||||
var errorMessage = await settings.SendUpdateRequest(HttpClientFactory.CreateClient());
|
||||
if (errorMessage == null)
|
||||
timeout.CancelAfter(TimeSpan.FromSeconds(20.0));
|
||||
try
|
||||
{
|
||||
Logs.PayServer.LogInformation("Dynamic DNS service successfully refresh the DNS record");
|
||||
settings.LastUpdated = DateTimeOffset.UtcNow;
|
||||
await SettingsRepository.UpdateSetting(settings);
|
||||
var errorMessage = await service.SendUpdateRequest(HttpClientFactory.CreateClient());
|
||||
if (errorMessage == null)
|
||||
{
|
||||
Logs.PayServer.LogInformation("Dynamic DNS service successfully refresh the DNS record");
|
||||
service.LastUpdated = DateTimeOffset.UtcNow;
|
||||
await SettingsRepository.UpdateSetting(settings);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logs.PayServer.LogWarning($"Dynamic DNS service is enabled but the request to the provider failed: {errorMessage}");
|
||||
}
|
||||
}
|
||||
else
|
||||
catch (OperationCanceledException) when (timeout.IsCancellationRequested)
|
||||
{
|
||||
Logs.PayServer.LogWarning($"Dynamic DNS service is enabled but the request to the provider failed: {errorMessage}");
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException) when (timeout.IsCancellationRequested)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
using (var delayCancel = CancellationTokenSource.CreateLinkedTokenSource(Cancellation))
|
||||
|
@ -19,8 +19,8 @@ namespace BTCPayServer.Models.ServerViewModels
|
||||
public string Name { get; set; }
|
||||
public string Url { get; set; }
|
||||
}
|
||||
|
||||
public DynamicDnsSettings Settings { get; set; }
|
||||
public bool Modify { get; set; }
|
||||
public DynamicDnsService Settings { get; set; }
|
||||
public string LastUpdated
|
||||
{
|
||||
get
|
||||
|
@ -5,7 +5,6 @@ using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Hosting;
|
||||
@ -15,15 +14,21 @@ using Newtonsoft.Json;
|
||||
namespace BTCPayServer.Services
|
||||
{
|
||||
public class DynamicDnsSettings
|
||||
{
|
||||
public List<DynamicDnsService> Services { get; set; } = new List<DynamicDnsService>();
|
||||
}
|
||||
public class DynamicDnsService
|
||||
{
|
||||
[Display(Name = "Url of the Dynamic DNS service you are using")]
|
||||
[Required]
|
||||
public string ServiceUrl { get; set; }
|
||||
public string Login { get; set; }
|
||||
[DataType(DataType.Password)]
|
||||
public string Password { get; set; }
|
||||
[Display(Name = "Your dynamic DNS hostname")]
|
||||
[Required]
|
||||
public string Hostname { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
[JsonConverter(typeof(NBitcoin.JsonConverters.DateTimeToUnixTimeConverter))]
|
||||
public DateTimeOffset? LastUpdated { get; set; }
|
||||
|
||||
@ -54,7 +59,7 @@ namespace BTCPayServer.Services
|
||||
HttpRequestMessage webRequest = new HttpRequestMessage();
|
||||
if (!Uri.TryCreate(ServiceUrl, UriKind.Absolute, out var uri) || uri.HostNameType == UriHostNameType.Unknown)
|
||||
{
|
||||
throw new FormatException($"Invalid {ServiceUrl}");
|
||||
throw new FormatException($"Invalid service url");
|
||||
}
|
||||
|
||||
var builder = new UriBuilder(uri);
|
||||
|
@ -4,20 +4,21 @@
|
||||
}
|
||||
|
||||
|
||||
<h4>Dynamic DNS Settings</h4>
|
||||
<h4>Dynamic DNS Service</h4>
|
||||
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||
|
||||
@if (!this.ViewContext.ModelState.IsValid)
|
||||
{
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div asp-validation-summary="All" class="text-danger"></div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<p>
|
||||
<span>Dynamic DNS service allows you to have a stable DNS name pointing to your server, even if your IP address change regulary. <br />
|
||||
This is recommended if you are hosting BTCPayServer at home and wish to have a clearnet HTTPS address to access your server.</span>
|
||||
</p>
|
||||
<p>Note that you need to properly configure your NAT and BTCPayServer install to get HTTPS certificate.</p>
|
||||
</div>
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<input type="hidden" asp-for="Modify" />
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.ServiceUrl"></label>
|
||||
<input id="ServiceUrl" asp-for="Settings.ServiceUrl" class="form-control" placeholder="Url" />
|
||||
@ -31,14 +32,22 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Hostname"></label>
|
||||
<input asp-for="Settings.Hostname" class="form-control" placeholder="Hostname" />
|
||||
<p class="form-text text-muted">
|
||||
<span>The DNS record has been refreshed: </span>
|
||||
@if (Model.LastUpdated != null)
|
||||
{
|
||||
<span>@Model.LastUpdated</span>
|
||||
}
|
||||
</p>
|
||||
@if (Model.Modify)
|
||||
{
|
||||
<input asp-for="Settings.Hostname" class="form-control" readonly placeholder="Hostname" />
|
||||
<p class="form-text text-muted">
|
||||
<span>The DNS record has been refreshed: </span>
|
||||
@if (Model.LastUpdated != null)
|
||||
{
|
||||
<span>@Model.LastUpdated</span>
|
||||
}
|
||||
</p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<input asp-for="Settings.Hostname" class="form-control" placeholder="Hostname" />
|
||||
<span asp-validation-for="Settings.Hostname" class="text-danger"></span>
|
||||
}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Login"></label>
|
||||
@ -48,11 +57,13 @@
|
||||
<label asp-for="Settings.Password"></label>
|
||||
<input asp-for="Settings.Password" class="form-control" placeholder="Password" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Enabled"></label>
|
||||
<input asp-for="Settings.Enabled" class="form-check-inline" type="checkbox" />
|
||||
</div>
|
||||
|
||||
@if (Model.Modify)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="Settings.Enabled"></label>
|
||||
<input asp-for="Settings.Enabled" class="form-check-inline" type="checkbox" />
|
||||
</div>
|
||||
}
|
||||
<button name="command" class="btn btn-primary" type="submit" value="Save">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
|
55
BTCPayServer/Views/Server/DynamicDnsServices.cshtml
Normal file
55
BTCPayServer/Views/Server/DynamicDnsServices.cshtml
Normal file
@ -0,0 +1,55 @@
|
||||
@model BTCPayServer.Models.ServerViewModels.DynamicDnsViewModel[]
|
||||
@{
|
||||
ViewData.SetActivePageAndTitle(ServerNavPages.Services);
|
||||
}
|
||||
|
||||
|
||||
<h4>Dynamic DNS Settings</h4>
|
||||
<partial name="_StatusMessage" for="@TempData["TempDataProperty-StatusMessage"]" />
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<div class="form-group">
|
||||
<p>
|
||||
<span>
|
||||
Dynamic DNS service allows you to have a stable DNS name pointing to your server, even if your IP address change regulary. <br />
|
||||
This is recommended if you are hosting BTCPayServer at home and wish to have a clearnet HTTPS address to access your server.
|
||||
</span>
|
||||
</p>
|
||||
<p>Note that you need to properly configure your NAT and BTCPayServer install to get HTTPS certificate.</p>
|
||||
</div>
|
||||
<form method="post" asp-action="DynamicDnsService">
|
||||
<button class="btn btn-primary" type="submit"><span class="fa fa-plus"></span> Add Dynamic DNS</button>
|
||||
</form>
|
||||
<table class="table table-sm table-responsive-md">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Hostname</th>
|
||||
<th>Last updated</th>
|
||||
<th style="text-align:center;">Enabled</th>
|
||||
<th style="text-align:right">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var service in Model)
|
||||
{
|
||||
<tr>
|
||||
<td>@service.Settings.Hostname</td>
|
||||
<td>@service.LastUpdated</td>
|
||||
<td style="text-align:center;">
|
||||
@if(service.Settings.Enabled)
|
||||
{
|
||||
<span class="fa fa-check"></span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span class="fa fa-times"></span>
|
||||
}
|
||||
</td>
|
||||
<td><a asp-action="DynamicDnsService" asp-route-hostname="@service.Settings.Hostname">Edit</a> <span> - </span> <a asp-action="DynamicDnsServiceDelete" asp-route-hostname="@service.Settings.Hostname">Remove</a></td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
Loading…
Reference in New Issue
Block a user