using System; using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; using Bit.Core.Settings; using Microsoft.Extensions.Logging; using Newtonsoft.Json; namespace Bit.Core.Services { public class HCaptchaValidationService : ICaptchaValidationService { private readonly ILogger _logger; private readonly IHttpClientFactory _httpClientFactory; private readonly GlobalSettings _globalSettings; public HCaptchaValidationService( ILogger logger, IHttpClientFactory httpClientFactory, GlobalSettings globalSettings) { _logger = logger; _httpClientFactory = httpClientFactory; _globalSettings = globalSettings; } public bool ServiceEnabled => true; public async Task ValidateCaptchaResponseAsync(string captchResponse, string clientIpAddress) { if (string.IsNullOrWhiteSpace(captchResponse)) { return false; } var httpClient = _httpClientFactory.CreateClient("HCaptchaValidationService"); var requestMessage = new HttpRequestMessage { Method = HttpMethod.Post, RequestUri = new Uri("https://hcaptcha.com/siteverify"), Content = new FormUrlEncodedContent(new Dictionary { { "response", captchResponse.TrimStart("hcaptcha|".ToCharArray()) }, { "secret", _globalSettings.Captcha.HCaptchaSecretKey }, { "sitekey", _globalSettings.Captcha.HCaptchaSiteKey }, { "remoteip", clientIpAddress } }) }; HttpResponseMessage responseMessage; try { responseMessage = await httpClient.SendAsync(requestMessage); } catch (Exception e) { _logger.LogError(11389, e, "Unable to verify with HCaptcha."); return false; } if (!responseMessage.IsSuccessStatusCode) { return false; } var responseContent = await responseMessage.Content.ReadAsStringAsync(); dynamic jsonResponse = JsonConvert.DeserializeObject(responseContent); return (bool)jsonResponse.success; } } }