mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-02 05:34:22 +01:00
Merge pull request #1361 from btcpayserver/pr/fix-1316
Showing the next available address in the invoices list
This commit is contained in:
@@ -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")
|
||||
};
|
||||
|
||||
@@ -146,6 +146,7 @@ namespace BTCPayServer.Tests
|
||||
};
|
||||
await account.Register(RegisterDetails);
|
||||
UserId = account.RegisteredUserId;
|
||||
IsAdmin = account.RegisteredAdmin;
|
||||
}
|
||||
|
||||
public RegisterViewModel RegisterDetails{ get; set; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -183,7 +183,8 @@
|
||||
</div>
|
||||
}
|
||||
|
||||
<partial name="InvoicePaymentsPartial" model="Model" />
|
||||
<partial name="ListInvoicesPaymentsPartial" model="(Model, false)" />
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
Reference in New Issue
Block a user