diff --git a/mobile/lib/infrastructure/repositories/user_api.repository.dart b/mobile/lib/infrastructure/repositories/user_api.repository.dart index d21a1b71a6..20049cac23 100644 --- a/mobile/lib/infrastructure/repositories/user_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/user_api.repository.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:typed_data'; import 'package:http/http.dart'; @@ -18,8 +19,34 @@ class UserApiRepository extends ApiRepository { } Future createProfileImage({required String name, required Uint8List data}) async { - final res = await checkNull(_api.createProfileImage(MultipartFile.fromBytes('file', data, filename: name))); - return res.profileImagePath; + // Workaround: the autogenerated OpenAPI client forces `Content-Type: multipart/form-data` + // without a boundary, which can break multer parsing server-side. + // We bypass `UsersApi.createProfileImage()` and send the multipart request directly, + // while still reusing the configured basePath + auth headers + http client. + final apiClient = _api.apiClient; + + final headers = {}; + await apiClient.authentication?.applyToParams([], headers); + headers.addAll(apiClient.defaultHeaderMap); + headers.remove('Content-Type'); + headers.remove('content-type'); + + final filename = name.isNotEmpty ? name : 'profile-picture.png'; + final uri = Uri.parse('${apiClient.basePath}/users/profile-image'); + + final request = MultipartRequest('POST', uri) + ..headers.addAll(headers) + ..files.add(MultipartFile.fromBytes('file', data, filename: filename)); + + final streamed = await apiClient.client.send(request); + final response = await Response.fromStream(streamed); + + if (response.statusCode >= 400) { + throw ApiException(response.statusCode, response.body); + } + + final body = jsonDecode(response.body) as Map; + return body['profileImagePath'] as String; } Future> getAll() async {