From 308c684aa2d0abdccabd75d5ad5043be175e318d Mon Sep 17 00:00:00 2001 From: root Date: Sun, 18 Jan 2026 19:19:03 +0300 Subject: [PATCH] fix CRM contacts --- app/Libraries/Twig/TwigGlobalsExtension.php | 5 + .../CRM/Controllers/ContactsController.php | 101 +-- app/Views/layouts/base.twig | 3 +- dump.sql | 587 ------------------ public/assets/js/base.js | 2 +- public/assets/js/modules/contacts.js | 79 ++- 6 files changed, 122 insertions(+), 655 deletions(-) delete mode 100644 dump.sql diff --git a/app/Libraries/Twig/TwigGlobalsExtension.php b/app/Libraries/Twig/TwigGlobalsExtension.php index 5db223c..fdc77f2 100644 --- a/app/Libraries/Twig/TwigGlobalsExtension.php +++ b/app/Libraries/Twig/TwigGlobalsExtension.php @@ -51,9 +51,14 @@ class TwigGlobalsExtension extends AbstractExtension // Module subscription functions new TwigFunction('is_module_active', [$this, 'isModuleActive'], ['is_safe' => ['html']]), new TwigFunction('is_module_available', [$this, 'isModuleAvailable'], ['is_safe' => ['html']]), + new TwigFunction('csrf_meta', [$this, 'csrf_meta'], ['is_safe' => ['html']]), ]; } + public function csrf_meta() + { + return csrf_meta(); + } // ======================================== // Access Functions для Twig // ======================================== diff --git a/app/Modules/CRM/Controllers/ContactsController.php b/app/Modules/CRM/Controllers/ContactsController.php index 0c389a7..7142360 100644 --- a/app/Modules/CRM/Controllers/ContactsController.php +++ b/app/Modules/CRM/Controllers/ContactsController.php @@ -249,11 +249,14 @@ class ContactsController extends BaseController ]; }, $contacts); - return $this->response->setJSON([ - 'success' => true, - 'items' => $items, - 'total' => count($items), - ]); + return $this->response + ->setHeader('X-CSRF-TOKEN', csrf_hash()) + ->setHeader('X-CSRF-HASH', csrf_token()) + ->setJSON([ + 'success' => true, + 'items' => $items, + 'total' => count($items), + ]); } /** @@ -263,7 +266,12 @@ class ContactsController extends BaseController public function ajaxStore() { $organizationId = $this->requireActiveOrg(); - $customerId = $this->request->getPost('customer_id'); + + // Поддержка JSON и form-urlencoded данных + $jsonData = $this->request->getJSON(true); + $rawInput = $jsonData ?? $this->request->getPost(); + + $customerId = $rawInput['customer_id'] ?? null; // Проверяем клиента если указан if ($customerId) { @@ -279,10 +287,10 @@ class ContactsController extends BaseController $data = [ 'organization_id' => $organizationId, 'customer_id' => $customerId ?: null, - 'name' => $this->request->getPost('name'), - 'email' => $this->request->getPost('email') ?: null, - 'phone' => $this->request->getPost('phone') ?: null, - 'position' => $this->request->getPost('position') ?: null, + 'name' => $rawInput['name'] ?? '', + 'email' => $rawInput['email'] ?? null, + 'phone' => $rawInput['phone'] ?? null, + 'position' => $rawInput['position'] ?? null, ]; // Валидация @@ -304,17 +312,20 @@ class ContactsController extends BaseController ])->setStatusCode(422); } - return $this->response->setJSON([ - 'success' => true, - 'message' => 'Контакт создан', - 'item' => [ - 'id' => $contactId, - 'name' => $data['name'], - 'email' => $data['email'], - 'phone' => $data['phone'], - 'position' => $data['position'], - ], - ]); + return $this->response + ->setHeader('X-CSRF-TOKEN', csrf_hash()) + ->setHeader('X-CSRF-HASH', csrf_token()) + ->setJSON([ + 'success' => true, + 'message' => 'Контакт создан', + 'item' => [ + 'id' => $contactId, + 'name' => $data['name'], + 'email' => $data['email'], + 'phone' => $data['phone'], + 'position' => $data['position'], + ], + ]); } /** @@ -334,11 +345,15 @@ class ContactsController extends BaseController ])->setStatusCode(404); } + // Поддержка JSON и form-urlencoded данных + $jsonData = $this->request->getJSON(true); + $rawInput = $jsonData ?? $this->request->getPost(); + $data = [ - 'name' => $this->request->getPost('name'), - 'email' => $this->request->getPost('email') ?: null, - 'phone' => $this->request->getPost('phone') ?: null, - 'position' => $this->request->getPost('position') ?: null, + 'name' => $rawInput['name'] ?? '', + 'email' => $rawInput['email'] ?? null, + 'phone' => $rawInput['phone'] ?? null, + 'position' => $rawInput['position'] ?? null, ]; // Валидация @@ -360,17 +375,20 @@ class ContactsController extends BaseController ])->setStatusCode(422); } - return $this->response->setJSON([ - 'success' => true, - 'message' => 'Контакт обновлён', - 'item' => [ - 'id' => $id, - 'name' => $data['name'], - 'email' => $data['email'], - 'phone' => $data['phone'], - 'position' => $data['position'], - ], - ]); + return $this->response + ->setHeader('X-CSRF-TOKEN', csrf_hash()) + ->setHeader('X-CSRF-HASH', csrf_token()) + ->setJSON([ + 'success' => true, + 'message' => 'Контакт обновлён', + 'item' => [ + 'id' => $id, + 'name' => $data['name'], + 'email' => $data['email'], + 'phone' => $data['phone'], + 'position' => $data['position'], + ], + ]); } /** @@ -392,9 +410,12 @@ class ContactsController extends BaseController $this->contactModel->delete($id); - return $this->response->setJSON([ - 'success' => true, - 'message' => 'Контакт удалён', - ]); + return $this->response + ->setHeader('X-CSRF-TOKEN', csrf_hash()) + ->setHeader('X-CSRF-HASH', csrf_token()) + ->setJSON([ + 'success' => true, + 'message' => 'Контакт удалён', + ]); } } diff --git a/app/Views/layouts/base.twig b/app/Views/layouts/base.twig index 104f0ed..2932a02 100644 --- a/app/Views/layouts/base.twig +++ b/app/Views/layouts/base.twig @@ -7,6 +7,7 @@ + {{ csrf_meta() }} {% block title %}Бизнес.Точка{% endblock %} @@ -17,7 +18,7 @@ {% block styles %}{% endblock %} - +
diff --git a/dump.sql b/dump.sql deleted file mode 100644 index 78db8c2..0000000 --- a/dump.sql +++ /dev/null @@ -1,587 +0,0 @@ -/*M!999999\- enable the sandbox mode */ --- MariaDB dump 10.19-11.8.3-MariaDB, for debian-linux-gnu (x86_64) --- --- Host: localhost Database: bp_mirv_db --- ------------------------------------------------------ --- Server version 11.8.3-MariaDB-0+deb13u1 from Debian - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; -/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; -/*!40101 SET NAMES utf8mb4 */; -/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; -/*!40103 SET TIME_ZONE='+00:00' */; -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; - --- --- Table structure for table `ci_sessions` --- - -DROP TABLE IF EXISTS `ci_sessions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `ci_sessions` ( - `id` varchar(128) NOT NULL, - `ip_address` varchar(45) NOT NULL, - `timestamp` int(10) unsigned NOT NULL DEFAULT 0, - `data` blob DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `timestamp` (`timestamp`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `ci_sessions` --- - -LOCK TABLES `ci_sessions` WRITE; -/*!40000 ALTER TABLE `ci_sessions` DISABLE KEYS */; -set autocommit=0; -/*!40000 ALTER TABLE `ci_sessions` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `contacts` --- - -DROP TABLE IF EXISTS `contacts`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `contacts` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `organization_id` int(11) unsigned NOT NULL, - `customer_id` int(11) unsigned NOT NULL COMMENT 'Ссылка на клиента (компанию)', - `name` varchar(255) NOT NULL COMMENT 'Имя контакта', - `email` varchar(255) DEFAULT NULL, - `phone` varchar(50) DEFAULT NULL, - `position` varchar(255) DEFAULT NULL COMMENT 'Должность', - `is_primary` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT 'Основной контакт', - `notes` text DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `deleted_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `organization_id` (`organization_id`), - KEY `customer_id` (`customer_id`), - CONSTRAINT `contacts_customer_id_foreign` FOREIGN KEY (`customer_id`) REFERENCES `organizations_clients` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `contacts_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `contacts` --- - -LOCK TABLES `contacts` WRITE; -/*!40000 ALTER TABLE `contacts` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `contacts` VALUES -(1,12,1,'Петров',NULL,'+79999999955','Вахтер',0,NULL,'2026-01-15 02:50:50','2026-01-15 02:50:50',NULL); -/*!40000 ALTER TABLE `contacts` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `deal_history` --- - -DROP TABLE IF EXISTS `deal_history`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `deal_history` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `deal_id` bigint(20) unsigned NOT NULL, - `user_id` int(11) unsigned NOT NULL, - `action` varchar(50) NOT NULL, - `field_name` varchar(50) DEFAULT NULL, - `old_value` text DEFAULT NULL, - `new_value` text DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `deal_id` (`deal_id`), - KEY `user_id` (`user_id`), - CONSTRAINT `deal_history_deal_id_foreign` FOREIGN KEY (`deal_id`) REFERENCES `deals` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `deal_history_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `deal_history` --- - -LOCK TABLES `deal_history` WRITE; -/*!40000 ALTER TABLE `deal_history` DISABLE KEYS */; -set autocommit=0; -/*!40000 ALTER TABLE `deal_history` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `deal_stages` --- - -DROP TABLE IF EXISTS `deal_stages`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `deal_stages` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `organization_id` int(11) unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `color` varchar(7) NOT NULL DEFAULT '#6B7280', - `order_index` int(11) NOT NULL DEFAULT 0, - `type` enum('progress','won','lost') NOT NULL DEFAULT 'progress', - `probability` int(3) unsigned NOT NULL DEFAULT 0, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `deleted_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `organization_id` (`organization_id`), - CONSTRAINT `deal_stages_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `deal_stages` --- - -LOCK TABLES `deal_stages` WRITE; -/*!40000 ALTER TABLE `deal_stages` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `deal_stages` VALUES -(1,12,'Первый контакт','#6b7280',1,'progress',1,NULL,NULL,NULL), -(2,12,'Второй контакт','#9a9996',2,'progress',5,NULL,NULL,NULL), -(3,12,'Переговоры по договору','#c061cb',3,'progress',10,NULL,NULL,NULL); -/*!40000 ALTER TABLE `deal_stages` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `deals` --- - -DROP TABLE IF EXISTS `deals`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `deals` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `organization_id` int(11) unsigned NOT NULL, - `contact_id` int(11) unsigned DEFAULT NULL, - `company_id` int(11) unsigned DEFAULT NULL, - `title` varchar(255) NOT NULL, - `description` text DEFAULT NULL, - `amount` decimal(15,2) NOT NULL DEFAULT 0.00, - `currency` char(3) NOT NULL DEFAULT 'RUB', - `stage_id` int(11) unsigned NOT NULL, - `assigned_user_id` int(11) unsigned DEFAULT NULL, - `expected_close_date` date DEFAULT NULL, - `created_by` int(11) unsigned NOT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `deleted_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `organization_id` (`organization_id`), - KEY `stage_id` (`stage_id`), - KEY `assigned_user_id` (`assigned_user_id`), - CONSTRAINT `deals_assigned_user_id_foreign` FOREIGN KEY (`assigned_user_id`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE SET NULL, - CONSTRAINT `deals_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `deals_stage_id_foreign` FOREIGN KEY (`stage_id`) REFERENCES `deal_stages` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `deals` --- - -LOCK TABLES `deals` WRITE; -/*!40000 ALTER TABLE `deals` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `deals` VALUES -(1,12,1,1,'Раскрутка сайта','',1000.00,'RUB',3,NULL,NULL,11,'2026-01-15 03:07:32','2026-01-15 03:07:32',NULL), -(2,12,NULL,1,'Пупупу','',15000.00,'RUB',1,11,'2026-02-28',11,'2026-01-15 03:45:08','2026-01-15 07:43:07',NULL); -/*!40000 ALTER TABLE `deals` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `migrations` --- - -DROP TABLE IF EXISTS `migrations`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `migrations` ( - `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, - `version` varchar(255) NOT NULL, - `class` varchar(255) NOT NULL, - `group` varchar(255) NOT NULL, - `namespace` varchar(255) NOT NULL, - `time` int(11) NOT NULL, - `batch` int(11) unsigned NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `migrations` --- - -LOCK TABLES `migrations` WRITE; -/*!40000 ALTER TABLE `migrations` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `migrations` VALUES -(1,'2026-01-07-053357','App\\Database\\Migrations\\CreateUsersTable','default','App',1767769689,1), -(2,'2026-01-07-053401','App\\Database\\Migrations\\CreateOrganizationsTable','default','App',1767769689,1), -(3,'2026-01-07-053407','App\\Database\\Migrations\\CreateOrganizationUsersTable','default','App',1767769689,1), -(4,'2026-01-07-053412','App\\Database\\Migrations\\CreateOrganizationSubscriptionsTable','default','App',1767769689,1), -(5,'2026-01-07-053413','App\\Database\\Migrations\\CreateOrganizationSubscriptionsTable','default','App',1767769974,2), -(6,'2026-01-08-000001','App\\Database\\Migrations\\AddEmailVerificationToUsers','default','App',1767870811,3), -(7,'2026-01-08-200001','App\\Database\\Migrations\\CreateOrganizationsClientsTable','default','App',1767878430,4), -(8,'2026-01-12-000001','App\\Database\\Migrations\\AddInviteFieldsToOrganizationUsers','default','App',1768267451,5), -(9,'2026-01-13-000001','App\\Database\\Migrations\\CreateRememberTokensTable','default','App',1768267451,5), -(10,'2026-01-13-163701','App\\Database\\Migrations\\AddTrialEndsAtToSubscriptions','default','App',1768295204,6), -(11,'2026-01-13-200001','App\\Database\\Migrations\\CreateCiSessionsTable','default','App',1768313545,7), -(12,'2026-01-13-200002','App\\Database\\Migrations\\AddPasswordResetFieldsToUsers','default','App',1768313545,7), -(13,'2026-01-14-000001','App\\Database\\Migrations\\AddSystemRoleToUsers','default','App',1768317531,8), -(14,'2026-01-15-000001','App\\Database\\Migrations\\AddPlansTable','default','App',1768317531,8), -(15,'2026-01-15-000002','App\\Database\\Migrations\\CreateOrganizationPlanSubscriptionsTable','default','App',1768320790,9), -(16,'2026-01-15-000003','App\\Database\\Migrations\\AddTokenExpiresToUsers','default','App',1768372597,10), -(17,'2026-01-15-000004','App\\Database\\Migrations\\AddInviteExpiresToOrganizationUsers','default','App',1768372597,10), -(18,'2026-01-15-000005','App\\Database\\Migrations\\AddStatusToOrganizations','default','App',1768376017,11), -(19,'2026-01-15-000006','App\\Database\\Migrations\\CreateDealsTables','default','App',1768439721,12), -(21,'2026-01-15-000007','App\\Database\\Migrations\\CreateContactsTable','default','App',1768440786,13), -(22,'2026-01-16-210001','App\\Database\\Migrations\\DropOrganizationPlanSubscriptionsTable','default','App',1768572350,14), -(23,'2026-01-16-220001','App\\Database\\Migrations\\CreateModuleSettingsTable','default','App',1768573190,15); -/*!40000 ALTER TABLE `migrations` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `module_settings` --- - -DROP TABLE IF EXISTS `module_settings`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `module_settings` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `module_code` varchar(50) NOT NULL, - `name` varchar(100) NOT NULL, - `description` varchar(255) NOT NULL, - `price_monthly` int(11) NOT NULL DEFAULT 0, - `price_yearly` int(11) NOT NULL DEFAULT 0, - `trial_days` int(11) NOT NULL DEFAULT 0, - `is_active` tinyint(1) NOT NULL DEFAULT 1, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `module_code` (`module_code`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `module_settings` --- - -LOCK TABLES `module_settings` WRITE; -/*!40000 ALTER TABLE `module_settings` DISABLE KEYS */; -set autocommit=0; -/*!40000 ALTER TABLE `module_settings` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `organization_subscriptions` --- - -DROP TABLE IF EXISTS `organization_subscriptions`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `organization_subscriptions` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `organization_id` int(11) unsigned NOT NULL, - `module_code` varchar(50) NOT NULL, - `status` enum('trial','active','expired','cancelled') NOT NULL DEFAULT 'trial', - `trial_ends_at` datetime DEFAULT NULL COMMENT 'Дата окончания триального периода', - `expires_at` datetime DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `organization_id_module_code` (`organization_id`,`module_code`), - CONSTRAINT `organization_subscriptions_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `organization_subscriptions` --- - -LOCK TABLES `organization_subscriptions` WRITE; -/*!40000 ALTER TABLE `organization_subscriptions` DISABLE KEYS */; -set autocommit=0; -/*!40000 ALTER TABLE `organization_subscriptions` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `organization_users` --- - -DROP TABLE IF EXISTS `organization_users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `organization_users` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `organization_id` int(11) unsigned NOT NULL, - `user_id` int(11) unsigned NOT NULL, - `role` enum('owner','admin','manager','guest') NOT NULL DEFAULT 'manager', - `invite_token` varchar(64) DEFAULT NULL, - `invited_by` int(10) unsigned DEFAULT NULL, - `invited_at` datetime DEFAULT NULL, - `invite_expires_at` datetime DEFAULT NULL, - `status` enum('active','pending','invited','blocked') NOT NULL DEFAULT 'pending', - `joined_at` datetime DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `organization_id_user_id` (`organization_id`,`user_id`), - KEY `organization_users_user_id_foreign` (`user_id`), - KEY `idx_org_users_token` (`invite_token`), - CONSTRAINT `organization_users_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE, - CONSTRAINT `organization_users_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `organization_users` --- - -LOCK TABLES `organization_users` WRITE; -/*!40000 ALTER TABLE `organization_users` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `organization_users` VALUES -(12,12,11,'owner',NULL,NULL,NULL,NULL,'active','2026-01-08 12:48:27',NULL), -(13,13,11,'owner',NULL,NULL,NULL,NULL,'active','2026-01-08 15:29:08',NULL); -/*!40000 ALTER TABLE `organization_users` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `organizations` --- - -DROP TABLE IF EXISTS `organizations`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `organizations` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `owner_id` int(11) unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `type` enum('business','personal') NOT NULL DEFAULT 'business', - `logo` varchar(255) DEFAULT NULL, - `requisites` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`requisites`)), - `trial_ends_at` datetime DEFAULT NULL, - `settings` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`settings`)), - `status` enum('active','blocked') NOT NULL DEFAULT 'active', - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `deleted_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `organizations_owner_id_foreign` (`owner_id`), - CONSTRAINT `organizations_owner_id_foreign` FOREIGN KEY (`owner_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `organizations` --- - -LOCK TABLES `organizations` WRITE; -/*!40000 ALTER TABLE `organizations` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `organizations` VALUES -(12,11,'Личное пространство','personal',NULL,NULL,NULL,NULL,'active','2026-01-08 12:48:27','2026-01-08 12:48:27',NULL), -(13,11,'Редька','business',NULL,'{\"inn\":\"1112223334\",\"ogrn\":\"1231231231230\",\"kpp\":\"\",\"legal_address\":\"\\u041f\\u0438\\u0442\\u0435\\u0440, \\u041c\\u043e\\u0439\\u043a\\u0430 13\",\"actual_address\":\"\",\"phone\":\"\",\"email\":\"\",\"website\":\"\",\"bank_name\":\"\",\"bank_bik\":\"\",\"checking_account\":\"\",\"correspondent_account\":\"\"}',NULL,'[]','active','2026-01-08 15:29:08','2026-01-14 07:34:02',NULL); -/*!40000 ALTER TABLE `organizations` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `organizations_clients` --- - -DROP TABLE IF EXISTS `organizations_clients`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `organizations_clients` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `organization_id` int(11) unsigned NOT NULL, - `name` varchar(255) NOT NULL, - `email` varchar(255) DEFAULT NULL, - `phone` varchar(50) DEFAULT NULL, - `notes` text DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `deleted_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `organization_id` (`organization_id`), - CONSTRAINT `organizations_clients_organization_id_foreign` FOREIGN KEY (`organization_id`) REFERENCES `organizations` (`id`) ON DELETE CASCADE ON UPDATE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `organizations_clients` --- - -LOCK TABLES `organizations_clients` WRITE; -/*!40000 ALTER TABLE `organizations_clients` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `organizations_clients` VALUES -(1,12,'РогаКопыта','','','Текст','2026-01-08 13:40:47','2026-01-11 15:52:48',NULL), -(2,12,'Третий','ttt@ttt.com','','','2026-01-08 14:15:49','2026-01-08 14:15:49',NULL), -(3,12,'ыва','ddd@ddd.com','','','2026-01-08 21:34:38','2026-01-08 21:34:38',NULL), -(4,12,'ппп','','','','2026-01-12 01:22:38','2026-01-12 01:22:38',NULL), -(5,12,'ккк','','','','2026-01-12 01:22:43','2026-01-12 01:22:43',NULL), -(6,12,'еее','','','','2026-01-12 01:22:49','2026-01-12 01:22:49',NULL), -(7,12,'ннн','','','','2026-01-12 01:22:53','2026-01-12 01:22:53',NULL), -(8,12,'ггг','test3@test.com','','Вот такие вот заметки ','2026-01-12 01:22:56','2026-01-15 03:51:00',NULL), -(9,12,'шшш','','','','2026-01-12 01:22:59','2026-01-12 01:22:59',NULL), -(10,12,'щщщ','','','','2026-01-12 01:23:04','2026-01-12 01:23:04',NULL), -(11,12,'ффф','','','','2026-01-12 01:23:08','2026-01-12 01:23:08',NULL), -(12,13,'Супер','','','','2026-01-12 02:56:33','2026-01-12 02:56:33',NULL), -(13,13,'Супер222','','','','2026-01-12 09:04:04','2026-01-12 09:04:16',NULL); -/*!40000 ALTER TABLE `organizations_clients` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `plans` --- - -DROP TABLE IF EXISTS `plans`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `plans` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `name` varchar(100) NOT NULL, - `description` text DEFAULT NULL, - `price` decimal(10,2) NOT NULL DEFAULT 0.00, - `currency` varchar(3) NOT NULL DEFAULT 'RUB', - `billing_period` enum('monthly','yearly','quarterly') NOT NULL DEFAULT 'monthly', - `max_users` int(11) NOT NULL DEFAULT 5, - `max_clients` int(11) NOT NULL DEFAULT 100, - `max_storage` int(11) NOT NULL DEFAULT 10, - `features` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`features`)), - `is_active` tinyint(4) NOT NULL DEFAULT 1, - `is_default` tinyint(4) NOT NULL DEFAULT 0, - `created_at` datetime NOT NULL, - `updated_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `name` (`name`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `plans` --- - -LOCK TABLES `plans` WRITE; -/*!40000 ALTER TABLE `plans` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `plans` VALUES -(1,'Бесплатный','Базовый тариф для небольших команд',0.00,'RUB','monthly',3,50,5,'[\"\\u0411\\u0430\\u0437\\u043e\\u0432\\u044b\\u0435 \\u043c\\u043e\\u0434\\u0443\\u043b\\u0438\",\"Email \\u043f\\u043e\\u0434\\u0434\\u0435\\u0440\\u0436\\u043a\\u0430\",\"\\u042d\\u043a\\u0441\\u043f\\u043e\\u0440\\u0442 \\u0432 CSV\"]',1,1,'2026-01-13 15:18:51',NULL), -(2,'Старт','Тариф для растущих компаний',990.00,'RUB','monthly',10,500,50,'[\"\\u0412\\u0441\\u0435 \\u043c\\u043e\\u0434\\u0443\\u043b\\u0438\",\"\\u041f\\u0440\\u0438\\u043e\\u0440\\u0438\\u0442\\u0435\\u0442\\u043d\\u0430\\u044f \\u043f\\u043e\\u0434\\u0434\\u0435\\u0440\\u0436\\u043a\\u0430\",\"\\u042d\\u043a\\u0441\\u043f\\u043e\\u0440\\u0442 \\u0432 PDF \\u0438 Excel\",\"API \\u0434\\u043e\\u0441\\u0442\\u0443\\u043f\"]',1,0,'2026-01-13 15:18:51',NULL), -(3,'Бизнес','Полный функционал для крупных компаний',4990.00,'RUB','monthly',50,5000,500,'[\"\\u0412\\u0441\\u0435 \\u043c\\u043e\\u0434\\u0443\\u043b\\u0438\",\"\\u041f\\u0435\\u0440\\u0441\\u043e\\u043d\\u0430\\u043b\\u044c\\u043d\\u044b\\u0439 \\u043c\\u0435\\u043d\\u0435\\u0434\\u0436\\u0435\\u0440\",\"\\u042d\\u043a\\u0441\\u043f\\u043e\\u0440\\u0442 \\u0432 PDF \\u0438 Excel\",\"\\u041f\\u043e\\u043b\\u043d\\u044b\\u0439 API \\u0434\\u043e\\u0441\\u0442\\u0443\\u043f\",\"\\u0418\\u043d\\u0442\\u0435\\u0433\\u0440\\u0430\\u0446\\u0438\\u0438\",\"\\u0411\\u0440\\u0435\\u043d\\u0434\\u0438\\u043d\\u0433\"]',1,0,'2026-01-13 15:18:51',NULL); -/*!40000 ALTER TABLE `plans` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `remember_tokens` --- - -DROP TABLE IF EXISTS `remember_tokens`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `remember_tokens` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `user_id` int(11) unsigned NOT NULL, - `selector` varchar(64) NOT NULL, - `token_hash` varchar(128) NOT NULL, - `expires_at` datetime NOT NULL, - `created_at` datetime DEFAULT NULL, - `user_agent` varchar(500) DEFAULT NULL, - `ip_address` varchar(45) DEFAULT NULL, - PRIMARY KEY (`id`), - KEY `user_id` (`user_id`), - KEY `selector` (`selector`), - KEY `expires_at` (`expires_at`), - CONSTRAINT `remember_tokens_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE -) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `remember_tokens` --- - -LOCK TABLES `remember_tokens` WRITE; -/*!40000 ALTER TABLE `remember_tokens` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `remember_tokens` VALUES -(4,11,'508781e7a1d7bfb7b15c4ed38a71e205','dc94c9825eed3efd9d960fdefb9e9048203a2b837d8168e1c78ce1cc3e38f90d','2026-02-13 07:17:58','2026-01-14 07:17:58','Mozilla/5.0 (X11; Linux x86_64; rv:146.0) Gecko/20100101 Firefox/146.0','91.234.172.241'); -/*!40000 ALTER TABLE `remember_tokens` ENABLE KEYS */; -UNLOCK TABLES; -commit; - --- --- Table structure for table `users` --- - -DROP TABLE IF EXISTS `users`; -/*!40101 SET @saved_cs_client = @@character_set_client */; -/*!40101 SET character_set_client = utf8mb4 */; -CREATE TABLE `users` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT, - `email` varchar(255) NOT NULL, - `password` varchar(255) NOT NULL, - `system_role` enum('user','admin','superadmin') DEFAULT 'user', - `name` varchar(100) NOT NULL, - `phone` varchar(20) DEFAULT NULL, - `avatar` varchar(255) DEFAULT NULL, - `created_at` datetime DEFAULT NULL, - `updated_at` datetime DEFAULT NULL, - `verification_token` varchar(255) DEFAULT NULL COMMENT 'Токен для подтверждения email', - `token_expires_at` datetime DEFAULT NULL, - `email_verified` tinyint(1) DEFAULT 0 COMMENT 'Статус подтверждения email (0 - не подтвержден, 1 - подтвержден)', - `verified_at` datetime DEFAULT NULL COMMENT 'Дата и время подтверждения email', - `reset_token` varchar(255) DEFAULT NULL, - `reset_expires_at` datetime DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `email` (`email`) -) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -/*!40101 SET character_set_client = @saved_cs_client */; - --- --- Dumping data for table `users` --- - -LOCK TABLES `users` WRITE; -/*!40000 ALTER TABLE `users` DISABLE KEYS */; -set autocommit=0; -INSERT INTO `users` VALUES -(11,'mirvtop@yandex.ru','$2y$12$lPkp/tIPEgltYiyIw5ZWuukNPrMdGzfzerRG1oSXbKuBSpVbBmhhu','superadmin','Mirivlad',NULL,'avatar_11_1768273671.jpg','2026-01-08 12:48:27','2026-01-13 15:29:21',NULL,NULL,1,'2026-01-08 12:48:38',NULL,NULL); -/*!40000 ALTER TABLE `users` ENABLE KEYS */; -UNLOCK TABLES; -commit; -/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; -/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; -/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; -/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; - --- Dump completed on 2026-01-16 17:43:45 diff --git a/public/assets/js/base.js b/public/assets/js/base.js index 7fbcbb4..2b881de 100644 --- a/public/assets/js/base.js +++ b/public/assets/js/base.js @@ -5,7 +5,7 @@ document.addEventListener("DOMContentLoaded", function () { const body = document.body; // Базовая функция для получения base URL (объявляем ДО использования) - const baseUrl = '{{ base_url("/") }}'.replace(/\/+$/, ''); + const baseUrl = '/'.replace(/\/+$/, ''); if (sidebarToggle) { // Обработчик клика diff --git a/public/assets/js/modules/contacts.js b/public/assets/js/modules/contacts.js index 39ad58c..257be27 100644 --- a/public/assets/js/modules/contacts.js +++ b/public/assets/js/modules/contacts.js @@ -24,6 +24,16 @@ class ContactsManager { this.loadContacts(); } + /** + * Получить заголовки запроса + */ + getHeaders() { + return { + 'Content-Type': 'application/json', + 'X-Requested-With': 'XMLHttpRequest' + }; + } + /** * Загрузить список контактов */ @@ -31,9 +41,8 @@ class ContactsManager { try { const response = await fetch(`${this.apiUrl}/list/${this.clientId}`, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, + credentials: 'same-origin', + headers: this.getHeaders(), body: JSON.stringify({}) }); @@ -106,6 +115,7 @@ class ContactsManager { * Отобразить одну строку контакта */ renderRow(contact) { + const escapedId = this.escapeJs(contact.id); return ` @@ -129,29 +139,27 @@ class ContactsManager { value="${this.escapeHtml(contact.position || '')}" style="display: none;" placeholder="Должность"> -
+
-