cli: avoid data-dir initialization for version; create db parent dirs; redact generated passwords in CLI output

- Prevent 'nx9-wg version' from creating data directories by avoiding database initialization.
- Create parent directories when an explicit --database path is provided.
- Redact printed generated administrator passwords; announce file path or redact instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
thakaresandCopilot committed 2026-08-16 16:26:24 +05:30
commit 2ac6c81dfe
140 files changed
+31342

No files matched your search

@@ -0,0 +1,219 @@
------------------------------------------------------------------------
-- nx9-wg SQLite Initial Migration (0001_initial.sql)
------------------------------------------------------------------------
------------------------------------------------------------------------
-- 1. Admin (Exactly one row, id=1 enforced by CHECK)
------------------------------------------------------------------------
CREATE TABLE admin (
id INTEGER PRIMARY KEY CHECK (id = 1),
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
totp_secret TEXT,
totp_enabled INTEGER NOT NULL DEFAULT 0,
last_login_at TEXT,
last_login_ip TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_admin_username ON admin(username);
------------------------------------------------------------------------
-- 2. Sessions
------------------------------------------------------------------------
CREATE TABLE sessions (
id TEXT PRIMARY KEY,
admin_id INTEGER NOT NULL DEFAULT 1 REFERENCES admin(id) ON DELETE CASCADE,
ip_address TEXT,
user_agent TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
expires_at TEXT NOT NULL,
last_seen_at TEXT
);
CREATE INDEX idx_sessions_expires_at ON sessions(expires_at);
CREATE INDEX idx_sessions_admin_id ON sessions(admin_id);
------------------------------------------------------------------------
-- 3. Login Attempts (Brute force protection)
------------------------------------------------------------------------
CREATE TABLE login_attempts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip_address TEXT NOT NULL,
attempted_at TEXT NOT NULL DEFAULT (datetime('now')),
success INTEGER NOT NULL DEFAULT 0
);
CREATE INDEX idx_login_attempts_ip ON login_attempts(ip_address, attempted_at);
------------------------------------------------------------------------
-- 4. API Tokens
------------------------------------------------------------------------
CREATE TABLE api_tokens (
id TEXT PRIMARY KEY,
admin_id INTEGER NOT NULL DEFAULT 1 REFERENCES admin(id) ON DELETE CASCADE,
name TEXT NOT NULL,
token_hash TEXT NOT NULL UNIQUE,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
expires_at TEXT,
last_used_at TEXT,
revoked_at TEXT
);
CREATE INDEX idx_api_tokens_token_hash ON api_tokens(token_hash);
CREATE INDEX idx_api_tokens_expires_at ON api_tokens(expires_at);
------------------------------------------------------------------------
-- 5. WireGuard Interfaces
------------------------------------------------------------------------
CREATE TABLE interfaces (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
private_key TEXT NOT NULL,
public_key TEXT NOT NULL,
listen_port INTEGER NOT NULL DEFAULT 51820,
ipv4_cidr TEXT NOT NULL,
ipv6_cidr TEXT,
mtu INTEGER,
dns TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
pre_up TEXT,
post_up TEXT,
pre_down TEXT,
post_down TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_interfaces_name ON interfaces(name);
------------------------------------------------------------------------
-- 6. Peers / Clients
------------------------------------------------------------------------
CREATE TABLE peers (
id TEXT PRIMARY KEY,
interface_id TEXT NOT NULL REFERENCES interfaces(id) ON DELETE CASCADE,
name TEXT NOT NULL,
peer_type TEXT NOT NULL DEFAULT 'road_warrior'
CHECK (peer_type IN ('road_warrior', 'site_gateway', 'server', 'relay')),
state TEXT NOT NULL DEFAULT 'active'
CHECK (state IN ('active', 'disabled', 'revoked', 'expired')),
profile TEXT NOT NULL DEFAULT 'full_tunnel'
CHECK (profile IN ('full_tunnel', 'split_tunnel', 'custom')),
public_key TEXT NOT NULL,
private_key TEXT,
preshared_key TEXT,
endpoint TEXT,
allowed_ips TEXT NOT NULL,
server_allowed_ips TEXT,
address_ipv4 TEXT,
address_ipv6 TEXT,
dns TEXT,
mtu INTEGER,
persistent_keepalive INTEGER,
expires_at TEXT,
last_handshake_at TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
UNIQUE(interface_id, name),
UNIQUE(interface_id, public_key)
);
CREATE INDEX idx_peers_interface_id ON peers(interface_id);
CREATE INDEX idx_peers_name ON peers(interface_id, name);
CREATE INDEX idx_peers_state ON peers(state);
------------------------------------------------------------------------
-- 7. Networks
------------------------------------------------------------------------
CREATE TABLE networks (
id TEXT PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
cidr TEXT NOT NULL,
enabled INTEGER NOT NULL DEFAULT 1,
description TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_networks_name ON networks(name);
------------------------------------------------------------------------
-- 8. Routes
------------------------------------------------------------------------
CREATE TABLE routes (
id TEXT PRIMARY KEY,
network_id TEXT REFERENCES networks(id) ON DELETE SET NULL,
interface_id TEXT REFERENCES interfaces(id) ON DELETE SET NULL,
destination TEXT NOT NULL,
gateway TEXT,
metric INTEGER,
enabled INTEGER NOT NULL DEFAULT 1,
description TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_routes_network_id ON routes(network_id);
CREATE INDEX idx_routes_interface_id ON routes(interface_id);
------------------------------------------------------------------------
-- 9. Firewall Rules
------------------------------------------------------------------------
CREATE TABLE firewall_rules (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
interface_id TEXT REFERENCES interfaces(id) ON DELETE SET NULL,
direction TEXT NOT NULL DEFAULT 'in'
CHECK (direction IN ('in', 'out', 'forward')),
action TEXT NOT NULL DEFAULT 'accept'
CHECK (action IN ('accept', 'drop', 'reject')),
protocol TEXT NOT NULL DEFAULT 'any'
CHECK (protocol IN ('tcp', 'udp', 'tcp_udp', 'icmp', 'any')),
source TEXT,
destination TEXT,
source_port INTEGER,
destination_port INTEGER,
priority INTEGER NOT NULL DEFAULT 100,
enabled INTEGER NOT NULL DEFAULT 1,
description TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_firewall_interface_priority ON firewall_rules(interface_id, priority);
------------------------------------------------------------------------
-- 10. Settings (Key-Value)
------------------------------------------------------------------------
CREATE TABLE settings (
key TEXT PRIMARY KEY NOT NULL,
value TEXT NOT NULL,
is_secret INTEGER NOT NULL DEFAULT 0,
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
);
------------------------------------------------------------------------
-- 11. Audit Events (Append-only)
------------------------------------------------------------------------
CREATE TABLE audit_events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_type TEXT NOT NULL,
actor TEXT NOT NULL DEFAULT 'admin',
resource_type TEXT,
resource_id TEXT,
message TEXT,
metadata TEXT,
ip_address TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_audit_created_at ON audit_events(created_at);
CREATE INDEX idx_audit_event_type ON audit_events(event_type);
CREATE INDEX idx_audit_resource ON audit_events(resource_type, resource_id);
------------------------------------------------------------------------
-- 12. Backups (Metadata)
------------------------------------------------------------------------
CREATE TABLE backups (
id TEXT PRIMARY KEY,
filename TEXT NOT NULL,
size INTEGER NOT NULL,
checksum TEXT NOT NULL,
encrypted INTEGER NOT NULL DEFAULT 0,
schema_version TEXT NOT NULL,
description TEXT,
created_at TEXT NOT NULL DEFAULT (datetime('now'))
);
CREATE INDEX idx_backups_created_at ON backups(created_at);
@@ -0,0 +1,7 @@
-- 0002_wiregui_capabilities.sql
-- Add peer-specific firewall association and structured port semantics
ALTER TABLE firewall_rules ADD COLUMN peer_id TEXT REFERENCES peers(id) ON DELETE CASCADE;
ALTER TABLE firewall_rules ADD COLUMN port_range TEXT;
CREATE INDEX IF NOT EXISTS idx_firewall_peer_id ON firewall_rules(peer_id);
@@ -0,0 +1,38 @@
-- 0003_client_profiles.sql
-- Client Environment and MTU Profile System
CREATE TABLE IF NOT EXISTS client_profiles (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
provider TEXT,
device TEXT CHECK (device IS NULL OR device IN ('android', 'ios', 'linux', 'windows', 'macos', 'other')),
connection_type TEXT NOT NULL CHECK (connection_type IN ('web', 'mobile', 'wifi', 'wired', 'other')),
nat_type TEXT NOT NULL DEFAULT 'unknown' CHECK (nat_type IN ('direct', 'cgnat', 'unknown')),
mtu INTEGER NOT NULL CHECK (mtu >= 1280 AND mtu <= 9000),
dns TEXT,
persistent_keepalive INTEGER CHECK (persistent_keepalive IS NULL OR (persistent_keepalive >= 0 AND persistent_keepalive <= 65535)),
is_builtin BOOLEAN NOT NULL DEFAULT 0,
description TEXT,
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_client_profiles_provider ON client_profiles(provider);
CREATE INDEX IF NOT EXISTS idx_client_profiles_device ON client_profiles(device);
CREATE INDEX IF NOT EXISTS idx_client_profiles_connection ON client_profiles(connection_type);
CREATE INDEX IF NOT EXISTS idx_client_profiles_nat ON client_profiles(nat_type);
-- Insert authoritative built-in client profiles
INSERT OR IGNORE INTO client_profiles (id, name, provider, device, connection_type, nat_type, mtu, dns, persistent_keepalive, is_builtin, description, created_at, updated_at)
VALUES
('default-mobile', 'Default Mobile', NULL, NULL, 'mobile', 'unknown', 1280, NULL, 25, 1, 'Standard mobile carrier profile with 1280 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('default-cgnat', 'Default CGNAT', NULL, NULL, 'other', 'cgnat', 1360, NULL, 25, 1, 'Carrier-grade NAT environment profile with 1360 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('default-wifi', 'Default Wi-Fi', NULL, NULL, 'wifi', 'unknown', 1420, NULL, 25, 1, 'Standard Wi-Fi wireless profile with 1420 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('default-web', 'Default Web', NULL, NULL, 'web', 'unknown', 1420, NULL, 25, 1, 'Standard Web client profile with 1420 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('default-wired', 'Default Wired', NULL, NULL, 'wired', 'direct', 1420, NULL, 25, 1, 'High-throughput wired Ethernet profile with 1420 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('android-mobile', 'Android Mobile', NULL, 'android', 'mobile', 'unknown', 1280, NULL, 25, 1, 'Android cellular client profile with 1280 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('ios-mobile', 'iOS Mobile', NULL, 'ios', 'mobile', 'unknown', 1280, NULL, 25, 1, 'Apple iOS cellular profile with 1280 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('tmobile-mobile', 'T-Mobile Mobile', 'tmobile', NULL, 'mobile', 'cgnat', 1280, NULL, 25, 1, 'T-Mobile US IPv6/CGNAT mobile profile with 1280 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('verizon-mobile', 'Verizon Mobile', 'verizon', NULL, 'mobile', 'cgnat', 1280, NULL, 25, 1, 'Verizon Wireless mobile profile with 1280 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('jio-mobile', 'Jio Mobile', 'jio', NULL, 'mobile', 'cgnat', 1280, NULL, 25, 1, 'Reliance Jio 4G/5G mobile profile with 1280 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('starlink-cgnat', 'Starlink CGNAT', 'starlink', NULL, 'other', 'cgnat', 1360, NULL, 25, 1, 'Starlink satellite CGNAT profile with 1360 MTU and 25s keepalive', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);