defmodule Meta.Captcha do # We can't use a graphical-only captcha library such as # https://hex.pm/packages/captcha since it would break accessibility for # blind people. Let's make it simple maths instead! # Captcha expression tuning: @terms 1..6 @operands ["+", "-", "*"] def validate(changeset, expected_result) do result = Ecto.Changeset.get_field(changeset, :captcha) if result == expected_result do changeset else Ecto.Changeset.add_error(changeset, :captcha, "does not match") end end def generate do left = @terms |> Enum.random right = @terms |> Enum.random operation = @operands |> Enum.random text = "#{left} #{operation} #{right}" value = case operation do "+" -> left + right "-" -> left - right "*" -> left * right end {text, value} end end