diff --git a/.editorconfig b/.editorconfig index 7fdbafc..a8fca2d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -18,7 +18,7 @@ trim_trailing_whitespace = true # C# files [*.cs] -file_header_template = Copyright © Benjamin Abt 2020-2021, all rights reserved +file_header_template = Copyright © Benjamin Abt 2020-2024, all rights reserved #### .NET Coding Conventions #### diff --git a/.github/workflows/ci.yml b/.github/workflows/build.yml similarity index 64% rename from .github/workflows/ci.yml rename to .github/workflows/build.yml index c2fd5ba..115bb0f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/build.yml @@ -1,18 +1,17 @@ -name: NETCore +name: NET on: push: branches: - main pull_request: - types: [labeled] branches: - main + env: BuildConfig: Release DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true - DOTNET_VERSION: '6.0.101' # https://dotnetcli.blob.core.windows.net/dotnet/release-metadata/6.0/releases.json jobs: build: @@ -20,42 +19,45 @@ jobs: steps: - name: Cancel previous builds in PR - uses: styfle/cancel-workflow-action@0.9.1 + uses: styfle/cancel-workflow-action@0.12.1 with: access_token: ${{ github.token }} - - name: Checkout - uses: actions/checkout@v2 + - name: Checkout code + uses: actions/checkout@v4 with: fetch-depth: 0 # avoid shallow clone so nbgv can do its work. - - name: 'Install .NET SDK' - uses: actions/setup-dotnet@v1 + - name: Setup .NET SDK + uses: actions/setup-dotnet@v4 with: - dotnet-version: ${{ env.DOTNET_VERSION }} + global-json-file: ./global.json + + - name: Restore dependencies + run: dotnet restore - - name: Versioning + - name: Setup Git Versioning uses: dotnet/nbgv@master id: nbgv - - name: Version Info + - name: Show Version Info run: | echo 'SemVer2: ${{ steps.nbgv.outputs.SemVer2 }}' + - name: Build with dotnet run: dotnet build - --configuration ${{ env.BuildConfig }} + --no-restore --configuration ${{ env.BuildConfig }} /p:Version=${{ steps.nbgv.outputs.AssemblyVersion }} - - name: Test with dotnet - run: dotnet test - - name: Pack NuGet run: dotnet pack --configuration ${{ env.BuildConfig }} + /p:ContinuousIntegrationBuild=true /p:Version=${{ steps.nbgv.outputs.NuGetPackageVersion }} - name: Push to NuGet run: dotnet nuget push **/*.nupkg --api-key ${{ secrets.NUGET_DEPLOY_KEY }} --source https://api.nuget.org/v3/index.json - --no-symbols 1 + --no-symbols + --skip-duplicate diff --git a/hcaptchanet.sln b/BenjaminAbt.HCaptchaNET.sln similarity index 96% rename from hcaptchanet.sln rename to BenjaminAbt.HCaptchaNET.sln index fe11afe..351ee25 100644 --- a/hcaptchanet.sln +++ b/BenjaminAbt.HCaptchaNET.sln @@ -16,8 +16,9 @@ EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_", "_", "{246E4F1E-C4B3-4180-906C-605E72C69097}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig - .github\workflows\ci.yml = .github\workflows\ci.yml + .github\workflows\build.yml = .github\workflows\build.yml Directory.Build.props = Directory.Build.props + Directory.Packages.props = Directory.Packages.props global.json = global.json README.md = README.md version.json = version.json diff --git a/BenjaminAbt.HCaptchaNET.snk b/BenjaminAbt.HCaptchaNET.snk new file mode 100644 index 0000000..f118320 Binary files /dev/null and b/BenjaminAbt.HCaptchaNET.snk differ diff --git a/Directory.Build.props b/Directory.Build.props index 8f37e32..2b79e5d 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -6,19 +6,41 @@ https://github.com/BenjaminAbt/hcaptcha MIT en-US - true - preview - enable true true embedded + false + true + snupkg + + + $(MSBuildProjectName.Contains('Test')) $(MsBuildProjectName.Contains('Benchmark')) - false - - true + + net8.0 + + + + preview + enable + enable + true + + + + true + $(MSBuildThisFileDirectory)BenjaminAbt.HCaptchaNET.snk + + + 0024000004800000940000000602000000240000525341310004000001000100a9ba6ecd5a2e4a + a9095322a9baebe05966db4f05bf23df1457fc7b084079d7b320a3b0bcf5bb278d9e66f8f70d7e + 3d813aeb6a96baf75ef83033a5e0e5558df774d575599cdafbe6e047522db722b6244860a0d5b3 + b3bfbe24c50d698411c5d19e3d3765c9599809e2808ed0d6b2f9129395a95468484eac0815b070 + ea5b95dc + diff --git a/Directory.Packages.props b/Directory.Packages.props new file mode 100644 index 0000000..ff021a9 --- /dev/null +++ b/Directory.Packages.props @@ -0,0 +1,12 @@ + + + true + + + + + + + + + diff --git a/global.json b/global.json index 2a9ec01..76474f0 100644 --- a/global.json +++ b/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "6.0.101" + "version": "9.0.100" } } diff --git a/public.snk b/public.snk new file mode 100644 index 0000000..c708c4c Binary files /dev/null and b/public.snk differ diff --git a/sample/sample.aspnetcore/Controllers/HomeController.cs b/sample/sample.aspnetcore/Controllers/HomeController.cs index b3b464a..47b02c7 100644 --- a/sample/sample.aspnetcore/Controllers/HomeController.cs +++ b/sample/sample.aspnetcore/Controllers/HomeController.cs @@ -1,4 +1,4 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved using Microsoft.AspNetCore.Mvc; @@ -13,9 +13,7 @@ public class HomeController : Controller public IActionResult Index(HCaptchaVerifyResponse hCaptcha) => View(new IndexViewModel(hCaptcha)); } -public class IndexViewModel +public class IndexViewModel(HCaptchaVerifyResponse? response = null) { - public HCaptchaVerifyResponse? Response { get; } - - public IndexViewModel(HCaptchaVerifyResponse? response = null) => Response = response; + public HCaptchaVerifyResponse? Response { get; } = response; } diff --git a/sample/sample.aspnetcore/Program.cs b/sample/sample.aspnetcore/Program.cs index cfd8cbd..dc3fef1 100644 --- a/sample/sample.aspnetcore/Program.cs +++ b/sample/sample.aspnetcore/Program.cs @@ -1,21 +1,32 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved - -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Hosting; +// Copyright © Benjamin Abt 2020-2024, all rights reserved namespace BenjaminAbt.HCaptcha.Samples.AspNetCore; +/// +/// The entry point for the application, responsible for setting up and running the web host. +/// public class Program { + /// + /// The main entry point for the application. + /// + /// The command-line arguments passed to the application. public static void Main(string[] args) { + // Build and run the host CreateHostBuilder(args).Build().Run(); } + /// + /// Creates and configures the for the application. + /// + /// The command-line arguments passed to the application. + /// An that configures the web host. public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => { + // Use the Startup class for configuring services and middleware webBuilder.UseStartup(); }); } diff --git a/sample/sample.aspnetcore/Properties/launchSettings.json b/sample/sample.aspnetcore/Properties/launchSettings.json index 4f49531..6ca3990 100644 --- a/sample/sample.aspnetcore/Properties/launchSettings.json +++ b/sample/sample.aspnetcore/Properties/launchSettings.json @@ -1,4 +1,4 @@ -{ +{ "iisSettings": { "windowsAuthentication": false, "anonymousAuthentication": true, @@ -8,13 +8,6 @@ } }, "profiles": { - "IIS Express": { - "commandName": "IISExpress", - "launchBrowser": true, - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "hcaptcha.aspnetcore": { "commandName": "Project", "launchBrowser": true, diff --git a/sample/sample.aspnetcore/Startup.cs b/sample/sample.aspnetcore/Startup.cs index ef4423a..6cef1d0 100644 --- a/sample/sample.aspnetcore/Startup.cs +++ b/sample/sample.aspnetcore/Startup.cs @@ -1,47 +1,62 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved using BenjaminAbt.HCaptcha.AspNetCore; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; namespace BenjaminAbt.HCaptcha.Samples.AspNetCore; +/// +/// Configures services and the HTTP request pipeline for the application. +/// public class Startup { + /// + /// Gets the configuration settings for the application. + /// + public IConfiguration Configuration { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The configuration settings for the application. public Startup(IConfiguration configuration) { Configuration = configuration; } - public IConfiguration Configuration { get; } - + /// + /// Configures services for dependency injection in the application. + /// + /// The to which services are added. public void ConfigureServices(IServiceCollection services) { - // HCaptcha + // Add hCaptcha services using the configuration from the "HCaptcha" section services.AddHCaptcha(Configuration.GetSection("HCaptcha")); - // Mvc + // Add MVC controllers with views and configure the hCaptcha model binder services.AddControllersWithViews(mvcOptions => - // add model binder + // Add custom model binder for hCaptcha mvcOptions.AddHCaptchaModelBinder()); } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + /// + /// Configures the HTTP request pipeline for the application. + /// + /// The used to configure the middleware pipeline. + /// The containing information about the hosting environment. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { + // Use the developer exception page in development app.UseDeveloperExceptionPage(); } + // Enable routing in the middleware pipeline app.UseRouting(); app.UseEndpoints(endpoints => { - // Mvc + // Map MVC controllers to their respective endpoints endpoints.MapControllers(); }); } diff --git a/sample/sample.aspnetcore/Views/Home/Index.cshtml b/sample/sample.aspnetcore/Views/Home/Index.cshtml index ebfcd7a..115ee56 100644 --- a/sample/sample.aspnetcore/Views/Home/Index.cshtml +++ b/sample/sample.aspnetcore/Views/Home/Index.cshtml @@ -8,7 +8,6 @@ } -

hCaptcha Demo

@@ -20,7 +19,6 @@
- @{ var response = Model?.Response; if (response != null) diff --git a/sample/sample.aspnetcore/sample.aspnetcore.csproj b/sample/sample.aspnetcore/sample.aspnetcore.csproj index 6a177a0..ba76029 100644 --- a/sample/sample.aspnetcore/sample.aspnetcore.csproj +++ b/sample/sample.aspnetcore/sample.aspnetcore.csproj @@ -1,7 +1,6 @@  - net6.0 BenjaminAbt.HCaptcha.Samples.AspNetCore BenjaminAbt.HCaptcha.Samples.AspNetCore diff --git a/src/HCaptcha.AspNetCore/AuthorEntityBinderProvider.cs b/src/HCaptcha.AspNetCore/AuthorEntityBinderProvider.cs index 1dbcfd6..e47cbd3 100644 --- a/src/HCaptcha.AspNetCore/AuthorEntityBinderProvider.cs +++ b/src/HCaptcha.AspNetCore/AuthorEntityBinderProvider.cs @@ -1,22 +1,38 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; namespace BenjaminAbt.HCaptcha.AspNetCore; +/// +/// Provides a model binder for binding an to an action parameter. +/// public class AuthorEntityBinderProvider : IModelBinderProvider { + /// + /// Returns a model binder for the model type, if applicable. + /// + /// The context that provides information about the model being bound. + /// + /// An instance if the model type is , otherwise null. + /// + /// + /// Thrown when the is null. + /// public IModelBinder? GetBinder(ModelBinderProviderContext context) { + // Ensure the context is not null ArgumentNullException.ThrowIfNull(context); + // Check if the model type is HCaptchaVerifyResponse if (context.Metadata.ModelType == typeof(HCaptchaVerifyResponse)) { + // Return a binder for HCaptchaVerifyResponse return new BinderTypeModelBinder(typeof(HCaptchaModelBinder)); } + // Return null if no binder is required for the model type return null; } } diff --git a/src/HCaptcha.AspNetCore/HCaptcha.AspNetCore.csproj b/src/HCaptcha.AspNetCore/HCaptcha.AspNetCore.csproj index 6728da3..36ccd07 100644 --- a/src/HCaptcha.AspNetCore/HCaptcha.AspNetCore.csproj +++ b/src/HCaptcha.AspNetCore/HCaptcha.AspNetCore.csproj @@ -2,17 +2,11 @@ HCaptcha for ASP.NET Core - net6.0 BenjaminAbt.HCaptcha.AspNetCore BenjaminAbt.HCaptcha.AspNetCore - true embedded - - - - true - snupkg true + true @@ -34,7 +28,7 @@ - + diff --git a/src/HCaptcha.AspNetCore/HCaptchaExtensions.cs b/src/HCaptcha.AspNetCore/HCaptchaExtensions.cs index 99ad7e8..50cbab9 100644 --- a/src/HCaptcha.AspNetCore/HCaptchaExtensions.cs +++ b/src/HCaptcha.AspNetCore/HCaptchaExtensions.cs @@ -1,32 +1,42 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Refit; namespace BenjaminAbt.HCaptcha.AspNetCore; +/// +/// Provides extension methods for registering hCaptcha services in the dependency injection container. +/// public static class HCaptchaExtensions { /// - /// Adds the HCaptcha configuration as . - /// Adds as Refit Client with given base address in . + /// Adds hCaptcha services to the using the provided configuration section. /// + /// The to which the hCaptcha services will be added. + /// The containing the hCaptcha configuration settings. + /// The with hCaptcha services added. + /// + /// Thrown when or is null. + /// public static IServiceCollection AddHCaptcha(this IServiceCollection services, IConfigurationSection section) { + // Bind configuration to HCaptchaOptions HCaptchaOptions captchaOptions = new(); section.Bind(captchaOptions); + // Configure options to be injected wherever needed services.Configure(section); + // Register the Refit client for IHCaptchaApi with the base URL from configuration services.AddRefitClient() .ConfigureHttpClient(c => - { - c.BaseAddress = new Uri(captchaOptions.ApiBaseUrl); - } - ); + { + c.BaseAddress = new Uri(captchaOptions.ApiBaseUrl); + }); + // Register the hCaptcha provider services.AddScoped(); return services; diff --git a/src/HCaptcha.AspNetCore/HCaptchaModelBinder.cs b/src/HCaptcha.AspNetCore/HCaptchaModelBinder.cs index 76b84c2..5005e0a 100644 --- a/src/HCaptcha.AspNetCore/HCaptchaModelBinder.cs +++ b/src/HCaptcha.AspNetCore/HCaptchaModelBinder.cs @@ -1,45 +1,67 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System; -using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.Extensions.Options; +using Microsoft.Extensions.Primitives; namespace BenjaminAbt.HCaptcha.AspNetCore; +/// +/// A model binder that binds an hCaptcha verification result to an action parameter. +/// public class HCaptchaModelBinder : IModelBinder { private readonly IHCaptchaProvider _captchaProvider; private readonly HCaptchaOptions _captchaOptions; + /// + /// Initializes a new instance of the class. + /// + /// The hCaptcha provider used to verify the captcha token. + /// The configuration options for hCaptcha. public HCaptchaModelBinder(IHCaptchaProvider captchaProvider, IOptions captchaOptionsAccessor) { _captchaProvider = captchaProvider; _captchaOptions = captchaOptionsAccessor.Value; } + /// + /// Binds the model by verifying the hCaptcha token from the HTTP request. + /// + /// The that contains the HTTP request data to bind. + /// A representing the asynchronous operation. + /// + /// Thrown when is null. + /// + /// + /// Thrown if the HTTP request method is not "POST", as hCaptcha validation is only allowed on POST requests. + /// public async Task BindModelAsync(ModelBindingContext bindingContext) { + // Ensure bindingContext is not null ArgumentNullException.ThrowIfNull(bindingContext); - // validate context - var httpContext = bindingContext.HttpContext; + // Validate that the request method is POST + HttpContext httpContext = bindingContext.HttpContext; if (httpContext.Request.Method != "POST") { throw new InvalidOperationException($"{nameof(HCaptchaModelBinder)} can only be used with HTTP Post."); } - // read token - var token = httpContext.Request.Form[_captchaOptions.HttpPostResponseKeyName]; + // Retrieve the token from the form data + StringValues token = httpContext.Request.Form[_captchaOptions.HttpPostResponseKeyName]; - // verify + // Verify the token with the hCaptcha provider try { - var result = await _captchaProvider.Verify(token, httpContext.Connection?.RemoteIpAddress?.ToString()); + HCaptchaVerifyResponse? result = await _captchaProvider + .Verify(token, httpContext.Connection?.RemoteIpAddress?.ToString()).ConfigureAwait(false); bindingContext.Result = ModelBindingResult.Success(result); } catch (HCaptchaApiException apiException) { + // If verification fails, add a model error and mark the binding result as failed bindingContext.ModelState.TryAddModelError(bindingContext.FieldName, apiException.Message); bindingContext.Result = ModelBindingResult.Failed(); } diff --git a/src/HCaptcha.AspNetCore/HCaptchaModelBinderExtensions.cs b/src/HCaptcha.AspNetCore/HCaptchaModelBinderExtensions.cs index 6be4611..229cf15 100644 --- a/src/HCaptcha.AspNetCore/HCaptchaModelBinderExtensions.cs +++ b/src/HCaptcha.AspNetCore/HCaptchaModelBinderExtensions.cs @@ -1,18 +1,30 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System; using Microsoft.AspNetCore.Mvc; namespace BenjaminAbt.HCaptcha.AspNetCore; +/// +/// Extension methods for configuring the hCaptcha model binder in MVC options. +/// public static class HCaptchaModelBinderExtensions { + /// + /// Adds the hCaptcha model binder to the with optional configuration. + /// + /// The to which the model binder will be added. + /// An optional configuration action for setting up the model binder options. + /// The updated with the hCaptcha model binder added. public static MvcOptions AddHCaptchaModelBinder(this MvcOptions mvcOptions, Action? captchaModelBinderOptions = null) { + // Create a default set of model binder options HCaptchaModelBinderOptions cmbo = new(); + + // Apply custom configuration if provided captchaModelBinderOptions?.Invoke(cmbo); + // Insert the custom AuthorEntityBinderProvider at the specified position mvcOptions.ModelBinderProviders.Insert(cmbo.BinderPosition, new AuthorEntityBinderProvider()); return mvcOptions; diff --git a/src/HCaptcha.AspNetCore/HCaptchaModelBinderOptions.cs b/src/HCaptcha.AspNetCore/HCaptchaModelBinderOptions.cs index a1655ed..575a933 100644 --- a/src/HCaptcha.AspNetCore/HCaptchaModelBinderOptions.cs +++ b/src/HCaptcha.AspNetCore/HCaptchaModelBinderOptions.cs @@ -1,8 +1,20 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved + +using Microsoft.AspNetCore.Mvc; namespace BenjaminAbt.HCaptcha.AspNetCore; +/// +/// Options for configuring the position of the hCaptcha model binder in the model binder provider list. +/// public class HCaptchaModelBinderOptions { + /// + /// Gets or sets the position of the hCaptcha model binder in the model binder provider list. + /// + /// + /// The binder is inserted at the specified position in the list. + /// A value of 0 means it will be inserted at the beginning of the list. + /// public int BinderPosition { get; set; } = 0; } diff --git a/src/HCaptcha/HCaptcha.csproj b/src/HCaptcha/HCaptcha.csproj index d4190ee..c863e3d 100644 --- a/src/HCaptcha/HCaptcha.csproj +++ b/src/HCaptcha/HCaptcha.csproj @@ -4,15 +4,9 @@ HCaptcha for .NET BenjaminAbt.HCaptcha BenjaminAbt.HCaptcha - net6.0 - true embedded - - - - true - snupkg true + true @@ -30,9 +24,9 @@ - - - + + + diff --git a/src/HCaptcha/HCaptchaApiException.cs b/src/HCaptcha/HCaptchaApiException.cs index b83deb6..9cc8ec0 100644 --- a/src/HCaptcha/HCaptchaApiException.cs +++ b/src/HCaptcha/HCaptchaApiException.cs @@ -1,28 +1,23 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System; using System.Net; using Refit; namespace BenjaminAbt.HCaptcha; /// -/// hCapcha API Exception +/// Represents an exception that occurs when an hCaptcha API request fails. /// -/// Inner exception is a of type which is a part of Refit. -public class HCaptchaApiException : Exception +/// +/// Initializes a new instance of the class. +/// +/// The HTTP status code returned by the hCaptcha API. +/// The inner exception that contains details about the API error. +public class HCaptchaApiException(HttpStatusCode statusCode, ApiException apiException) + : Exception("hCaptcha API request failed. See inner exception for details.", apiException) { /// - /// Status Code + /// Gets the HTTP status code associated with the failed hCaptcha API request. /// - public HttpStatusCode StatusCode { get; } // Refit as Inner Exception - - /// - /// Creates an instance of with wrapped - /// - public HCaptchaApiException(HttpStatusCode statusCode, ApiException apiException) - : base("hCaptcha API request failed. See inner exception for details.", apiException) - { - StatusCode = statusCode; - } + public HttpStatusCode StatusCode { get; } = statusCode; } diff --git a/src/HCaptcha/HCaptchaOptions.cs b/src/HCaptcha/HCaptchaOptions.cs index 6a9528f..9c2035c 100644 --- a/src/HCaptcha/HCaptchaOptions.cs +++ b/src/HCaptcha/HCaptchaOptions.cs @@ -1,4 +1,4 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved namespace BenjaminAbt.HCaptcha; diff --git a/src/HCaptcha/HCaptchaProvider.cs b/src/HCaptcha/HCaptchaProvider.cs index ae85a79..7120c6d 100644 --- a/src/HCaptcha/HCaptchaProvider.cs +++ b/src/HCaptcha/HCaptchaProvider.cs @@ -1,7 +1,5 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System.Threading; -using System.Threading.Tasks; using Microsoft.Extensions.Options; using Refit; diff --git a/src/HCaptcha/HCaptchaResponseExtensions.cs b/src/HCaptcha/HCaptchaResponseExtensions.cs index a5d83bb..fcaf449 100644 --- a/src/HCaptcha/HCaptchaResponseExtensions.cs +++ b/src/HCaptcha/HCaptchaResponseExtensions.cs @@ -1,6 +1,4 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved - -using System.Collections.Generic; +// Copyright © Benjamin Abt 2020-2024, all rights reserved namespace BenjaminAbt.HCaptcha; diff --git a/src/HCaptcha/HCaptchaVerifyErrorCode.cs b/src/HCaptcha/HCaptchaVerifyErrorCode.cs index a3a1028..5ff3506 100644 --- a/src/HCaptcha/HCaptchaVerifyErrorCode.cs +++ b/src/HCaptcha/HCaptchaVerifyErrorCode.cs @@ -1,4 +1,4 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved namespace BenjaminAbt.HCaptcha; diff --git a/src/HCaptcha/HCaptchaVerifyResponse.cs b/src/HCaptcha/HCaptchaVerifyResponse.cs index fd96f69..60dbe00 100644 --- a/src/HCaptcha/HCaptchaVerifyResponse.cs +++ b/src/HCaptcha/HCaptchaVerifyResponse.cs @@ -1,6 +1,5 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System; using System.Text.Json.Serialization; namespace BenjaminAbt.HCaptcha; diff --git a/src/HCaptcha/IHCaptchaApi.cs b/src/HCaptcha/IHCaptchaApi.cs index d1da735..e33a5d7 100644 --- a/src/HCaptcha/IHCaptchaApi.cs +++ b/src/HCaptcha/IHCaptchaApi.cs @@ -1,7 +1,5 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved +// Copyright © Benjamin Abt 2020-2024, all rights reserved -using System.Threading; -using System.Threading.Tasks; using Refit; namespace BenjaminAbt.HCaptcha; diff --git a/src/HCaptcha/IHCaptchaProvider.cs b/src/HCaptcha/IHCaptchaProvider.cs index 216d83b..a07b3c2 100644 --- a/src/HCaptcha/IHCaptchaProvider.cs +++ b/src/HCaptcha/IHCaptchaProvider.cs @@ -1,7 +1,4 @@ -// Copyright © Benjamin Abt 2020-2021, all rights reserved - -using System.Threading; -using System.Threading.Tasks; +// Copyright © Benjamin Abt 2020-2024, all rights reserved namespace BenjaminAbt.HCaptcha; diff --git a/version.json b/version.json index 1a05557..1dc6bc7 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "0.9", + "version": "1.0", "assemblyVersion": { "precision": "revision" // optional. Use when you want a more precise assembly version than the default major.minor. },