Pārlūkot izejas kodu

Improved MX record validation

Will Browning 5 gadi atpakaļ
vecāks
revīzija
bd78841741

+ 10 - 0
app/Alias.php

@@ -125,4 +125,14 @@ class Alias extends Model
     {
         $this->update(['active' => true]);
     }
+
+    public function isUuid()
+    {
+        return $this->id === $this->local_part;
+    }
+
+    public function isCustomDomain()
+    {
+        return $this->aliasable_type === 'App\Domain';
+    }
 }

+ 23 - 4
app/Domain.php

@@ -2,11 +2,10 @@
 
 namespace App;
 
+use App\Http\Resources\DomainResource;
 use App\Traits\HasEncryptedAttributes;
 use App\Traits\HasUuid;
 use Illuminate\Database\Eloquent\Model;
-use Illuminate\Support\Str;
-use Spatie\Dns\Dns;
 
 class Domain extends Model
 {
@@ -125,10 +124,30 @@ class Domain extends Model
      */
     public function checkVerification()
     {
-        $dns = new Dns($this->domain, config('anonaddy.dns_resolver'));
+        $records = collect(dns_get_record($this->domain . '.', DNS_MX));
 
-        if (Str::contains($dns->getRecords('MX'), 'MX 10 ' . config('anonaddy.hostname') . '.')) {
+        $lowestPriority = $records->groupBy('pri')->sortKeys()->first();
+
+        if ($lowestPriority->count() !== 1) {
+            return response()->json([
+                'success' => false,
+                'message' => 'Please make sure you do not have any other MX records with the same priority.'
+            ]);
+        }
+
+        // Check the target for the lowest priority record is correct.
+        if ($lowestPriority->first()['target'] === 'mail.anonaddy.me') {
             $this->markDomainAsVerified();
+            return response()->json([
+                'success' => true,
+                'message' => 'MX Record successfully verified.',
+                'data' => new DomainResource($this->fresh())
+            ]);
         }
+
+        return response()->json([
+            'success' => false,
+            'message' => 'Record not found. This could be due to DNS caching, please try again later.'
+        ]);
     }
 }

+ 1 - 5
app/Http/Controllers/DomainVerificationController.php

@@ -2,8 +2,6 @@
 
 namespace App\Http\Controllers;
 
-use App\Http\Resources\DomainResource;
-
 class DomainVerificationController extends Controller
 {
     public function __construct()
@@ -19,8 +17,6 @@ class DomainVerificationController extends Controller
             return response('Domain already verified', 404);
         }
 
-        $domain->checkVerification();
-
-        return new DomainResource($domain->fresh());
+        return $domain->checkVerification();
     }
 }

+ 7 - 4
app/Mail/ForwardEmail.php

@@ -55,18 +55,19 @@ class ForwardEmail extends Mailable implements ShouldQueue
     }
 
     /**
-     * Build the message.4
+     * Build the message.
      *
      * @return $this
      */
     public function build()
     {
         $replyToDisplay = $this->replyToAddress ?? $this->sender;
-
         $replyToEmail = $this->alias->local_part.'+'.sha1(config('anonaddy.secret').$replyToDisplay).'@'.$this->alias->domain;
 
+        $fromEmail = $this->alias->isUuid() ? $this->alias->email : config('mail.from.address');
+
         $email =  $this
-            ->from(config('mail.from.address'), base64_decode($this->displayFrom)." '".$this->sender."'")
+            ->from($fromEmail, base64_decode($this->displayFrom)." '".$this->sender."'")
             ->replyTo($replyToEmail, $replyToDisplay)
             ->subject($this->user->email_subject ?? base64_decode($this->emailSubject))
             ->text('emails.forward.text')->with([
@@ -81,11 +82,13 @@ class ForwardEmail extends Mailable implements ShouldQueue
             ])
             ->withSwiftMessage(function ($message) {
                 $message->getHeaders()
-                        ->addTextHeader('List-Unsubscribe', '<' . $this->deactivateUrl . '>, <mailto:' . $this->alias->id . '@unsubscribe.' . config('anonaddy.domain') . '>');
+                        ->addTextHeader('List-Unsubscribe', '<mailto:' . $this->alias->id . '@unsubscribe.' . config('anonaddy.domain') . '?subject=unsubscribe>, <' . $this->deactivateUrl . '>');
 
                 $message->getHeaders()
                         ->addTextHeader('Return-Path', config('anonaddy.return_path'));
 
+                $message->setId(bin2hex(random_bytes(16)).'@'.$this->alias->domain);
+
                 if ($this->fingerprint) {
                     $message->attachSigner($this->openpgpsigner);
                 }

+ 6 - 5
app/Mail/ReplyToEmail.php

@@ -44,18 +44,19 @@ class ReplyToEmail extends Mailable implements ShouldQueue
     public function build()
     {
         $fromName = $this->user->from_name ? $this->user->from_name : $this->alias->email;
-        $fromAddress = $this->alias->isUuid() ? $this->alias->email : config('mail.from.address');
-        $returnPath = $this->alias->isUuid() ? $this->alias->email : config('anonaddy.return_path');
+        $fromEmail = $this->alias->isUuid() ? $this->alias->email : config('mail.from.address');
 
         $email =  $this
-            ->from($fromAddress, $fromName)
+            ->from($fromEmail, $fromName)
             ->subject(base64_decode($this->emailSubject))
             ->text('emails.reply.text')->with([
                 'text' => base64_decode($this->emailText)
             ])
-            ->withSwiftMessage(function ($message) use ($returnPath) {
+            ->withSwiftMessage(function ($message) {
                 $message->getHeaders()
-                        ->addTextHeader('Return-Path', $returnPath);
+                        ->addTextHeader('Return-Path', config('anonaddy.return_path'));
+
+                $message->setId(bin2hex(random_bytes(16)).'@'.$this->alias->domain);
             });
 
         if (! $this->alias->isUuid()) {

+ 1 - 2
composer.json

@@ -19,8 +19,7 @@
         "php-mime-mail-parser/php-mime-mail-parser": "^5.0",
         "pragmarx/google2fa-laravel": "^1.3",
         "predis/predis": "^1.1",
-        "ramsey/uuid": "^3.8",
-        "spatie/dns": "^1.4"
+        "ramsey/uuid": "^3.8"
     },
     "require-dev": {
         "beyondcode/laravel-dump-server": "^1.0",

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 175 - 220
composer.lock


+ 4 - 4
resources/js/pages/Domains.vue

@@ -484,11 +484,11 @@ export default {
         .then(({ data }) => {
           this.recheckRecordsLoading = false
 
-          if (data.data.domain_verified_at === null) {
-            this.warn('MX record not found, please try again later')
-          } else {
-            this.success('Domain verified successfully')
+          if (data.success === true) {
+            this.success(data.message)
             domain.domain_verified_at = data.data.domain_verified_at
+          } else {
+            this.warn(data.message)
           }
         })
         .catch(error => {

+ 1 - 1
resources/views/settings/show.blade.php

@@ -9,7 +9,7 @@
                 <div class="flex items-center mb-2">
                     <span class="rounded-full bg-yellow-400 uppercase px-2 py-1 text-xs font-bold mr-2">Important</span>
                     <div>
-                        2FA enabled successfully, please <b>make a copy of your backup code below</b>. If you lose your 2FA device you can use this backup code to disable 2FA on your account. <b>This is the only time this code will be displayed, so be sure not to lose it!</b>
+                        2FA enabled successfully. Please <b>make a copy of your backup code below</b>. If you lose your 2FA device you can use this backup code to disable 2FA on your account. <b>This is the only time this code will be displayed, so be sure not to lose it!</b>
                     </div>
                 </div>
                 <pre class="flex p-3 text-grey-900 bg-white border rounded">

Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels