mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-31 04:24:33 -04:00
Test for Gmail (#3706)
* Fixes for null values in custom values * Refactor mailing * Working on send emails from GMail API * Fixes for tests * Test for GMail
This commit is contained in:
parent
a01d7a59aa
commit
d05bd7d2c1
@ -312,7 +312,7 @@ class LoginController extends BaseController
|
|||||||
if(array_key_exists('refresh_token', $token))
|
if(array_key_exists('refresh_token', $token))
|
||||||
$refresh_token = $token['refresh_token'];
|
$refresh_token = $token['refresh_token'];
|
||||||
|
|
||||||
$access_token = $token['access_token'];
|
$access_token = $token['access_token'];
|
||||||
|
|
||||||
$name = OAuth::splitName($google->harvestName($user));
|
$name = OAuth::splitName($google->harvestName($user));
|
||||||
|
|
||||||
|
60
app/Jobs/Mail/BaseMailerJob.php
Normal file
60
app/Jobs/Mail/BaseMailerJob.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
|
use App\Libraries\Google\Google;
|
||||||
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Providers\MailServiceProvider;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
|
||||||
|
class BaseMailerJob implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
|
||||||
|
private function setMailDriver(string $driver)
|
||||||
|
{
|
||||||
|
switch ($driver) {
|
||||||
|
case 'default':
|
||||||
|
break;
|
||||||
|
case 'gmail':
|
||||||
|
$this->setGmailMailer();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private function setGmailMailer()
|
||||||
|
{
|
||||||
|
$sending_user = $this->entity->client->getSetting('gmail_sending_user_id');
|
||||||
|
|
||||||
|
$user = User::find($sending_user);
|
||||||
|
|
||||||
|
$google = (new Google())->init();
|
||||||
|
$google->getClient->setAccessToken($user->oauth_user_token);
|
||||||
|
|
||||||
|
if ($google->getClient->isAccessTokenExpired()) {
|
||||||
|
$google->refreshToken($user);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that our token is refresh and valid we can boot the
|
||||||
|
* mail driver at runtime and also set the token which will persist
|
||||||
|
* just for this request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Config::set('mail.driver', 'gmail');
|
||||||
|
Config::set('services.gmail.token', $user->oauth_user_token);
|
||||||
|
(new MailServiceProvider(app()))->register();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,14 +2,23 @@
|
|||||||
|
|
||||||
namespace App\Jobs\Mail;
|
namespace App\Jobs\Mail;
|
||||||
|
|
||||||
|
use App\Jobs\Util\SystemLogger;
|
||||||
|
use App\Libraries\Google\Google;
|
||||||
use App\Libraries\MultiDB;
|
use App\Libraries\MultiDB;
|
||||||
|
use App\Mail\Admin\EntitySent;
|
||||||
|
use App\Mail\Admin\EntitySentObject;
|
||||||
|
use App\Models\SystemLog;
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Providers\MailServiceProvider;
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
use Illuminate\Foundation\Bus\Dispatchable;
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
use Illuminate\Queue\InteractsWithQueue;
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\Config;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
|
||||||
class EntitySentEmail implements ShouldQueue
|
class EntitySentEmail extends BaseMailerJob implements ShouldQueue
|
||||||
{
|
{
|
||||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
@ -45,32 +54,37 @@ class EntitySentEmail implements ShouldQueue
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
//set DB
|
||||||
MultiDB::setDb($this->company->db);
|
MultiDB::setDb($this->company->db);
|
||||||
|
|
||||||
//if we need to set an email driver do it now
|
//if we need to set an email driver do it now
|
||||||
$this->setMailDriver($this->entity->client->getSetting('email_sending_method'));
|
$this->setMailDriver($this->entity->client->getSetting('email_sending_method'));
|
||||||
|
|
||||||
}
|
$mail_obj = (new EntitySentObject($this->invitation, $this->entity_type))->build();
|
||||||
|
$mail_obj->from = $this->entity->user->present()->name();
|
||||||
|
|
||||||
private function setMailDriver(string $driver)
|
//send email
|
||||||
{
|
// Mail::to($this->user->email)
|
||||||
switch ($driver) {
|
Mail::to('turbo124@gmail.com') //@todo
|
||||||
case 'default':
|
->send(new EntitySent($mail_obj));
|
||||||
break;
|
|
||||||
case 'gmail':
|
//catch errors
|
||||||
$this->setGmailMailer();
|
if (count(Mail::failures()) > 0) {
|
||||||
break;
|
$this->logMailError(Mail::failures());
|
||||||
default:
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if($driver == 'default')
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function setGmailMailer()
|
private function logMailError($errors)
|
||||||
{
|
{
|
||||||
$sending_user = $this->entity->client->getSetting('gmail_sending_user_id');
|
SystemLogger::dispatch(
|
||||||
|
$errors,
|
||||||
|
SystemLog::CATEGORY_MAIL,
|
||||||
|
SystemLog::EVENT_MAIL_SEND,
|
||||||
|
SystemLog::TYPE_FAILURE,
|
||||||
|
$this->invoice->client
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
65
app/Libraries/Google/Google.php
Normal file
65
app/Libraries/Google/Google.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Libraries\Google;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Google
|
||||||
|
* @package App\Libraries\Google
|
||||||
|
*/
|
||||||
|
class Google
|
||||||
|
{
|
||||||
|
public $client;
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->client = new \Google_Client();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function init()
|
||||||
|
{
|
||||||
|
$this->client->setClientId(config('ninja.auth.google.client_id'));
|
||||||
|
$this->client->setClientSecret(config('ninja.auth.google.client_secret'));
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getClient()
|
||||||
|
{
|
||||||
|
return $this->client;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function checkAccessToken()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refreshToken($user)
|
||||||
|
{
|
||||||
|
if($this->client->isAccessTokenExpired()) {
|
||||||
|
$this->client->fetchAccessTokenWithRefreshToken($user->oauth_user_refresh_token);
|
||||||
|
|
||||||
|
$access_token = $this->client->getAccessToken();
|
||||||
|
|
||||||
|
if(is_string($access_token))
|
||||||
|
$user->oauth_user_token = $access_token;
|
||||||
|
elseif(isset($access_token['access_token']))
|
||||||
|
$user->oauth_user_token = $access_token['access_token']);
|
||||||
|
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
$this->client->setAccessToken($access_token);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
45
app/Mail/Admin/EntitySent.php
Normal file
45
app/Mail/Admin/EntitySent.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\Admin;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
|
||||||
|
class EntitySent extends Mailable
|
||||||
|
{
|
||||||
|
|
||||||
|
public $mail_obj;
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct($mail_obj)
|
||||||
|
{
|
||||||
|
$this->mail_obj = $mail_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
return $this->from($this->mail_obj->from) //todo
|
||||||
|
->subject($this->mail_obj->subject)
|
||||||
|
->markdown($this->mail_obj->markdown, ['data' => $this->mail_obj->data])
|
||||||
|
->withSwiftMessage(function ($message) {
|
||||||
|
$message->getHeaders()->addTextHeader('Tag', $this->mail_obj->tag);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
90
app/Mail/Admin/EntitySentObject.php
Normal file
90
app/Mail/Admin/EntitySentObject.php
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Invoice Ninja (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2020. Invoice Ninja LLC (https://invoiceninja.com)
|
||||||
|
*
|
||||||
|
* @license https://opensource.org/licenses/AAL
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Mail\Admin;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use App\Utils\Number;
|
||||||
|
|
||||||
|
class EntitySentObject
|
||||||
|
{
|
||||||
|
public $invitation;
|
||||||
|
|
||||||
|
public $entity_type;
|
||||||
|
|
||||||
|
public $entity;
|
||||||
|
|
||||||
|
public $contact;
|
||||||
|
|
||||||
|
public $company;
|
||||||
|
|
||||||
|
public $settings;
|
||||||
|
|
||||||
|
public function __construct($invitation, $entity_type)
|
||||||
|
{
|
||||||
|
$this->invitation = $invitation;
|
||||||
|
$this->entity_type = $entity_type;
|
||||||
|
$this->entity = $invitation->{$entity_type};
|
||||||
|
$this->contact = $invitation->contact;
|
||||||
|
$this->company = $invitation->company;
|
||||||
|
$this->settings = $this->entity->client->getMergedSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$mail_obj = new \stdClass;
|
||||||
|
$mail_obj->amount = $this->getAmount();
|
||||||
|
$mail_obj->subject = $this->getSubject();
|
||||||
|
$mail_obj->data = $this->getData();
|
||||||
|
$mail_obj->markdown = 'email.admin.generic';
|
||||||
|
$mail_obj->tag = $this->company->company_key;
|
||||||
|
|
||||||
|
return $mail_obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAmount()
|
||||||
|
{
|
||||||
|
return Number::formatMoney($this->entity->amount, $this->entity->client);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getSubject()
|
||||||
|
{
|
||||||
|
return
|
||||||
|
ctrans(
|
||||||
|
"texts.notification_{$this->entity_type}_sent_subject",
|
||||||
|
[
|
||||||
|
'client' => $this->contact->present()->name(),
|
||||||
|
'invoice' => $this->entity->number,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getData()
|
||||||
|
{
|
||||||
|
$data = [
|
||||||
|
'title' => $this->getSubject,
|
||||||
|
'message' => ctrans(
|
||||||
|
"texts.notification_{$this->entity_type}_sent",
|
||||||
|
[
|
||||||
|
'amount' => $amount,
|
||||||
|
'client' => $this->contact->present()->name(),
|
||||||
|
'invoice' => $this->entity->number,
|
||||||
|
]
|
||||||
|
),
|
||||||
|
'url' => $this->invitation->getAdminLink(),
|
||||||
|
'button' => ctrans("texts.view_{$this->entity_type}"),
|
||||||
|
'signature' => $this->settings->email_signature,
|
||||||
|
'logo' => $this->company->present()->logo(),
|
||||||
|
];
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
}
|
@ -34,7 +34,7 @@ class CreditTest extends TestCase
|
|||||||
public function testCreditsList()
|
public function testCreditsList()
|
||||||
{
|
{
|
||||||
|
|
||||||
factory(Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) {
|
factory(Client::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c) {
|
||||||
factory(\App\Models\ClientContact::class, 1)->create([
|
factory(\App\Models\ClientContact::class, 1)->create([
|
||||||
'user_id' => $this->user->id,
|
'user_id' => $this->user->id,
|
||||||
'client_id' => $c->id,
|
'client_id' => $c->id,
|
||||||
|
@ -44,64 +44,30 @@ class InvoiceTest extends TestCase
|
|||||||
|
|
||||||
public function testInvoiceList()
|
public function testInvoiceList()
|
||||||
{
|
{
|
||||||
Account::all()->each(function($account) {
|
|
||||||
$account->delete();
|
|
||||||
});
|
|
||||||
|
|
||||||
$data = [
|
factory(\App\Models\Client::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id])->each(function ($c){
|
||||||
'first_name' => $this->faker->firstName,
|
|
||||||
'last_name' => $this->faker->lastName,
|
|
||||||
'name' => $this->faker->company,
|
|
||||||
'email' => $this->faker->unique()->safeEmail,
|
|
||||||
'password' => 'ALongAndBrilliantPassword123',
|
|
||||||
'_token' => csrf_token(),
|
|
||||||
'privacy_policy' => 1,
|
|
||||||
'terms_of_service' => 1
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
|
||||||
'X-API-SECRET' => config('ninja.api_secret'),
|
|
||||||
])->post('/api/v1/signup?include=account', $data);
|
|
||||||
|
|
||||||
$acc = $response->json();
|
|
||||||
|
|
||||||
$account = Account::find($this->decodePrimaryKey($acc['data'][0]['account']['id']));
|
|
||||||
|
|
||||||
$company_token = $account->default_company->tokens()->first();
|
|
||||||
$token = $company_token->token;
|
|
||||||
$company = $company_token->company;
|
|
||||||
|
|
||||||
$user = $company_token->user;
|
|
||||||
|
|
||||||
$this->assertNotNull($company_token);
|
|
||||||
$this->assertNotNull($token);
|
|
||||||
$this->assertNotNull($user);
|
|
||||||
$this->assertNotNull($company);
|
|
||||||
//$this->assertNotNull($user->token->company);
|
|
||||||
|
|
||||||
factory(\App\Models\Client::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id])->each(function ($c) use ($user, $company) {
|
|
||||||
factory(\App\Models\ClientContact::class, 1)->create([
|
factory(\App\Models\ClientContact::class, 1)->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $this->user->id,
|
||||||
'client_id' => $c->id,
|
'client_id' => $c->id,
|
||||||
'company_id' => $company->id,
|
'company_id' => $this->company->id,
|
||||||
'is_primary' => 1
|
'is_primary' => 1
|
||||||
]);
|
]);
|
||||||
|
|
||||||
factory(\App\Models\ClientContact::class, 1)->create([
|
factory(\App\Models\ClientContact::class, 1)->create([
|
||||||
'user_id' => $user->id,
|
'user_id' => $this->user->id,
|
||||||
'client_id' => $c->id,
|
'client_id' => $c->id,
|
||||||
'company_id' => $company->id
|
'company_id' => $this->company->id
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$client = Client::all()->first();
|
$client = Client::all()->first();
|
||||||
|
|
||||||
factory(\App\Models\Invoice::class, 1)->create(['user_id' => $user->id, 'company_id' => $company->id, 'client_id' => $client->id]);
|
factory(\App\Models\Invoice::class, 1)->create(['user_id' => $this->user->id, 'company_id' => $this->company->id, 'client_id' => $this->client->id]);
|
||||||
|
|
||||||
|
|
||||||
$response = $this->withHeaders([
|
$response = $this->withHeaders([
|
||||||
'X-API-SECRET' => config('ninja.api_secret'),
|
'X-API-SECRET' => config('ninja.api_secret'),
|
||||||
'X-API-TOKEN' => $token,
|
'X-API-TOKEN' => $this->token,
|
||||||
])->get('/api/v1/invoices');
|
])->get('/api/v1/invoices');
|
||||||
|
|
||||||
$response->assertStatus(200);
|
$response->assertStatus(200);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user