Block disposable email domains at registration#122
Merged
Conversation
Add an always-on NotThrowawayEmail constraint (via mattketmo/email-checker) to the base User entity's email property, layering the package's built-in list with a supplemental, refreshable blocklist file. Includes a console command to refresh the file from upstream and covering tests.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds disposable/temporary email domain blocking to the PlatformBundle’s base User model by attaching an email-checker validation constraint to the inherited email property, and wires the EmailChecker service to use both the vendor built-in list and a bundled supplemental blocklist file. It also introduces a console command to refresh that supplemental list, plus tests covering constraint inheritance and matching behavior.
Changes:
- Add
mattketmo/email-checkerand apply#[NotThrowawayEmail]toPlatformBundle\Model\User::$email. - Register an aggregated
EmailChecker+NotThrowawayEmailValidatorservice, backed byBuiltInAdapterandFileAdapterpointing toResources/data/disposable_email_blocklist.conf. - Add
platform:disposable-domains:updateplus PHPUnit tests for validation behavior and list refresh.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| composer.json | Adds mattketmo/email-checker dependency. |
| src/Bundle/Platform/Model/User.php | Adds NotThrowawayEmail constraint to the base email property; removes stale #[Override] on eraseCredentials(). |
| src/Bundle/Platform/Resources/config/services.php | Wires EmailChecker with an aggregated adapter and registers the vendor validator as a service; configures the update command output path. |
| src/Bundle/Platform/Command/UpdateDisposableDomainsCommand.php | Adds a command to download and rewrite the supplemental disposable-domain blocklist file. |
| src/Bundle/Platform/Resources/data/disposable_email_blocklist.conf | Adds the supplemental disposable-domain snapshot used by the FileAdapter. |
| tests/Bundle/PlatformBundle/Validator/Fixtures/UserFixture.php | Adds a concrete User subclass fixture to assert inherited constraints. |
| tests/Bundle/PlatformBundle/Validator/DisposableEmailValidationTest.php | Adds tests for inheritance and matching (built-in, custom list, parent/subdomain). |
| tests/Bundle/PlatformBundle/Command/UpdateDisposableDomainsCommandTest.php | Adds a test for the refresh command using a mocked HTTP client. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| )] | ||
| final class UpdateDisposableDomainsCommand extends Command | ||
| { | ||
| private const string SOURCE_URL = 'https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/master/disposable_email_blocklist.conf'; |
Comment on lines
+97
to
+100
| public function getInstance(Constraint $constraint): ConstraintValidatorInterface | ||
| { | ||
| return $this->notThrowawayEmailValidator; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Block disposable email domains at registration
Rejects disposable / temporary email domains on the platform's base
Userentity at validation time, surfacing a normal form-validation error. The check
is always-on: it is declared on the abstract base's protected
emailproperty, so every concrete subclass inherits it automatically with no
per-extender wiring.
What changed
mattketmo/email-checker:^3.0as the detection engine(exact + parent/suffix domain matching out of the box).
#[NotThrowawayEmail]added toUser::$email, alongside theexisting
NotBlank/Emailasserts.supplemental, refreshable file via
AggregatorAdapter([BuiltInAdapter, FileAdapter]). The committed snapshotlives at
Resources/data/disposable_email_blocklist.conf.NotThrowawayEmailValidatoris registered as a service soour aggregated
EmailChecker(built-in + supplemental file) is injected,rather than the package default that only sees the built-in list.
platform:disposable-domains:updatedownloads theupstream
disposable-email-domains
blocklist and rewrites the data file.
Drive-by fix
#[Override]fromUser::eraseCredentials(). Symfony 7.3removed that method from
UserInterface, so the attribute was a latent fatalthat prevented any concrete
Userfrom being instantiated — which the newvalidation path requires.
Tests
DisposableEmailValidationTest— constraint inheritance (concrete subclass)plus matching behavior: built-in domain, supplemental-list domain, subdomain
(parent matching), and a normal domain (no violation).
UpdateDisposableDomainsCommandTest— mocked HTTP client, asserts the datafile is written and the command returns success.
All new tests pass (6 tests). The 4 pre-existing
LemonSqueezyPayloadConvertersnapshot failures are unrelated environment drift (empty-object serialization
whitespace) in a bundle untouched here.
Note on scope
This branch also carries earlier commits not yet in
main(TiptapTextEditorTypeform type, the auto-detected 2FA security-config redesign, andrelated docs), so the diff is broader than the disposable-email feature alone.