diff --git a/.env.example b/.env.example index c61ceba1e..8e097c644 100644 --- a/.env.example +++ b/.env.example @@ -23,6 +23,10 @@ DEFAULT_LANGUAGE="English" MEDIA_ROOT=images/ +# hCaptcha configuration +HCAPTCHA_SITEKEY= +HCAPTCHA_SECRET= + # Database configuration PGPORT=5432 POSTGRES_PASSWORD=securedbypassword123 diff --git a/bookwyrm/forms/landing.py b/bookwyrm/forms/landing.py index 831d1d539..5f08ee56b 100644 --- a/bookwyrm/forms/landing.py +++ b/bookwyrm/forms/landing.py @@ -4,6 +4,7 @@ from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError from django.utils.translation import gettext_lazy as _ +from hcaptcha_field import hCaptchaField import pyotp from bookwyrm import models @@ -38,9 +39,11 @@ class LoginForm(CustomForm): class RegisterForm(CustomForm): + hcaptcha = hCaptchaField() + class Meta: model = models.User - fields = ["localname", "email", "password"] + fields = ["localname", "email", "password", "hcaptcha"] help_texts = {f: None for f in fields} widgets = {"password": forms.PasswordInput()} diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 6da6f4bae..70cffddaf 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -35,6 +35,9 @@ SESSION_COOKIE_AGE = env.int("SESSION_COOKIE_AGE", 3600 * 24 * 30) # 1 month JS_CACHE = "8a89cad7" +HCAPTCHA_SITEKEY = env("HCAPTCHA_SITEKEY") +HCAPTCHA_SECRET = env("HCAPTCHA_SECRET") + # email EMAIL_BACKEND = env("EMAIL_BACKEND", "django.core.mail.backends.smtp.EmailBackend") EMAIL_HOST = env("EMAIL_HOST") @@ -101,6 +104,7 @@ INSTALLED_APPS = [ "django.contrib.messages", "django.contrib.staticfiles", "django.contrib.humanize", + "hcaptcha_field", "oauth2_provider", "file_resubmit", "sass_processor", @@ -479,8 +483,8 @@ elif USE_AZURE: ) MEDIA_FULL_URL = MEDIA_URL # Content Security Policy - CSP_DEFAULT_SRC = ["'self'", AZURE_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS - CSP_SCRIPT_SRC = ["'self'", AZURE_CUSTOM_DOMAIN] + CSP_ADDITIONAL_HOSTS + CSP_DEFAULT_SRC = ["'self'", AZURE_CUSTOM_DOMAIN] + env.list("CSP_ADDITIONAL_HOSTS") + CSP_SCRIPT_SRC = ["'self'", AZURE_CUSTOM_DOMAIN] + env.list("CSP_ADDITIONAL_HOSTS") else: # Storages STORAGES = { @@ -504,8 +508,8 @@ else: MEDIA_URL = "/images/" MEDIA_FULL_URL = BASE_URL + MEDIA_URL # Content Security Policy - CSP_DEFAULT_SRC = ["'self'"] + CSP_ADDITIONAL_HOSTS - CSP_SCRIPT_SRC = ["'self'"] + CSP_ADDITIONAL_HOSTS + CSP_DEFAULT_SRC = ["'self'"] + env.list("CSP_ADDITIONAL_HOSTS") + CSP_SCRIPT_SRC = ["'self'"] + env.list("CSP_ADDITIONAL_HOSTS") CSP_INCLUDE_NONCE_IN = ["script-src"] diff --git a/bookwyrm/templates/snippets/register_form.html b/bookwyrm/templates/snippets/register_form.html index 61e3b9c96..8df8d4393 100644 --- a/bookwyrm/templates/snippets/register_form.html +++ b/bookwyrm/templates/snippets/register_form.html @@ -60,6 +60,13 @@ +