defmodule BerrypodWeb.NewsletterController do use BerrypodWeb, :controller alias Berrypod.Newsletter @doc "No-JS fallback for newsletter signup form." def subscribe(conn, %{"email" => email}) do ip_hash = hash_ip(conn) case Newsletter.subscribe(email, consent_text: "Newsletter signup on website", ip_hash: ip_hash ) do {:ok, _} -> conn |> put_flash(:info, "Check your inbox to confirm your subscription.") |> redirect(to: redirect_back(conn)) {:already_confirmed, _} -> conn |> put_flash(:info, "You're already subscribed!") |> redirect(to: redirect_back(conn)) {:error, _} -> conn |> put_flash(:error, "Please enter a valid email address.") |> redirect(to: redirect_back(conn)) end end def subscribe(conn, _params) do conn |> put_flash(:error, "Please enter your email address.") |> redirect(to: ~p"/") end @doc "Handles confirmation link from the double opt-in email." def confirm(conn, %{"token" => token}) do case Newsletter.confirm(token) do {:ok, _sub} -> conn |> put_status(200) |> html(confirmation_html(:success)) {:error, :invalid_token} -> conn |> put_status(400) |> html(confirmation_html(:invalid)) end end defp confirmation_html(:success) do shop_name = Berrypod.Settings.get_setting("shop_name", "Berrypod") """ Subscription confirmed

You're subscribed!

Thanks for confirming. You'll receive the #{shop_name} newsletter from now on.

Back to the shop

""" end defp confirmation_html(:invalid) do """ Invalid link

Link invalid or expired

This confirmation link has expired or is invalid. Please try subscribing again.

Back to the shop

""" end defp redirect_back(conn) do case get_req_header(conn, "referer") do [referer | _] -> uri = URI.parse(referer) uri.path || "/" _ -> "/" end end defp hash_ip(conn) do daily_salt = Date.utc_today() |> Date.to_iso8601() ip_string = conn.remote_ip |> :inet.ntoa() |> to_string() :crypto.hash(:sha256, ip_string <> daily_salt) |> Base.encode16(case: :lower) end end