feat: добавлена возможность ручного ввода времени и трафика
- Добавлены custom input поля для expiration (секунды) и traffic (МБ) - Добавлена функциональность редактирования клиента - Исправлена migration 007 (AFTER expires_at) - Удалены дублирующиеся миграции (0025, 0044, 0053, 0057) - Удалён старый init.sql (заменён на 001_init.sql) - Добавлены переводы для custom полей на 6 языках
This commit is contained in:
@@ -208,6 +208,10 @@ INSERT INTO translations (language_code, translation_key, translation_value) VAL
|
||||
('en', 'clients.traffic_limit', 'Traffic Limit'),
|
||||
('en', 'clients.unlimited', 'Unlimited'),
|
||||
('en', 'clients.overlimit', 'Over Limit'),
|
||||
('en', 'clients.custom_seconds', 'Custom (seconds)'),
|
||||
('en', 'clients.custom_mb', 'Custom (MB)'),
|
||||
('en', 'clients.enter_seconds', 'Enter seconds'),
|
||||
('en', 'clients.enter_megabytes', 'Enter megabytes'),
|
||||
('en', 'backups.title', 'Server Backups'),
|
||||
('en', 'backups.create', 'Create Backup'),
|
||||
('en', 'backups.restore', 'Restore'),
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
-- Spanish translations
|
||||
-- This migration adds Spanish language translations
|
||||
|
||||
INSERT INTO translations (language_code, translation_key, translation_value) VALUES
|
||||
('es', 'auth.email', 'Correo electrónico'),
|
||||
('es', 'auth.login', 'Iniciar sesión'),
|
||||
('es', 'auth.name', 'Nombre'),
|
||||
('es', 'auth.password', 'Contraseña'),
|
||||
('es', 'auth.register', 'Registrarse'),
|
||||
('es', 'backups.create', 'Crear copia de seguridad'),
|
||||
('es', 'backups.create_confirm', '¿Crear copia de seguridad de todos los clientes en este servidor?'),
|
||||
('es', 'backups.created_success', 'Copia de seguridad creada exitosamente'),
|
||||
('es', 'backups.delete_confirm', '¿Eliminar esta copia de seguridad permanentemente?'),
|
||||
('es', 'backups.deleted_success', 'Copia de seguridad eliminada exitosamente'),
|
||||
('es', 'backups.login_required', 'Por favor inicie sesión vía API para gestionar copias de seguridad'),
|
||||
('es', 'backups.no_backups', 'Aún no hay copias de seguridad'),
|
||||
('es', 'backups.restore', 'Restaurar'),
|
||||
('es', 'backups.restore_confirm', '¿Restaurar clientes desde esta copia de seguridad? Los clientes existentes no se verán afectados.'),
|
||||
('es', 'backups.restored_success', 'Restaurado'),
|
||||
('es', 'backups.title', 'Copias de seguridad del servidor'),
|
||||
('es', 'clients.actions', 'Acciones'),
|
||||
('es', 'clients.add', 'Agregar cliente'),
|
||||
('es', 'clients.create', 'Crear cliente'),
|
||||
('es', 'clients.delete', 'Eliminar'),
|
||||
('es', 'clients.download_config', 'Descargar configuración'),
|
||||
('es', 'clients.expiration', 'Vencimiento'),
|
||||
('es', 'clients.expired', 'Vencido'),
|
||||
('es', 'clients.ip', 'Dirección IP'),
|
||||
('es', 'clients.last_handshake', 'Último contacto'),
|
||||
('es', 'clients.name', 'Nombre del cliente'),
|
||||
('es', 'clients.never_expires', 'Nunca vence'),
|
||||
('es', 'clients.qr_code', 'Código QR'),
|
||||
('es', 'clients.received', 'Recibido'),
|
||||
('es', 'clients.restore', 'Restaurar'),
|
||||
('es', 'clients.revoke', 'Revocar'),
|
||||
('es', 'clients.sent', 'Enviado'),
|
||||
('es', 'clients.server', 'Servidor'),
|
||||
('es', 'clients.status', 'Estado'),
|
||||
('es', 'clients.sync_stats', 'Sincronizar estadísticas'),
|
||||
('es', 'clients.title', 'Clientes'),
|
||||
('es', 'clients.traffic', 'Tráfico'),
|
||||
('es', 'common.days', 'días'),
|
||||
('es', 'dashboard.active_clients', 'Clientes activos'),
|
||||
('es', 'dashboard.add_first_server', 'Agregar primer servidor'),
|
||||
('es', 'dashboard.get_started', 'Comience agregando su primer servidor VPN'),
|
||||
('es', 'dashboard.no_servers', 'Aún no hay servidores'),
|
||||
('es', 'dashboard.quick_actions', 'Acciones rápidas'),
|
||||
('es', 'dashboard.recent_servers', 'Servidores recientes'),
|
||||
('es', 'dashboard.title', 'Panel de control'),
|
||||
('es', 'dashboard.total_clients', 'Total de clientes'),
|
||||
('es', 'dashboard.total_servers', 'Total de servidores'),
|
||||
('es', 'dashboard.total_traffic', 'Tráfico total'),
|
||||
('es', 'dashboard.welcome', 'Bienvenido al Panel de Gestión de Amnezia VPN'),
|
||||
('es', 'form.cancel', 'Cancelar'),
|
||||
('es', 'form.close', 'Cerrar'),
|
||||
('es', 'form.create', 'Crear'),
|
||||
('es', 'form.loading', 'Cargando...'),
|
||||
('es', 'form.processing', 'Procesando...'),
|
||||
('es', 'form.save', 'Guardar'),
|
||||
('es', 'form.submit', 'Enviar'),
|
||||
('es', 'form.update', 'Actualizar'),
|
||||
('es', 'menu.clients', 'Clientes'),
|
||||
('es', 'menu.dashboard', 'Panel de control'),
|
||||
('es', 'menu.logout', 'Cerrar sesión'),
|
||||
('es', 'menu.servers', 'Servidores'),
|
||||
('es', 'menu.settings', 'Configuración'),
|
||||
('es', 'menu.users', 'Usuarios'),
|
||||
('es', 'message.confirm', '¿Está seguro?'),
|
||||
('es', 'message.deleted', 'Eliminado exitosamente'),
|
||||
('es', 'message.deployed', 'Implementado exitosamente'),
|
||||
('es', 'message.error', 'Ha ocurrido un error'),
|
||||
('es', 'message.saved', 'Guardado exitosamente'),
|
||||
('es', 'message.success', 'Operación completada exitosamente'),
|
||||
('es', 'servers.actions', 'Acciones'),
|
||||
('es', 'servers.add', 'Agregar servidor'),
|
||||
('es', 'servers.clients', 'Clientes'),
|
||||
('es', 'servers.delete', 'Eliminar'),
|
||||
('es', 'servers.deploy', 'Implementar'),
|
||||
('es', 'servers.edit', 'Editar'),
|
||||
('es', 'servers.host', 'Host'),
|
||||
('es', 'servers.name', 'Nombre'),
|
||||
('es', 'servers.port', 'Puerto'),
|
||||
('es', 'servers.status', 'Estado'),
|
||||
('es', 'servers.title', 'Servidores'),
|
||||
('es', 'servers.view', 'Ver'),
|
||||
('es', 'settings.actions', 'Acciones'),
|
||||
('es', 'settings.api_key_configured', 'Clave API configurada'),
|
||||
('es', 'settings.api_keys', 'Claves API'),
|
||||
('es', 'settings.api_keys_desc', 'Configurar claves API para servicios externos'),
|
||||
('es', 'settings.auto_translate', 'Auto-traducir'),
|
||||
('es', 'settings.change_password', 'Cambiar contraseña'),
|
||||
('es', 'settings.confirm_password', 'Confirmar contraseña'),
|
||||
('es', 'settings.confirm_translate', '¿Iniciar traducción automática? Esto puede tomar unos minutos.'),
|
||||
('es', 'settings.current_password', 'Contraseña actual'),
|
||||
('es', 'settings.description', 'Gestionar configuración del panel e integraciones API'),
|
||||
('es', 'settings.error_empty_key', 'La clave API no puede estar vacía'),
|
||||
('es', 'settings.error_invalid_key', 'Formato de clave API inválido'),
|
||||
('es', 'settings.error_key_test', 'Prueba de clave API fallida'),
|
||||
('es', 'settings.for_translation', 'para auto-traducción'),
|
||||
('es', 'settings.get_key_at', 'Obtenga su clave API en'),
|
||||
('es', 'settings.key_saved', 'Clave API guardada exitosamente'),
|
||||
('es', 'settings.keys', 'claves'),
|
||||
('es', 'settings.language', 'Idioma'),
|
||||
('es', 'settings.min_6_chars', 'Mínimo 6 caracteres'),
|
||||
('es', 'settings.new_password', 'Nueva contraseña'),
|
||||
('es', 'settings.no_api_key', 'No hay clave API configurada. La auto-traducción no funcionará.'),
|
||||
('es', 'settings.profile', 'Perfil'),
|
||||
('es', 'settings.progress', 'Progreso'),
|
||||
('es', 'settings.skip_validation', 'Omitir validación (guardar sin probar)'),
|
||||
('es', 'settings.translation_complete', 'Traducción completada'),
|
||||
('es', 'settings.translation_status', 'Estado de traducción'),
|
||||
('es', 'settings.translations', 'Traducciones'),
|
||||
('es', 'settings.users', 'Usuarios'),
|
||||
('es', 'status.active', 'Activo'),
|
||||
('es', 'status.deploying', 'Implementando'),
|
||||
('es', 'status.disabled', 'Deshabilitado'),
|
||||
('es', 'status.error', 'Error'),
|
||||
('es', 'status.inactive', 'Inactivo'),
|
||||
('es', 'users.add_user', 'Agregar usuario'),
|
||||
('es', 'users.administrator', 'Administrador'),
|
||||
('es', 'users.all_users', 'Todos los usuarios'),
|
||||
('es', 'users.created', 'Creado'),
|
||||
('es', 'users.delete_confirm', '¿Eliminar {0}?'),
|
||||
('es', 'users.role', 'Rol'),
|
||||
('es', 'users.role_admin', 'Administrador'),
|
||||
('es', 'users.role_user', 'Usuario')
|
||||
ON DUPLICATE KEY UPDATE translation_value=VALUES(translation_value);
|
||||
@@ -46,6 +46,10 @@ INSERT INTO translations (language_code, translation_key, translation_value) VAL
|
||||
('ru', 'clients.traffic', 'Трафик'),
|
||||
('ru', 'clients.traffic_limit', 'Лимит трафика'),
|
||||
('ru', 'clients.unlimited', 'Безлимитно'),
|
||||
('ru', 'clients.custom_seconds', 'Своё значение (секунды)'),
|
||||
('ru', 'clients.custom_mb', 'Своё значение (МБ)'),
|
||||
('ru', 'clients.enter_seconds', 'Введите секунды'),
|
||||
('ru', 'clients.enter_megabytes', 'Введите мегабайты'),
|
||||
('ru', 'common.days', 'дней'),
|
||||
('ru', 'dashboard.active_clients', 'Активные клиенты'),
|
||||
('ru', 'dashboard.add_first_server', 'Добавить первый сервер'),
|
||||
|
||||
@@ -46,6 +46,10 @@ INSERT INTO translations (language_code, translation_key, translation_value) VAL
|
||||
('es', 'clients.traffic', 'Tráfico'),
|
||||
('es', 'clients.traffic_limit', 'Límite de tráfico'),
|
||||
('es', 'clients.unlimited', 'Ilimitado'),
|
||||
('es', 'clients.custom_seconds', 'Personalizado (segundos)'),
|
||||
('es', 'clients.custom_mb', 'Personalizado (MB)'),
|
||||
('es', 'clients.enter_seconds', 'Ingrese segundos'),
|
||||
('es', 'clients.enter_megabytes', 'Ingrese megabytes'),
|
||||
('es', 'common.days', 'días'),
|
||||
('es', 'dashboard.active_clients', 'Clientes activos'),
|
||||
('es', 'dashboard.add_first_server', 'Agregar primer servidor'),
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
-- German translations
|
||||
-- This migration adds German language translations
|
||||
|
||||
INSERT INTO translations (language_code, translation_key, translation_value) VALUES
|
||||
('de', 'auth.email', 'E-Mail'),
|
||||
('de', 'auth.login', 'Anmelden'),
|
||||
('de', 'auth.name', 'Name'),
|
||||
('de', 'auth.password', 'Passwort'),
|
||||
('de', 'auth.register', 'Registrieren'),
|
||||
('de', 'backups.create', 'Backup erstellen'),
|
||||
('de', 'backups.create_confirm', 'Backup aller Clients auf diesem Server erstellen?'),
|
||||
('de', 'backups.created_success', 'Backup erfolgreich erstellt'),
|
||||
('de', 'backups.delete_confirm', 'Dieses Backup endgültig löschen?'),
|
||||
('de', 'backups.deleted_success', 'Backup erfolgreich gelöscht'),
|
||||
('de', 'backups.login_required', 'Bitte melden Sie sich über die API an, um Backups zu verwalten'),
|
||||
('de', 'backups.no_backups', 'Noch keine Backups'),
|
||||
('de', 'backups.restore', 'Wiederherstellen'),
|
||||
('de', 'backups.restore_confirm', 'Clients aus diesem Backup wiederherstellen? Bestehende Clients bleiben unberührt.'),
|
||||
('de', 'backups.restored_success', 'Wiederhergestellt'),
|
||||
('de', 'backups.title', 'Server-Backups'),
|
||||
('de', 'clients.actions', 'Aktionen'),
|
||||
('de', 'clients.add', 'Client hinzufügen'),
|
||||
('de', 'clients.create', 'Client erstellen'),
|
||||
('de', 'clients.delete', 'Löschen'),
|
||||
('de', 'clients.download_config', 'Konfiguration herunterladen'),
|
||||
('de', 'clients.expiration', 'Ablaufdatum'),
|
||||
('de', 'clients.expired', 'Abgelaufen'),
|
||||
('de', 'clients.ip', 'IP-Adresse'),
|
||||
('de', 'clients.last_handshake', 'Letzter Handshake'),
|
||||
('de', 'clients.name', 'Client-Name'),
|
||||
('de', 'clients.never_expires', 'Läuft nie ab'),
|
||||
('de', 'clients.qr_code', 'QR-Code'),
|
||||
('de', 'clients.received', 'Empfangen'),
|
||||
('de', 'clients.restore', 'Wiederherstellen'),
|
||||
('de', 'clients.revoke', 'Widerrufen'),
|
||||
('de', 'clients.sent', 'Gesendet'),
|
||||
('de', 'clients.server', 'Server'),
|
||||
('de', 'clients.status', 'Status'),
|
||||
('de', 'clients.sync_stats', 'Statistiken synchronisieren'),
|
||||
('de', 'clients.title', 'Clients'),
|
||||
('de', 'clients.traffic', 'Datenverkehr'),
|
||||
('de', 'common.days', 'Tage'),
|
||||
('de', 'dashboard.active_clients', 'Aktive Clients'),
|
||||
('de', 'dashboard.add_first_server', 'Ersten Server hinzufügen'),
|
||||
('de', 'dashboard.get_started', 'Beginnen Sie mit dem Hinzufügen Ihres ersten VPN-Servers'),
|
||||
('de', 'dashboard.no_servers', 'Noch keine Server'),
|
||||
('de', 'dashboard.quick_actions', 'Schnellaktionen'),
|
||||
('de', 'dashboard.recent_servers', 'Aktuelle Server'),
|
||||
('de', 'dashboard.title', 'Dashboard'),
|
||||
('de', 'dashboard.total_clients', 'Gesamtzahl Clients'),
|
||||
('de', 'dashboard.total_servers', 'Gesamtzahl Server'),
|
||||
('de', 'dashboard.total_traffic', 'Gesamter Datenverkehr'),
|
||||
('de', 'dashboard.welcome', 'Willkommen im Amnezia VPN Verwaltungspanel'),
|
||||
('de', 'form.cancel', 'Abbrechen'),
|
||||
('de', 'form.close', 'Schließen'),
|
||||
('de', 'form.create', 'Erstellen'),
|
||||
('de', 'form.loading', 'Lädt...'),
|
||||
('de', 'form.processing', 'Verarbeitung...'),
|
||||
('de', 'form.save', 'Speichern'),
|
||||
('de', 'form.submit', 'Absenden'),
|
||||
('de', 'form.update', 'Aktualisieren'),
|
||||
('de', 'menu.clients', 'Clients'),
|
||||
('de', 'menu.dashboard', 'Dashboard'),
|
||||
('de', 'menu.logout', 'Abmelden'),
|
||||
('de', 'menu.servers', 'Server'),
|
||||
('de', 'menu.settings', 'Einstellungen'),
|
||||
('de', 'menu.users', 'Benutzer'),
|
||||
('de', 'message.confirm', 'Sind Sie sicher?'),
|
||||
('de', 'message.deleted', 'Erfolgreich gelöscht'),
|
||||
('de', 'message.deployed', 'Erfolgreich bereitgestellt'),
|
||||
('de', 'message.error', 'Ein Fehler ist aufgetreten'),
|
||||
('de', 'message.saved', 'Erfolgreich gespeichert'),
|
||||
('de', 'message.success', 'Vorgang erfolgreich abgeschlossen'),
|
||||
('de', 'servers.actions', 'Aktionen'),
|
||||
('de', 'servers.add', 'Server hinzufügen'),
|
||||
('de', 'servers.clients', 'Clients'),
|
||||
('de', 'servers.delete', 'Löschen'),
|
||||
('de', 'servers.deploy', 'Bereitstellen'),
|
||||
('de', 'servers.edit', 'Bearbeiten'),
|
||||
('de', 'servers.host', 'Host'),
|
||||
('de', 'servers.name', 'Name'),
|
||||
('de', 'servers.port', 'Port'),
|
||||
('de', 'servers.status', 'Status'),
|
||||
('de', 'servers.title', 'Server'),
|
||||
('de', 'servers.view', 'Ansehen'),
|
||||
('de', 'settings.actions', 'Aktionen'),
|
||||
('de', 'settings.api_key_configured', 'API-Schlüssel konfiguriert'),
|
||||
('de', 'settings.api_keys', 'API-Schlüssel'),
|
||||
('de', 'settings.api_keys_desc', 'API-Schlüssel für externe Dienste konfigurieren'),
|
||||
('de', 'settings.auto_translate', 'Automatische Übersetzung'),
|
||||
('de', 'settings.change_password', 'Passwort ändern'),
|
||||
('de', 'settings.confirm_password', 'Passwort bestätigen'),
|
||||
('de', 'settings.confirm_translate', 'Automatische Übersetzung starten? Dies kann einige Minuten dauern.'),
|
||||
('de', 'settings.current_password', 'Aktuelles Passwort'),
|
||||
('de', 'settings.description', 'Panel-Konfiguration und API-Integrationen verwalten'),
|
||||
('de', 'settings.error_empty_key', 'API-Schlüssel darf nicht leer sein'),
|
||||
('de', 'settings.error_invalid_key', 'Ungültiges API-Schlüssel-Format'),
|
||||
('de', 'settings.error_key_test', 'API-Schlüssel-Test fehlgeschlagen'),
|
||||
('de', 'settings.for_translation', 'für automatische Übersetzung'),
|
||||
('de', 'settings.get_key_at', 'Holen Sie sich Ihren API-Schlüssel bei'),
|
||||
('de', 'settings.key_saved', 'API-Schlüssel erfolgreich gespeichert'),
|
||||
('de', 'settings.keys', 'Schlüssel'),
|
||||
('de', 'settings.language', 'Sprache'),
|
||||
('de', 'settings.min_6_chars', 'Mindestens 6 Zeichen'),
|
||||
('de', 'settings.new_password', 'Neues Passwort'),
|
||||
('de', 'settings.no_api_key', 'Kein API-Schlüssel konfiguriert. Automatische Übersetzung wird nicht funktionieren.'),
|
||||
('de', 'settings.profile', 'Profil'),
|
||||
('de', 'settings.progress', 'Fortschritt'),
|
||||
('de', 'settings.skip_validation', 'Validierung überspringen (ohne Test speichern)'),
|
||||
('de', 'settings.translation_complete', 'Übersetzung abgeschlossen'),
|
||||
('de', 'settings.translation_status', 'Übersetzungsstatus'),
|
||||
('de', 'settings.translations', 'Übersetzungen'),
|
||||
('de', 'settings.users', 'Benutzer'),
|
||||
('de', 'status.active', 'Aktiv'),
|
||||
('de', 'status.deploying', 'Wird bereitgestellt'),
|
||||
('de', 'status.disabled', 'Deaktiviert'),
|
||||
('de', 'status.error', 'Fehler'),
|
||||
('de', 'status.inactive', 'Inaktiv'),
|
||||
('de', 'users.add_user', 'Benutzer hinzufügen'),
|
||||
('de', 'users.administrator', 'Administrator'),
|
||||
('de', 'users.all_users', 'Alle Benutzer'),
|
||||
('de', 'users.created', 'Erstellt'),
|
||||
('de', 'users.delete_confirm', '{0} löschen?'),
|
||||
('de', 'users.role', 'Rolle'),
|
||||
('de', 'users.role_admin', 'Admin'),
|
||||
('de', 'users.role_user', 'Benutzer')
|
||||
ON DUPLICATE KEY UPDATE translation_value=VALUES(translation_value);
|
||||
@@ -46,6 +46,10 @@ INSERT INTO translations (language_code, translation_key, translation_value) VAL
|
||||
('de', 'clients.traffic', 'Datenverkehr'),
|
||||
('de', 'clients.traffic_limit', 'Traffic-Limit'),
|
||||
('de', 'clients.unlimited', 'Unbegrenzt'),
|
||||
('de', 'clients.custom_seconds', 'Benutzerdefiniert (Sekunden)'),
|
||||
('de', 'clients.custom_mb', 'Benutzerdefiniert (MB)'),
|
||||
('de', 'clients.enter_seconds', 'Sekunden eingeben'),
|
||||
('de', 'clients.enter_megabytes', 'Megabytes eingeben'),
|
||||
('de', 'common.days', 'Tage'),
|
||||
('de', 'dashboard.active_clients', 'Aktive Clients'),
|
||||
('de', 'dashboard.add_first_server', 'Ersten Server hinzufügen'),
|
||||
|
||||
@@ -1,127 +0,0 @@
|
||||
-- Russian translations
|
||||
-- This migration adds Russian language translations
|
||||
|
||||
INSERT INTO translations (language_code, translation_key, translation_value) VALUES
|
||||
('ru', 'auth.email', 'Email'),
|
||||
('ru', 'auth.login', 'Вход'),
|
||||
('ru', 'auth.name', 'Имя'),
|
||||
('ru', 'auth.password', 'Пароль'),
|
||||
('ru', 'auth.register', 'Регистрация'),
|
||||
('ru', 'backups.create', 'Создать резервную копию'),
|
||||
('ru', 'backups.create_confirm', 'Создать резервную копию всех клиентов на этом сервере?'),
|
||||
('ru', 'backups.created_success', 'Резервная копия успешно создана'),
|
||||
('ru', 'backups.delete_confirm', 'Удалить эту резервную копию навсегда?'),
|
||||
('ru', 'backups.deleted_success', 'Резервная копия успешно удалена'),
|
||||
('ru', 'backups.login_required', 'Пожалуйста, войдите через API для управления резервными копиями'),
|
||||
('ru', 'backups.no_backups', 'Пока нет резервных копий'),
|
||||
('ru', 'backups.restore', 'Восстановить'),
|
||||
('ru', 'backups.restore_confirm', 'Восстановить клиентов из этой резервной копии? Существующие клиенты не будут затронуты.'),
|
||||
('ru', 'backups.restored_success', 'Восстановлено'),
|
||||
('ru', 'backups.title', 'Резервные копии сервера'),
|
||||
('ru', 'clients.actions', 'Действия'),
|
||||
('ru', 'clients.add', 'Добавить клиента'),
|
||||
('ru', 'clients.create', 'Создать клиента'),
|
||||
('ru', 'clients.delete', 'Удалить'),
|
||||
('ru', 'clients.download_config', 'Скачать конфигурацию'),
|
||||
('ru', 'clients.expiration', 'Срок действия'),
|
||||
('ru', 'clients.expired', 'Истек'),
|
||||
('ru', 'clients.ip', 'IP-адрес'),
|
||||
('ru', 'clients.last_handshake', 'Последнее соединение'),
|
||||
('ru', 'clients.name', 'Имя клиента'),
|
||||
('ru', 'clients.never_expires', 'Бессрочно'),
|
||||
('ru', 'clients.qr_code', 'QR-код'),
|
||||
('ru', 'clients.received', 'Получено'),
|
||||
('ru', 'clients.restore', 'Восстановить'),
|
||||
('ru', 'clients.revoke', 'Отозвать'),
|
||||
('ru', 'clients.sent', 'Отправлено'),
|
||||
('ru', 'clients.server', 'Сервер'),
|
||||
('ru', 'clients.status', 'Статус'),
|
||||
('ru', 'clients.sync_stats', 'Синхронизировать статистику'),
|
||||
('ru', 'clients.title', 'Клиенты'),
|
||||
('ru', 'clients.traffic', 'Трафик'),
|
||||
('ru', 'common.days', 'дней'),
|
||||
('ru', 'dashboard.active_clients', 'Активные клиенты'),
|
||||
('ru', 'dashboard.add_first_server', 'Добавить первый сервер'),
|
||||
('ru', 'dashboard.get_started', 'Начните с добавления вашего первого VPN-сервера'),
|
||||
('ru', 'dashboard.no_servers', 'Пока нет серверов'),
|
||||
('ru', 'dashboard.quick_actions', 'Быстрые действия'),
|
||||
('ru', 'dashboard.recent_servers', 'Недавние серверы'),
|
||||
('ru', 'dashboard.title', 'Панель управления'),
|
||||
('ru', 'dashboard.total_clients', 'Всего клиентов'),
|
||||
('ru', 'dashboard.total_servers', 'Всего серверов'),
|
||||
('ru', 'dashboard.total_traffic', 'Общий трафик'),
|
||||
('ru', 'dashboard.welcome', 'Добро пожаловать в панель управления Amnezia VPN'),
|
||||
('ru', 'form.cancel', 'Отмена'),
|
||||
('ru', 'form.close', 'Закрыть'),
|
||||
('ru', 'form.create', 'Создать'),
|
||||
('ru', 'form.loading', 'Загрузка...'),
|
||||
('ru', 'form.processing', 'Обработка...'),
|
||||
('ru', 'form.save', 'Сохранить'),
|
||||
('ru', 'form.submit', 'Отправить'),
|
||||
('ru', 'form.update', 'Обновить'),
|
||||
('ru', 'menu.clients', 'Клиенты'),
|
||||
('ru', 'menu.dashboard', 'Панель управления'),
|
||||
('ru', 'menu.logout', 'Выход'),
|
||||
('ru', 'menu.servers', 'Серверы'),
|
||||
('ru', 'menu.settings', 'Настройки'),
|
||||
('ru', 'menu.users', 'Пользователи'),
|
||||
('ru', 'message.confirm', 'Вы уверены?'),
|
||||
('ru', 'message.deleted', 'Успешно удалено'),
|
||||
('ru', 'message.deployed', 'Успешно развернуто'),
|
||||
('ru', 'message.error', 'Произошла ошибка'),
|
||||
('ru', 'message.saved', 'Успешно сохранено'),
|
||||
('ru', 'message.success', 'Операция успешно завершена'),
|
||||
('ru', 'servers.actions', 'Действия'),
|
||||
('ru', 'servers.add', 'Добавить сервер'),
|
||||
('ru', 'servers.clients', 'Клиенты'),
|
||||
('ru', 'servers.delete', 'Удалить'),
|
||||
('ru', 'servers.deploy', 'Развернуть'),
|
||||
('ru', 'servers.edit', 'Редактировать'),
|
||||
('ru', 'servers.host', 'Хост'),
|
||||
('ru', 'servers.name', 'Имя'),
|
||||
('ru', 'servers.port', 'Порт'),
|
||||
('ru', 'servers.status', 'Статус'),
|
||||
('ru', 'servers.title', 'Серверы'),
|
||||
('ru', 'servers.view', 'Просмотр'),
|
||||
('ru', 'settings.actions', 'Действия'),
|
||||
('ru', 'settings.api_key_configured', 'API-ключ настроен'),
|
||||
('ru', 'settings.api_keys', 'API-ключи'),
|
||||
('ru', 'settings.api_keys_desc', 'Настройка API-ключей для внешних сервисов'),
|
||||
('ru', 'settings.auto_translate', 'Автоперевод'),
|
||||
('ru', 'settings.change_password', 'Изменить пароль'),
|
||||
('ru', 'settings.confirm_password', 'Подтвердите пароль'),
|
||||
('ru', 'settings.confirm_translate', 'Начать автоматический перевод? Это может занять несколько минут.'),
|
||||
('ru', 'settings.current_password', 'Текущий пароль'),
|
||||
('ru', 'settings.description', 'Управление конфигурацией панели и интеграциями API'),
|
||||
('ru', 'settings.error_empty_key', 'API-ключ не может быть пустым'),
|
||||
('ru', 'settings.error_invalid_key', 'Неверный формат API-ключа'),
|
||||
('ru', 'settings.error_key_test', 'Тест API-ключа не удался'),
|
||||
('ru', 'settings.for_translation', 'для автоперевода'),
|
||||
('ru', 'settings.get_key_at', 'Получите ваш API-ключ на'),
|
||||
('ru', 'settings.key_saved', 'API-ключ успешно сохранен'),
|
||||
('ru', 'settings.keys', 'ключи'),
|
||||
('ru', 'settings.language', 'Язык'),
|
||||
('ru', 'settings.min_6_chars', 'Минимум 6 символов'),
|
||||
('ru', 'settings.new_password', 'Новый пароль'),
|
||||
('ru', 'settings.no_api_key', 'API-ключ не настроен. Автоперевод не будет работать.'),
|
||||
('ru', 'settings.profile', 'Профиль'),
|
||||
('ru', 'settings.progress', 'Прогресс'),
|
||||
('ru', 'settings.skip_validation', 'Пропустить проверку (сохранить без тестирования)'),
|
||||
('ru', 'settings.translation_complete', 'Перевод завершен'),
|
||||
('ru', 'settings.translation_status', 'Статус перевода'),
|
||||
('ru', 'settings.translations', 'Переводы'),
|
||||
('ru', 'settings.users', 'Пользователи'),
|
||||
('ru', 'status.active', 'Активен'),
|
||||
('ru', 'status.deploying', 'Развертывание'),
|
||||
('ru', 'status.disabled', 'Отключен'),
|
||||
('ru', 'status.error', 'Ошибка'),
|
||||
('ru', 'status.inactive', 'Неактивен'),
|
||||
('ru', 'users.add_user', 'Добавить пользователя'),
|
||||
('ru', 'users.administrator', 'Администратор'),
|
||||
('ru', 'users.all_users', 'Все пользователи'),
|
||||
('ru', 'users.created', 'Создан'),
|
||||
('ru', 'users.delete_confirm', 'Удалить {0}?'),
|
||||
('ru', 'users.role', 'Роль'),
|
||||
('ru', 'users.role_admin', 'Администратор'),
|
||||
('ru', 'users.role_user', 'Пользователь')
|
||||
ON DUPLICATE KEY UPDATE translation_value=VALUES(translation_value);
|
||||
@@ -1,127 +0,0 @@
|
||||
-- French translations
|
||||
-- This migration adds French language translations
|
||||
|
||||
INSERT INTO translations (language_code, translation_key, translation_value) VALUES
|
||||
('fr', 'auth.email', 'Email'),
|
||||
('fr', 'auth.login', 'Connexion'),
|
||||
('fr', 'auth.name', 'Nom'),
|
||||
('fr', 'auth.password', 'Mot de passe'),
|
||||
('fr', 'auth.register', 'S''inscrire'),
|
||||
('fr', 'backups.create', 'Créer une sauvegarde'),
|
||||
('fr', 'backups.create_confirm', 'Créer une sauvegarde de tous les clients sur ce serveur ?'),
|
||||
('fr', 'backups.created_success', 'Sauvegarde créée avec succès'),
|
||||
('fr', 'backups.delete_confirm', 'Supprimer définitivement cette sauvegarde ?'),
|
||||
('fr', 'backups.deleted_success', 'Sauvegarde supprimée avec succès'),
|
||||
('fr', 'backups.login_required', 'Veuillez vous connecter via l''API pour gérer les sauvegardes'),
|
||||
('fr', 'backups.no_backups', 'Aucune sauvegarde pour le moment'),
|
||||
('fr', 'backups.restore', 'Restaurer'),
|
||||
('fr', 'backups.restore_confirm', 'Restaurer les clients depuis cette sauvegarde ? Les clients existants ne seront pas affectés.'),
|
||||
('fr', 'backups.restored_success', 'Restauré'),
|
||||
('fr', 'backups.title', 'Sauvegardes du serveur'),
|
||||
('fr', 'clients.actions', 'Actions'),
|
||||
('fr', 'clients.add', 'Ajouter un client'),
|
||||
('fr', 'clients.create', 'Créer un client'),
|
||||
('fr', 'clients.delete', 'Supprimer'),
|
||||
('fr', 'clients.download_config', 'Télécharger la configuration'),
|
||||
('fr', 'clients.expiration', 'Expiration'),
|
||||
('fr', 'clients.expired', 'Expiré'),
|
||||
('fr', 'clients.ip', 'Adresse IP'),
|
||||
('fr', 'clients.last_handshake', 'Dernière connexion'),
|
||||
('fr', 'clients.name', 'Nom du client'),
|
||||
('fr', 'clients.never_expires', 'N''expire jamais'),
|
||||
('fr', 'clients.qr_code', 'Code QR'),
|
||||
('fr', 'clients.received', 'Reçu'),
|
||||
('fr', 'clients.restore', 'Restaurer'),
|
||||
('fr', 'clients.revoke', 'Révoquer'),
|
||||
('fr', 'clients.sent', 'Envoyé'),
|
||||
('fr', 'clients.server', 'Serveur'),
|
||||
('fr', 'clients.status', 'Statut'),
|
||||
('fr', 'clients.sync_stats', 'Synchroniser les statistiques'),
|
||||
('fr', 'clients.title', 'Clients'),
|
||||
('fr', 'clients.traffic', 'Trafic'),
|
||||
('fr', 'common.days', 'jours'),
|
||||
('fr', 'dashboard.active_clients', 'Clients actifs'),
|
||||
('fr', 'dashboard.add_first_server', 'Ajouter le premier serveur'),
|
||||
('fr', 'dashboard.get_started', 'Commencez par ajouter votre premier serveur VPN'),
|
||||
('fr', 'dashboard.no_servers', 'Aucun serveur pour le moment'),
|
||||
('fr', 'dashboard.quick_actions', 'Actions rapides'),
|
||||
('fr', 'dashboard.recent_servers', 'Serveurs récents'),
|
||||
('fr', 'dashboard.title', 'Tableau de bord'),
|
||||
('fr', 'dashboard.total_clients', 'Total des clients'),
|
||||
('fr', 'dashboard.total_servers', 'Total des serveurs'),
|
||||
('fr', 'dashboard.total_traffic', 'Trafic total'),
|
||||
('fr', 'dashboard.welcome', 'Bienvenue sur le panneau de gestion Amnezia VPN'),
|
||||
('fr', 'form.cancel', 'Annuler'),
|
||||
('fr', 'form.close', 'Fermer'),
|
||||
('fr', 'form.create', 'Créer'),
|
||||
('fr', 'form.loading', 'Chargement...'),
|
||||
('fr', 'form.processing', 'Traitement...'),
|
||||
('fr', 'form.save', 'Enregistrer'),
|
||||
('fr', 'form.submit', 'Soumettre'),
|
||||
('fr', 'form.update', 'Mettre à jour'),
|
||||
('fr', 'menu.clients', 'Clients'),
|
||||
('fr', 'menu.dashboard', 'Tableau de bord'),
|
||||
('fr', 'menu.logout', 'Déconnexion'),
|
||||
('fr', 'menu.servers', 'Serveurs'),
|
||||
('fr', 'menu.settings', 'Paramètres'),
|
||||
('fr', 'menu.users', 'Utilisateurs'),
|
||||
('fr', 'message.confirm', 'Êtes-vous sûr ?'),
|
||||
('fr', 'message.deleted', 'Supprimé avec succès'),
|
||||
('fr', 'message.deployed', 'Déployé avec succès'),
|
||||
('fr', 'message.error', 'Une erreur est survenue'),
|
||||
('fr', 'message.saved', 'Enregistré avec succès'),
|
||||
('fr', 'message.success', 'Opération terminée avec succès'),
|
||||
('fr', 'servers.actions', 'Actions'),
|
||||
('fr', 'servers.add', 'Ajouter un serveur'),
|
||||
('fr', 'servers.clients', 'Clients'),
|
||||
('fr', 'servers.delete', 'Supprimer'),
|
||||
('fr', 'servers.deploy', 'Déployer'),
|
||||
('fr', 'servers.edit', 'Modifier'),
|
||||
('fr', 'servers.host', 'Hôte'),
|
||||
('fr', 'servers.name', 'Nom'),
|
||||
('fr', 'servers.port', 'Port'),
|
||||
('fr', 'servers.status', 'Statut'),
|
||||
('fr', 'servers.title', 'Serveurs'),
|
||||
('fr', 'servers.view', 'Voir'),
|
||||
('fr', 'settings.actions', 'Actions'),
|
||||
('fr', 'settings.api_key_configured', 'Clé API configurée'),
|
||||
('fr', 'settings.api_keys', 'Clés API'),
|
||||
('fr', 'settings.api_keys_desc', 'Configurer les clés API pour les services externes'),
|
||||
('fr', 'settings.auto_translate', 'Traduction automatique'),
|
||||
('fr', 'settings.change_password', 'Changer le mot de passe'),
|
||||
('fr', 'settings.confirm_password', 'Confirmer le mot de passe'),
|
||||
('fr', 'settings.confirm_translate', 'Démarrer la traduction automatique ? Cela peut prendre quelques minutes.'),
|
||||
('fr', 'settings.current_password', 'Mot de passe actuel'),
|
||||
('fr', 'settings.description', 'Gérer la configuration du panneau et les intégrations API'),
|
||||
('fr', 'settings.error_empty_key', 'La clé API ne peut pas être vide'),
|
||||
('fr', 'settings.error_invalid_key', 'Format de clé API invalide'),
|
||||
('fr', 'settings.error_key_test', 'Test de la clé API échoué'),
|
||||
('fr', 'settings.for_translation', 'pour la traduction automatique'),
|
||||
('fr', 'settings.get_key_at', 'Obtenez votre clé API sur'),
|
||||
('fr', 'settings.key_saved', 'Clé API enregistrée avec succès'),
|
||||
('fr', 'settings.keys', 'clés'),
|
||||
('fr', 'settings.language', 'Langue'),
|
||||
('fr', 'settings.min_6_chars', 'Minimum 6 caractères'),
|
||||
('fr', 'settings.new_password', 'Nouveau mot de passe'),
|
||||
('fr', 'settings.no_api_key', 'Aucune clé API configurée. La traduction automatique ne fonctionnera pas.'),
|
||||
('fr', 'settings.profile', 'Profil'),
|
||||
('fr', 'settings.progress', 'Progression'),
|
||||
('fr', 'settings.skip_validation', 'Ignorer la validation (enregistrer sans tester)'),
|
||||
('fr', 'settings.translation_complete', 'Traduction terminée'),
|
||||
('fr', 'settings.translation_status', 'État de la traduction'),
|
||||
('fr', 'settings.translations', 'Traductions'),
|
||||
('fr', 'settings.users', 'Utilisateurs'),
|
||||
('fr', 'status.active', 'Actif'),
|
||||
('fr', 'status.deploying', 'Déploiement'),
|
||||
('fr', 'status.disabled', 'Désactivé'),
|
||||
('fr', 'status.error', 'Erreur'),
|
||||
('fr', 'status.inactive', 'Inactif'),
|
||||
('fr', 'users.add_user', 'Ajouter un utilisateur'),
|
||||
('fr', 'users.administrator', 'Administrateur'),
|
||||
('fr', 'users.all_users', 'Tous les utilisateurs'),
|
||||
('fr', 'users.created', 'Créé'),
|
||||
('fr', 'users.delete_confirm', 'Supprimer {0} ?'),
|
||||
('fr', 'users.role', 'Rôle'),
|
||||
('fr', 'users.role_admin', 'Administrateur'),
|
||||
('fr', 'users.role_user', 'Utilisateur')
|
||||
ON DUPLICATE KEY UPDATE translation_value=VALUES(translation_value);
|
||||
@@ -46,6 +46,10 @@ INSERT INTO translations (language_code, translation_key, translation_value) VAL
|
||||
('fr', 'clients.traffic', 'Trafic'),
|
||||
('fr', 'clients.traffic_limit', 'Limite de trafic'),
|
||||
('fr', 'clients.unlimited', 'Illimité'),
|
||||
('fr', 'clients.custom_seconds', 'Personnalisé (secondes)'),
|
||||
('fr', 'clients.custom_mb', 'Personnalisé (MB)'),
|
||||
('fr', 'clients.enter_seconds', 'Saisissez les secondes'),
|
||||
('fr', 'clients.enter_megabytes', 'Saisissez les mégaoctets'),
|
||||
('fr', 'common.days', 'jours'),
|
||||
('fr', 'dashboard.active_clients', 'Clients actifs'),
|
||||
('fr', 'dashboard.add_first_server', 'Ajouter le premier serveur'),
|
||||
|
||||
@@ -46,6 +46,10 @@ INSERT INTO translations (language_code, translation_key, translation_value) VAL
|
||||
('zh', 'clients.traffic', '流量'),
|
||||
('zh', 'clients.traffic_limit', '流量限制'),
|
||||
('zh', 'clients.unlimited', '无限制'),
|
||||
('zh', 'clients.custom_seconds', '自定义(秒)'),
|
||||
('zh', 'clients.custom_mb', '自定义(MB)'),
|
||||
('zh', 'clients.enter_seconds', '输入秒数'),
|
||||
('zh', 'clients.enter_megabytes', '输入兆字节'),
|
||||
('zh', 'common.days', '天'),
|
||||
('zh', 'dashboard.active_clients', '活跃客户端'),
|
||||
('zh', 'dashboard.add_first_server', '添加第一个服务器'),
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
-- This migration adds traffic limit functionality to clients
|
||||
|
||||
ALTER TABLE vpn_clients
|
||||
ADD COLUMN traffic_limit BIGINT UNSIGNED NULL COMMENT 'Traffic limit in bytes (NULL = unlimited)' AFTER traffic_received,
|
||||
ADD COLUMN traffic_limit BIGINT UNSIGNED NULL COMMENT 'Traffic limit in bytes (NULL = unlimited)' AFTER expires_at,
|
||||
ADD INDEX idx_traffic_limit (traffic_limit);
|
||||
|
||||
@@ -1,300 +0,0 @@
|
||||
-- Amnezia VPN Panel - Complete Database Schema
|
||||
-- Single migration file containing all tables and initial data
|
||||
|
||||
-- Users table
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL UNIQUE,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
role ENUM('admin', 'user') DEFAULT 'user',
|
||||
preferred_language VARCHAR(10) DEFAULT 'en',
|
||||
status ENUM('active', 'disabled') DEFAULT 'active',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login_at TIMESTAMP NULL,
|
||||
INDEX idx_email (email),
|
||||
INDEX idx_role (role),
|
||||
INDEX idx_language (preferred_language)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- VPN Servers table
|
||||
CREATE TABLE IF NOT EXISTS vpn_servers (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
host VARCHAR(255) NOT NULL,
|
||||
port INT UNSIGNED NOT NULL,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
container_name VARCHAR(255) DEFAULT 'amnezia-awg',
|
||||
vpn_port INT UNSIGNED NULL,
|
||||
vpn_subnet VARCHAR(50) DEFAULT '10.8.1.0/24',
|
||||
server_public_key TEXT NULL,
|
||||
preshared_key TEXT NULL,
|
||||
awg_params JSON NULL COMMENT 'Jc, Jmin, Jmax, S1, S2, H1-H4',
|
||||
status ENUM('deploying', 'active', 'stopped', 'error') DEFAULT 'deploying',
|
||||
deployed_at TIMESTAMP NULL,
|
||||
last_check_at TIMESTAMP NULL,
|
||||
error_message TEXT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_status (status),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- VPN Clients table
|
||||
CREATE TABLE IF NOT EXISTS vpn_clients (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
server_id INT UNSIGNED NOT NULL,
|
||||
user_id INT UNSIGNED NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
client_ip VARCHAR(50) NOT NULL,
|
||||
public_key TEXT NOT NULL,
|
||||
private_key TEXT NOT NULL,
|
||||
preshared_key TEXT NULL,
|
||||
config TEXT NULL COMMENT 'Full WireGuard config file',
|
||||
qr_code LONGTEXT NULL COMMENT 'Base64 encoded QR code image',
|
||||
bytes_sent BIGINT UNSIGNED DEFAULT 0 COMMENT 'Total bytes sent by client',
|
||||
bytes_received BIGINT UNSIGNED DEFAULT 0 COMMENT 'Total bytes received by client',
|
||||
last_handshake TIMESTAMP NULL COMMENT 'Last successful WireGuard handshake',
|
||||
last_sync_at TIMESTAMP NULL COMMENT 'Last time stats were synced from server',
|
||||
status ENUM('active', 'disabled') DEFAULT 'active',
|
||||
expires_at TIMESTAMP NULL COMMENT 'Client expiration date (NULL = never expires)',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_server_id (server_id),
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_expires_at (expires_at),
|
||||
INDEX idx_last_handshake (last_handshake),
|
||||
UNIQUE KEY unique_server_client_ip (server_id, client_ip),
|
||||
FOREIGN KEY (server_id) REFERENCES vpn_servers(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- API Tokens table
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT UNSIGNED NOT NULL,
|
||||
token VARCHAR(255) NOT NULL UNIQUE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
last_used_at TIMESTAMP NULL,
|
||||
expires_at TIMESTAMP NULL,
|
||||
revoked_at TIMESTAMP NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_token (token),
|
||||
INDEX idx_user_id (user_id),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Settings table
|
||||
CREATE TABLE IF NOT EXISTS settings (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id INT UNSIGNED NULL COMMENT 'NULL for global settings',
|
||||
namespace VARCHAR(100) NOT NULL,
|
||||
`key` VARCHAR(100) NOT NULL,
|
||||
value JSON NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY unique_setting (user_id, namespace, `key`),
|
||||
INDEX idx_namespace (namespace)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Languages table
|
||||
CREATE TABLE IF NOT EXISTS languages (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
code VARCHAR(10) NOT NULL UNIQUE COMMENT 'Language code (en, ru, es, de, fr, zh)',
|
||||
name VARCHAR(50) NOT NULL COMMENT 'Language name in English',
|
||||
native_name VARCHAR(50) NOT NULL COMMENT 'Language name in native language',
|
||||
is_active TINYINT(1) DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX idx_code (code),
|
||||
INDEX idx_active (is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Translations table
|
||||
CREATE TABLE IF NOT EXISTS translations (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
language_code VARCHAR(10) NOT NULL,
|
||||
translation_key VARCHAR(255) NOT NULL COMMENT 'Translation key (e.g., menu.dashboard)',
|
||||
translation_value TEXT NOT NULL COMMENT 'Translated text',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY unique_translation (language_code, translation_key),
|
||||
FOREIGN KEY (language_code) REFERENCES languages(code) ON DELETE CASCADE,
|
||||
INDEX idx_key (translation_key),
|
||||
INDEX idx_language (language_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- API Keys table
|
||||
CREATE TABLE IF NOT EXISTS api_keys (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
service_name VARCHAR(50) NOT NULL UNIQUE COMMENT 'Service name (e.g., openrouter)',
|
||||
api_key TEXT NOT NULL COMMENT 'API key value',
|
||||
is_active TINYINT(1) DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX idx_service (service_name),
|
||||
INDEX idx_active (is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Server Backups table
|
||||
CREATE TABLE IF NOT EXISTS server_backups (
|
||||
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||
server_id INT UNSIGNED NOT NULL,
|
||||
backup_name VARCHAR(255) NOT NULL COMMENT 'Backup file name',
|
||||
backup_path VARCHAR(500) NOT NULL COMMENT 'Path to backup file',
|
||||
backup_size BIGINT UNSIGNED DEFAULT 0 COMMENT 'Backup file size in bytes',
|
||||
clients_count INT UNSIGNED DEFAULT 0 COMMENT 'Number of clients in backup',
|
||||
backup_type ENUM('manual', 'automatic') DEFAULT 'manual',
|
||||
status ENUM('creating', 'completed', 'failed') DEFAULT 'creating',
|
||||
error_message TEXT NULL COMMENT 'Error message if backup failed',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INT UNSIGNED NULL COMMENT 'User who created the backup',
|
||||
INDEX idx_server_id (server_id),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_created_at (created_at),
|
||||
FOREIGN KEY (server_id) REFERENCES vpn_servers(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Insert default admin user
|
||||
INSERT IGNORE INTO users (email, password_hash, name, role, status)
|
||||
VALUES ('admin@amnez.ia', '$2y$10$SKEI6ogiWr2gsSG/nELLp.JcfpGhxsDLAAI7gdtTOI3ELz4zJzzPG', 'Administrator', 'admin', 'active');
|
||||
|
||||
-- Insert supported languages
|
||||
INSERT INTO languages (code, name, native_name) VALUES
|
||||
('en', 'English', 'English'),
|
||||
('ru', 'Russian', 'Русский'),
|
||||
('es', 'Spanish', 'Español'),
|
||||
('de', 'German', 'Deutsch'),
|
||||
('fr', 'French', 'Français'),
|
||||
('zh', 'Chinese', '中文')
|
||||
ON DUPLICATE KEY UPDATE name=VALUES(name);
|
||||
|
||||
-- Insert English translations
|
||||
INSERT INTO translations (language_code, translation_key, translation_value) VALUES
|
||||
('en', 'auth.email', 'Email'),
|
||||
('en', 'auth.login', 'Login'),
|
||||
('en', 'auth.name', 'Name'),
|
||||
('en', 'auth.password', 'Password'),
|
||||
('en', 'auth.register', 'Register'),
|
||||
('en', 'clients.actions', 'Actions'),
|
||||
('en', 'clients.add', 'Add Client'),
|
||||
('en', 'clients.create', 'Create Client'),
|
||||
('en', 'clients.delete', 'Delete'),
|
||||
('en', 'clients.download_config', 'Download Config'),
|
||||
('en', 'clients.expiration', 'Expiration'),
|
||||
('en', 'clients.expired', 'Expired'),
|
||||
('en', 'clients.never_expires', 'Never expires'),
|
||||
('en', 'clients.ip', 'IP Address'),
|
||||
('en', 'clients.last_handshake', 'Last Handshake'),
|
||||
('en', 'clients.name', 'Client Name'),
|
||||
('en', 'clients.qr_code', 'QR Code'),
|
||||
('en', 'clients.received', 'Received'),
|
||||
('en', 'clients.restore', 'Restore'),
|
||||
('en', 'clients.revoke', 'Revoke'),
|
||||
('en', 'clients.sent', 'Sent'),
|
||||
('en', 'clients.server', 'Server'),
|
||||
('en', 'clients.status', 'Status'),
|
||||
('en', 'clients.sync_stats', 'Sync Stats'),
|
||||
('en', 'clients.title', 'Clients'),
|
||||
('en', 'clients.traffic', 'Traffic'),
|
||||
('en', 'backups.title', 'Server Backups'),
|
||||
('en', 'backups.create', 'Create Backup'),
|
||||
('en', 'backups.restore', 'Restore'),
|
||||
('en', 'backups.no_backups', 'No backups yet'),
|
||||
('en', 'backups.create_confirm', 'Create backup of all clients on this server?'),
|
||||
('en', 'backups.restore_confirm', 'Restore clients from this backup? Existing clients will not be affected.'),
|
||||
('en', 'backups.delete_confirm', 'Delete this backup permanently?'),
|
||||
('en', 'backups.created_success', 'Backup created successfully'),
|
||||
('en', 'backups.restored_success', 'Restored'),
|
||||
('en', 'backups.deleted_success', 'Backup deleted successfully'),
|
||||
('en', 'backups.login_required', 'Please login via API to manage backups'),
|
||||
('en', 'common.days', 'days'),
|
||||
('en', 'dashboard.active_clients', 'Active Clients'),
|
||||
('en', 'dashboard.add_first_server', 'Add First Server'),
|
||||
('en', 'dashboard.get_started', 'Get started by adding your first VPN server'),
|
||||
('en', 'dashboard.no_servers', 'No servers yet'),
|
||||
('en', 'dashboard.quick_actions', 'Quick Actions'),
|
||||
('en', 'dashboard.recent_servers', 'Recent Servers'),
|
||||
('en', 'dashboard.title', 'Dashboard'),
|
||||
('en', 'dashboard.total_clients', 'Total Clients'),
|
||||
('en', 'dashboard.total_servers', 'Total Servers'),
|
||||
('en', 'dashboard.total_traffic', 'Total Traffic'),
|
||||
('en', 'dashboard.welcome', 'Welcome to Amnezia VPN Management Panel'),
|
||||
('en', 'form.cancel', 'Cancel'),
|
||||
('en', 'form.close', 'Close'),
|
||||
('en', 'form.create', 'Create'),
|
||||
('en', 'form.loading', 'Loading...'),
|
||||
('en', 'form.processing', 'Processing...'),
|
||||
('en', 'form.save', 'Save'),
|
||||
('en', 'form.submit', 'Submit'),
|
||||
('en', 'form.update', 'Update'),
|
||||
('en', 'menu.clients', 'Clients'),
|
||||
('en', 'menu.dashboard', 'Dashboard'),
|
||||
('en', 'menu.logout', 'Logout'),
|
||||
('en', 'menu.servers', 'Servers'),
|
||||
('en', 'menu.settings', 'Settings'),
|
||||
('en', 'menu.users', 'Users'),
|
||||
('en', 'message.confirm', 'Are you sure?'),
|
||||
('en', 'message.deleted', 'Deleted successfully'),
|
||||
('en', 'message.deployed', 'Deployed successfully'),
|
||||
('en', 'message.error', 'An error occurred'),
|
||||
('en', 'message.saved', 'Saved successfully'),
|
||||
('en', 'message.success', 'Operation completed successfully'),
|
||||
('en', 'servers.actions', 'Actions'),
|
||||
('en', 'servers.add', 'Add Server'),
|
||||
('en', 'servers.clients', 'Clients'),
|
||||
('en', 'servers.delete', 'Delete'),
|
||||
('en', 'servers.deploy', 'Deploy'),
|
||||
('en', 'servers.edit', 'Edit'),
|
||||
('en', 'servers.host', 'Host'),
|
||||
('en', 'servers.name', 'Name'),
|
||||
('en', 'servers.port', 'Port'),
|
||||
('en', 'servers.status', 'Status'),
|
||||
('en', 'servers.title', 'Servers'),
|
||||
('en', 'servers.view', 'View'),
|
||||
('en', 'settings.actions', 'Actions'),
|
||||
('en', 'settings.api_keys', 'API Keys'),
|
||||
('en', 'settings.api_keys_desc', 'Configure API keys for external services'),
|
||||
('en', 'settings.auto_translate', 'Auto-translate'),
|
||||
('en', 'settings.change_password', 'Change Password'),
|
||||
('en', 'settings.confirm_password', 'Confirm Password'),
|
||||
('en', 'settings.confirm_translate', 'Start automatic translation? This may take a few minutes.'),
|
||||
('en', 'settings.current_password', 'Current Password'),
|
||||
('en', 'settings.description', 'Manage panel configuration and API integrations'),
|
||||
('en', 'settings.error_empty_key', 'API key cannot be empty'),
|
||||
('en', 'settings.error_invalid_key', 'Invalid API key format'),
|
||||
('en', 'settings.error_key_test', 'API key test failed'),
|
||||
('en', 'settings.for_translation', 'for auto-translation'),
|
||||
('en', 'settings.get_key_at', 'Get your API key at'),
|
||||
('en', 'settings.key_saved', 'API key saved successfully'),
|
||||
('en', 'settings.keys', 'keys'),
|
||||
('en', 'settings.language', 'Language'),
|
||||
('en', 'settings.min_6_chars', 'Minimum 6 characters'),
|
||||
('en', 'settings.new_password', 'New Password'),
|
||||
('en', 'settings.profile', 'Profile'),
|
||||
('en', 'settings.progress', 'Progress'),
|
||||
('en', 'settings.translations', 'Translations'),
|
||||
('en', 'settings.translation_complete', 'Translation completed'),
|
||||
('en', 'settings.translation_status', 'Translation Status'),
|
||||
('en', 'settings.users', 'Users'),
|
||||
('en', 'status.active', 'Active'),
|
||||
('en', 'status.deploying', 'Deploying'),
|
||||
('en', 'status.disabled', 'Disabled'),
|
||||
('en', 'status.error', 'Error'),
|
||||
('en', 'status.inactive', 'Inactive'),
|
||||
('en', 'users.add_user', 'Add User'),
|
||||
('en', 'users.all_users', 'All Users'),
|
||||
('en', 'users.administrator', 'Administrator'),
|
||||
('en', 'users.created', 'Created'),
|
||||
('en', 'users.delete_confirm', 'Delete {0}?'),
|
||||
('en', 'users.role', 'Role'),
|
||||
('en', 'users.role_admin', 'Admin'),
|
||||
('en', 'users.role_user', 'User'),
|
||||
('en', 'settings.api_key_configured', 'API Key Configured'),
|
||||
('en', 'settings.no_api_key', 'No API key configured. Auto-translation will not work.'),
|
||||
('en', 'settings.skip_validation', 'Skip validation (save without testing)')
|
||||
ON DUPLICATE KEY UPDATE translation_value=VALUES(translation_value);
|
||||
Reference in New Issue
Block a user