Compare commits

...

11 Commits

Author SHA1 Message Date
92777ba181 Make sure SSH does not throw in separate thread 2019-11-18 17:15:40 +09:00
81843fb609 Do not delete the password from the seed 2019-11-18 17:00:54 +09:00
3af3ffd038 Merge pull request #1167 from dennisreimann/ui-improvements
UI: Payment request improvement
2019-11-18 14:23:51 +09:00
2ce5cd0b6f Merge pull request #1171 from bitcoinbrisbane/master
Add office 365 to the quick fill settings
2019-11-18 14:23:12 +09:00
d791fd59e9 Merge branch 'master' of github.com:bitcoinbrisbane/btcpayserver 2019-11-18 08:12:30 +10:00
6064e3ce55 Add office365 quick settings 2019-11-18 08:12:06 +10:00
0fcfe0e977 Can prune wallet transaction history 2019-11-17 17:13:09 +09:00
997df5c64d Remove build warnings 2019-11-17 16:50:28 +09:00
0be6f3ca70 UI: Remove superfluous spaces when description is empty 2019-11-16 23:28:53 +01:00
7af80611b6 UI: Better payment request amounts display
Uses a table instead of list group items, so that the columns properly align (rows use the same grid). Also aligns the values on the right.
2019-11-16 22:59:51 +01:00
929b5c7951 Add display attributes. Fix #98 2019-08-24 15:39:43 +10:00
10 changed files with 134 additions and 97 deletions

View File

@ -2,7 +2,7 @@
<Import Project="../Build/Version.csproj" Condition="Exists('../Build/Version.csproj')" />
<Import Project="../Build/Common.csproj" />
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.1'">
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.9" />
<PackageReference Include="Microsoft.AspNetCore.App" AllowExplicitVersion="true" Version="2.1.9" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.1.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.1.2" />

View File

@ -56,7 +56,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.9" Condition="'$(TargetFramework)' == 'netcoreapp2.1'" />
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.9" AllowExplicitVersion="true" Condition="'$(TargetFramework)' == 'netcoreapp2.1'" />
<PackageReference Include="TwentyTwenty.Storage" Version="2.11.2" />
<PackageReference Include="TwentyTwenty.Storage.Amazon" Version="2.11.2" />
<PackageReference Include="TwentyTwenty.Storage.Azure" Version="2.11.2" />

View File

@ -873,27 +873,48 @@ namespace BTCPayServer.Controllers
[HttpPost]
public async Task<IActionResult> WalletSettings(
[ModelBinder(typeof(WalletIdModelBinder))]
WalletId walletId, WalletSettingsViewModel vm)
WalletId walletId, WalletSettingsViewModel vm, string command = "save", CancellationToken cancellationToken = default)
{
if (!ModelState.IsValid)
return View(vm);
var derivationScheme = GetDerivationSchemeSettings(walletId);
if (derivationScheme == null)
return NotFound();
derivationScheme.Label = vm.Label;
derivationScheme.SigningKey = string.IsNullOrEmpty(vm.SelectedSigningKey) ? null : new BitcoinExtPubKey(vm.SelectedSigningKey, derivationScheme.Network.NBitcoinNetwork);
for (int i = 0; i < derivationScheme.AccountKeySettings.Length; i++)
if (command == "save")
{
derivationScheme.AccountKeySettings[i].AccountKeyPath = string.IsNullOrWhiteSpace(vm.AccountKeys[i].AccountKeyPath) ? null
: new KeyPath(vm.AccountKeys[i].AccountKeyPath);
derivationScheme.AccountKeySettings[i].RootFingerprint = string.IsNullOrWhiteSpace(vm.AccountKeys[i].MasterFingerprint) ? (HDFingerprint?)null
: new HDFingerprint(Encoders.Hex.DecodeData(vm.AccountKeys[i].MasterFingerprint));
derivationScheme.Label = vm.Label;
derivationScheme.SigningKey = string.IsNullOrEmpty(vm.SelectedSigningKey) ? null : new BitcoinExtPubKey(vm.SelectedSigningKey, derivationScheme.Network.NBitcoinNetwork);
for (int i = 0; i < derivationScheme.AccountKeySettings.Length; i++)
{
derivationScheme.AccountKeySettings[i].AccountKeyPath = string.IsNullOrWhiteSpace(vm.AccountKeys[i].AccountKeyPath) ? null
: new KeyPath(vm.AccountKeys[i].AccountKeyPath);
derivationScheme.AccountKeySettings[i].RootFingerprint = string.IsNullOrWhiteSpace(vm.AccountKeys[i].MasterFingerprint) ? (HDFingerprint?)null
: new HDFingerprint(Encoders.Hex.DecodeData(vm.AccountKeys[i].MasterFingerprint));
}
var store = (await Repository.FindStore(walletId.StoreId, GetUserId()));
store.SetSupportedPaymentMethod(derivationScheme);
await Repository.UpdateStore(store);
TempData[WellKnownTempData.SuccessMessage] = "Wallet settings updated";
return RedirectToAction(nameof(WalletSettings));
}
else if (command == "prune")
{
var result = await ExplorerClientProvider.GetExplorerClient(walletId.CryptoCode).PruneAsync(derivationScheme.AccountDerivation, cancellationToken);
if (result.TotalPruned == 0)
{
TempData[WellKnownTempData.SuccessMessage] = $"The wallet is already pruned";
}
else
{
TempData[WellKnownTempData.SuccessMessage] = $"The wallet has been successfully pruned ({result.TotalPruned} transactions have been removed from the history)";
}
return RedirectToAction(nameof(WalletSettings));
}
else
{
return NotFound();
}
var store = (await Repository.FindStore(walletId.StoreId, GetUserId()));
store.SetSupportedPaymentMethod(derivationScheme);
await Repository.UpdateStore(store);
TempData[WellKnownTempData.SuccessMessage] = "Wallet settings updated";
return RedirectToAction(nameof(WalletSettings));
}
}

View File

@ -71,22 +71,26 @@ namespace BTCPayServer
var tcs = new TaskCompletionSource<SSHCommandResult>(TaskCreationOptions.RunContinuationsAsynchronously);
new Thread(() =>
{
sshCommand.BeginExecute(ar =>
try
{
try
sshCommand.BeginExecute(ar =>
{
sshCommand.EndExecute(ar);
tcs.TrySetResult(CreateSSHCommandResult(sshCommand));
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
finally
{
sshCommand.Dispose();
}
});
try
{
sshCommand.EndExecute(ar);
tcs.TrySetResult(CreateSSHCommandResult(sshCommand));
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
finally
{
sshCommand.Dispose();
}
});
}
catch(Exception ex) { tcs.TrySetException(ex); }
})
{ IsBackground = true }.Start();
return tcs.Task;

View File

@ -22,7 +22,7 @@ namespace BTCPayServer.Models.ServerViewModels
var removedDate = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ssZ", CultureInfo.InvariantCulture);
var seedFile = new LndSeedFile
{
wallet_password = "",
wallet_password = WalletPassword,
cipher_seed_mnemonic = new List<string> { $"Seed removed on {removedDate}" }
};
var json = JsonConvert.SerializeObject(seedFile);
@ -47,7 +47,13 @@ namespace BTCPayServer.Models.ServerViewModels
{
var unlockFileContents = File.ReadAllText(lndSeedFilePath);
var unlockFile = JsonConvert.DeserializeObject<LndSeedFile>(unlockFileContents);
#pragma warning disable CA1820 // Test for empty strings using string length
if (unlockFile.wallet_password == string.Empty)
#pragma warning restore CA1820 // Test for empty strings using string length
{
// Nicolas stupidinly deleted the password, so we should use the default one here...
unlockFile.wallet_password = "hellorockstar";
}
if (unlockFile.wallet_password != null)
{
return new LndSeedBackupViewModel

View File

@ -4,45 +4,43 @@
<div class="row w-100 p-0 m-0" style="height: 100vh">
<div class="mx-auto my-auto w-100">
<div class="card">
<h1 class="card-header">
<h1 class="card-header px-3">
@Model.Title
<span class="text-muted float-right text-center">@Model.Status</span>
</h1>
<div class="card-body px-0 pt-0">
<div class="row mb-4">
<div class="col-sm-12 col-md-12 col-lg-6 ">
<ul class="w-100 list-group list-group-flush">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Request amount:</span>
<span class="h2">@Model.AmountFormatted</span>
</div>
</li>
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Paid so far:</span>
<span class="h2">@Model.AmountCollectedFormatted</span>
</div>
</li>
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Amount due:</span>
<span class="h2">@Model.AmountDueFormatted</span>
</div>
</li>
</ul>
<div class="w-100 p-2">@Safe.Raw(Model.Description)</div>
<div class="card-body px-0 pt-0 pb-0">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
<table class="table table-light mb-0">
<tbody>
<tr>
<td class="px-3 h2 text-muted">Request amount:</td>
<td class="px-3 h2 text-nowrap text-right">@Model.AmountFormatted</td>
</tr>
<tr>
<td class="px-3 h2 text-muted">Paid so far:</td>
<td class="px-3 h2 text-nowrap text-right">@Model.AmountCollectedFormatted</td>
</tr>
<tr>
<td class="px-3 h2 text-muted">Amount due:</td>
<td class="px-3 h2 text-nowrap text-right">@Model.AmountDueFormatted</td>
</tr>
</tbody>
</table>
@if (Model.Description != null && Model.Description != "" && Model.Description != "<br>")
{
<div class="w-100 px-3 pt-4 pb-3">@Safe.Raw(Model.Description)</div>
}
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
<div class="col-sm-12 col-md-12 col-lg-6 pt-2">
<div class="table-responsive">
<table class="table border-top-0 ">
<table class="table border-top-0">
<thead>
<tr>
<th class=" border-top-0" scope="col">Invoice #</th>
<th class=" border-top-0">Price</th>
<th class=" border-top-0">Expiry</th>
<th class=" border-top-0">Status</th>
<th class="border-top-0" scope="col">Invoice #</th>
<th class="border-top-0">Price</th>
<th class="border-top-0">Expiry</th>
<th class="border-top-0">Status</th>
</tr>
</thead>
<tbody>

View File

@ -52,7 +52,7 @@ else
<div class="row w-100 p-0 m-0" style="height: 100vh">
<div class="mx-auto my-auto w-100">
<div class="card">
<h1 class="card-header">
<h1 class="card-header px-3">
{{srvModel.title}}
<span class="text-muted float-right text-center">
@ -64,41 +64,40 @@ else
</template>
</span>
</h1>
<div class="card-body px-0 pt-0">
<div class="row mb-4">
<div class="col-sm-12 col-md-12 col-lg-6 ">
<ul class="w-100 list-group list-group-flush">
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Request amount:</span>
<span class="h2">{{srvModel.amountFormatted}}</span>
</div>
</li>
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Paid so far:</span>
<span class="h2">{{srvModel.amountCollectedFormatted}}</span>
</div>
</li>
<li class="list-group-item list-group-item-light">
<div class="d-flex justify-content-between">
<span class="h2 text-muted">Amount due:</span>
<span class="h2">{{srvModel.amountDueFormatted}}</span>
</div>
</li>
</ul>
<div v-html="srvModel.description" class="w-100 p-2"></div>
<div class="card-body px-0 pt-0 pb-0">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-6">
<table class="table table-light mb-0">
<tbody>
<tr>
<td class="px-3 h2 text-muted">Request amount:</td>
<td class="px-3 h2 text-nowrap text-right">{{srvModel.amountFormatted}}</td>
</tr>
<tr>
<td class="px-3 h2 text-muted">Paid so far:</td>
<td class="px-3 h2 text-nowrap text-right">{{srvModel.amountCollectedFormatted}}</td>
</tr>
<tr>
<td class="px-3 h2 text-muted">Amount due:</td>
<td class="px-3 h2 text-nowrap text-right">{{srvModel.amountDueFormatted}}</td>
</tr>
</tbody>
</table>
<div
v-if="srvModel.description && srvModel.description !== '' && srvModel.description !== '<br>'"
v-html="srvModel.description"
class="w-100 px-3 pt-4 pb-3"
></div>
</div>
<div class="col-sm-12 col-md-12 col-lg-6">
<div class="col-sm-12 col-md-12 col-lg-6 pt-2">
<div class="table-responsive">
<table class="table border-top-0 ">
<thead>
<tr>
<th class=" border-top-0" scope="col">Invoice #</th>
<th class=" border-top-0">Price</th>
<th class=" border-top-0">Expiry</th>
<th class=" border-top-0">Status</th>
<th class="border-top-0" scope="col">Invoice #</th>
<th class="border-top-0">Price</th>
<th class="border-top-0">Expiry</th>
<th class="border-top-0">Status</th>
</tr>
</thead>
<tbody>

View File

@ -18,6 +18,7 @@
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="" data-Server="smtp.gmail.com" data-Port="587" data-EnableSSL="true">Gmail.com</a>
<a class="dropdown-item" href="" data-Server="mail.yahoo.com" data-Port="587" data-EnableSSL="true">Yahoo.com</a>
<a class="dropdown-item" href="" data-Server="smtp.office365.com" data-Port="587" data-EnableSSL="true">Office365</a>
</div>
</div>
<p></p>

View File

@ -68,8 +68,16 @@
</div>
}
}
<div class="form-group">
<button name="command" type="submit" class="btn btn-primary">Save</button>
<div class="form-group d-flex mt-2">
<button name="command" type="submit" class="btn btn-primary" value="save">Save</button>
<div class="dropdown">
<button class="ml-1 btn btn-secondary dropdown-toggle" type="button" id="SendMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Other actions...
</button>
<div class="dropdown-menu" aria-labelledby="SendMenu">
<button name="command" type="submit" class="dropdown-item" value="prune">Prune old transactions from history</button>
</div>
</div>
</div>
</form>
</div>

View File

@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<Version>1.0.3.139</Version>
<Version>1.0.3.141</Version>
</PropertyGroup>
</Project>