diff --git a/src/Learnify.Api/Controllers/CoursesController.cs b/src/Learnify.Api/Controllers/CoursesController.cs index 97c7823..53e5ebd 100644 --- a/src/Learnify.Api/Controllers/CoursesController.cs +++ b/src/Learnify.Api/Controllers/CoursesController.cs @@ -99,17 +99,28 @@ public async Task Update(int id, [FromForm] UpdateCourseRequest r return Unauthorized("User not authenticated"); } - // TODO: Add authorization check to ensure user owns this course - // For now, we'll let the command handler deal with authorization + // Authorization check: Ensure user is admin or course owner + var isAdmin = User.IsInRole("Admin"); + var course = await _mediator.Send(new GetCourseByIdQuery(id)); + + if (course == null) + { + return NotFound(); + } + + if (!isAdmin && course.InstructorId != currentUserId) + { + return Forbid("Only course owners or administrators can update courses"); + } var command = new UpdateCourseCommand( - id, - request.Title, - request.Description, - request.Price, - request.IsPublished, - request.ThumbnailImageUrl, - request.CategoryId, + id, + request.Title, + request.Description, + request.Price, + request.IsPublished, + request.ThumbnailImageUrl, + request.CategoryId, request.ThumbnailFile); await _mediator.Send(command); diff --git a/src/Learnify.Api/Program.cs b/src/Learnify.Api/Program.cs index 196643b..a35de0f 100644 --- a/src/Learnify.Api/Program.cs +++ b/src/Learnify.Api/Program.cs @@ -53,9 +53,21 @@ public static async Task Main(string[] args) builder.Services.AddRateLimitingPolicies(); // CORS + var allowedOrigins = builder.Configuration.GetSection("AllowedOrigins").Get() + ?? new[] { "http://localhost:3000", "http://localhost:5173", "https://localhost:3000" }; + builder.Services.AddCors(options => { - options.AddPolicy("AllowAllOrigins", policy => + options.AddPolicy("ProductionCors", policy => + { + policy.WithOrigins(allowedOrigins) + .AllowAnyMethod() + .AllowAnyHeader() + .AllowCredentials(); + }); + + // Keep development policy for fallback + options.AddPolicy("DevelopmentCors", policy => { policy.AllowAnyOrigin() .AllowAnyMethod() @@ -137,7 +149,15 @@ public static async Task Main(string[] args) app.UseStaticFiles(); app.UseMiddleware(); - app.UseCors("AllowAllOrigins"); + + // HTTPS redirection (except in development) + if (!app.Environment.IsDevelopment()) + { + app.UseHttpsRedirection(); + app.UseHsts(); + } + + app.UseCors(builder.Environment.IsDevelopment() ? "DevelopmentCors" : "ProductionCors"); app.UseRateLimiter(); app.UseAuthentication(); app.UseAuthorization(); diff --git a/src/Learnify.Api/appsettings.json b/src/Learnify.Api/appsettings.json index fac6fcf..d90a69a 100644 --- a/src/Learnify.Api/appsettings.json +++ b/src/Learnify.Api/appsettings.json @@ -44,6 +44,12 @@ "App": { "BaseUrl": "http://localhost:5279" }, + "AllowedOrigins": [ + "http://localhost:3000", + "http://localhost:5173", + "https://localhost:3000", + "https://yourdomain.com" + ], "PerformanceLogging": { "SlowThresholdMs": 500, "VerySlowThresholdMs": 2000 diff --git a/src/Learnify.Application/Learnify.Application.csproj b/src/Learnify.Application/Learnify.Application.csproj index 1bee389..ed31932 100644 --- a/src/Learnify.Application/Learnify.Application.csproj +++ b/src/Learnify.Application/Learnify.Application.csproj @@ -10,12 +10,11 @@ - - + - +