diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index 1999349ac..7984cb761 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -94,6 +94,55 @@ namespace BTCPayServer.Tests s.Driver.FindElement(By.Id("LoginButton")).Click(); s.Driver.AssertNoError(); } + [Fact] + public void CanUseDynamicDns() + { + using (var s = SeleniumTester.Create()) + { + s.Start(); + var alice = s.RegisterNewUser(isAdmin: true); + s.Driver.Navigate().GoToUrl(s.Link("/server/services")); + Assert.Contains("Dynamic DNS", s.Driver.PageSource); + + s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns")); + s.Driver.AssertNoError(); + if (s.Driver.PageSource.Contains("CanUseDynamicDns.hello.com")) + { + // Cleanup old test run + s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns/CanUseDynamicDns.hello.com/delete")); + s.Driver.FindElement(By.Id("continue")).Click(); + } + s.Driver.FindElement(By.Id("AddDynamicDNS")).Click(); + s.Driver.AssertNoError(); + // We will just cheat for test purposes by only querying the server + s.Driver.FindElement(By.Id("ServiceUrl")).SendKeys(s.Link("/")); + s.Driver.FindElement(By.Id("Settings_Hostname")).SendKeys("CanUseDynamicDns.hello.com"); + s.Driver.FindElement(By.Id("Settings_Login")).SendKeys("MyLog"); + s.Driver.FindElement(By.Id("Settings_Password")).SendKeys("MyLog" + Keys.Enter); + s.Driver.AssertNoError(); + Assert.Contains("The Dynamic DNS has been successfully queried", s.Driver.PageSource); + Assert.EndsWith("/server/services/dynamic-dns", s.Driver.Url); + + // Try to do the same thing should fail (hostname already exists) + s.Driver.FindElement(By.Id("AddDynamicDNS")).Click(); + s.Driver.AssertNoError(); + s.Driver.FindElement(By.Id("ServiceUrl")).SendKeys(s.Link("/")); + s.Driver.FindElement(By.Id("Settings_Hostname")).SendKeys("CanUseDynamicDns.hello.com"); + s.Driver.FindElement(By.Id("Settings_Login")).SendKeys("MyLog"); + s.Driver.FindElement(By.Id("Settings_Password")).SendKeys("MyLog" + Keys.Enter); + s.Driver.AssertNoError(); + Assert.Contains("This hostname already exists", s.Driver.PageSource); + + // Delete it + s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns")); + Assert.Contains("/server/services/dynamic-dns/CanUseDynamicDns.hello.com/delete", s.Driver.PageSource); + s.Driver.Navigate().GoToUrl(s.Link("/server/services/dynamic-dns/CanUseDynamicDns.hello.com/delete")); + s.Driver.FindElement(By.Id("continue")).Click(); + s.Driver.AssertNoError(); + + Assert.DoesNotContain("/server/services/dynamic-dns/CanUseDynamicDns.hello.com/delete", s.Driver.PageSource); + } + } [Fact] public void CanCreateStores() diff --git a/BTCPayServer/Controllers/ServerController.cs b/BTCPayServer/Controllers/ServerController.cs index d18ac3090..9e23e0696 100644 --- a/BTCPayServer/Controllers/ServerController.cs +++ b/BTCPayServer/Controllers/ServerController.cs @@ -845,6 +845,8 @@ namespace BTCPayServer.Controllers ModelState.AddModelError(nameof(viewModel.Settings.Hostname), "This hostname already exists"); return View(viewModel); } + if (viewModel.Settings.Hostname != null) + viewModel.Settings.Hostname = viewModel.Settings.Hostname.Trim().ToLowerInvariant(); string errorMessage = await viewModel.Settings.SendUpdateRequest(HttpClientFactory.CreateClient()); if (errorMessage == null) { @@ -876,6 +878,8 @@ namespace BTCPayServer.Controllers return NotFound(); if (viewModel.Settings.Password == null) viewModel.Settings.Password = settings.Services[i].Password; + if (viewModel.Settings.Hostname != null) + viewModel.Settings.Hostname = viewModel.Settings.Hostname.Trim().ToLowerInvariant(); if (!viewModel.Settings.Enabled) { StatusMessage = $"The Dynamic DNS service has been disabled"; @@ -900,6 +904,35 @@ namespace BTCPayServer.Controllers this.RouteData.Values.Remove(nameof(hostname)); return RedirectToAction(nameof(DynamicDnsServices)); } + [HttpGet] + [Route("server/services/dynamic-dns/{hostname}/delete")] + public async Task DeleteDynamicDnsService(string hostname) + { + var settings = (await _SettingsRepository.GetSettingAsync()) ?? new DynamicDnsSettings(); + var i = settings.Services.FindIndex(d => d.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase)); + if (i == -1) + return NotFound(); + return View("Confirm", new ConfirmModel() + { + Title = "Delete the dynamic dns service for " + hostname, + Description = "BTCPayServer will stop updating this DNS record periodically", + Action = "Delete" + }); + } + [HttpPost] + [Route("server/services/dynamic-dns/{hostname}/delete")] + public async Task DeleteDynamicDnsServicePost(string hostname) + { + var settings = (await _SettingsRepository.GetSettingAsync()) ?? new DynamicDnsSettings(); + var i = settings.Services.FindIndex(d => d.Hostname.Equals(hostname, StringComparison.OrdinalIgnoreCase)); + if (i == -1) + return NotFound(); + settings.Services.RemoveAt(i); + await _SettingsRepository.UpdateSetting(settings); + StatusMessage = "Dynamic DNS service successfully removed"; + this.RouteData.Values.Remove(nameof(hostname)); + return RedirectToAction(nameof(DynamicDnsServices)); + } [Route("server/services/ssh")] public IActionResult SSHService(bool downloadKeyFile = false) diff --git a/BTCPayServer/Views/Server/DynamicDnsServices.cshtml b/BTCPayServer/Views/Server/DynamicDnsServices.cshtml index 2123b8ecf..f7acf204c 100644 --- a/BTCPayServer/Views/Server/DynamicDnsServices.cshtml +++ b/BTCPayServer/Views/Server/DynamicDnsServices.cshtml @@ -19,7 +19,7 @@

Note that you need to properly configure your NAT and BTCPayServer install to get HTTPS certificate.

- +
@@ -46,7 +46,7 @@ } - + } diff --git a/BTCPayServer/Views/Shared/Confirm.cshtml b/BTCPayServer/Views/Shared/Confirm.cshtml index 0b9c9a559..48323cb6c 100644 --- a/BTCPayServer/Views/Shared/Confirm.cshtml +++ b/BTCPayServer/Views/Shared/Confirm.cshtml @@ -17,7 +17,7 @@
- +
Edit - RemoveEdit - Remove