From af53f14879b624063eaee7220abe314a84cdc261 Mon Sep 17 00:00:00 2001 From: Alex Lion Date: Mon, 27 Apr 2026 17:17:26 +0200 Subject: [PATCH] feat: add legal notice links for terms and privacy policy on registration page --- .env.sample | 4 ++ config/runtime.exs | 29 +++++++++- .../templates/user_registration/new.html.heex | 42 +++++++++------ .../user_reset_password/edit.html.heex | 4 +- .../user_registration_controller_test.exs | 54 +++++++++++++++++++ 5 files changed, 112 insertions(+), 21 deletions(-) diff --git a/.env.sample b/.env.sample index 8cdd36d..a2671f7 100644 --- a/.env.sample +++ b/.env.sample @@ -75,6 +75,10 @@ MAIL_FROM_NAME=Claper # GS_JPG_RESOLUTION=300x300 # LANGUAGES=en,fr,es,it,nl,de +# == Legal links shown on the registration page (both must be set to display the notice) +# TERMS_URL=https://example.com/terms +# PRIVACY_URL=https://example.com/privacy + # == Reverse proxy / IP forwarding (set these if Claper runs behind a load balancer or reverse proxy) # Comma-separated list of trusted proxy IPs or CIDR ranges whose forwarding headers will be trusted diff --git a/config/runtime.exs b/config/runtime.exs index 1f66d4a..1f972fc 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -164,6 +164,31 @@ allow_unlink_external_provider = logout_redirect_url = get_var_from_path_or_env(config_dir, "LOGOUT_REDIRECT_URL", nil) +normalize_url = fn + nil -> + nil + + value -> + case String.trim(value) do + "" -> nil + trimmed -> trimmed + end +end + +terms_url = normalize_url.(get_var_from_path_or_env(config_dir, "TERMS_URL", nil)) +privacy_url = normalize_url.(get_var_from_path_or_env(config_dir, "PRIVACY_URL", nil)) + +for {name, value} <- [{"TERMS_URL", terms_url}, {"PRIVACY_URL", privacy_url}], + not is_nil(value) do + case URI.parse(value) do + %URI{scheme: scheme} when scheme in ["http", "https"] -> + :ok + + _ -> + raise "#{name} must start with `http` or `https`. Got `#{value}`" + end +end + languages = get_var_from_path_or_env(config_dir, "LANGUAGES", "en,fr,es,it,de") |> String.split(",") @@ -210,7 +235,9 @@ config :claper, logout_redirect_url: logout_redirect_url, languages: languages, remote_ip_proxies: remote_ip_proxies, - remote_ip_headers: remote_ip_headers + remote_ip_headers: remote_ip_headers, + terms_url: terms_url, + privacy_url: privacy_url config :claper, :presentations, max_file_size: max_file_size, diff --git a/lib/claper_web/templates/user_registration/new.html.heex b/lib/claper_web/templates/user_registration/new.html.heex index d1c06e4..583201e 100644 --- a/lib/claper_web/templates/user_registration/new.html.heex +++ b/lib/claper_web/templates/user_registration/new.html.heex @@ -111,23 +111,31 @@ )}

-

- {gettext("By creating an account, you agree to our")} - {" "} - {link(gettext("Terms of Service"), - to: ~p"/tos", - class: - "text-gray-300 underline decoration-gray-500 underline-offset-2 hover:text-white" - )} - {" "} - {gettext("and")} - {" "} - {link(gettext("Privacy Policy"), - to: ~p"/privacy", - class: - "text-gray-300 underline decoration-gray-500 underline-offset-2 hover:text-white" - )} . -

+ <% terms_url = Application.get_env(:claper, :terms_url) %> + <% privacy_url = Application.get_env(:claper, :privacy_url) %> + <%= if terms_url && privacy_url do %> +

+ {gettext("By creating an account, you agree to our")} + {" "} + {link(gettext("Terms of Service"), + to: terms_url, + target: "_blank", + rel: "noopener noreferrer", + class: + "text-gray-300 underline decoration-gray-500 underline-offset-2 hover:text-white" + )} + {" "} + {gettext("and")} + {" "} + {link(gettext("Privacy Policy"), + to: privacy_url, + target: "_blank", + rel: "noopener noreferrer", + class: + "text-gray-300 underline decoration-gray-500 underline-offset-2 hover:text-white" + )} . +

+ <% end %> diff --git a/lib/claper_web/templates/user_reset_password/edit.html.heex b/lib/claper_web/templates/user_reset_password/edit.html.heex index c972129..b2bb4b7 100644 --- a/lib/claper_web/templates/user_reset_password/edit.html.heex +++ b/lib/claper_web/templates/user_reset_password/edit.html.heex @@ -18,9 +18,7 @@ {gettext("Pick a new password and get back to presenting.")}

- {gettext( - "Choose something secure that you'll remember, then you're all set." - )} + {gettext("Choose something secure that you'll remember, then you're all set.")}

diff --git a/test/claper_web/controllers/user_registration_controller_test.exs b/test/claper_web/controllers/user_registration_controller_test.exs index e7f47a8..c656030 100644 --- a/test/claper_web/controllers/user_registration_controller_test.exs +++ b/test/claper_web/controllers/user_registration_controller_test.exs @@ -8,10 +8,14 @@ defmodule ClaperWeb.UserRegistrationControllerTest do setup do enable_account_creation = Application.get_env(:claper, :enable_account_creation) email_confirmation = Application.get_env(:claper, :email_confirmation) + terms_url = Application.get_env(:claper, :terms_url) + privacy_url = Application.get_env(:claper, :privacy_url) on_exit(fn -> Application.put_env(:claper, :enable_account_creation, enable_account_creation) Application.put_env(:claper, :email_confirmation, email_confirmation) + Application.put_env(:claper, :terms_url, terms_url) + Application.put_env(:claper, :privacy_url, privacy_url) end) :ok @@ -48,6 +52,56 @@ defmodule ClaperWeb.UserRegistrationControllerTest do assert redirected_to(conn) == "/events" end + + test "shows the legal notice when both TERMS_URL and PRIVACY_URL are configured", %{ + conn: conn + } do + Application.put_env(:claper, :enable_account_creation, true) + Application.put_env(:claper, :terms_url, "https://example.com/terms") + Application.put_env(:claper, :privacy_url, "https://example.com/privacy") + + conn = get(conn, ~p"/users/register") + response = html_response(conn, 200) + + assert response =~ "By creating an account" + assert response =~ "https://example.com/terms" + assert response =~ "https://example.com/privacy" + end + + test "hides the legal notice when only TERMS_URL is configured", %{conn: conn} do + Application.put_env(:claper, :enable_account_creation, true) + Application.put_env(:claper, :terms_url, "https://example.com/terms") + Application.put_env(:claper, :privacy_url, nil) + + conn = get(conn, ~p"/users/register") + response = html_response(conn, 200) + + refute response =~ "By creating an account" + refute response =~ "https://example.com/terms" + end + + test "hides the legal notice when only PRIVACY_URL is configured", %{conn: conn} do + Application.put_env(:claper, :enable_account_creation, true) + Application.put_env(:claper, :terms_url, nil) + Application.put_env(:claper, :privacy_url, "https://example.com/privacy") + + conn = get(conn, ~p"/users/register") + response = html_response(conn, 200) + + refute response =~ "By creating an account" + refute response =~ "https://example.com/privacy" + end + + test "hides the legal notice when neither URL is configured", %{conn: conn} do + Application.put_env(:claper, :enable_account_creation, true) + Application.put_env(:claper, :terms_url, nil) + Application.put_env(:claper, :privacy_url, nil) + + conn = get(conn, ~p"/users/register") + response = html_response(conn, 200) + + refute response =~ "By creating an account" + end end describe "POST /users/register" do