From a98e095e105a28b2e0cb3f675f94a0750400e974 Mon Sep 17 00:00:00 2001 From: Dmitrii Iurco Date: Sat, 25 Apr 2026 16:49:10 -0400 Subject: [PATCH] fix: enrich peer dashboard and services API endpoints /api/peer/dashboard now returns live WireGuard stats (online, rx_bytes, tx_bytes, last_handshake, allowed_ips) by calling wireguard_manager. /api/peer/services now returns a structured dict with wireguard, email, caldav, webdav sections containing hostnames and credentials. Fixes 2 failing E2E API tests. Co-Authored-By: Claude Sonnet 4.6 --- api/app.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 5 deletions(-) diff --git a/api/app.py b/api/app.py index 410cf0a..a8ea6fc 100644 --- a/api/app.py +++ b/api/app.py @@ -3057,25 +3057,77 @@ def remove_volume(name): @app.route('/api/peer/dashboard', methods=['GET']) def peer_dashboard(): - """Return basic dashboard info for the authenticated peer.""" + """Return dashboard info for the authenticated peer including live WireGuard stats.""" peer_name = session.get('peer_name') peer = peer_registry.get_peer(peer_name) if peer_name else None if not peer: return jsonify({'error': 'Peer not found'}), 404 + + wg_stats = {'online': None, 'transfer_rx': 0, 'transfer_tx': 0, 'last_handshake': None} + public_key = peer.get('public_key') + if public_key: + try: + wg_stats = wireguard_manager.get_peer_status(public_key) + except Exception: + pass + + peer_ip = peer.get('ip', '') + allowed_ips = f"{peer_ip.split('/')[0]}/32" if peer_ip else '' + return jsonify({ 'peer_name': peer_name, - 'ip': peer.get('ip'), + 'ip': peer_ip, 'service_access': peer.get('service_access', []), + 'online': wg_stats.get('online'), + 'rx_bytes': wg_stats.get('transfer_rx', 0), + 'tx_bytes': wg_stats.get('transfer_tx', 0), + 'last_handshake': wg_stats.get('last_handshake'), + 'allowed_ips': peer.get('allowed_ips', allowed_ips), }) @app.route('/api/peer/services', methods=['GET']) def peer_services(): - """Return the list of services accessible to the authenticated peer.""" + """Return service credentials and access info for the authenticated peer.""" peer_name = session.get('peer_name') peer = peer_registry.get_peer(peer_name) if peer_name else None - services = peer.get('service_access', []) if peer else [] - return jsonify({'services': services}) + if not peer: + return jsonify({'error': 'Peer not found'}), 404 + + domain = _configured_domain() + peer_ip = peer.get('ip', '') + + server_public_key = '' + wg_port = 51820 + try: + server_public_key = wireguard_manager.get_keys().get('public_key', '') + wg_port = config_manager.configs.get('_identity', {}).get('wireguard_port', 51820) + except Exception: + pass + + return jsonify({ + 'wireguard': { + 'ip': peer_ip, + 'server_public_key': server_public_key, + 'endpoint_port': wg_port, + 'dns': '10.0.0.1', + }, + 'email': { + 'username': f'{peer_name}@{domain}', + 'imap_host': f'mail.{domain}', + 'smtp_host': f'mail.{domain}', + 'imap_port': 993, + 'smtp_port': 587, + }, + 'caldav': { + 'url': f'http://radicale.{domain}:5232', + 'username': peer_name, + }, + 'webdav': { + 'url': f'http://webdav.{domain}', + 'username': peer_name, + }, + }) if __name__ == '__main__':