Merge pull request #1361 from btcpayserver/pr/fix-1316

Showing the next available address in the invoices list
This commit is contained in:
rockstardev
2020-03-01 21:49:14 -06:00
committed by GitHub
8 changed files with 50 additions and 35 deletions

View File

@@ -53,6 +53,9 @@ namespace BTCPayServer.Tests
{
NBXplorerUri = ExplorerClient.Address,
TestDatabase = Enum.Parse<TestDatabases>(GetEnvironment("TESTS_DB", TestDatabases.Postgres.ToString()), true),
// TODO: The fact that we use same conn string as development database can cause huge problems with tests
// since in dev we already can have some users / stores registered, while on CI database is being initalized
// for the first time and first registered user gets admin status by default
Postgres = GetEnvironment("TESTS_POSTGRES", "User ID=postgres;Host=127.0.0.1;Port=39372;Database=btcpayserver"),
MySQL = GetEnvironment("TESTS_MYSQL", "User ID=root;Host=127.0.0.1;Port=33036;Database=btcpayserver")
};

View File

@@ -146,6 +146,7 @@ namespace BTCPayServer.Tests
};
await account.Register(RegisterDetails);
UserId = account.RegisteredUserId;
IsAdmin = account.RegisteredAdmin;
}
public RegisterViewModel RegisterDetails{ get; set; }

View File

@@ -39,7 +39,7 @@ namespace BTCPayServer.Controllers
SettingsRepository _SettingsRepository;
Configuration.BTCPayServerOptions _Options;
private readonly BTCPayServerEnvironment _btcPayServerEnvironment;
public U2FService _u2FService;
public U2FService _u2FService;
ILogger _logger;
public AccountController(
@@ -75,7 +75,7 @@ namespace BTCPayServer.Controllers
[AllowAnonymous]
public async Task<IActionResult> Login(string returnUrl = null)
{
if (User.Identity.IsAuthenticated && string.IsNullOrEmpty(returnUrl))
return RedirectToLocal();
// Clear the existing external cookie to ensure a clean login process
@@ -85,7 +85,7 @@ namespace BTCPayServer.Controllers
{
SetInsecureFlags();
}
ViewData["ReturnUrl"] = returnUrl;
return View();
}
@@ -126,7 +126,7 @@ namespace BTCPayServer.Controllers
if (await _userManager.CheckPasswordAsync(user, model.Password))
{
LoginWith2faViewModel twoFModel = null;
if (user.TwoFactorEnabled)
{
// we need to do an actual sign in attempt so that 2fa can function in next step
@@ -145,14 +145,14 @@ namespace BTCPayServer.Controllers
}
else
{
var incrementAccessFailedResult = await _userManager.AccessFailedAsync(user);
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
var incrementAccessFailedResult = await _userManager.AccessFailedAsync(user);
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
return View(model);
}
}
var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: true);
if (result.Succeeded)
{
@@ -215,7 +215,7 @@ namespace BTCPayServer.Controllers
{
return RedirectToAction("Login");
}
ViewData["ReturnUrl"] = returnUrl;
var user = await _userManager.FindByIdAsync(viewModel.UserId);
@@ -276,7 +276,7 @@ namespace BTCPayServer.Controllers
return View("SecondaryLogin", new SecondaryLoginViewModel()
{
LoginWith2FaViewModel = new LoginWith2faViewModel { RememberMe = rememberMe },
LoginWithU2FViewModel = (await _u2FService.HasDevices(user.Id))? await BuildU2FViewModel(rememberMe, user): null
LoginWithU2FViewModel = (await _u2FService.HasDevices(user.Id)) ? await BuildU2FViewModel(rememberMe, user) : null
});
}
@@ -322,7 +322,7 @@ namespace BTCPayServer.Controllers
return View("SecondaryLogin", new SecondaryLoginViewModel()
{
LoginWith2FaViewModel = model,
LoginWithU2FViewModel = (await _u2FService.HasDevices(user.Id))? await BuildU2FViewModel(rememberMe, user): null
LoginWithU2FViewModel = (await _u2FService.HasDevices(user.Id)) ? await BuildU2FViewModel(rememberMe, user) : null
});
}
}
@@ -447,12 +447,13 @@ namespace BTCPayServer.Controllers
var settings = await _SettingsRepository.GetSettingAsync<ThemeSettings>();
settings.FirstRun = false;
await _SettingsRepository.UpdateSetting<ThemeSettings>(settings);
if(_Options.DisableRegistration)
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).
policies.LockSubscription = true;
await _SettingsRepository.UpdateSetting(policies);
}
RegisteredAdmin = true;
}
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
@@ -462,7 +463,7 @@ namespace BTCPayServer.Controllers
_EmailSenderFactory.GetEmailSender().SendEmailConfirmation(model.Email, callbackUrl);
if (!policies.RequiresConfirmedEmail)
{
if(logon)
if (logon)
await _signInManager.SignInAsync(user, isPersistent: false);
return RedirectToLocal(returnUrl);
}
@@ -479,13 +480,9 @@ namespace BTCPayServer.Controllers
return View(model);
}
/// <summary>
/// Test property
/// </summary>
public string RegisteredUserId
{
get; set;
}
// Properties used by tests
public string RegisteredUserId { get; set; }
public bool RegisteredAdmin { get; set; }
[HttpGet]
public async Task<IActionResult> Logout()
@@ -539,7 +536,7 @@ namespace BTCPayServer.Controllers
var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
_EmailSenderFactory.GetEmailSender().SendEmail(model.Email, "Reset Password",
$"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
return RedirectToAction(nameof(ForgotPasswordConfirmation));
}
@@ -625,8 +622,8 @@ namespace BTCPayServer.Controllers
return RedirectToAction(nameof(HomeController.Index), "Home");
}
}
private bool CanLoginOrRegister()
{
return _btcPayServerEnvironment.IsDevelopping || _btcPayServerEnvironment.IsSecure;
@@ -639,7 +636,7 @@ namespace BTCPayServer.Controllers
Severity = StatusMessageModel.StatusSeverity.Error,
Message = "You cannot login over an insecure connection. Please use HTTPS or Tor."
});
ViewData["disabled"] = true;
}

View File

@@ -103,6 +103,7 @@ namespace BTCPayServer.Controllers
cryptoPayment.Paid = _CurrencyNameTable.DisplayFormatCurrency(accounting.CryptoPaid.ToDecimal(MoneyUnit.BTC), paymentMethodId.CryptoCode);
cryptoPayment.Overpaid = _CurrencyNameTable.DisplayFormatCurrency(accounting.OverpaidHelper.ToDecimal(MoneyUnit.BTC), paymentMethodId.CryptoCode);
var paymentMethodDetails = data.GetPaymentMethodDetails();
cryptoPayment.Address = paymentMethodDetails.GetPaymentDestination();
cryptoPayment.Rate = ExchangeRate(data);
model.CryptoPayments.Add(cryptoPayment);
}

View File

@@ -38,6 +38,7 @@ namespace BTCPayServer.Models.InvoicingModels
public string PaymentMethod { get; set; }
public string Due { get; set; }
public string Paid { get; set; }
public string Address { get; internal set; }
public string Rate { get; internal set; }
public string PaymentUrl { get; internal set; }
public string Overpaid { get; set; }

View File

@@ -183,7 +183,8 @@
</div>
}
<partial name="InvoicePaymentsPartial" model="Model" />
<partial name="ListInvoicesPaymentsPartial" model="(Model, false)" />
<div class="row">
<div class="col-md-12">

View File

@@ -274,7 +274,8 @@
<tr id="invoice_@invoice.InvoiceId" style="display:none;">
<td colspan="99">
<div style="margin-left: 15px; margin-bottom: 0;">
<partial name="InvoicePaymentsPartial" model="invoice.Details" />
@* Leaving this as partial because it abstracts complexity of Invoice Payments *@
<partial name="ListInvoicesPaymentsPartial" model="(invoice.Details, true)" />
</div>
</td>
</tr>

View File

@@ -1,31 +1,42 @@
@model InvoiceDetailsModel
@model (InvoiceDetailsModel Invoice, bool ShowAddress)
@{ var invoice = Model.Invoice; }
@inject PaymentMethodHandlerDictionary PaymentMethodHandlerDictionary
<div class="row">
<div class="col-md-12 invoice-payments">
<h3>Current status</h3>
<h3>Paid summary</h3>
<table class="table table-sm table-responsive-md">
<thead class="thead-inverse">
<tr>
<th>Payment method</th>
@if (Model.ShowAddress)
{
<th>Address</th>
}
<th class="text-right">Rate</th>
<th class="text-right">Paid</th>
<th class="text-right">Due</th>
@if (Model.StatusException == InvoiceExceptionStatus.PaidOver)
@if (invoice.StatusException == InvoiceExceptionStatus.PaidOver)
{
<th class="text-right">Overpaid</th>
}
</tr>
</thead>
<tbody>
@foreach (var payment in Model.CryptoPayments)
@foreach (var payment in invoice.CryptoPayments)
{
<tr>
<td>@payment.PaymentMethod</td>
@if (Model.ShowAddress)
{
<td title="@payment.Address">
<span class="text-truncate d-block" style="max-width: 400px">@payment.Address</span>
</td>
}
<td class="text-right">@payment.Rate</td>
<td class="text-right">@payment.Paid</td>
<td class="text-right">@payment.Due</td>
@if (Model.StatusException == InvoiceExceptionStatus.PaidOver)
@if (invoice.StatusException == InvoiceExceptionStatus.PaidOver)
{
<td class="text-right">@payment.Overpaid</td>
}
@@ -36,8 +47,7 @@
</div>
</div>
@{
var grouped = Model.Payments.GroupBy(payment => payment.GetPaymentMethodId().PaymentType);
var grouped = invoice.Payments.GroupBy(payment => payment.GetPaymentMethodId().PaymentType);
}
@foreach (var paymentGroup in grouped)
{