- if DateTime.after?(at, valid_if_after),
- do: method().validate(token, captcha, answer_md5),
- else: {:error, "CAPTCHA expired"}
+ try do
+ if DateTime.before?(at, valid_if_after),
+ do: throw({:error, dgettext("errors", "CAPTCHA expired")})
+
+ if not is_nil(Cachex.get!(:used_captcha_cache, token)),
+ do: throw({:error, dgettext("errors", "CAPTCHA already used")})
+
+ res = method().validate(token, captcha, answer_md5)
+ # Throw if an error occurs
+ if res != :ok, do: throw(res)
+
+ # Mark this captcha as used
+ {:ok, _} =
+ Cachex.put(:used_captcha_cache, token, true, ttl: :timer.seconds(seconds_valid))
+
+ :ok
+ catch
+ :throw, e -> e
+ end