mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
restruct files
This commit is contained in:
parent
a6f9275144
commit
8d6925afd3
19
app/Helpers/Mail/Mailbox/BaseMailbox.php
Normal file
19
app/Helpers/Mail/Mailbox/BaseMailbox.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\Mail;
|
||||
|
||||
interface BaseMailbox
|
||||
{
|
||||
public function getUnprocessedEmails();
|
||||
public function moveProcessed();
|
||||
public function moveFailed();
|
||||
}
|
@ -15,11 +15,7 @@ use Ddeboer\Imap\MessageInterface;
|
||||
use Ddeboer\Imap\Server;
|
||||
use Ddeboer\Imap\SearchExpression;
|
||||
use Ddeboer\Imap\Search\Date\Since;
|
||||
use Ddeboer\Imap\Search\Flag\Unflagged;
|
||||
|
||||
/**
|
||||
* GmailTransport.
|
||||
*/
|
||||
class ImapMailbox
|
||||
{
|
||||
private $server;
|
||||
@ -43,10 +39,6 @@ class ImapMailbox
|
||||
$thirtyDaysAgo = $today->sub(new \DateInterval('P30D'));
|
||||
$search->addCondition(new Since($thirtyDaysAgo));
|
||||
|
||||
// not flagged with IN-PARSED
|
||||
$search->addCondition(new Unflagged());
|
||||
|
||||
|
||||
return $mailbox->getMessages($search);
|
||||
}
|
||||
|
57
app/Helpers/Mail/Mailbox/Pop3/Pop3Mailbox.php
Normal file
57
app/Helpers/Mail/Mailbox/Pop3/Pop3Mailbox.php
Normal file
@ -0,0 +1,57 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\Mail;
|
||||
|
||||
use Ddeboer\Imap\MessageInterface;
|
||||
use Ddeboer\Imap\Server;
|
||||
use Ddeboer\Imap\SearchExpression;
|
||||
use Ddeboer\Imap\Search\Date\Since;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*/
|
||||
class Pop3Mailbox implements BaseMailbox
|
||||
{
|
||||
private $server;
|
||||
public $connection;
|
||||
public function __construct(string $server, string $port, string $user, string $password)
|
||||
{
|
||||
$this->server = new Server($server, $port != '' ? $port : null);
|
||||
|
||||
$this->connection = $this->server->authenticate($user, $password);
|
||||
}
|
||||
|
||||
|
||||
public function getUnprocessedEmails()
|
||||
{
|
||||
$mailbox = $this->connection->getMailbox('INBOX');
|
||||
|
||||
$search = new SearchExpression();
|
||||
|
||||
// not older than 30days
|
||||
$today = new \DateTimeImmutable();
|
||||
$thirtyDaysAgo = $today->sub(new \DateInterval('P30D'));
|
||||
$search->addCondition(new Since($thirtyDaysAgo));
|
||||
|
||||
return $mailbox->getMessages($search);
|
||||
}
|
||||
|
||||
public function moveProcessed(MessageInterface $mail)
|
||||
{
|
||||
return $mail->move($this->connection->getMailbox('PROCESSED'));
|
||||
}
|
||||
|
||||
public function moveFailed(MessageInterface $mail)
|
||||
{
|
||||
return $mail->move($this->connection->getMailbox('FAILED'));
|
||||
}
|
||||
}
|
20
app/Helpers/Mail/Webhook/BaseWebhookHandler.php
Normal file
20
app/Helpers/Mail/Webhook/BaseWebhookHandler.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\Mail\Webhook;
|
||||
|
||||
interface BaseWebhookHandler
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
22
app/Helpers/Mail/Webhook/Mailgun/MailgunWebhookHandler.php
Normal file
22
app/Helpers/Mail/Webhook/Mailgun/MailgunWebhookHandler.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\Mail\Webhook\Maigun;
|
||||
|
||||
use App\Helpers\Mail\Webhook\BaseWebhookHandler;
|
||||
|
||||
interface MailgunWebhookHandler extends BaseWebhookHandler
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
22
app/Helpers/Mail/Webhook/Postmark/PostmarkWebhookHandler.php
Normal file
22
app/Helpers/Mail/Webhook/Postmark/PostmarkWebhookHandler.php
Normal file
@ -0,0 +1,22 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\Mail\Webhook\Postmark;
|
||||
|
||||
use App\Helpers\Mail\Webhook\BaseWebhookHandler;
|
||||
|
||||
interface PostmarkWebhookHandler extends BaseWebhookHandler
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
72
app/Http/Controllers/MailgunController.php
Normal file
72
app/Http/Controllers/MailgunController.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Jobs\Mailgun\ProcessMailgunInboundWebhook;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class PostMarkController.
|
||||
*/
|
||||
class MailgunController extends BaseController
|
||||
{
|
||||
private $invitation;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Process Postmark Webhook.
|
||||
*
|
||||
*
|
||||
* @OA\Post(
|
||||
* path="/api/v1/postmark_inbound_webhook",
|
||||
* operationId="postmarkInboundWebhook",
|
||||
* tags={"postmark"},
|
||||
* summary="Processing inbound webhooks from PostMark",
|
||||
* description="Adds an credit to the system",
|
||||
* @OA\Parameter(ref="#/components/parameters/X-API-TOKEN"),
|
||||
* @OA\Parameter(ref="#/components/parameters/X-Requested-With"),
|
||||
* @OA\Parameter(ref="#/components/parameters/include"),
|
||||
* @OA\Response(
|
||||
* response=200,
|
||||
* description="Returns the saved credit object",
|
||||
* @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"),
|
||||
* @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"),
|
||||
* @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"),
|
||||
* @OA\JsonContent(ref="#/components/schemas/Credit"),
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response=422,
|
||||
* description="Validation error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/ValidationError"),
|
||||
*
|
||||
* ),
|
||||
* @OA\Response(
|
||||
* response="default",
|
||||
* description="Unexpected Error",
|
||||
* @OA\JsonContent(ref="#/components/schemas/Error"),
|
||||
* ),
|
||||
* )
|
||||
*/
|
||||
public function inboundWebhook(Request $request)
|
||||
{
|
||||
if ($request->header('X-API-SECURITY') && $request->header('X-API-SECURITY') == config('services.postmark.token')) {
|
||||
ProcessMailgunInboundWebhook::dispatch($request->all())->delay(10);
|
||||
|
||||
return response()->json(['message' => 'Success'], 200);
|
||||
}
|
||||
|
||||
return response()->json(['message' => 'Unauthorized'], 403);
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ use App\Events\Expense\ExpenseWasCreated;
|
||||
use App\Events\Invoice\InvoiceWasEmailedAndFailed;
|
||||
use App\Events\Payment\PaymentWasEmailedAndFailed;
|
||||
use App\Factory\ExpenseFactory;
|
||||
use App\Helpers\Mail\ImapMailbox;
|
||||
use App\Helpers\Mail\Mailbox\Imap\ImapMailbox;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\Google\Google;
|
||||
use App\Libraries\MultiDB;
|
||||
|
180
app/Jobs/Mailgun/ProcessMailgunInboundWebhook.php
Normal file
180
app/Jobs/Mailgun/ProcessMailgunInboundWebhook.php
Normal file
@ -0,0 +1,180 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Jobs\PostMark;
|
||||
|
||||
use App\DataMapper\Analytics\Mail\EmailBounce;
|
||||
use App\DataMapper\Analytics\Mail\EmailSpam;
|
||||
use App\Jobs\Util\SystemLogger;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Models\CreditInvitation;
|
||||
use App\Models\Expense;
|
||||
use App\Models\InvoiceInvitation;
|
||||
use App\Models\PurchaseOrderInvitation;
|
||||
use App\Models\QuoteInvitation;
|
||||
use App\Models\RecurringInvoiceInvitation;
|
||||
use App\Models\SystemLog;
|
||||
use App\Notifications\Ninja\EmailSpamNotification;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Postmark\PostmarkClient;
|
||||
use Turbo124\Beacon\Facades\LightLogs;
|
||||
|
||||
class ProcessMailgunInboundWebhook implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
public $tries = 1;
|
||||
|
||||
public $invitation;
|
||||
|
||||
private $entity;
|
||||
|
||||
private array $default_response = [
|
||||
'recipients' => '',
|
||||
'subject' => 'Message not found.',
|
||||
'entity' => '',
|
||||
'entity_id' => '',
|
||||
'events' => [],
|
||||
];
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
*/
|
||||
public function __construct(private array $request)
|
||||
{
|
||||
}
|
||||
|
||||
private function getSystemLog(string $message_id): ?SystemLog
|
||||
{
|
||||
return SystemLog::query()
|
||||
->where('company_id', $this->invitation->company_id)
|
||||
->where('type_id', SystemLog::TYPE_WEBHOOK_RESPONSE)
|
||||
->whereJsonContains('log', ['MessageID' => $message_id])
|
||||
->orderBy('id', 'desc')
|
||||
->first();
|
||||
|
||||
}
|
||||
|
||||
private function updateSystemLog(SystemLog $system_log, array $data): void
|
||||
{
|
||||
$system_log->log = $data;
|
||||
$system_log->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
MultiDB::findAndSetDbByCompanyKey($this->request['Tag']);
|
||||
|
||||
// match companies
|
||||
if (array_key_exists('ToFull', $this->request))
|
||||
throw new \Exception('invalid body');
|
||||
|
||||
$toEmails = [];
|
||||
foreach ($this->request['ToFull'] as $toEmailEntry)
|
||||
$toEmails[] = $toEmailEntry['Email'];
|
||||
|
||||
// create expense for each company
|
||||
$expense = new Expense();
|
||||
|
||||
$expense->company_id;
|
||||
}
|
||||
// {
|
||||
// "FromName": "Postmarkapp Support",
|
||||
// "MessageStream": "inbound",
|
||||
// "From": "support@postmarkapp.com",
|
||||
// "FromFull": {
|
||||
// "Email": "support@postmarkapp.com",
|
||||
// "Name": "Postmarkapp Support",
|
||||
// "MailboxHash": ""
|
||||
// },
|
||||
// "To": "\"Firstname Lastname\" <yourhash+SampleHash@inbound.postmarkapp.com>",
|
||||
// "ToFull": [
|
||||
// {
|
||||
// "Email": "yourhash+SampleHash@inbound.postmarkapp.com",
|
||||
// "Name": "Firstname Lastname",
|
||||
// "MailboxHash": "SampleHash"
|
||||
// }
|
||||
// ],
|
||||
// "Cc": "\"First Cc\" <firstcc@postmarkapp.com>, secondCc@postmarkapp.com>",
|
||||
// "CcFull": [
|
||||
// {
|
||||
// "Email": "firstcc@postmarkapp.com",
|
||||
// "Name": "First Cc",
|
||||
// "MailboxHash": ""
|
||||
// },
|
||||
// {
|
||||
// "Email": "secondCc@postmarkapp.com",
|
||||
// "Name": "",
|
||||
// "MailboxHash": ""
|
||||
// }
|
||||
// ],
|
||||
// "Bcc": "\"First Bcc\" <firstbcc@postmarkapp.com>, secondbcc@postmarkapp.com>",
|
||||
// "BccFull": [
|
||||
// {
|
||||
// "Email": "firstbcc@postmarkapp.com",
|
||||
// "Name": "First Bcc",
|
||||
// "MailboxHash": ""
|
||||
// },
|
||||
// {
|
||||
// "Email": "secondbcc@postmarkapp.com",
|
||||
// "Name": "",
|
||||
// "MailboxHash": ""
|
||||
// }
|
||||
// ],
|
||||
// "OriginalRecipient": "yourhash+SampleHash@inbound.postmarkapp.com",
|
||||
// "Subject": "Test subject",
|
||||
// "MessageID": "73e6d360-66eb-11e1-8e72-a8904824019b",
|
||||
// "ReplyTo": "replyto@postmarkapp.com",
|
||||
// "MailboxHash": "SampleHash",
|
||||
// "Date": "Fri, 1 Aug 2014 16:45:32 -04:00",
|
||||
// "TextBody": "This is a test text body.",
|
||||
// "HtmlBody": "<html><body><p>This is a test html body.<\/p><\/body><\/html>",
|
||||
// "StrippedTextReply": "This is the reply text",
|
||||
// "Tag": "TestTag",
|
||||
// "Headers": [
|
||||
// {
|
||||
// "Name": "X-Header-Test",
|
||||
// "Value": ""
|
||||
// },
|
||||
// {
|
||||
// "Name": "X-Spam-Status",
|
||||
// "Value": "No"
|
||||
// },
|
||||
// {
|
||||
// "Name": "X-Spam-Score",
|
||||
// "Value": "-0.1"
|
||||
// },
|
||||
// {
|
||||
// "Name": "X-Spam-Tests",
|
||||
// "Value": "DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,SPF_PASS"
|
||||
// }
|
||||
// ],
|
||||
// "Attachments": [
|
||||
// {
|
||||
// "Name": "test.txt",
|
||||
// "Content": "VGhpcyBpcyBhdHRhY2htZW50IGNvbnRlbnRzLCBiYXNlLTY0IGVuY29kZWQu",
|
||||
// "ContentType": "text/plain",
|
||||
// "ContentLength": 45
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
}
|
@ -388,6 +388,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale']
|
||||
// Route::post('hooks', [SubscriptionController::class, 'subscribe'])->name('hooks.subscribe');
|
||||
// Route::delete('hooks/{subscription_id}', [SubscriptionController::class, 'unsubscribe'])->name('hooks.unsubscribe');
|
||||
|
||||
|
||||
Route::post('stripe/update_payment_methods', [StripeController::class, 'update'])->middleware('password_protected')->name('stripe.update');
|
||||
Route::post('stripe/import_customers', [StripeController::class, 'import'])->middleware('password_protected')->name('stripe.import');
|
||||
|
||||
@ -415,6 +416,7 @@ Route::match(['get', 'post'], 'payment_notification_webhook/{company_key}/{compa
|
||||
|
||||
Route::post('api/v1/postmark_webhook', [PostMarkController::class, 'webhook'])->middleware('throttle:1000,1');
|
||||
Route::post('api/v1/postmark_inbound_webhook', [PostMarkController::class, 'inboundWebhook'])->middleware('throttle:1000,1');
|
||||
Route::post('api/v1/mailgun_inbound_webhook', [MailgunController::class, 'inboundWebhook'])->middleware('throttle:1000,1');
|
||||
Route::get('token_hash_router', [OneTimeTokenController::class, 'router'])->middleware('throttle:500,1');
|
||||
Route::get('webcron', [WebCronController::class, 'index'])->middleware('throttle:100,1');
|
||||
Route::post('api/v1/get_migration_account', [HostedMigrationController::class, 'getAccount'])->middleware('guest')->middleware('throttle:100,1');
|
||||
|
Loading…
x
Reference in New Issue
Block a user