Skip to content

Commit 9d24967

Browse files
authored
Merge pull request #907 from WordPress/906-backup-code-early-notice
#906: add early notice for soon exhausting recovery codes
2 parents 0f357fe + 404c241 commit 9d24967

1 file changed

Lines changed: 71 additions & 21 deletions

File tree

providers/class-two-factor-backup-codes.php

Lines changed: 71 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ class Two_Factor_Backup_Codes extends Two_Factor_Provider {
2828
*/
2929
const NUMBER_OF_CODES = 10;
3030

31+
/**
32+
* The default number of remaining codes at or below which the user is
33+
* warned to regenerate, before they run out entirely.
34+
*
35+
* @type int
36+
*/
37+
const LOW_CODES_THRESHOLD = 2;
38+
3139
/**
3240
* Class constructor.
3341
*
@@ -97,7 +105,7 @@ public function register_rest_routes() {
97105
}
98106

99107
/**
100-
* Displays an admin notice when backup codes have run out.
108+
* Displays an admin notice when backup codes have run out, or are running low.
101109
*
102110
* @since 0.1-dev
103111
*
@@ -111,28 +119,70 @@ public function admin_notices() {
111119
return;
112120
}
113121

114-
// Return if we are not out of codes.
115-
if ( $this->is_available_for_user( $user ) ) {
122+
$count = self::codes_remaining_for_user( $user );
123+
$regenerate_url = esc_url( get_edit_user_link( $user->ID ) . '#two-factor-backup-codes' );
124+
125+
// Out of codes: show an error and bail.
126+
if ( 0 === $count ) {
127+
?>
128+
<div class="error">
129+
<p>
130+
<span>
131+
<?php
132+
echo wp_kses(
133+
sprintf(
134+
/* translators: %s: URL for code regeneration */
135+
__( 'Two-Factor: You are out of recovery codes and need to <a href="%s">regenerate!</a>', 'two-factor' ),
136+
$regenerate_url
137+
),
138+
array( 'a' => array( 'href' => true ) )
139+
);
140+
?>
141+
</span>
142+
</p>
143+
</div>
144+
<?php
116145
return;
117146
}
118-
?>
119-
<div class="error">
120-
<p>
121-
<span>
122-
<?php
123-
echo wp_kses(
124-
sprintf(
125-
/* translators: %s: URL for code regeneration */
126-
__( 'Two-Factor: You are out of recovery codes and need to <a href="%s">regenerate!</a>', 'two-factor' ),
127-
esc_url( get_edit_user_link( $user->ID ) . '#two-factor-backup-codes' )
128-
),
129-
array( 'a' => array( 'href' => true ) )
130-
);
131-
?>
132-
</span>
133-
</p>
134-
</div>
135-
<?php
147+
148+
/**
149+
* Filters the number of remaining recovery codes at or below which the
150+
* user is warned to regenerate, before they run out entirely.
151+
*
152+
* @since 0.17.0
153+
*
154+
* @param int $threshold Number of remaining codes that triggers the warning. Default 2.
155+
* @param WP_User $user User object.
156+
*/
157+
$threshold = (int) apply_filters( 'two_factor_backup_codes_low_threshold', self::LOW_CODES_THRESHOLD, $user );
158+
159+
// Running low: warn the user before they hit zero.
160+
if ( $count <= $threshold ) {
161+
?>
162+
<div class="notice notice-warning">
163+
<p>
164+
<span>
165+
<?php
166+
echo wp_kses(
167+
sprintf(
168+
/* translators: 1: number of recovery codes remaining, 2: URL for code regeneration */
169+
_n(
170+
'Two-Factor: You only have %1$s recovery code left. <a href="%2$s">Regenerate your codes</a> now before you run out.',
171+
'Two-Factor: You only have %1$s recovery codes left. <a href="%2$s">Regenerate your codes</a> now before you run out.',
172+
$count,
173+
'two-factor'
174+
),
175+
number_format_i18n( $count ),
176+
$regenerate_url
177+
),
178+
array( 'a' => array( 'href' => true ) )
179+
);
180+
?>
181+
</span>
182+
</p>
183+
</div>
184+
<?php
185+
}
136186
}
137187

138188
/**

0 commit comments

Comments
 (0)