Files
provider_imap/lib/Providers/ServiceLocation.php
T
2026-06-23 14:23:56 -04:00

190 lines
7.8 KiB
PHP

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: Sebastian Krupinski <krupinski01@gmail.com>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace KTXM\ProviderImap\Providers;
use KTXM\ProviderImap\Client\ConnectionConfig;
use KTXM\ProviderImap\Client\ConnectionSecurity;
use KTXM\ProviderImap\Smtp\ConnectionConfig as SmtpConnectionConfig;
use KTXM\ProviderImap\Smtp\ConnectionSecurity as SmtpConnectionSecurity;
use KTXF\Resource\Provider\ResourceServiceLocationSocketSplit;
/**
* IMAP/SMTP Service Location
*
* Split socket location: the inbound side describes the IMAP server, the
* outbound side describes the SMTP submission server.
*/
class ServiceLocation implements ResourceServiceLocationSocketSplit
{
public function __construct(
private string $inboundHost = '',
private int $inboundPort = 993,
private string $inboundEncryption = 'ssl', // none | ssl | tls | starttls
private bool $inboundVerifyPeer = true,
private bool $inboundVerifyHost = true,
private string $outboundHost = '',
private int $outboundPort = 587,
private string $outboundEncryption = 'starttls', // none | ssl | tls | starttls
private bool $outboundVerifyPeer = true,
private bool $outboundVerifyHost = true,
) {}
// ── Serialisation ────────────────────────────────────────────────────────
public function toStore(): array
{
return $this->jsonSerialize();
}
public function fromStore(array $data): static
{
return $this->jsonDeserialize($data);
}
public function jsonSerialize(): array
{
return [
'type' => self::TYPE_SOCKET_SPLIT,
'inboundHost' => $this->inboundHost,
'inboundPort' => $this->inboundPort,
'inboundEncryption' => $this->inboundEncryption,
'inboundVerifyPeer' => $this->inboundVerifyPeer,
'inboundVerifyHost' => $this->inboundVerifyHost,
'outboundHost' => $this->outboundHost,
'outboundPort' => $this->outboundPort,
'outboundEncryption' => $this->outboundEncryption,
'outboundVerifyPeer' => $this->outboundVerifyPeer,
'outboundVerifyHost' => $this->outboundVerifyHost,
];
}
public function jsonDeserialize(array|string $data): static
{
if (is_string($data)) {
$data = json_decode($data, true);
}
$this->inboundHost = $data['inboundHost'] ?? '';
$this->inboundPort = (int) ($data['inboundPort'] ?? 993);
$this->inboundEncryption = $data['inboundEncryption'] ?? 'ssl';
$this->inboundVerifyPeer = $data['inboundVerifyPeer'] ?? true;
$this->inboundVerifyHost = $data['inboundVerifyHost'] ?? true;
$this->outboundHost = $data['outboundHost'] ?? '';
$this->outboundPort = (int) ($data['outboundPort'] ?? 587);
$this->outboundEncryption = $data['outboundEncryption'] ?? 'starttls';
$this->outboundVerifyPeer = $data['outboundVerifyPeer'] ?? true;
$this->outboundVerifyHost = $data['outboundVerifyHost'] ?? true;
return $this;
}
// ── ResourceServiceLocationSocketSplit ───────────────────────────────────
public function type(): string
{
return self::TYPE_SOCKET_SPLIT;
}
public function locationInbound(): string
{
return $this->inboundEncryption . '://' . $this->inboundHost . ':' . $this->inboundPort;
}
public function locationOutbound(): string
{
return $this->outboundEncryption . '://' . $this->outboundHost . ':' . $this->outboundPort;
}
public function getInboundHost(): string { return $this->inboundHost; }
public function setInboundHost(string $value): void { $this->inboundHost = $value; }
public function getOutboundHost(): string { return $this->outboundHost; }
public function setOutboundHost(string $value): void { $this->outboundHost = $value; }
public function getInboundPort(): int { return $this->inboundPort; }
public function setInboundPort(int $value): void { $this->inboundPort = $value; }
public function getOutboundPort(): int { return $this->outboundPort; }
public function setOutboundPort(int $value): void { $this->outboundPort = $value; }
public function getInboundEncryption(): string { return $this->inboundEncryption; }
public function setInboundEncryption(string $value): void { $this->inboundEncryption = $value; }
public function getOutboundEncryption(): string { return $this->outboundEncryption; }
public function setOutboundEncryption(string $value): void { $this->outboundEncryption = $value; }
public function getInboundVerifyPeer(): bool { return $this->inboundVerifyPeer; }
public function setInboundVerifyPeer(bool $value): void { $this->inboundVerifyPeer = $value; }
public function getInboundVerifyHost(): bool { return $this->inboundVerifyHost; }
public function setInboundVerifyHost(bool $value): void { $this->inboundVerifyHost = $value; }
public function getOutboundVerifyPeer(): bool { return $this->outboundVerifyPeer; }
public function setOutboundVerifyPeer(bool $value): void { $this->outboundVerifyPeer = $value; }
public function getOutboundVerifyHost(): bool { return $this->outboundVerifyHost; }
public function setOutboundVerifyHost(bool $value): void { $this->outboundVerifyHost = $value; }
// ── Client helpers ───────────────────────────────────────────────────────
/**
* Build an IMAP ConnectionConfig from the inbound side.
*/
public function toConnectionConfig(?string $username = null, ?string $password = null): ConnectionConfig
{
return new ConnectionConfig(
host: $this->inboundHost,
port: $this->inboundPort,
security: $this->imapSecurity($this->inboundEncryption),
username: $username,
password: $password,
verifyPeer: $this->inboundVerifyPeer,
verifyPeerName: $this->inboundVerifyHost,
allowSelfSigned: !$this->inboundVerifyPeer,
);
}
/**
* Build an SMTP submission ConnectionConfig from the outbound side.
*/
public function toSmtpConnectionConfig(?string $username = null, ?string $password = null): SmtpConnectionConfig
{
return new SmtpConnectionConfig(
host: $this->outboundHost,
port: $this->outboundPort,
security: $this->smtpSecurity($this->outboundEncryption),
username: $username,
password: $password,
verifyPeer: $this->outboundVerifyPeer,
verifyPeerName: $this->outboundVerifyHost,
allowSelfSigned: !$this->outboundVerifyPeer,
);
}
private function imapSecurity(string $encryption): ConnectionSecurity
{
return match ($encryption) {
'ssl', 'tls' => ConnectionSecurity::Tls,
'starttls' => ConnectionSecurity::StartTls,
default => ConnectionSecurity::Plain,
};
}
private function smtpSecurity(string $encryption): SmtpConnectionSecurity
{
return match ($encryption) {
'ssl', 'tls' => SmtpConnectionSecurity::Tls,
'starttls' => SmtpConnectionSecurity::StartTls,
default => SmtpConnectionSecurity::Plain,
};
}
}