v1.6.6
This commit is contained in:
parent
c72a96e2a0
commit
f9c073a582
5 changed files with 93 additions and 17 deletions
|
|
@ -1,5 +1,25 @@
|
||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
|
= 1.6.6 =
|
||||||
|
|
||||||
|
_Release date: 2026-09-17_
|
||||||
|
|
||||||
|
**Added**
|
||||||
|
|
||||||
|
* Forced-enrollment warning on the profile 2FA section: when a user's role enforces 2FA but they have no verification method configured yet, the 2FA section of their profile (wp-admin and the frontend shortcode) opens with a warning notice asking them to activate at least one method. While a grace period is active, the notice appends the remaining days.
|
||||||
|
|
||||||
|
**Compatibility**
|
||||||
|
|
||||||
|
* WordPress: 5.6 – 7.1
|
||||||
|
* PHP: 8.0 – 8.5
|
||||||
|
|
||||||
|
**Tests**
|
||||||
|
|
||||||
|
* PHP Coding Standards: PHP_CodeSniffer 3.13.6 / WPCS 3.4.1 — 0 errors
|
||||||
|
* PHPStan: level 9 — 0 errors
|
||||||
|
* PHPCompatibility: 8.0–8.5 — 0 issues
|
||||||
|
* PHPUnit: 9.6.36 — 93 tests, 189 assertions
|
||||||
|
|
||||||
= 1.6.5 =
|
= 1.6.5 =
|
||||||
|
|
||||||
_Release date: 2026-09-17_
|
_Release date: 2026-09-17_
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,13 @@ class Profile_Settings {
|
||||||
*/
|
*/
|
||||||
private Trusted_Devices $trusted_devices;
|
private Trusted_Devices $trusted_devices;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Grace period manager.
|
||||||
|
*
|
||||||
|
* @var Grace_Period
|
||||||
|
*/
|
||||||
|
private Grace_Period $grace_period;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the post-save redirect should focus the 2FA section.
|
* Whether the post-save redirect should focus the 2FA section.
|
||||||
*
|
*
|
||||||
|
|
@ -113,6 +120,7 @@ class Profile_Settings {
|
||||||
$this->otp_manager = new OTP_Manager();
|
$this->otp_manager = new OTP_Manager();
|
||||||
$this->recovery_codes = new Recovery_Codes();
|
$this->recovery_codes = new Recovery_Codes();
|
||||||
$this->trusted_devices = new Trusted_Devices();
|
$this->trusted_devices = new Trusted_Devices();
|
||||||
|
$this->grace_period = new Grace_Period();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -170,6 +178,57 @@ class Profile_Settings {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the forced-enrollment warning on the profile 2FA section.
|
||||||
|
*
|
||||||
|
* Shown when the user's role enforces 2FA but no verification method is
|
||||||
|
* configured yet, so the requirement is visible before the login flow
|
||||||
|
* (grace notice, setup wizard, or login block) kicks in. When a grace
|
||||||
|
* period is active, the number of remaining days is appended.
|
||||||
|
*
|
||||||
|
* @since 1.6.6
|
||||||
|
*
|
||||||
|
* @param \WP_User $user User whose profile section is being rendered.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function render_forced_enrollment_warning( \WP_User $user ): void {
|
||||||
|
$user_settings = $this->user_settings_repository->get_user_settings( $user->ID );
|
||||||
|
|
||||||
|
if ( empty( $this->config->get_required_methods_for_user( $user ) ) || ! empty( $user_settings['methods'] ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$grace_note = '';
|
||||||
|
$grace_days = $this->config->get_grace_period_days();
|
||||||
|
|
||||||
|
if ( $grace_days > 0 && $this->grace_period->is_active( $user, $grace_days ) ) {
|
||||||
|
$remaining = $this->grace_period->get_days_remaining( $user, $grace_days );
|
||||||
|
|
||||||
|
/* translators: %d: number of days remaining to complete the setup. */
|
||||||
|
$grace_note = sprintf(
|
||||||
|
_n(
|
||||||
|
'You have %d day left to complete the setup.',
|
||||||
|
'You have %d days left to complete the setup.',
|
||||||
|
$remaining,
|
||||||
|
'robotstxt-2fa'
|
||||||
|
),
|
||||||
|
$remaining
|
||||||
|
);
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="notice notice-warning inline robotstxt-2fa-forced-warning">
|
||||||
|
<p>
|
||||||
|
<strong><?php esc_html_e( 'Two-factor authentication is required for your account.', 'robotstxt-2fa' ); ?></strong>
|
||||||
|
<?php esc_html_e( 'You have not set up any verification method yet. Activate at least one method below to keep access to your account.', 'robotstxt-2fa' ); ?>
|
||||||
|
<?php if ( '' !== $grace_note ) : ?>
|
||||||
|
<em><?php echo esc_html( $grace_note ); ?></em>
|
||||||
|
<?php endif; ?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render profile settings UI.
|
* Render profile settings UI.
|
||||||
*
|
*
|
||||||
|
|
@ -313,6 +372,7 @@ class Profile_Settings {
|
||||||
}
|
}
|
||||||
?>
|
?>
|
||||||
<h2 id="<?php echo esc_attr( self::SECTION_ANCHOR ); ?>"><?php esc_html_e( 'Two-Factor Authentication', 'robotstxt-2fa' ); ?></h2>
|
<h2 id="<?php echo esc_attr( self::SECTION_ANCHOR ); ?>"><?php esc_html_e( 'Two-Factor Authentication', 'robotstxt-2fa' ); ?></h2>
|
||||||
|
<?php $this->render_forced_enrollment_warning( $user ); ?>
|
||||||
<?php wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD ); ?>
|
<?php wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD ); ?>
|
||||||
<table class="form-table" role="presentation">
|
<table class="form-table" role="presentation">
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
|
||||||
22
readme.txt
22
readme.txt
|
|
@ -4,7 +4,7 @@ Tags: security, two-factor authentication, login, otp
|
||||||
Requires at least: 5.6
|
Requires at least: 5.6
|
||||||
Tested up to: 7.0
|
Tested up to: 7.0
|
||||||
Requires PHP: 8.0
|
Requires PHP: 8.0
|
||||||
Stable tag: 1.6.5
|
Stable tag: 1.6.6
|
||||||
License: GPLv3 or later
|
License: GPLv3 or later
|
||||||
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
License URI: https://www.gnu.org/licenses/gpl-3.0.html
|
||||||
|
|
||||||
|
|
@ -59,6 +59,14 @@ Yes. Activate the plugin at the network level. Network administrators can set an
|
||||||
|
|
||||||
== Changelog ==
|
== Changelog ==
|
||||||
|
|
||||||
|
= 1.6.6 =
|
||||||
|
|
||||||
|
_Release date: 2026-09-17_
|
||||||
|
|
||||||
|
**Added**
|
||||||
|
|
||||||
|
* Forced-enrollment warning on the profile 2FA section: when a user's role enforces 2FA but they have no verification method configured yet, the 2FA section of their profile (wp-admin and the frontend shortcode) opens with a warning notice asking them to activate at least one method. While a grace period is active, the notice appends the remaining days.
|
||||||
|
|
||||||
= 1.6.5 =
|
= 1.6.5 =
|
||||||
|
|
||||||
_Release date: 2026-09-17_
|
_Release date: 2026-09-17_
|
||||||
|
|
@ -76,18 +84,6 @@ _Release date: 2026-09-11_
|
||||||
|
|
||||||
* Compatibility with Restrict Content Pro's "Hijack Login URL" option: RCP's `login_url` filter made every `wp_login_url()` call return a membership page, so the 2FA verification redirect landed on a restricted page where the verification form cannot render, and the visitor was bounced to the registration page. Verification-stage URLs are now built from the canonical `wp-login.php`, mirroring WordPress core's URL construction before the filterable output. The "Back to login" link keeps the site-configured login URL.
|
* Compatibility with Restrict Content Pro's "Hijack Login URL" option: RCP's `login_url` filter made every `wp_login_url()` call return a membership page, so the 2FA verification redirect landed on a restricted page where the verification form cannot render, and the visitor was bounced to the registration page. Verification-stage URLs are now built from the canonical `wp-login.php`, mirroring WordPress core's URL construction before the filterable output. The "Back to login" link keeps the site-configured login URL.
|
||||||
|
|
||||||
= 1.6.3 =
|
|
||||||
|
|
||||||
_Release date: 2026-08-24_
|
|
||||||
|
|
||||||
**Changed**
|
|
||||||
|
|
||||||
* Manager detection now uses the ecosystem presence constant (`ROBOTSTXT_MANAGER_NOTICED`, defined by Manager 1.6.2+) with a fallback to the plugin-list scan for older Manager versions.
|
|
||||||
|
|
||||||
**Fixed**
|
|
||||||
|
|
||||||
* Compatibility with the ALTCHA Spam Protection plugin: when "Protect login" was enabled, submitting the 2FA verification code failed with "[ALTCHA] Sorry, your request could not be processed.". The ALTCHA interceptor is now disabled while the verification screen is shown; the first login step keeps its ALTCHA check.
|
|
||||||
|
|
||||||
= Previous versions =
|
= Previous versions =
|
||||||
|
|
||||||
For the full changelog see the [changelog](https://www.robotstxt.software/plugins/robotstxt-2fa/) page.
|
For the full changelog see the [changelog](https://www.robotstxt.software/plugins/robotstxt-2fa/) page.
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
* Plugin URI: https://www.robotstxt.software/plugins/robotstxt-2fa/
|
* Plugin URI: https://www.robotstxt.software/plugins/robotstxt-2fa/
|
||||||
* Update URI: https://www.robotstxt.software/plugins/robotstxt-2fa/
|
* Update URI: https://www.robotstxt.software/plugins/robotstxt-2fa/
|
||||||
* Description: Adds two-factor authentication to the WordPress login flow.
|
* Description: Adds two-factor authentication to the WordPress login flow.
|
||||||
* Version: 1.6.5
|
* Version: 1.6.6
|
||||||
* Author: ROBOTSTXT
|
* Author: ROBOTSTXT
|
||||||
* Author URI: https://www.robotstxt.software/
|
* Author URI: https://www.robotstxt.software/
|
||||||
* Text Domain: robotstxt-2fa
|
* Text Domain: robotstxt-2fa
|
||||||
|
|
@ -25,7 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! defined( 'ROBOTSTXT_2FA_VERSION' ) ) {
|
if ( ! defined( 'ROBOTSTXT_2FA_VERSION' ) ) {
|
||||||
define( 'ROBOTSTXT_2FA_VERSION', '1.6.5' );
|
define( 'ROBOTSTXT_2FA_VERSION', '1.6.6' );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! defined( 'ROBOTSTXT_2FA_FILE' ) ) {
|
if ( ! defined( 'ROBOTSTXT_2FA_FILE' ) ) {
|
||||||
|
|
|
||||||
4
vendor/composer/installed.php
vendored
4
vendor/composer/installed.php
vendored
|
|
@ -3,7 +3,7 @@
|
||||||
'name' => 'robotstxt/robotstxt-2fa',
|
'name' => 'robotstxt/robotstxt-2fa',
|
||||||
'pretty_version' => 'dev-main',
|
'pretty_version' => 'dev-main',
|
||||||
'version' => 'dev-main',
|
'version' => 'dev-main',
|
||||||
'reference' => 'ed617610896f05f9dc90a3b0f53b19c9dacd59a5',
|
'reference' => 'f1d493aefc9da797d99b3b635736b6c627166ddf',
|
||||||
'type' => 'wordpress-plugin',
|
'type' => 'wordpress-plugin',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
'robotstxt/robotstxt-2fa' => array(
|
'robotstxt/robotstxt-2fa' => array(
|
||||||
'pretty_version' => 'dev-main',
|
'pretty_version' => 'dev-main',
|
||||||
'version' => 'dev-main',
|
'version' => 'dev-main',
|
||||||
'reference' => 'ed617610896f05f9dc90a3b0f53b19c9dacd59a5',
|
'reference' => 'f1d493aefc9da797d99b3b635736b6c627166ddf',
|
||||||
'type' => 'wordpress-plugin',
|
'type' => 'wordpress-plugin',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue