diff --git a/VoidCat/Controllers/DownloadController.cs b/VoidCat/Controllers/DownloadController.cs index 1806007..87f0bfa 100644 --- a/VoidCat/Controllers/DownloadController.cs +++ b/VoidCat/Controllers/DownloadController.cs @@ -1,7 +1,7 @@ using System.Net; using Microsoft.AspNetCore.Mvc; using VoidCat.Model; -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; @@ -12,16 +12,16 @@ public class DownloadController : Controller { private readonly FileStoreFactory _storage; private readonly FileInfoManager _fileInfo; - private readonly IPaywallOrderStore _paywallOrders; + private readonly IPaymentOrderStore _paymentOrders; private readonly ILogger _logger; public DownloadController(FileStoreFactory storage, ILogger logger, FileInfoManager fileInfo, - IPaywallOrderStore paywall) + IPaymentOrderStore paymentOrderStore) { _storage = storage; _logger = logger; _fileInfo = fileInfo; - _paywallOrders = paywall; + _paymentOrders = paymentOrderStore; } [HttpOptions] @@ -45,7 +45,7 @@ public class DownloadController : Controller var voidFile = await SetupDownload(gid); if (voidFile == default) return; - var egressReq = new EgressRequest(gid, GetRanges(Request, (long)voidFile!.Metadata!.Size)); + var egressReq = new EgressRequest(gid, GetRanges(Request, (long) voidFile!.Metadata!.Size)); if (egressReq.Ranges.Count() > 1) { _logger.LogWarning("Multi-range request not supported!"); @@ -57,10 +57,10 @@ public class DownloadController : Controller } else if (egressReq.Ranges.Count() == 1) { - Response.StatusCode = (int)HttpStatusCode.PartialContent; + Response.StatusCode = (int) HttpStatusCode.PartialContent; if (egressReq.Ranges.Sum(a => a.Size) == 0) { - Response.StatusCode = (int)HttpStatusCode.RequestedRangeNotSatisfiable; + Response.StatusCode = (int) HttpStatusCode.RequestedRangeNotSatisfiable; return; } } @@ -78,7 +78,7 @@ public class DownloadController : Controller var preResult = await _storage.StartEgress(egressReq); if (preResult.Redirect != null) { - Response.StatusCode = (int)HttpStatusCode.Redirect; + Response.StatusCode = (int) HttpStatusCode.Redirect; Response.Headers.Location = preResult.Redirect.ToString(); Response.ContentLength = 0; return; @@ -99,13 +99,13 @@ public class DownloadController : Controller return default; } - // check paywall - if (meta.Paywall != default && meta.Paywall.Service != PaymentServices.None) + // check payment order + if (meta.Payment != default && meta.Payment.Service != PaymentServices.None) { var orderId = Request.Headers.GetHeader("V-OrderId") ?? Request.Query["orderId"]; if (!await IsOrderPaid(orderId)) { - Response.StatusCode = (int)HttpStatusCode.PaymentRequired; + Response.StatusCode = (int) HttpStatusCode.PaymentRequired; return default; } } @@ -121,8 +121,8 @@ public class DownloadController : Controller { if (Guid.TryParse(orderId, out var oid)) { - var order = await _paywallOrders.Get(oid); - if (order?.Status == PaywallOrderStatus.Paid) + var order = await _paymentOrders.Get(oid); + if (order?.Status == PaymentOrderStatus.Paid) { return true; } @@ -146,4 +146,4 @@ public class DownloadController : Controller } } } -} +} \ No newline at end of file diff --git a/VoidCat/Controllers/UploadController.cs b/VoidCat/Controllers/UploadController.cs index d794bec..f981e85 100644 --- a/VoidCat/Controllers/UploadController.cs +++ b/VoidCat/Controllers/UploadController.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.StaticFiles; using Newtonsoft.Json; using VoidCat.Model; -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; @@ -15,22 +15,22 @@ namespace VoidCat.Controllers { private readonly FileStoreFactory _storage; private readonly IFileMetadataStore _metadata; - private readonly IPaywallStore _paywall; - private readonly IPaywallFactory _paywallFactory; + private readonly IPaymentStore _payment; + private readonly IPaymentFactory _paymentFactory; private readonly FileInfoManager _fileInfo; private readonly IUserUploadsStore _userUploads; private readonly IUserStore _userStore; private readonly ITimeSeriesStatsReporter _timeSeriesStats; private readonly VoidSettings _settings; - public UploadController(FileStoreFactory storage, IFileMetadataStore metadata, IPaywallStore paywall, - IPaywallFactory paywallFactory, FileInfoManager fileInfo, IUserUploadsStore userUploads, + public UploadController(FileStoreFactory storage, IFileMetadataStore metadata, IPaymentStore payment, + IPaymentFactory paymentFactory, FileInfoManager fileInfo, IUserUploadsStore userUploads, ITimeSeriesStatsReporter timeSeriesStats, IUserStore userStore, VoidSettings settings) { _storage = storage; _metadata = metadata; - _paywall = paywall; - _paywallFactory = paywallFactory; + _payment = payment; + _paymentFactory = paymentFactory; _fileInfo = fileInfo; _userUploads = userUploads; _timeSeriesStats = timeSeriesStats; @@ -204,20 +204,20 @@ namespace VoidCat.Controllers } /// - /// Create a paywall order to pay + /// Create a payment order to pay /// /// File id /// [HttpGet] - [Route("{id}/paywall")] - public async ValueTask CreateOrder([FromRoute] string id) + [Route("{id}/payment")] + public async ValueTask CreateOrder([FromRoute] string id) { var gid = id.FromBase58Guid(); var file = await _fileInfo.Get(gid); - var config = await _paywall.Get(gid); + var config = await _payment.Get(gid); - var provider = await _paywallFactory.CreateProvider(config!.Service); - return await provider.CreateOrder(file!.Paywall!); + var provider = await _paymentFactory.CreateProvider(config!.Service); + return await provider.CreateOrder(file!.Payment!); } /// @@ -227,25 +227,25 @@ namespace VoidCat.Controllers /// Order id /// [HttpGet] - [Route("{id}/paywall/{order:guid}")] - public async ValueTask GetOrderStatus([FromRoute] string id, [FromRoute] Guid order) + [Route("{id}/payment/{order:guid}")] + public async ValueTask GetOrderStatus([FromRoute] string id, [FromRoute] Guid order) { var gid = id.FromBase58Guid(); - var config = await _paywall.Get(gid); + var config = await _payment.Get(gid); - var provider = await _paywallFactory.CreateProvider(config!.Service); + var provider = await _paymentFactory.CreateProvider(config!.Service); return await provider.GetOrderStatus(order); } /// - /// Update the paywall config + /// Update the payment config /// /// File id /// Requested config to set on the file /// [HttpPost] - [Route("{id}/paywall")] - public async Task SetPaywallConfig([FromRoute] string id, [FromBody] SetPaywallConfigRequest req) + [Route("{id}/payment")] + public async Task SetPaymentConfig([FromRoute] string id, [FromBody] SetPaymentConfigRequest req) { var gid = id.FromBase58Guid(); var meta = await _metadata.Get(gid); @@ -254,7 +254,7 @@ namespace VoidCat.Controllers if (req.Strike != default) { - await _paywall.Add(gid, new StrikePaywallConfig() + await _payment.Add(gid, new StrikePaymentConfig() { Service = PaymentServices.Strike, Handle = req.Strike.Handle, @@ -265,7 +265,7 @@ namespace VoidCat.Controllers } // if none set, delete config - await _paywall.Delete(gid); + await _payment.Delete(gid); return Ok(); } @@ -335,11 +335,11 @@ namespace VoidCat.Controllers => new(false, null, message); } - public record SetPaywallConfigRequest + public record SetPaymentConfigRequest { [JsonConverter(typeof(Base58GuidConverter))] public Guid EditSecret { get; init; } - public StrikePaywallConfig? Strike { get; init; } + public StrikePaymentConfig? Strike { get; init; } } } diff --git a/VoidCat/Model/Payments/PaymentMoney.cs b/VoidCat/Model/Payments/PaymentMoney.cs new file mode 100644 index 0000000..c6419db --- /dev/null +++ b/VoidCat/Model/Payments/PaymentMoney.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace VoidCat.Model.Payments; + +/// +/// Money amount for payment orders +/// +/// +/// +public record PaymentMoney(decimal Amount, PaymentCurrencies Currency); + +/// +/// Supported payment currencies +/// +[JsonConverter(typeof(JsonStringEnumConverter))] +public enum PaymentCurrencies : byte +{ + BTC = 0, + USD = 1, + EUR = 2, + GBP = 3 +} diff --git a/VoidCat/Model/Paywall/PaywallOrder.cs b/VoidCat/Model/Payments/PaymentOrder.cs similarity index 75% rename from VoidCat/Model/Paywall/PaywallOrder.cs rename to VoidCat/Model/Payments/PaymentOrder.cs index 3fae47c..dac7ca0 100644 --- a/VoidCat/Model/Paywall/PaywallOrder.cs +++ b/VoidCat/Model/Payments/PaymentOrder.cs @@ -1,9 +1,9 @@ -namespace VoidCat.Model.Paywall; +namespace VoidCat.Model.Payments; /// -/// Status of paywall order +/// Status of payment order /// -public enum PaywallOrderStatus : byte +public enum PaymentOrderStatus : byte { /// /// Invoice is not paid yet @@ -22,9 +22,9 @@ public enum PaywallOrderStatus : byte } /// -/// Base paywall order +/// Base payment order /// -public class PaywallOrder +public class PaymentOrder { /// /// Unique id of the order @@ -44,18 +44,18 @@ public class PaywallOrder /// /// The price of the order /// - public PaywallMoney Price { get; init; } = null!; + public PaymentMoney Price { get; init; } = null!; /// /// Current status of the order /// - public PaywallOrderStatus Status { get; set; } + public PaymentOrderStatus Status { get; set; } } /// -/// A paywall order lightning network invoice +/// A payment order lightning network invoice /// -public class LightningPaywallOrder : PaywallOrder +public class LightningPaymentOrder : PaymentOrder { /// /// Lightning invoice diff --git a/VoidCat/Model/Payments/PaymentServices.cs b/VoidCat/Model/Payments/PaymentServices.cs new file mode 100644 index 0000000..6e66e9e --- /dev/null +++ b/VoidCat/Model/Payments/PaymentServices.cs @@ -0,0 +1,17 @@ +namespace VoidCat.Model.Payments; + +/// +/// Payment services supported by the system +/// +public enum PaymentServices +{ + /// + /// No service + /// + None, + + /// + /// Strike.me payment service + /// + Strike +} \ No newline at end of file diff --git a/VoidCat/Model/Payments/PaymentsConfig.cs b/VoidCat/Model/Payments/PaymentsConfig.cs new file mode 100644 index 0000000..af50b8b --- /dev/null +++ b/VoidCat/Model/Payments/PaymentsConfig.cs @@ -0,0 +1,45 @@ +namespace VoidCat.Model.Payments; + +/// +/// Base payment config +/// +public abstract class PaymentConfig +{ + /// + /// File this config is for + /// + public Guid File { get; init; } + + /// + /// Service used to pay the payment + /// + public PaymentServices Service { get; init; } = PaymentServices.None; + + /// + /// The cost for the payment to pass + /// + public PaymentMoney Cost { get; init; } = new(0m, PaymentCurrencies.BTC); + + /// + /// If the payment is required + /// + public bool Required { get; init; } = true; +} + +/// +public sealed class NoPaymentConfig : PaymentConfig +{ + +} + +/// +/// Payment config for service +/// +/// +public sealed class StrikePaymentConfig : PaymentConfig +{ + /// + /// Strike username to pay to + /// + public string Handle { get; init; } = null!; +} \ No newline at end of file diff --git a/VoidCat/Model/Paywall/Paywall.cs b/VoidCat/Model/Paywall/Paywall.cs deleted file mode 100644 index 8001660..0000000 --- a/VoidCat/Model/Paywall/Paywall.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace VoidCat.Model.Paywall; - -/// -/// Payment services supported by the system -/// -public enum PaymentServices -{ - /// - /// No service - /// - None, - - /// - /// Strike.me payment service - /// - Strike -} - -/// -/// Base paywall config -/// -public abstract class PaywallConfig -{ - /// - /// File this config is for - /// - public Guid File { get; init; } - - /// - /// Service used to pay the paywall - /// - public PaymentServices Service { get; init; } = PaymentServices.None; - - /// - /// The cost for the paywall to pass - /// - public PaywallMoney Cost { get; init; } = new(0m, PaywallCurrencies.BTC); -} - -/// -public sealed class NoPaywallConfig : PaywallConfig -{ - -} - -/// -/// Paywall config for service -/// -/// -public sealed class StrikePaywallConfig : PaywallConfig -{ - /// - /// Strike username to pay to - /// - public string Handle { get; init; } = null!; -} \ No newline at end of file diff --git a/VoidCat/Model/Paywall/PaywallMoney.cs b/VoidCat/Model/Paywall/PaywallMoney.cs deleted file mode 100644 index 6a0d9b2..0000000 --- a/VoidCat/Model/Paywall/PaywallMoney.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Text.Json.Serialization; - -namespace VoidCat.Model.Paywall; - -public record PaywallMoney(decimal Amount, PaywallCurrencies Currency); - -[JsonConverter(typeof(JsonStringEnumConverter))] -public enum PaywallCurrencies : byte -{ - BTC = 0, - USD = 1, - EUR = 2, - GBP = 3 -} diff --git a/VoidCat/Model/VoidFile.cs b/VoidCat/Model/VoidFile.cs index c7f0b09..eeb7052 100644 --- a/VoidCat/Model/VoidFile.cs +++ b/VoidCat/Model/VoidFile.cs @@ -1,5 +1,5 @@ using Newtonsoft.Json; -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; namespace VoidCat.Model { @@ -17,9 +17,9 @@ namespace VoidCat.Model public TMeta? Metadata { get; init; } /// - /// Optional paywall config + /// Optional payment config /// - public PaywallConfig? Paywall { get; init; } + public PaymentConfig? Payment { get; init; } /// /// User profile that uploaded the file diff --git a/VoidCat/Services/Abstractions/IPaymentFactory.cs b/VoidCat/Services/Abstractions/IPaymentFactory.cs new file mode 100644 index 0000000..49235ba --- /dev/null +++ b/VoidCat/Services/Abstractions/IPaymentFactory.cs @@ -0,0 +1,16 @@ +using VoidCat.Model.Payments; + +namespace VoidCat.Services.Abstractions; + +/// +/// Factory class to access service provider implementations +/// +public interface IPaymentFactory +{ + /// + /// Create provider handler for specified service type + /// + /// + /// + ValueTask CreateProvider(PaymentServices svc); +} \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaywallOrderStore.cs b/VoidCat/Services/Abstractions/IPaymentOrderStore.cs similarity index 58% rename from VoidCat/Services/Abstractions/IPaywallOrderStore.cs rename to VoidCat/Services/Abstractions/IPaymentOrderStore.cs index 406b13c..e998d24 100644 --- a/VoidCat/Services/Abstractions/IPaywallOrderStore.cs +++ b/VoidCat/Services/Abstractions/IPaymentOrderStore.cs @@ -1,11 +1,11 @@ -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; namespace VoidCat.Services.Abstractions; /// -/// Paywall order store +/// Payment order store /// -public interface IPaywallOrderStore : IBasicStore +public interface IPaymentOrderStore : IBasicStore { /// /// Update the status of an order @@ -13,5 +13,5 @@ public interface IPaywallOrderStore : IBasicStore /// /// /// - ValueTask UpdateStatus(Guid order, PaywallOrderStatus status); + ValueTask UpdateStatus(Guid order, PaymentOrderStatus status); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaywallProvider.cs b/VoidCat/Services/Abstractions/IPaymentProvider.cs similarity index 70% rename from VoidCat/Services/Abstractions/IPaywallProvider.cs rename to VoidCat/Services/Abstractions/IPaymentProvider.cs index ad6fc0e..3ada1d5 100644 --- a/VoidCat/Services/Abstractions/IPaywallProvider.cs +++ b/VoidCat/Services/Abstractions/IPaymentProvider.cs @@ -1,23 +1,23 @@ -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; namespace VoidCat.Services.Abstractions; /// /// Provider to generate orders for a specific config /// -public interface IPaywallProvider +public interface IPaymentProvider { /// /// Create an order with the provider /// /// /// - ValueTask CreateOrder(PaywallConfig file); + ValueTask CreateOrder(PaymentConfig file); /// /// Get the status of an existing order with the provider /// /// /// - ValueTask GetOrderStatus(Guid id); + ValueTask GetOrderStatus(Guid id); } \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaymentStore.cs b/VoidCat/Services/Abstractions/IPaymentStore.cs new file mode 100644 index 0000000..71e18ac --- /dev/null +++ b/VoidCat/Services/Abstractions/IPaymentStore.cs @@ -0,0 +1,10 @@ +using VoidCat.Model.Payments; + +namespace VoidCat.Services.Abstractions; + +/// +/// Store for payment configs +/// +public interface IPaymentStore : IBasicStore +{ +} \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaywallFactory.cs b/VoidCat/Services/Abstractions/IPaywallFactory.cs deleted file mode 100644 index 9511ab5..0000000 --- a/VoidCat/Services/Abstractions/IPaywallFactory.cs +++ /dev/null @@ -1,8 +0,0 @@ -using VoidCat.Model.Paywall; - -namespace VoidCat.Services.Abstractions; - -public interface IPaywallFactory -{ - ValueTask CreateProvider(PaymentServices svc); -} \ No newline at end of file diff --git a/VoidCat/Services/Abstractions/IPaywallStore.cs b/VoidCat/Services/Abstractions/IPaywallStore.cs deleted file mode 100644 index f0a1a16..0000000 --- a/VoidCat/Services/Abstractions/IPaywallStore.cs +++ /dev/null @@ -1,10 +0,0 @@ -using VoidCat.Model.Paywall; - -namespace VoidCat.Services.Abstractions; - -/// -/// Store for paywall configs -/// -public interface IPaywallStore : IBasicStore -{ -} \ No newline at end of file diff --git a/VoidCat/Services/Files/FileInfoManager.cs b/VoidCat/Services/Files/FileInfoManager.cs index d8b320d..1895ca6 100644 --- a/VoidCat/Services/Files/FileInfoManager.cs +++ b/VoidCat/Services/Files/FileInfoManager.cs @@ -10,17 +10,17 @@ namespace VoidCat.Services.Files; public sealed class FileInfoManager { private readonly IFileMetadataStore _metadataStore; - private readonly IPaywallStore _paywallStore; + private readonly IPaymentStore _paymentStore; private readonly IStatsReporter _statsReporter; private readonly IUserStore _userStore; private readonly IVirusScanStore _virusScanStore; private readonly IUserUploadsStore _userUploadsStore; - public FileInfoManager(IFileMetadataStore metadataStore, IPaywallStore paywallStore, IStatsReporter statsReporter, + public FileInfoManager(IFileMetadataStore metadataStore, IPaymentStore paymentStore, IStatsReporter statsReporter, IUserStore userStore, IVirusScanStore virusScanStore, IUserUploadsStore userUploadsStore) { _metadataStore = metadataStore; - _paywallStore = paywallStore; + _paymentStore = paymentStore; _statsReporter = statsReporter; _userStore = userStore; _virusScanStore = virusScanStore; @@ -75,7 +75,7 @@ public sealed class FileInfoManager public async ValueTask Delete(Guid id) { await _metadataStore.Delete(id); - await _paywallStore.Delete(id); + await _paymentStore.Delete(id); await _statsReporter.Delete(id); await _virusScanStore.Delete(id); } @@ -84,11 +84,11 @@ public sealed class FileInfoManager where TMeta : VoidFileMeta where TFile : VoidFile, new() { var meta = _metadataStore.Get(id); - var paywall = _paywallStore.Get(id); + var payment = _paymentStore.Get(id); var bandwidth = _statsReporter.GetBandwidth(id); var virusScan = _virusScanStore.GetByFile(id); var uploader = _userUploadsStore.Uploader(id); - await Task.WhenAll(meta.AsTask(), paywall.AsTask(), bandwidth.AsTask(), virusScan.AsTask(), uploader.AsTask()); + await Task.WhenAll(meta.AsTask(), payment.AsTask(), bandwidth.AsTask(), virusScan.AsTask(), uploader.AsTask()); if (meta.Result == default) return default; var user = uploader.Result.HasValue ? await _userStore.Get(uploader.Result.Value) : null; @@ -97,7 +97,7 @@ public sealed class FileInfoManager { Id = id, Metadata = meta.Result, - Paywall = paywall.Result, + Payment = payment.Result, Bandwidth = bandwidth.Result, Uploader = user?.Flags.HasFlag(VoidUserFlags.PublicProfile) == true ? user : null, VirusScan = virusScan.Result diff --git a/VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs b/VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs new file mode 100644 index 0000000..1ecbd30 --- /dev/null +++ b/VoidCat/Services/Migrations/Database/03-PaywallToPayments.cs @@ -0,0 +1,27 @@ +using FluentMigrator; + +namespace VoidCat.Services.Migrations.Database; + +[Migration(20220908_1527)] +public class PaywallToPayments : Migration +{ + public override void Up() + { + Rename.Table("Paywall") + .To("Payment"); + + Rename.Table("PaywallOrder") + .To("PaymentOrder"); + + Rename.Table("PaywallStrike") + .To("PaymentStrike"); + + Rename.Table("PaywallOrderLightning") + .To("PaymentOrderLightning"); + } + + public override void Down() + { + // yolo + } +} \ No newline at end of file diff --git a/VoidCat/Services/Migrations/MigrateToPostgres.cs b/VoidCat/Services/Migrations/MigrateToPostgres.cs index 9bd867a..b256c71 100644 --- a/VoidCat/Services/Migrations/MigrateToPostgres.cs +++ b/VoidCat/Services/Migrations/MigrateToPostgres.cs @@ -3,7 +3,7 @@ using Newtonsoft.Json; using VoidCat.Model; using VoidCat.Services.Abstractions; using VoidCat.Services.Files; -using VoidCat.Services.Paywall; +using VoidCat.Services.Payment; using VoidCat.Services.Users; namespace VoidCat.Services.Migrations; @@ -15,20 +15,20 @@ public class MigrateToPostgres : IMigration private readonly VoidSettings _settings; private readonly IFileMetadataStore _fileMetadata; private readonly ICache _cache; - private readonly IPaywallStore _paywallStore; + private readonly IPaymentStore _paymentStore; private readonly IUserStore _userStore; private readonly IUserUploadsStore _userUploads; private readonly FileStoreFactory _fileStore; public MigrateToPostgres(VoidSettings settings, ILogger logger, IFileMetadataStore fileMetadata, - ICache cache, IPaywallStore paywallStore, IUserStore userStore, IUserUploadsStore userUploads, + ICache cache, IPaymentStore paymentStore, IUserStore userStore, IUserUploadsStore userUploads, FileStoreFactory fileStore) { _logger = logger; _settings = settings; _fileMetadata = fileMetadata; _cache = cache; - _paywallStore = paywallStore; + _paymentStore = paymentStore; _userStore = userStore; _userUploads = userUploads; _fileStore = fileStore; @@ -99,7 +99,7 @@ public class MigrateToPostgres : IMigration private async Task MigratePaywall() { - var cachePaywallStore = new CachePaywallStore(_cache); + var cachePaywallStore = new CachePaymentStore(_cache); var files = await _fileMetadata.ListFiles(new(0, int.MaxValue)); await foreach (var file in files.Results) @@ -109,7 +109,7 @@ public class MigrateToPostgres : IMigration var old = await cachePaywallStore.Get(file.Id); if (old != default) { - await _paywallStore.Add(file.Id, old); + await _paymentStore.Add(file.Id, old); _logger.LogInformation("Migrated paywall config for {File}", file.Id); } } @@ -165,4 +165,4 @@ public class MigrateToPostgres : IMigration [JsonConverter(typeof(Base58GuidConverter))] public Guid? Uploader { get; set; } } -} +} \ No newline at end of file diff --git a/VoidCat/Services/Payment/CachePaymentOrderStore.cs b/VoidCat/Services/Payment/CachePaymentOrderStore.cs new file mode 100644 index 0000000..4221a6f --- /dev/null +++ b/VoidCat/Services/Payment/CachePaymentOrderStore.cs @@ -0,0 +1,26 @@ +using VoidCat.Model.Payments; +using VoidCat.Services.Abstractions; + +namespace VoidCat.Services.Payment; + +/// +public class CachePaymentOrderStore : BasicCacheStore, IPaymentOrderStore +{ + public CachePaymentOrderStore(ICache cache) : base(cache) + { + } + + /// + public async ValueTask UpdateStatus(Guid order, PaymentOrderStatus status) + { + var old = await Get(order); + if (old == default) return; + + old.Status = status; + + await Add(order, old); + } + + /// + protected override string MapKey(Guid id) => $"payment:order:{id}"; +} \ No newline at end of file diff --git a/VoidCat/Services/Payment/CachePaymentStore.cs b/VoidCat/Services/Payment/CachePaymentStore.cs new file mode 100644 index 0000000..60b626b --- /dev/null +++ b/VoidCat/Services/Payment/CachePaymentStore.cs @@ -0,0 +1,28 @@ +using VoidCat.Model.Payments; +using VoidCat.Services.Abstractions; + +namespace VoidCat.Services.Payment; + +/// +public class CachePaymentStore : BasicCacheStore, IPaymentStore +{ + public CachePaymentStore(ICache database) + : base(database) + { + } + + /// + public override async ValueTask Get(Guid id) + { + var cfg = await Cache.Get(MapKey(id)); + return cfg?.Service switch + { + PaymentServices.None => cfg, + PaymentServices.Strike => await Cache.Get(MapKey(id)), + _ => default + }; + } + + /// + protected override string MapKey(Guid id) => $"payment:config:{id}"; +} \ No newline at end of file diff --git a/VoidCat/Services/Payment/PaymentFactory.cs b/VoidCat/Services/Payment/PaymentFactory.cs new file mode 100644 index 0000000..be30a2b --- /dev/null +++ b/VoidCat/Services/Payment/PaymentFactory.cs @@ -0,0 +1,23 @@ +using VoidCat.Model.Payments; +using VoidCat.Services.Abstractions; + +namespace VoidCat.Services.Payment; + +public class PaymentFactory : IPaymentFactory +{ + private readonly IServiceProvider _services; + + public PaymentFactory(IServiceProvider services) + { + _services = services; + } + + public ValueTask CreateProvider(PaymentServices svc) + { + return ValueTask.FromResult(svc switch + { + PaymentServices.Strike => _services.GetRequiredService(), + _ => throw new ArgumentException("Must have a payment config", nameof(svc)) + }); + } +} \ No newline at end of file diff --git a/VoidCat/Services/Payment/PaymentStartup.cs b/VoidCat/Services/Payment/PaymentStartup.cs new file mode 100644 index 0000000..467889a --- /dev/null +++ b/VoidCat/Services/Payment/PaymentStartup.cs @@ -0,0 +1,32 @@ +using VoidCat.Model; +using VoidCat.Services.Abstractions; +using VoidCat.Services.Strike; + +namespace VoidCat.Services.Payment; + +public static class PaymentStartup +{ + /// + /// Add services required to use payment functions + /// + /// + /// + public static void AddPaymentServices(this IServiceCollection services, VoidSettings settings) + { + services.AddTransient(); + if (settings.HasPostgres()) + { + services.AddTransient(); + services.AddTransient(); + } + else + { + services.AddTransient(); + services.AddTransient(); + } + + // strike + services.AddTransient(); + services.AddTransient(); + } +} \ No newline at end of file diff --git a/VoidCat/Services/Paywall/PostgresPaywallOrderStore.cs b/VoidCat/Services/Payment/PostgresPaymentOrderStore.cs similarity index 67% rename from VoidCat/Services/Paywall/PostgresPaywallOrderStore.cs rename to VoidCat/Services/Payment/PostgresPaymentOrderStore.cs index 0ef0be8..cc710bb 100644 --- a/VoidCat/Services/Paywall/PostgresPaywallOrderStore.cs +++ b/VoidCat/Services/Payment/PostgresPaymentOrderStore.cs @@ -1,33 +1,33 @@ using Dapper; -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; -namespace VoidCat.Services.Paywall; +namespace VoidCat.Services.Payment; /// -public class PostgresPaywallOrderStore : IPaywallOrderStore +public class PostgresPaymentOrderStore : IPaymentOrderStore { private readonly PostgresConnectionFactory _connection; - public PostgresPaywallOrderStore(PostgresConnectionFactory connection) + public PostgresPaymentOrderStore(PostgresConnectionFactory connection) { _connection = connection; } /// - public async ValueTask Get(Guid id) + public async ValueTask Get(Guid id) { await using var conn = await _connection.Get(); - var order = await conn.QuerySingleOrDefaultAsync( - @"select * from ""PaywallOrder"" where ""Id"" = :id", new {id}); + var order = await conn.QuerySingleOrDefaultAsync( + @"select * from ""PaymentOrder"" where ""Id"" = :id", new {id}); if (order.Service is PaymentServices.Strike) { - var lnDetails = await conn.QuerySingleAsync( - @"select * from ""PaywallOrderLightning"" where ""Order"" = :id", new + var lnDetails = await conn.QuerySingleAsync( + @"select * from ""PaymentOrderLightning"" where ""Order"" = :id", new { id = order.Id }); - return new LightningPaywallOrder + return new LightningPaymentOrder { Id = order.Id, File = order.File, @@ -43,18 +43,18 @@ public class PostgresPaywallOrderStore : IPaywallOrderStore } /// - public ValueTask> Get(Guid[] ids) + public ValueTask> Get(Guid[] ids) { throw new NotImplementedException(); } /// - public async ValueTask Add(Guid id, PaywallOrder obj) + public async ValueTask Add(Guid id, PaymentOrder obj) { await using var conn = await _connection.Get(); await using var txn = await conn.BeginTransactionAsync(); await conn.ExecuteAsync( - @"insert into ""PaywallOrder""(""Id"", ""File"", ""Service"", ""Currency"", ""Amount"", ""Status"") + @"insert into ""PaymentOrder""(""Id"", ""File"", ""Service"", ""Currency"", ""Amount"", ""Status"") values(:id, :file, :service, :currency, :amt, :status)", new { @@ -66,10 +66,10 @@ values(:id, :file, :service, :currency, :amt, :status)", status = (int) obj.Status }); - if (obj is LightningPaywallOrder ln) + if (obj is LightningPaymentOrder ln) { await conn.ExecuteAsync( - @"insert into ""PaywallOrderLightning""(""Order"", ""Invoice"", ""Expire"") values(:order, :invoice, :expire)", + @"insert into ""PaymentOrderLightning""(""Order"", ""Invoice"", ""Expire"") values(:order, :invoice, :expire)", new { order = id, @@ -85,20 +85,20 @@ values(:id, :file, :service, :currency, :amt, :status)", public async ValueTask Delete(Guid id) { await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""PaywallOrder"" where ""Id"" = :id", new {id}); + await conn.ExecuteAsync(@"delete from ""PaymentOrder"" where ""Id"" = :id", new {id}); } /// - public async ValueTask UpdateStatus(Guid order, PaywallOrderStatus status) + public async ValueTask UpdateStatus(Guid order, PaymentOrderStatus status) { await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"update ""PaywallOrder"" set ""Status"" = :status where ""Id"" = :id", + await conn.ExecuteAsync(@"update ""PaymentOrder"" set ""Status"" = :status where ""Id"" = :id", new {id = order, status = (int) status}); } - private sealed class DtoPaywallOrder : PaywallOrder + private sealed class DtoPaymentOrder : PaymentOrder { - public PaywallCurrencies Currency { get; init; } + public PaymentCurrencies Currency { get; init; } public decimal Amount { get; init; } } } \ No newline at end of file diff --git a/VoidCat/Services/Paywall/PostgresPaywallStore.cs b/VoidCat/Services/Payment/PostgresPaymentStore.cs similarity index 67% rename from VoidCat/Services/Paywall/PostgresPaywallStore.cs rename to VoidCat/Services/Payment/PostgresPaymentStore.cs index 23df6e5..75a4793 100644 --- a/VoidCat/Services/Paywall/PostgresPaywallStore.cs +++ b/VoidCat/Services/Payment/PostgresPaymentStore.cs @@ -1,25 +1,25 @@ using Dapper; -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; -namespace VoidCat.Services.Paywall; +namespace VoidCat.Services.Payment; /// -public sealed class PostgresPaywallStore : IPaywallStore +public sealed class PostgresPaymentStore : IPaymentStore { private readonly PostgresConnectionFactory _connection; - public PostgresPaywallStore(PostgresConnectionFactory connection) + public PostgresPaymentStore(PostgresConnectionFactory connection) { _connection = connection; } /// - public async ValueTask Get(Guid id) + public async ValueTask Get(Guid id) { await using var conn = await _connection.Get(); - var svc = await conn.QuerySingleOrDefaultAsync( - @"select * from ""Paywall"" where ""File"" = :file", new {file = id}); + var svc = await conn.QuerySingleOrDefaultAsync( + @"select * from ""Payment"" where ""File"" = :file", new {file = id}); if (svc != default) { switch (svc.Service) @@ -28,8 +28,8 @@ public sealed class PostgresPaywallStore : IPaywallStore { var handle = await conn.ExecuteScalarAsync( - @"select ""Handle"" from ""PaywallStrike"" where ""File"" = :file", new {file = id}); - return new StrikePaywallConfig + @"select ""Handle"" from ""PaymentStrike"" where ""File"" = :file", new {file = id}); + return new StrikePaymentConfig { Cost = new(svc.Amount, svc.Currency), File = svc.File, @@ -44,18 +44,18 @@ public sealed class PostgresPaywallStore : IPaywallStore } /// - public ValueTask> Get(Guid[] ids) + public ValueTask> Get(Guid[] ids) { throw new NotImplementedException(); } /// - public async ValueTask Add(Guid id, PaywallConfig obj) + public async ValueTask Add(Guid id, PaymentConfig obj) { await using var conn = await _connection.Get(); await using var txn = await conn.BeginTransactionAsync(); await conn.ExecuteAsync( - @"insert into ""Paywall""(""File"", ""Service"", ""Amount"", ""Currency"") values(:file, :service, :amount, :currency) + @"insert into ""Payment""(""File"", ""Service"", ""Amount"", ""Currency"") values(:file, :service, :amount, :currency) on conflict(""File"") do update set ""Service"" = :service, ""Amount"" = :amount, ""Currency"" = :currency", new { @@ -65,9 +65,9 @@ on conflict(""File"") do update set ""Service"" = :service, ""Amount"" = :amount currency = obj.Cost.Currency }); - if (obj is StrikePaywallConfig sc) + if (obj is StrikePaymentConfig sc) { - await conn.ExecuteAsync(@"insert into ""PaywallStrike""(""File"", ""Handle"") values(:file, :handle) + await conn.ExecuteAsync(@"insert into ""PaymentStrike""(""File"", ""Handle"") values(:file, :handle) on conflict(""File"") do update set ""Handle"" = :handle", new { file = id, @@ -82,12 +82,12 @@ on conflict(""File"") do update set ""Handle"" = :handle", new public async ValueTask Delete(Guid id) { await using var conn = await _connection.Get(); - await conn.ExecuteAsync(@"delete from ""Paywall"" where ""File"" = :file", new {file = id}); + await conn.ExecuteAsync(@"delete from ""Payment"" where ""File"" = :file", new {file = id}); } - private sealed class DtoPaywallConfig : PaywallConfig + private sealed class DtoPaymentConfig : PaymentConfig { - public PaywallCurrencies Currency { get; init; } + public PaymentCurrencies Currency { get; init; } public decimal Amount { get; init; } } } \ No newline at end of file diff --git a/VoidCat/Services/Paywall/StrikePaywallProvider.cs b/VoidCat/Services/Payment/StrikePaymentProvider.cs similarity index 66% rename from VoidCat/Services/Paywall/StrikePaywallProvider.cs rename to VoidCat/Services/Payment/StrikePaymentProvider.cs index 2f5242f..3cf84eb 100644 --- a/VoidCat/Services/Paywall/StrikePaywallProvider.cs +++ b/VoidCat/Services/Payment/StrikePaymentProvider.cs @@ -1,19 +1,19 @@ using System.Globalization; using VoidCat.Model; -using VoidCat.Model.Paywall; +using VoidCat.Model.Payments; using VoidCat.Services.Abstractions; using VoidCat.Services.Strike; -namespace VoidCat.Services.Paywall; +namespace VoidCat.Services.Payment; /// -public class StrikePaywallProvider : IPaywallProvider +public class StrikePaymentProvider : IPaymentProvider { - private readonly ILogger _logger; + private readonly ILogger _logger; private readonly StrikeApi _strike; - private readonly IPaywallOrderStore _orderStore; + private readonly IPaymentOrderStore _orderStore; - public StrikePaywallProvider(ILogger logger, StrikeApi strike, IPaywallOrderStore orderStore) + public StrikePaymentProvider(ILogger logger, StrikeApi strike, IPaymentOrderStore orderStore) { _logger = logger; _strike = strike; @@ -21,9 +21,9 @@ public class StrikePaywallProvider : IPaywallProvider } /// - public async ValueTask CreateOrder(PaywallConfig config) + public async ValueTask CreateOrder(PaymentConfig config) { - IsStrikePaywall(config, out var strikeConfig); + IsStrikePayment(config, out var strikeConfig); _logger.LogInformation("Generating invoice for {Currency} {Amount}", config.Cost.Currency, config.Cost.Amount); var currency = MapCurrency(strikeConfig.Cost.Currency); @@ -57,13 +57,13 @@ public class StrikePaywallProvider : IPaywallProvider var quote = await _strike.GetInvoiceQuote(invoice.InvoiceId); if (quote != default) { - var order = new LightningPaywallOrder + var order = new LightningPaymentOrder { Id = invoice.InvoiceId, File = config.File, Service = PaymentServices.Strike, Price = config.Cost, - Status = PaywallOrderStatus.Unpaid, + Status = PaymentOrderStatus.Unpaid, Invoice = quote.LnInvoice!, Expire = DateTime.SpecifyKind(quote.Expiration.DateTime, DateTimeKind.Utc) }; @@ -80,10 +80,10 @@ public class StrikePaywallProvider : IPaywallProvider } /// - public async ValueTask GetOrderStatus(Guid id) + public async ValueTask GetOrderStatus(Guid id) { var order = await _orderStore.Get(id); - if (order is {Status: PaywallOrderStatus.Paid or PaywallOrderStatus.Expired}) return order; + if (order is {Status: PaymentOrderStatus.Paid or PaymentOrderStatus.Expired}) return order; var providerOrder = await _strike.GetInvoice(id); if (providerOrder != default) @@ -104,44 +104,44 @@ public class StrikePaywallProvider : IPaywallProvider return default; } - private PaywallOrderStatus MapStatus(InvoiceState providerOrderState) + private PaymentOrderStatus MapStatus(InvoiceState providerOrderState) => providerOrderState switch { - InvoiceState.UNPAID => PaywallOrderStatus.Unpaid, - InvoiceState.PENDING => PaywallOrderStatus.Unpaid, - InvoiceState.PAID => PaywallOrderStatus.Paid, - InvoiceState.CANCELLED => PaywallOrderStatus.Expired, + InvoiceState.UNPAID => PaymentOrderStatus.Unpaid, + InvoiceState.PENDING => PaymentOrderStatus.Unpaid, + InvoiceState.PAID => PaymentOrderStatus.Paid, + InvoiceState.CANCELLED => PaymentOrderStatus.Expired, _ => throw new ArgumentOutOfRangeException(nameof(providerOrderState), providerOrderState, null) }; - private static Currencies MapCurrency(PaywallCurrencies c) + private static Currencies MapCurrency(PaymentCurrencies c) => c switch { - PaywallCurrencies.BTC => Currencies.BTC, - PaywallCurrencies.USD => Currencies.USD, - PaywallCurrencies.EUR => Currencies.EUR, - PaywallCurrencies.GBP => Currencies.GBP, + PaymentCurrencies.BTC => Currencies.BTC, + PaymentCurrencies.USD => Currencies.USD, + PaymentCurrencies.EUR => Currencies.EUR, + PaymentCurrencies.GBP => Currencies.GBP, _ => throw new ArgumentOutOfRangeException(nameof(c), c, null) }; - private static PaywallCurrencies MapCurrency(Currencies c) + private static PaymentCurrencies MapCurrency(Currencies c) => c switch { - Currencies.BTC => PaywallCurrencies.BTC, - Currencies.USD => PaywallCurrencies.USD, - Currencies.USDT => PaywallCurrencies.USD, - Currencies.EUR => PaywallCurrencies.EUR, - Currencies.GBP => PaywallCurrencies.GBP, + Currencies.BTC => PaymentCurrencies.BTC, + Currencies.USD => PaymentCurrencies.USD, + Currencies.USDT => PaymentCurrencies.USD, + Currencies.EUR => PaymentCurrencies.EUR, + Currencies.GBP => PaymentCurrencies.GBP, _ => throw new ArgumentOutOfRangeException(nameof(c), c, null) }; - private static void IsStrikePaywall(PaywallConfig? cfg, out StrikePaywallConfig strikeConfig) + private static void IsStrikePayment(PaymentConfig? cfg, out StrikePaymentConfig strikeConfig) { if (cfg?.Service != PaymentServices.Strike) { - throw new ArgumentException("Must be strike paywall"); + throw new ArgumentException("Must be strike Payment"); } - strikeConfig = (cfg as StrikePaywallConfig)!; + strikeConfig = (cfg as StrikePaymentConfig)!; } } \ No newline at end of file diff --git a/VoidCat/Services/Paywall/CachePaywallOrderStore.cs b/VoidCat/Services/Paywall/CachePaywallOrderStore.cs deleted file mode 100644 index cf5fd78..0000000 --- a/VoidCat/Services/Paywall/CachePaywallOrderStore.cs +++ /dev/null @@ -1,26 +0,0 @@ -using VoidCat.Model.Paywall; -using VoidCat.Services.Abstractions; - -namespace VoidCat.Services.Paywall; - -/// -public class CachePaywallOrderStore : BasicCacheStore, IPaywallOrderStore -{ - public CachePaywallOrderStore(ICache cache) : base(cache) - { - } - - /// - public async ValueTask UpdateStatus(Guid order, PaywallOrderStatus status) - { - var old = await Get(order); - if (old == default) return; - - old.Status = status; - - await Add(order, old); - } - - /// - protected override string MapKey(Guid id) => $"paywall:order:{id}"; -} \ No newline at end of file diff --git a/VoidCat/Services/Paywall/CachePaywallStore.cs b/VoidCat/Services/Paywall/CachePaywallStore.cs deleted file mode 100644 index 0732ecc..0000000 --- a/VoidCat/Services/Paywall/CachePaywallStore.cs +++ /dev/null @@ -1,28 +0,0 @@ -using VoidCat.Model.Paywall; -using VoidCat.Services.Abstractions; - -namespace VoidCat.Services.Paywall; - -/// -public class CachePaywallStore : BasicCacheStore, IPaywallStore -{ - public CachePaywallStore(ICache database) - : base(database) - { - } - - /// - public override async ValueTask Get(Guid id) - { - var cfg = await Cache.Get(MapKey(id)); - return cfg?.Service switch - { - PaymentServices.None => cfg, - PaymentServices.Strike => await Cache.Get(MapKey(id)), - _ => default - }; - } - - /// - protected override string MapKey(Guid id) => $"paywall:config:{id}"; -} \ No newline at end of file diff --git a/VoidCat/Services/Paywall/PaywallFactory.cs b/VoidCat/Services/Paywall/PaywallFactory.cs deleted file mode 100644 index 568fd74..0000000 --- a/VoidCat/Services/Paywall/PaywallFactory.cs +++ /dev/null @@ -1,23 +0,0 @@ -using VoidCat.Model.Paywall; -using VoidCat.Services.Abstractions; - -namespace VoidCat.Services.Paywall; - -public class PaywallFactory : IPaywallFactory -{ - private readonly IServiceProvider _services; - - public PaywallFactory(IServiceProvider services) - { - _services = services; - } - - public ValueTask CreateProvider(PaymentServices svc) - { - return ValueTask.FromResult(svc switch - { - PaymentServices.Strike => _services.GetRequiredService(), - _ => throw new ArgumentException("Must have a paywall config", nameof(svc)) - }); - } -} \ No newline at end of file diff --git a/VoidCat/Services/Paywall/PaywallStartup.cs b/VoidCat/Services/Paywall/PaywallStartup.cs deleted file mode 100644 index 39985ea..0000000 --- a/VoidCat/Services/Paywall/PaywallStartup.cs +++ /dev/null @@ -1,32 +0,0 @@ -using VoidCat.Model; -using VoidCat.Services.Abstractions; -using VoidCat.Services.Strike; - -namespace VoidCat.Services.Paywall; - -public static class PaywallStartup -{ - /// - /// Add services required to use paywall functions - /// - /// - /// - public static void AddPaywallServices(this IServiceCollection services, VoidSettings settings) - { - services.AddTransient(); - if (settings.HasPostgres()) - { - services.AddTransient(); - services.AddTransient(); - } - else - { - services.AddTransient(); - services.AddTransient(); - } - - // strike - services.AddTransient(); - services.AddTransient(); - } -} \ No newline at end of file diff --git a/VoidCat/VoidStartup.cs b/VoidCat/VoidStartup.cs index 2ff5aec..d4a5816 100644 --- a/VoidCat/VoidStartup.cs +++ b/VoidCat/VoidStartup.cs @@ -18,7 +18,7 @@ using VoidCat.Services.Captcha; using VoidCat.Services.Files; using VoidCat.Services.InMemory; using VoidCat.Services.Migrations; -using VoidCat.Services.Paywall; +using VoidCat.Services.Payment; using VoidCat.Services.Redis; using VoidCat.Services.Stats; using VoidCat.Services.Users; @@ -66,7 +66,7 @@ public static class VoidStartup { services.AddStorage(voidSettings); services.AddMetrics(voidSettings); - services.AddPaywallServices(voidSettings); + services.AddPaymentServices(voidSettings); services.AddUserServices(voidSettings); services.AddVirusScanner(voidSettings); services.AddCaptcha(voidSettings); diff --git a/VoidCat/spa/src/Api.js b/VoidCat/spa/src/Api.js index 1b89953..0fe38b9 100644 --- a/VoidCat/spa/src/Api.js +++ b/VoidCat/spa/src/Api.js @@ -33,9 +33,9 @@ export function useApi() { Api: { info: () => getJson("GET", "/info"), fileInfo: (id) => getJson("GET", `/upload/${id}`, undefined, auth), - setPaywallConfig: (id, cfg) => getJson("POST", `/upload/${id}/paywall`, cfg, auth), - createOrder: (id) => getJson("GET", `/upload/${id}/paywall`), - getOrder: (file, order) => getJson("GET", `/upload/${file}/paywall/${order}`), + setPaymentConfig: (id, cfg) => getJson("POST", `/upload/${id}/payment`, cfg, auth), + createOrder: (id) => getJson("GET", `/upload/${id}/payment`), + getOrder: (file, order) => getJson("GET", `/upload/${file}/payment/${order}`), login: (username, password, captcha) => getJson("POST", `/auth/login`, {username, password, captcha}), register: (username, password, captcha) => getJson("POST", `/auth/register`, {username, password, captcha}), getUser: (id) => getJson("GET", `/user/${id}`, undefined, auth), diff --git a/VoidCat/spa/src/Const.js b/VoidCat/spa/src/Const.js index 0c1bdf1..c9770ca 100644 --- a/VoidCat/spa/src/Const.js +++ b/VoidCat/spa/src/Const.js @@ -37,19 +37,19 @@ export const ZiB = Math.pow(1024, 7); */ export const YiB = Math.pow(1024, 8); -export const PaywallCurrencies = { +export const PaymentCurrencies = { BTC: 0, USD: 1, EUR: 2, GBP: 3 } -export const PaywallServices = { +export const PaymentServices = { None: 0, Strike: 1 } -export const PaywallOrderState = { +export const PaymentOrderState = { Unpaid: 0, Paid: 1, Expired: 2 diff --git a/VoidCat/spa/src/FileEdit.js b/VoidCat/spa/src/FileEdit.js index 5ddc622..d3657cd 100644 --- a/VoidCat/spa/src/FileEdit.js +++ b/VoidCat/spa/src/FileEdit.js @@ -1,7 +1,7 @@ import {useState} from "react"; -import {StrikePaywallConfig} from "./StrikePaywallConfig"; -import {NoPaywallConfig} from "./NoPaywallConfig"; +import {StrikePaymentConfig} from "./StrikePaymentConfig"; +import {NoPaymentConfig} from "./NoPaymentConfig"; import {useApi} from "./Api"; import "./FileEdit.css"; import {useSelector} from "react-redux"; @@ -13,7 +13,7 @@ export function FileEdit(props) { const file = props.file; const meta = file.metadata; const profile = useSelector(state => state.login.profile); - const [paywall, setPaywall] = useState(file.paywall?.service); + const [payment, setPayment] = useState(file.payment?.service); const [name, setName] = useState(meta?.name); const [description, setDescription] = useState(meta?.description); const [expiry, setExpiry] = useState(meta?.expires === undefined || meta?.expires === null ? null : moment(meta?.expires).unix() * 1000); @@ -26,7 +26,7 @@ export function FileEdit(props) { } async function saveConfig(cfg) { - let req = await Api.setPaywallConfig(file.id, cfg); + let req = await Api.setPaymentConfig(file.id, cfg); return req.ok; } @@ -40,13 +40,13 @@ export function FileEdit(props) { await Api.updateMetadata(file.id, meta); } - function renderPaywallConfig() { - switch (paywall) { + function renderPaymentConfig() { + switch (payment) { case 0: { - return ; + return ; } case 1: { - return + return } } return null; @@ -81,13 +81,13 @@ export function FileEdit(props) { saveMeta()} options={{showSuccess: true}}>Save
-

Paywall Config

+

Payment Config

Type: - setPayment(parseInt(e.target.value))} value={payment}> - {renderPaywallConfig()} + {renderPaymentConfig()}
); diff --git a/VoidCat/spa/src/FilePaywall.css b/VoidCat/spa/src/FilePayment.css similarity index 91% rename from VoidCat/spa/src/FilePaywall.css rename to VoidCat/spa/src/FilePayment.css index 2546b07..ea8db93 100644 --- a/VoidCat/spa/src/FilePaywall.css +++ b/VoidCat/spa/src/FilePayment.css @@ -1,4 +1,4 @@ -.paywall { +.payment { text-align: center; border: 1px solid lightgreen; padding: 10px; diff --git a/VoidCat/spa/src/FilePaywall.js b/VoidCat/spa/src/FilePayment.js similarity index 70% rename from VoidCat/spa/src/FilePaywall.js rename to VoidCat/spa/src/FilePayment.js index 0ce827a..981d249 100644 --- a/VoidCat/spa/src/FilePaywall.js +++ b/VoidCat/spa/src/FilePayment.js @@ -1,16 +1,16 @@ -import "./FilePaywall.css"; +import "./FilePayment.css"; import {FormatCurrency} from "./Util"; -import {PaywallServices} from "./Const"; +import {PaymentServices} from "./Const"; import {useState} from "react"; -import {LightningPaywall} from "./LightningPaywall"; +import {LightningPayment} from "./LightningPayment"; import {useApi} from "./Api"; import {VoidButton} from "./VoidButton"; -export function FilePaywall(props) { +export function FilePayment(props) { const {Api} = useApi(); const file = props.file; - const pw = file.paywall; - const paywallKey = `paywall-${file.id}`; + const pw = file.payment; + const paymentKey = `payment-${file.id}`; const onPaid = props.onPaid; const [order, setOrder] = useState(); @@ -27,7 +27,7 @@ export function FilePaywall(props) { } function handlePaid(order) { - window.localStorage.setItem(paywallKey, JSON.stringify(order)); + window.localStorage.setItem(paymentKey, JSON.stringify(order)); if (typeof onPaid === "function") { onPaid(); } @@ -35,7 +35,7 @@ export function FilePaywall(props) { if (!order) { return ( -
+

You must pay {FormatCurrency(pw.cost.amount, pw.cost.currency)} to view this file.

@@ -44,8 +44,8 @@ export function FilePaywall(props) { ); } else { switch (pw.service) { - case PaywallServices.Strike: { - return ; + case PaymentServices.Strike: { + return ; } } return null; diff --git a/VoidCat/spa/src/FilePreview.js b/VoidCat/spa/src/FilePreview.js index 87c1277..4405661 100644 --- a/VoidCat/spa/src/FilePreview.js +++ b/VoidCat/spa/src/FilePreview.js @@ -4,7 +4,7 @@ import {TextPreview} from "./TextPreview"; import FeatherIcon from "feather-icons-react"; import "./FilePreview.css"; import {FileEdit} from "./FileEdit"; -import {FilePaywall} from "./FilePaywall"; +import {FilePayment} from "./FilePayment"; import {useApi} from "./Api"; import {Helmet} from "react-helmet"; import {FormatBytes} from "./Util"; @@ -27,9 +27,9 @@ export function FilePreview() { } function renderTypes() { - if (info.paywall && info.paywall.service !== 0) { + if (info.payment && info.payment.service !== 0) { if (!order) { - return ; + return ; } } @@ -132,7 +132,7 @@ export function FilePreview() { useEffect(() => { if (info) { let fileLink = info.metadata?.url ?? `${ApiHost}/d/${info.id}`; - let order = window.localStorage.getItem(`paywall-${info.id}`); + let order = window.localStorage.getItem(`payment-${info.id}`); if (order) { let orderObj = JSON.parse(order); setOrder(orderObj); diff --git a/VoidCat/spa/src/LightningPaywall.js b/VoidCat/spa/src/LightningPayment.js similarity index 89% rename from VoidCat/spa/src/LightningPaywall.js rename to VoidCat/spa/src/LightningPayment.js index 58f85b0..5dfd7bf 100644 --- a/VoidCat/spa/src/LightningPaywall.js +++ b/VoidCat/spa/src/LightningPayment.js @@ -2,10 +2,10 @@ import {useEffect} from "react"; import {Countdown} from "./Countdown"; -import {PaywallOrderState} from "./Const"; +import {PaymentOrderState} from "./Const"; import {useApi} from "./Api"; -export function LightningPaywall(props) { +export function LightningPayment(props) { const {Api} = useApi(); const file = props.file; const order = props.order; @@ -23,7 +23,7 @@ export function LightningPaywall(props) { if (req.ok) { let order = await req.json(); - if (order.status === PaywallOrderState.Paid && typeof onPaid === "function") { + if (order.status === PaymentOrderState.Paid && typeof onPaid === "function") { onPaid(order); } } diff --git a/VoidCat/spa/src/NoPaywallConfig.js b/VoidCat/spa/src/NoPaymentConfig.js similarity index 94% rename from VoidCat/spa/src/NoPaywallConfig.js rename to VoidCat/spa/src/NoPaymentConfig.js index 6a5c152..3d94c20 100644 --- a/VoidCat/spa/src/NoPaywallConfig.js +++ b/VoidCat/spa/src/NoPaymentConfig.js @@ -2,7 +2,7 @@ import {useState} from "react"; import {VoidButton} from "./VoidButton"; -export function NoPaywallConfig(props) { +export function NoPaymentConfig(props) { const [saveStatus, setSaveStatus] = useState(); const privateFile = props.privateFile; const onSaveConfig = props.onSaveConfig; diff --git a/VoidCat/spa/src/StrikePaywallConfig.js b/VoidCat/spa/src/StrikePaymentConfig.js similarity index 71% rename from VoidCat/spa/src/StrikePaywallConfig.js rename to VoidCat/spa/src/StrikePaymentConfig.js index d61b4bb..f2f016c 100644 --- a/VoidCat/spa/src/StrikePaywallConfig.js +++ b/VoidCat/spa/src/StrikePaymentConfig.js @@ -1,18 +1,18 @@ import {useState} from "react"; import FeatherIcon from "feather-icons-react"; -import {PaywallCurrencies} from "./Const"; +import {PaymentCurrencies} from "./Const"; import {VoidButton} from "./VoidButton"; -export function StrikePaywallConfig(props) { +export function StrikePaymentConfig(props) { const file = props.file; const privateFile = props.privateFile; const onSaveConfig = props.onSaveConfig; - const paywall = file.paywall; + const payment = file.payment; const editSecret = privateFile.metadata.editSecret; - const [username, setUsername] = useState(paywall?.handle ?? "hrf"); - const [currency, setCurrency] = useState(paywall?.cost.currency ?? PaywallCurrencies.USD); - const [price, setPrice] = useState(paywall?.cost.amount ?? 1); + const [username, setUsername] = useState(payment?.handle ?? "hrf"); + const [currency, setCurrency] = useState(payment?.cost.currency ?? PaymentCurrencies.USD); + const [price, setPrice] = useState(payment?.cost.amount ?? 1); const [saveStatus, setSaveStatus] = useState(); async function saveStrikeConfig(e) { @@ -31,7 +31,7 @@ export function StrikePaywallConfig(props) { if (await onSaveConfig(cfg)) { setSaveStatus(true); } else { - alert("Error settings paywall config!"); + alert("Error settings payment config!"); setSaveStatus(false); } } @@ -45,10 +45,10 @@ export function StrikePaywallConfig(props) {
Currency:
Price:
diff --git a/docker-compose.yml b/docker-compose.yml index d1a6ea9..b6cf748 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,7 +12,7 @@ services: redis: image: "redis:alpine" ports: - - "6379:6379" + - "6079:6379" postgres: image: "postgres:14.1" ports: @@ -21,4 +21,6 @@ services: - "POSTGRES_DB=void" - "POSTGRES_HOST_AUTH_METHOD=trust" clamav: - image: "clamav/clamav" \ No newline at end of file + image: "clamav/clamav" + ports: + - "3320:3310" \ No newline at end of file