@@ -86,7 +86,7 @@ class DomainSchema(Schema):
8686def init_db ():
8787 # Create data directory if it doesn't exist
8888 data_dir = os .path .dirname (DATABASE_PATH )
89- if not os .path .exists (data_dir ):
89+ if data_dir and not os .path .exists (data_dir ):
9090 os .makedirs (data_dir , exist_ok = True )
9191
9292 conn = sqlite3 .connect (DATABASE_PATH )
@@ -1354,6 +1354,52 @@ def signal_handler(sig, frame):
13541354except Exception as e :
13551355 logger .error (f"Error applying initial settings: { str (e )} " )
13561356
1357+ @app .route ('/api/logs' , methods = ['GET' ])
1358+ @auth .login_required
1359+ def get_logs ():
1360+ """Get proxy logs with pagination and sorting"""
1361+ try :
1362+ # Get query parameters
1363+ limit = request .args .get ('limit' , 25 , type = int )
1364+ offset = request .args .get ('offset' , 0 , type = int )
1365+ sort_by = request .args .get ('sort' , 'timestamp' )
1366+ order = request .args .get ('order' , 'desc' )
1367+
1368+ # Validate sort column to prevent SQL injection
1369+ valid_columns = ['timestamp' , 'source_ip' , 'destination' , 'status' , 'bytes' , 'method' ]
1370+ if sort_by not in valid_columns :
1371+ sort_by = 'timestamp'
1372+
1373+ # Validate order
1374+ if order .lower () not in ['asc' , 'desc' ]:
1375+ order = 'desc'
1376+
1377+ conn = get_db ()
1378+ cursor = conn .cursor ()
1379+
1380+ # Get total count
1381+ cursor .execute ("SELECT COUNT(*) FROM proxy_logs" )
1382+ total_count = cursor .fetchone ()[0 ]
1383+
1384+ # Get logs
1385+ query = f"SELECT * FROM proxy_logs ORDER BY { sort_by } { order .upper ()} LIMIT ? OFFSET ?"
1386+ cursor .execute (query , (limit , offset ))
1387+
1388+ logs = [dict (row ) for row in cursor .fetchall ()]
1389+
1390+ return jsonify ({
1391+ "status" : "success" ,
1392+ "data" : logs ,
1393+ "pagination" : {
1394+ "total" : total_count ,
1395+ "limit" : limit ,
1396+ "offset" : offset
1397+ }
1398+ })
1399+ except Exception as e :
1400+ logger .error (f"Error fetching logs: { str (e )} " )
1401+ return jsonify ({"status" : "error" , "message" : "Failed to fetch logs" }), 500
1402+
13571403@app .route ('/api/logs/stats' , methods = ['GET' ])
13581404@auth .login_required
13591405def get_log_stats ():
@@ -3016,7 +3062,7 @@ def client_statistics():
30163062 WHERE source_ip IS NOT NULL AND source_ip != ''
30173063 GROUP BY source_ip
30183064 ORDER BY requests DESC
3019- LIMIT 50 # Limit to top 50 clients for performance
3065+ LIMIT 50
30203066 """ )
30213067 clients = [dict (row ) for row in cursor .fetchall ()]
30223068
@@ -3055,7 +3101,7 @@ def domain_statistics():
30553101 WHERE destination IS NOT NULL AND destination != ''
30563102 GROUP BY destination
30573103 ORDER BY requests DESC
3058- LIMIT 50 # Limit to top 50 domains for performance
3104+ LIMIT 50
30593105 """ )
30603106 domains_raw = [dict (row ) for row in cursor .fetchall ()]
30613107
0 commit comments