Compare commits

..

9 Commits

14 changed files with 93 additions and 125 deletions

View File

@ -2,7 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<Version>1.0.3.65</Version>
<Version>1.0.3.69</Version>
<NoWarn>NU1701,CA1816,CA1308,CA1810,CA2208</NoWarn>
</PropertyGroup>
<PropertyGroup>

View File

@ -227,7 +227,6 @@ namespace BTCPayServer.Configuration
PostgresConnectionString = conf.GetOrDefault<string>("postgres", null);
MySQLConnectionString = conf.GetOrDefault<string>("mysql", null);
BundleJsCss = conf.GetOrDefault<bool>("bundlejscss", true);
ExternalUrl = conf.GetOrDefault<Uri>("externalurl", null);
var sshSettings = ParseSSHConfiguration(conf);
if ((!string.IsNullOrEmpty(sshSettings.Password) || !string.IsNullOrEmpty(sshSettings.KeyFile)) && !string.IsNullOrEmpty(sshSettings.Server))
@ -287,7 +286,6 @@ namespace BTCPayServer.Configuration
private SSHSettings ParseSSHConfiguration(IConfiguration conf)
{
var externalUrl = conf.GetOrDefault<Uri>("externalurl", null);
var settings = new SSHSettings();
settings.Server = conf.GetOrDefault<string>("sshconnection", null);
if (settings.Server != null)
@ -314,12 +312,6 @@ namespace BTCPayServer.Configuration
settings.Username = "root";
}
}
else if (externalUrl != null)
{
settings.Port = 22;
settings.Username = "root";
settings.Server = externalUrl.DnsSafeHost;
}
settings.Password = conf.GetOrDefault<string>("sshpassword", "");
settings.KeyFile = conf.GetOrDefault<string>("sshkeyfile", "");
settings.KeyFilePassword = conf.GetOrDefault<string>("sshkeyfilepassword", "");
@ -348,11 +340,6 @@ namespace BTCPayServer.Configuration
get;
set;
}
public Uri ExternalUrl
{
get;
set;
}
public bool BundleJsCss
{
get;
@ -364,14 +351,5 @@ namespace BTCPayServer.Configuration
get;
set;
}
internal string GetRootUri()
{
if (ExternalUrl == null)
return null;
UriBuilder builder = new UriBuilder(ExternalUrl);
builder.Path = RootPath;
return builder.ToString();
}
}
}

View File

@ -288,6 +288,8 @@ namespace BTCPayServer.Controllers
store.AdditionalClaims.Add(new Claim(Policies.CanCreateInvoice.Key, store.Id));
try
{
var redirectUrl = Request.GetDisplayUrl().TrimEnd("/pay", StringComparison.InvariantCulture)
.Replace("hub?id=", string.Empty, StringComparison.InvariantCultureIgnoreCase);
var newInvoiceId = (await _InvoiceController.CreateInvoiceCore(new CreateInvoiceRequest()
{
OrderId = $"{PaymentRequestRepository.GetOrderIdForPaymentRequest(id)}",
@ -295,7 +297,7 @@ namespace BTCPayServer.Controllers
Price = amount.GetValueOrDefault(result.AmountDue),
FullNotifications = true,
BuyerEmail = result.Email,
RedirectURL = Request.GetDisplayUrl().Replace("/pay", "", StringComparison.InvariantCulture),
RedirectURL = redirectUrl,
}, store, HttpContext.Request.GetAbsoluteRoot(), new List<string>() { PaymentRequestRepository.GetInternalTag(id) })).Data.Id;
if (redirectToInvoice)

View File

@ -315,5 +315,15 @@ namespace BTCPayServer
var res = JsonConvert.SerializeObject(o, Formatting.None, jsonSettings);
return res;
}
public static string TrimEnd(this string input, string suffixToRemove,
StringComparison comparisonType) {
if (input != null && suffixToRemove != null
&& input.EndsWith(suffixToRemove, comparisonType)) {
return input.Substring(0, input.Length - suffixToRemove.Length);
}
else return input;
}
}
}

View File

@ -147,59 +147,33 @@ namespace BTCPayServer.Hosting
}
}
// Make sure that code executing after this point think that the external url has been hit.
if (_Options.ExternalUrl != null)
{
if (reverseProxyScheme != null && _Options.ExternalUrl.Scheme != reverseProxyScheme)
{
if (reverseProxyScheme == "http" && _Options.ExternalUrl.Scheme == "https")
Logs.PayServer.LogWarning($"BTCPay ExternalUrl setting expected to use scheme '{_Options.ExternalUrl.Scheme}' externally, but the reverse proxy uses scheme '{reverseProxyScheme}' (X-Forwarded-Port), forcing ExternalUrl");
}
httpContext.Request.Scheme = _Options.ExternalUrl.Scheme;
if (_Options.ExternalUrl.IsDefaultPort)
httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host);
else
{
if (reverseProxyPort != null && _Options.ExternalUrl.Port != reverseProxyPort.Value)
{
Logs.PayServer.LogWarning($"BTCPay ExternalUrl setting expected to use port '{_Options.ExternalUrl.Port}' externally, but the reverse proxy uses port '{reverseProxyPort.Value}'");
httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host, reverseProxyPort.Value);
}
else
{
httpContext.Request.Host = new HostString(_Options.ExternalUrl.Host, _Options.ExternalUrl.Port);
}
}
}
// NGINX pass X-Forwarded-Proto and X-Forwarded-Port, so let's use that to have better guess of the real domain
else
ushort? p = null;
if (reverseProxyScheme != null)
{
ushort? p = null;
if (reverseProxyScheme != null)
{
httpContext.Request.Scheme = reverseProxyScheme;
if (reverseProxyScheme == "http")
p = 80;
if (reverseProxyScheme == "https")
p = 443;
}
if (reverseProxyPort != null)
{
p = reverseProxyPort.Value;
}
if (p.HasValue)
{
bool isDefault = httpContext.Request.Scheme == "http" && p.Value == 80;
isDefault |= httpContext.Request.Scheme == "https" && p.Value == 443;
if (isDefault)
httpContext.Request.Host = new HostString(httpContext.Request.Host.Host);
else
httpContext.Request.Host = new HostString(httpContext.Request.Host.Host, p.Value);
}
httpContext.Request.Scheme = reverseProxyScheme;
if (reverseProxyScheme == "http")
p = 80;
if (reverseProxyScheme == "https")
p = 443;
}
if (reverseProxyPort != null)
{
p = reverseProxyPort.Value;
}
if (p.HasValue)
{
bool isDefault = httpContext.Request.Scheme == "http" && p.Value == 80;
isDefault |= httpContext.Request.Scheme == "https" && p.Value == 443;
if (isDefault)
httpContext.Request.Host = new HostString(httpContext.Request.Host.Host);
else
httpContext.Request.Host = new HostString(httpContext.Request.Host.Host, p.Value);
}
}
private static async Task HandleBitpayHttpException(HttpContext httpContext, BitpayHttpException ex)

View File

@ -45,11 +45,13 @@
<div class="single-item-order__right">
@if (Model.AvailableCryptos.Count > 1)
{
<div class="payment__currencies cursorPointer" onclick="openPaymentMethodDialog()">
<img v-bind:src="srvModel.cryptoImage" />
<span class="clickable_underline">{{srvModel.paymentMethodName}} ({{srvModel.cryptoCode}})</span>
<span v-show="srvModel.isLightning">&#9889;</span>
<span class="clickable_indicator fa fa-angle-right"></span>
<div class="paywithRowRight cursorPointer" onclick="openPaymentMethodDialog()">
<span class="payment__currencies ">
<img v-bind:src="srvModel.cryptoImage" />
<span>{{srvModel.paymentMethodName}} ({{srvModel.cryptoCode}})</span>
<span v-show="srvModel.isLightning">&#9889;</span>
<span class="clickable_indicator fa fa-angle-right"></span>
</span>
</div>
<div id="vexPopupDialog">
<ul class="vexmenu">

View File

@ -1,7 +1,6 @@
@model InvoicesModel
@{
ViewData["Title"] = "Invoices";
var rootUrl = Context.Request.GetAbsoluteRoot();
}
@section HeadScripts {

View File

@ -85,12 +85,7 @@
</div>
<div id="badUrl" class="alert alert-danger alert-dismissible" style="display:none; position:absolute; top:75px;" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<span>BTCPay is expecting you to access this website from <b>@(env.ExpectedProtocol)://@(env.ExpectedHost)/</b>. If you want to change this expectation:</span>
<ul>
<li>Either starts BTCPay with <b>--externalurl @(env.ExpectedProtocol)://@(env.ExpectedHost)/</b></li>
<li>Or, if using docker-compose deployment, setting environment variable <b>BTCPAY_PROTOCOL=@(env.ExpectedProtocol)</b> and <b>BTCPAY_HOST=@(env.ExpectedDomain)</b></li>
</ul>
<span>BTCPay is expecting you to access this website from <b>@(env.ExpectedProtocol)://@(env.ExpectedHost)/</b>. If you use a reverse proxy, please set the <b>X-Forwarded-Proto</b> header to <b>@(env.ExpectedProtocol)</b>:</span>
</div>
</div>
</nav>

View File

@ -8223,7 +8223,7 @@ a:hover {
}
.action-button--secondary {
background: #e7e7e7;
background: #e0e0e0;
border: 0;
box-shadow: none;
color: #4A4A4A;
@ -8397,9 +8397,9 @@ strong {
}
.currency-selection {
border-bottom: 1px solid #E9E9E9;
border-bottom: 1px solid #e0e0e0;
position: relative;
padding: 4px 15px;
padding: 4px 10px 4px 15px;
display: flex;
font-weight: 300;
color: #565D6E;
@ -8516,7 +8516,7 @@ strong {
.payment-tabs {
position: relative;
background: #fff;
border-top: 1px solid #E9E9E9;
border-top: 1px solid #e0e0e0;
display: flex;
font-size: 13.5px;
box-shadow: 0px 5px 7px 0px rgba(0, 0, 0, 0.09);
@ -8605,7 +8605,7 @@ strong {
margin-top: 15px;
padding: 15px;
background-color: #ffffff;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
border-radius: 5px;
width: 100%;
max-height: 300px;
@ -8701,7 +8701,7 @@ strong {
.manual-box.underpaid-expired__refund-pending > .manual-box__amount {
transition: all 250ms cubic-bezier(0.4, 0, 1, 1);
border-top-color: #E9E9E9;
border-top-color: #e0e0e0;
border-top-right-radius: 5px;
border-top-left-radius: 5px;
}
@ -8722,7 +8722,7 @@ strong {
padding-bottom: .7rem;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
border-bottom: 0;
max-height: 300px;
}
@ -8737,7 +8737,7 @@ strong {
text-align: center;
position: relative;
border-radius: 5px;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
}
.flipped .manual-box__amount {
@ -8776,8 +8776,8 @@ strong {
height: 10px;
width: 10px;
left: 50%;
border-right: 1px solid #E9E9E9;
border-bottom: 1px solid #E9E9E9;
border-right: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
transform: rotate(45deg);
margin-left: -5px;
bottom: -6px;
@ -8800,8 +8800,8 @@ strong {
height: 10px;
width: 10px;
left: 50%;
border-right: 1px solid #E9E9E9;
border-bottom: 1px solid #E9E9E9;
border-right: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
transform: rotateZ(45deg);
margin-left: -5px;
top: -5px;
@ -8813,7 +8813,7 @@ strong {
.manual-box__address > .flipper {
backface-visibility: hidden;
height: 100%;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
border-top: 0;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
@ -9155,7 +9155,7 @@ strong {
}
.bp-input {
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
border-radius: 2px;
font-size: 15px;
font-weight: 400;
@ -9482,7 +9482,7 @@ strong {
.payment__scan__qrcode img {
padding: 15px;
background-color: #ffffff;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
border-radius: 5px;
}
@ -9714,7 +9714,7 @@ strong {
background: #fff;
padding: 30px 15px;
text-align: center;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
border-radius: 5px;
margin: -5px 0 18px;
font-weight: 300;
@ -11335,7 +11335,7 @@ low-fee-timeline {
text-align: center;
position: relative;
border-radius: 5px;
border: 1px solid #E9E9E9;
border: 1px solid #e0e0e0;
background: #fff;
}
@ -11353,7 +11353,7 @@ low-fee-timeline {
}
.copySectionBox.bottomBorder {
border-bottom: 1px solid #e9e9e9;
border-bottom: 1px solid #e0e0e0;
}
.separatorGem {
@ -11361,8 +11361,8 @@ low-fee-timeline {
height: 10px;
width: 10px;
left: 50%;
border-right: 1px solid #E9E9E9;
border-bottom: 1px solid #E9E9E9;
border-right: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
transform: rotateZ(45deg);
margin-left: -5px;
top: -5px;
@ -11374,7 +11374,7 @@ low-fee-timeline {
.checkoutTextbox {
width: 100%;
border: 1px solid #e9e9e9;
border: 1px solid #e0e0e0;
border-radius: 4px;
outline: none;
padding: 8px 4px 8px;
@ -11402,7 +11402,7 @@ low-fee-timeline {
color: #aaa;
height: 16px;
padding: 0px 4px;
border-right: 1px solid #e9e9e9;
border-right: 1px solid #e0e0e0;
}
.inputWithIcon.inputIconBg img {

View File

@ -40,32 +40,35 @@
display: none;
}
.paywithRowRight {
margin-top: -1px;
}
.cursorPointer {
cursor: pointer;
}
.payment__currencies {
font-size: 14px;
font-size: 13px;
border: 1px solid #e0e0e0;
border-radius: 5px;
padding: 6px;
}
.payment__currencies img {
height: 32px;
margin-top: -3px;
height: 24px;
}
.clickable_underline {
border-bottom: 1px dotted #ccc;
font-size: 13px;
}
.payment__currencies:hover .clickable_underline {
border-bottom: 1px dotted black;
}
.payment__currencies:hover .clickable_underline {
border-bottom: 1px dotted black;
}
.payment__currencies:hover {
border: 1px solid #5c6373;
background: #f8f8f8;
}
.clickable_indicator {
margin-right: -10px;
opacity: 0.3;
}
.payment__currencies:hover .clickable_indicator {
opacity: 1;
color: #5c6373;
}

View File

@ -21,4 +21,4 @@ ENV BTCPAY_DATADIR=/datadir
VOLUME /datadir
COPY --from=builder "/app" .
ENTRYPOINT ["dotnet", "BTCPayServer.dll"]
ENTRYPOINT ["./docker-entrypoint.sh"]

View File

@ -18,4 +18,4 @@ ENV BTCPAY_DATADIR=/datadir
VOLUME /datadir
COPY --from=builder "/app" .
ENTRYPOINT ["dotnet", "BTCPayServer.dll"]
ENTRYPOINT ["./docker-entrypoint.sh"]

View File

@ -10,6 +10,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{29290EC7-00E6-4C4B-96D9-4D7E9611DF28}"
ProjectSection(SolutionItems) = preProject
.circleci\config.yml = .circleci\config.yml
docker-entrypoint.sh = docker-entrypoint.sh
Dockerfile.linuxamd64 = Dockerfile.linuxamd64
Dockerfile.linuxarm32v7 = Dockerfile.linuxarm32v7
EndProjectSection

4
docker-entrypoint.sh Normal file
View File

@ -0,0 +1,4 @@
#!/bin/sh
echo "$(/sbin/ip route|awk '/default/ { print $3 }') host.docker.internal" >> /etc/hosts
exec dotnet BTCPayServer.dll