1f91f17f57
Added time limits and backup functions for servers
305 lines
13 KiB
SQL
305 lines
13 KiB
SQL
-- 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.delete_confirm', 'Delete this client permanently?'),
|
|
('en', 'clients.download_config', 'Download Config'),
|
|
('en', 'clients.expiration', 'Expiration'),
|
|
('en', 'clients.expired', 'Expired'),
|
|
('en', 'clients.never', 'Never'),
|
|
('en', 'clients.never_expires', 'Never expires'),
|
|
('en', 'clients.no_clients', 'No clients yet'),
|
|
('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.revoke_confirm', 'Revoke access for this client?'),
|
|
('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);
|