mirror of
https://github.com/btcpayserver/btcpayserver.git
synced 2025-02-22 14:22:40 +01:00
Merge pull request #1121 from NicolasDorier/ux/login-register
Add sponsor and new design to the login and registration page
This commit is contained in:
commit
d392880102
18 changed files with 367 additions and 152 deletions
|
@ -18,7 +18,7 @@ namespace BTCPayServer.Tests
|
|||
[Trait("Selenium", "Selenium")]
|
||||
public class CheckoutUITests
|
||||
{
|
||||
public const int TestTimeout = 60_000;
|
||||
public const int TestTimeout = TestUtils.TestTimeout;
|
||||
public CheckoutUITests(ITestOutputHelper helper)
|
||||
{
|
||||
Logs.Tester = new XUnitLog(helper) { Name = "Tests" };
|
||||
|
@ -32,6 +32,7 @@ namespace BTCPayServer.Tests
|
|||
using (var s = SeleniumTester.Create())
|
||||
{
|
||||
await s.StartAsync();
|
||||
s.GoToRegister();
|
||||
s.RegisterNewUser();
|
||||
var store = s.CreateNewStore();
|
||||
s.AddDerivationScheme("BTC");
|
||||
|
@ -80,6 +81,7 @@ namespace BTCPayServer.Tests
|
|||
using (var s = SeleniumTester.Create())
|
||||
{
|
||||
await s.StartAsync();
|
||||
s.GoToRegister();
|
||||
s.RegisterNewUser();
|
||||
var store = s.CreateNewStore();
|
||||
s.AddDerivationScheme("BTC");
|
||||
|
@ -109,6 +111,7 @@ namespace BTCPayServer.Tests
|
|||
using (var s = SeleniumTester.Create())
|
||||
{
|
||||
await s.StartAsync();
|
||||
s.GoToRegister();
|
||||
s.RegisterNewUser();
|
||||
var store = s.CreateNewStore();
|
||||
s.AddDerivationScheme("BTC");
|
||||
|
@ -152,6 +155,7 @@ namespace BTCPayServer.Tests
|
|||
using (var s = SeleniumTester.Create())
|
||||
{
|
||||
await s.StartAsync();
|
||||
s.GoToRegister();
|
||||
s.RegisterNewUser();
|
||||
var store = s.CreateNewStore();
|
||||
s.AddInternalLightningNode("BTC");
|
||||
|
|
|
@ -28,8 +28,11 @@ namespace BTCPayServer.Tests
|
|||
try
|
||||
{
|
||||
Assert.NotEmpty(driver.FindElements(By.ClassName("navbar-brand")));
|
||||
foreach (var dangerAlert in driver.FindElements(By.ClassName("alert-danger")))
|
||||
Assert.False(dangerAlert.Displayed, "No alert should be displayed");
|
||||
if (driver.PageSource.Contains("alert-danger"))
|
||||
{
|
||||
foreach (var dangerAlert in driver.FindElements(By.ClassName("alert-danger")))
|
||||
Assert.False(dangerAlert.Displayed, "No alert should be displayed");
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace BTCPayServer.Tests
|
|||
Logs.Tester.LogInformation("Selenium: Browsing to " + Server.PayTester.ServerUri);
|
||||
Logs.Tester.LogInformation($"Selenium: Resolution {Driver.Manage().Window.Size}");
|
||||
Driver.Manage().Timeouts().ImplicitWait = ImplicitWait;
|
||||
Driver.Navigate().GoToUrl(Server.PayTester.ServerUri);
|
||||
GoToRegister();
|
||||
Driver.AssertNoError();
|
||||
}
|
||||
|
||||
|
@ -76,10 +76,13 @@ namespace BTCPayServer.Tests
|
|||
return Server.PayTester.ServerUri.AbsoluteUri.WithoutEndingSlash() + relativeLink.WithStartingSlash();
|
||||
}
|
||||
|
||||
public void GoToRegister()
|
||||
{
|
||||
Driver.Navigate().GoToUrl(this.Link("/Account/Register"));
|
||||
}
|
||||
public string RegisterNewUser(bool isAdmin = false)
|
||||
{
|
||||
var usr = RandomUtils.GetUInt256().ToString().Substring(64 - 20) + "@a.com";
|
||||
Driver.FindElement(By.Id("Register")).Click();
|
||||
Driver.FindElement(By.Id("Email")).SendKeys(usr);
|
||||
Driver.FindElement(By.Id("Password")).SendKeys("123456");
|
||||
Driver.FindElement(By.Id("ConfirmPassword")).SendKeys("123456");
|
||||
|
|
|
@ -46,8 +46,7 @@ namespace BTCPayServer.Tests
|
|||
var email = s.RegisterNewUser();
|
||||
s.Driver.FindElement(By.Id("Logout")).Click();
|
||||
s.Driver.AssertNoError();
|
||||
s.Driver.FindElement(By.Id("Login")).Click();
|
||||
s.Driver.AssertNoError();
|
||||
Assert.Contains("Account/Login", s.Driver.Url);
|
||||
|
||||
s.Driver.Navigate().GoToUrl(s.Link("/invoices"));
|
||||
Assert.Contains("ReturnUrl=%2Finvoices", s.Driver.Url);
|
||||
|
@ -76,7 +75,6 @@ namespace BTCPayServer.Tests
|
|||
s.Driver.AssertNoError();
|
||||
|
||||
//Log In With New Password
|
||||
s.Driver.FindElement(By.Id("Login")).Click();
|
||||
s.Driver.FindElement(By.Id("Email")).SendKeys(email);
|
||||
s.Driver.FindElement(By.Id("Password")).SendKeys("abc???");
|
||||
s.Driver.FindElement(By.Id("LoginButton")).Click();
|
||||
|
@ -91,7 +89,6 @@ namespace BTCPayServer.Tests
|
|||
|
||||
static void LogIn(SeleniumTester s, string email)
|
||||
{
|
||||
s.Driver.FindElement(By.Id("Login")).Click();
|
||||
s.Driver.FindElement(By.Id("Email")).SendKeys(email);
|
||||
s.Driver.FindElement(By.Id("Password")).SendKeys("123456");
|
||||
s.Driver.FindElement(By.Id("LoginButton")).Click();
|
||||
|
@ -208,7 +205,7 @@ namespace BTCPayServer.Tests
|
|||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
s.Driver.Navigate().GoToUrl(invoiceUrl);
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
|
||||
s.GoToRegister();
|
||||
// When logged we should not be able to access store and invoice details
|
||||
var bob = s.RegisterNewUser();
|
||||
s.Driver.Navigate().GoToUrl(storeUrl);
|
||||
|
@ -252,7 +249,7 @@ namespace BTCPayServer.Tests
|
|||
await s.StartAsync();
|
||||
s.Driver.Navigate().GoToUrl(s.Link("/api-access-request"));
|
||||
Assert.Contains("ReturnUrl", s.Driver.Url);
|
||||
|
||||
s.GoToRegister();
|
||||
var alice = s.RegisterNewUser();
|
||||
var store = s.CreateNewStore().storeName;
|
||||
s.AddDerivationScheme();
|
||||
|
|
|
@ -398,7 +398,9 @@ namespace BTCPayServer.Controllers
|
|||
{
|
||||
await _RoleManager.CreateAsync(new IdentityRole(Roles.ServerAdmin));
|
||||
await _userManager.AddToRoleAsync(user, Roles.ServerAdmin);
|
||||
|
||||
var settings = await _SettingsRepository.GetSettingAsync<ThemeSettings>();
|
||||
settings.FirstRun = false;
|
||||
await _SettingsRepository.UpdateSetting<ThemeSettings>(settings);
|
||||
if(_Options.DisableRegistration)
|
||||
{
|
||||
// Once the admin user has been created lock subsequent user registrations (needs to be disabled for unit tests that require multiple users).
|
||||
|
|
|
@ -12,6 +12,8 @@ using Newtonsoft.Json;
|
|||
using BTCPayServer.Services;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Services.Apps;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using BTCPayServer.Data;
|
||||
|
||||
namespace BTCPayServer.Controllers
|
||||
{
|
||||
|
@ -20,11 +22,15 @@ namespace BTCPayServer.Controllers
|
|||
private readonly CssThemeManager _cachedServerSettings;
|
||||
|
||||
public IHttpClientFactory HttpClientFactory { get; }
|
||||
SignInManager<ApplicationUser> SignInManager { get; }
|
||||
|
||||
public HomeController(IHttpClientFactory httpClientFactory, CssThemeManager cachedServerSettings)
|
||||
public HomeController(IHttpClientFactory httpClientFactory,
|
||||
CssThemeManager cachedServerSettings,
|
||||
SignInManager<ApplicationUser> signInManager)
|
||||
{
|
||||
HttpClientFactory = httpClientFactory;
|
||||
_cachedServerSettings = cachedServerSettings;
|
||||
SignInManager = signInManager;
|
||||
}
|
||||
|
||||
private async Task<ViewResult> GoToApp(string appId, AppType? appType)
|
||||
|
@ -71,14 +77,26 @@ namespace BTCPayServer.Controllers
|
|||
|
||||
public async Task<IActionResult> Index()
|
||||
{
|
||||
if (_cachedServerSettings.FirstRun)
|
||||
{
|
||||
return RedirectToAction(nameof(AccountController.Register), "Account");
|
||||
}
|
||||
var matchedDomainMapping = _cachedServerSettings.DomainToAppMapping.FirstOrDefault(item =>
|
||||
item.Domain.Equals(Request.Host.Host, StringComparison.InvariantCultureIgnoreCase));
|
||||
if (matchedDomainMapping != null)
|
||||
{
|
||||
return await GoToApp(matchedDomainMapping.AppId, matchedDomainMapping.AppType) ?? View("Home");
|
||||
return await GoToApp(matchedDomainMapping.AppId, matchedDomainMapping.AppType) ?? GoToHome();
|
||||
}
|
||||
|
||||
return await GoToApp(_cachedServerSettings.RootAppId, _cachedServerSettings.RootAppType) ?? View("Home");
|
||||
return await GoToApp(_cachedServerSettings.RootAppId, _cachedServerSettings.RootAppType) ?? GoToHome();
|
||||
}
|
||||
|
||||
private IActionResult GoToHome()
|
||||
{
|
||||
if (SignInManager.IsSignedIn(User))
|
||||
return View("Home");
|
||||
else
|
||||
return RedirectToAction(nameof(AccountController.Login), "Account");
|
||||
}
|
||||
|
||||
[Route("translate")]
|
||||
|
|
|
@ -31,6 +31,7 @@ namespace BTCPayServer.HostedServices
|
|||
_creativeStartUri = "/vendor/bootstrap4-creativestart/creative.css?v=" + DateTime.Now.Ticks;
|
||||
else
|
||||
_creativeStartUri = data.CreativeStartCssUri;
|
||||
FirstRun = data.FirstRun;
|
||||
}
|
||||
|
||||
private string _bootstrapUri;
|
||||
|
@ -52,6 +53,8 @@ namespace BTCPayServer.HostedServices
|
|||
public AppType? RootAppType { get; set; }
|
||||
public string RootAppId { get; set; }
|
||||
|
||||
public bool FirstRun { get; set; }
|
||||
|
||||
public List<PoliciesSettings.DomainToAppMappingItem> DomainToAppMapping { get; set; } = new List<PoliciesSettings.DomainToAppMappingItem>();
|
||||
|
||||
internal void Update(PoliciesSettings data)
|
||||
|
|
|
@ -10,6 +10,7 @@ using BTCPayServer.Services.Stores;
|
|||
using BTCPayServer.Logging;
|
||||
using System.Threading;
|
||||
using Npgsql;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
|
||||
namespace BTCPayServer
|
||||
{
|
||||
|
@ -19,16 +20,19 @@ namespace BTCPayServer
|
|||
private StoreRepository _StoreRepository;
|
||||
private BTCPayNetworkProvider _NetworkProvider;
|
||||
private SettingsRepository _Settings;
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
public MigrationStartupTask(
|
||||
BTCPayNetworkProvider networkProvider,
|
||||
StoreRepository storeRepository,
|
||||
ApplicationDbContextFactory dbContextFactory,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
SettingsRepository settingsRepository)
|
||||
{
|
||||
_DBContextFactory = dbContextFactory;
|
||||
_StoreRepository = storeRepository;
|
||||
_NetworkProvider = networkProvider;
|
||||
_Settings = settingsRepository;
|
||||
_userManager = userManager;
|
||||
}
|
||||
public async Task ExecuteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
|
@ -72,6 +76,15 @@ namespace BTCPayServer
|
|||
settings.ConvertWalletKeyPathRoots = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
if (!settings.CheckedFirstRun)
|
||||
{
|
||||
var themeSettings = await _Settings.GetSettingAsync<ThemeSettings>() ?? new ThemeSettings();
|
||||
var admin = await _userManager.GetUsersInRoleAsync(Roles.ServerAdmin);
|
||||
themeSettings.FirstRun = admin.Count == 0;
|
||||
await _Settings.UpdateSetting(themeSettings);
|
||||
settings.CheckedFirstRun = true;
|
||||
await _Settings.UpdateSetting(settings);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace BTCPayServer.Services
|
|||
public bool ConvertNetworkFeeProperty { get; set; }
|
||||
public bool ConvertCrowdfundOldSettings { get; set; }
|
||||
public bool ConvertWalletKeyPathRoots { get; set; }
|
||||
public bool CheckedFirstRun { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Empty;
|
||||
|
|
|
@ -16,5 +16,11 @@ namespace BTCPayServer.Services
|
|||
|
||||
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
|
||||
public string CreativeStartCssUri { get; set; }
|
||||
public bool FirstRun { get; set; }
|
||||
public override string ToString()
|
||||
{
|
||||
// no logs
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,54 +1,46 @@
|
|||
@model LoginViewModel
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
@inject BTCPayServer.HostedServices.CssThemeManager themeManager
|
||||
|
||||
@{
|
||||
ViewData["Title"] = "Log in";
|
||||
Layout = "_WelcomeLayout.cshtml";
|
||||
}
|
||||
|
||||
<section>
|
||||
<div>
|
||||
<div class="modal-dialog modal-login">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Sign In</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form asp-route-returnurl="@ViewData["ReturnUrl"]" method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="LoginButton">Sign in</button>
|
||||
</div>
|
||||
<p class="hint-text"><a asp-action="ForgotPassword">Forgot your password?</a></p>
|
||||
</form>
|
||||
</div>
|
||||
@if (themeManager.ShowRegister)
|
||||
{
|
||||
<div class="modal-footer"><span>Don't have an account? <a asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]">Create one</a></span></div>
|
||||
}
|
||||
</div>
|
||||
<div class="modal-dialog modal-login">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Sign In</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form asp-route-returnurl="@ViewData["ReturnUrl"]" method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="LoginButton">Sign in</button>
|
||||
</div>
|
||||
<p class="hint-text"><a asp-action="ForgotPassword">Forgot your password?</a></p>
|
||||
</form>
|
||||
</div>
|
||||
@if (themeManager.ShowRegister)
|
||||
{
|
||||
<div class="modal-footer"><span>Don't have an account? <a id="Register" asp-action="Register" asp-route-returnurl="@ViewData["ReturnUrl"]">Create one</a></span></div>
|
||||
}
|
||||
</div>
|
||||
</section>
|
||||
@section Scripts {
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -1,62 +1,56 @@
|
|||
@model RegisterViewModel
|
||||
@{
|
||||
ViewData["Title"] = "Register";
|
||||
Layout = "_WelcomeLayout.cshtml";
|
||||
}
|
||||
|
||||
<section>
|
||||
<div>
|
||||
<div class="modal-dialog modal-login">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Create account</h4>
|
||||
<div class="modal-dialog modal-login">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h4 class="modal-title">Create account</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form asp-route-returnUrl="@ViewData["ReturnUrl"]" asp-route-logon="@ViewData["Logon"]" method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form asp-route-returnUrl="@ViewData["ReturnUrl"]" asp-route-logon="@ViewData["Logon"]" method="post">
|
||||
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Email" class="input-group-text"><span class="input-group-addon fa fa-user"></span></label>
|
||||
</div>
|
||||
<input asp-for="Email" class="form-control" placeholder="Email" required="required"/>
|
||||
</div>
|
||||
<span asp-validation-for="Email" class="text-danger"></span>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="Password" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required"/>
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="ConfirmPassword" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="ConfirmPassword" class="form-control" placeholder="Repeat password" required="required"/>
|
||||
</div>
|
||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
@if (ViewData["AllowIsAdmin"] is true)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="IsAdmin"></label>
|
||||
<input asp-for="IsAdmin" type="checkbox" class="form-check-inline"/>
|
||||
<span asp-validation-for="IsAdmin" class="text-danger"></span>
|
||||
</div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="RegisterButton">Create account</button>
|
||||
</div>
|
||||
</form>
|
||||
<input asp-for="Password" class="form-control" placeholder="Password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="Password" class="text-danger"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
<label for="ConfirmPassword" class="input-group-text"><span class="input-group-addon fa fa-lock"></span></label>
|
||||
</div>
|
||||
<input asp-for="ConfirmPassword" class="form-control" placeholder="Repeat password" required="required" />
|
||||
</div>
|
||||
<span asp-validation-for="ConfirmPassword" class="text-danger"></span>
|
||||
</div>
|
||||
@if (ViewData["AllowIsAdmin"] is true)
|
||||
{
|
||||
<div class="form-group">
|
||||
<label asp-for="IsAdmin"></label>
|
||||
<input asp-for="IsAdmin" type="checkbox" class="form-check-inline" />
|
||||
<span asp-validation-for="IsAdmin" class="text-danger"></span>
|
||||
</div>
|
||||
}
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-primary btn-block btn-lg" id="RegisterButton">Create account</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@section Scripts {
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
}
|
||||
</div>
|
||||
|
|
76
BTCPayServer/Views/Account/_WelcomeLayout.cshtml
Normal file
76
BTCPayServer/Views/Account/_WelcomeLayout.cshtml
Normal file
|
@ -0,0 +1,76 @@
|
|||
@model LoginViewModel
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<partial name="Header" />
|
||||
<style>
|
||||
.lead-title {
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-size: 40px;
|
||||
line-height: 60px;
|
||||
/* or 150% */
|
||||
letter-spacing: 0.1em;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.lead-login {
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-size: 18px;
|
||||
line-height: 33px;
|
||||
/* or 183% */
|
||||
letter-spacing: 0.1em;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.lead-h {
|
||||
font-family: Montserrat;
|
||||
font-style: normal;
|
||||
margin-bottom: 30px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
/* identical to box height, or 129% */
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
color: #000000;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<section>
|
||||
<!-- Dummy navbar-brand, hackish way to keep test AssertNoError passing -->
|
||||
<div class="navbar-brand" style="display:none;"></div>
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-7">
|
||||
<a asp-controller="Home" asp-action="Index"><img src="~/img/btcpay-logo.svg" alt="BTCPay Server" height="100" style="margin-bottom:30px;" /></a>
|
||||
<h1 class="lead-title text-uppercase">Welcome to your BTCPay Server</h1>
|
||||
<hr class="primary ml-0" style="margin-bottom:30px; margin-top:30px;">
|
||||
<p class="lead-login" style="margin-bottom:69px;">BTCPay Server lets you process Bitcoin transactions seemlessly, enabling global and near-instant peer-to-peer payments</p>
|
||||
<h3 class="lead-h">Our supporters</h3>
|
||||
<div class="figure">
|
||||
<a href="https://twitter.com/sqcrypto" target="_blank">
|
||||
<img src="~/img/squarecrypto.svg" alt="Sponsor Square Crypto" height="100" />
|
||||
</a>
|
||||
<div class="figure-caption text-center">
|
||||
<a href="https://twitter.com/sqcrypto" target="_blank">Square Crypto</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-5" style="margin-top:50px;">
|
||||
@RenderBody()
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@await Html.PartialAsync("_ValidationScriptsPartial")
|
||||
</body>
|
||||
</html>
|
|
@ -1,30 +1,14 @@
|
|||
@model ConfirmModel
|
||||
|
||||
@inject BTCPayServer.HostedServices.NBXplorerDashboard dashboard
|
||||
@inject BTCPayServer.HostedServices.CssThemeManager themeManager
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
@{
|
||||
ViewData["Title"] = Model.Title;
|
||||
Layout = null;
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
@if (themeManager.DiscourageSearchEngines)
|
||||
{
|
||||
<META NAME="robots" CONTENT="noindex">
|
||||
}
|
||||
<title>BTCPay Server</title>
|
||||
@* CSS *@
|
||||
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
|
||||
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.CreativeStartUri)" rel="stylesheet" />
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.css" />
|
||||
@* JS *@
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.js" />
|
||||
<partial name="Header" />
|
||||
</head>
|
||||
<body class="bg-light">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
|
|
18
BTCPayServer/Views/Shared/Header.cshtml
Normal file
18
BTCPayServer/Views/Shared/Header.cshtml
Normal file
|
@ -0,0 +1,18 @@
|
|||
@inject BTCPayServer.HostedServices.CssThemeManager themeManager
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
@if (themeManager.DiscourageSearchEngines)
|
||||
{
|
||||
<META NAME="robots" CONTENT="noindex">
|
||||
}
|
||||
<title>@ViewData["Title"]</title>
|
||||
@* CSS *@
|
||||
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
|
||||
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.CreativeStartUri)" rel="stylesheet" />
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.css" />
|
||||
@* JS *@
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.js" />
|
|
@ -5,31 +5,11 @@
|
|||
@inject BTCPayServer.HostedServices.NBXplorerDashboard dashboard
|
||||
@inject BTCPayServer.HostedServices.CssThemeManager themeManager
|
||||
|
||||
@addTagHelper *, BundlerMinifier.TagHelpers
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
@if (themeManager.DiscourageSearchEngines)
|
||||
{
|
||||
<META NAME="robots" CONTENT="noindex">
|
||||
}
|
||||
|
||||
<title>BTCPay Server</title>
|
||||
|
||||
@* CSS *@
|
||||
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.BootstrapUri)" rel="stylesheet" />
|
||||
<link href="@this.Context.Request.GetRelativePathOrAbsolute(themeManager.CreativeStartUri)" rel="stylesheet" />
|
||||
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.css" />
|
||||
|
||||
@* JS *@
|
||||
<bundle name="wwwroot/bundles/main-bundle.min.js" />
|
||||
<partial name="Header" />
|
||||
|
||||
@RenderSection("HeadScripts", required: false)
|
||||
@RenderSection("HeaderContent", false)
|
||||
|
|
97
BTCPayServer/wwwroot/img/btcpay-logo.svg
Normal file
97
BTCPayServer/wwwroot/img/btcpay-logo.svg
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="650 0 1706.6667 1066.6667"
|
||||
height="1066.6667"
|
||||
width="1706.6667"
|
||||
xml:space="preserve"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
sodipodi:docname="BTCPay Server Icon.svg"
|
||||
inkscape:version="0.92.3 (2405546, 2018-03-11)"><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
id="namedview82"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.16640624"
|
||||
inkscape:cx="853.33337"
|
||||
inkscape:cy="533.33337"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="g10" /><metadata
|
||||
id="metadata8"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs6"><clipPath
|
||||
id="clipPath18"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path16"
|
||||
d="M 0,800 H 1280 V 0 H 0 Z" /></clipPath><clipPath
|
||||
id="clipPath74"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path72"
|
||||
d="M 0,800 H 1280 V 0 H 0 Z" /></clipPath><clipPath
|
||||
id="clipPath128"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path126"
|
||||
d="M 0,800 H 1280 V 0 H 0 Z" /></clipPath><clipPath
|
||||
id="clipPath140"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
id="path138"
|
||||
d="M 0,800 H 1280 V 0 H 0 Z" /></clipPath></defs><g
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,955.493,249.38967)"
|
||||
id="g10"><g
|
||||
transform="matrix(0.29765316,0,0,0.29765316,413.69235,44.782893)"
|
||||
id="g134"><g
|
||||
transform="matrix(3.6585926,0,0,3.6585926,-4809.6898,-2104.6753)"
|
||||
clip-path="url(#clipPath140)"
|
||||
id="g136"><g
|
||||
transform="matrix(4.7732059,0,0,4.7732059,779.20458,11.551291)"
|
||||
id="g146"><path
|
||||
id="path148"
|
||||
style="fill:#cedc21;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -4.573,0 -8.281,3.707 -8.281,8.28 v 124.622 c 0,4.573 3.708,8.281 8.281,8.281 4.573,0 8.281,-3.708 8.281,-8.281 V 8.28 C 8.281,3.707 4.573,0 0,0"
|
||||
inkscape:connector-curvature="0" /></g><g
|
||||
transform="matrix(4.7732059,0,0,4.7732059,779.22987,11.542212)"
|
||||
id="g150"><path
|
||||
id="path152"
|
||||
style="fill:#51b13e;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -3.099,0 -6.069,1.746 -7.487,4.731 -1.96,4.132 -0.201,9.072 3.931,11.033 l 49.934,23.698 -51.295,37.79 c -3.682,2.713 -4.468,7.897 -1.754,11.58 2.711,3.681 7.898,4.467 11.577,1.754 L 67.347,44.583 c 2.345,-1.728 3.611,-4.56 3.331,-7.46 -0.279,-2.898 -2.06,-5.438 -4.693,-6.687 L 3.545,0.802 C 2.399,0.258 1.19,0 0,0"
|
||||
inkscape:connector-curvature="0" /></g><g
|
||||
transform="matrix(4.7732059,0,0,4.7732059,779.23704,245.35911)"
|
||||
id="g154"><path
|
||||
id="path156"
|
||||
style="fill:#cedc21;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 c -2.542,0 -5.05,1.166 -6.673,3.369 -2.713,3.683 -1.928,8.867 1.755,11.579 L 46.376,52.739 -3.557,76.438 c -4.132,1.96 -5.891,6.899 -3.931,11.031 1.962,4.132 6.902,5.893 11.031,3.93 L 65.984,61.766 c 2.632,-1.249 4.414,-3.789 4.693,-6.688 0.279,-2.9 -0.987,-5.733 -3.332,-7.46 L 4.905,1.614 C 3.426,0.525 1.705,0 0,0"
|
||||
inkscape:connector-curvature="0" /></g><g
|
||||
transform="matrix(4.7732059,0,0,4.7732059,818.73005,432.0807)"
|
||||
id="g158"><path
|
||||
id="path160"
|
||||
style="fill:#1e7a44;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="m 0,0 v -35.022 l 23.757,17.503 z"
|
||||
inkscape:connector-curvature="0" /></g><path
|
||||
id="path162"
|
||||
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.77320623"
|
||||
d="m 818.73151,309.4809 h -79.05385 v 192.68958 h 79.05385 z"
|
||||
inkscape:connector-curvature="0" /><g
|
||||
transform="matrix(4.7732059,0,0,4.7732059,779.20458,685.44488)"
|
||||
id="g164"><path
|
||||
id="path166"
|
||||
style="fill:#cedc21;fill-opacity:1;fill-rule:nonzero;stroke:none"
|
||||
d="M 0,0 C -4.573,0 -8.281,-3.708 -8.281,-8.281 V -112.496 H 8.281 V -8.281 C 8.281,-3.708 4.573,0 0,0"
|
||||
inkscape:connector-curvature="0" /></g></g></g></g></svg>
|
After Width: | Height: | Size: 4.9 KiB |
24
BTCPayServer/wwwroot/img/squarecrypto.svg
Normal file
24
BTCPayServer/wwwroot/img/squarecrypto.svg
Normal file
|
@ -0,0 +1,24 @@
|
|||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="500px" height="500px" viewBox="0 0 500 500" enable-background="new 0 0 500 500" xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<defs>
|
||||
<path id="SVGID_1_" d="M38.001,423.401C38.001,444.72,55.283,462,76.599,462c21.319,0,38.604-17.28,38.604-38.599
|
||||
c0-21.315-17.285-38.599-38.604-38.599C55.283,384.803,38.001,402.086,38.001,423.401 M192.399,384.803v77.194H418.65
|
||||
c23.939,0,43.348-19.408,43.348-43.347v-33.848H192.399z M38.001,288.603h269.6v-77.198h-269.6V288.603z M384.801,250.002
|
||||
c0,21.318,17.281,38.601,38.6,38.601s38.598-17.282,38.598-38.601c0-21.319-17.279-38.602-38.598-38.602
|
||||
S384.801,228.683,384.801,250.002 M38.001,76.604c0,21.314,17.281,38.598,38.597,38.598c21.319,0,38.604-17.283,38.604-38.598
|
||||
C115.203,55.286,97.917,38,76.599,38C55.283,38,38.001,55.286,38.001,76.604 M192.399,38v77.202h269.599V81.349
|
||||
C461.998,57.411,442.59,38,418.65,38H192.399z"></path>
|
||||
</defs>
|
||||
<clipPath id="SVGID_2_">
|
||||
<use xlink:href="#SVGID_1_" overflow="visible"></use>
|
||||
</clipPath>
|
||||
|
||||
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="-0.9131" y1="500" x2="1.9136" y2="500" gradientTransform="matrix(150 0 0 -150 175 75250)">
|
||||
<stop offset="0" style="stop-color:#FF00FF"></stop>
|
||||
<stop offset="1" style="stop-color:#0000FF"></stop>
|
||||
</linearGradient>
|
||||
<rect x="38.001" y="38" clip-path="url(#SVGID_2_)" fill="url(#SVGID_3_)" width="423.997" height="424"></rect>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
Loading…
Add table
Reference in a new issue