=== Registration Email Blocker === Contributors: altcreative Donate link: https://yookassa.ru/my/i/aVPRSGFZeJmV/l Tags: email, registration, spam, user-registration, email-validation Requires at least: 6.2 Tested up to: 7.1 Requires PHP: 8.0 Stable tag: 1.1.0 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Control which email domains may be used to register on your site and to change an existing account's email address. == Description == Registration Email Blocker decides which email domains are acceptable on your site. Run it as a blocklist to refuse the providers you name, or as an allowlist to accept only the ones you approve. The check is applied everywhere an address can be set, not only on the registration form: * the WordPress registration form * the profile screen and "Add New User" in wp-admin * the WordPress REST API * WooCommerce registration * the WooCommerce checkout, both the classic shortcode and the newer block based checkout * the "Account details" page of the WooCommerce My Account area Checking email changes matters as much as checking registration. If only the registration form is guarded, an account can be created with an accepted address and switched to any other one a minute later. That option is on by default and can be turned off. = What it does = * **Two modes.** Blocklist refuses the domains you list; allowlist accepts only the domains you list. Subdomains are matched in both directions, so listing `example.com` also covers `mail.example.com`. * **Two levels of strictness.** Refuse the address outright, or allow it and record the attempt. * **Internationalized domains.** Names such as `почта.рф` are converted to their punycode form when saved, so they match real addresses. Entries that are not valid domain names are reported back to you rather than silently dropped. * **Administrators are exempt by default**, so a mistake in a domain list cannot lock you out of your own site. * **Report on existing accounts.** See which accounts use a rejected domain, grouped by domain, and export the list as CSV. * **Batched notifications.** Ask affected users to change their address. Mail is sent in small batches with a progress bar and a stop button, and anyone notified recently is skipped, so a timeout cannot restart the run from the beginning. * **A log you can live with.** Attempts are recorded with a configurable level of detail, kept only as long as you choose, and trimmed automatically once a day. Repeated attempts from the same IP address within a minute are recorded once, so a bot cycling through addresses cannot inflate the table. * **Editable defaults.** Both domain lists ship pre-filled and can be changed freely; a button restores them to the versions shipped with the plugin whenever you want the newest entries. = Privacy = The plugin stores registration attempts in a table in your own database. Nothing is sent anywhere else, and no external service is contacted. You decide how much is kept: * email addresses in full, partially masked, reduced to the domain, or not stored at all * IP addresses in full, anonymized, or not stored at all * a retention period after which entries are deleted automatically The plugin registers a personal data exporter and eraser, so log entries are included in the export and erasure requests WordPress produces under Tools → Export/Erase Personal Data, and it suggests text for your privacy policy. The connection address is used by default; forwarded headers such as `X-Forwarded-For` are trusted only if you state that the site is behind a reverse proxy, because a visitor can otherwise put any value there. = A note on what a blocklist can do = A blocklist only refuses the domains you thought of. Somebody who wants an account will find a provider that is not on the list. When the set of acceptable providers is actually known, the allowlist is the mode that holds. The plugin is a technical control over email domains. It does not by itself make a site compliant with any particular legislation, and the site owner remains responsible for their own legal obligations. = Russian Federal Law 406-FZ = The plugin was originally written for Russian site owners working towards Federal Law No. 406-FZ, which requires authorization through a phone number, ESIA, a biometric system or another Russian-controlled system. This plugin implements none of those. It only controls the email domain used at registration, which the law does not address directly. Treat it as one piece of housekeeping, not as a compliance solution, and take legal advice about your own obligations. == Installation == 1. Install the plugin through Plugins → Add New, or upload the folder to `/wp-content/plugins/`. 2. Activate it. 3. Open "Email Blocker" in the admin menu and choose a mode. 4. Fill in the domain list for that mode. Pre-configured lists are provided and can be edited freely. 5. Send yourself a test message before notifying anybody, to confirm this site can send mail at all. On a multisite network the plugin can be network activated. Each site keeps its own settings and its own log table. == Frequently Asked Questions == = Does this make my site compliant with Federal Law 406-FZ? = No. The law requires authorization by phone number, ESIA, a biometric system or another Russian-controlled system, and this plugin implements none of them. It controls email domains only. Consult a lawyer about your actual obligations. = Can somebody get around a blocklist? = Yes. A blocklist can only refuse domains you have listed, and new mail providers appear constantly. If it matters that only certain providers are used, switch to allowlist mode. = Will existing users be blocked? = Not retroactively. Existing accounts keep working. They appear in the "Affected users" tab so you can see who is affected and notify them, and if email change checking is enabled they will be asked for a compliant address the next time they edit their profile. = Can an administrator set a rejected address for someone by hand? = Not while email change checking is on: the rules apply to the account being edited, whoever is doing the editing. Administrators are exempt as accounts, not as editors. To make an exception, either turn the setting off, or use the `regiembl_skip_validation` filter. = Does it work on WordPress with SQLite? = The domain rules do. The reports about existing accounts do not: they rely on `SUBSTRING_INDEX`, which the SQLite integration does not provide, and the "Affected users" tab will show nobody. This affects development environments such as WordPress Playground, not ordinary MySQL or MariaDB hosting. = Can I be locked out of my own site? = Administrators are exempt by default. Leave that setting on unless you have a specific reason to change it. = Does it work with the WooCommerce block checkout? = Yes. The block checkout is validated through the Store API, which requires WooCommerce 9.9 or newer. The classic shortcode checkout is validated as well, on any version. = What happens to a malformed email address? = Nothing, as far as this plugin is concerned. WordPress and WooCommerce already reject malformed addresses with a message that explains the real problem, so the plugin stays out of the way and does not record it as a blocked domain. = Can I add a .рф domain? = Yes. Type it in Cyrillic and it is converted to punycode when you save. If the PHP `intl` extension is missing on your server, the plugin tells you so and you can enter the punycode form directly, for example `xn--80a1acny.xn--p1ai`. = Does it slow the site down? = Registration checks are a string comparison against a list held in memory, so the cost is negligible. The reports about existing accounts are heavier by nature. They are answered with aggregate SQL rather than by loading user objects, the results are cached for an hour, and the tables are paginated. If you do not need that report on a very large site, turn off "Report existing accounts that do not comply" and it will not be calculated at all. = How many emails are sent at once? = Up to ten per request, and fewer if your mail server is slow: a batch also stops after ten seconds, so it cannot run into the execution time limit. The browser drives the run, shows progress and can stop it. Users notified within the configured window are skipped, so restarting after an interruption does not mail anybody twice. The plugin sends through `wp_mail()` and does not set a From address, leaving that to WordPress or to your SMTP plugin. For any real volume, install an SMTP plugin. = What is removed when I delete the plugin? = The settings, the log table and the per-user notification timestamps, on every site of a network. User accounts are never touched. == Screenshots == 1. Settings: mode, domain lists, messages, log and privacy options 2. Affected users: paginated list of accounts with a rejected domain, and the domains in use 3. Log: recorded attempts with filtering and pagination 4. The message a visitor sees when a domain is refused == Changelog == = 1.1.0 = **This release contains security fixes. Updating is recommended for every installation.** Coverage: * The domain rules now also apply when an existing account changes its email address — on the profile screen, in the WooCommerce account page and over the REST API. Previously the rules applied at registration only, which left an obvious way around them. The behaviour can be switched off if you do not want it. * The WooCommerce block checkout is now validated, not just the classic shortcode checkout. Compatibility with High-Performance Order Storage and with the Cart and Checkout blocks is declared explicitly, so WooCommerce no longer lists the plugin as untested. * Internationalized domains such as `почта.рф` can be used: they are converted to punycode when saved. Entries that are not valid domains are reported instead of being dropped without a word. * An empty allowlist no longer switches the plugin off silently — the settings screen says so plainly. * A malformed email address is left to WordPress to report, rather than being blamed on the domain rules. Privacy and data retention: * Choose how much is kept: email addresses in full, partially masked, reduced to the domain, or not stored at all; IP addresses in full, anonymized, or not stored. * Set a retention period. Older entries are removed automatically once a day. * Log entries are now included in the personal data export and erasure requests WordPress produces, and the plugin suggests text for your privacy policy. * Repeated attempts from one address are collapsed, so an automated attack cannot inflate the table. Reliability on larger sites: * The reports about existing accounts are answered with aggregate queries and cached counters instead of loading every user account into memory, and the tables are paginated. Sites with tens of thousands of users can now open these screens. * Notifications are sent in small batches with a progress bar and a stop button, and anyone notified recently is skipped — an interrupted run no longer starts over and no longer mails anybody twice. * Log entries are cleared with a statement that does not require database privileges many shared hosts withhold. * Deleting the plugin now removes its data reliably, including over WP-CLI and on every site of a multisite network. * The database schema is versioned, so future updates can change it safely. Housekeeping: * Interface strings are now in English with a Russian translation included, so the plugin can be translated into other languages. * The default blocklist covers provider aliases, regional domains and common disposable-mail services. A button restores both lists to the shipped defaults. * Added a button that sends a test message, so you can confirm mail works before notifying anybody. * Requires WordPress 6.2 or newer. = 1.0.0 = * Initial release. == Upgrade Notice == = 1.1.0 = Security release — updating is recommended. Also closes a gap that let accounts switch to a blocked domain after registering, adds WooCommerce block checkout support, log retention and privacy controls. Requires WordPress 6.2 or newer. == Support == Questions and bug reports are welcome on the plugin's support forum on WordPress.org. Developer: Studio Playner — https://profiles.wordpress.org/altcreative/ == Support Development == This plugin is free and will stay free. If it saves you time, you can support its development through [YooKassa](https://yookassa.ru/my/i/aVPRSGFZeJmV/l). Contributions go towards new features, compatibility with new WordPress and WooCommerce releases, and answering support questions. == License == This plugin is licensed under the GPL v2 or later. Copyright (C) 2026 Studio Playner This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.