feat: sync sending identities

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-07-28 21:50:37 -04:00
parent f0b0f87ce2
commit 5aa95fa329
2 changed files with 74 additions and 65 deletions
+59
View File
@@ -9,6 +9,7 @@ declare(strict_types=1);
namespace KTXM\ProviderJmapc\Providers\Mail;
use KTXF\Mail\Object\Address;
use KTXF\Mail\Provider\ProviderBaseInterface;
use KTXF\Mail\Provider\ProviderServiceDiscoverInterface;
use KTXF\Mail\Provider\ProviderServiceMutateInterface;
@@ -142,9 +143,66 @@ class Provider implements ProviderBaseInterface, ProviderServiceMutateInterface,
}
$created = $this->serviceStore->create($tenantId, $userId, $service);
$this->serviceIdentitiesSync($tenantId, $userId, (new Service())->fromStore($created));
return (string) $created['sid'];
}
/**
* Fetches sending identities from the JMAP server and overwrites
* primaryAddress/secondaryAddresses on the service with them.
*/
private function serviceIdentitiesSync(string $tenantId, string $userId, Service $service): void
{
try {
$client = RemoteService::freshClient($service);
$identities = RemoteService::mailService($client)->identityFetch();
// A JMAP server may expose multiple identities sharing the same
// address (e.g. distinct signatures/display names for one
// mailbox) — collapse those down to one entry per address,
// keeping the first label seen.
$addresses = [];
foreach ($identities as $identity) {
if ($identity->address() === null) {
continue;
}
$key = strtolower($identity->address());
if (!isset($addresses[$key])) {
$addresses[$key] = Address::fromArray(['address' => $identity->address(), 'label' => $identity->name()]);
}
}
$addresses = array_values($addresses);
if (empty($addresses)) {
return;
}
$currentAddress = strtolower($service->getPrimaryAddress()->getAddress());
$primaryIndex = 0;
foreach ($addresses as $index => $address) {
if (strtolower($address->getAddress()) === $currentAddress) {
$primaryIndex = $index;
break;
}
}
$secondary = [];
foreach ($addresses as $index => $address) {
if ($index !== $primaryIndex) {
$secondary[] = $address;
}
}
$service->setPrimaryAddress($addresses[$primaryIndex]);
$service->setSecondaryAddresses($secondary);
$this->serviceStore->modify($tenantId, $userId, $service);
} catch (\Throwable) {
// Server may not support urn:ietf:params:jmap:submission, or have
// no identities configured — fall back to what the user entered.
}
}
public function serviceModify(string $tenantId, string $userId, ResourceServiceMutateInterface $service): string
{
if (!($service instanceof Service)) {
@@ -152,6 +210,7 @@ class Provider implements ProviderBaseInterface, ProviderServiceMutateInterface,
}
$this->serviceStore->modify($tenantId, $userId, $service);
$this->serviceIdentitiesSync($tenantId, $userId, $service);
return (string) $service->identifier();
}