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
**/
if ($request->getSchemeAndHttpHost() && config('ninja.db.multi_db_enabled') && ! MultiDB::findAndSetDbByDomain($request->getSchemeAndHttpHost())) {
if (request()->json) {
return response()->json($error, 403);
} else {
abort(404);
if(!config('ninja.db.multi_db_enabled'))
return $next($request);
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);
}

View File

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

View File

@ -57,6 +57,8 @@ class NinjaMailerJob implements ShouldQueue
public $override;
public $company;
public function __construct(NinjaMailerObject $nmo, bool $override = false)
{
@ -73,7 +75,8 @@ class NinjaMailerJob implements ShouldQueue
/*Set the correct database*/
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 */
$this->setMailDriver();
@ -89,7 +92,7 @@ class NinjaMailerJob implements ShouldQueue
}
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()}");
$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()) {
$google->refreshToken($user);

View File

@ -253,14 +253,14 @@ class MultiDB
return false;
}
public static function findAndSetDbByDomain($subdomain) :bool
public static function findAndSetDbByDomain($query_array) :bool
{
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) {
if ($company = Company::on($db)->whereSubdomain($subdomain)->first()) {
if ($company = Company::on($db)->where($query_array)->first()) {
self::setDb($company->db);
return true;
}

View File

@ -30,14 +30,15 @@ class DownloadBackup extends Mailable
$company = Company::where('company_key', $this->company->company_key)->first();
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(
'email.admin.download_files',
[
'url' => $this->file_path,
'logo' => $company->present()->logo,
'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',
'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',
'download_backup_subject' => 'Your company backup is ready for download',
'download_backup_subject' => ':company backup is ready for download',
);
return $LANG;

View File

@ -7,15 +7,20 @@
@endslot
@slot('greeting')
@endslot
@if(isset($greeting))
<p style="padding-top:20px">{{ $greeting }}</p>
@endif
<p style="padding-top:20px">
@lang('texts.download_timeframe')
</p>
<p style="padding-top:20px">
@component('email.components.button', ['url' => $url])
@lang('texts.download')
@endcomponent
</p>
@slot('signature')
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('error', 'ClientPortal\ContactHashLoginController@errorPage')->name('client.error');
//todo implement domain DB
Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence'], 'prefix' => 'client', 'as' => 'client.'], function () {
Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence','domain_db'], 'prefix' => 'client', 'as' => 'client.'], function () {
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');
@ -81,7 +80,7 @@ Route::group(['middleware' => ['auth:contact', 'locale', 'check_client_existence
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 () {
/*Invitation catches*/