| @@ -790,8 +790,15 @@ | ||
| 790 | 790 | * addresses that receive the alerts is another, and nobody presses a button |
| 791 | 791 | * called "restore defaults" expecting that. Both the Standard preset and the |
| 792 | 792 | * two reset buttons leave these alone. |
| 793 | 793 | * |
| 794 | + * Read from outside the plugin: the third-party network plugin Vigilante | |
| 795 | + * Network Sync calls this from its 2.0.3 to decide what NOT to copy between | |
| 796 | + * the sites of a network, so a key it does not know about is preserved per | |
| 797 | + * site instead of overwritten. Adding keys here is safe and helps it; | |
| 798 | + * renaming or removing the method, or changing the shape of what it returns, | |
| 799 | + * silently changes what that plugin replicates across a whole network. | |
| 800 | + * | |
| 794 | 801 | * @since 2.9.8 |
| 795 | 802 | * |
| 796 | 803 | * @return array<string,string[]> |
| 797 | 804 | */ |
| @@ -855,8 +862,12 @@ | ||
| 855 | 862 | * rights must not be able to silence it by turning either one off. Closing |
| 856 | 863 | * the ignore list and the clear-results button in 2.11.8 left these two as |
| 857 | 864 | * the remaining routes; found by the audit of the admin surface. |
| 858 | 865 | * |
| 866 | + * Since 3.0.0 the self-check has no setting at all, so there is nothing to lock: Vigilant's own | |
| 867 | + * files are shared by every site, and on the main site the self-check is | |
| 868 | + * the one that reports a change to them for the whole network. | |
| 869 | + * | |
| 859 | 870 | * On a subsite all of them only act on that site, so they stay editable |
| 860 | 871 | * there (get_locked_file_settings() adds this set only when owns_shared_files()). |
| 861 | 872 | * |
| 862 | 873 | * Until 2.11.6 an administrator of the main site without network rights |
| @@ -977,10 +988,12 @@ | ||
| 977 | 988 | * emailed code. So the question is asked per account, not per site. |
| 978 | 989 | * |
| 979 | 990 | * The order is what keeps it closed at both ends: |
| 980 | 991 | * |
| 981 | - * 1. An enrolment already made wins. It is the strongest factor the account | |
| 982 | - * has and it is ready to use, wherever in the network it was set up. | |
| 992 | + * 1. An enrolment already made wins while some site asking for a second | |
| 993 | + * factor asks for an authenticator app. It is the strongest factor the | |
| 994 | + * account has and it is ready to use, wherever in the network it was set | |
| 995 | + * up. | |
| 983 | 996 | * 2. Otherwise, if any site asking for a second factor asks for email, email |
| 984 | 997 | * handles it. Email needs no enrolment, so it can never fall into the |
| 985 | 998 | * branch that lets a login through for lack of one. |
| 986 | 999 | * 3. Only when every site asking wants an authenticator app does TOTP handle |
| @@ -985,9 +998,17 @@ | ||
| 985 | 998 | * branch that lets a login through for lack of one. |
| 986 | 999 | * 3. Only when every site asking wants an authenticator app does TOTP handle |
| 987 | 1000 | * it, which is the case the grace period was written for. |
| 988 | 1001 | * |
| 1002 | + * The condition on the first step came in 2.11.11. Without it an enrolment | |
| 1003 | + * left from a time when the site asked for an app outranked the method the | |
| 1004 | + * site asks for now: a single site set to email asked those accounts for an | |
| 1005 | + * authenticator code, which 2.11.9 never did and which locks out whoever | |
| 1006 | + * removed the app after the switch. Dropping that enrolment opens nothing, | |
| 1007 | + * because the account then goes to email, which needs no enrolment. | |
| 1008 | + * | |
| 989 | 1009 | * @since 2.11.10 |
| 1010 | + * @since 2.11.11 An enrolment only wins while an authenticator app is asked for. | |
| 990 | 1011 | * |
| 991 | 1012 | * @param WP_User $user User being authenticated. |
| 992 | 1013 | * @param bool $enrolled Whether the account has a TOTP enrolment anywhere. |
| 993 | 1014 | * @return string 'email', 'totp', or '' when nothing asks. |
| @@ -998,9 +1019,9 @@ | ||
| 998 | 1019 | if ( ! $methods ) { |
| 999 | 1020 | return ''; |
| 1000 | 1021 | } |
| 1001 | 1022 | |
| 1002 | - if ( $enrolled ) { | |
| 1023 | + if ( $enrolled && in_array( 'totp', $methods, true ) ) { | |
| 1003 | 1024 | return 'totp'; |
| 1004 | 1025 | } |
| 1005 | 1026 | |
| 1006 | 1027 | return in_array( 'email', $methods, true ) ? 'email' : 'totp'; |
| @@ -1035,9 +1056,12 @@ | ||
| 1035 | 1056 | * yet can log in through any of them and the cookie is valid everywhere. |
| 1036 | 1057 | * Asking only the sites they belong to left the account with the most |
| 1037 | 1058 | * power in the network outside the policy, which is the bypass upside |
| 1038 | 1059 | * down. So for them every site of the network is consulted. There are |
| 1039 | - * few super administrators and this runs at login, not per request. | |
| 1060 | + * few super administrators. It does not only run at login, though, which | |
| 1061 | + * this note claimed until 2.11.11: the dashboard hooks of the TOTP class | |
| 1062 | + * ask it on every admin screen of every site of a network, at least once | |
| 1063 | + * per hook. | |
| 1040 | 1064 | */ |
| 1041 | 1065 | if ( is_super_admin( $user->ID ) ) { |
| 1042 | 1066 | $blog_ids = array_merge( $blog_ids, get_sites( array( 'fields' => 'ids', 'number' => 200 ) ) ); |
| 1043 | 1067 | } |