mail setup
This commit is contained in:
@@ -2247,6 +2247,7 @@ class ApiKernel
|
||||
$subject = 'Testversand';
|
||||
}
|
||||
$senderId = (int)$this->val($this->in, ['sender_id'], 0);
|
||||
$smtpProfileId = (int)$this->val($this->in, ['smtp_profile_id'], 0);
|
||||
|
||||
$row = null;
|
||||
$html = '';
|
||||
@@ -2291,14 +2292,30 @@ class ApiKernel
|
||||
$sender = $this->fetchSenderRow($customerId, $senderId);
|
||||
}
|
||||
}
|
||||
$smtpOverride = null;
|
||||
if ($smtpProfileId > 0 && $customerId > 0) {
|
||||
$profile = $this->fetchSmtpProfileRow($customerId, $smtpProfileId);
|
||||
$smtpOverride = [
|
||||
'enabled' => true,
|
||||
'host' => $profile['smtp_host'] ?? '',
|
||||
'port' => $profile['smtp_port'] ?? 0,
|
||||
'user' => $profile['smtp_user'] ?? '',
|
||||
'pass' => $this->fetchSmtpProfilePassword($customerId, $smtpProfileId),
|
||||
'secure' => $profile['smtp_secure'] ?? '',
|
||||
'from_email' => $profile['from_email'] ?? '',
|
||||
'from_name' => $profile['from_name'] ?? '',
|
||||
'reply_to' => $profile['reply_to'] ?? '',
|
||||
];
|
||||
}
|
||||
|
||||
if (!$this->dispatchTestMail($recipient, $subject, $html, $sender, $customerId)) {
|
||||
if (!$this->dispatchTestMail($recipient, $subject, $html, $sender, $customerId, $smtpOverride)) {
|
||||
$this->writeDebugLog('templates_test_send', [
|
||||
'time' => date(DATE_ATOM),
|
||||
'template_id' => $templateId,
|
||||
'to' => $recipient,
|
||||
'subject' => $subject,
|
||||
'sender_id' => $senderId > 0 ? $senderId : null,
|
||||
'smtp_profile_id' => $smtpProfileId > 0 ? $smtpProfileId : null,
|
||||
'from_email' => $sender['from_email'] ?? ($this->conf['smtp']['from_email'] ?? null),
|
||||
'from_name' => $sender['from_name'] ?? ($this->conf['smtp']['from_name'] ?? null),
|
||||
'html_length' => strlen($html),
|
||||
@@ -3054,6 +3071,18 @@ class ApiKernel
|
||||
case 'account.senders.delete':
|
||||
$this->handleAccountSenderDelete();
|
||||
break;
|
||||
case 'account.smtp_profiles.list':
|
||||
$this->handleAccountSmtpProfilesList();
|
||||
break;
|
||||
case 'account.smtp_profiles.save':
|
||||
$this->handleAccountSmtpProfileSave();
|
||||
break;
|
||||
case 'account.smtp_profiles.delete':
|
||||
$this->handleAccountSmtpProfileDelete();
|
||||
break;
|
||||
case 'account.smtp_profiles.copy':
|
||||
$this->handleAccountSmtpProfileCopy();
|
||||
break;
|
||||
case 'dashboard.metrics':
|
||||
$this->handleDashboardMetrics();
|
||||
break;
|
||||
@@ -3835,8 +3864,22 @@ class ApiKernel
|
||||
$this->fail('Valid recipient required', null, 422);
|
||||
}
|
||||
|
||||
$smtpProfileId = (int)($this->in['smtp_profile_id'] ?? 0);
|
||||
$smtpOverride = null;
|
||||
if (array_key_exists('smtp_host', $this->in) || array_key_exists('smtp_enabled', $this->in)) {
|
||||
if ($smtpProfileId > 0) {
|
||||
$profile = $this->fetchSmtpProfileRow($customerId, $smtpProfileId);
|
||||
$smtpOverride = [
|
||||
'enabled' => true,
|
||||
'host' => $profile['smtp_host'] ?? '',
|
||||
'port' => $profile['smtp_port'] ?? 0,
|
||||
'user' => $profile['smtp_user'] ?? '',
|
||||
'pass' => $this->fetchSmtpProfilePassword($customerId, $smtpProfileId),
|
||||
'secure' => $profile['smtp_secure'] ?? '',
|
||||
'from_email' => $profile['from_email'] ?? '',
|
||||
'from_name' => $profile['from_name'] ?? '',
|
||||
'reply_to' => $profile['reply_to'] ?? '',
|
||||
];
|
||||
} elseif (array_key_exists('smtp_host', $this->in) || array_key_exists('smtp_enabled', $this->in)) {
|
||||
$smtpOverride = [
|
||||
'enabled' => !empty($this->in['smtp_enabled']),
|
||||
'host' => trim((string)($this->in['smtp_host'] ?? '')),
|
||||
@@ -3858,6 +3901,7 @@ class ApiKernel
|
||||
'time' => date(DATE_ATOM),
|
||||
'customer_id' => $customerId,
|
||||
'to' => $recipient,
|
||||
'smtp_profile_id' => $smtpProfileId > 0 ? $smtpProfileId : null,
|
||||
'smtp_enabled' => $smtpOverride['enabled'] ?? null,
|
||||
'smtp_host' => $smtpOverride['host'] ?? null,
|
||||
'smtp_port' => $smtpOverride['port'] ?? null,
|
||||
@@ -4291,6 +4335,158 @@ class ApiKernel
|
||||
$this->respond(['ok' => true, 'deleted' => true]);
|
||||
}
|
||||
|
||||
private function handleAccountSmtpProfilesList(): void
|
||||
{
|
||||
$user = $this->requireAuth();
|
||||
$customerId = (int)($user['customer_id'] ?? 0);
|
||||
if ($customerId <= 0) $this->fail('Customer context missing', null, 500);
|
||||
$this->ensureSmtpProfilesTableExists();
|
||||
$table = $this->smtpProfilesTable();
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM `$table` WHERE `customer_id` = :cid ORDER BY `label` ASC");
|
||||
$stmt->execute([':cid' => $customerId]);
|
||||
$items = [];
|
||||
while ($row = $stmt->fetch()) {
|
||||
$items[] = $this->formatSmtpProfileRow($row);
|
||||
}
|
||||
$this->respond(['ok' => true, 'items' => $items]);
|
||||
}
|
||||
|
||||
private function handleAccountSmtpProfileSave(): void
|
||||
{
|
||||
$user = $this->requireAuth();
|
||||
$this->ensureRole($user, ['owner', 'admin']);
|
||||
$customerId = (int)($user['customer_id'] ?? 0);
|
||||
if ($customerId <= 0) $this->fail('Customer context missing', null, 500);
|
||||
|
||||
$profileId = (int)($this->in['profile_id'] ?? 0);
|
||||
$label = trim((string)($this->in['label'] ?? ''));
|
||||
$host = trim((string)($this->in['smtp_host'] ?? ''));
|
||||
$port = (int)($this->in['smtp_port'] ?? 0);
|
||||
$userName = trim((string)($this->in['smtp_user'] ?? ''));
|
||||
$pass = (string)($this->in['smtp_pass'] ?? '');
|
||||
$secure = strtolower(trim((string)($this->in['smtp_secure'] ?? '')));
|
||||
$fromEmail = trim((string)($this->in['from_email'] ?? ''));
|
||||
$fromName = trim((string)($this->in['from_name'] ?? ''));
|
||||
$replyTo = trim((string)($this->in['reply_to'] ?? ''));
|
||||
$passClear = !empty($this->in['smtp_pass_clear']);
|
||||
|
||||
if ($label === '') $label = $fromEmail ?: $host;
|
||||
if ($host === '') $this->fail('SMTP-Host erforderlich', null, 422);
|
||||
if ($port < 0 || $port > 65535) $this->fail('Ungültiger SMTP-Port', null, 422);
|
||||
if ($secure !== '' && !in_array($secure, ['tls', 'ssl', 'none'], true)) {
|
||||
$this->fail('Ungültige SMTP-Sicherheit', null, 422);
|
||||
}
|
||||
if ($fromEmail !== '' && !filter_var($fromEmail, FILTER_VALIDATE_EMAIL)) {
|
||||
$this->fail('Ungültige Absenderadresse', null, 422);
|
||||
}
|
||||
if ($replyTo !== '' && !filter_var($replyTo, FILTER_VALIDATE_EMAIL)) {
|
||||
$this->fail('Ungültige Reply-To-Adresse', null, 422);
|
||||
}
|
||||
if ($secure === 'none') $secure = '';
|
||||
|
||||
$this->ensureSmtpProfilesTableExists();
|
||||
$table = $this->smtpProfilesTable();
|
||||
|
||||
if ($profileId > 0) {
|
||||
$fields = [
|
||||
'label' => $label,
|
||||
'smtp_host' => $host,
|
||||
'smtp_port' => $port > 0 ? $port : null,
|
||||
'smtp_user' => $userName ?: null,
|
||||
'smtp_secure' => $secure ?: null,
|
||||
'from_email' => $fromEmail ?: null,
|
||||
'from_name' => $fromName ?: null,
|
||||
'reply_to' => $replyTo ?: null,
|
||||
];
|
||||
if ($passClear) {
|
||||
$fields['smtp_pass'] = null;
|
||||
} elseif ($pass !== '') {
|
||||
$fields['smtp_pass'] = $pass;
|
||||
}
|
||||
$set = [];
|
||||
$params = [':id' => $profileId, ':cid' => $customerId];
|
||||
foreach ($fields as $k => $v) {
|
||||
$set[] = "`$k` = :$k";
|
||||
$params[":$k"] = $v;
|
||||
}
|
||||
$set[] = "`updated_at` = NOW()";
|
||||
$sql = "UPDATE `$table` SET " . implode(',', $set) . " WHERE `id` = :id AND `customer_id` = :cid LIMIT 1";
|
||||
$stmt = $this->pdo->prepare($sql);
|
||||
$stmt->execute($params);
|
||||
if ($stmt->rowCount() === 0) $this->fail('Versandprofil nicht gefunden', null, 404);
|
||||
} else {
|
||||
$stmt = $this->pdo->prepare("INSERT INTO `$table` (`customer_id`,`label`,`smtp_host`,`smtp_port`,`smtp_user`,`smtp_pass`,`smtp_secure`,`from_email`,`from_name`,`reply_to`,`created_at`,`updated_at`) VALUES (:cid,:label,:host,:port,:user,:pass,:secure,:fmail,:fname,:reply,NOW(),NOW())");
|
||||
$stmt->execute([
|
||||
':cid' => $customerId,
|
||||
':label' => $label,
|
||||
':host' => $host,
|
||||
':port' => $port > 0 ? $port : null,
|
||||
':user' => $userName ?: null,
|
||||
':pass' => $pass !== '' ? $pass : null,
|
||||
':secure' => $secure ?: null,
|
||||
':fmail' => $fromEmail ?: null,
|
||||
':fname' => $fromName ?: null,
|
||||
':reply' => $replyTo ?: null,
|
||||
]);
|
||||
$profileId = (int)$this->pdo->lastInsertId();
|
||||
}
|
||||
|
||||
$profile = $this->fetchSmtpProfileRow($customerId, $profileId);
|
||||
$this->respond(['ok' => true, 'profile' => $profile]);
|
||||
}
|
||||
|
||||
private function handleAccountSmtpProfileDelete(): void
|
||||
{
|
||||
$user = $this->requireAuth();
|
||||
$this->ensureRole($user, ['owner', 'admin']);
|
||||
$customerId = (int)($user['customer_id'] ?? 0);
|
||||
$profileId = (int)($this->in['profile_id'] ?? 0);
|
||||
if ($profileId <= 0) $this->fail('Ungültige Profil-ID', null, 422);
|
||||
$this->ensureSmtpProfilesTableExists();
|
||||
$table = $this->smtpProfilesTable();
|
||||
$stmt = $this->pdo->prepare("DELETE FROM `$table` WHERE `id` = :id AND `customer_id` = :cid LIMIT 1");
|
||||
$stmt->execute([':id' => $profileId, ':cid' => $customerId]);
|
||||
if ($stmt->rowCount() === 0) $this->fail('Versandprofil nicht gefunden', null, 404);
|
||||
$this->respond(['ok' => true, 'deleted' => true]);
|
||||
}
|
||||
|
||||
private function handleAccountSmtpProfileCopy(): void
|
||||
{
|
||||
$user = $this->requireAuth();
|
||||
$this->ensureRole($user, ['owner', 'admin']);
|
||||
$customerId = (int)($user['customer_id'] ?? 0);
|
||||
$profileId = (int)($this->in['profile_id'] ?? 0);
|
||||
if ($profileId <= 0) $this->fail('Ungültige Profil-ID', null, 422);
|
||||
$this->ensureSmtpProfilesTableExists();
|
||||
$table = $this->smtpProfilesTable();
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM `$table` WHERE `id` = :id AND `customer_id` = :cid LIMIT 1");
|
||||
$stmt->execute([':id' => $profileId, ':cid' => $customerId]);
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) $this->fail('Versandprofil nicht gefunden', null, 404);
|
||||
|
||||
$newLabel = trim((string)($this->in['label'] ?? ''));
|
||||
if ($newLabel === '') {
|
||||
$newLabel = ($row['label'] ?? 'Profil') . ' (Kopie)';
|
||||
}
|
||||
|
||||
$insert = $this->pdo->prepare("INSERT INTO `$table` (`customer_id`,`label`,`smtp_host`,`smtp_port`,`smtp_user`,`smtp_pass`,`smtp_secure`,`from_email`,`from_name`,`reply_to`,`created_at`,`updated_at`) VALUES (:cid,:label,:host,:port,:user,:pass,:secure,:fmail,:fname,:reply,NOW(),NOW())");
|
||||
$insert->execute([
|
||||
':cid' => $customerId,
|
||||
':label' => $newLabel,
|
||||
':host' => $row['smtp_host'],
|
||||
':port' => $row['smtp_port'],
|
||||
':user' => $row['smtp_user'],
|
||||
':pass' => $row['smtp_pass'],
|
||||
':secure' => $row['smtp_secure'],
|
||||
':fmail' => $row['from_email'],
|
||||
':fname' => $row['from_name'],
|
||||
':reply' => $row['reply_to'],
|
||||
]);
|
||||
$newId = (int)$this->pdo->lastInsertId();
|
||||
$profile = $this->fetchSmtpProfileRow($customerId, $newId);
|
||||
$this->respond(['ok' => true, 'profile' => $profile]);
|
||||
}
|
||||
|
||||
private function handleDashboardMetrics(): void
|
||||
{
|
||||
$user = $this->requireAuth();
|
||||
@@ -5297,6 +5493,46 @@ SQL;
|
||||
return 'emailtemplate_sender_identities';
|
||||
}
|
||||
|
||||
private function smtpProfilesTable(): string
|
||||
{
|
||||
return 'emailtemplate_smtp_profiles';
|
||||
}
|
||||
|
||||
private function ensureSmtpProfilesTableExists(): void
|
||||
{
|
||||
$table = $this->smtpProfilesTable();
|
||||
if ($this->tableExists($table)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$sql = <<<SQL
|
||||
CREATE TABLE IF NOT EXISTS `$table` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`customer_id` int(10) unsigned NOT NULL,
|
||||
`label` varchar(255) NOT NULL,
|
||||
`smtp_host` varchar(255) NOT NULL,
|
||||
`smtp_port` int(10) unsigned DEFAULT NULL,
|
||||
`smtp_user` varchar(255) DEFAULT NULL,
|
||||
`smtp_pass` varchar(255) DEFAULT NULL,
|
||||
`smtp_secure` varchar(16) DEFAULT NULL,
|
||||
`from_email` varchar(255) DEFAULT NULL,
|
||||
`from_name` varchar(255) DEFAULT NULL,
|
||||
`reply_to` varchar(255) DEFAULT NULL,
|
||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_smtp_customer` (`customer_id`),
|
||||
KEY `idx_smtp_host` (`smtp_host`),
|
||||
CONSTRAINT `fk_smtp_customer` FOREIGN KEY (`customer_id`) REFERENCES `emailtemplate_customers` (`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
||||
SQL;
|
||||
$this->pdo->exec($sql);
|
||||
$this->tableExistsCache[$table] = true;
|
||||
} catch (Throwable $e) {
|
||||
$this->fail('SMTP-Profil-Tabelle fehlt und konnte nicht erstellt werden', $e->getMessage(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
private function fetchSenderRow(int $customerId, int $senderId): array
|
||||
{
|
||||
if ($customerId <= 0 || $senderId <= 0) {
|
||||
@@ -5323,6 +5559,52 @@ SQL;
|
||||
];
|
||||
}
|
||||
|
||||
private function fetchSmtpProfileRow(int $customerId, int $profileId): array
|
||||
{
|
||||
if ($customerId <= 0 || $profileId <= 0) {
|
||||
$this->fail('Versandprofil nicht gefunden', null, 404);
|
||||
}
|
||||
$this->ensureSmtpProfilesTableExists();
|
||||
$table = $this->smtpProfilesTable();
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM `$table` WHERE `id` = :id AND `customer_id` = :cid LIMIT 1");
|
||||
$stmt->execute([':id' => $profileId, ':cid' => $customerId]);
|
||||
$row = $stmt->fetch();
|
||||
if (!$row) $this->fail('Versandprofil nicht gefunden', null, 404);
|
||||
return $this->formatSmtpProfileRow($row);
|
||||
}
|
||||
|
||||
private function fetchSmtpProfilePassword(int $customerId, int $profileId): string
|
||||
{
|
||||
if ($customerId <= 0 || $profileId <= 0) {
|
||||
return '';
|
||||
}
|
||||
$this->ensureSmtpProfilesTableExists();
|
||||
$table = $this->smtpProfilesTable();
|
||||
$stmt = $this->pdo->prepare("SELECT `smtp_pass` FROM `$table` WHERE `id` = :id AND `customer_id` = :cid LIMIT 1");
|
||||
$stmt->execute([':id' => $profileId, ':cid' => $customerId]);
|
||||
$row = $stmt->fetch();
|
||||
return (string)($row['smtp_pass'] ?? '');
|
||||
}
|
||||
|
||||
private function formatSmtpProfileRow(array $row): array
|
||||
{
|
||||
$pass = (string)($row['smtp_pass'] ?? '');
|
||||
return [
|
||||
'id' => (int)($row['id'] ?? 0),
|
||||
'label' => $row['label'] ?? '',
|
||||
'smtp_host' => $row['smtp_host'] ?? '',
|
||||
'smtp_port' => isset($row['smtp_port']) ? (int)$row['smtp_port'] : 0,
|
||||
'smtp_user' => $row['smtp_user'] ?? '',
|
||||
'smtp_secure' => $row['smtp_secure'] ?? '',
|
||||
'from_email' => $row['from_email'] ?? '',
|
||||
'from_name' => $row['from_name'] ?? '',
|
||||
'reply_to' => $row['reply_to'] ?? '',
|
||||
'smtp_pass_set' => $pass !== '',
|
||||
'created_at' => $row['created_at'] ?? null,
|
||||
'updated_at' => $row['updated_at'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
private function formatUserOutput(array $row): array
|
||||
{
|
||||
return [
|
||||
|
||||
Reference in New Issue
Block a user