import 'dart:convert'; import 'dart:io'; import 'package:supabase/supabase.dart'; import 'package:waylume_server/config/supabase_config.dart'; class VpnSessionService { /// Detects existing VPN sessions for this server and prints their IDs with keepalive info static Future detectSessions() async { try { final serverId = fromEnivronment('SERVER_ID'); if (serverId == null) { print('ERROR: SERVER_ID environment variable not set'); return; } // Get all sessions for this server with peer info final sessions = await SUPABASE_CLIENT .from('vpn_sessions') .select('id, peer_info') .eq('server_id', serverId); if (sessions.isEmpty) { print('No VPN sessions found for server: $serverId'); } else { print('Found ${sessions.length} VPN sessions for server: $serverId'); for (final session in sessions) { final sessionId = session['id']; final peerInfo = session['peer_info']; if (peerInfo != null && peerInfo['public_key'] != null) { final publicKey = peerInfo['public_key'] as String; final keepaliveInfo = await _getKeepaliveForPeer(publicKey); print('Session ID: $sessionId - Peer: ${publicKey.substring(0, 8)}... - $keepaliveInfo'); } else { print('Session ID: $sessionId - No peer info available'); } } } } catch (e) { print('Error detecting sessions: $e'); } } /// Gets keepalive info for a specific peer static Future _getKeepaliveForPeer(String publicKey) async { try { final result = await Process.run('wg', ['show', 'wg0', 'dump']); if (result.exitCode != 0) { return 'Failed to get WireGuard info'; } final lines = result.stdout.toString().trim().split('\n'); // Skip first line (server info) and look for this peer for (int i = 1; i < lines.length; i++) { final line = lines[i].trim(); if (line.isEmpty) continue; final parts = line.split('\t'); if (parts.length >= 5 && parts[0] == publicKey) { final latestHandshake = parts[4]; final handshakeTime = int.tryParse(latestHandshake) ?? 0; if (handshakeTime == 0) { return 'No handshake yet'; } else { final handshakeDateTime = DateTime.fromMillisecondsSinceEpoch(handshakeTime * 1000); final now = DateTime.now(); final timeSince = now.difference(handshakeDateTime); return 'Last keepalive ${timeSince.inSeconds}s ago'; } } } return 'Peer not found in WireGuard'; } catch (e) { return 'Error checking keepalive: $e'; } } }