diff --git a/Gemfile b/Gemfile
index 0aeda5cb2865644fc5b5f4e4ffb480c64465c2c9..1ca67840692c396f00c019f10a7ff7da1e7e4915 100644
--- a/Gemfile
+++ b/Gemfile
@@ -59,7 +59,7 @@ gem 'akismet', '~> 3.0'
 gem 'invisible_captcha', '~> 1.1.0'
 
 # Two-factor authentication
-gem 'devise-two-factor', '~> 3.1.0'
+gem 'devise-two-factor', '~> 4.0.0'
 gem 'rqrcode-rails3', '~> 0.1.7'
 gem 'attr_encrypted', '~> 3.1.0'
 gem 'u2f', '~> 0.2.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 682e8432b559a4ab22cfb301cfc685c785af8d7d..724412fa8ed0752081a431e3f561d9d902a6cd14 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -264,12 +264,12 @@ GEM
       railties (>= 4.1.0)
       responders
       warden (~> 1.2.3)
-    devise-two-factor (3.1.0)
-      activesupport (< 6.1)
+    devise-two-factor (4.0.0)
+      activesupport (< 6.2)
       attr_encrypted (>= 1.3, < 4, != 2)
       devise (~> 4.0)
-      railties (< 6.1)
-      rotp (~> 2.0)
+      railties (< 6.2)
+      rotp (~> 6.0)
     diff-lcs (1.4.4)
     diff_match_patch (0.1.0)
     diffy (3.3.0)
@@ -1044,7 +1044,7 @@ GEM
       nokogiri
     rexml (3.2.4)
     rinku (2.0.0)
-    rotp (2.1.2)
+    rotp (6.2.0)
     rouge (3.26.0)
     rqrcode (0.7.0)
       chunky_png
@@ -1385,7 +1385,7 @@ DEPENDENCIES
   derailed_benchmarks
   device_detector
   devise (~> 4.7.2)
-  devise-two-factor (~> 3.1.0)
+  devise-two-factor (~> 4.0.0)
   diff_match_patch (~> 0.1.0)
   diffy (~> 3.3)
   discordrb-webhooks (~> 3.4)
diff --git a/changelogs/unreleased/id-bump-devise-two-factor.yml b/changelogs/unreleased/id-bump-devise-two-factor.yml
new file mode 100644
index 0000000000000000000000000000000000000000..6a75991aaa46a38225c7c715db768e339d5631b8
--- /dev/null
+++ b/changelogs/unreleased/id-bump-devise-two-factor.yml
@@ -0,0 +1,5 @@
+---
+title: Bump devise-two-factor version
+merge_request: 58929
+author:
+type: other