Up captcha timer to 60 secs again, save used captchas in cachex
authorEkaterina Vaartis <vaartis@cock.li>
Wed, 26 Dec 2018 21:12:20 +0000 (00:12 +0300)
committerEkaterina Vaartis <vaartis@cock.li>
Wed, 26 Dec 2018 21:16:43 +0000 (00:16 +0300)
config/config.exs
lib/pleroma/application.ex
lib/pleroma/captcha/captcha.ex

index b8ef448b423225c6ca216bac78f9af0051b2ffbc..9cb81cf4739a8e201a703e67303e5a181eaf8d13 100644 (file)
@@ -12,7 +12,7 @@ config :pleroma, Pleroma.Repo, types: Pleroma.PostgresTypes
 
 config :pleroma, Pleroma.Captcha,
   enabled: false,
-  seconds_valid: 20,
+  seconds_valid: 60,
   method: Pleroma.Captcha.Kocaptcha
 
 config :pleroma, Pleroma.Captcha.Kocaptcha, endpoint: "https://captcha.kotobank.ch"
index e1599195717d59fa5112674d89b58ee08a7cd51a..bdd0ee26f2f22005b430f367359ae42a99a40d82 100644 (file)
@@ -25,6 +25,16 @@ defmodule Pleroma.Application do
         supervisor(Pleroma.Repo, []),
         worker(Pleroma.Emoji, []),
         worker(Pleroma.Captcha, []),
+        worker(
+          Cachex,
+          [
+            :used_captcha_cache,
+            [
+              ttl_interval: :timer.seconds(60 * 2)
+            ]
+          ],
+          id: :cachex_used_captcha_cache
+        ),
         worker(
           Cachex,
           [
index 04769d4b2b87582458fde62653df1a0474c86167..c7abafeb162b0f58d5365d12f56d8b97ffff93b1 100644 (file)
@@ -80,9 +80,24 @@ defmodule Pleroma.Captcha do
     result =
       with {:ok, data} <- MessageEncryptor.decrypt(answer_data, secret, sign_secret),
            %{at: at, answer_data: answer_md5} <- :erlang.binary_to_term(data) do
-        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, "CAPTCHA expired"})
+
+          if not is_nil(Cachex.get!(:used_captcha_cache, token)),
+            do: throw({:error, "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
       else
         _ -> {:error, "Invalid answer data"}
       end