Implement authentication middleware and rolling codes service for secure API access

This commit is contained in:
ImBenji
2025-08-19 20:30:43 +01:00
parent f829bd5fe1
commit 17091bcc95
4 changed files with 380 additions and 44 deletions

View File

@@ -7,22 +7,91 @@ import 'package:waylume_server/wireguard/utils.dart';
import 'package:waylume_server/core/utils.dart';
import 'package:waylume_server/services/vpn_session_service.dart';
import 'package:waylume_server/services/bandwidth_service.dart';
import 'package:waylume_server/services/rolling_codes_service.dart';
class PeerRoutes {
Router get router {
final router = Router();
router.get('/peers', _getPeers);
router.post('/peer', _createPeer);
router.delete('/peer/<publicKey>', _deletePeer);
router.get('/peer/<publicKey>/config', _getPeerConfig);
router.patch('/peer/<publicKey>/speed-limit', _setSpeedLimit);
router.patch('/peer/<publicKey>/data-cap', _setDataCap);
router.get('/bandwidth-stats', _getBandwidthStats);
router.get('/peers', _authMiddleware(_getPeers));
router.post('/peer', _authMiddleware(_createPeer));
router.delete('/peer/<publicKey>', _authMiddleware(_deletePeer));
router.get('/peer/<publicKey>/config', _authMiddleware(_getPeerConfig));
router.patch('/peer/<publicKey>/speed-limit', _authMiddleware(_setSpeedLimit));
router.patch('/peer/<publicKey>/data-cap', _authMiddleware(_setDataCap));
router.get('/bandwidth-stats', _authMiddleware(_getBandwidthStats));
return router;
}
/// Authentication middleware for API endpoints
Handler _authMiddleware(Handler handler) {
return (Request request) async {
try {
// Check if server is registered
if (!RollingCodesService.isRegistered) {
return Response(401,
body: jsonEncode({
'success': false,
'error': 'Server not registered - missing operational seed'
}),
headers: {'Content-Type': 'application/json'}
);
}
// Get authorization header
String? authHeader = request.headers['authorization'];
if (authHeader == null) {
return Response(401,
body: jsonEncode({
'success': false,
'error': 'Authorization header required'
}),
headers: {'Content-Type': 'application/json'}
);
}
// Validate WaylumeAuth format
if (!authHeader.startsWith('WaylumeAuth ')) {
return Response(401,
body: jsonEncode({
'success': false,
'error': 'Invalid authorization format - expected WaylumeAuth'
}),
headers: {'Content-Type': 'application/json'}
);
}
// Extract auth code
String authCode = authHeader.substring('WaylumeAuth '.length);
// Validate rolling code
bool isValid = RollingCodesService.validateOperationalCode(authCode);
if (!isValid) {
return Response(401,
body: jsonEncode({
'success': false,
'error': 'Invalid authentication code'
}),
headers: {'Content-Type': 'application/json'}
);
}
// Authentication successful, proceed to handler
return await handler(request);
} catch (e) {
return Response(500,
body: jsonEncode({
'success': false,
'error': 'Authentication error: $e'
}),
headers: {'Content-Type': 'application/json'}
);
}
};
}
Future<Response> _getPeers(Request request) async {
try {
final statusParam = request.url.queryParameters['status']?.toUpperCase();