add OAUth2.0
This commit is contained in:
@@ -12,7 +12,6 @@ use App\Models\Gruppo;
|
||||
use App\Models\Individuo;
|
||||
use App\Models\Documento;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
@@ -402,6 +401,10 @@ class EmailController extends Controller
|
||||
|
||||
$this->ensureFoldersExist();
|
||||
|
||||
if ($settings->isOauth()) {
|
||||
return $this->syncEmailsViaOAuth($settings);
|
||||
}
|
||||
|
||||
$mailbox = $this->connectImap($settings);
|
||||
|
||||
\Illuminate\Support\Facades\Log::info('IMAP connection established', ['host' => $settings->imap_host]);
|
||||
@@ -523,6 +526,10 @@ class EmailController extends Controller
|
||||
$encryption
|
||||
);
|
||||
|
||||
if ($settings->isOauth()) {
|
||||
$dsn .= '&auth_mode=xoauth2';
|
||||
}
|
||||
|
||||
try {
|
||||
$transport = \Symfony\Component\Mailer\Transport::fromDsn($dsn);
|
||||
$mailer = new \Symfony\Component\Mailer\Mailer($transport);
|
||||
@@ -643,6 +650,10 @@ class EmailController extends Controller
|
||||
throw new \Exception('Configurazione IMAP non valida');
|
||||
}
|
||||
|
||||
if ($settings->isOauth()) {
|
||||
return $this->connectOAuthImap($settings);
|
||||
}
|
||||
|
||||
$encryption = match ($settings->imap_encryption) {
|
||||
'ssl' => 'ssl',
|
||||
'tls' => 'tls',
|
||||
@@ -659,6 +670,27 @@ class EmailController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
private function connectOAuthImap($settings): \Webklex\PHPIMAP\Client
|
||||
{
|
||||
$token = $settings->getOAuthAccessToken();
|
||||
if (!$token) {
|
||||
throw new \Exception('Impossibile ottenere il token OAuth per IMAP');
|
||||
}
|
||||
|
||||
$client = new \Webklex\PHPIMAP\Client([
|
||||
'host' => $settings->imap_host,
|
||||
'port' => $settings->imap_port ?? 993,
|
||||
'encryption' => $settings->imap_encryption ?? 'ssl',
|
||||
'validate_cert' => false,
|
||||
'username' => $settings->imap_username,
|
||||
'password' => $token,
|
||||
'authentication' => 'oauth',
|
||||
]);
|
||||
$client->connect();
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
private function processImapMessage($imapMessage, $imapFolder)
|
||||
{
|
||||
$folderType = match ($imapFolder) {
|
||||
@@ -717,6 +749,133 @@ class EmailController extends Controller
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private function syncEmailsViaOAuth($settings): bool
|
||||
{
|
||||
$this->ensureFoldersExist();
|
||||
|
||||
$client = $this->connectOAuthImap($settings);
|
||||
|
||||
$folderMappings = [
|
||||
'INBOX' => 'inbox',
|
||||
'Sent' => 'sent',
|
||||
'[Gmail]/Sent Mail' => 'sent',
|
||||
'Sent Mail' => 'sent',
|
||||
'Drafts' => 'drafts',
|
||||
'[Gmail]/Drafts' => 'drafts',
|
||||
'Trash' => 'trash',
|
||||
'[Gmail]/Trash' => 'trash',
|
||||
];
|
||||
|
||||
$totalNew = 0;
|
||||
|
||||
foreach (array_keys($folderMappings) as $imapFolderName) {
|
||||
try {
|
||||
$folder = $client->getFolder($imapFolderName);
|
||||
if (!$folder) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages = $folder->messages()
|
||||
->setFetchFlags(true)
|
||||
->setFetchBody(true)
|
||||
->limit(100)
|
||||
->get();
|
||||
|
||||
foreach ($messages as $imapMessage) {
|
||||
$messageId = $imapMessage->getMessageId() ?? uniqid('msg_');
|
||||
$existing = EmailMessage::where('message_id', $messageId)->first();
|
||||
if ($existing) {
|
||||
continue;
|
||||
}
|
||||
$this->processWebklexMessage($imapMessage, $imapFolderName);
|
||||
$totalNew++;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Error processing OAuth IMAP folder', ['folder' => $imapFolderName, 'error' => $e->getMessage()]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$client->disconnect();
|
||||
\Illuminate\Support\Facades\Log::info('OAuth email sync completed', ['new' => $totalNew]);
|
||||
return true;
|
||||
}
|
||||
|
||||
private function processWebklexMessage($imapMessage, $imapFolder)
|
||||
{
|
||||
$folderType = match ($imapFolder) {
|
||||
'INBOX', 'inbox' => 'inbox',
|
||||
'Sent', 'sent', '[Gmail]/Sent Mail' => 'sent',
|
||||
'Drafts', 'drafts', '[Gmail]/Drafts' => 'drafts',
|
||||
'Trash', 'trash', '[Gmail]/Trash' => 'trash',
|
||||
'Archive', 'archive', '[Gmail]/All Mail' => 'archive',
|
||||
'Starred', 'starred', '[Gmail]/Starred' => 'starred',
|
||||
default => 'inbox',
|
||||
};
|
||||
|
||||
$folder = EmailFolder::where('type', $folderType)->first();
|
||||
if (!$folder) return;
|
||||
|
||||
$messageId = $imapMessage->getMessageId() ?? uniqid('msg_');
|
||||
$existing = EmailMessage::where('message_id', $messageId)->first();
|
||||
if ($existing) return;
|
||||
|
||||
$from = $imapMessage->getFrom();
|
||||
$to = $imapMessage->getTo();
|
||||
|
||||
$fromName = '';
|
||||
$fromEmail = '';
|
||||
if ($from && $from->first()) {
|
||||
$fromName = $from->first()->personal ?? '';
|
||||
$fromEmail = ($from->first()->mailbox ?? '') . '@' . ($from->first()->host ?? '');
|
||||
}
|
||||
|
||||
$toEmail = '';
|
||||
if ($to && $to->first()) {
|
||||
$toEmail = ($to->first()->mailbox ?? '') . '@' . ($to->first()->host ?? '');
|
||||
}
|
||||
|
||||
$message = EmailMessage::create([
|
||||
'email_folder_id' => $folder->id,
|
||||
'message_id' => $messageId,
|
||||
'subject' => mb_substr($imapMessage->getSubject() ?? '(senza oggetto)', 0, 255),
|
||||
'from_name' => mb_substr($fromName, 0, 255),
|
||||
'from_email' => mb_substr($fromEmail, 0, 255),
|
||||
'to_email' => mb_substr($toEmail, 0, 255),
|
||||
'body_text' => $imapMessage->getTextBody() ?? '',
|
||||
'body_html' => $imapMessage->getHTMLBody() ?? '',
|
||||
'is_read' => !($imapMessage->getFlags()['UNSEEN'] ?? false),
|
||||
'is_starred' => !empty($imapMessage->getFlags()['FLAGGED']),
|
||||
'is_sent' => $folderType === 'sent',
|
||||
'received_at' => $imapMessage->getDate() ?? now(),
|
||||
'imap_uid' => $imapMessage->getUid() ?? null,
|
||||
]);
|
||||
|
||||
$attachments = $imapMessage->getAttachments();
|
||||
if ($attachments && count($attachments) > 0) {
|
||||
foreach ($attachments as $attachment) {
|
||||
try {
|
||||
$filename = $attachment->getName() ?? 'attachment';
|
||||
$contents = $attachment->getContent();
|
||||
$path = 'email-attachments/' . \Illuminate\Support\Str::uuid() . '_' . $filename;
|
||||
\Illuminate\Support\Facades\Storage::put($path, $contents);
|
||||
|
||||
EmailAttachment::create([
|
||||
'email_message_id' => $message->id,
|
||||
'filename' => $filename,
|
||||
'mime_type' => $attachment->getMimeType() ?? 'application/octet-stream',
|
||||
'size' => strlen($contents),
|
||||
'file_path' => $path,
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
\Illuminate\Support\Facades\Log::error('Error saving OAuth attachment', ['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function ensureFoldersExist()
|
||||
{
|
||||
$systemFolders = EmailFolder::getSystemFolders();
|
||||
|
||||
Reference in New Issue
Block a user