diff --git a/.gitignore b/.gitignore
index 96895cd..a65f965 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,6 +17,8 @@ docker-compose.*.yml
.idea
+*.lscache
+
# User-specific files
*.rsuser
*.suo
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index f9b4826..05eb7a8 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -3,39 +3,39 @@
true
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/OpenWish.Application/Services/EventService.cs b/src/OpenWish.Application/Services/EventService.cs
index 57623b2..3468e2d 100644
--- a/src/OpenWish.Application/Services/EventService.cs
+++ b/src/OpenWish.Application/Services/EventService.cs
@@ -799,14 +799,20 @@ public async Task DeleteEventByPublicIdAsync(string publicId)
await DeleteEventAsync(existingEvent.Id);
}
- public async Task AddUserToEventByPublicIdAsync(string eventPublicId, string userId, string role = "Participant")
+ public async Task AddUserToEventByPublicIdAsync(string eventPublicId, string userId, string role, string callerId)
{
using var scope = _scopeFactory.CreateScope();
var context = scope.ServiceProvider.GetRequiredService();
var eventEntity = await context.Events
+ .Include(e => e.CreatedBy)
.FirstOrDefaultAsync(e => e.PublicId == eventPublicId && !e.Deleted)
?? throw new KeyNotFoundException($"Event with publicId {eventPublicId} not found");
+ if (!IsEventOwner(eventEntity, callerId))
+ {
+ throw new UnauthorizedAccessException("Only the event creator can add users to an event.");
+ }
+
return await AddUserToEventAsync(eventEntity.Id, userId, role);
}
diff --git a/src/OpenWish.Application/Services/NotificationService.cs b/src/OpenWish.Application/Services/NotificationService.cs
index 8c33de1..be1e109 100644
--- a/src/OpenWish.Application/Services/NotificationService.cs
+++ b/src/OpenWish.Application/Services/NotificationService.cs
@@ -8,14 +8,15 @@
namespace OpenWish.Application.Services;
-public class NotificationService(ApplicationDbContext context, IMapper mapper) : INotificationService
+public class NotificationService(IDbContextFactory contextFactory, IMapper mapper) : INotificationService
{
- private readonly ApplicationDbContext _context = context;
+ private readonly IDbContextFactory _contextFactory = contextFactory;
private readonly IMapper _mapper = mapper;
public async Task> GetUserNotificationsAsync(string userId, bool includeRead = false)
{
- var query = _context.Notifications
+ await using var context = await _contextFactory.CreateDbContextAsync();
+ var query = context.Notifications
.Include(n => n.User)
.Where(n => n.UserId == userId && !n.Deleted);
@@ -33,12 +34,14 @@ public async Task> GetUserNotificationsAsync(stri
public async Task GetUnreadNotificationCountAsync(string userId)
{
- return await _context.Notifications
+ await using var context = await _contextFactory.CreateDbContextAsync();
+ return await context.Notifications
.CountAsync(n => n.UserId == userId && !n.IsRead && !n.Deleted);
}
public async Task CreateNotificationAsync(string userId, string message)
{
+ await using var context = await _contextFactory.CreateDbContextAsync();
var notification = new Notification
{
UserId = userId,
@@ -49,8 +52,8 @@ public async Task CreateNotificationAsync(string userId, stri
UpdatedOn = DateTimeOffset.UtcNow
};
- _context.Notifications.Add(notification);
- await _context.SaveChangesAsync();
+ context.Notifications.Add(notification);
+ await context.SaveChangesAsync();
return _mapper.Map(notification);
}
@@ -63,6 +66,7 @@ public async Task CreateNotificationAsync(
string type,
NotificationActionModel? action = null)
{
+ await using var context = await _contextFactory.CreateDbContextAsync();
var notification = new Notification
{
UserId = targetUserId,
@@ -77,15 +81,16 @@ public async Task CreateNotificationAsync(
UpdatedOn = DateTimeOffset.UtcNow
};
- _context.Notifications.Add(notification);
- await _context.SaveChangesAsync();
+ context.Notifications.Add(notification);
+ await context.SaveChangesAsync();
return _mapper.Map(notification);
}
public async Task MarkNotificationAsReadAsync(int notificationId)
{
- var notification = await _context.Notifications.FindAsync(notificationId);
+ await using var context = await _contextFactory.CreateDbContextAsync();
+ var notification = await context.Notifications.FindAsync(notificationId);
if (notification == null || notification.Deleted)
{
@@ -95,13 +100,14 @@ public async Task MarkNotificationAsReadAsync(int notificationId)
notification.IsRead = true;
notification.UpdatedOn = DateTimeOffset.UtcNow;
- await _context.SaveChangesAsync();
+ await context.SaveChangesAsync();
return true;
}
public async Task MarkAllNotificationsAsReadAsync(string userId)
{
- var notifications = await _context.Notifications
+ await using var context = await _contextFactory.CreateDbContextAsync();
+ var notifications = await context.Notifications
.Where(n => n.UserId == userId && !n.IsRead && !n.Deleted)
.ToListAsync();
@@ -116,13 +122,14 @@ public async Task MarkAllNotificationsAsReadAsync(string userId)
notification.UpdatedOn = DateTimeOffset.UtcNow;
}
- await _context.SaveChangesAsync();
+ await context.SaveChangesAsync();
return true;
}
public async Task DeleteNotificationAsync(int notificationId)
{
- var notification = await _context.Notifications.FindAsync(notificationId);
+ await using var context = await _contextFactory.CreateDbContextAsync();
+ var notification = await context.Notifications.FindAsync(notificationId);
if (notification == null)
{
@@ -132,7 +139,7 @@ public async Task DeleteNotificationAsync(int notificationId)
notification.Deleted = true;
notification.UpdatedOn = DateTimeOffset.UtcNow;
- await _context.SaveChangesAsync();
+ await context.SaveChangesAsync();
return true;
}
}
\ No newline at end of file
diff --git a/src/OpenWish.Application/Services/OpenWishEmailSender.cs b/src/OpenWish.Application/Services/OpenWishEmailSender.cs
index 0ca5277..fdfcc1b 100644
--- a/src/OpenWish.Application/Services/OpenWishEmailSender.cs
+++ b/src/OpenWish.Application/Services/OpenWishEmailSender.cs
@@ -114,9 +114,15 @@ public async Task SendEmailAsync(string toEmail, string subject, string message)
.Body(message, true)
.SendAsync();
- _logger.LogInformation(response.Successful
- ? $"Email to {toEmail} queued successfully!"
- : $"Failure sending email to {toEmail}");
+ if (response.Successful)
+ {
+ _logger.LogInformation("Email to {Email} queued successfully!", toEmail);
+ }
+ else
+ {
+ _logger.LogError("Failure sending email to {Email}: {Errors}", toEmail, string.Join(", ", response.ErrorMessages));
+ throw new InvalidOperationException($"Failed to send email to {toEmail}.");
+ }
}
private string WrapInHtmlFormattedEmail(string message)
diff --git a/src/OpenWish.Application/Services/ProductService.cs b/src/OpenWish.Application/Services/ProductService.cs
index f1b659f..82c2e3e 100644
--- a/src/OpenWish.Application/Services/ProductService.cs
+++ b/src/OpenWish.Application/Services/ProductService.cs
@@ -124,12 +124,12 @@ private static async Task IsSafeUrlAsync(Uri uri)
}
catch (HttpRequestException ex)
{
- _logger.LogError(ex, $"Error fetching URL: {ex.Message}");
+ _logger.LogError(ex, "Error fetching URL: {Message}", ex.Message);
return null;
}
catch (Exception ex)
{
- _logger.LogError(ex, $"Error parsing HTML: {ex.Message}");
+ _logger.LogError(ex, "Error parsing HTML: {Message}", ex.Message);
return null;
}
}
diff --git a/src/OpenWish.Application/Services/WishlistService.cs b/src/OpenWish.Application/Services/WishlistService.cs
index a6ca2e0..ab52975 100644
--- a/src/OpenWish.Application/Services/WishlistService.cs
+++ b/src/OpenWish.Application/Services/WishlistService.cs
@@ -3,6 +3,7 @@
using System.Linq;
using AutoMapper;
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Logging;
using OpenWish.Data;
using OpenWish.Data.Entities;
using OpenWish.Shared.Models;
@@ -10,11 +11,12 @@
namespace OpenWish.Application.Services;
-public class WishlistService(IDbContextFactory contextFactory, IMapper mapper, IActivityService activityService) : IWishlistService
+public class WishlistService(IDbContextFactory contextFactory, IMapper mapper, IActivityService activityService, ILogger logger) : IWishlistService
{
private readonly IDbContextFactory _contextFactory = contextFactory;
private readonly IMapper _mapper = mapper;
private readonly IActivityService _activityService = activityService;
+ private readonly ILogger _logger = logger;
public async Task CreateWishlistAsync(WishlistModel wishlistModel, string ownerId)
{
@@ -41,6 +43,8 @@ public async Task CreateWishlistAsync(WishlistModel wishlistModel
var entry = context.Wishlists.Add(wishlistEntity);
await context.SaveChangesAsync();
+ _logger.LogInformation("Wishlist '{Name}' created by user {UserId}", wishlistEntity.Name, ownerId);
+
// Log activity
await _activityService.LogActivityAsync(
ownerId,
@@ -101,6 +105,7 @@ public async Task GetWishlistByPublicIdAsync(string publicId, str
var canAccess = await CanUserAccessWishlistInternalAsync(context, wishlistEntity.Id, userId);
if (!canAccess)
{
+ _logger.LogWarning("Access denied: user {UserId} attempted to access wishlist {PublicId}", userId, publicId);
throw new UnauthorizedAccessException($"Access denied to wishlist {publicId}");
}
}
diff --git a/src/OpenWish.Shared/Services/IEventService.cs b/src/OpenWish.Shared/Services/IEventService.cs
index 6e5cd79..09e1cd7 100644
--- a/src/OpenWish.Shared/Services/IEventService.cs
+++ b/src/OpenWish.Shared/Services/IEventService.cs
@@ -13,7 +13,7 @@ public interface IEventService
Task DeleteEventAsync(int id);
Task DeleteEventByPublicIdAsync(string publicId);
Task AddUserToEventAsync(int eventId, string userId, string role = "Participant");
- Task AddUserToEventByPublicIdAsync(string eventPublicId, string userId, string role = "Participant");
+ Task AddUserToEventByPublicIdAsync(string eventPublicId, string userId, string role, string callerId);
Task RemoveUserFromEventAsync(int eventId, string userId, string requestorId);
Task RemoveUserFromEventByPublicIdAsync(string eventPublicId, string userId, string requestorId);
Task> GetEventWishlistsAsync(int eventId, string? requestingUserId = null);
diff --git a/src/OpenWish.Web.Client/Services/ActivityHttpClientService.cs b/src/OpenWish.Web.Client/Services/ActivityHttpClientService.cs
index 229efc6..6faae4b 100644
--- a/src/OpenWish.Web.Client/Services/ActivityHttpClientService.cs
+++ b/src/OpenWish.Web.Client/Services/ActivityHttpClientService.cs
@@ -18,7 +18,6 @@ public async Task LogActivityAsync(
{
var activity = new
{
- UserId = userId,
ActivityType = activityType,
Description = description,
WishlistId = wishlistId,
@@ -33,13 +32,13 @@ public async Task LogActivityAsync(
public async Task> GetUserActivityFeedAsync(string userId, int count = 20, int skip = 0)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/user/{userId}?count={count}&skip={skip}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/user?count={count}&skip={skip}")
?? Array.Empty();
}
public async Task> GetFriendsActivityFeedAsync(string userId, int count = 20, int skip = 0)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/friends/{userId}?count={count}&skip={skip}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/friends?count={count}&skip={skip}")
?? Array.Empty();
}
diff --git a/src/OpenWish.Web.Client/Services/EventHttpClientService.cs b/src/OpenWish.Web.Client/Services/EventHttpClientService.cs
index 5329461..55ddece 100644
--- a/src/OpenWish.Web.Client/Services/EventHttpClientService.cs
+++ b/src/OpenWish.Web.Client/Services/EventHttpClientService.cs
@@ -183,7 +183,7 @@ public async Task DeleteEventByPublicIdAsync(string publicId)
response.EnsureSuccessStatusCode();
}
- public async Task AddUserToEventByPublicIdAsync(string eventPublicId, string userId, string role = "Participant")
+ public async Task AddUserToEventByPublicIdAsync(string eventPublicId, string userId, string role, string callerId)
{
var request = new { UserId = userId, Role = role };
var response = await httpClient.PostAsJsonAsync($"api/events/{eventPublicId}/users", request);
diff --git a/src/OpenWish.Web.Client/Services/FriendHttpClientService.cs b/src/OpenWish.Web.Client/Services/FriendHttpClientService.cs
index 680a202..9f74dc0 100644
--- a/src/OpenWish.Web.Client/Services/FriendHttpClientService.cs
+++ b/src/OpenWish.Web.Client/Services/FriendHttpClientService.cs
@@ -11,25 +11,25 @@ public class FriendHttpClientService(HttpClient httpClient) : IFriendService
public async Task> GetFriendsAsync(string userId)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/user/{userId}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/user")
?? Array.Empty();
}
public async Task AreFriendsAsync(string userId, string otherUserId)
{
- return await _httpClient.GetFromJsonAsync($"{BaseUrl}/check/{userId}/{otherUserId}");
+ return await _httpClient.GetFromJsonAsync($"{BaseUrl}/check/{otherUserId}");
}
public async Task RemoveFriendAsync(string userId, string friendId)
{
- var response = await _httpClient.DeleteAsync($"{BaseUrl}/{userId}/{friendId}");
+ var response = await _httpClient.DeleteAsync($"{BaseUrl}/{friendId}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
public async Task SendFriendRequestAsync(string requesterId, string receiverId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requesterId}/{receiverId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/request/{receiverId}", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync()
?? throw new HttpRequestException("Failed to send friend request");
@@ -37,33 +37,33 @@ public async Task SendFriendRequestAsync(string requesterId,
public async Task> GetReceivedFriendRequestsAsync(string userId)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/requests/received/{userId}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/requests/received")
?? Array.Empty();
}
public async Task> GetSentFriendRequestsAsync(string userId)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/requests/sent/{userId}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/requests/sent")
?? Array.Empty();
}
public async Task AcceptFriendRequestAsync(int requestId, string userId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/accept/{userId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/accept", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
public async Task RejectFriendRequestAsync(int requestId, string userId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/reject/{userId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/reject", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
public async Task CancelFriendRequestAsync(int requestId, string requesterId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/cancel/{requesterId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/cancel", null);
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return false;
@@ -75,7 +75,7 @@ public async Task CancelFriendRequestAsync(int requestId, string requester
public async Task ResendFriendRequestAsync(int requestId, string requesterId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/resend/{requesterId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/request/{requestId}/resend", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync()
?? throw new HttpRequestException("Failed to resend friend request");
@@ -83,34 +83,34 @@ public async Task ResendFriendRequestAsync(int requestId, st
public async Task SendFriendInviteByEmailAsync(string senderUserId, string emailAddress)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/invite/{senderUserId}?email={Uri.EscapeDataString(emailAddress)}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/invite?email={Uri.EscapeDataString(emailAddress)}", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
public async Task SendFriendInvitesByEmailAsync(string senderUserId, IEnumerable emailAddresses)
{
- var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/invite/{senderUserId}/batch", emailAddresses);
+ var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/invite/batch", emailAddresses);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
public async Task CreateFriendshipFromInviteAsync(string newUserId, string inviterUserId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/invite/complete/{newUserId}/{inviterUserId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/invite/complete/{inviterUserId}", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
public async Task> GetPendingFriendInvitesAsync(string userId)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/pending-invites/{userId}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/pending-invites")
?? Array.Empty();
}
public async Task CancelPendingFriendInviteAsync(int inviteId, string userId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/pending-invite/{inviteId}/cancel/{userId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/pending-invite/{inviteId}/cancel", null);
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return false;
@@ -122,7 +122,7 @@ public async Task CancelPendingFriendInviteAsync(int inviteId, string user
public async Task ResendPendingFriendInviteAsync(int inviteId, string userId)
{
- var response = await _httpClient.PostAsync($"{BaseUrl}/pending-invite/{inviteId}/resend/{userId}", null);
+ var response = await _httpClient.PostAsync($"{BaseUrl}/pending-invite/{inviteId}/resend", null);
if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
{
return false;
diff --git a/src/OpenWish.Web.Client/Services/NotificationHttpClientService.cs b/src/OpenWish.Web.Client/Services/NotificationHttpClientService.cs
index 0bd1020..60cda4b 100644
--- a/src/OpenWish.Web.Client/Services/NotificationHttpClientService.cs
+++ b/src/OpenWish.Web.Client/Services/NotificationHttpClientService.cs
@@ -11,18 +11,18 @@ public class NotificationHttpClientService(HttpClient httpClient) : INotificatio
public async Task> GetUserNotificationsAsync(string userId, bool includeRead = false)
{
- return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/user/{userId}?includeRead={includeRead}")
+ return await _httpClient.GetFromJsonAsync>($"{BaseUrl}/user?includeRead={includeRead}")
?? Array.Empty();
}
public async Task GetUnreadNotificationCountAsync(string userId)
{
- return await _httpClient.GetFromJsonAsync($"{BaseUrl}/user/{userId}/count");
+ return await _httpClient.GetFromJsonAsync($"{BaseUrl}/count");
}
public async Task CreateNotificationAsync(string userId, string message)
{
- var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/user/{userId}", message);
+ var response = await _httpClient.PostAsJsonAsync(BaseUrl, message);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync()
?? throw new HttpRequestException("Failed to create notification");
@@ -38,7 +38,6 @@ public async Task CreateNotificationAsync(
{
var notificationData = new
{
- SenderUserId = senderUserId,
Title = title,
Message = message,
Type = type,
@@ -60,7 +59,7 @@ public async Task MarkNotificationAsReadAsync(int notificationId)
public async Task MarkAllNotificationsAsReadAsync(string userId)
{
- var response = await _httpClient.PutAsync($"{BaseUrl}/user/{userId}/read-all", null);
+ var response = await _httpClient.PutAsync($"{BaseUrl}/read-all", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
diff --git a/src/OpenWish.Web.Client/Services/WishlistHttpClientService.cs b/src/OpenWish.Web.Client/Services/WishlistHttpClientService.cs
index f8217db..ede6c05 100644
--- a/src/OpenWish.Web.Client/Services/WishlistHttpClientService.cs
+++ b/src/OpenWish.Web.Client/Services/WishlistHttpClientService.cs
@@ -132,10 +132,9 @@ public async Task CanUserEditWishlistAsync(int wishlistId, string userId)
return await _httpClient.GetFromJsonAsync($"{BaseUrl}/{wishlistId}/can-edit/{userId}");
}
- // Item comments
public async Task AddCommentToItemAsync(int wishlistId, int itemId, string userId, string text)
{
- var commentRequest = new { userId, text };
+ var commentRequest = new { text };
var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/{wishlistId}/items/{itemId}/comments", commentRequest);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
@@ -148,7 +147,7 @@ public async Task> GetItemCommentsAsync(int wishli
public async Task RemoveItemCommentAsync(int commentId, string userId)
{
- var response = await _httpClient.DeleteAsync($"{BaseUrl}/comments/{commentId}?userId={userId}");
+ var response = await _httpClient.DeleteAsync($"{BaseUrl}/comments/{commentId}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
@@ -156,7 +155,7 @@ public async Task RemoveItemCommentAsync(int commentId, string userId)
// Item reservations
public async Task ReserveItemAsync(int wishlistId, int itemId, string userId, bool isAnonymous = false)
{
- var reservationRequest = new { userId, isAnonymous };
+ var reservationRequest = new { isAnonymous };
var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/{wishlistId}/items/{itemId}/reserve", reservationRequest);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
@@ -164,7 +163,7 @@ public async Task ReserveItemAsync(int wishlistId, int itemId, string user
public async Task CancelReservationAsync(int wishlistId, int itemId, string userId)
{
- var response = await _httpClient.DeleteAsync($"{BaseUrl}/{wishlistId}/items/{itemId}/reservation?userId={userId}");
+ var response = await _httpClient.DeleteAsync($"{BaseUrl}/{wishlistId}/items/{itemId}/reservation");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
}
@@ -276,7 +275,7 @@ public async Task UpdateWishlistItemByPublicIdAsync(string wi
public async Task AddCommentToItemByPublicIdAsync(string wishlistPublicId, int itemId, string userId, string text)
{
- var request = new { UserId = userId, Text = text };
+ var request = new { Text = text };
var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/{wishlistPublicId}/items/{itemId}/comments", request);
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync();
@@ -289,14 +288,14 @@ public async Task> GetItemCommentsByPublicIdAsync(
public async Task ReserveItemByPublicIdAsync(string wishlistPublicId, int itemId, string userId, bool isAnonymous = false)
{
- var request = new { UserId = userId, IsAnonymous = isAnonymous };
+ var request = new { IsAnonymous = isAnonymous };
var response = await _httpClient.PostAsJsonAsync($"{BaseUrl}/{wishlistPublicId}/items/{itemId}/reserve", request);
return response.IsSuccessStatusCode;
}
public async Task CancelReservationByPublicIdAsync(string wishlistPublicId, int itemId, string userId)
{
- var response = await _httpClient.DeleteAsync($"{BaseUrl}/{wishlistPublicId}/items/{itemId}/reservation?userId={userId}");
+ var response = await _httpClient.DeleteAsync($"{BaseUrl}/{wishlistPublicId}/items/{itemId}/reservation");
return response.IsSuccessStatusCode;
}
diff --git a/src/OpenWish.Web/Controllers/ActivityController.cs b/src/OpenWish.Web/Controllers/ActivityController.cs
index 46fa111..dee62b8 100644
--- a/src/OpenWish.Web/Controllers/ActivityController.cs
+++ b/src/OpenWish.Web/Controllers/ActivityController.cs
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using OpenWish.Shared.Services;
+using OpenWish.Web.Services;
namespace OpenWish.Web.Controllers;
@@ -10,22 +11,28 @@ namespace OpenWish.Web.Controllers;
public class ActivityController : ControllerBase
{
private readonly IActivityService _activityService;
+ private readonly ApiUserContextService _userContextService;
- public ActivityController(IActivityService activityService)
+ public ActivityController(IActivityService activityService, ApiUserContextService userContextService)
{
_activityService = activityService;
+ _userContextService = userContextService;
}
- [HttpGet("user/{userId}")]
- public async Task GetUserActivities(string userId, [FromQuery] int count = 20, [FromQuery] int skip = 0)
+ [HttpGet("user")]
+ public async Task GetUserActivities([FromQuery] int count = 20, [FromQuery] int skip = 0)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var activities = await _activityService.GetUserActivityFeedAsync(userId, count, skip);
return Ok(activities);
}
- [HttpGet("friends/{userId}")]
- public async Task GetFriendsActivities(string userId, [FromQuery] int count = 20, [FromQuery] int skip = 0)
+ [HttpGet("friends")]
+ public async Task GetFriendsActivities([FromQuery] int count = 20, [FromQuery] int skip = 0)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var activities = await _activityService.GetFriendsActivityFeedAsync(userId, count, skip);
return Ok(activities);
}
@@ -40,8 +47,10 @@ public async Task GetWishlistActivities(int wishlistId, [FromQuer
[HttpPost]
public async Task LogActivity([FromBody] ActivityLogRequest request)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var activity = await _activityService.LogActivityAsync(
- request.UserId,
+ userId,
request.ActivityType,
request.Description,
request.WishlistId,
@@ -52,7 +61,6 @@ public async Task LogActivity([FromBody] ActivityLogRequest reque
public class ActivityLogRequest
{
- public string UserId { get; set; }
public string ActivityType { get; set; }
public string Description { get; set; }
public int? WishlistId { get; set; }
diff --git a/src/OpenWish.Web/Controllers/EventController.cs b/src/OpenWish.Web/Controllers/EventController.cs
index 2bec5bb..e5ba37f 100644
--- a/src/OpenWish.Web/Controllers/EventController.cs
+++ b/src/OpenWish.Web/Controllers/EventController.cs
@@ -85,12 +85,21 @@ public async Task DeleteEvent(string publicId)
[HttpPost("{eventPublicId}/users")]
public async Task AddUserToEvent(string eventPublicId, [FromBody] AddUserToEventRequest request)
{
- var result = await _eventService.AddUserToEventByPublicIdAsync(eventPublicId, request.UserId, request.Role);
- if (!result)
+ var callerId = await _userContextService.GetUserIdAsync();
+ if (callerId is null) return Unauthorized();
+ try
{
- return NotFound();
+ var result = await _eventService.AddUserToEventByPublicIdAsync(eventPublicId, request.UserId, request.Role, callerId);
+ if (!result)
+ {
+ return NotFound();
+ }
+ return NoContent();
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ return Forbid(ex.Message);
}
- return NoContent();
}
[HttpDelete("{eventPublicId}/users/{userId}")]
diff --git a/src/OpenWish.Web/Controllers/FriendController.cs b/src/OpenWish.Web/Controllers/FriendController.cs
index fdd1a59..0411753 100644
--- a/src/OpenWish.Web/Controllers/FriendController.cs
+++ b/src/OpenWish.Web/Controllers/FriendController.cs
@@ -19,72 +19,99 @@ public FriendController(IFriendService friendService, IUserContextService userCo
_userContextService = userContextService;
}
- [HttpGet("user/{userId}")]
- public async Task GetFriends(string userId)
+ [HttpGet("user")]
+ public async Task GetFriends()
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var friends = await _friendService.GetFriendsAsync(userId);
return Ok(friends);
}
- [HttpGet("check/{userId}/{otherUserId}")]
- public async Task CheckFriendship(string userId, string otherUserId)
+ [HttpGet("check/{otherUserId}")]
+ public async Task CheckFriendship(string otherUserId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var areFriends = await _friendService.AreFriendsAsync(userId, otherUserId);
return Ok(areFriends);
}
- [HttpDelete("{userId}/{friendId}")]
- public async Task RemoveFriend(string userId, string friendId)
+ [HttpDelete("{friendId}")]
+ public async Task RemoveFriend(string friendId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _friendService.RemoveFriendAsync(userId, friendId);
return Ok(result);
}
- [HttpPost("request/{requesterId}/{receiverId}")]
- public async Task SendFriendRequest(string requesterId, string receiverId)
+ [HttpPost("request/{receiverId}")]
+ public async Task SendFriendRequest(string receiverId)
{
- var request = await _friendService.SendFriendRequestAsync(requesterId, receiverId);
- return Ok(request);
+ var requesterId = await _userContextService.GetUserIdAsync();
+ if (requesterId is null) return Unauthorized();
+ try
+ {
+ var request = await _friendService.SendFriendRequestAsync(requesterId, receiverId);
+ return Ok(request);
+ }
+ catch (InvalidOperationException ex)
+ {
+ return BadRequest(ex.Message);
+ }
}
- [HttpGet("requests/received/{userId}")]
- public async Task GetReceivedRequests(string userId)
+ [HttpGet("requests/received")]
+ public async Task GetReceivedRequests()
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var requests = await _friendService.GetReceivedFriendRequestsAsync(userId);
return Ok(requests);
}
- [HttpGet("requests/sent/{userId}")]
- public async Task GetSentRequests(string userId)
+ [HttpGet("requests/sent")]
+ public async Task GetSentRequests()
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var requests = await _friendService.GetSentFriendRequestsAsync(userId);
return Ok(requests);
}
- [HttpPost("request/{requestId}/accept/{userId}")]
- public async Task AcceptRequest(int requestId, string userId)
+ [HttpPost("request/{requestId}/accept")]
+ public async Task AcceptRequest(int requestId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _friendService.AcceptFriendRequestAsync(requestId, userId);
return Ok(result);
}
- [HttpPost("request/{requestId}/reject/{userId}")]
- public async Task RejectRequest(int requestId, string userId)
+ [HttpPost("request/{requestId}/reject")]
+ public async Task RejectRequest(int requestId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _friendService.RejectFriendRequestAsync(requestId, userId);
return Ok(result);
}
- [HttpPost("request/{requestId}/cancel/{userId}")]
- public async Task CancelRequest(int requestId, string userId)
+ [HttpPost("request/{requestId}/cancel")]
+ public async Task CancelRequest(int requestId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _friendService.CancelFriendRequestAsync(requestId, userId);
return result ? Ok(true) : NotFound();
}
- [HttpPost("request/{requestId}/resend/{userId}")]
- public async Task ResendRequest(int requestId, string userId)
+ [HttpPost("request/{requestId}/resend")]
+ public async Task ResendRequest(int requestId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
try
{
var updatedRequest = await _friendService.ResendFriendRequestAsync(requestId, userId);
@@ -96,9 +123,11 @@ public async Task ResendRequest(int requestId, string userId)
}
}
- [HttpPost("invite/{senderUserId}")]
- public async Task SendFriendInviteByEmail(string senderUserId, [FromQuery] string email)
+ [HttpPost("invite")]
+ public async Task SendFriendInviteByEmail([FromQuery] string email)
{
+ var senderUserId = await _userContextService.GetUserIdAsync();
+ if (senderUserId is null) return Unauthorized();
try
{
var result = await _friendService.SendFriendInviteByEmailAsync(senderUserId, email);
@@ -110,9 +139,11 @@ public async Task SendFriendInviteByEmail(string senderUserId, [F
}
}
- [HttpPost("invite/{senderUserId}/batch")]
- public async Task SendFriendInvitesByEmail(string senderUserId, [FromBody] List emails)
+ [HttpPost("invite/batch")]
+ public async Task SendFriendInvitesByEmail([FromBody] List emails)
{
+ var senderUserId = await _userContextService.GetUserIdAsync();
+ if (senderUserId is null) return Unauthorized();
try
{
var result = await _friendService.SendFriendInvitesByEmailAsync(senderUserId, emails);
@@ -124,9 +155,11 @@ public async Task SendFriendInvitesByEmail(string senderUserId, [
}
}
- [HttpPost("invite/complete/{newUserId}/{inviterUserId}")]
- public async Task CreateFriendshipFromInvite(string newUserId, string inviterUserId)
+ [HttpPost("invite/complete/{inviterUserId}")]
+ public async Task CreateFriendshipFromInvite(string inviterUserId)
{
+ var newUserId = await _userContextService.GetUserIdAsync();
+ if (newUserId is null) return Unauthorized();
try
{
var result = await _friendService.CreateFriendshipFromInviteAsync(newUserId, inviterUserId);
@@ -138,23 +171,29 @@ public async Task CreateFriendshipFromInvite(string newUserId, st
}
}
- [HttpGet("pending-invites/{userId}")]
- public async Task GetPendingFriendInvites(string userId)
+ [HttpGet("pending-invites")]
+ public async Task GetPendingFriendInvites()
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var invites = await _friendService.GetPendingFriendInvitesAsync(userId);
return Ok(invites);
}
- [HttpPost("pending-invite/{inviteId}/cancel/{userId}")]
- public async Task CancelPendingFriendInvite(int inviteId, string userId)
+ [HttpPost("pending-invite/{inviteId}/cancel")]
+ public async Task CancelPendingFriendInvite(int inviteId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _friendService.CancelPendingFriendInviteAsync(inviteId, userId);
return result ? Ok(true) : NotFound();
}
- [HttpPost("pending-invite/{inviteId}/resend/{userId}")]
- public async Task ResendPendingFriendInvite(int inviteId, string userId)
+ [HttpPost("pending-invite/{inviteId}/resend")]
+ public async Task ResendPendingFriendInvite(int inviteId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _friendService.ResendPendingFriendInviteAsync(inviteId, userId);
return result ? Ok(true) : NotFound();
}
diff --git a/src/OpenWish.Web/Controllers/NotificationController.cs b/src/OpenWish.Web/Controllers/NotificationController.cs
index 082fbb5..37c6d44 100644
--- a/src/OpenWish.Web/Controllers/NotificationController.cs
+++ b/src/OpenWish.Web/Controllers/NotificationController.cs
@@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Mvc;
using OpenWish.Shared.Models;
using OpenWish.Shared.Services;
+using OpenWish.Web.Services;
namespace OpenWish.Web.Controllers;
@@ -11,29 +12,37 @@ namespace OpenWish.Web.Controllers;
public class NotificationController : ControllerBase
{
private readonly INotificationService _notificationService;
+ private readonly ApiUserContextService _userContextService;
- public NotificationController(INotificationService notificationService)
+ public NotificationController(INotificationService notificationService, ApiUserContextService userContextService)
{
_notificationService = notificationService;
+ _userContextService = userContextService;
}
- [HttpGet("user/{userId}")]
- public async Task GetUserNotifications(string userId, [FromQuery] bool includeRead = false)
+ [HttpGet("user")]
+ public async Task GetUserNotifications([FromQuery] bool includeRead = false)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var notifications = await _notificationService.GetUserNotificationsAsync(userId, includeRead);
return Ok(notifications);
}
- [HttpGet("user/{userId}/count")]
- public async Task GetUnreadNotificationCount(string userId)
+ [HttpGet("count")]
+ public async Task GetUnreadNotificationCount()
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var count = await _notificationService.GetUnreadNotificationCountAsync(userId);
return Ok(count);
}
- [HttpPost("user/{userId}")]
- public async Task CreateNotification(string userId, [FromBody] string message)
+ [HttpPost]
+ public async Task CreateNotification([FromBody] string message)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var notification = await _notificationService.CreateNotificationAsync(userId, message);
return Ok(notification);
}
@@ -41,8 +50,10 @@ public async Task CreateNotification(string userId, [FromBody] st
[HttpPost("user/{targetUserId}/detailed")]
public async Task CreateDetailedNotification(string targetUserId, [FromBody] DetailedNotificationRequest request)
{
+ var senderUserId = await _userContextService.GetUserIdAsync();
+ if (senderUserId is null) return Unauthorized();
var notification = await _notificationService.CreateNotificationAsync(
- request.SenderUserId,
+ senderUserId,
targetUserId,
request.Title,
request.Message,
@@ -59,9 +70,11 @@ public async Task MarkAsRead(int notificationId)
return Ok(result);
}
- [HttpPut("user/{userId}/read-all")]
- public async Task MarkAllAsRead(string userId)
+ [HttpPut("read-all")]
+ public async Task MarkAllAsRead()
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _notificationService.MarkAllNotificationsAsReadAsync(userId);
return Ok(result);
}
@@ -76,7 +89,6 @@ public async Task DeleteNotification(int notificationId)
public class DetailedNotificationRequest
{
- public string SenderUserId { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string Message { get; set; } = string.Empty;
public string Type { get; set; } = string.Empty;
diff --git a/src/OpenWish.Web/Controllers/WishlistController.cs b/src/OpenWish.Web/Controllers/WishlistController.cs
index d874cb1..74fd1fa 100644
--- a/src/OpenWish.Web/Controllers/WishlistController.cs
+++ b/src/OpenWish.Web/Controllers/WishlistController.cs
@@ -59,12 +59,16 @@ public async Task> CreateWishlist(WishlistModel wish
return Unauthorized();
}
var createdWishlist = await _wishlistService.CreateWishlistAsync(wishlist, userId);
- return CreatedAtAction(nameof(GetWishlist), new { id = createdWishlist.Id }, createdWishlist);
+ return CreatedAtAction(nameof(GetWishlist), new { publicId = createdWishlist.PublicId }, createdWishlist);
}
[HttpPut("{publicId}")]
public async Task UpdateWishlist(string publicId, WishlistModel wishlist)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ var canEdit = await _wishlistService.CanUserEditWishlistByPublicIdAsync(publicId, userId);
+ if (!canEdit) return Forbid();
var updatedWishlist = await _wishlistService.UpdateWishlistByPublicIdAsync(publicId, wishlist);
if (updatedWishlist == null)
{
@@ -76,6 +80,10 @@ public async Task UpdateWishlist(string publicId, WishlistModel w
[HttpDelete("{publicId}")]
public async Task DeleteWishlist(string publicId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ var canEdit = await _wishlistService.CanUserEditWishlistByPublicIdAsync(publicId, userId);
+ if (!canEdit) return Forbid();
await _wishlistService.DeleteWishlistByPublicIdAsync(publicId);
return NoContent();
}
@@ -228,6 +236,21 @@ public async Task RemoveItemFromWishlist(string wishlistPublicId,
[HttpPost("{wishlistPublicId}/permissions")]
public async Task> ShareWishlist(string wishlistPublicId, [FromBody] ShareRequest request)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ try
+ {
+ var wishlist = await _wishlistService.GetWishlistByPublicIdAsync(wishlistPublicId, userId);
+ if (wishlist.OwnerId != userId) return Forbid();
+ }
+ catch (KeyNotFoundException)
+ {
+ return NotFound();
+ }
+ catch (UnauthorizedAccessException)
+ {
+ return Forbid();
+ }
var permission = await _wishlistService.ShareWishlistByPublicIdAsync(wishlistPublicId, request.UserId, request.PermissionType);
return Ok(permission);
}
@@ -235,6 +258,21 @@ public async Task> ShareWishlist(string wi
[HttpPost("{wishlistPublicId}/share-link")]
public async Task> CreateSharingLink(string wishlistPublicId, [FromBody] SharingLinkRequest request)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ try
+ {
+ var wishlist = await _wishlistService.GetWishlistByPublicIdAsync(wishlistPublicId, userId);
+ if (wishlist.OwnerId != userId) return Forbid();
+ }
+ catch (KeyNotFoundException)
+ {
+ return NotFound();
+ }
+ catch (UnauthorizedAccessException)
+ {
+ return Forbid();
+ }
var token = await _wishlistService.CreateSharingLinkByPublicIdAsync(wishlistPublicId, request.PermissionType, request.Expiration);
return Ok(token);
}
@@ -249,6 +287,21 @@ public async Task> AcceptSharingLink(string token, [FromBody]
[HttpGet("{wishlistPublicId}/permissions")]
public async Task>> GetWishlistPermissions(string wishlistPublicId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ try
+ {
+ var wishlist = await _wishlistService.GetWishlistByPublicIdAsync(wishlistPublicId, userId);
+ if (wishlist.OwnerId != userId) return Forbid();
+ }
+ catch (KeyNotFoundException)
+ {
+ return NotFound();
+ }
+ catch (UnauthorizedAccessException)
+ {
+ return Forbid();
+ }
var permissions = await _wishlistService.GetWishlistPermissionsByPublicIdAsync(wishlistPublicId);
return Ok(permissions);
}
@@ -256,6 +309,21 @@ public async Task>> GetWishlis
[HttpDelete("{wishlistPublicId}/permissions/{userId}")]
public async Task> RemovePermission(string wishlistPublicId, string userId)
{
+ var callerId = await _userContextService.GetUserIdAsync();
+ if (callerId is null) return Unauthorized();
+ try
+ {
+ var wishlist = await _wishlistService.GetWishlistByPublicIdAsync(wishlistPublicId, callerId);
+ if (wishlist.OwnerId != callerId) return Forbid();
+ }
+ catch (KeyNotFoundException)
+ {
+ return NotFound();
+ }
+ catch (UnauthorizedAccessException)
+ {
+ return Forbid();
+ }
var result = await _wishlistService.RemoveWishlistPermissionByPublicIdAsync(wishlistPublicId, userId);
return Ok(result);
}
@@ -304,7 +372,9 @@ public async Task> CanUserEdit(string wishlistPublicId, strin
[HttpPost("{wishlistPublicId}/items/{itemId}/comments")]
public async Task> AddComment(string wishlistPublicId, int itemId, [FromBody] CommentRequest request)
{
- var comment = await _wishlistService.AddCommentToItemByPublicIdAsync(wishlistPublicId, itemId, request.UserId, request.Text);
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ var comment = await _wishlistService.AddCommentToItemByPublicIdAsync(wishlistPublicId, itemId, userId, request.Text);
return Ok(comment);
}
@@ -316,8 +386,10 @@ public async Task>> GetComments(strin
}
[HttpDelete("comments/{commentId}")]
- public async Task> RemoveComment(int commentId, [FromQuery] string userId)
+ public async Task> RemoveComment(int commentId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _wishlistService.RemoveItemCommentAsync(commentId, userId);
return Ok(result);
}
@@ -326,13 +398,17 @@ public async Task> RemoveComment(int commentId, [FromQuery] s
[HttpPost("{wishlistPublicId}/items/{itemId}/reserve")]
public async Task> ReserveItem(string wishlistPublicId, int itemId, [FromBody] ReservationRequest request)
{
- var result = await _wishlistService.ReserveItemByPublicIdAsync(wishlistPublicId, itemId, request.UserId, request.IsAnonymous);
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
+ var result = await _wishlistService.ReserveItemByPublicIdAsync(wishlistPublicId, itemId, userId, request.IsAnonymous);
return Ok(result);
}
[HttpDelete("{wishlistPublicId}/items/{itemId}/reservation")]
- public async Task> CancelReservation(string wishlistPublicId, int itemId, [FromQuery] string userId)
+ public async Task> CancelReservation(string wishlistPublicId, int itemId)
{
+ var userId = await _userContextService.GetUserIdAsync();
+ if (userId is null) return Unauthorized();
var result = await _wishlistService.CancelReservationByPublicIdAsync(wishlistPublicId, itemId, userId);
return Ok(result);
}
@@ -401,13 +477,11 @@ public class AcceptLinkRequest
public class CommentRequest
{
- public string UserId { get; set; }
public string Text { get; set; }
}
public class ReservationRequest
{
- public string UserId { get; set; }
public bool IsAnonymous { get; set; }
}
}
\ No newline at end of file
diff --git a/src/OpenWish.Web/Services/OpenAIService.cs b/src/OpenWish.Web/Services/OpenAIService.cs
index 62bcfe8..e17e747 100644
--- a/src/OpenWish.Web/Services/OpenAIService.cs
+++ b/src/OpenWish.Web/Services/OpenAIService.cs
@@ -1,3 +1,5 @@
+using System.Net.Http.Json;
+
namespace OpenWish.Web.Services;
public interface IOpenAIService
@@ -52,9 +54,21 @@ public async Task GenerateCompletionToJsonAsync(string model, List()
+ ?? throw new InvalidOperationException("Received a null response from the OpenAI API.");
+
+ if (chatResponse.Choices is null || chatResponse.Choices.Count == 0)
+ {
+ throw new InvalidOperationException("OpenAI API response contained no choices.");
+ }
+
+ var content = chatResponse.Choices[0].Message?.Content;
+ if (string.IsNullOrEmpty(content))
+ {
+ throw new InvalidOperationException("OpenAI API response message content was empty or null.");
+ }
- return responseContent;
+ return content;
}
}