Plugin Directory

Changeset 3757983


Ignore:
Timestamp:
10/21/2026 08:51:46 AM (4 weeks ago)
Author:
WPZOOM
Message:

Update to version 3.6.0 from GitHub

Location:
goodbye-captcha
Files:
4 added
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • goodbye-captcha/tags/3.6.0/assets/admin/styles/gdbc-admin.css

    r3754143 r3757983  
    19591959    }
    19601960}
     1961
     1962/* ------------------------------------------------------------------------
     1963 * Checkup screen
     1964 * A summary row, the "needs your attention" list, the protections grouped in
     1965 * plain tables with a status dot, and the plugin check. Same white panels,
     1966 * 1px #dcdcde borders and section titles as the Integrations screen.
     1967 * ---------------------------------------------------------------------- */
     1968
     1969.gdbc-chk
     1970{
     1971    max-width: 1080px;
     1972    margin-top: 12px;
     1973}
     1974
     1975.gdbc-chk-summary
     1976{
     1977    display: grid;
     1978    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
     1979    gap: 12px;
     1980}
     1981
     1982.gdbc-chk-summary__item
     1983{
     1984    padding: 14px 16px;
     1985    background: #fff;
     1986    border: 1px solid #dcdcde;
     1987    border-radius: 4px;
     1988}
     1989
     1990.gdbc-chk-summary__number
     1991{
     1992    display: block;
     1993    font-size: 26px;
     1994    font-weight: 600;
     1995    line-height: 1.2;
     1996    color: #1d2327;
     1997}
     1998
     1999.gdbc-chk-summary__number.is-warning
     2000{
     2001    color: #996800;
     2002}
     2003
     2004.gdbc-chk-summary__label
     2005{
     2006    display: block;
     2007    margin-top: 2px;
     2008    color: #646970;
     2009}
     2010
     2011.gdbc-chk-section
     2012{
     2013    margin: 28px 0 0;
     2014}
     2015
     2016.gdbc-chk .gdbc-chk-section__title
     2017{
     2018    margin: 0 0 12px;
     2019    padding: 0 0 8px;
     2020    font-size: 14px;
     2021    font-weight: 600;
     2022    line-height: 1.4;
     2023    color: #1d2327;
     2024    border-bottom: 1px solid #dcdcde;
     2025}
     2026
     2027.gdbc-chk-dot
     2028{
     2029    display: inline-block;
     2030    flex: 0 0 8px;
     2031    width: 8px;
     2032    height: 8px;
     2033    border-radius: 50%;
     2034    background: #c3c4c7;
     2035}
     2036
     2037.gdbc-chk-dot.is-good    { background: #00a32a; }
     2038.gdbc-chk-dot.is-warning { background: #dba617; }
     2039.gdbc-chk-dot.is-bad     { background: #d63638; }
     2040.gdbc-chk-dot.is-notice  { background: #8c8f94; }
     2041.gdbc-chk-dot.is-off     { background: #c3c4c7; }
     2042
     2043.gdbc-chk-list
     2044{
     2045    margin: 0;
     2046    background: #fff;
     2047    border: 1px solid #dcdcde;
     2048    border-radius: 4px;
     2049}
     2050
     2051.gdbc-chk-list__item
     2052{
     2053    display: flex;
     2054    align-items: center;
     2055    gap: 12px;
     2056    margin: 0;
     2057    padding: 12px 16px;
     2058    border-top: 1px solid #f0f0f1;
     2059}
     2060
     2061.gdbc-chk-list__item:first-child
     2062{
     2063    border-top: 0;
     2064}
     2065
     2066.gdbc-chk-list__text
     2067{
     2068    flex: 1 1 auto;
     2069    min-width: 0;
     2070    color: #1d2327;
     2071}
     2072
     2073.gdbc-chk-list__item .button
     2074{
     2075    flex: 0 0 auto;
     2076}
     2077
     2078.gdbc-chk-table
     2079{
     2080    width: 100%;
     2081    border-collapse: collapse;
     2082    background: #fff;
     2083    border: 1px solid #dcdcde;
     2084    border-radius: 4px;
     2085}
     2086
     2087.gdbc-chk-table td
     2088{
     2089    padding: 12px 16px;
     2090    vertical-align: top;
     2091    border-top: 1px solid #f0f0f1;
     2092}
     2093
     2094.gdbc-chk-table tr:first-child td
     2095{
     2096    border-top: 0;
     2097}
     2098
     2099.gdbc-chk-table__status
     2100{
     2101    width: 120px;
     2102    white-space: nowrap;
     2103}
     2104
     2105.gdbc-chk-table__main strong
     2106{
     2107    color: #1d2327;
     2108}
     2109
     2110.gdbc-chk-table__main .gdbc-int-tag
     2111{
     2112    margin-left: 6px;
     2113    vertical-align: 1px;
     2114}
     2115
     2116.gdbc-chk-table__why
     2117{
     2118    display: block;
     2119    margin-top: 2px;
     2120    color: #646970;
     2121}
     2122
     2123.gdbc-chk-table__action
     2124{
     2125    width: 110px;
     2126    text-align: right;
     2127    white-space: nowrap;
     2128}
     2129
     2130.gdbc-chk-status
     2131{
     2132    display: inline-flex;
     2133    align-items: center;
     2134    gap: 8px;
     2135    color: #1d2327;
     2136}
     2137
     2138.gdbc-chk-plugins-bar
     2139{
     2140    display: flex;
     2141    flex-wrap: wrap;
     2142    align-items: center;
     2143    justify-content: space-between;
     2144    gap: 8px 16px;
     2145    margin: 0 0 12px;
     2146}
     2147
     2148.gdbc-chk .gdbc-chk-note
     2149{
     2150    flex: 1 1 400px;
     2151    margin: 0;
     2152    color: #646970;
     2153}
     2154
     2155.gdbc-chk-plugins td,
     2156.gdbc-chk-plugins th
     2157{
     2158    padding: 10px 16px;
     2159}
     2160
     2161.gdbc-chk-plugins .gdbc-chk-muted,
     2162.gdbc-chk-muted
     2163{
     2164    color: #646970;
     2165}
     2166
     2167.gdbc-chk-plugins td strong + .gdbc-chk-muted
     2168{
     2169    margin-left: 6px;
     2170    font-size: 12px;
     2171}
     2172
     2173@media screen and (max-width: 600px)
     2174{
     2175    .gdbc-chk-list__item
     2176    {
     2177        flex-wrap: wrap;
     2178    }
     2179
     2180    .gdbc-chk-table__status
     2181    {
     2182        width: auto;
     2183    }
     2184
     2185    .gdbc-chk-table td
     2186    {
     2187        display: block;
     2188        width: auto;
     2189        padding: 6px 16px;
     2190        text-align: left;
     2191        border-top: 0;
     2192    }
     2193
     2194    .gdbc-chk-table tr
     2195    {
     2196        display: block;
     2197        padding: 6px 0;
     2198        border-top: 1px solid #f0f0f1;
     2199    }
     2200
     2201    .gdbc-chk-table tr:first-child
     2202    {
     2203        border-top: 0;
     2204    }
     2205}
     2206
     2207.gdbc-chk-more
     2208{
     2209    margin-top: 12px;
     2210}
     2211
     2212.gdbc-chk-more summary
     2213{
     2214    margin-bottom: 12px;
     2215    color: var(--gdbc-accent, #2271b1);
     2216    cursor: pointer;
     2217}
     2218
     2219.gdbc-chk-plugins th:first-child,
     2220.gdbc-chk-plugins td:first-child
     2221{
     2222    width: 38%;
     2223}
     2224
     2225.gdbc-chk-plugins th:nth-child(2),
     2226.gdbc-chk-plugins td:nth-child(2)
     2227{
     2228    width: 22%;
     2229}
  • goodbye-captcha/tags/3.6.0/engine/GdbcSummaryReport.php

    r3756213 r3757983  
    428428         * Things on the site worth fixing, most important first.
    429429         *
    430          * @param bool $isLogging Whether blocked attempts are logged.
     430         * @param bool   $isLogging Whether blocked attempts are logged.
     431         * @param string $context   "report" or "checkup".
    431432         * @return array[] With Level ("warning" or "notice"), Text, Url and Button.
    432433         */
    433         public static function getChecks($isLogging = true)
     434        public static function getChecks($isLogging = true, $context = 'report')
    434435        {
    435436                $arrChecks = array();
    … …  
    518519                                'Url'    => GoodByeCaptcha::isNetworkActivated() ? network_admin_url('update-core.php') : admin_url('update-core.php'),
    519520                                'Button' => __('Update now', 'goodbye-captcha'),
     521                        );
     522                }
     523
     524                if(GdbcPluginHealth::isEnabled())
     525                        $arrChecks = array_merge($arrChecks, GdbcPluginHealth::getReportChecks($context));
     526
     527                $otherUpdates = self::countOtherPluginUpdates();
     528                if($otherUpdates > 0)
     529                {
     530                        // "Other" when the WPBruiser update above is listed too.
     531                        $updatesText = empty(self::getAvailableUpdates())
     532                                /* translators: %d: number of plugins. */
     533                                ? _n('%d plugin has an update waiting.', '%d plugins have updates waiting.', $otherUpdates, 'goodbye-captcha')
     534                                /* translators: %d: number of plugins. */
     535                                : _n('%d other plugin has an update waiting.', '%d other plugins have updates waiting.', $otherUpdates, 'goodbye-captcha');
     536
     537                        $arrChecks[] = array(
     538                                'Level'  => 'notice',
     539                                'Text'   => sprintf($updatesText, $otherUpdates),
     540                                'Url'    => GoodByeCaptcha::isNetworkActivated() ? network_admin_url('update-core.php') : admin_url('update-core.php'),
     541                                'Button' => __('See updates', 'goodbye-captcha'),
    520542                        );
    521543                }
    … …  
    595617
    596618                return null;
     619        }
     620
     621        /**
     622         * Plugins other than WPBruiser and WPBruiser Pro with an update waiting.
     623         *
     624         * @return int
     625         */
     626        private static function countOtherPluginUpdates()
     627        {
     628                $updates = get_site_transient('update_plugins');
     629                if(!is_object($updates) || empty($updates->response) || !is_array($updates->response))
     630                        return 0;
     631
     632                return count(array_diff_key($updates->response, array_flip(array(plugin_basename(GoodByeCaptcha::getMainFilePath()), 'wpbruiser-pro/wpbruiser-pro.php'))));
    597633        }
    598634
  • goodbye-captcha/tags/3.6.0/engine/GoodByeCaptchaAdmin.php

    r3754143 r3757983  
    118118                                // Contact Forms, Membership, eCommerce and Others screens in 3.3.0.
    119119                                new GdbcIntegrationsAdminPage(__('Integrations', 'goodbye-captcha'), __('Integrations', 'goodbye-captcha'), self::$PLUGIN_SLUG),
     120                                // Checkup: what needs attention, which protections are on, and the plugin check.
     121                                new GdbcCheckupAdminPage(__('Checkup', 'goodbye-captcha'), __('Security Checkup', 'goodbye-captcha'), self::$PLUGIN_SLUG),
    120122                                new GdbcNotificationsAdminPage(__('Notifications', 'goodbye-captcha'), __('Notifications Settings', 'goodbye-captcha'), self::$PLUGIN_SLUG),
    121123                                new GdbcReportsAdminPage(__('Reports', 'goodbye-captcha'), __('WPBruiser - Blocked Attempts', 'goodbye-captcha'), self::$PLUGIN_SLUG),
  • goodbye-captcha/tags/3.6.0/engine/admin/GdbcDashboardWidget.php

    r3756213 r3757983  
    5858                                        <?php esc_html_e('No forms are protected yet.', 'goodbye-captcha'); ?>
    5959                                        <a href="<?php echo esc_url($integrationsUrl); ?>"><?php esc_html_e('Choose what to protect', 'goodbye-captcha'); ?></a>
     60                                </p>
     61                        <?php endif; ?>
     62
     63                        <?php
     64                        $arrClosedPlugins = array();
     65                        foreach(GdbcPluginHealth::isEnabled() ? GdbcPluginHealth::getIssues() : array() as $arrPluginIssue)
     66                        {
     67                                GdbcPluginHealth::STATUS_CLOSED === $arrPluginIssue['Status'] ? $arrClosedPlugins[] = $arrPluginIssue['Name'] : null;
     68                        }
     69                        ?>
     70                        <?php if(!empty($arrClosedPlugins)) : ?>
     71                                <p class="gdbc-dash__warning">
     72                                        <?php
     73                                        echo esc_html(sprintf(
     74                                                /* translators: %s: list of plugin names. */
     75                                                _n('%s was closed on WordPress.org and no longer gets security fixes.', '%s were closed on WordPress.org and no longer get security fixes.', count($arrClosedPlugins), 'goodbye-captcha'),
     76                                                wp_sprintf_l('%l', $arrClosedPlugins)
     77                                        ));
     78                                        ?>
     79                                        <a href="<?php echo esc_url(GdbcSummaryReport::getAdminPageUrl('checkup') . '#gdbc-chk-plugins'); ?>"><?php esc_html_e('See details', 'goodbye-captcha'); ?></a>
    6080                                </p>
    6181                        <?php endif; ?>
    … …  
    126146         * @return bool
    127147         */
    128         private static function isAnythingProtected()
     148        public static function isAnythingProtected()
    129149        {
    130150                foreach(array_keys(GdbcModulesController::getRegisteredModules()) as $moduleName)
  • goodbye-captcha/tags/3.6.0/goodbye-captcha.php

    r3756213 r3757983  
    1111 * Plugin URI: https://www.wpzoom.com/plugins/wpbruiser/
    1212 * Description: Security and anti-spam without CAPTCHA. Stops spam bots on your forms, limits login attempts and hardens WordPress, with an invisible check and no third-party service.
    13  * Version: 3.5.0
     13 * Version: 3.6.0
    1414 * Requires at least: 6.5
    1515 * Requires PHP: 7.4
    … …  
    3030        {
    3131               
    32                 CONST PLUGIN_VERSION    = '3.5.0';
     32                CONST PLUGIN_VERSION    = '3.6.0';
    3333                // PLUGIN_SLUG is also the prefix for option keys and admin menu slugs, so it
    3434                // must keep its historical value or existing installs lose their settings.
    … …  
    6464                        'GdbcSecurityAdminPage'       => '/engine/admin/pages/GdbcSecurityAdminPage.php',
    6565                        'GdbcReportsAdminPage'        => '/engine/admin/pages/GdbcReportsAdminPage.php',
     66                        'GdbcCheckupAdminPage'        => '/engine/admin/pages/GdbcCheckupAdminPage.php',
    6667                        'GdbcWelcomeAdminPage'        => '/engine/admin/pages/GdbcWelcomeAdminPage.php',
    6768                        'GdbcAdminNotice'             => '/engine/admin/GdbcAdminNotice.php',
    … …  
    7374                        'GdbcNotificationsController' => '/engine/GdbcNotificationsController.php',
    7475                        'GdbcSummaryReport'           => '/engine/GdbcSummaryReport.php',
     76                        'GdbcPluginHealth'            => '/engine/GdbcPluginHealth.php',
    7577                        'GdbcLogsCleanerTask'         => '/engine/tasks/GdbcLogsCleanerTask.php',
    7678                        'GdbcTaskScheduler'           => '/engine/GdbcTaskScheduler.php',
    … …  
    102104                        // The security report email, sent from a daily WP-Cron check.
    103105                        GdbcSummaryReport::init();
     106
     107                        // Weekly check of installed plugins against the WordPress.org directory.
     108                        GdbcPluginHealth::init();
    104109
    105110                        if (MchGdbcWpUtils::isAjaxRequest()) {
  • goodbye-captcha/tags/3.6.0/readme.txt

    r3756213 r3757983  
    55Requires PHP: 7.4
    66Tested up to: 7.1
    7 Stable tag: 3.5.0
     7Stable tag: 3.6.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
    … …  
    7575* A Dashboard widget with blocked attempts for the last day, week and month, and the forms bots target most
    7676* A weekly or monthly security report by email: what was blocked, the usernames bots tried, and anything that needs your attention
     77* A weekly check of your plugins against WordPress.org, with a warning for any that were closed (often for a security issue) or abandoned, on the Plugins screen and in Site Health
    7778* Old log entries are deleted automatically after the number of days you choose, or you can turn logging off
    7879
    … …  
    122123= External services =
    123124
    124 WPBruiser does not connect to any external service. It makes no remote API requests, collects no telemetry, runs no license or update checks of its own and loads no third-party fonts or scripts. All detection happens on your server, and the IP reputation and country data it uses ship inside the plugin.
     125All spam and bot detection happens on your server. WPBruiser collects no telemetry, runs no license or update checks of its own and loads no third-party fonts or scripts, and the IP reputation and country data it uses ship inside the plugin. Nothing about your visitors is ever sent anywhere.
     126
     127The one external service is the WordPress.org plugin directory, for the plugin check:
     128
     129* What is sent: the folder names of the plugins installed on your site (for example "contact-form-7"), one request per plugin, to api.wordpress.org. Plugins with an Update URI pointing somewhere other than WordPress.org are not sent. WordPress itself already sends this list to WordPress.org to check for updates.
     130* When: about once a week per plugin, from the daily WP-Cron event, and when you open WPBruiser's Checkup screen or Tools > Site Health.
     131* Why: to find plugins that WordPress.org has closed or that haven't been updated in over two years.
     132* You can turn it off with `add_filter( 'wpbruiser_plugin_health_enabled', '__return_false' );`.
     133* WordPress.org [privacy policy](https://wordpress.org/about/privacy/).
    125134
    126135= Support =
    … …  
    193202= Does it send data to any server? =
    194203
    195 No. See "External services" in the description. (The optional WPBruiser Pro add-on contacts wpzoom.com for its license and updates only.)
     204Nothing about your visitors, ever. The only outside request is the weekly plugin check, which sends the names of your installed plugins to the WordPress.org plugin directory, as WordPress itself does for updates. See "External services" in the description. (The optional WPBruiser Pro add-on contacts wpzoom.com for its license and updates, and, only if you set them up, Slack, Telegram or your webhook for the report.)
    196205
    197206= Does it replace a full security plugin? =
    … …  
    242251
    243252== Changelog ==
     253
     254= 3.6.0 =
     255- New: Checkup screen. One page with everything that needs your attention, every WPBruiser protection grouped by area with whether it's on and a link to turn it on, and the status of each installed plugin on WordPress.org.
     256- New: plugin check. Once a week WPBruiser looks up your installed plugins on the WordPress.org plugin directory and warns you about any that were closed (often for a security issue) or haven't been updated in over two years. Closed plugins no longer get security fixes, and even an inactive one can be a way in. You'll find them on the Checkup screen, under the plugin on the Plugins screen, in Site Health, on the Dashboard widget and in the security report. Premium and custom plugins that aren't in the directory are skipped.
     257- Improved: the security report also says when other plugins have updates waiting.
     258- New: a Preview email button next to "Send a test report", which opens the report in a new tab.
     259- For developers: new filters `wpbruiser_plugin_health_enabled`, to turn the plugin check off, and `wpbruiser_checkup_protections`, to add to the Checkup screen's list.
    244260
    245261= 3.5.0 =
  • goodbye-captcha/tags/3.6.0/uninstall.php

    r3756213 r3757983  
    2727                GdbcSummaryReport::unschedule();
    2828                GdbcSummaryReport::deleteState();
     29                GdbcPluginHealth::deleteCache();
    2930                GdbcBruteGuardian::deleteSiteFlags();
    3031
  • goodbye-captcha/trunk/assets/admin/styles/gdbc-admin.css

    r3754143 r3757983  
    19591959    }
    19601960}
     1961
     1962/* ------------------------------------------------------------------------
     1963 * Checkup screen
     1964 * A summary row, the "needs your attention" list, the protections grouped in
     1965 * plain tables with a status dot, and the plugin check. Same white panels,
     1966 * 1px #dcdcde borders and section titles as the Integrations screen.
     1967 * ---------------------------------------------------------------------- */
     1968
     1969.gdbc-chk
     1970{
     1971    max-width: 1080px;
     1972    margin-top: 12px;
     1973}
     1974
     1975.gdbc-chk-summary
     1976{
     1977    display: grid;
     1978    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
     1979    gap: 12px;
     1980}
     1981
     1982.gdbc-chk-summary__item
     1983{
     1984    padding: 14px 16px;
     1985    background: #fff;
     1986    border: 1px solid #dcdcde;
     1987    border-radius: 4px;
     1988}
     1989
     1990.gdbc-chk-summary__number
     1991{
     1992    display: block;
     1993    font-size: 26px;
     1994    font-weight: 600;
     1995    line-height: 1.2;
     1996    color: #1d2327;
     1997}
     1998
     1999.gdbc-chk-summary__number.is-warning
     2000{
     2001    color: #996800;
     2002}
     2003
     2004.gdbc-chk-summary__label
     2005{
     2006    display: block;
     2007    margin-top: 2px;
     2008    color: #646970;
     2009}
     2010
     2011.gdbc-chk-section
     2012{
     2013    margin: 28px 0 0;
     2014}
     2015
     2016.gdbc-chk .gdbc-chk-section__title
     2017{
     2018    margin: 0 0 12px;
     2019    padding: 0 0 8px;
     2020    font-size: 14px;
     2021    font-weight: 600;
     2022    line-height: 1.4;
     2023    color: #1d2327;
     2024    border-bottom: 1px solid #dcdcde;
     2025}
     2026
     2027.gdbc-chk-dot
     2028{
     2029    display: inline-block;
     2030    flex: 0 0 8px;
     2031    width: 8px;
     2032    height: 8px;
     2033    border-radius: 50%;
     2034    background: #c3c4c7;
     2035}
     2036
     2037.gdbc-chk-dot.is-good    { background: #00a32a; }
     2038.gdbc-chk-dot.is-warning { background: #dba617; }
     2039.gdbc-chk-dot.is-bad     { background: #d63638; }
     2040.gdbc-chk-dot.is-notice  { background: #8c8f94; }
     2041.gdbc-chk-dot.is-off     { background: #c3c4c7; }
     2042
     2043.gdbc-chk-list
     2044{
     2045    margin: 0;
     2046    background: #fff;
     2047    border: 1px solid #dcdcde;
     2048    border-radius: 4px;
     2049}
     2050
     2051.gdbc-chk-list__item
     2052{
     2053    display: flex;
     2054    align-items: center;
     2055    gap: 12px;
     2056    margin: 0;
     2057    padding: 12px 16px;
     2058    border-top: 1px solid #f0f0f1;
     2059}
     2060
     2061.gdbc-chk-list__item:first-child
     2062{
     2063    border-top: 0;
     2064}
     2065
     2066.gdbc-chk-list__text
     2067{
     2068    flex: 1 1 auto;
     2069    min-width: 0;
     2070    color: #1d2327;
     2071}
     2072
     2073.gdbc-chk-list__item .button
     2074{
     2075    flex: 0 0 auto;
     2076}
     2077
     2078.gdbc-chk-table
     2079{
     2080    width: 100%;
     2081    border-collapse: collapse;
     2082    background: #fff;
     2083    border: 1px solid #dcdcde;
     2084    border-radius: 4px;
     2085}
     2086
     2087.gdbc-chk-table td
     2088{
     2089    padding: 12px 16px;
     2090    vertical-align: top;
     2091    border-top: 1px solid #f0f0f1;
     2092}
     2093
     2094.gdbc-chk-table tr:first-child td
     2095{
     2096    border-top: 0;
     2097}
     2098
     2099.gdbc-chk-table__status
     2100{
     2101    width: 120px;
     2102    white-space: nowrap;
     2103}
     2104
     2105.gdbc-chk-table__main strong
     2106{
     2107    color: #1d2327;
     2108}
     2109
     2110.gdbc-chk-table__main .gdbc-int-tag
     2111{
     2112    margin-left: 6px;
     2113    vertical-align: 1px;
     2114}
     2115
     2116.gdbc-chk-table__why
     2117{
     2118    display: block;
     2119    margin-top: 2px;
     2120    color: #646970;
     2121}
     2122
     2123.gdbc-chk-table__action
     2124{
     2125    width: 110px;
     2126    text-align: right;
     2127    white-space: nowrap;
     2128}
     2129
     2130.gdbc-chk-status
     2131{
     2132    display: inline-flex;
     2133    align-items: center;
     2134    gap: 8px;
     2135    color: #1d2327;
     2136}
     2137
     2138.gdbc-chk-plugins-bar
     2139{
     2140    display: flex;
     2141    flex-wrap: wrap;
     2142    align-items: center;
     2143    justify-content: space-between;
     2144    gap: 8px 16px;
     2145    margin: 0 0 12px;
     2146}
     2147
     2148.gdbc-chk .gdbc-chk-note
     2149{
     2150    flex: 1 1 400px;
     2151    margin: 0;
     2152    color: #646970;
     2153}
     2154
     2155.gdbc-chk-plugins td,
     2156.gdbc-chk-plugins th
     2157{
     2158    padding: 10px 16px;
     2159}
     2160
     2161.gdbc-chk-plugins .gdbc-chk-muted,
     2162.gdbc-chk-muted
     2163{
     2164    color: #646970;
     2165}
     2166
     2167.gdbc-chk-plugins td strong + .gdbc-chk-muted
     2168{
     2169    margin-left: 6px;
     2170    font-size: 12px;
     2171}
     2172
     2173@media screen and (max-width: 600px)
     2174{
     2175    .gdbc-chk-list__item
     2176    {
     2177        flex-wrap: wrap;
     2178    }
     2179
     2180    .gdbc-chk-table__status
     2181    {
     2182        width: auto;
     2183    }
     2184
     2185    .gdbc-chk-table td
     2186    {
     2187        display: block;
     2188        width: auto;
     2189        padding: 6px 16px;
     2190        text-align: left;
     2191        border-top: 0;
     2192    }
     2193
     2194    .gdbc-chk-table tr
     2195    {
     2196        display: block;
     2197        padding: 6px 0;
     2198        border-top: 1px solid #f0f0f1;
     2199    }
     2200
     2201    .gdbc-chk-table tr:first-child
     2202    {
     2203        border-top: 0;
     2204    }
     2205}
     2206
     2207.gdbc-chk-more
     2208{
     2209    margin-top: 12px;
     2210}
     2211
     2212.gdbc-chk-more summary
     2213{
     2214    margin-bottom: 12px;
     2215    color: var(--gdbc-accent, #2271b1);
     2216    cursor: pointer;
     2217}
     2218
     2219.gdbc-chk-plugins th:first-child,
     2220.gdbc-chk-plugins td:first-child
     2221{
     2222    width: 38%;
     2223}
     2224
     2225.gdbc-chk-plugins th:nth-child(2),
     2226.gdbc-chk-plugins td:nth-child(2)
     2227{
     2228    width: 22%;
     2229}
  • goodbye-captcha/trunk/engine/GdbcSummaryReport.php

    r3756213 r3757983  
    428428         * Things on the site worth fixing, most important first.
    429429         *
    430          * @param bool $isLogging Whether blocked attempts are logged.
     430         * @param bool   $isLogging Whether blocked attempts are logged.
     431         * @param string $context   "report" or "checkup".
    431432         * @return array[] With Level ("warning" or "notice"), Text, Url and Button.
    432433         */
    433         public static function getChecks($isLogging = true)
     434        public static function getChecks($isLogging = true, $context = 'report')
    434435        {
    435436                $arrChecks = array();
    … …  
    518519                                'Url'    => GoodByeCaptcha::isNetworkActivated() ? network_admin_url('update-core.php') : admin_url('update-core.php'),
    519520                                'Button' => __('Update now', 'goodbye-captcha'),
     521                        );
     522                }
     523
     524                if(GdbcPluginHealth::isEnabled())
     525                        $arrChecks = array_merge($arrChecks, GdbcPluginHealth::getReportChecks($context));
     526
     527                $otherUpdates = self::countOtherPluginUpdates();
     528                if($otherUpdates > 0)
     529                {
     530                        // "Other" when the WPBruiser update above is listed too.
     531                        $updatesText = empty(self::getAvailableUpdates())
     532                                /* translators: %d: number of plugins. */
     533                                ? _n('%d plugin has an update waiting.', '%d plugins have updates waiting.', $otherUpdates, 'goodbye-captcha')
     534                                /* translators: %d: number of plugins. */
     535                                : _n('%d other plugin has an update waiting.', '%d other plugins have updates waiting.', $otherUpdates, 'goodbye-captcha');
     536
     537                        $arrChecks[] = array(
     538                                'Level'  => 'notice',
     539                                'Text'   => sprintf($updatesText, $otherUpdates),
     540                                'Url'    => GoodByeCaptcha::isNetworkActivated() ? network_admin_url('update-core.php') : admin_url('update-core.php'),
     541                                'Button' => __('See updates', 'goodbye-captcha'),
    520542                        );
    521543                }
    … …  
    595617
    596618                return null;
     619        }
     620
     621        /**
     622         * Plugins other than WPBruiser and WPBruiser Pro with an update waiting.
     623         *
     624         * @return int
     625         */
     626        private static function countOtherPluginUpdates()
     627        {
     628                $updates = get_site_transient('update_plugins');
     629                if(!is_object($updates) || empty($updates->response) || !is_array($updates->response))
     630                        return 0;
     631
     632                return count(array_diff_key($updates->response, array_flip(array(plugin_basename(GoodByeCaptcha::getMainFilePath()), 'wpbruiser-pro/wpbruiser-pro.php'))));
    597633        }
    598634
  • goodbye-captcha/trunk/engine/GoodByeCaptchaAdmin.php

    r3754143 r3757983  
    118118                                // Contact Forms, Membership, eCommerce and Others screens in 3.3.0.
    119119                                new GdbcIntegrationsAdminPage(__('Integrations', 'goodbye-captcha'), __('Integrations', 'goodbye-captcha'), self::$PLUGIN_SLUG),
     120                                // Checkup: what needs attention, which protections are on, and the plugin check.
     121                                new GdbcCheckupAdminPage(__('Checkup', 'goodbye-captcha'), __('Security Checkup', 'goodbye-captcha'), self::$PLUGIN_SLUG),
    120122                                new GdbcNotificationsAdminPage(__('Notifications', 'goodbye-captcha'), __('Notifications Settings', 'goodbye-captcha'), self::$PLUGIN_SLUG),
    121123                                new GdbcReportsAdminPage(__('Reports', 'goodbye-captcha'), __('WPBruiser - Blocked Attempts', 'goodbye-captcha'), self::$PLUGIN_SLUG),
  • goodbye-captcha/trunk/engine/admin/GdbcDashboardWidget.php

    r3756213 r3757983  
    5858                                        <?php esc_html_e('No forms are protected yet.', 'goodbye-captcha'); ?>
    5959                                        <a href="<?php echo esc_url($integrationsUrl); ?>"><?php esc_html_e('Choose what to protect', 'goodbye-captcha'); ?></a>
     60                                </p>
     61                        <?php endif; ?>
     62
     63                        <?php
     64                        $arrClosedPlugins = array();
     65                        foreach(GdbcPluginHealth::isEnabled() ? GdbcPluginHealth::getIssues() : array() as $arrPluginIssue)
     66                        {
     67                                GdbcPluginHealth::STATUS_CLOSED === $arrPluginIssue['Status'] ? $arrClosedPlugins[] = $arrPluginIssue['Name'] : null;
     68                        }
     69                        ?>
     70                        <?php if(!empty($arrClosedPlugins)) : ?>
     71                                <p class="gdbc-dash__warning">
     72                                        <?php
     73                                        echo esc_html(sprintf(
     74                                                /* translators: %s: list of plugin names. */
     75                                                _n('%s was closed on WordPress.org and no longer gets security fixes.', '%s were closed on WordPress.org and no longer get security fixes.', count($arrClosedPlugins), 'goodbye-captcha'),
     76                                                wp_sprintf_l('%l', $arrClosedPlugins)
     77                                        ));
     78                                        ?>
     79                                        <a href="<?php echo esc_url(GdbcSummaryReport::getAdminPageUrl('checkup') . '#gdbc-chk-plugins'); ?>"><?php esc_html_e('See details', 'goodbye-captcha'); ?></a>
    6080                                </p>
    6181                        <?php endif; ?>
    … …  
    126146         * @return bool
    127147         */
    128         private static function isAnythingProtected()
     148        public static function isAnythingProtected()
    129149        {
    130150                foreach(array_keys(GdbcModulesController::getRegisteredModules()) as $moduleName)
  • goodbye-captcha/trunk/goodbye-captcha.php

    r3756213 r3757983  
    1111 * Plugin URI: https://www.wpzoom.com/plugins/wpbruiser/
    1212 * Description: Security and anti-spam without CAPTCHA. Stops spam bots on your forms, limits login attempts and hardens WordPress, with an invisible check and no third-party service.
    13  * Version: 3.5.0
     13 * Version: 3.6.0
    1414 * Requires at least: 6.5
    1515 * Requires PHP: 7.4
    … …  
    3030        {
    3131               
    32                 CONST PLUGIN_VERSION    = '3.5.0';
     32                CONST PLUGIN_VERSION    = '3.6.0';
    3333                // PLUGIN_SLUG is also the prefix for option keys and admin menu slugs, so it
    3434                // must keep its historical value or existing installs lose their settings.
    … …  
    6464                        'GdbcSecurityAdminPage'       => '/engine/admin/pages/GdbcSecurityAdminPage.php',
    6565                        'GdbcReportsAdminPage'        => '/engine/admin/pages/GdbcReportsAdminPage.php',
     66                        'GdbcCheckupAdminPage'        => '/engine/admin/pages/GdbcCheckupAdminPage.php',
    6667                        'GdbcWelcomeAdminPage'        => '/engine/admin/pages/GdbcWelcomeAdminPage.php',
    6768                        'GdbcAdminNotice'             => '/engine/admin/GdbcAdminNotice.php',
    … …  
    7374                        'GdbcNotificationsController' => '/engine/GdbcNotificationsController.php',
    7475                        'GdbcSummaryReport'           => '/engine/GdbcSummaryReport.php',
     76                        'GdbcPluginHealth'            => '/engine/GdbcPluginHealth.php',
    7577                        'GdbcLogsCleanerTask'         => '/engine/tasks/GdbcLogsCleanerTask.php',
    7678                        'GdbcTaskScheduler'           => '/engine/GdbcTaskScheduler.php',
    … …  
    102104                        // The security report email, sent from a daily WP-Cron check.
    103105                        GdbcSummaryReport::init();
     106
     107                        // Weekly check of installed plugins against the WordPress.org directory.
     108                        GdbcPluginHealth::init();
    104109
    105110                        if (MchGdbcWpUtils::isAjaxRequest()) {
  • goodbye-captcha/trunk/readme.txt

    r3756213 r3757983  
    55Requires PHP: 7.4
    66Tested up to: 7.1
    7 Stable tag: 3.5.0
     7Stable tag: 3.6.0
    88License: GPLv2 or later
    99License URI: http://www.gnu.org/licenses/gpl-2.0.html
    … …  
    7575* A Dashboard widget with blocked attempts for the last day, week and month, and the forms bots target most
    7676* A weekly or monthly security report by email: what was blocked, the usernames bots tried, and anything that needs your attention
     77* A weekly check of your plugins against WordPress.org, with a warning for any that were closed (often for a security issue) or abandoned, on the Plugins screen and in Site Health
    7778* Old log entries are deleted automatically after the number of days you choose, or you can turn logging off
    7879
    … …  
    122123= External services =
    123124
    124 WPBruiser does not connect to any external service. It makes no remote API requests, collects no telemetry, runs no license or update checks of its own and loads no third-party fonts or scripts. All detection happens on your server, and the IP reputation and country data it uses ship inside the plugin.
     125All spam and bot detection happens on your server. WPBruiser collects no telemetry, runs no license or update checks of its own and loads no third-party fonts or scripts, and the IP reputation and country data it uses ship inside the plugin. Nothing about your visitors is ever sent anywhere.
     126
     127The one external service is the WordPress.org plugin directory, for the plugin check:
     128
     129* What is sent: the folder names of the plugins installed on your site (for example "contact-form-7"), one request per plugin, to api.wordpress.org. Plugins with an Update URI pointing somewhere other than WordPress.org are not sent. WordPress itself already sends this list to WordPress.org to check for updates.
     130* When: about once a week per plugin, from the daily WP-Cron event, and when you open WPBruiser's Checkup screen or Tools > Site Health.
     131* Why: to find plugins that WordPress.org has closed or that haven't been updated in over two years.
     132* You can turn it off with `add_filter( 'wpbruiser_plugin_health_enabled', '__return_false' );`.
     133* WordPress.org [privacy policy](https://wordpress.org/about/privacy/).
    125134
    126135= Support =
    … …  
    193202= Does it send data to any server? =
    194203
    195 No. See "External services" in the description. (The optional WPBruiser Pro add-on contacts wpzoom.com for its license and updates only.)
     204Nothing about your visitors, ever. The only outside request is the weekly plugin check, which sends the names of your installed plugins to the WordPress.org plugin directory, as WordPress itself does for updates. See "External services" in the description. (The optional WPBruiser Pro add-on contacts wpzoom.com for its license and updates, and, only if you set them up, Slack, Telegram or your webhook for the report.)
    196205
    197206= Does it replace a full security plugin? =
    … …  
    242251
    243252== Changelog ==
     253
     254= 3.6.0 =
     255- New: Checkup screen. One page with everything that needs your attention, every WPBruiser protection grouped by area with whether it's on and a link to turn it on, and the status of each installed plugin on WordPress.org.
     256- New: plugin check. Once a week WPBruiser looks up your installed plugins on the WordPress.org plugin directory and warns you about any that were closed (often for a security issue) or haven't been updated in over two years. Closed plugins no longer get security fixes, and even an inactive one can be a way in. You'll find them on the Checkup screen, under the plugin on the Plugins screen, in Site Health, on the Dashboard widget and in the security report. Premium and custom plugins that aren't in the directory are skipped.
     257- Improved: the security report also says when other plugins have updates waiting.
     258- New: a Preview email button next to "Send a test report", which opens the report in a new tab.
     259- For developers: new filters `wpbruiser_plugin_health_enabled`, to turn the plugin check off, and `wpbruiser_checkup_protections`, to add to the Checkup screen's list.
    244260
    245261= 3.5.0 =
  • goodbye-captcha/trunk/uninstall.php

    r3756213 r3757983  
    2727                GdbcSummaryReport::unschedule();
    2828                GdbcSummaryReport::deleteState();
     29                GdbcPluginHealth::deleteCache();
    2930                GdbcBruteGuardian::deleteSiteFlags();
    3031
Note: See TracChangeset for help on using the changeset viewer.