+
+ def validate_captcha(app, params) do
+ if app.trusted || not Pleroma.Captcha.enabled?() do
+ :ok
+ else
+ do_validate_captcha(params)
+ end
+ end
+
+ defp do_validate_captcha(params) do
+ with :ok <- validate_captcha_presence(params),
+ :ok <-
+ Pleroma.Captcha.validate(
+ params[:captcha_token],
+ params[:captcha_solution],
+ params[:captcha_answer_data]
+ ) do
+ :ok
+ else
+ {:error, :captcha_error} ->
+ captcha_error(dgettext("errors", "CAPTCHA Error"))
+
+ {:error, :invalid} ->
+ captcha_error(dgettext("errors", "Invalid CAPTCHA"))
+
+ {:error, :kocaptcha_service_unavailable} ->
+ captcha_error(dgettext("errors", "Kocaptcha service unavailable"))
+
+ {:error, :expired} ->
+ captcha_error(dgettext("errors", "CAPTCHA expired"))
+
+ {:error, :already_used} ->
+ captcha_error(dgettext("errors", "CAPTCHA already used"))
+
+ {:error, :invalid_answer_data} ->
+ captcha_error(dgettext("errors", "Invalid answer data"))
+
+ {:error, error} ->
+ captcha_error(error)
+ end
+ end
+
+ defp validate_captcha_presence(params) do
+ [:captcha_solution, :captcha_token, :captcha_answer_data]
+ |> Enum.find_value(:ok, fn key ->
+ unless is_binary(params[key]) do
+ error = dgettext("errors", "Invalid CAPTCHA (Missing parameter: %{name})", name: key)
+ {:error, error}
+ end
+ end)
+ end
+
+ # For some reason FE expects error message to be a serialized JSON
+ defp captcha_error(error), do: {:error, Jason.encode!(%{captcha: [error]})}