From 55270ae450c2fca4333a270629b1532492f6aba9 Mon Sep 17 00:00:00 2001 From: "ayushrajsrivastava.akeneo736" Date: Fri, 15 Nov 2024 17:19:55 +0530 Subject: [PATCH 01/10] updated code for microsoft integration --- Console/RefreshMailboxCommand.php | 363 +++++++-- Controller/MailboxChannel.php | 523 ++++++++++--- .../views/manageConfigurations.html.twig | 628 +++++++++++++-- Services/MailboxService.php | 722 +++++++++++++----- Utils/MailboxConfiguration.php | 124 ++- Utils/SMTP/Configuration.php | 106 +++ .../AppTransportConfigurationInterface.php | 16 + ...DefaultTransportConfigurationInterface.php | 26 + ...esolvedTransportConfigurationInterface.php | 18 + .../TransportConfigurationInterface.php | 10 + Utils/SMTP/Transport/Type/Gmail.php | 61 ++ Utils/SMTP/Transport/Type/Outlook.php | 61 ++ .../SMTP/Transport/Type/OutlookModernAuth.php | 53 ++ Utils/SMTP/Transport/Type/SMTP.php | 88 +++ Utils/SMTP/Transport/Type/Yahoo.php | 61 ++ 15 files changed, 2424 insertions(+), 436 deletions(-) create mode 100644 Utils/SMTP/Configuration.php create mode 100644 Utils/SMTP/Transport/AppTransportConfigurationInterface.php create mode 100644 Utils/SMTP/Transport/DefaultTransportConfigurationInterface.php create mode 100644 Utils/SMTP/Transport/ResolvedTransportConfigurationInterface.php create mode 100644 Utils/SMTP/Transport/TransportConfigurationInterface.php create mode 100644 Utils/SMTP/Transport/Type/Gmail.php create mode 100644 Utils/SMTP/Transport/Type/Outlook.php create mode 100644 Utils/SMTP/Transport/Type/OutlookModernAuth.php create mode 100644 Utils/SMTP/Transport/Type/SMTP.php create mode 100644 Utils/SMTP/Transport/Type/Yahoo.php diff --git a/Console/RefreshMailboxCommand.php b/Console/RefreshMailboxCommand.php index 14df11c..8d0315f 100644 --- a/Console/RefreshMailboxCommand.php +++ b/Console/RefreshMailboxCommand.php @@ -10,37 +10,48 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; +use Webkul\UVDesk\CoreFrameworkBundle\Entity\Microsoft\MicrosoftApp; +use Webkul\UVDesk\CoreFrameworkBundle\Entity\Microsoft\MicrosoftAccount; +use Webkul\UVDesk\CoreFrameworkBundle\Utils\Microsoft\Graph as MicrosoftGraph; +use Webkul\UVDesk\CoreFrameworkBundle\Services\MicrosoftIntegration; +use Webkul\UVDesk\MailboxBundle\Services\MailboxService; +use Webkul\UVDesk\MailboxBundle\Utils\IMAP; class RefreshMailboxCommand extends Command { private $endpoint; + private $outlookEndpoint; - public function __construct(ContainerInterface $container, EntityManagerInterface $entityManager) + public function __construct(ContainerInterface $container, EntityManagerInterface $entityManager, MicrosoftIntegration $microsoftIntegration, MailboxService $mailboxService) { - $this->container = $container; - $this->entityManager = $entityManager; + $this->container = $container; + $this->entityManager = $entityManager; + $this->microsoftIntegration = $microsoftIntegration; + $this->mailboxService = $mailboxService; parent::__construct(); } protected function configure() { - $this->setName('uvdesk:refresh-mailbox'); - $this->setDescription('Check if any new emails have been received and process them into tickets'); - - $this->addArgument('emails', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, "Email address of the mailboxes you wish to update"); - $this->addOption('timestamp', 't', InputOption::VALUE_REQUIRED, "Fetch messages no older than the given timestamp"); + $this + ->setName('uvdesk:refresh-mailbox') + ->setDescription('Check if any new emails have been received and process them into tickets') + ->addArgument('emails', InputArgument::IS_ARRAY | InputArgument::OPTIONAL, "Email address of the mailboxes you wish to update") + ->addOption('timestamp', 't', InputOption::VALUE_REQUIRED, "Fetch messages no older than the given timestamp") + ->addOption('secure', null, InputOption::VALUE_NONE, "Use HTTTPS for communicating with required api endpoints") + ; } protected function initialize(InputInterface $input, OutputInterface $output) { - $router = $this->container->get('router'); - $useSecureConnection = $this->isSecureConnectionAvailable(); + $this->router = $this->container->get('router'); - $router->getContext()->setHost($this->container->getParameter('uvdesk.site_url')); - $router->getContext()->setScheme(false === $useSecureConnection ? 'http' : 'https'); + $this->router->getContext()->setHost($this->container->getParameter('uvdesk.site_url')); + $this->router->getContext()->setScheme((bool) $input->getOption('secure') ? 'https' : 'http'); - $this->endpoint = $router->generate('helpdesk_member_mailbox_notification', [], UrlGeneratorInterface::ABSOLUTE_URL); + $this->endpoint = $this->router->generate('helpdesk_member_mailbox_notification', [], UrlGeneratorInterface::ABSOLUTE_URL); + $this->outlookEndpoint = $this->router->generate('helpdesk_member_outlook_mailbox_notification', [], UrlGeneratorInterface::ABSOLUTE_URL); } protected function execute(InputInterface $input, OutputInterface $output): int @@ -64,44 +75,105 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($mailboxEmailCollection as $mailboxEmail) { $output->writeln("\n# Retrieving mailbox configuration details for $mailboxEmail:\n"); + + if('microsoft') { + $mailboxConfigurations = $this->mailboxService->parseMailboxConfigurations(); + $mailbox = $mailboxConfigurations->getIncomingMailboxByEmailAddress($mailboxEmail); - try { - $mailbox = $this->container->get('uvdesk.mailbox')->getMailboxByEmail($mailboxEmail); - - if (false == $mailbox['enabled']) { + if (empty($mailbox)) { if (false === $input->getOption('no-interaction')) { - $output->writeln(" Error: Mailbox for email $mailboxEmail is not enabled."); + $output->writeln(" Error: Mailbox for email $mailboxEmail not found."); } continue; - } else if (empty($mailbox['imap_server'])) { + } else if (false == $mailbox->getIsEnabled()) { if (false === $input->getOption('no-interaction')) { - $output->writeln(" Error: No imap configurations defined for email $mailboxEmail."); + $output->writeln(" Error: Mailbox for email $mailboxEmail is not enabled."); } - + continue; + } else { + $imapConfiguration = $mailbox->getImapConfiguration(); + + if (empty($imapConfiguration)) { + if (false === $input->getOption('no-interaction')) { + $output->writeln(" Error: No imap configurations defined for email $mailboxEmail."); + } + + continue; + } } - } catch (\Exception $e) { - if (false == $input->getOption('no-interaction')) { - $output->writeln(" Error: Mailbox for email $mailboxEmail not found."); - - // return Command::INVALID; + + try { + if ($imapConfiguration instanceof IMAP\Transport\SimpleTransportConfigurationInterface) { + $output->writeln(" Cannot fetch emails from mailboxes with simple transport configurations."); + } else if ($imapConfiguration instanceof IMAP\Transport\AppTransportConfigurationInterface) { + $microsoftApp = $this->entityManager->getRepository(MicrosoftApp::class)->findOneByClientId($imapConfiguration->getClient()); + + if (empty($microsoftApp)) { + $output->writeln(" No microsoft app was found for configured client id '" . $imapConfiguration->getClient() . "'."); + + continue; + } else { + $microsoftAccount = $this->entityManager->getRepository(MicrosoftAccount::class)->findOneBy([ + 'email' => $imapConfiguration->getUsername(), + 'microsoftApp' => $microsoftApp, + ]); + + if (empty($microsoftAccount)) { + $output->writeln(" No microsoft account was found with email '" . $imapConfiguration->getUsername() . "' for configured client id '" . $imapConfiguration->getClient() . "'."); + + continue; + } + } + + $this->refreshOutlookMailbox($microsoftApp, $microsoftAccount, $timestamp, $output); + } else { + $this->refreshMailbox($imapConfiguration->getHost(), $imapConfiguration->getUsername(), urldecode($imapConfiguration->getPassword()), $timestamp, $output); + } + } catch (\Exception $e) { + $output->writeln(" An unexpected error occurred: " . $e->getMessage() . ""); } + }else { - continue; - } - - try { - $this->refreshMailbox( - $mailbox['imap_server']['host'], - $mailbox['imap_server']['username'], - base64_decode($mailbox['imap_server']['password']), - $timestamp, - $output, - $mailbox - ); - } catch (\Exception $e) { - $output->writeln(" An unexpected error occurred: " . $e->getMessage() . ""); + try { + $mailbox = $this->container->get('uvdesk.mailbox')->getMailboxByEmail($mailboxEmail); + + if (false == $mailbox['enabled']) { + if (false === $input->getOption('no-interaction')) { + $output->writeln(" Error: Mailbox for email $mailboxEmail is not enabled."); + } + + continue; + } else if (empty($mailbox['imap_server'])) { + if (false === $input->getOption('no-interaction')) { + $output->writeln(" Error: No imap configurations defined for email $mailboxEmail."); + } + + continue; + } + } catch (\Exception $e) { + if (false == $input->getOption('no-interaction')) { + $output->writeln(" Error: Mailbox for email $mailboxEmail not found."); + + // return Command::INVALID; + } + + continue; + } + + try { + $this->refreshMailbox( + $mailbox['imap_server']['host'], + $mailbox['imap_server']['username'], + base64_decode($mailbox['imap_server']['password']), + $timestamp, + $output, + $mailbox + ); + } catch (\Exception $e) { + $output->writeln(" An unexpected error occurred: " . $e->getMessage() . ""); + } } } @@ -110,7 +182,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return Command::SUCCESS; } - public function refreshMailbox($server_host, $server_username, $server_password, \DateTime $timestamp, OutputInterface $output, $mailbox) + public function refreshMailbox($server_host, $server_username, $server_password, \DateTime $timestamp, OutputInterface $output, $mailbox=null) { $output->writeln(" - Establishing connection with mailbox"); @@ -153,30 +225,187 @@ public function refreshMailbox($server_host, $server_username, $server_password, if ($responseCode == 200) { $output->writeln("\n 200 " . $response['message'] . "\n"); } else { - if (!empty($responseErrorMessage)) { + if (! empty($responseErrorMessage)) { $output->writeln("\n ERROR $responseErrorMessage\n"); } else { $output->writeln("\n ERROR " . $response['message'] . "\n"); } } - if (true == $mailbox['deleted']) { - imap_delete($imap, $messageNumber); + $counter++; + } + + $output->writeln(" - Mailbox refreshed successfully!"); + } + } + + return; + } + + public function refreshOutlookMailbox($microsoftApp, $microsoftAccount, \DateTime $timestamp, OutputInterface $output) + { + $timeSpan = $timestamp->format('Y-m-d'); + $credentials = json_decode($microsoftAccount->getCredentials(), true); + $redirectEndpoint = str_replace('http', 'https', $this->router->generate('uvdesk_member_core_framework_integrations_microsoft_apps_oauth_login', [], UrlGeneratorInterface::ABSOLUTE_URL)); + + $filters = [ + 'ReceivedDateTime' => [ + 'operation' => '>', + 'value' => $timeSpan, + ], + ]; + + $mailboxFolderId = null; + $mailboxFolderCollection = $this->getOutlookMailboxFolders($credentials['access_token'], $credentials['refresh_token'], $microsoftApp, $microsoftAccount, $output); + + foreach ($mailboxFolderCollection as $mailboxFolder) { + if ($mailboxFolder['displayName'] == 'Inbox') { + $mailboxFolderId = $mailboxFolder['id']; + break; + } + } + + $nextLink = null; + $counter = 1; + + do { + $response = $nextLink ? MicrosoftGraph\Me::getMessagesWithNextLink($nextLink, $credentials['access_token']) : MicrosoftGraph\Me::messages($credentials['access_token'], $mailboxFolderId, $filters); + + if (! empty($response['error'])) { + if (! empty($response['error']['code']) && $response['error']['code'] == 'InvalidAuthenticationToken') { + $tokenResponse = $this->microsoftIntegration->refreshAccessToken($microsoftApp, $credentials['refresh_token']); + + if (! empty($tokenResponse['access_token'])) { + $microsoftAccount->setCredentials(json_encode($tokenResponse)); + $this->entityManager->persist($microsoftAccount); + $this->entityManager->flush(); + + $credentials['access_token'] = $tokenResponse['access_token']; + $response = $nextLink ? MicrosoftGraph\Me::getMessagesWithNextLink($nextLink, $credentials['access_token']) : MicrosoftGraph\Me::messages($credentials['access_token'], $mailboxFolderId, $filters); + } else { + $output->writeln("\n ERROR Failed to retrieve a valid access token.\n"); + + return; } + } else { + $errorCode = $response['error']['code'] ?? 'Unknown'; + $output->writeln("\n ERROR An unexpected api error occurred of type '" . $errorCode . "'.\n"); - $counter ++; + return; } + } - $output->writeln(" - Mailbox refreshed successfully!"); + if ($counter === 1) { + $emailCount = $response['@odata.count'] ?? 'NA'; + $output->writeln(" - Found a total of $emailCount emails in mailbox since $timeSpan"); + } + + if (! empty($response['value'])) { + $output->writeln("\n # Processing all found emails iteratively:"); + $output->writeln("\n API " . $this->outlookEndpoint . "\n"); + + foreach ($response['value'] as $message) { + $output->writeln(" - Processing email $counter of $emailCount:"); + + $detailedMessage = MicrosoftGraph\Me::message($message['id'], $credentials['access_token']); + + $attachments = $detailedMessage['attachments']; + $outlookAttachments = ['outlookAttachments' => []]; + + foreach ($attachments as $attachment) { + if (isset($attachment['contentBytes'])) { + $tempFilePath = sys_get_temp_dir(); + + if (! is_dir($tempFilePath)) { + mkdir($tempFilePath, 0755, true); + } + + $filePath = $tempFilePath . '/' . $attachment['name']; + + if (file_exists($filePath)) { + $mimeType = mime_content_type($filePath); + } else { + $mimeType = 'application/octet-stream'; + } + + $outlookAttachments['outlookAttachments'][] = [ + 'content' => $attachment['contentBytes'], + 'mimeType' => $mimeType, + 'name' => $attachment['name'], + ]; + } + } + + $detailedMessage = array_merge($detailedMessage, $outlookAttachments); + + if (isset($detailedMessage['body']['content'])) { + $detailedMessage['body']['content'] = preg_replace('/]+>/', '', $detailedMessage['body']['content']); + $detailedMessage['body']['content'] = preg_replace('/<\/?head[^>]*>/', '', $detailedMessage['body']['content']); + $detailedMessage['body']['content'] = preg_replace('/<\/?body[^>]*>/', '', $detailedMessage['body']['content']); + } + + unset($detailedMessage['attachments']); + + list($response, $responseCode, $responseErrorMessage) = $this->parseOutlookInboundEmail($detailedMessage, $output); + + if ($responseCode == 200) { + $output->writeln("\n 200 " . $response['message'] . "\n"); + } else { + if (!empty($responseErrorMessage)) { + $output->writeln("\n ERROR $responseErrorMessage\n"); + } else { + $responseErrorMessage = $response['message'] ?? "Null response received"; + $output->writeln("\n ERROR $responseErrorMessage\n"); + } + } - if (true == $mailbox['deleted']) { - imap_expunge($imap); - imap_close($imap,CL_EXPUNGE); + $counter++; } } + + $nextLink = $response['@odata.nextLink'] ?? null; + + } while ($nextLink); + + $output->writeln(" - Mailbox refreshed successfully!"); + } + + private function getOutlookMailboxFolders($accessToken, $refreshToken, $microsoftApp, $microsoftAccount, OutputInterface $output) + { + $response = MicrosoftGraph\Me::mailFolders($accessToken); + + if (! empty($response['error'])) { + if ( + ! empty($response['error']['code']) + && $response['error']['code'] == 'InvalidAuthenticationToken' + ) { + $tokenResponse = $this->microsoftIntegration->refreshAccessToken($microsoftApp, $refreshToken); + + if (! empty($tokenResponse['access_token'])) { + $microsoftAccount->setCredentials(json_encode($tokenResponse)); + + $this->entityManager->persist($microsoftAccount); + $this->entityManager->flush(); + + $response = MicrosoftGraph\Me::mailFolders($tokenResponse['access_token']); + + } else { + $output->writeln("\n ERROR Failed to retrieve a valid access token.\n"); + + return []; + } + } else { + if (! empty($response['error']['code'])) { + $output->writeln("\n ERROR An unexpected api error occurred of type '" . $response['error']['code'] . "'.\n"); + } else { + $output->writeln("\n ERROR An unexpected api error occurred.\n"); + } + + return []; + } } - return; + return !empty($response['value']) ? $response['value'] : []; } public function parseInboundEmail($message, $output) @@ -195,7 +424,9 @@ public function parseInboundEmail($message, $output) $responseCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE); $responseErrorMessage = null; - if (curl_errno($curlHandler) || $responseCode != 200) { + if (curl_errno($curlHandler) + || $responseCode != 200 + ) { $responseErrorMessage = curl_error($curlHandler); } @@ -204,17 +435,31 @@ public function parseInboundEmail($message, $output) return [$response, $responseCode, $responseErrorMessage]; } - protected function isSecureConnectionAvailable() + public function parseOutlookInboundEmail($detailedMessage, $output) { - $headers = [CURLOPT_NOBODY => true, CURLOPT_HEADER => false]; - $curlHandler = curl_init('https://' . $this->container->getParameter('uvdesk.site_url')); + $curlHandler = curl_init(); + + curl_setopt($curlHandler, CURLOPT_HEADER, 0); + curl_setopt($curlHandler, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curlHandler, CURLOPT_POST, 1); + curl_setopt($curlHandler, CURLOPT_URL, $this->outlookEndpoint); + curl_setopt($curlHandler, CURLOPT_POSTFIELDS, http_build_query(['email' => $detailedMessage])); - curl_setopt_array($curlHandler, $headers); - curl_exec($curlHandler); + $curlResponse = curl_exec($curlHandler); + + $response = json_decode($curlResponse, true); + $responseCode = curl_getinfo($curlHandler, CURLINFO_HTTP_CODE); + $responseErrorMessage = null; + + if ( + curl_errno($curlHandler) + || $responseCode != 200 + ) { + $responseErrorMessage = curl_error($curlHandler); + } - $isSecureRequestAvailable = curl_errno($curlHandler) === 0 ? true : false; curl_close($curlHandler); - return $isSecureRequestAvailable; + return [$response, $responseCode, $responseErrorMessage]; } -} +} \ No newline at end of file diff --git a/Controller/MailboxChannel.php b/Controller/MailboxChannel.php index 755d991..94e7716 100644 --- a/Controller/MailboxChannel.php +++ b/Controller/MailboxChannel.php @@ -2,6 +2,7 @@ namespace Webkul\UVDesk\MailboxBundle\Controller; +use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -13,6 +14,10 @@ use Symfony\Contracts\Translation\TranslatorInterface; use Webkul\UVDesk\CoreFrameworkBundle\SwiftMailer\SwiftMailer as SwiftMailerService; use Webkul\UVDesk\CoreFrameworkBundle\Services\UserService; +use Webkul\UVDesk\MailboxBundle\Utils\IMAP; +use Webkul\UVDesk\MailboxBundle\Utils\SMTP; +use Webkul\UVDesk\CoreFrameworkBundle\Entity\Microsoft\MicrosoftApp; +use Webkul\UVDesk\CoreFrameworkBundle\Entity\Microsoft\MicrosoftAccount; class MailboxChannel extends AbstractController { @@ -20,13 +25,15 @@ class MailboxChannel extends AbstractController private $translator; private $swiftMailer; private $userService; + private $entityManager; - public function __construct(UserService $userService, MailboxService $mailboxService, TranslatorInterface $translator, SwiftMailerService $swiftMailer) + public function __construct(UserService $userService, MailboxService $mailboxService, TranslatorInterface $translator, SwiftMailerService $swiftMailer, EntityManagerInterface $entityManager) { $this->userService = $userService; $this->mailboxService = $mailboxService; $this->translator = $translator; $this->swiftMailer = $swiftMailer; + $this->entityManager = $entityManager; } public function loadMailboxes() @@ -37,58 +44,221 @@ public function loadMailboxes() return $this->render('@UVDeskMailbox//listConfigurations.html.twig'); } - + public function createMailboxConfiguration(Request $request) { if (!$this->userService->isAccessAuthorized('ROLE_ADMIN')) { return $this->redirect($this->generateUrl('helpdesk_member_dashboard')); } - $swiftmailerConfigurationCollection = $this->swiftMailer->parseSwiftMailerConfigurations(); + if ('microsoft') { + $microsoftAppCollection = $this->entityManager->getRepository(MicrosoftApp::class)->findBy(['isEnabled' => true, 'isVerified' => true]); + $microsoftAccountCollection = $this->entityManager->getRepository(MicrosoftAccount::class)->findAll(); - if ($request->getMethod() == 'POST') { - $params = $request->request->all(); + $microsoftAppCollection = array_map(function ($microsoftApp) { + return [ + 'id' => $microsoftApp->getId(), + 'name' => $microsoftApp->getName(), + ]; + }, $microsoftAppCollection); - // IMAP Configuration - if (!empty($params['imap']['transport'])) { - ($imapConfiguration = ImapConfiguration::createTransportDefinition($params['imap']['transport'], !empty($params['imap']['host']) ? trim($params['imap']['host'], '"') : null)) - ->setUsername($params['imap']['username']) - ->setPassword(base64_encode($params['imap']['password'])); - } + $microsoftAccountCollection = array_map(function ($microsoftAccount) { + return [ + 'id' => $microsoftAccount->getId(), + 'name' => $microsoftAccount->getName(), + 'email' => $microsoftAccount->getEmail(), + ]; + }, $microsoftAccountCollection); + + if ($request->getMethod() == 'POST') { + $params = $request->request->all(); + + $smtpConfiguration = null; + $imapConfiguration = null; + + // IMAP Configuration + if (!empty($params['imap']['transport'])) { + $imapConfiguration = IMAP\Configuration::createTransportDefinition($params['imap']['transport'], !empty($params['imap']['host']) ? trim($params['imap']['host'], '"') : null); + + if ($imapConfiguration instanceof IMAP\Transport\AppTransportConfigurationInterface) { + if ($params['imap']['transport'] == 'outlook_oauth') { + $microsoftAccount = $this->entityManager->getRepository(MicrosoftAccount::class)->findOneById($params['imap']['username']); + + if (empty($microsoftAccount)) { + $this->addFlash('warning', 'No configuration details were found for the provided microsoft account.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + + $params['imap']['username'] = $microsoftAccount->getEmail(); + $params['imap']['client'] = $microsoftAccount->getMicrosoftApp()->getClientId(); + + $imapConfiguration + ->setClient($params['imap']['client']) + ->setUsername($params['imap']['username']) + ; + } else { + $this->addFlash('warning', 'The resolved IMAP configuration is not configured for any valid available app.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + } else if ($imapConfiguration instanceof IMAP\Transport\SimpleTransportConfigurationInterface) { + $imapConfiguration + ->setUsername($params['imap']['username']) + ; + } else { + $imapConfiguration + ->setUsername($params['imap']['username']) + ->setPassword(urlencode($params['imap']['password'])) + ; + } + } - // Swiftmailer Configuration - if (!empty($params['swiftmailer_id'])) { - foreach ($swiftmailerConfigurationCollection as $configuration) { - if ($configuration->getId() == $params['swiftmailer_id']) { - $swiftmailerConfiguration = $configuration; - break; + // SMTP Configuration + if (!empty($params['smtp']['transport'])) { + $smtpConfiguration = SMTP\Configuration::createTransportDefinition($params['smtp']['transport'], !empty($params['smtp']['host']) ? trim($params['smtp']['host'], '"') : null); + + if ($smtpConfiguration instanceof SMTP\Transport\AppTransportConfigurationInterface) { + if ($params['smtp']['transport'] == 'outlook_oauth') { + $microsoftAccount = $this->entityManager->getRepository(MicrosoftAccount::class)->findOneById($params['smtp']['username']); + + if (empty($microsoftAccount)) { + $this->addFlash('warning', 'No configuration details were found for the provided microsoft account.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + + $params['smtp']['username'] = $microsoftAccount->getEmail(); + $params['smtp']['client'] = $microsoftAccount->getMicrosoftApp()->getClientId(); + + $smtpConfiguration + ->setClient($params['smtp']['client']) + ->setUsername($params['smtp']['username']) + ; + } else { + $this->addFlash('warning', 'The resolved SMTP configuration is not configured for any valid available app.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + } else if ($smtpConfiguration instanceof SMTP\Transport\ResolvedTransportConfigurationInterface) { + $smtpConfiguration + ->setUsername($params['smtp']['username']) + ->setPassword(urlencode($params['smtp']['password'])) + ; + } else { + $smtpConfiguration + ->setHost($params['smtp']['host']) + ->setPort((int) $params['smtp']['port']) + ->setUsername($params['smtp']['username']) + ->setPassword(urlencode($params['smtp']['password'])) + ->setSenderAddress(!empty($params['smtp']['senderAddress']) ? $params['smtp']['senderAddress'] : null) + ; } } + + if (empty($imapConfiguration) && empty($smtpConfiguration)) { + $this->addFlash('warning', 'Invalid mailbox details provided. Mailbox needs to have at least IMAP or SMTP settings defined.'); + } else { + $mailboxConfiguration = $mailboxService->parseMailboxConfigurations(); + + $mailbox = new Mailbox(!empty($params['id']) ? $params['id'] : null); + $mailbox + ->setName($params['name']) + ->setIsEnabled(!empty($params['isEnabled']) && 'on' == $params['isEnabled'] ? true : false) + ->setIsEmailDeliveryDisabled(!empty($params['isEmailDeliveryDisabled']) && 'on' == $params['isEmailDeliveryDisabled'] ? true : false) + ; + + if (!empty($imapConfiguration)) { + $mailbox + ->setImapConfiguration($imapConfiguration) + ; + } + + if (!empty($smtpConfiguration)) { + $mailbox + ->setSmtpConfiguration($smtpConfiguration) + ; + } + + $mailboxConfiguration->addMailbox($mailbox); + + if (!empty($params['isDefault']) && 'on' == $params['isDefault']) { + $mailboxConfiguration + ->setDefaultMailbox($mailbox) + ; + } + + file_put_contents($mailboxService->getPathToConfigurationFile(), (string) $mailboxConfiguration); + + $this->addFlash('success', $translator->trans('Mailbox successfully created.')); + + return new RedirectResponse($this->generateUrl('helpdesk_member_mailbox_settings')); + } } - if (!empty($imapConfiguration) && !empty($swiftmailerConfiguration)) { - $mailboxService = $this->mailboxService; - $mailboxConfiguration = $mailboxService->parseMailboxConfigurations(); + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + }else { + $swiftmailerConfigurationCollection = $this->swiftMailer->parseSwiftMailerConfigurations(); - ($mailbox = new Mailbox(!empty($params['id']) ? $params['id'] : null)) - ->setName($params['name']) - ->setIsEnabled(!empty($params['isEnabled']) && 'on' == $params['isEnabled'] ? true : false) - ->setIsDeleted(!empty($params['isDeleted']) && 'on' == $params['isDeleted'] ? true : false) - ->setImapConfiguration($imapConfiguration) - ->setSwiftMailerConfiguration($swiftmailerConfiguration); + if ($request->getMethod() == 'POST') { + $params = $request->request->all(); + + // IMAP Configuration + if (!empty($params['imap']['transport'])) { + ($imapConfiguration = ImapConfiguration::createTransportDefinition($params['imap']['transport'], !empty($params['imap']['host']) ? trim($params['imap']['host'], '"') : null)) + ->setUsername($params['imap']['username']) + ->setPassword(base64_encode($params['imap']['password'])); + } - $mailboxConfiguration->addMailbox($mailbox); + // Swiftmailer Configuration + if (!empty($params['swiftmailer_id'])) { + foreach ($swiftmailerConfigurationCollection as $configuration) { + if ($configuration->getId() == $params['swiftmailer_id']) { + $swiftmailerConfiguration = $configuration; + break; + } + } + } - file_put_contents($mailboxService->getPathToConfigurationFile(), (string) $mailboxConfiguration); + if (!empty($imapConfiguration) && !empty($swiftmailerConfiguration)) { + $mailboxService = $this->mailboxService; + $mailboxConfiguration = $mailboxService->parseMailboxConfigurations(); - $this->addFlash('success', $this->translator->trans('Mailbox successfully created.')); - return new RedirectResponse($this->generateUrl('helpdesk_member_mailbox_settings')); + ($mailbox = new Mailbox(!empty($params['id']) ? $params['id'] : null)) + ->setName($params['name']) + ->setIsEnabled(!empty($params['isEnabled']) && 'on' == $params['isEnabled'] ? true : false) + ->setIsDeleted(!empty($params['isDeleted']) && 'on' == $params['isDeleted'] ? true : false) + ->setImapConfiguration($imapConfiguration) + ->setSwiftMailerConfiguration($swiftmailerConfiguration); + + $mailboxConfiguration->addMailbox($mailbox); + + file_put_contents($mailboxService->getPathToConfigurationFile(), (string) $mailboxConfiguration); + + $this->addFlash('success', $this->translator->trans('Mailbox successfully created.')); + return new RedirectResponse($this->generateUrl('helpdesk_member_mailbox_settings')); + } } - } - return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ - 'swiftmailerConfigurations' => $swiftmailerConfigurationCollection, - ]); + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'swiftmailerConfigurations' => $swiftmailerConfigurationCollection, + ]); + } } public function updateMailboxConfiguration($id, Request $request) @@ -96,79 +266,258 @@ public function updateMailboxConfiguration($id, Request $request) if (!$this->userService->isAccessAuthorized('ROLE_ADMIN')) { return $this->redirect($this->generateUrl('helpdesk_member_dashboard')); } - - $mailboxService = $this->mailboxService; - $existingMailboxConfiguration = $mailboxService->parseMailboxConfigurations(); - $swiftmailerConfigurationCollection = $this->swiftMailer->parseSwiftMailerConfigurations(); - - foreach ($existingMailboxConfiguration->getMailboxes() as $configuration) { - if ($configuration->getId() == $id) { - $mailbox = $configuration; - break; - } - } - if (empty($mailbox)) { - return new Response('', 404); - } + if('microsoft') { + $mailboxConfiguration = $mailboxService->parseMailboxConfigurations(); + $mailbox = $mailboxConfiguration->getMailboxById($id); - if ($request->getMethod() == 'POST') { - $params = $request->request->all(); - // IMAP Configuration - if (!empty($params['imap']['transport'])) { - ($imapConfiguration = ImapConfiguration::createTransportDefinition($params['imap']['transport'], !empty($params['imap']['host']) ? trim($params['imap']['host'], '"') : null)) - ->setUsername($params['imap']['username']) - ->setPassword(base64_encode($params['imap']['password'])); + if (empty($mailbox)) { + return new Response('', 404); } - // Swiftmailer Configuration - if (!empty($params['swiftmailer_id'])) { - foreach ($swiftmailerConfigurationCollection as $configuration) { - if ($configuration->getId() == $params['swiftmailer_id']) { - $swiftmailerConfiguration = $configuration; + $microsoftAppCollection = $this->entityManager->getRepository(MicrosoftApp::class)->findBy(['isEnabled' => true, 'isVerified' => true]); + $microsoftAccountCollection = $this->entityManager->getRepository(MicrosoftAccount::class)->findAll(); + + $microsoftAppCollection = array_map(function ($microsoftApp) { + return [ + 'id' => $microsoftApp->getId(), + 'name' => $microsoftApp->getName(), + ]; + }, $microsoftAppCollection); + + $microsoftAccountCollection = array_map(function ($microsoftAccount) { + return [ + 'id' => $microsoftAccount->getId(), + 'name' => $microsoftAccount->getName(), + 'email' => $microsoftAccount->getEmail(), + ]; + }, $microsoftAccountCollection); + + if ($request->getMethod() == 'POST') { + $params = $request->request->all(); + + $smtpConfiguration = null; + $imapConfiguration = null; - break; + // IMAP Configuration + if (!empty($params['imap']['transport'])) { + $imapConfiguration = IMAP\Configuration::createTransportDefinition($params['imap']['transport'], !empty($params['imap']['host']) ? trim($params['imap']['host'], '"') : null); + + if ($imapConfiguration instanceof IMAP\Transport\AppTransportConfigurationInterface) { + if ($params['imap']['transport'] == 'outlook_oauth') { + $microsoftAccount = $this->entityManager->getRepository(MicrosoftAccount::class)->findOneById($params['imap']['username']); + + if (empty($microsoftAccount)) { + $this->addFlash('warning', 'No configuration details were found for the provided microsoft account.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + + $params['imap']['username'] = $microsoftAccount->getEmail(); + $params['imap']['client'] = $microsoftAccount->getMicrosoftApp()->getClientId(); + + $imapConfiguration + ->setClient($params['imap']['client']) + ->setUsername($params['imap']['username']) + ; + } else { + $this->addFlash('warning', 'The resolved IMAP configuration is not configured for any valid available app.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + } else if ($imapConfiguration instanceof IMAP\Transport\SimpleTransportConfigurationInterface) { + $imapConfiguration + ->setUsername($params['imap']['username']) + ; + } else { + $imapConfiguration + ->setUsername($params['imap']['username']) + ->setPassword(urlencode($params['imap']['password'])) + ; } } - } - if (!empty($imapConfiguration) && !empty($swiftmailerConfiguration)) { - $mailboxConfiguration = new MailboxConfiguration(); - - foreach ($existingMailboxConfiguration->getMailboxes() as $configuration) { - if ($mailbox->getId() == $configuration->getId()) { - if (empty($params['id'])) { - $mailbox = new Mailbox(); - } else if ($mailbox->getId() != $params['id']) { - $mailbox = new Mailbox($params['id']); + // SMTP Configuration + if (!empty($params['smtp']['transport'])) { + $smtpConfiguration = SMTP\Configuration::createTransportDefinition($params['smtp']['transport'], !empty($params['smtp']['host']) ? trim($params['smtp']['host'], '"') : null); + + if ($smtpConfiguration instanceof SMTP\Transport\AppTransportConfigurationInterface) { + if ($params['smtp']['transport'] == 'outlook_oauth') { + $microsoftAccount = $this->entityManager->getRepository(MicrosoftAccount::class)->findOneById($params['smtp']['username']); + + if (empty($microsoftAccount)) { + $this->addFlash('warning', 'No configuration details were found for the provided microsoft account.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); + } + + $params['smtp']['username'] = $microsoftAccount->getEmail(); + $params['smtp']['client'] = $microsoftAccount->getMicrosoftApp()->getClientId(); + + $smtpConfiguration + ->setClient($params['smtp']['client']) + ->setUsername($params['smtp']['username']) + ; + } else { + $this->addFlash('warning', 'The resolved SMTP configuration is not configured for any valid available app.'); + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); } + } else if ($smtpConfiguration instanceof SMTP\Transport\ResolvedTransportConfigurationInterface) { + $smtpConfiguration + ->setUsername($params['smtp']['username']) + ->setPassword(urlencode($params['smtp']['password'])) + ; + } else { + $smtpConfiguration + ->setHost($params['smtp']['host']) + ->setPort((int) $params['smtp']['port']) + ->setUsername($params['smtp']['username']) + ->setPassword(urlencode($params['smtp']['password'])) + ->setSenderAddress(!empty($params['smtp']['senderAddress']) ? $params['smtp']['senderAddress'] : null) + ; + } + } + if (empty($imapConfiguration) && empty($smtpConfiguration)) { + $this->addFlash('warning', 'Invalid mailbox details provided. Mailbox needs to have at least IMAP or SMTP settings defined.'); + } else { + if (!empty($params['id']) && $params['id'] != $mailbox->getId()) { + $mailboxConfiguration->removeMailbox($mailbox); + + $mailbox = new Mailbox($params['id']); + } + + $mailbox + ->setName($params['name']) + ->setIsEnabled(!empty($params['isEnabled']) && 'on' == $params['isEnabled'] ? true : false) + ->setIsEmailDeliveryDisabled(!empty($params['isEmailDeliveryDisabled']) && 'on' == $params['isEmailDeliveryDisabled'] ? true : false) + ; + + if (!empty($imapConfiguration)) { $mailbox - ->setName($params['name']) - ->setIsEnabled(!empty($params['isEnabled']) && 'on' == $params['isEnabled'] ? true : false) - ->setIsDeleted(!empty($params['isDeleted']) && 'on' == $params['isDeleted'] ? true : false) ->setImapConfiguration($imapConfiguration) - ->setSwiftMailerConfiguration($swiftmailerConfiguration); + ; + } - $mailboxConfiguration->addMailbox($mailbox); + if (!empty($smtpConfiguration)) { + $mailbox + ->setSmtpConfiguration($smtpConfiguration) + ; + } - continue; + $mailboxConfiguration->addMailbox($mailbox); + + if (!empty($params['isDefault']) && 'on' == $params['isDefault']) { + $mailboxConfiguration + ->setDefaultMailbox($mailbox) + ; } - $mailboxConfiguration->addMailbox($configuration); + file_put_contents($mailboxService->getPathToConfigurationFile(), (string) $mailboxConfiguration); + + $this->addFlash('success', $translator->trans('Mailbox successfully updated.')); + + return new RedirectResponse($this->generateUrl('helpdesk_member_mailbox_settings')); } + } + + $defaultMailbox = $mailboxConfiguration->getDefaultMailbox(); - file_put_contents($mailboxService->getPathToConfigurationFile(), (string) $mailboxConfiguration); + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'mailbox' => $mailbox, + 'isDefaultMailbox' => !empty($defaultMailbox) && $defaultMailbox->getId() == $mailbox->getId(), + 'microsoftAppCollection' => $microsoftAppCollection, + 'microsoftAccountCollection' => $microsoftAccountCollection, + ]); - $this->addFlash('success', $this->translator->trans('Mailbox successfully updated.')); - - return new RedirectResponse($this->generateUrl('helpdesk_member_mailbox_settings')); + } else { + $mailboxService = $this->mailboxService; + $existingMailboxConfiguration = $mailboxService->parseMailboxConfigurations(); + $swiftmailerConfigurationCollection = $this->swiftMailer->parseSwiftMailerConfigurations(); + + foreach ($existingMailboxConfiguration->getMailboxes() as $configuration) { + if ($configuration->getId() == $id) { + $mailbox = $configuration; + break; + } } - } - return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ - 'mailbox' => $mailbox ?? null, - 'swiftmailerConfigurations' => $swiftmailerConfigurationCollection, - ]); + if (empty($mailbox)) { + return new Response('', 404); + } + + if ($request->getMethod() == 'POST') { + $params = $request->request->all(); + // IMAP Configuration + if (!empty($params['imap']['transport'])) { + ($imapConfiguration = ImapConfiguration::createTransportDefinition($params['imap']['transport'], !empty($params['imap']['host']) ? trim($params['imap']['host'], '"') : null)) + ->setUsername($params['imap']['username']) + ->setPassword(base64_encode($params['imap']['password'])); + } + + // Swiftmailer Configuration + if (!empty($params['swiftmailer_id'])) { + foreach ($swiftmailerConfigurationCollection as $configuration) { + if ($configuration->getId() == $params['swiftmailer_id']) { + $swiftmailerConfiguration = $configuration; + + break; + } + } + } + + if (!empty($imapConfiguration) && !empty($swiftmailerConfiguration)) { + $mailboxConfiguration = new MailboxConfiguration(); + + foreach ($existingMailboxConfiguration->getMailboxes() as $configuration) { + if ($mailbox->getId() == $configuration->getId()) { + if (empty($params['id'])) { + $mailbox = new Mailbox(); + } else if ($mailbox->getId() != $params['id']) { + $mailbox = new Mailbox($params['id']); + } + + $mailbox + ->setName($params['name']) + ->setIsEnabled(!empty($params['isEnabled']) && 'on' == $params['isEnabled'] ? true : false) + ->setIsDeleted(!empty($params['isDeleted']) && 'on' == $params['isDeleted'] ? true : false) + ->setImapConfiguration($imapConfiguration) + ->setSwiftMailerConfiguration($swiftmailerConfiguration); + + $mailboxConfiguration->addMailbox($mailbox); + + continue; + } + + $mailboxConfiguration->addMailbox($configuration); + } + + file_put_contents($mailboxService->getPathToConfigurationFile(), (string) $mailboxConfiguration); + + $this->addFlash('success', $this->translator->trans('Mailbox successfully updated.')); + + return new RedirectResponse($this->generateUrl('helpdesk_member_mailbox_settings')); + } + } + + return $this->render('@UVDeskMailbox//manageConfigurations.html.twig', [ + 'mailbox' => $mailbox ?? null, + 'swiftmailerConfigurations' => $swiftmailerConfigurationCollection, + ]); + + } } } diff --git a/Resources/views/manageConfigurations.html.twig b/Resources/views/manageConfigurations.html.twig index f4a759c..cd59d73 100644 --- a/Resources/views/manageConfigurations.html.twig +++ b/Resources/views/manageConfigurations.html.twig @@ -85,6 +85,7 @@ + {# Default Mailbox #}