diff --git a/lib/services/sync/r2_upload_service.dart b/lib/services/sync/r2_upload_service.dart index ea61753..986e095 100644 --- a/lib/services/sync/r2_upload_service.dart +++ b/lib/services/sync/r2_upload_service.dart @@ -29,11 +29,11 @@ class R2UploadService { Future uploadTelemetryBundle({required String idToken, required String remoteRideId, required Uint8List zipBytes, required String sha256Hash, required String appVersion, Duration timeout = const Duration(seconds: 45)}) async { if (idToken.trim().isEmpty) return const R2UploadResult.authRequired('Firebase ID token is required for R2 upload.'); - if (zipBytes.isEmpty) return const R2UploadResult.permanentFailure('Telemetry bundle is empty.'); + if (zipBytes.isEmpty) return const R2UploadResult.permanentFailure('Telemetry bundle is empty.', statusCode: 400); // Prevent path traversal at the client boundary. The Worker remains the // authoritative verifier of SHA-256 and Firebase UID ownership. - if (!RegExp(r'^ride_[A-Za-z0-9_-]+$').hasMatch(remoteRideId)) return const R2UploadResult.permanentFailure('Invalid remote ride identifier.'); - if (sha256Hash.trim().isEmpty) return const R2UploadResult.permanentFailure('Telemetry bundle SHA-256 is required.'); + if (!RegExp(r'^ride_[A-Za-z0-9_-]+$').hasMatch(remoteRideId)) return const R2UploadResult.permanentFailure('Invalid remote ride identifier.', statusCode: 400); + if (sha256Hash.trim().isEmpty) return const R2UploadResult.permanentFailure('Telemetry bundle SHA-256 is required.', statusCode: 400); try { final response = await _client.put(Uri.parse('$_workerBaseUrl/r2/upload'), headers: {