Skip to content

Conversation

@nickmoline
Copy link
Contributor

Summary

Enhanced the Laravel Domain Validation package to support optional DNS record verification, allowing developers to validate not just domain format but also the existence and values of DNS records.

New Features

1. DNS Record Type Checking

Added support for checking the existence of various DNS record types:

  • A Records - IPv4 address records
  • AAAA Records - IPv6 address records
  • CNAME Records - Canonical name records
  • TXT Records - Text records
  • MX Records - Mail exchange records
  • DNS - Checks for presence of any DNS record (A, AAAA, CNAME, TXT, MX, NS, or SOA)

2. String Syntax Support

Developers can now use a simple string-based syntax for DNS checks:

// Single DNS check
'domain' => ['required', 'domain:mx']

// Multiple DNS checks
'domain' => ['required', 'domain:a,mx']

// Check for DNS records
'domain' => ['required', 'domain:dns']

3. Fluent API

Introduced a chainable fluent API for more control:

(new Domain)->requireA()->requireMx()->requireTxt()

4. DNS Record Value Verification

Added ability to verify that DNS records resolve to expected values:

(new Domain)->requireA('192.0.2.1')
(new Domain)->requireMx('mail.example.com')

Multiple Records Matching: When a domain has multiple DNS records of the same type (e.g., multiple A records for load balancing), the validator passes if ANY of the records match the expected value. This allows you to chain multiple calls to verify multiple specific values:

// Verify domain has BOTH these IPs (for redundancy/load balancing)
(new Domain)
    ->requireA('8.8.8.8')
    ->requireA('8.8.4.4')

5. Enhanced Error Messages

Implemented specific error messages for different validation scenarios:

  • Invalid domain format
  • Missing required DNS records
  • DNS record value mismatch
  • Customizable via language files

6. Backward Compatibility

The enhancement maintains full backward compatibility:

// Still works exactly as before
new Domain  // Just validates format

Technical Changes

Modified Files

src/Validator/Domain.php

Changes:

  • Implemented ValidatorAwareRule interface
  • Added traits: Conditionable, Macroable
  • Added constructor to accept optional DNS check parameters
  • Added methods:
    • requireA(?string $expectedValue = null)
    • requireAaaa(?string $expectedValue = null)
    • requireCname(?string $expectedValue = null)
    • requireTxt(?string $expectedValue = null)
    • requireMx(?string $expectedValue = null)
    • requireAny()
    • parseParameters(array $parameters)
    • hasAnyDnsRecords(string $domain)
    • hasDnsRecord(string $domain, string $type)
    • dnsRecordMatchesValue(string $domain, string $type, string $expectedValue)
    • extractRecordValue(array $record, string $type)
    • matchesExpectedValue(string $recordValue, string $expectedValue)
    • getDnsConstant(string $type)
    • trans(string $key, array $replace = [])
  • Enhanced passes() method with DNS checking logic
  • Enhanced message() method with specific error messages

tests/DomainTest.php

Added Tests:

  • testLocalhost() - Verify localhost handling
  • testDnsCheckWithParameters() - Test string syntax with single parameter
  • testDnsCheckWithMultipleParameters() - Test string syntax with multiple parameters
  • testDnsCheckAny() - Test 'any' DNS check
  • testFluentApiRequireMx() - Test fluent API MX check
  • testFluentApiRequireA() - Test fluent API A record check
  • testFluentApiChaining() - Test method chaining
  • testFluentApiRequireAny() - Test requireAny method
  • testDnsCheckFailsForInvalidDomain() - Test DNS validation failure
  • testDnsCheckWithExpectedValue() - Test value matching
  • testErrorMessage() - Test error message generation
  • testDnsErrorMessage() - Test DNS-specific error messages

Methods

requireA(?string $expectedValue = null): self

Require A record. Optionally verify it points to a specific IP.

requireAaaa(?string $expectedValue = null): self

Require AAAA record. Optionally verify it points to a specific IPv6 address.

requireCname(?string $expectedValue = null): self

Require CNAME record. Optionally verify it points to a specific target.

requireTxt(?string $expectedValue = null): self

Require TXT record. Optionally verify it contains a specific value.

requireMx(?string $expectedValue = null): self

Require MX record. Optionally verify it points to a specific mail server.

requireAny(): self

Require any DNS record (A, AAAA, CNAME, TXT, MX, NS, or SOA).

Translation Keys

Added support for custom translation keys:

  • validation.domain - Invalid domain format message
  • validation.domain_dns - Missing DNS record type message
  • validation.domain_dns_any - Missing any DNS record message
  • validation.domain_dns_value - DNS record value mismatch message

Usage Examples

Before (Still Supported)

'domain' => ['required', 'string', new Domain]

After - String Syntax

'domain' => ['required', 'domain:mx']
'domain' => ['required', 'domain:a,mx']

After - Fluent API

'domain' => ['required', (new Domain)->requireMx()]
'domain' => ['required', (new Domain)->requireA()->requireMx()]
'domain' => ['required', (new Domain)->requireA('192.0.2.1')]

Breaking Changes

None - This is a fully backward-compatible enhancement.

Performance Considerations

  • DNS lookups are performed during validation
  • Each DNS check makes a network request
  • Consider caching validation results for production use
  • Localhost is automatically recognized and skips DNS checks

Testing

All tests pass:

  • 20 test cases
  • 37 assertions
  • 100% success rate

Run tests:

./vendor/bin/phpunit tests/DomainTest.php

Future Enhancements

Potential improvements for future versions:

  1. Caching: Add built-in DNS result caching
  2. Async Validation: Support for asynchronous DNS checks
  3. Custom DNS Servers: Allow specifying custom DNS servers for lookups
  4. Wildcard Records: Support for wildcard DNS record checks
  5. DNSSEC Validation: Verify DNSSEC signatures
  6. Batch Validation: Optimize multiple domain validation
  7. Rate Limiting: Built-in rate limiting for DNS queries

Credits

Based on the Laravel Email validation rule pattern and inspired by:

nickmoline and others added 4 commits November 7, 2025 01:03
In addition to teh existing validation that a domain meets the valid syntax of a domain, this update adds options for validating that the domain actually exists by doing various dns lookups
@nickmoline
Copy link
Contributor Author

Also updated workflow rules to test PHP 8.4 and Laravel 13

11 and 12 supports 8.2 - 8.4, 13 supports 8.3 - 8.4
@dacoto dacoto merged commit 43befc6 into dacoto:main Nov 17, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants