diff --git a/schema.sql b/schema.sql index 0717399..1ce01c8 100644 --- a/schema.sql +++ b/schema.sql @@ -1,6 +1,11 @@ --- Schema-Dump für `d044ae9e` (erstellt am 2025-12-07 02:21:49 UTC) +-- Schema-Dump für `d044ae9e` (erstellt am 2025-12-08 00:14:08 UTC) -- Hinweis: Es werden nur CREATE-Anweisungen ausgegeben, bestehende Tabellen bleiben unangetastet. +CREATE DATABASE IF NOT EXISTS `d044ae9e` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; +USE `d044ae9e`; +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + -- Tabelle: customers CREATE TABLE IF NOT EXISTS `customers` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, @@ -101,7 +106,6 @@ CREATE TABLE IF NOT EXISTS `emailtemplate_customer_settings` ( `bridge_token` varchar(255) DEFAULT NULL, `sender_token` varchar(255) DEFAULT NULL, `external_api_token` varchar(255) DEFAULT NULL, - `bridge_tables` text DEFAULT NULL, `created_at` timestamp NOT NULL DEFAULT current_timestamp(), `updated_at` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(), PRIMARY KEY (`customer_id`) @@ -123,33 +127,6 @@ CREATE TABLE IF NOT EXISTS `emailtemplate_customer_tokens` ( CONSTRAINT `emailtemplate_customer_tokens_ibfk_1` FOREIGN KEY (`customer_id`) REFERENCES `emailtemplate_customers` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; --- Tabelle: emailtemplate_sender_identities -CREATE TABLE IF NOT EXISTS `emailtemplate_sender_identities` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `customer_id` int(10) unsigned NOT NULL, - `label` varchar(255) NOT NULL, - `from_name` varchar(255) DEFAULT NULL, - `from_email` varchar(255) NOT 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_sender_customer` (`customer_id`), - KEY `idx_sender_email` (`from_email`), - CONSTRAINT `fk_sender_customer` FOREIGN KEY (`customer_id`) REFERENCES `emailtemplate_customers` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; - --- Tabelle: emailtemplate_template_usage -CREATE TABLE IF NOT EXISTS `emailtemplate_template_usage` ( - `template_id` int(10) unsigned NOT NULL, - `customer_id` int(10) unsigned NOT NULL, - `render_count` int(10) unsigned NOT NULL DEFAULT 0, - `last_rendered_at` timestamp NULL DEFAULT NULL, - PRIMARY KEY (`template_id`), - KEY `idx_usage_customer` (`customer_id`), - CONSTRAINT `fk_usage_template` FOREIGN KEY (`template_id`) REFERENCES `emailtemplate_templates` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; - -- Tabelle: emailtemplate_customer_users CREATE TABLE IF NOT EXISTS `emailtemplate_customer_users` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, @@ -203,6 +180,22 @@ CREATE TABLE IF NOT EXISTS `emailtemplate_section_items` ( CONSTRAINT `fk_sitems_section` FOREIGN KEY (`section_id`) REFERENCES `emailtemplate_sections` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +-- Tabelle: emailtemplate_sender_identities +CREATE TABLE IF NOT EXISTS `emailtemplate_sender_identities` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `customer_id` int(10) unsigned NOT NULL, + `label` varchar(255) NOT NULL, + `from_name` varchar(255) DEFAULT NULL, + `from_email` varchar(255) NOT 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_sender_customer` (`customer_id`), + KEY `idx_sender_email` (`from_email`), + CONSTRAINT `fk_sender_customer` FOREIGN KEY (`customer_id`) REFERENCES `emailtemplate_customers` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + -- Tabelle: emailtemplate_snippets CREATE TABLE IF NOT EXISTS `emailtemplate_snippets` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, @@ -255,5 +248,16 @@ CREATE TABLE IF NOT EXISTS `emailtemplate_template_items` ( CONSTRAINT `fk_titems_template` FOREIGN KEY (`template_id`) REFERENCES `emailtemplate_templates` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; +-- Tabelle: emailtemplate_template_usage +CREATE TABLE IF NOT EXISTS `emailtemplate_template_usage` ( + `template_id` int(10) unsigned NOT NULL, + `customer_id` int(10) unsigned NOT NULL, + `render_count` int(10) unsigned NOT NULL DEFAULT 0, + `last_rendered_at` timestamp NULL DEFAULT NULL, + PRIMARY KEY (`template_id`), + KEY `idx_usage_customer` (`customer_id`), + CONSTRAINT `fk_usage_template` FOREIGN KEY (`template_id`) REFERENCES `emailtemplate_templates` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; + SET FOREIGN_KEY_CHECKS = 1; --- Ende des Schema-Dumps +-- Ende des Schema-Dumps \ No newline at end of file diff --git a/src/ApiKernel.php b/src/ApiKernel.php index 99bc3e0..c560279 100644 --- a/src/ApiKernel.php +++ b/src/ApiKernel.php @@ -206,8 +206,9 @@ class ApiKernel $row = $stmt->fetch(); return $row['Column_name'] ?? null; } - private function requireAuth(): array { /* ... Logik bleibt unverändert ... */ - return $this->authService->requireAuth(); + private function requireAuth(): array + { + return $this->ensureAuthUserHydrated($this->authService->requireAuth()); } private function pullId(array $src) { /* ... Logik bleibt unverändert ... */ $aliases = ['id', 'item_id', 'template_id', 'tpl_id', 'section_id', 'sec_id', 'block_id', 'blk_id', 'snippet_id', 'snip_id']; @@ -1230,7 +1231,9 @@ class ApiKernel private function handlePlaceholderSchema(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); + $user = $this->requireAuth(); + $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); $bridge = $this->resolveBridgeConfig($customerId); $url = trim((string)($bridge['url'] ?? '')); @@ -1262,7 +1265,7 @@ class ApiKernel private function handlePlaceholderStatus(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $customerId = (int)($user['customer_id'] ?? 0); $bridge = $this->resolveBridgeConfig($customerId); $url = trim((string)($bridge['url'] ?? '')); @@ -1325,7 +1328,7 @@ class ApiKernel private function handleAccountProfileGet(): void { - $user = $this->ensureAuthUserHydrated($this->authService->requireAuth()); + $user = $this->requireAuth(); $customerId = (int)($user['customer_id'] ?? 0); $settings = $customerId ? $this->ensureSettingsTokens($customerId, $this->getCustomerSettings($customerId)) : []; $this->respond([ @@ -1338,7 +1341,7 @@ class ApiKernel private function handleAccountProfileUpdate(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $cols = $this->authUserColumns(); $table = $cols['table']; $dbCols = $this->tableColumns($table); @@ -1385,7 +1388,7 @@ class ApiKernel private function handleAccountPasswordUpdate(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $current = (string)($this->in['current_password'] ?? ''); $new = (string)($this->in['new_password'] ?? ''); if ($current === '' || $new === '') { @@ -1423,7 +1426,7 @@ class ApiKernel private function handleAccountSettingsGet(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); $settings = $this->ensureSettingsTokens($customerId, $this->getCustomerSettings($customerId)); @@ -1432,7 +1435,7 @@ class ApiKernel private function handleAccountSettingsUpdate(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); if ($customerId <= 0) $this->fail('Customer context missing', null, 500); @@ -1469,7 +1472,7 @@ class ApiKernel private function handleAccountUsersList(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureOwner($user); $customerId = (int)($user['customer_id'] ?? 0); $cols = $this->authUserColumns(); @@ -1477,9 +1480,10 @@ class ApiKernel $dbCols = $this->tableColumns($table); $select = [ sprintf('`%s` AS user_id', $cols['col_id']), - sprintf('`%s` AS name', $cols['col_name']), - sprintf('`%s` AS email', $cols['col_email']), ]; + $nameSource = $this->columnExists($dbCols, $cols['col_name']) ? $cols['col_name'] : $cols['col_email']; + $select[] = sprintf('`%s` AS name', $nameSource); + $select[] = sprintf('`%s` AS email', $cols['col_email']); if ($this->columnExists($dbCols, $cols['col_role'])) { $select[] = sprintf('`%s` AS role', $cols['col_role']); } else { @@ -1498,7 +1502,7 @@ class ApiKernel implode(',', $select), $table, $cols['col_customer'], - $cols['col_name'] + $nameSource ); $stmt = $this->pdo->prepare($sql); $stmt->execute([':cid' => $customerId]); @@ -1511,7 +1515,7 @@ class ApiKernel private function handleAccountUsersCreate(): void { - $owner = $this->authService->requireAuth(); + $owner = $this->requireAuth(); $this->ensureOwner($owner); $customerId = (int)($owner['customer_id'] ?? 0); @@ -1532,7 +1536,9 @@ class ApiKernel $dbCols = $this->tableColumns($table); $data = []; - $data[$cols['col_name']] = $name; + if ($this->columnExists($dbCols, $cols['col_name'])) { + $data[$cols['col_name']] = $name; + } $data[$cols['col_email']] = $email; $data[$cols['col_pass']] = $hash; if ($this->columnExists($dbCols, $cols['col_role'])) $data[$cols['col_role']] = $role; @@ -1556,7 +1562,7 @@ class ApiKernel private function handleAccountUsersUpdate(): void { - $owner = $this->authService->requireAuth(); + $owner = $this->requireAuth(); $this->ensureOwner($owner); $customerId = (int)($owner['customer_id'] ?? 0); @@ -1632,7 +1638,7 @@ class ApiKernel private function handleAccountUsersDelete(): void { - $owner = $this->authService->requireAuth(); + $owner = $this->requireAuth(); $this->ensureOwner($owner); $customerId = (int)($owner['customer_id'] ?? 0); @@ -1665,7 +1671,7 @@ class ApiKernel private function handleAccountSendersList(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $customerId = (int)($user['customer_id'] ?? 0); if ($customerId <= 0) $this->fail('Customer context missing', null, 500); $table = $this->senderTable(); @@ -1684,7 +1690,7 @@ class ApiKernel private function handleAccountSenderSave(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); @@ -1731,7 +1737,7 @@ class ApiKernel private function handleAccountSenderDelete(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); $senderId = (int)($this->in['sender_id'] ?? 0); @@ -1745,7 +1751,7 @@ class ApiKernel private function handleDashboardMetrics(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); if ($customerId <= 0) $this->fail('Customer context missing', null, 500); @@ -1760,7 +1766,7 @@ class ApiKernel private function handleDashboardResetUsage(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); if ($customerId <= 0) $this->fail('Customer context missing', null, 500); @@ -1775,7 +1781,7 @@ class ApiKernel private function handleDownloadFile(string $type): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); if ($customerId <= 0) $this->fail('Customer context missing', null, 500); @@ -1813,7 +1819,7 @@ class ApiKernel private function handleAccountBridgeTest(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureRole($user, ['owner', 'admin']); $customerId = (int)($user['customer_id'] ?? 0); $bridgeUrl = trim((string)($this->in['bridge_url'] ?? '')); @@ -1846,7 +1852,7 @@ class ApiKernel private function handleDebugPhpInfo(): void { - $user = $this->authService->requireAuth(); + $user = $this->requireAuth(); $this->ensureDebugUser($user); ob_start(); phpinfo(INFO_GENERAL | INFO_CONFIGURATION | INFO_MODULES | INFO_ENVIRONMENT); @@ -2051,7 +2057,8 @@ SQL; { $role = (string)($user['role'] ?? ''); $hasOwnerFlag = isset($user['permissions']['owner']); - if ($role !== '' && $hasOwnerFlag) { + $hasCustomer = (int)($user['customer_id'] ?? 0) > 0; + if ($role !== '' && $hasOwnerFlag && $hasCustomer) { return $user; } $userId = (int)($user['id'] ?? 0); @@ -2074,16 +2081,29 @@ SQL; $where .= sprintf(' AND `%s` = :cid', $cols['col_customer']); $params[':cid'] = $customerId; } - $sql = sprintf('SELECT `%s` FROM `%s` WHERE %s LIMIT 1', $cols['col_role'], $table, $where); + $sql = sprintf('SELECT * FROM `%s` WHERE %s LIMIT 1', $table, $where); $stmt = $this->pdo->prepare($sql); $stmt->execute($params); $row = $stmt->fetch(); - if ($row && isset($row[$cols['col_role']])) { - $roleValue = $this->sanitizeRole((string)$row[$cols['col_role']]); - $user['role'] = $roleValue; - $user['permissions']['owner'] = ($roleValue === 'owner'); - $_SESSION['auth']['role'] = $roleValue; - $_SESSION['auth']['permissions']['owner'] = ($roleValue === 'owner'); + if ($row) { + if (isset($row[$cols['col_role']])) { + $roleValue = $this->sanitizeRole((string)$row[$cols['col_role']]); + $user['role'] = $roleValue; + $user['permissions']['owner'] = ($roleValue === 'owner'); + } elseif ($role === '') { + $user['role'] = 'user'; + $user['permissions']['owner'] = false; + } + if ((!$hasCustomer || $customerId <= 0) && isset($row[$cols['col_customer']])) { + $user['customer_id'] = (int)$row[$cols['col_customer']]; + } + if (empty($user['name']) && $this->columnExists($dbCols, $cols['col_name']) && isset($row[$cols['col_name']])) { + $user['name'] = (string)$row[$cols['col_name']]; + } + if (empty($user['email']) && isset($row[$cols['col_email']])) { + $user['email'] = (string)$row[$cols['col_email']]; + } + $_SESSION['auth'] = array_merge($_SESSION['auth'] ?? [], $user); } else { if ($role === '') $user['role'] = 'user'; if (!$hasOwnerFlag) {