MultiDB domain resolution for client portals

This commit is contained in:
David Bomba 2021-05-15 13:31:41 +10:00
parent c38b948121
commit d7d76ae6ea
8 changed files with 69 additions and 24 deletions

View File

@ -34,13 +34,46 @@ class SetDomainNameDb
/* /*
* Use the host name to set the active DB * Use the host name to set the active DB
**/ **/
if ($request->getSchemeAndHttpHost() && config('ninja.db.multi_db_enabled') && ! MultiDB::findAndSetDbByDomain($request->getSchemeAndHttpHost())) {
if (request()->json) { if(!config('ninja.db.multi_db_enabled'))
return response()->json($error, 403); return $next($request);
} else {
abort(404);
if (strpos($request->getHost(), 'invoicing.co') !== false)
{
$subdomain = array_first(explode('.', $request->getHost()));
$query = [
'subdomain' => $subdomain,
'portal_mode' => 'subdomain',
];
if(!MultiDB::findAndSetDbByDomain($query)){
if ($request->json) {
return response()->json($error, 403);
} else {
abort(400, 'Domain not found');
}
} }
} }
else {
$query = [
'portal_domain' => $request->getHost(),
'portal_mode' => 'domain',
];
if(!MultiDB::findAndSetDbByDomain($query)){
if ($request->json) {
return response()->json($error, 403);
} else {
abort(400, 'Domain not found');
}
}
}
return $next($request); return $next($request);
} }

View File

@ -431,7 +431,6 @@ class CompanyExport implements ShouldQueue
private function zipAndSend() private function zipAndSend()
{ {
nlog("zipping");
$tempStream = fopen('php://memory', 'w+'); $tempStream = fopen('php://memory', 'w+');
@ -450,11 +449,8 @@ class CompanyExport implements ShouldQueue
$zip->finish(); $zip->finish();
$path = 'backups/'; $path = 'backups/';
nlog($path.$file_name);
Storage::disk(config('filesystems.default'))->put($path.$file_name, $tempStream); Storage::disk(config('filesystems.default'))->put($path.$file_name, $tempStream);
// fclose($fp);
fclose($tempStream); fclose($tempStream);

View File

@ -57,6 +57,8 @@ class NinjaMailerJob implements ShouldQueue
public $override; public $override;
public $company;
public function __construct(NinjaMailerObject $nmo, bool $override = false) public function __construct(NinjaMailerObject $nmo, bool $override = false)
{ {
@ -73,7 +75,8 @@ class NinjaMailerJob implements ShouldQueue
/*Set the correct database*/ /*Set the correct database*/
MultiDB::setDb($this->nmo->company->db); MultiDB::setDb($this->nmo->company->db);
$company = Company::where('company_key', $this->nmo->company->company_key)->first(); /* Serializing models from other jobs wipes the primary key */
$this->company = Company::where('company_key', $this->nmo->company->company_key)->first();
/* Set the email driver */ /* Set the email driver */
$this->setMailDriver(); $this->setMailDriver();
@ -89,7 +92,7 @@ class NinjaMailerJob implements ShouldQueue
} }
else { else {
$this->nmo->mailable->replyTo($company->owner()->email, $company->owner()->present()->name()); $this->nmo->mailable->replyTo($this->company->owner()->email, $this->company->owner()->present()->name());
} }
@ -178,7 +181,15 @@ class NinjaMailerJob implements ShouldQueue
nlog("Sending via {$user->name()}"); nlog("Sending via {$user->name()}");
$google = (new Google())->init(); $google = (new Google())->init();
$google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
try{
$google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
}
catch(\Exception $e) {
$this->logMailError('Gmail Token Invalid', $this->company->clients()->first());
$this->nmo->settings->email_sending_method = 'default';
return $this->setMailDriver();
}
if ($google->getClient()->isAccessTokenExpired()) { if ($google->getClient()->isAccessTokenExpired()) {
$google->refreshToken($user); $google->refreshToken($user);

View File

@ -253,14 +253,14 @@ class MultiDB
return false; return false;
} }
public static function findAndSetDbByDomain($subdomain) :bool public static function findAndSetDbByDomain($query_array) :bool
{ {
if (! config('ninja.db.multi_db_enabled')) if (! config('ninja.db.multi_db_enabled'))
return (Company::whereSubdomain($subdomain)->exists() === true); return (Company::where($query_array)->exists() === true);
foreach (self::$dbs as $db) { foreach (self::$dbs as $db) {
if ($company = Company::on($db)->whereSubdomain($subdomain)->first()) { if ($company = Company::on($db)->where($query_array)->first()) {
self::setDb($company->db); self::setDb($company->db);
return true; return true;
} }

View File

@ -30,14 +30,15 @@ class DownloadBackup extends Mailable
$company = Company::where('company_key', $this->company->company_key)->first(); $company = Company::where('company_key', $this->company->company_key)->first();
return $this->from(config('mail.from.address'), config('mail.from.name')) return $this->from(config('mail.from.address'), config('mail.from.name'))
->subject(ctrans('texts.download_backup_subject')) ->subject(ctrans('texts.download_backup_subject', ['company' => $company->present()->name()]))
->markdown( ->markdown(
'email.admin.download_files', 'email.admin.download_files',
[ [
'url' => $this->file_path, 'url' => $this->file_path,
'logo' => $company->present()->logo, 'logo' => $company->present()->logo,
'whitelabel' => $company->account->isPaid() ? true : false, 'whitelabel' => $company->account->isPaid() ? true : false,
'settings' => $company->settings 'settings' => $company->settings,
'greeting' => $company->present()->name(),
] ]
); );
} }

View File

@ -4248,7 +4248,7 @@ $LANG = array(
'activity_104' => ':user restored recurring invoice :recurring_invoice', 'activity_104' => ':user restored recurring invoice :recurring_invoice',
'new_login_detected' => 'New login detected for your account.', 'new_login_detected' => 'New login detected for your account.',
'new_login_description' => 'You recently logged in to your Invoice Ninja account from a new location or device:<br><br><b>IP:</b> :ip<br><b>Time:</b> :time<br><b>Email:</b> :email', 'new_login_description' => 'You recently logged in to your Invoice Ninja account from a new location or device:<br><br><b>IP:</b> :ip<br><b>Time:</b> :time<br><b>Email:</b> :email',
'download_backup_subject' => 'Your company backup is ready for download', 'download_backup_subject' => ':company backup is ready for download',
); );
return $LANG; return $LANG;

View File

@ -7,15 +7,20 @@
@endslot @endslot
@slot('greeting')
@endslot
@if(isset($greeting))
<p style="padding-top:20px">{{ $greeting }}</p>
@endif
<p style="padding-top:20px">
@lang('texts.download_timeframe') @lang('texts.download_timeframe')
</p>
<p style="padding-top:20px">
@component('email.components.button', ['url' => $url]) @component('email.components.button', ['url' => $url])
@lang('texts.download') @lang('texts.download')
@endcomponent @endcomponent
</p>
@slot('signature') @slot('signature')
InvoiceNinja (contact@invoiceninja.com) InvoiceNinja (contact@invoiceninja.com)

View File

@ -26,8 +26,7 @@ Route::get('client/magic_link/{magic_link}', 'ClientPortal\ContactHashLoginContr
Route::get('documents/{document_hash}', 'ClientPortal\DocumentController@publicDownload')->name('documents.public_download'); Route::get('documents/{document_hash}', 'ClientPortal\DocumentController@publicDownload')->name('documents.public_download');
Route::get('error', 'ClientPortal\ContactHashLoginController@errorPage')->name('client.error'); Route::get('error', 'ClientPortal\ContactHashLoginController@errorPage')->name('client.error');
//todo implement domain DB Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence','domain_db'], 'prefix' => 'client', 'as' => 'client.'], function () {
Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence'], 'prefix' => 'client', 'as' => 'client.'], function () {
Route::get('dashboard', 'ClientPortal\DashboardController@index')->name('dashboard'); // name = (dashboard. index / create / show / update / destroy / edit Route::get('dashboard', 'ClientPortal\DashboardController@index')->name('dashboard'); // name = (dashboard. index / create / show / update / destroy / edit
Route::get('invoices', 'ClientPortal\InvoiceController@index')->name('invoices.index')->middleware('portal_enabled'); Route::get('invoices', 'ClientPortal\InvoiceController@index')->name('invoices.index')->middleware('portal_enabled');
@ -81,7 +80,7 @@ Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence
Route::get('logout', 'Auth\ContactLoginController@logout')->name('logout'); Route::get('logout', 'Auth\ContactLoginController@logout')->name('logout');
}); });
Route::get('client/subscription/{subscription}/purchase/', 'ClientPortal\SubscriptionPurchaseController@index')->name('client.subscription.purchase'); Route::get('client/subscription/{subscription}/purchase', 'ClientPortal\SubscriptionPurchaseController@index')->name('client.subscription.purchase')->middleware('domain_db');
Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'client.'], function () { Route::group(['middleware' => ['invite_db'], 'prefix' => 'client', 'as' => 'client.'], function () {
/*Invitation catches*/ /*Invitation catches*/