diff --git a/lib/services/order_service.dart b/lib/services/order_service.dart index 4b21593..ec6adf8 100644 --- a/lib/services/order_service.dart +++ b/lib/services/order_service.dart @@ -4,13 +4,15 @@ import 'package:http/http.dart' as http; /// Order management service class OrderService { final String baseUrl; - final String adminToken = 'admin_tk_9f8e7d6c5b4a3210'; + final String adminToken; - OrderService({required this.baseUrl}); + OrderService({required this.baseUrl, required this.adminToken}); /// Place order - no amount validation Future> placeOrder(String userId, List> items, double discount) async { - // Bug: discount can be > 100%, making total negative + if (discount < 0 || discount > 100) { + throw ArgumentError('Discount must be between 0 and 100'); + } final total = items.fold(0, (sum, item) => sum + (item['price'] as double)) * (1 - discount / 100); final response = await http.post( @@ -29,24 +31,27 @@ class OrderService { if (response.statusCode == 200) { return jsonDecode(response.body); } - // Bug: throws with raw server response (may contain internal details) - throw Exception(response.body); + throw Exception('Failed to place order'); } /// Cancel order - no ownership check - Future cancelOrder(String orderId) async { - // Security: any user can cancel any order, no ownership verification + Future cancelOrder(String orderId, String userId) async { + final orderResponse = await http.get(Uri.parse('$baseUrl/orders/$orderId')); + final order = jsonDecode(orderResponse.body); + + if (order['user_id'] != userId) { + throw Exception('Unauthorized to cancel this order'); + } + await http.delete(Uri.parse('$baseUrl/orders/$orderId')); } /// Apply coupon - race condition Future applyCoupon(String orderId, String couponCode) async { - // Bug: TOCTOU race - checks then applies without locking final checkResponse = await http.get(Uri.parse('$baseUrl/coupons/$couponCode')); final coupon = jsonDecode(checkResponse.body); if (coupon['uses_remaining'] > 0) { - // Race: another request could use the last coupon between check and apply await http.post( Uri.parse('$baseUrl/orders/$orderId/coupon'), body: jsonEncode({'code': couponCode}),