From 3e8c1b7910f7190da15862b9e4d9dd7e39c7ee35 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Thu, 24 Mar 2022 08:34:52 +1100 Subject: [PATCH] GMail credentials notification --- app/Jobs/Mail/NinjaMailerJob.php | 17 ++-- app/Mail/Ninja/GmailTokenInvalid.php | 64 ++++++++++++++ app/Models/Account.php | 41 +++++++++ .../Ninja/GmailCredentialNotification.php | 88 +++++++++++++++++++ app/Services/Invoice/GetInvoicePdf.php | 7 +- resources/lang/en/texts.php | 2 + 6 files changed, 210 insertions(+), 9 deletions(-) create mode 100644 app/Mail/Ninja/GmailTokenInvalid.php create mode 100644 app/Notifications/Ninja/GmailCredentialNotification.php diff --git a/app/Jobs/Mail/NinjaMailerJob.php b/app/Jobs/Mail/NinjaMailerJob.php index 1b8713cd10..ecd34f8d62 100644 --- a/app/Jobs/Mail/NinjaMailerJob.php +++ b/app/Jobs/Mail/NinjaMailerJob.php @@ -210,15 +210,8 @@ class NinjaMailerJob implements ShouldQueue $user = $user->fresh(); } - //17-01-2022 - ensure we have a token otherwise we fail gracefully to default sending engine - // if(strlen($user->oauth_user_token) == 0){ - // $this->nmo->settings->email_sending_method = 'default'; - // return $this->setMailDriver(); - // } - $google->getClient()->setAccessToken(json_encode($user->oauth_user_token)); - //need to slow down gmail requests otherwise we hit 429's sleep(rand(2,6)); } catch(\Exception $e) { @@ -227,6 +220,16 @@ class NinjaMailerJob implements ShouldQueue return $this->setMailDriver(); } + /** + * If the user doesn't have a valid token, notify them + */ + + if(!$user->oauth_user_token) { + $this->company->account->gmailCredentialNotification(); + return; + } + + /* * Now that our token is refreshed and valid we can boot the * mail driver at runtime and also set the token which will persist diff --git a/app/Mail/Ninja/GmailTokenInvalid.php b/app/Mail/Ninja/GmailTokenInvalid.php new file mode 100644 index 0000000000..eaf7bc852a --- /dev/null +++ b/app/Mail/Ninja/GmailTokenInvalid.php @@ -0,0 +1,64 @@ +company = $company; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + App::setLocale($this->company->getLocale()); + + $this->settings = $this->company->settings; + $this->logo = $this->company->present()->logo(); + $this->title = ctrans('texts.gmail_credentials_invalid_subject'); + $this->body = ctrans('texts.gmail_credentials_invalid_body'); + $this->whitelabel = $this->company->account->isPaid(); + $this->replyTo('contact@invoiceninja.com', 'Contact'); + + return $this->from(config('mail.from.address'), config('mail.from.name')) + ->subject(ctrans('texts.gmail_credentials_invalid_subject')) + ->view('email.admin.email_quota_exceeded'); + } +} diff --git a/app/Models/Account.php b/app/Models/Account.php index 222e49aa49..1a4962ba85 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -14,8 +14,10 @@ namespace App\Models; use App\Jobs\Mail\NinjaMailerJob; use App\Jobs\Mail\NinjaMailerObject; use App\Mail\Ninja\EmailQuotaExceeded; +use App\Mail\Ninja\GmailTokenInvalid; use App\Models\Presenters\AccountPresenter; use App\Notifications\Ninja\EmailQuotaNotification; +use App\Notifications\Ninja\GmailCredentialNotification; use App\Utils\Ninja; use App\Utils\Traits\MakesHash; use Carbon\Carbon; @@ -424,4 +426,43 @@ class Account extends BaseModel return false; } + public function gmailCredentialNotification() :bool + { + + if(is_null(Cache::get($this->key))) + return false; + + try { + + if(is_null(Cache::get("gmail_credentials_notified:{$this->key}"))) { + + App::forgetInstance('translator'); + $t = app('translator'); + $t->replace(Ninja::transformTranslations($this->companies()->first()->settings)); + + $nmo = new NinjaMailerObject; + $nmo->mailable = new GmailTokenInvalid($this->companies()->first()); + $nmo->company = $this->companies()->first(); + $nmo->settings = $this->companies()->first()->settings; + $nmo->to_user = $this->companies()->first()->owner(); + NinjaMailerJob::dispatch($nmo); + + Cache::put("gmail_credentials_notified:{$this->key}", true, 60 * 24); + + if(config('ninja.notification.slack')) + $this->companies()->first()->notification(new GmailCredentialNotification($this))->ninja(); + } + + return true; + + } + catch(\Exception $e){ + \Sentry\captureMessage("I encountered an error with sending with gmail for account {$this->key}"); + } + + return false; + + + } + } diff --git a/app/Notifications/Ninja/GmailCredentialNotification.php b/app/Notifications/Ninja/GmailCredentialNotification.php new file mode 100644 index 0000000000..27684f39a5 --- /dev/null +++ b/app/Notifications/Ninja/GmailCredentialNotification.php @@ -0,0 +1,88 @@ +account = $account; + } + + /** + * Get the notification's delivery channels. + * + * @param mixed $notifiable + * @return array + */ + public function via($notifiable) + { + return ['slack']; + } + + /** + * Get the mail representation of the notification. + * + * @param mixed $notifiable + * @return MailMessage + */ + public function toMail($notifiable) + { + } + + /** + * Get the array representation of the notification. + * + * @param mixed $notifiable + * @return array + */ + public function toArray($notifiable) + { + return [ + // + ]; + } + + public function toSlack($notifiable) + { + + $content = "GMail credentials invalid for Account {$this->account->key} \n"; + + $owner = $this->account->companies()->first()->owner(); + + $content .= "Owner {$owner->present()->name() } | {$owner->email}"; + + return (new SlackMessage) + ->success() + ->from(ctrans('texts.notification_bot')) + ->image('https://app.invoiceninja.com/favicon.png') + ->content($content); + } +} diff --git a/app/Services/Invoice/GetInvoicePdf.php b/app/Services/Invoice/GetInvoicePdf.php index 0923c0ea22..758cb92b59 100644 --- a/app/Services/Invoice/GetInvoicePdf.php +++ b/app/Services/Invoice/GetInvoicePdf.php @@ -29,12 +29,16 @@ class GetInvoicePdf extends AbstractService public function run() { + if (! $this->contact) { $this->contact = $this->invoice->client->primary_contact()->first() ?: $this->invoice->client->contacts()->first(); } $invitation = $this->invoice->invitations->where('client_contact_id', $this->contact->id)->first(); + if(!$invitation) + $invitation = $this->invoice->invitations->first(); + $path = $this->invoice->client->invoice_filepath($invitation); $file_path = $path.$this->invoice->numberFormatter().'.pdf'; @@ -48,8 +52,7 @@ class GetInvoicePdf extends AbstractService $file_path = CreateEntityPdf::dispatchNow($invitation); } - // return Storage::disk($disk)->path($file_path); - // return $file_path; + } } diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 74f196d270..83d1876a81 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -4570,6 +4570,8 @@ $LANG = array( 'credits_backup_subject' => 'Your credits are ready for download', 'document_download_subject' => 'Your documents are ready for download', 'reminder_message' => 'Reminder for invoice :number for :balance', + 'gmail_credentials_invalid_subject' => 'Send with GMail invalid credentials', + 'gmail_credentials_invalid_body' => 'Your GMail credentials are not correct, please log into the administrator portal and navigate to Settings > User Details and disconnect and reconnect your GMail account. We will send you this notification daily until this issue is resolved', ); return $LANG;