diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php index 3bc064ea40a4..f53f47348ef8 100644 --- a/app/Http/Controllers/EmailController.php +++ b/app/Http/Controllers/EmailController.php @@ -13,6 +13,7 @@ namespace App\Http\Controllers; use App\Events\Credit\CreditWasEmailed; use App\Events\Quote\QuoteWasEmailed; +use App\Http\Middleware\UserVerified; use App\Http\Requests\Email\SendEmailRequest; use App\Jobs\Entity\EmailEntity; use App\Jobs\Mail\EntitySentMailer; @@ -130,7 +131,8 @@ class EmailController extends BaseController $entity_obj->service()->markSent()->save(); - EmailEntity::dispatch($invitation, $invitation->company, $template, $data)->delay(now()->addSeconds(5)); + EmailEntity::dispatch($invitation, $invitation->company, $template, $data) + ->delay(now()->addSeconds(5)); } diff --git a/app/Http/Controllers/PostMarkController.php b/app/Http/Controllers/PostMarkController.php index cb0ef144c219..e4f6a855d0af 100644 --- a/app/Http/Controllers/PostMarkController.php +++ b/app/Http/Controllers/PostMarkController.php @@ -78,10 +78,8 @@ class PostMarkController extends BaseController $this->invitation = $this->discoverInvitation($request->input('MessageID')); - if($this->invitation){ + if($this->invitation) $this->invitation->email_error = $request->input('Details'); - $this->invitation->save(); - } else return response()->json(['message' => 'Message not found']); @@ -122,6 +120,9 @@ class PostMarkController extends BaseController // } private function processDelivery($request) { + $this->invitation->email_status = 'delivered'; + $this->invitation->save(); + SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_DELIVERY, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client); } @@ -153,6 +154,9 @@ class PostMarkController extends BaseController private function processBounce($request) { + $this->invitation->email_status = 'bounced'; + $this->invitation->save(); + SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_BOUNCED, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client); } @@ -183,6 +187,10 @@ class PostMarkController extends BaseController // } private function processSpamComplaint($request) { + + $this->invitation->email_status = 'spam'; + $this->invitation->save(); + SystemLogger::dispatch($request->all(), SystemLog::CATEGORY_MAIL, SystemLog::EVENT_MAIL_SPAM_COMPLAINT, SystemLog::TYPE_WEBHOOK_RESPONSE, $this->invitation->contact->client); } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index aa85deb5bcb6..87de725daaf8 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -386,6 +386,7 @@ class UserController extends BaseController /* When changing email address we store the former email in case we need to rollback */ if ($old_user_email != $new_email) { $user->last_confirmed_email_address = $old_user_email; + $user->email_verified_at = null; $user->save(); UserEmailChanged::dispatch($new_user, json_decode($old_user), auth()->user()->company()); } diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 892be0b99aea..63803aa46499 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -38,6 +38,7 @@ use App\Http\Middleware\TokenAuth; use App\Http\Middleware\TrimStrings; use App\Http\Middleware\TrustProxies; use App\Http\Middleware\UrlSetDb; +use App\Http\Middleware\UserVerified; use App\Http\Middleware\VerifyCsrfToken; use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; use Illuminate\Auth\Middleware\Authorize; @@ -157,5 +158,6 @@ class Kernel extends HttpKernel 'phantom_secret' => PhantomSecret::class, 'contact_key_login' => ContactKeyLogin::class, 'check_client_existence' => CheckClientExistence::class, + 'user_verified' => UserVerified::class, ]; } diff --git a/app/Jobs/Account/CreateAccount.php b/app/Jobs/Account/CreateAccount.php index 882604331bab..f9131b004870 100644 --- a/app/Jobs/Account/CreateAccount.php +++ b/app/Jobs/Account/CreateAccount.php @@ -110,8 +110,7 @@ class CreateAccount NinjaMailerJob::dispatch($nmo); - - NinjaMailerJob::dispatchNow($nmo); + // NinjaMailerJob::dispatchNow($nmo); VersionCheck::dispatchNow(); diff --git a/app/Models/User.php b/app/Models/User.php index bbe68cb2af51..52582d0a95ee 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -339,6 +339,11 @@ class User extends Authenticatable implements MustVerifyEmail return $this->morphMany(Document::class, 'documentable'); } + public function isVerified() + { + return is_null($this->email_verified_at) ? false : true; + } + public function getEmailVerifiedAt() { if ($this->email_verified_at) { diff --git a/app/Transformers/CreditInvitationTransformer.php b/app/Transformers/CreditInvitationTransformer.php index 4996c165c1a8..fca841563848 100644 --- a/app/Transformers/CreditInvitationTransformer.php +++ b/app/Transformers/CreditInvitationTransformer.php @@ -31,6 +31,8 @@ class CreditInvitationTransformer extends EntityTransformer 'updated_at' => (int) $invitation->updated_at, 'archived_at' => (int) $invitation->deleted_at, 'created_at' => (int) $invitation->created_at, + 'email_status' => $invitation->email_status, + 'email_error' => (string)$invitation->email_error, ]; } } diff --git a/app/Transformers/InvoiceInvitationTransformer.php b/app/Transformers/InvoiceInvitationTransformer.php index 4517bf35faa5..76a514c409a8 100644 --- a/app/Transformers/InvoiceInvitationTransformer.php +++ b/app/Transformers/InvoiceInvitationTransformer.php @@ -30,7 +30,9 @@ class InvoiceInvitationTransformer extends EntityTransformer 'opened_date' => $invitation->opened_date ?: '', 'updated_at' => (int) $invitation->updated_at, 'archived_at' => (int) $invitation->deleted_at, - 'created_at' => (int) $invitation->created_at, + 'created_at' => (int) $invitation->created_at, + 'email_status' => $invitation->email_status, + 'email_error' => (string)$invitation->email_error, ]; } } diff --git a/app/Transformers/QuoteInvitationTransformer.php b/app/Transformers/QuoteInvitationTransformer.php index 31eeb080de6b..021b3b74e380 100644 --- a/app/Transformers/QuoteInvitationTransformer.php +++ b/app/Transformers/QuoteInvitationTransformer.php @@ -31,6 +31,8 @@ class QuoteInvitationTransformer extends EntityTransformer 'updated_at' => (int) $invitation->updated_at, 'archived_at' => (int) $invitation->deleted_at, 'created_at' => (int) $invitation->created_at, + 'email_status' => $invitation->email_status, + 'email_error' => (string)$invitation->email_error, ]; } } diff --git a/app/Transformers/RecurringInvoiceInvitationTransformer.php b/app/Transformers/RecurringInvoiceInvitationTransformer.php index 815115030248..43f0682c56fb 100644 --- a/app/Transformers/RecurringInvoiceInvitationTransformer.php +++ b/app/Transformers/RecurringInvoiceInvitationTransformer.php @@ -31,6 +31,8 @@ class RecurringInvoiceInvitationTransformer extends EntityTransformer 'updated_at' => (int) $invitation->updated_at, 'archived_at' => (int) $invitation->deleted_at, 'created_at' => (int) $invitation->created_at, + 'email_status' => $invitation->email_status, + 'email_error' => (string)$invitation->email_error, ]; } } diff --git a/app/Transformers/UserTransformer.php b/app/Transformers/UserTransformer.php index dd6e2c82816e..bd3632ab69b7 100644 --- a/app/Transformers/UserTransformer.php +++ b/app/Transformers/UserTransformer.php @@ -59,6 +59,7 @@ class UserTransformer extends EntityTransformer 'custom_value4' => $user->custom_value4 ?: '', 'oauth_provider_id' => (string) $user->oauth_provider_id, 'last_confirmed_email_address' => (string) $user->last_confirmed_email_address ?: '', + 'google_2fa_secret' => (bool) $user->google_2fa_secret, ]; } diff --git a/database/migrations/2021_02_25_205901_enum_invitations_email_status.php b/database/migrations/2021_02_25_205901_enum_invitations_email_status.php new file mode 100644 index 000000000000..cb7e8be1cce3 --- /dev/null +++ b/database/migrations/2021_02_25_205901_enum_invitations_email_status.php @@ -0,0 +1,42 @@ +enum('email_status', ['delivered', 'bounced', 'spam'])->nullable(); + }); + + Schema::table('quote_invitations', function(Blueprint $table){ + $table->enum('email_status', ['delivered', 'bounced', 'spam'])->nullable(); + }); + + Schema::table('credit_invitations', function(Blueprint $table){ + $table->enum('email_status', ['delivered', 'bounced', 'spam'])->nullable(); + }); + + Schema::table('recurring_invoice_invitations', function(Blueprint $table){ + $table->enum('email_status', ['delivered', 'bounced', 'spam'])->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/routes/api.php b/routes/api.php index 5ef05ac22167..5728607a20c1 100644 --- a/routes/api.php +++ b/routes/api.php @@ -65,7 +65,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::get('documents/{document}/download', 'DocumentController@download')->name('documents.download'); Route::post('documents/bulk', 'DocumentController@bulk')->name('documents.bulk'); - Route::post('emails', 'EmailController@send')->name('email.send'); + Route::post('emails', 'EmailController@send')->name('email.send')->middleware('user_verified'); Route::resource('expenses', 'ExpenseController'); // name = (expenses. index / create / show / update / destroy / edit Route::put('expenses/{expense}/upload', 'ExpenseController@upload');