diff --git a/BTCPayServer.Tests/SeleniumTests.cs b/BTCPayServer.Tests/SeleniumTests.cs index f86bfbbcf..0bd1260dc 100644 --- a/BTCPayServer.Tests/SeleniumTests.cs +++ b/BTCPayServer.Tests/SeleniumTests.cs @@ -1179,7 +1179,7 @@ namespace BTCPayServer.Tests var bolt = (await s.Server.CustomerLightningD.CreateInvoice( payoutAmount, - $"LN payout test {DateTime.Now.Ticks}", + $"LN payout test {DateTime.UtcNow.Ticks}", TimeSpan.FromHours(1), CancellationToken.None)).BOLT11; s.Driver.FindElement(By.Id("Destination")).SendKeys(bolt); s.Driver.FindElement(By.Id("SelectedPaymentMethod")).Click(); @@ -1193,7 +1193,7 @@ namespace BTCPayServer.Tests bolt = (await s.Server.CustomerLightningD.CreateInvoice( payoutAmount, - $"LN payout test {DateTime.Now.Ticks}", + $"LN payout test {DateTime.UtcNow.Ticks}", TimeSpan.FromDays(31), CancellationToken.None)).BOLT11; s.Driver.FindElement(By.Id("Destination")).Clear(); s.Driver.FindElement(By.Id("Destination")).SendKeys(bolt); diff --git a/BTCPayServer/Controllers/AppsPublicController.cs b/BTCPayServer/Controllers/AppsPublicController.cs index 45caf01b9..527dadccb 100644 --- a/BTCPayServer/Controllers/AppsPublicController.cs +++ b/BTCPayServer/Controllers/AppsPublicController.cs @@ -308,8 +308,8 @@ namespace BTCPayServer.Controllers var info = await GetAppInfo(appId); if (!isAdmin && - ((settings.StartDate.HasValue && DateTime.Now < settings.StartDate) || - (settings.EndDate.HasValue && DateTime.Now > settings.EndDate) || + ((settings.StartDate.HasValue && DateTime.UtcNow < settings.StartDate) || + (settings.EndDate.HasValue && DateTime.UtcNow > settings.EndDate) || (settings.EnforceTargetAmount && (info.Info.PendingProgressPercentage.GetValueOrDefault(0) + info.Info.ProgressPercentage.GetValueOrDefault(0)) >= 100))) diff --git a/BTCPayServer/Controllers/InvoiceController.API.cs b/BTCPayServer/Controllers/InvoiceController.API.cs index 8d9f06861..520601ff6 100644 --- a/BTCPayServer/Controllers/InvoiceController.API.cs +++ b/BTCPayServer/Controllers/InvoiceController.API.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using BTCPayServer.Abstractions.Constants; using BTCPayServer.Client; using BTCPayServer.Filters; +using BTCPayServer.ModelBinders; using BTCPayServer.Models; using BTCPayServer.Security; using BTCPayServer.Services.Invoices; @@ -54,7 +55,9 @@ namespace BTCPayServer.Controllers [Route("invoices")] public async Task GetInvoices( string token, + [ModelBinder(typeof(BitpayDateTimeOffsetModelBinder))] DateTimeOffset? dateStart = null, + [ModelBinder(typeof(BitpayDateTimeOffsetModelBinder))] DateTimeOffset? dateEnd = null, string orderId = null, string itemCode = null, diff --git a/BTCPayServer/Controllers/PaymentRequestController.cs b/BTCPayServer/Controllers/PaymentRequestController.cs index 2a16c223d..3724d510c 100644 --- a/BTCPayServer/Controllers/PaymentRequestController.cs +++ b/BTCPayServer/Controllers/PaymentRequestController.cs @@ -201,7 +201,7 @@ namespace BTCPayServer.Controllers return BadRequest("Payment Request has already been settled."); } - if (result.ExpiryDate.HasValue && DateTime.Now >= result.ExpiryDate) + if (result.ExpiryDate.HasValue && DateTime.UtcNow >= result.ExpiryDate) { if (redirectToInvoice) { diff --git a/BTCPayServer/Controllers/PullPaymentController.cs b/BTCPayServer/Controllers/PullPaymentController.cs index 084429e3a..b933b50c0 100644 --- a/BTCPayServer/Controllers/PullPaymentController.cs +++ b/BTCPayServer/Controllers/PullPaymentController.cs @@ -75,7 +75,7 @@ namespace BTCPayServer.Controllers AmountDueFormatted = _currencyNameTable.FormatCurrency(amountDue, blob.Currency), CurrencyData = cd, StartDate = pp.StartDate, - LastRefreshed = DateTime.Now, + LastRefreshed = DateTime.UtcNow, Payouts = payouts .Select(entity => new ViewPullPaymentModel.PayoutLine { diff --git a/BTCPayServer/ModelBinders/BitpayDateTimeOffsetModelBinder.cs b/BTCPayServer/ModelBinders/BitpayDateTimeOffsetModelBinder.cs new file mode 100644 index 000000000..c6f069bc0 --- /dev/null +++ b/BTCPayServer/ModelBinders/BitpayDateTimeOffsetModelBinder.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc.ModelBinding; +using Microsoft.VisualBasic.CompilerServices; + +namespace BTCPayServer.ModelBinders +{ + public class BitpayDateTimeOffsetModelBinder : IModelBinder + { + public Task BindModelAsync(ModelBindingContext bindingContext) + { + if (!typeof(DateTimeOffset).GetTypeInfo().IsAssignableFrom(bindingContext.ModelType) && + !typeof(DateTimeOffset?).GetTypeInfo().IsAssignableFrom(bindingContext.ModelType)) + { + return Task.CompletedTask; + } + ValueProviderResult val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); + string v = val.FirstValue as string; + if (v == null) + { + return Task.CompletedTask; + } + + try + { + var sec = DateTimeOffset.ParseExact(v, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); + bindingContext.Result = ModelBindingResult.Success(sec); + } + catch + { + bindingContext.Result = ModelBindingResult.Failed(); + bindingContext.ModelState.AddModelError(bindingContext.ModelName, "Invalid date (MM/dd/yyyy)"); + } + return Task.CompletedTask; + } + } +} diff --git a/BTCPayServer/PaymentRequest/PaymentRequestHub.cs b/BTCPayServer/PaymentRequest/PaymentRequestHub.cs index 2b15e5bde..0b17cb489 100644 --- a/BTCPayServer/PaymentRequest/PaymentRequestHub.cs +++ b/BTCPayServer/PaymentRequest/PaymentRequestHub.cs @@ -192,7 +192,7 @@ namespace BTCPayServer.PaymentRequest { Task.Run(async () => { - var delay = expiry - DateTime.Now; + var delay = expiry - DateTime.UtcNow; if (delay > TimeSpan.Zero) await Task.Delay(delay, cancellationToken); await _PaymentRequestService.UpdatePaymentRequestStateIfNeeded(paymentRequestId); diff --git a/BTCPayServer/PaymentRequest/PaymentRequestService.cs b/BTCPayServer/PaymentRequest/PaymentRequestService.cs index b338de146..2e4bcfb4e 100644 --- a/BTCPayServer/PaymentRequest/PaymentRequestService.cs +++ b/BTCPayServer/PaymentRequest/PaymentRequestService.cs @@ -96,7 +96,7 @@ namespace BTCPayServer.PaymentRequest AmountDue = amountDue, AmountDueFormatted = _currencies.FormatCurrency(amountDue, blob.Currency), CurrencyData = _currencies.GetCurrencyData(blob.Currency, true), - LastUpdated = DateTime.Now, + LastUpdated = DateTime.UtcNow, AnyPendingInvoice = pendingInvoice != null, PendingInvoiceHasPayments = pendingInvoice != null && pendingInvoice.ExceptionStatus != InvoiceExceptionStatus.None, diff --git a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs index 50d7130af..736e65e85 100644 --- a/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs +++ b/BTCPayServer/Services/Altcoins/Monero/Services/MoneroRPCProvider.cs @@ -65,7 +65,7 @@ namespace BTCPayServer.Services.Altcoins.Monero.Services summary.CurrentHeight = daemonResult.Height; summary.TargetHeight = summary.TargetHeight == 0 ? summary.CurrentHeight : summary.TargetHeight; summary.Synced = daemonResult.Height >= summary.TargetHeight && summary.CurrentHeight > 0; - summary.UpdatedAt = DateTime.Now; + summary.UpdatedAt = DateTime.UtcNow; summary.DaemonAvailable = true; } catch diff --git a/BTCPayServer/Services/Apps/AppService.cs b/BTCPayServer/Services/Apps/AppService.cs index 6cc37a929..a0a355f03 100644 --- a/BTCPayServer/Services/Apps/AppService.cs +++ b/BTCPayServer/Services/Apps/AppService.cs @@ -69,7 +69,7 @@ namespace BTCPayServer.Services.Apps lastResetDate = settings.StartDate.Value; nextResetDate = lastResetDate.Value; - while (DateTime.Now >= nextResetDate) + while (DateTime.UtcNow >= nextResetDate) { lastResetDate = nextResetDate; switch (resetEvery) @@ -171,7 +171,7 @@ namespace BTCPayServer.Services.Apps TotalContributors = paidInvoices.Length, ProgressPercentage = (currentPayments.TotalCurrency / settings.TargetAmount) * 100, PendingProgressPercentage = (pendingPayments.TotalCurrency / settings.TargetAmount) * 100, - LastUpdated = DateTime.Now, + LastUpdated = DateTime.UtcNow, PaymentStats = currentPayments.ToDictionary(c => c.Key.ToString(), c => c.Value.Value), PendingPaymentStats = pendingPayments.ToDictionary(c => c.Key.ToString(), c => c.Value.Value), LastResetDate = lastResetDate, diff --git a/BTCPayServer/Storage/Services/Providers/BaseTwentyTwentyStorageFileProviderServiceBase.cs b/BTCPayServer/Storage/Services/Providers/BaseTwentyTwentyStorageFileProviderServiceBase.cs index 73e5d310d..7a8c2e52c 100644 --- a/BTCPayServer/Storage/Services/Providers/BaseTwentyTwentyStorageFileProviderServiceBase.cs +++ b/BTCPayServer/Storage/Services/Providers/BaseTwentyTwentyStorageFileProviderServiceBase.cs @@ -33,7 +33,7 @@ namespace BTCPayServer.Storage.Services.Providers return new StoredFile() { - Timestamp = DateTime.Now, + Timestamp = DateTime.UtcNow, FileName = file.FileName, StorageFileName = storageFileName }; diff --git a/BTCPayServer/Storage/Services/Providers/FileSystemStorage/TemporaryLocalFileProvider.cs b/BTCPayServer/Storage/Services/Providers/FileSystemStorage/TemporaryLocalFileProvider.cs index 2a812490a..ad65211e5 100644 --- a/BTCPayServer/Storage/Services/Providers/FileSystemStorage/TemporaryLocalFileProvider.cs +++ b/BTCPayServer/Storage/Services/Providers/FileSystemStorage/TemporaryLocalFileProvider.cs @@ -30,7 +30,7 @@ namespace BTCPayServer.Storage.Services.Providers.FileSystemStorage var text = File.ReadAllText(path); var descriptor = JsonConvert.DeserializeObject(text); - if (descriptor.Expiry < DateTime.Now) + if (descriptor.Expiry < DateTime.UtcNow) { File.Delete(path); return new NotFoundFileInfo(tmpFileId);