Add support for hcaptcha

This commit is contained in:
jvyden 2022-02-05 00:42:39 -05:00
commit df257b38c4
No known key found for this signature in database
GPG key ID: 18BCF2BE0262B278
6 changed files with 73 additions and 5 deletions

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JavaScriptLibraryMappings">
<file url="PROJECT" libraries="{fomantic-ui, sha256}" />
<file url="PROJECT" libraries="{api, fomantic-ui, sha256}" />
</component>
</project>

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Types.Settings;
using Newtonsoft.Json.Linq;
namespace LBPUnion.ProjectLighthouse.Helpers;
public static class CaptchaHelper
{
private static readonly HttpClient client = new()
{
BaseAddress = new Uri("https://hcaptcha.com"),
};
public static async Task<bool> Verify(string token)
{
if (!ServerSettings.Instance.HCaptchaEnabled) return true;
List<KeyValuePair<string, string>> payload = new()
{
new("secret", ServerSettings.Instance.HCaptchaSecret),
new("response", token),
};
HttpResponseMessage response = await client.PostAsync("/siteverify", new FormUrlEncodedContent(payload));
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
// We only really care about the success result, nothing else that hcaptcha sends us, so lets only parse that.
bool success = bool.Parse(JObject.Parse(responseBody)["success"]?.ToString() ?? "false");
return success;
}
}

View file

@ -50,6 +50,11 @@
</div>
</div>
@if (ServerSettings.Instance.HCaptchaEnabled)
{
@await Html.PartialAsync("Partials/CaptchaPartial")
}
<input type="submit" value="Log in" id="submit" class="ui blue button">
@if (ServerSettings.Instance.RegistrationEnabled)
{

View file

@ -6,8 +6,10 @@ using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types;
using LBPUnion.ProjectLighthouse.Types.Settings;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Primitives;
namespace LBPUnion.ProjectLighthouse.Pages;
@ -18,8 +20,6 @@ public class LoginForm : BaseLayout
public string Error { get; private set; }
public bool WasLoginRequest { get; private set; }
[UsedImplicitly]
public async Task<IActionResult> OnPost(string username, string password)
{
@ -35,6 +35,19 @@ public class LoginForm : BaseLayout
return this.Page();
}
if (ServerSettings.Instance.HCaptchaEnabled)
{
// && (!this.Request.Form.TryGetValue("h-captcha-response", out StringValues values) || !await CaptchaHelper.Verify(values[0])))
bool gotCaptcha = this.Request.Form.TryGetValue("h-captcha-response", out StringValues values);
string? token = gotCaptcha ? values[0] : null;
if (token == null || !await CaptchaHelper.Verify(token))
{
this.Error = "You must solve the captcha correctly.";
return this.Page();
}
}
User? user = await this.Database.Users.FirstOrDefaultAsync(u => u.Username == username);
if (user == null)
{
@ -68,6 +81,8 @@ public class LoginForm : BaseLayout
this.Response.Cookies.Append("LighthouseToken", webToken.UserToken);
Logger.Log($"User {user.Username} (id: {user.UserId}) successfully logged in on web", LoggerLevelLogin.Instance);
if (user.PasswordResetRequired) return this.Redirect("~/passwordResetRequired");
return this.RedirectToPage(nameof(LandingPage));

View file

@ -0,0 +1,6 @@
@using LBPUnion.ProjectLighthouse.Types.Settings
@if (ServerSettings.Instance.HCaptchaEnabled)
{
<div class="h-captcha" data-sitekey="@ServerSettings.Instance.HCaptchaSiteKey"></div>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
}

View file

@ -5,7 +5,6 @@ using System.Text.Json;
using System.Text.Json.Serialization;
using JetBrains.Annotations;
using Kettu;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
namespace LBPUnion.ProjectLighthouse.Types.Settings;
@ -13,7 +12,7 @@ namespace LBPUnion.ProjectLighthouse.Types.Settings;
[Serializable]
public class ServerSettings
{
public const int CurrentConfigVersion = 18; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
public const int CurrentConfigVersion = 19; // MUST BE INCREMENTED FOR EVERY CONFIG CHANGE!
private static FileSystemWatcher fileWatcher;
static ServerSettings()
{
@ -150,6 +149,12 @@ public class ServerSettings
public string MissingIconHash { get; set; } = "";
public bool HCaptchaEnabled { get; set; }
public string HCaptchaSiteKey { get; set; } = "";
public string HCaptchaSecret { get; set; } = "";
#region Meta
[NotNull]