diff --git a/app/Http/Controllers/EmailController.php b/app/Http/Controllers/EmailController.php
index 4ecad444a932..b18360285b73 100644
--- a/app/Http/Controllers/EmailController.php
+++ b/app/Http/Controllers/EmailController.php
@@ -21,8 +21,6 @@ use Illuminate\Http\Response;
use App\Utils\Traits\MakesHash;
use App\Jobs\Entity\EmailEntity;
use App\Models\RecurringInvoice;
-use App\Services\Email\MailEntity;
-use App\Services\Email\MailObject;
use App\Services\Email\EmailObject;
use App\Events\Quote\QuoteWasEmailed;
use App\Transformers\QuoteTransformer;
@@ -121,7 +119,6 @@ class EmailController extends BaseController
$entity_obj = $entity::withTrashed()->with('invitations')->find($request->input('entity_id'));
$subject = $request->has('subject') ? $request->input('subject') : '';
$body = $request->has('body') ? $request->input('body') : '';
- $entity_string = strtolower(class_basename($entity_obj));
$template = str_replace('email_template_', '', $request->input('template'));
$data = [
@@ -133,10 +130,10 @@ class EmailController extends BaseController
$mo->subject = strlen($subject) > 3 ? $subject : null;
$mo->body = strlen($body) > 3 ? $body : null;
$mo->entity_id = $request->input('entity_id');
- $mo->template = $template;
+ $mo->template = $template; //full template name in use
$mo->entity_class = $this->resolveClass($entity);
- $mo->email_template_body = "email_template_{$template}";
- $mo->email_template_subject = "email_subject_{$template}";
+ $mo->email_template_body = $template;
+ $mo->email_template_subject = str_replace("template", "subject", $template);
if (Ninja::isHosted() && !$entity_obj->company->account->account_sms_verified) {
return response(['message' => 'Please verify your account to send emails.'], 400);
@@ -146,7 +143,7 @@ class EmailController extends BaseController
return $this->sendPurchaseOrder($entity_obj, $data, $template);
}
- $entity_obj->invitations->each(function ($invitation) use ($data, $entity_string, $entity_obj, $template, $mo) {
+ $entity_obj->invitations->each(function ($invitation) use ($data, $entity_obj, $template, $mo) {
if (! $invitation->contact->trashed() && $invitation->contact->email) {
$entity_obj->service()->markSent()->save();
@@ -155,7 +152,7 @@ class EmailController extends BaseController
$mo->invitation_id = $invitation->id;
Email::dispatch($mo, $invitation->company);
- // MailEntity::dispatch($invitation, $invitation->company->db, $mo);
+
}
});
@@ -214,10 +211,14 @@ class EmailController extends BaseController
private function resolveClass(string $entity): string
{
+
match($entity){
'invoice' => $class = Invoice::class,
+ 'App\Models\Invoice' => $class = Invoice::class,
'credit' => $class = Credit::class,
+ 'App\Models\Credit' => $class = Credit::class,
'quote' => $class = Quote::class,
+ 'App\Models\Quote' => $class = Quote::class,
'purchase_order' => $class = PurchaseOrder::class,
'purchaseOrder' => $class = PurchaseOrder::class,
'App\Models\PurchaseOrder' => $class = PurchaseOrder::class,
@@ -225,5 +226,6 @@ class EmailController extends BaseController
};
return $class;
+
}
}
diff --git a/app/Services/Email/EmailDefaults.php b/app/Services/Email/EmailDefaults.php
index 9d13bd5ce9ab..0178a8b7cee9 100644
--- a/app/Services/Email/EmailDefaults.php
+++ b/app/Services/Email/EmailDefaults.php
@@ -134,7 +134,6 @@ class EmailDefaults
*/
private function setTo(): self
{
-
if ($this->email->email_object->to) {
return $this;
}
@@ -150,10 +149,13 @@ class EmailDefaults
private function setBody(): self
{
if ($this->email->email_object->body) {
- $this->email->email_object->body = $this->email->email_object->body;
+ // A Custom Message has been set in the email screen.
+ return $this;
} elseif (strlen($this->email->email_object->settings?->{$this->email->email_object->email_template_body}) > 3) {
+ // A body has been saved in the settings.
$this->email->email_object->body = $this->email->email_object->settings?->{$this->email->email_object->email_template_body};
} else {
+ // Default template to be used
$this->email->email_object->body = EmailTemplateDefaults::getDefaultTemplate($this->email->email_object->email_template_body, $this->locale);
}
@@ -207,7 +209,7 @@ class EmailDefaults
if ($this->template != 'custom') {
$this->email->email_object->body = $this->parseMarkdownToHtml($this->email->email_object->body);
}
-nlog($this->email->email_object->subject);
+ nlog($this->email->email_object->subject);
return $this;
}
diff --git a/app/Services/Email/MailBuild.php b/app/Services/Email/MailBuild.php
deleted file mode 100644
index 51ac2a89e452..000000000000
--- a/app/Services/Email/MailBuild.php
+++ /dev/null
@@ -1,570 +0,0 @@
-resolveEntities()
- ->setLocale()
- ->setMetaData()
- ->setFrom()
- ->setTo()
- ->setTemplate()
- ->setSubject()
- ->setBody()
- ->setReplyTo()
- ->setBcc()
- ->setAttachments()
- ->setVariables();
-
- return $this;
- }
-
- /**
- * Returns the mailable to the mailer
- *
- * @return Mailable
- */
- public function getMailable(): Mailable
- {
- return new MailMailable($this->mail_entity->mail_object);
- }
-
- /**
- * Resolve any class entities
- *
- * @return self
- */
- private function resolveEntities(): self
- {
- $client_contact = $this->mail_entity?->invitation?->client_contact_id ? ClientContact::withTrashed()->find($this->mail_entity->invitation->client_contact_id) : null;
-
- $this->client = $client_contact?->client;
-
- $vendor_contact = $this->mail_entity?->invitation?->vendor_contact_id ? VendorContact::withTrashed()->find($this->mail_entity->invitation->vendor_contact_id) : null;
-
- $this->vendor = $vendor_contact?->vendor;
-
- if ($this->mail_entity?->invitation) {
- if ($this->mail_entity->invitation?->invoice) {
- $this->mail_entity->mail_object->entity_string = 'invoice';
- $this->mail_entity->mail_object->entity_class = Invoice::class;
- }
-
- if ($this->mail_entity->invitation?->quote) {
- $this->mail_entity->mail_object->entity_string = 'quote';
- $this->mail_entity->mail_object->entity_class = Quote::class;
- }
-
- if ($this->mail_entity->invitation?->credit) {
- $this->mail_entity->mail_object->entity_string = 'credit';
- $this->mail_entity->mail_object->entity_class = Credit::class;
- }
-
- if ($this->mail_entity->invitation?->puchase_order) {
- $this->mail_entity->mail_object->entity_string = 'purchase_order';
- $this->mail_entity->mail_object->entity_class = PurchaseOrder::class;
- }
- }
-
- return $this;
- }
-
- /**
- * Sets the locale
- * Sets the settings object depending on context
- * Sets the HTML variables depending on context
- *
- * @return self
- */
- private function setLocale(): self
- {
- if ($this->client) {
- $this->locale = $this->client->locale();
- $this->settings = $this->client->getMergedSettings();
-
- if ($this->mail_entity->invitation) {
- $this->variables = (new HtmlEngine($this->mail_entity->invitation))->makeValues();
- }
- } elseif ($this->vendor) {
- $this->locale = $this->vendor->locale();
- $this->settings = $this->mail_entity->company->settings;
-
- if ($this->mail_entity->invitation) {
- $this->variables = (new VendorHtmlEngine($this->mail_entity->invitation))->makeValues();
- }
- } else {
- $this->locale = $this->mail_entity->company->locale();
- $this->settings = $this->mail_entity->company->settings;
- }
-
- $this->mail_entity->mail_object->settings = $this->settings;
-
- App::setLocale($this->locale);
- App::forgetInstance('translator');
- $t = app('translator');
- $t->replace(Ninja::transformTranslations($this->settings));
-
- return $this;
- }
-
- /**
- * Sets the meta data for the Email object
- *
- * @return self
- */
- private function setMetaData(): self
- {
- $this->mail_entity->mail_object->company_key = $this->mail_entity->company->company_key;
-
- $this->mail_entity->mail_object->logo = $this->mail_entity->company->present()->logo();
-
- $this->mail_entity->mail_object->signature = $this->mail_entity->mail_object->signature ?: $this->settings->email_signature;
-
- $this->mail_entity->mail_object->whitelabel = $this->mail_entity->company->account->isPaid() ? true : false;
-
- $this->mail_entity->mail_object->company = $this->mail_entity->company;
-
- return $this;
- }
-
- /**
- * Sets the template
- *
- * @return self
- */
- private function setTemplate(): self
- {
- $this->template = $this->settings->email_style;
-
- match ($this->settings->email_style) {
- 'light' => $this->template = 'email.template.client',
- 'dark' => $this->template = 'email.template.client',
- 'custom' => $this->template = 'email.template.custom',
- default => $this->template = 'email.template.client',
- };
-
- $this->mail_entity->mail_object->html_template = $this->template;
-
- return $this;
- }
-
- /**
- * setTo
- *
- * @return self
- */
- private function setTo(): self
- {
- $this->mail_entity->mail_object->to = array_merge(
- $this->mail_entity->mail_object->to,
- [new Address($this->mail_entity->invitation->contact->email, $this->mail_entity->invitation->contact->present()->name())]
- );
-
- return $this;
- }
-
- /**
- * Sets the FROM address
- *
- * @return self
- */
- private function setFrom(): self
- {
- if (Ninja::isHosted() && $this->settings->email_sending_method == 'default') {
- $this->mail_entity->mail_object->from = new Address(config('mail.from.address'), $this->mail_entity->company->owner()->name());
- return $this;
- }
-
- if ($this->mail_entity->mail_object->from) {
- return $this;
- }
-
- $this->mail_entity->mail_object->from = new Address($this->mail_entity->company->owner()->email, $this->mail_entity->company->owner()->name());
-
- return $this;
- }
-
- /**
- * Sets the subject of the email
- *
- * @return self
- */
- private function setSubject(): self
- {
- if ($this->mail_entity->mail_object->subject) { //where the user updates the subject from the UI
- return $this;
- } elseif (is_string($this->mail_entity->mail_object->email_template) && strlen($this->settings->{$this->resolveBaseEntityTemplate()}) > 3) {
- $this->mail_entity->mail_object->subject = $this->settings->{$this->resolveBaseEntityTemplate()};
- } else {
- $this->mail_entity->mail_object->subject = EmailTemplateDefaults::getDefaultTemplate($this->resolveBaseEntityTemplate(), $this->locale);
- }
-
- return $this;
- }
-
- /**
- * Sets the body of the email
- *
- * @return self
- */
- private function setBody(): self
- {
- if ($this->mail_entity->mail_object->body) {
- $this->mail_entity->mail_object->body = $this->mail_entity->mail_object->body;
- } elseif (is_string($this->mail_entity->mail_object->email_template) && strlen($this->settings->{$this->resolveBaseEntityTemplate('body')}) > 3) {
- $this->mail_entity->mail_object->body = $this->settings->{$this->resolveBaseEntityTemplate('body')};
- } else {
- $this->mail_entity->mail_object->body = EmailTemplateDefaults::getDefaultTemplate($this->resolveBaseEntityTemplate('body'), $this->locale);
- }
-
- if ($this->template == 'email.template.custom') {
- $this->mail_entity->mail_object->body = (str_replace('$body', $this->mail_entity->mail_object->body, $this->settings->email_style_custom));
- }
-
- return $this;
- }
-
- /**
- * Where no template is explicitly passed, we need to infer by the entity type -
- * which is hopefully resolvable.
- *
- * @param string $type
- * @return string
- */
- private function resolveBaseEntityTemplate(string $type = 'subject'): string
- {
- if ($this->mail_entity->mail_object->email_template) {
- match ($type) {
- 'subject' => $template = "email_subject_{$this->mail_entity->mail_object->email_template}",
- 'body' => $template = "email_template_{$this->mail_entity->mail_object->email_template}",
- default => $template = "email_template_invoice",
- };
-
- return $template;
- }
-
- //handle statements being emailed
- //handle custom templates these types won't have a resolvable entity_string
- if (!$this->mail_entity->mail_object->entity_string) {
- return 'email_template_invoice';
- }
-
- match ($type) {
- 'subject' => $template = "email_subject_{$this->mail_entity->mail_object->entity_string}",
- 'body' => $template = "email_template_{$this->mail_entity->mail_object->entity_string}",
- default => $template = "email_template_invoice",
- };
-
- return $template;
- }
-
- /**
- * Sets the attachments for the email
- *
- * Note that we base64 encode these, as they
- * sometimes may not survive serialization.
- *
- * We decode these in the Mailable later
- *
- * @return self
- */
- private function setAttachments(): self
- {
- $this->setContextAttachments();
-
- if ($this->settings->document_email_attachment && $this->mail_entity->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
- $this->attachDocuments($this->mail_entity->company->documents);
- }
-
- return $this;
- }
-
- private function attachDocuments($documents): self
- {
- foreach ($documents as $document) {
- if ($document->size > $this->max_attachment_size) {
- $this->mail_entity->mail_object->attachment_links = array_merge($this->mail_entity->mail_object->attachment_links, [[" $document->hash]) ."'>". $document->name .""]]);
- } else {
- $this->mail_entity->mail_object->attachments = array_merge($this->mail_entity->mail_object->attachments, [['file' => base64_encode($document->getFile()), 'name' => $document->name]]);
- }
- }
-
- return $this;
- }
-
- /**
- * Depending on context we may need to resolve the
- * attachment dependencies.
- *
- * ie. Resolve the entity.
- * ie. Resolve if we should attach the Entity PDF
- * ie. Create the Entity PDF
- * ie. Inject the PDF
- *
- * @return self
- */
- private function setContextAttachments(): self
- {
- if (!$this->settings->pdf_email_attachment || !$this->mail_entity->company->account->hasFeature(Account::FEATURE_PDF_ATTACHMENT)) {
- return $this;
- }
-
- if ($this->mail_entity->invitation?->purchase_order) {
- $pdf = (new CreatePurchaseOrderPdf($this->mail_entity->invitation))->rawPdf();
-
- $this->mail_entity->mail_object->attachments = array_merge($this->mail_entity->mail_object->attachments, [['file' => base64_encode($pdf), 'name' => $this->mail_entity->invitation->purchase_order->numberFormatter().'.pdf']]);
-
- if ($this->vendor->getSetting('document_email_attachment') !== false && $this->mail_entity->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
- $this->attachDocuments($this->mail_entity->invitation->purchase_order->documents);
- }
-
- return $this;
- }
-
- if (!$this->mail_entity->mail_object->entity_string) {
- return $this;
- }
-
- $pdf = ((new CreateRawPdf($this->mail_entity->invitation, $this->mail_entity->invitation->company->db))->handle());
-
- $this->mail_entity->mail_object->attachments = array_merge($this->mail_entity->mail_object->attachments, [['file' => base64_encode($pdf), 'name' => $this->mail_entity->invitation->{$this->mail_entity->mail_object->entity_string}->numberFormatter().'.pdf']]);
-
- if ($this->client->getSetting('document_email_attachment') !== false && $this->mail_entity->company->account->hasFeature(Account::FEATURE_DOCUMENTS)) {
- $this->attachDocuments($this->mail_entity->invitation->{$this->mail_entity->mail_object->entity_string}->documents);
- }
-
- return $this;
-
-
-
-
- if ($this->settings->ubl_email_attachment && $this->mail_entity->mail_object->entity_string == 'invoice') {
- }
-
- if ($this->mail_entity->mail_object->entity_string == 'invoice') {
- $line_items = $this->mail_entity->invitation->invoice->line_items;
-
- foreach ($line_items as $item) {
- $expense_ids = [];
-
- if (property_exists($item, 'expense_id')) {
- $expense_ids[] = $item->expense_id;
- }
-
- if (count($expense_ids) > 0) {
- $expenses = Expense::whereIn('id', $this->transformKeys($expense_ids))
- ->where('invoice_documents', 1)
- ->cursor()
- ->each(function ($expense) {
- $this->attachDocuments($expense->documents);
- });
- }
-
- $task_ids = [];
-
- if (property_exists($item, 'task_id')) {
- $task_ids[] = $item->task_id;
- }
-
- if (count($task_ids) > 0 && $this->mail_entity->company->invoice_task_documents) {
- $tasks = Task::whereIn('id', $this->transformKeys($task_ids))
- ->cursor()
- ->each(function ($task) {
- $this->attachDocuments($task->documents);
- });
- }
- }
- }
-
-
- return $this;
- }
-
-
- /**
- * Sets the reply to of the email
- *
- * @return self
- */
- private function setReplyTo(): self
- {
- $reply_to_email = str_contains($this->settings->reply_to_email, "@") ? $this->settings->reply_to_email : $this->mail_entity->company->owner()->email;
-
- $reply_to_name = strlen($this->settings->reply_to_name) > 3 ? $this->settings->reply_to_name : $this->mail_entity->company->owner()->present()->name();
-
- $this->mail_entity->mail_object->reply_to = array_merge($this->mail_entity->mail_object->reply_to, [new Address($reply_to_email, $reply_to_name)]);
-
- return $this;
- }
-
- /**
- * Replaces the template placeholders
- * with variable values.
- *
- * @return self
- */
- public function setVariables(): self
- {
- if ($this->mail_entity->mail_object->variables) {
- $this->mail_entity->mail_object->subject = strtr($this->mail_entity->mail_object->subject, $this->mail_entity->mail_object->variables);
- $this->mail_entity->mail_object->body = strtr($this->mail_entity->mail_object->body, $this->mail_entity->mail_object->variables);
- }
-
- $this->mail_entity->mail_object->subject = strtr($this->mail_entity->mail_object->subject, $this->variables);
- $this->mail_entity->mail_object->body = strtr($this->mail_entity->mail_object->body, $this->variables);
-
- if ($this->template != 'custom') {
- $this->mail_entity->mail_object->body = $this->parseMarkdownToHtml($this->mail_entity->mail_object->body);
- }
-
- return $this;
- }
-
- /**
- * Sets the BCC of the email
- *
- * @return self
- */
- private function setBcc(): self
- {
- $bccs = [];
- $bcc_array = [];
-
- if (strlen($this->settings->bcc_email) > 1) {
- if (Ninja::isHosted() && $this->mail_entity->company->account->isPaid()) {
- $bccs = array_slice(explode(',', str_replace(' ', '', $this->settings->bcc_email)), 0, 2);
- } elseif (Ninja::isSelfHost()) {
- $bccs = (explode(',', str_replace(' ', '', $this->settings->bcc_email)));
- }
- }
-
- foreach ($bccs as $bcc) {
- $bcc_array[] = new Address($bcc);
- }
-
- $this->mail_entity->mail_object->bcc = array_merge($this->mail_entity->mail_object->bcc, $bcc_array);
-
- return $this;
- }
-
- /**
- * Sets the CC of the email
- * @todo at some point....
- */
- private function buildCc()
- {
- return [
-
- ];
- }
-
-
- /**
- * Sets the headers for the email
- *
- * @return self
- */
- private function setHeaders(): self
- {
- if ($this->mail_entity->mail_object->invitation_key) {
- $this->mail_entity->mail_object->headers = array_merge($this->mail_entity->mail_object->headers, ['x-invitation-key' => $this->mail_entity->mail_object->invitation_key]);
- } elseif ($this->mail_entity->invitation) {
- $this->mail_entity->mail_object->headers = array_merge($this->mail_entity->mail_object->headers, ['x-invitation-key' => $this->mail_entity->invitation->key]);
- }
-
- return $this;
- }
-
- /**
- * Converts any markdown to HTML in the email
- *
- * @param string $markdown The body to convert
- * @return string The parsed markdown response
- */
- private function parseMarkdownToHtml(string $markdown): ?string
- {
- $converter = new CommonMarkConverter([
- 'allow_unsafe_links' => false,
- ]);
-
- return $converter->convert($markdown);
- }
-}
diff --git a/app/Services/Email/MailEntity.php b/app/Services/Email/MailEntity.php
deleted file mode 100644
index 64629e57f523..000000000000
--- a/app/Services/Email/MailEntity.php
+++ /dev/null
@@ -1,589 +0,0 @@
-db);
-
- /* Where there are no invitations, we need to harvest the company and also use the correct context to build the mailable*/
- $this->company = $this->invitation->company;
-
- $this->override = $this->mail_object->override;
-
- $builder = new MailBuild($this);
-
- /* Construct Mailable */
- $builder->run($this);
-
- $this->mailable = $builder->getMailable();
-
- /* Email quality checks */
- if ($this->preFlightChecksFail()) {
- return;
- }
-
- /* Try sending email */
- $this->setMailDriver()
- ->configureMailer()
- ->trySending();
- }
-
- /**
- * configureMailer
- *
- * @return self
- */
- public function configureMailer(): self
- {
- $this->mail = Mail::mailer($this->mailer);
-
- if ($this->client_postmark_secret) {
- $this->mail->postmark_config($this->client_postmark_secret);
- }
-
- if ($this->client_mailgun_secret) {
- $this->mail->mailgun_config($this->client_mailgun_secret, $this->client_mailgun_domain);
- }
-
- return $this;
- }
-
-
- /**
- * Sets the mail driver to use and applies any specific configuration
- * the the mailable
- */
- private function setMailDriver(): self
- {
- switch ($this->mail_object->settings->email_sending_method) {
- case 'default':
- $this->mailer = config('mail.default');
- break;
- case 'gmail':
- $this->mailer = 'gmail';
- $this->setGmailMailer();
- return $this;
- case 'office365':
- $this->mailer = 'office365';
- $this->setOfficeMailer();
- return $this;
- case 'client_postmark':
- $this->mailer = 'postmark';
- $this->setPostmarkMailer();
- return $this;
- case 'client_mailgun':
- $this->mailer = 'mailgun';
- $this->setMailgunMailer();
- return $this;
-
- default:
- break;
- }
-
- if (Ninja::isSelfHost()) {
- $this->setSelfHostMultiMailer();
- }
-
- return $this;
- }
-
- /**
- * Allows configuration of multiple mailers
- * per company for use by self hosted users
- */
- private function setSelfHostMultiMailer(): void
- {
- if (env($this->company->id . '_MAIL_HOST')) {
- config([
- 'mail.mailers.smtp' => [
- 'transport' => 'smtp',
- 'host' => env($this->company->id . '_MAIL_HOST'),
- 'port' => env($this->company->id . '_MAIL_PORT'),
- 'username' => env($this->company->id . '_MAIL_USERNAME'),
- 'password' => env($this->company->id . '_MAIL_PASSWORD'),
- ],
- ]);
-
- if (env($this->company->id . '_MAIL_FROM_ADDRESS')) {
- $this->mailable
- ->from(env($this->company->id . '_MAIL_FROM_ADDRESS', env('MAIL_FROM_ADDRESS')), env($this->company->id . '_MAIL_FROM_NAME', env('MAIL_FROM_NAME')));
- }
- }
- }
-
-
- /**
- * Ensure we discard any data that is not required
- *
- * @return void
- */
- private function cleanUpMailers(): void
- {
- $this->client_postmark_secret = false;
-
- $this->client_mailgun_secret = false;
-
- $this->client_mailgun_domain = false;
-
- app('mail.manager')->forgetMailers();
- }
-
-
- /**
- * Attempts to send the email
- *
- * @return void
- */
- public function trySending(): void
- {
- try {
- $this->mail->send($this->mailable);
-
- /* Count the amount of emails sent across all the users accounts */
- Cache::increment($this->company->account->key);
-
- LightLogs::create(new EmailSuccess($this->company->company_key))
- ->send();
- } catch(\Symfony\Component\Mime\Exception\RfcComplianceException $e) {
- nlog("Mailer failed with a Logic Exception {$e->getMessage()}");
- $this->fail();
- $this->cleanUpMailers();
- // $this->logMailError($e->getMessage(), $this->company->clients()->first());
- return;
- } catch(\Symfony\Component\Mime\Exception\LogicException $e) {
- nlog("Mailer failed with a Logic Exception {$e->getMessage()}");
- $this->fail();
- $this->cleanUpMailers();
- // $this->logMailError($e->getMessage(), $this->company->clients()->first());
- return;
- } catch (\Exception | \Google\Service\Exception $e) {
- nlog("Mailer failed with {$e->getMessage()}");
- $message = $e->getMessage();
-
- /**
- * Post mark buries the proper message in a a guzzle response
- * this merges a text string with a json object
- * need to harvest the ->Message property using the following
- */
- if (stripos($e->getMessage(), 'code 406') || stripos($e->getMessage(), 'code 300') || stripos($e->getMessage(), 'code 413')) {
- $message = "Either Attachment too large, or recipient has been suppressed.";
-
- $this->fail();
- // $this->logMailError($e->getMessage(), $this->company->clients()->first());
- $this->cleanUpMailers();
-
- return;
- }
-
- //only report once, not on all tries
- if ($this->attempts() == $this->tries) {
- /* If the is an entity attached to the message send a failure mailer */
- if ($this->mail_object->entity_id) {
- // $this->entityEmailFailed($message);
-
- /* Don't send postmark failures to Sentry */
- if (Ninja::isHosted() && (!$e instanceof ClientException)) {
- app('sentry')->captureException($e);
- }
- }
- }
-
- /* Releasing immediately does not add in the backoff */
- $this->release($this->backoff()[$this->attempts()-1]);
- }
- }
-
- /**
- * On the hosted platform we scan all outbound email for
- * spam. This sequence processes the filters we use on all
- * emails.
- */
- public function preFlightChecksFail(): bool
- {
- /* Handle bad state */
- if (!$this->company) {
- return true;
- }
-
- /* Handle deactivated company */
- if ($this->company->is_disabled && !$this->override) {
- return true;
- }
-
- /* To handle spam users we drop all emails from flagged accounts */
- if (Ninja::isHosted() && $this->company->account && $this->company->account->is_flagged) {
- return true;
- }
-
- /* On the hosted platform we set default contacts a @example.com email address - we shouldn't send emails to these types of addresses */
- if ($this->hasInValidEmails()) {
- return true;
- }
-
- /* GMail users are uncapped */
- if (in_array($this->mail_object->settings->email_sending_method, ['gmail', 'office365', 'client_postmark', 'client_mailgun'])) {
- return false;
- }
-
- /* On the hosted platform, if the user is over the email quotas, we do not send the email. */
- if (Ninja::isHosted() && $this->company->account && $this->company->account->emailQuotaExceeded()) {
- return true;
- }
-
- /* If the account is verified, we allow emails to flow */
- if (Ninja::isHosted() && $this->company->account && $this->company->account->is_verified_account) {
- //11-01-2022
-
- /* Continue to analyse verified accounts in case they later start sending poor quality emails*/
- // if(class_exists(\Modules\Admin\Jobs\Account\EmailQuality::class))
- // (new \Modules\Admin\Jobs\Account\EmailQuality($this->mail_object, $this->company))->run();
-
- return false;
- }
-
-
- /* On the hosted platform if the user has not verified their account we fail here - but still check what they are trying to send! */
- if ($this->company->account && !$this->company->account->account_sms_verified) {
- if (class_exists(\Modules\Admin\Jobs\Account\EmailFilter::class)) {
- (new \Modules\Admin\Jobs\Account\EmailFilter($this->mail_object, $this->company))->run();
- }
-
- return true;
- }
-
- /* On the hosted platform we actively scan all outbound emails to ensure outbound email quality remains high */
- if (class_exists(\Modules\Admin\Jobs\Account\EmailFilter::class)) {
- (new \Modules\Admin\Jobs\Account\EmailFilter($this->mail_object, $this->company))->run();
- }
-
- return false;
- }
-
-
- /**
- * Checks if emails are have some illegal / required characters.
- *
- * @return bool
- */
- private function hasInValidEmails(): bool
- {
- if (Ninja::isSelfHost()) {
- return false;
- }
-
- foreach ($this->mail_object->to as $address_object) {
- if (strpos($address_object->address, '@example.com') !== false) {
- return true;
- }
-
- if (!str_contains($address_object->address, "@")) {
- return true;
- }
-
- if ($address_object->address == " ") {
- return true;
- }
- }
-
-
- return false;
- }
-
-
- /**
- * Check to ensure no cross account
- * emails can be sent.
- *
- * @param User $user
- */
- private function checkValidSendingUser($user)
- {
- /* Always ensure the user is set on the correct account */
- if ($user->account_id != $this->company->account_id) {
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
- }
-
- /**
- * Resolves the sending user
- * when configuring the Mailer
- * on behalf of the client
- *
- * @return User $user
- */
- private function resolveSendingUser(): ?User
- {
- $sending_user = $this->mail_object->settings->gmail_sending_user_id;
-
- if ($sending_user == "0") {
- $user = $this->company->owner();
- } else {
- $user = User::find($this->decodePrimaryKey($sending_user));
- }
-
- return $user;
- }
-
- /**
- * Configures Mailgun using client supplied secret
- * as the Mailer
- */
- private function setMailgunMailer()
- {
- if (strlen($this->mail_object->settings->mailgun_secret) > 2 && strlen($this->mail_object->settings->mailgun_domain) > 2) {
- $this->client_mailgun_secret = $this->mail_object->settings->mailgun_secret;
- $this->client_mailgun_domain = $this->mail_object->settings->mailgun_domain;
- } else {
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
-
- $user = $this->resolveSendingUser();
-
- $sending_email = (isset($this->mail_object->settings->custom_sending_email) && stripos($this->mail_object->settings->custom_sending_email, "@")) ? $this->mail_object->settings->custom_sending_email : $user->email;
- $sending_user = (isset($this->mail_object->settings->email_from_name) && strlen($this->mail_object->settings->email_from_name) > 2) ? $this->mail_object->settings->email_from_name : $user->name();
-
- $this->mailable
- ->from($sending_email, $sending_user);
- }
-
- /**
- * Configures Postmark using client supplied secret
- * as the Mailer
- */
- private function setPostmarkMailer()
- {
- if (strlen($this->mail_object->settings->postmark_secret) > 2) {
- $this->client_postmark_secret = $this->mail_object->settings->postmark_secret;
- } else {
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
-
- $user = $this->resolveSendingUser();
-
- $sending_email = (isset($this->mail_object->settings->custom_sending_email) && stripos($this->mail_object->settings->custom_sending_email, "@")) ? $this->mail_object->settings->custom_sending_email : $user->email;
- $sending_user = (isset($this->mail_object->settings->email_from_name) && strlen($this->mail_object->settings->email_from_name) > 2) ? $this->mail_object->settings->email_from_name : $user->name();
-
- $this->mailable
- ->from($sending_email, $sending_user);
- }
-
- /**
- * Configures Microsoft via Oauth
- * as the Mailer
- */
- private function setOfficeMailer()
- {
- $user = $this->resolveSendingUser();
-
- $this->checkValidSendingUser($user);
-
- nlog("Sending via {$user->name()}");
-
- $token = $this->refreshOfficeToken($user);
-
- if ($token) {
- $user->oauth_user_token = $token;
- $user->save();
- } else {
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
-
- $this->mailable
- ->from($user->email, $user->name())
- ->withSymfonyMessage(function ($message) use ($token) {
- $message->getHeaders()->addTextHeader('gmailtoken', $token);
- });
- }
-
- /**
- * Configures GMail via Oauth
- * as the Mailer
- */
- private function setGmailMailer()
- {
- $user = $this->resolveSendingUser();
-
- $this->checkValidSendingUser($user);
-
- nlog("Sending via {$user->name()}");
-
- $google = (new Google())->init();
-
- try {
- if ($google->getClient()->isAccessTokenExpired()) {
- $google->refreshToken($user);
- $user = $user->fresh();
- }
-
- $google->getClient()->setAccessToken(json_encode($user->oauth_user_token));
- } catch(\Exception $e) {
- // $this->logMailError('Gmail Token Invalid', $this->company->clients()->first());
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
-
- /**
- * If the user doesn't have a valid token, notify them
- */
-
- if (!$user->oauth_user_token) {
- $this->company->account->gmailCredentialNotification();
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
-
- /*
- * Now that our token is refreshed and valid we can boot the
- * mail driver at runtime and also set the token which will persist
- * just for this request.
- */
-
- $token = $user->oauth_user_token->access_token;
-
- if (!$token) {
- $this->company->account->gmailCredentialNotification();
- $this->mail_object->settings->email_sending_method = 'default';
- return $this->setMailDriver();
- }
-
- $this->mailable
- ->from($user->email, $user->name())
- ->withSymfonyMessage(function ($message) use ($token) {
- $message->getHeaders()->addTextHeader('gmailtoken', $token);
- });
- }
-
- /**
- * Attempts to refresh the Microsoft refreshToken
- *
- * @param App\Models\User
- * @return string | boool
- */
- private function refreshOfficeToken($user)
- {
- $expiry = $user->oauth_user_token_expiry ?: now()->subDay();
-
- if ($expiry->lt(now())) {
- $guzzle = new \GuzzleHttp\Client();
- $url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
-
- $token = json_decode($guzzle->post($url, [
- 'form_params' => [
- 'client_id' => config('ninja.o365.client_id') ,
- 'client_secret' => config('ninja.o365.client_secret') ,
- 'scope' => 'email Mail.Send offline_access profile User.Read openid',
- 'grant_type' => 'refresh_token',
- 'refresh_token' => $user->oauth_user_refresh_token
- ],
- ])->getBody()->getContents());
-
- if ($token) {
- $user->oauth_user_refresh_token = property_exists($token, 'refresh_token') ? $token->refresh_token : $user->oauth_user_refresh_token;
- $user->oauth_user_token = $token->access_token;
- $user->oauth_user_token_expiry = now()->addSeconds($token->expires_in);
- $user->save();
-
- return $token->access_token;
- }
-
- return false;
- }
-
- return $user->oauth_user_token;
- }
-
- /**
- * Backoff time
- *
- * @return void
- */
- public function backoff()
- {
- return [5, 10, 30, 240];
- }
-
- /**
- * Failed handler
- *
- * @param mixed $exception
- * @return void
- */
- public function failed($exception = null)
- {
- config(['queue.failed.driver' => null]);
- }
-}
diff --git a/app/Services/Email/MailMailable.php b/app/Services/Email/MailMailable.php
deleted file mode 100644
index 31fb9e3b238c..000000000000
--- a/app/Services/Email/MailMailable.php
+++ /dev/null
@@ -1,100 +0,0 @@
-mail_object->subject,
- tags: [$this->mail_object->company_key],
- replyTo: $this->mail_object->reply_to,
- from: $this->mail_object->from,
- to: $this->mail_object->to,
- bcc: $this->mail_object->bcc
- );
- }
-
- /**
- * Get the message content definition.
- *
- * @return \Illuminate\Mail\Mailables\Content
- */
- public function content()
- {
- return new Content(
- view: $this->mail_object->html_template,
- text: $this->mail_object->text_template,
- with: [
- 'text_body' => str_replace("
", "\n", strip_tags($this->mail_object->body, "
")), //@todo this is a bit hacky here.
- 'body' => $this->mail_object->body,
- 'settings' => $this->mail_object->settings,
- 'whitelabel' => $this->mail_object->whitelabel,
- 'logo' => $this->mail_object->logo,
- 'signature' => $this->mail_object->signature,
- 'company' => $this->mail_object->company,
- 'greeting' => ''
- ]
- );
- }
-
- /**
- * Get the attachments for the message.
- *
- * @return array
- */
- public function attachments()
- {
- $attachments = [];
-
- foreach ($this->mail_object->attachments as $file) {
- $attachments[] = Attachment::fromData(fn () => base64_decode($file['file']), $file['name']);
- }
-
- return $attachments;
- }
-
- /**
- * Get the message headers.
- *
- * @return \Illuminate\Mail\Mailables\Headers
- */
- public function headers()
- {
- return new Headers(
- messageId: null,
- references: [],
- text: $this->mail_object->headers,
- );
- }
-}
diff --git a/app/Services/Email/MailObject.php b/app/Services/Email/MailObject.php
deleted file mode 100644
index d42a71a12ccb..000000000000
--- a/app/Services/Email/MailObject.php
+++ /dev/null
@@ -1,89 +0,0 @@
-=8.40.0 || ^7.0",
- "php": "^7.2 || ^8.0",
- "swagger-api/swagger-ui": "^3.0",
- "symfony/yaml": "^5.0",
- "zircote/swagger-php": "3.*"
- },
- "require-dev": {
- "mockery/mockery": "1.*",
- "orchestra/testbench": "6.* || 5.*",
- "php-coveralls/php-coveralls": "^2.0",
- "phpunit/phpunit": "9.*"
- },
- "type": "library",
- "extra": {
- "laravel": {
- "providers": [
- "L5Swagger\\L5SwaggerServiceProvider"
- ],
- "aliases": {
- "L5Swagger": "L5Swagger\\L5SwaggerFacade"
- }
- }
- },
- "autoload": {
- "files": [
- "src/helpers.php"
- ],
- "psr-4": {
- "L5Swagger\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Darius Matulionis",
- "email": "darius@matulionis.lt"
- }
- ],
- "description": "OpenApi or Swagger integration to Laravel",
- "keywords": [
- "api",
- "documentation",
- "laravel",
- "openapi",
- "specification",
- "swagger",
- "ui"
- ],
- "support": {
- "issues": "https://github.com/DarkaOnLine/L5-Swagger/issues",
- "source": "https://github.com/DarkaOnLine/L5-Swagger/tree/8.1.0"
- },
- "funding": [
- {
- "url": "https://github.com/DarkaOnLine",
- "type": "github"
- }
- ],
- "time": "2022-01-07T09:08:44+00:00"
- },
{
"name": "dnoegel/php-xdg-base-dir",
"version": "v0.1.1",
@@ -13717,30 +13637,30 @@
},
{
"name": "doctrine/annotations",
- "version": "1.14.3",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
- "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af"
+ "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/annotations/zipball/fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
- "reference": "fb0d71a7393298a7b232cbf4c8b1f73f3ec3d5af",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
+ "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f",
"shasum": ""
},
"require": {
- "doctrine/lexer": "^1 || ^2",
+ "doctrine/lexer": "^2 || ^3",
"ext-tokenizer": "*",
- "php": "^7.1 || ^8.0",
+ "php": "^7.2 || ^8.0",
"psr/cache": "^1 || ^2 || ^3"
},
"require-dev": {
- "doctrine/cache": "^1.11 || ^2.0",
- "doctrine/coding-standard": "^9 || ^10",
- "phpstan/phpstan": "~1.4.10 || ^1.8.0",
+ "doctrine/cache": "^2.0",
+ "doctrine/coding-standard": "^10",
+ "phpstan/phpstan": "^1.8.0",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
- "symfony/cache": "^4.4 || ^5.4 || ^6",
+ "symfony/cache": "^5.4 || ^6",
"vimeo/psalm": "^4.10"
},
"suggest": {
@@ -13787,9 +13707,9 @@
],
"support": {
"issues": "https://github.com/doctrine/annotations/issues",
- "source": "https://github.com/doctrine/annotations/tree/1.14.3"
+ "source": "https://github.com/doctrine/annotations/tree/2.0.1"
},
- "time": "2023-02-01T09:20:38+00:00"
+ "time": "2023-02-02T22:02:53+00:00"
},
{
"name": "doctrine/instantiator",
@@ -14096,27 +14016,27 @@
},
{
"name": "friendsofphp/php-cs-fixer",
- "version": "v3.14.2",
+ "version": "v3.14.4",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
- "reference": "14f0541651841b63640e7aafad041ad55dc7aa88"
+ "reference": "1b3d9dba63d93b8a202c31e824748218781eae6b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/14f0541651841b63640e7aafad041ad55dc7aa88",
- "reference": "14f0541651841b63640e7aafad041ad55dc7aa88",
+ "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/1b3d9dba63d93b8a202c31e824748218781eae6b",
+ "reference": "1b3d9dba63d93b8a202c31e824748218781eae6b",
"shasum": ""
},
"require": {
"composer/semver": "^3.3",
"composer/xdebug-handler": "^3.0.3",
- "doctrine/annotations": "^1.14.2 || ^2",
- "doctrine/lexer": "^2",
+ "doctrine/annotations": "^2",
+ "doctrine/lexer": "^2 || ^3",
"ext-json": "*",
"ext-tokenizer": "*",
"php": "^7.4 || ^8.0",
- "sebastian/diff": "^4.0",
+ "sebastian/diff": "^4.0 || ^5.0",
"symfony/console": "^5.4 || ^6.0",
"symfony/event-dispatcher": "^5.4 || ^6.0",
"symfony/filesystem": "^5.4 || ^6.0",
@@ -14174,7 +14094,7 @@
"description": "A tool to automatically fix PHP code style",
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
- "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.2"
+ "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.14.4"
},
"funding": [
{
@@ -14182,7 +14102,7 @@
"type": "github"
}
],
- "time": "2023-01-29T23:47:01+00:00"
+ "time": "2023-02-09T21:49:13+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@@ -16836,67 +16756,6 @@
],
"time": "2023-01-03T19:28:04+00:00"
},
- {
- "name": "swagger-api/swagger-ui",
- "version": "v3.52.5",
- "source": {
- "type": "git",
- "url": "https://github.com/swagger-api/swagger-ui.git",
- "reference": "f1ad60dc92e7edb0898583e16c3e66fe3e9eada2"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/swagger-api/swagger-ui/zipball/f1ad60dc92e7edb0898583e16c3e66fe3e9eada2",
- "reference": "f1ad60dc92e7edb0898583e16c3e66fe3e9eada2",
- "shasum": ""
- },
- "type": "library",
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Anna Bodnia",
- "email": "anna.bodnia@gmail.com"
- },
- {
- "name": "Buu Nguyen",
- "email": "buunguyen@gmail.com"
- },
- {
- "name": "Josh Ponelat",
- "email": "jponelat@gmail.com"
- },
- {
- "name": "Kyle Shockey",
- "email": "kyleshockey1@gmail.com"
- },
- {
- "name": "Robert Barnwell",
- "email": "robert@robertismy.name"
- },
- {
- "name": "Sahar Jafari",
- "email": "shr.jafari@gmail.com"
- }
- ],
- "description": " Swagger UI is a collection of HTML, Javascript, and CSS assets that dynamically generate beautiful documentation from a Swagger-compliant API.",
- "homepage": "http://swagger.io",
- "keywords": [
- "api",
- "documentation",
- "openapi",
- "specification",
- "swagger",
- "ui"
- ],
- "support": {
- "issues": "https://github.com/swagger-api/swagger-ui/issues",
- "source": "https://github.com/swagger-api/swagger-ui/tree/v3.52.5"
- },
- "time": "2021-10-14T14:25:14+00:00"
- },
{
"name": "symfony/polyfill-php81",
"version": "v1.27.0",
@@ -17038,81 +16897,6 @@
],
"time": "2023-02-14T08:44:56+00:00"
},
- {
- "name": "symfony/yaml",
- "version": "v5.4.21",
- "source": {
- "type": "git",
- "url": "https://github.com/symfony/yaml.git",
- "reference": "3713e20d93e46e681e51605d213027e48dab3469"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/symfony/yaml/zipball/3713e20d93e46e681e51605d213027e48dab3469",
- "reference": "3713e20d93e46e681e51605d213027e48dab3469",
- "shasum": ""
- },
- "require": {
- "php": ">=7.2.5",
- "symfony/deprecation-contracts": "^2.1|^3",
- "symfony/polyfill-ctype": "^1.8"
- },
- "conflict": {
- "symfony/console": "<5.3"
- },
- "require-dev": {
- "symfony/console": "^5.3|^6.0"
- },
- "suggest": {
- "symfony/console": "For validating YAML files using the lint command"
- },
- "bin": [
- "Resources/bin/yaml-lint"
- ],
- "type": "library",
- "autoload": {
- "psr-4": {
- "Symfony\\Component\\Yaml\\": ""
- },
- "exclude-from-classmap": [
- "/Tests/"
- ]
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com"
- },
- {
- "name": "Symfony Community",
- "homepage": "https://symfony.com/contributors"
- }
- ],
- "description": "Loads and dumps YAML files",
- "homepage": "https://symfony.com",
- "support": {
- "source": "https://github.com/symfony/yaml/tree/v5.4.21"
- },
- "funding": [
- {
- "url": "https://symfony.com/sponsor",
- "type": "custom"
- },
- {
- "url": "https://github.com/fabpot",
- "type": "github"
- },
- {
- "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
- "type": "tidelift"
- }
- ],
- "time": "2023-02-21T19:46:44+00:00"
- },
{
"name": "theseer/tokenizer",
"version": "1.2.1",
@@ -17321,79 +17105,6 @@
},
"abandoned": "symfony/filesystem",
"time": "2015-12-17T08:42:14+00:00"
- },
- {
- "name": "zircote/swagger-php",
- "version": "3.3.7",
- "source": {
- "type": "git",
- "url": "https://github.com/zircote/swagger-php.git",
- "reference": "e8c3bb316e385e93a0c7e8b2aa0681079244c381"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/zircote/swagger-php/zipball/e8c3bb316e385e93a0c7e8b2aa0681079244c381",
- "reference": "e8c3bb316e385e93a0c7e8b2aa0681079244c381",
- "shasum": ""
- },
- "require": {
- "doctrine/annotations": "^1.7",
- "ext-json": "*",
- "php": ">=7.2",
- "psr/log": "^1.1 || ^2.0 || ^3.0",
- "symfony/finder": ">=2.2",
- "symfony/yaml": ">=3.3"
- },
- "require-dev": {
- "composer/package-versions-deprecated": "1.11.99.2",
- "friendsofphp/php-cs-fixer": "^2.17 || ^3.0",
- "phpunit/phpunit": ">=8.5.14"
- },
- "bin": [
- "bin/openapi"
- ],
- "type": "library",
- "autoload": {
- "files": [
- "src/functions.php"
- ],
- "psr-4": {
- "OpenApi\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "Apache-2.0"
- ],
- "authors": [
- {
- "name": "Robert Allen",
- "email": "zircote@gmail.com"
- },
- {
- "name": "Bob Fanger",
- "email": "bfanger@gmail.com",
- "homepage": "https://bfanger.nl"
- },
- {
- "name": "Martin Rademacher",
- "email": "mano@radebatz.net",
- "homepage": "https://radebatz.net"
- }
- ],
- "description": "swagger-php - Generate interactive documentation for your RESTful API using phpdoc annotations",
- "homepage": "https://github.com/zircote/swagger-php/",
- "keywords": [
- "api",
- "json",
- "rest",
- "service discovery"
- ],
- "support": {
- "issues": "https://github.com/zircote/swagger-php/issues",
- "source": "https://github.com/zircote/swagger-php/tree/3.3.7"
- },
- "time": "2023-01-03T21:17:10+00:00"
}
],
"aliases": [],
diff --git a/config/liap.php b/config/liap.php
index 1eaa57a8aa04..b7f91958ab8e 100644
--- a/config/liap.php
+++ b/config/liap.php
@@ -39,7 +39,7 @@ return [
| @see https://imdhemy.com/laravel-iap-docs/docs/credentials/google-play
|
*/
- 'google_application_credentials' => env('GOOGLE_APPLICATION_CREDENTIALS',false),
+ 'google_application_credentials' => env('GOOGLE_APPLICATION_CREDENTIALS', base_path('VERSION.txt')),
/*
|--------------------------------------------------------------------------
diff --git a/config/ninja.php b/config/ninja.php
index 9b7cb534c74b..937a6fb60062 100644
--- a/config/ninja.php
+++ b/config/ninja.php
@@ -213,5 +213,4 @@ return [
'config_name' => env("YODLEE_CONFIG_NAME", false),
],
'licenses' => env('LICENSES',false),
- 'google_service_account' => env('GOOGLE_APPLICATION_CREDENTIALS', false),
];