{"id":296332,"date":"2026-04-29T06:51:08","date_gmt":"2026-04-29T06:51:08","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/two-factor-shield\/"},"modified":"2026-06-05T06:59:03","modified_gmt":"2026-06-05T06:59:03","slug":"loginarmor-email-2fa","status":"publish","type":"plugin","link":"https:\/\/sna.wordpress.org\/plugins\/loginarmor-email-2fa\/","author":23190646,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2","stable_tag":"1.2","tested":"7.0","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"LoginArmor - Email 2FA","header_author":"TechArk Solutions","header_description":"Adds Two-Factor Authentication via Email for secure WordPress logins.","assets_banners_color":"f8faff","last_updated":"2026-06-05 06:59:03","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/profiles.wordpress.org\/gotechark\/","rating":0,"author_block_rating":0,"active_installs":20,"downloads":234,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0":{"tag":"1.0","author":"gotechark","date":"2026-04-29 06:52:21"},"1.1":{"tag":"1.1","author":"gotechark","date":"2026-05-11 09:18:30"},"1.2":{"tag":"1.2","author":"gotechark","date":"2026-06-05 06:59:03"}},"upgrade_notice":{"1.2":"<p>Recommended update. Fixes a silent breakage affecting REST API \/ application password users, fixes the recovery code &quot;Continue&quot; redirect, and improves log file handling. No settings changes required \u2014 upgrade and activate.<\/p>","1.1":"<p>Code &amp; performance optimizations<\/p>","1.0":"<p>This version standardizes the plugin as email-only 2FA for the first public release and updates older saved settings accordingly.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3518040,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3518040,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3518030,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3518030,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.0","1.1","1.2"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3518030,"resolution":"1","location":"assets","locale":"","width":1373,"height":788},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3518030,"resolution":"2","location":"assets","locale":"","width":1373,"height":788}},"screenshots":{"1":"Configure 2FA Setting","2":"Configure Email Template"}},"plugin_section":[],"plugin_tags":[9211,209326,1229,261354,1909],"plugin_category":[],"plugin_contributors":[244901,237096],"plugin_business_model":[],"class_list":["post-296332","plugin","type-plugin","status-publish","hentry","plugin_tags-2fa","plugin_tags-email-otp","plugin_tags-login-security","plugin_tags-recovery-codes","plugin_tags-two-factor-authentication","plugin_contributors-gotechark","plugin_contributors-yogid","plugin_committers-gotechark"],"banners":{"banner":"https:\/\/ps.w.org\/loginarmor-email-2fa\/assets\/banner-772x250.png?rev=3518030","banner_2x":"https:\/\/ps.w.org\/loginarmor-email-2fa\/assets\/banner-1544x500.png?rev=3518030","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/loginarmor-email-2fa\/assets\/icon-128x128.png?rev=3518040","icon_2x":"https:\/\/ps.w.org\/loginarmor-email-2fa\/assets\/icon-256x256.png?rev=3518040","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/loginarmor-email-2fa\/assets\/screenshot-1.png?rev=3518030","caption":"Configure 2FA Setting"},{"src":"https:\/\/ps.w.org\/loginarmor-email-2fa\/assets\/screenshot-2.png?rev=3518030","caption":"Configure Email Template"}],"raw_content":"<!--section=description-->\n<p>LoginArmor adds an extra layer of protection to WordPress logins by requiring a one-time verification code after a valid username and password are entered.<\/p>\n\n<h4>Key features<\/h4>\n\n<ul>\n<li>Email-based one-time passcodes for WordPress logins<\/li>\n<li>Apply 2FA to selected user roles<\/li>\n<li>Apply 2FA to specific users<\/li>\n<li>Optional grace period before activation is enforced<\/li>\n<li>Recovery codes for backup access<\/li>\n<li>Customizable email subject and login code email template<\/li>\n<li>Optional debug logging to <code>wp-content\/uploads\/loginarmor-email-2fa\/loginarmor-debug.log<\/code><\/li>\n<li>Automatic log rotation to prevent unbounded log file growth<\/li>\n<li>Compatible with WordPress application passwords and REST API clients<\/li>\n<li>Dedicated settings screen inside the WordPress admin<\/li>\n<\/ul>\n\n<h4>How it works<\/h4>\n\n<ol>\n<li>A user enters a valid username and password.<\/li>\n<li>LoginArmor sends a one-time code to the user\u2019s email address.<\/li>\n<li>The user enters the code to complete login.<\/li>\n<li>If needed, the user can use a recovery code instead.<\/li>\n<\/ol>\n\n<h4>Recovery codes<\/h4>\n\n<p>The plugin includes recovery codes as a backup login option. Codes are stored securely as hashes in user meta. Plaintext codes are shown only temporarily so users can save or download them once.<\/p>\n\n<h4>Grace period<\/h4>\n\n<p>You can optionally set a grace period in days. During the grace period, eligible users can continue signing in while they complete activation. After the grace period ends, 2FA is enforced.<\/p>\n\n<h4>No external service required<\/h4>\n\n<p>LoginArmor uses WordPress email delivery and does not require a third-party 2FA service.<\/p>\n\n<h4>Developer notes<\/h4>\n\n<p>The plugin exposes a filter for sites running behind a reverse proxy (Cloudflare, load balancers, etc.) that need to supply the real visitor IP:<\/p>\n\n<pre><code>add_filter( 'la2fa_get_client_ip', function( $ip ) {\n    return $_SERVER['HTTP_CF_CONNECTING_IP'] ?? $_SERVER['REMOTE_ADDR'] ?? 'unknown';\n} );\n<\/code><\/pre>\n\n<p>Without this filter the plugin behaves exactly as before \u2014 it reads <code>REMOTE_ADDR<\/code> by default.<\/p>\n\n<h3>Privacy<\/h3>\n\n<p>LoginArmor does not connect to an external third-party verification service.<\/p>\n\n<p>The plugin may process and store the following data on your WordPress site:<\/p>\n\n<ul>\n<li>Email-based one-time passcodes for login verification<\/li>\n<li>Recovery code hashes stored in user meta<\/li>\n<li>Optional debug log entries in <code>wp-content\/uploads\/loginarmor-email-2fa\/loginarmor-debug.log<\/code><\/li>\n<li>Temporary transients used for login, cooldown, and verification flow<\/li>\n<\/ul>\n\n<p>This data stays on your site unless your own email delivery system or hosting stack routes it elsewhere.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to the <code>\/wp-content\/plugins\/loginarmor-email-2fa\/<\/code> directory, or install the plugin through the WordPress plugins screen.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> screen in WordPress.<\/li>\n<li>Go to <strong>LoginArmor<\/strong> in the WordPress admin menu.<\/li>\n<li>Enable two-factor authentication.<\/li>\n<li>Choose the user roles and\/or specific users who should use 2FA.<\/li>\n<li>Configure the grace period if needed.<\/li>\n<li>Customize the email subject and email template if desired.<\/li>\n<li>Save your settings.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"can%20i%20apply%202fa%20to%20only%20some%20users%3F\"><h3>Can I apply 2FA to only some users?<\/h3><\/dt>\n<dd><p>Yes. You can apply 2FA by user role, by specific users, or both.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20a%20user%20cannot%20access%20their%20email%3F\"><h3>What happens if a user cannot access their email?<\/h3><\/dt>\n<dd><p>They can use a recovery code if one has been generated and saved.<\/p><\/dd>\n<dt id=\"can%20i%20customize%20the%20email%20content%3F\"><h3>Can I customize the email content?<\/h3><\/dt>\n<dd><p>Yes. You can customize the sender email address, subject line, and login code email template from the plugin settings.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20require%20a%20third-party%20account%3F\"><h3>Does the plugin require a third-party account?<\/h3><\/dt>\n<dd><p>No. It works with your WordPress site and its email sending setup.<\/p><\/dd>\n<dt id=\"where%20are%20recovery%20codes%20managed%3F\"><h3>Where are recovery codes managed?<\/h3><\/dt>\n<dd><p>Recovery codes are available from the user profile area and are intended to be saved by the user for emergency access.<\/p><\/dd>\n<dt id=\"does%202fa%20affect%20rest%20api%20access%20or%20application%20passwords%3F\"><h3>Does 2FA affect REST API access or application passwords?<\/h3><\/dt>\n<dd><p>No. WordPress application passwords used for REST API access bypass the OTP flow by design. 2FA applies only to interactive browser-based logins via wp-login.php.<\/p><\/dd>\n<dt id=\"does%202fa%20work%20with%20xml-rpc%3F\"><h3>Does 2FA work with XML-RPC?<\/h3><\/dt>\n<dd><p>XML-RPC logins for accounts that have 2FA enabled will be blocked with a clear error message. This is intentional \u2014 XML-RPC cannot complete an OTP challenge. If you rely on XML-RPC for a specific integration, either exclude that user from 2FA targeting or switch to application passwords, which are fully supported.<\/p><\/dd>\n<dt id=\"my%20site%20is%20behind%20cloudflare%20or%20a%20load%20balancer%20%E2%80%94%20will%20rate%20limiting%20work%20correctly%3F\"><h3>My site is behind Cloudflare or a load balancer \u2014 will rate limiting work correctly?<\/h3><\/dt>\n<dd><p>By default the plugin reads <code>REMOTE_ADDR<\/code> for IP-based rate limiting, which may be the proxy's IP rather than the real visitor's. Use the <code>la2fa_get_client_ip<\/code> filter (see Developer notes in the Description tab) to supply the correct IP for your hosting environment.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2<\/h4>\n\n<ul>\n<li>Security: 2FA OTP challenge is now correctly skipped for REST API requests authenticated via WordPress application passwords, preventing broken API integrations.<\/li>\n<li>Security: XML-RPC login attempts for 2FA-protected accounts now return a clear WP_Error instead of issuing a silent broken redirect.<\/li>\n<li>Fix: Recovery code setup redirect now correctly passes the user to their original destination after saving codes (\"Continue\" button works as expected).<\/li>\n<li>Improvement: Debug log file is now automatically rotated when it exceeds 5 MB, preventing unbounded disk usage on busy sites.<\/li>\n<li>Improvement: Added <code>la2fa_get_client_ip<\/code> filter to allow sites behind reverse proxies (Cloudflare, load balancers) to supply the correct visitor IP for rate limiting.<\/li>\n<\/ul>\n\n<h4>1.1<\/h4>\n\n<ul>\n<li>Minor code optimizations.<\/li>\n<\/ul>\n\n<h4>1.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<li>Improved settings handling and login flow stability<\/li>\n<li>Refined admin UI and general plugin behavior<\/li>\n<\/ul>","raw_excerpt":"Add secure email-based 2FA authentication to WordPress logins with OTP verification, recovery codes, a grace period, and flexible user targeting.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/296332","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=296332"}],"author":[{"embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/gotechark"}],"wp:attachment":[{"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=296332"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=296332"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=296332"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=296332"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=296332"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/sna.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=296332"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}