From 927adcc756b8e4f0e9b6f79e7783e1a7acbd4e20 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 15 Jan 2026 15:39:05 +0100 Subject: [PATCH 1/3] fix(m365): Fix checking proxy address when importing alias The main issue was that we tested presence of "smtp" string instead of "smtp:". Also, we make sure that the substring is at the beginning of the string. Also, "smtp:" is case insensitive. --- app/src/Command/Office365ImportCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/Command/Office365ImportCommand.php b/app/src/Command/Office365ImportCommand.php index 77aed2ac..740898a4 100644 --- a/app/src/Command/Office365ImportCommand.php +++ b/app/src/Command/Office365ImportCommand.php @@ -177,8 +177,8 @@ private function addAliases(User $user, array $proxyAdresses): array { $aliases = []; foreach ($proxyAdresses as $proxyAdresse) { - if (strpos($proxyAdresse, "smtp") !== false) { - $aliasEmail = explode('smtp:', $proxyAdresse)[1]; + if (str_starts_with(strtolower($proxyAdresse), 'smtp:')) { + $aliasEmail = substr($proxyAdresse, strlen('smtp:')); $domainAlias = explode('@', $aliasEmail)[1]; if ($domainAlias == $this->connector->getDomain()->getDomain()) { $alias = $this->em->getRepository(User::class)->findOneBy(['email' => $aliasEmail]); From ed4cff1ee6c2b7de527e4fa6e540b97a5d6843b0 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 15 Jan 2026 15:40:36 +0100 Subject: [PATCH 2/3] fix(m365): Don't mark initial user as an alias of himself --- app/migrations/Version20260115151631.php | 26 ++++++++++++++++++++++ app/src/Command/Office365ImportCommand.php | 6 +++++ 2 files changed, 32 insertions(+) create mode 100644 app/migrations/Version20260115151631.php diff --git a/app/migrations/Version20260115151631.php b/app/migrations/Version20260115151631.php new file mode 100644 index 00000000..851e32e9 --- /dev/null +++ b/app/migrations/Version20260115151631.php @@ -0,0 +1,26 @@ +addSql('UPDATE users SET original_user_id = null WHERE original_user_id = id'); + } + + public function down(Schema $schema): void + { + // Do nothing on purpose + } +} diff --git a/app/src/Command/Office365ImportCommand.php b/app/src/Command/Office365ImportCommand.php index 740898a4..42f27dfb 100644 --- a/app/src/Command/Office365ImportCommand.php +++ b/app/src/Command/Office365ImportCommand.php @@ -179,6 +179,12 @@ private function addAliases(User $user, array $proxyAdresses): array foreach ($proxyAdresses as $proxyAdresse) { if (str_starts_with(strtolower($proxyAdresse), 'smtp:')) { $aliasEmail = substr($proxyAdresse, strlen('smtp:')); + + // Don't mark the initial user as an alias of himself + if ($aliasEmail === $user->getEmail()) { + continue; + } + $domainAlias = explode('@', $aliasEmail)[1]; if ($domainAlias == $this->connector->getDomain()->getDomain()) { $alias = $this->em->getRepository(User::class)->findOneBy(['email' => $aliasEmail]); From f24fb50cabcc5e13e7a95a73b8bf5c845225d008 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Thu, 15 Jan 2026 15:44:05 +0100 Subject: [PATCH 3/3] chore(m365): Refactor creation of aliases --- app/src/Command/Office365ImportCommand.php | 62 ++++++++++++++-------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/app/src/Command/Office365ImportCommand.php b/app/src/Command/Office365ImportCommand.php index 42f27dfb..275f0a03 100644 --- a/app/src/Command/Office365ImportCommand.php +++ b/app/src/Command/Office365ImportCommand.php @@ -7,6 +7,7 @@ use App\Entity\Office365Connector; use App\Entity\User as User; use App\Service\MailaddrService; +use App\Util\Email; use Doctrine\ORM\EntityManagerInterface; use GuzzleHttp\Client; use GuzzleHttp\Exception\GuzzleException; @@ -176,31 +177,48 @@ private function importUsers(string $token): void private function addAliases(User $user, array $proxyAdresses): array { $aliases = []; - foreach ($proxyAdresses as $proxyAdresse) { - if (str_starts_with(strtolower($proxyAdresse), 'smtp:')) { - $aliasEmail = substr($proxyAdresse, strlen('smtp:')); + foreach ($proxyAdresses as $proxyAdress) { + if (!str_starts_with(strtolower($proxyAdress), 'smtp:')) { + continue; + } - // Don't mark the initial user as an alias of himself - if ($aliasEmail === $user->getEmail()) { - continue; - } + $aliasEmail = substr($proxyAdress, strlen('smtp:')); + if (!Email::validate($aliasEmail)) { + continue; + } - $domainAlias = explode('@', $aliasEmail)[1]; - if ($domainAlias == $this->connector->getDomain()->getDomain()) { - $alias = $this->em->getRepository(User::class)->findOneBy(['email' => $aliasEmail]); - if (!$alias) { - $alias = clone $user; - } - $alias->setUid(null); - $alias->setEmail($aliasEmail); - $alias->setUserName($aliasEmail); - $alias->setOriginalUser($user); - $alias->setOriginConnector($this->connector); - $this->em->persist($alias); - - $aliases[] = $alias; - } + // Don't mark the initial user as an alias of himself + if ($aliasEmail === $user->getEmail()) { + continue; + } + + // Get the domain associated to the email address + $domainName = Email::extractDomain($aliasEmail); + if (!$domainName) { + continue; } + + $domain = $this->em->getRepository(Domain::class)->findOneByDomain($domainName); + if (!$domain || $domain->getId() !== $this->connector->getDomain()->getId()) { + continue; + } + + // Create the alias if it doesn't exist yet + $alias = $this->em->getRepository(User::class)->findOneBy(['email' => $aliasEmail]); + if (!$alias) { + $alias = new User(); + $alias->setOriginConnector($this->connector); + } + + // And update information + $alias->setEmail($aliasEmail); + $alias->setUsername($aliasEmail); + $alias->setOriginalUser($user); + $alias->setDomain($domain); + + $this->em->persist($alias); + + $aliases[] = $alias; } return $aliases; }