diff --git a/WebApp/DTOs/EventSummaryNoErDto.cs b/WebApp/DTOs/EventSummaryNoErDto.cs new file mode 100644 index 0000000..121b276 --- /dev/null +++ b/WebApp/DTOs/EventSummaryNoErDto.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; +using WebApp.Entities; + +namespace WebApp.DTOs; + +// Output values in JSON file +public record class EventSummaryNoErDto( + int EventId, + [Required] string Organisation, + [Required] int OrganisationId, + [Required][StringLength(50)] string Title, + [StringLength(500)] string Description, + [Required][StringLength(100)] string Location, + [Required] DateTime? EventDate, + ICollection EventSkills +); diff --git a/WebApp/DTOs/UserSummaryDto.cs b/WebApp/DTOs/UserSummaryDto.cs new file mode 100644 index 0000000..6688eab --- /dev/null +++ b/WebApp/DTOs/UserSummaryDto.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; + +namespace WebApp.DTOs +{ + public record class UserSummaryDto + ( + [Required] int UserId, + [Required] string Email, + [Required] string FirstName, + [Required] string LastName, + [Required] DateTime CreatedAt, + [Required] bool isOrganisation + ); +} diff --git a/WebApp/Endpoints/AuthEndpoints.cs b/WebApp/Endpoints/AuthEndpoints.cs index 4a17580..6344dbb 100644 --- a/WebApp/Endpoints/AuthEndpoints.cs +++ b/WebApp/Endpoints/AuthEndpoints.cs @@ -1,9 +1,11 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.EntityFrameworkCore; using System.Security.Cryptography; using System.Text; using WebApp.Data; using WebApp.DTOs; using WebApp.Entities; +using WebApp.Mapping; namespace WebApp.Endpoints { @@ -12,33 +14,23 @@ namespace WebApp.Endpoints public static RouteGroupBuilder MapAuthEndpoints(this WebApplication app) { - var group = app.MapGroup("auth") + const string GetUserEndpointName = "GetUser"; + + var group = app.MapGroup("api/auth") .WithParameterValidation(); - group.MapPost("/login", async (LoginDto dto, ApplicationDbContext context) => + group.MapPost("/login", async (LoginDto dto, ApplicationDbContext context, GeneralUseHelpers guh) => { var user = await context.WebUsers.FirstOrDefaultAsync(u => u.Email == dto.Email); - if (user == null) - { - return Results.Json(new {message = "Wrong email or password."}, statusCode: 401); - } string hashedPassword = HashPasswordSHA512(dto.Password); - if(user.Password != hashedPassword) + if (user == null || user.Password != hashedPassword) { return Results.Json(new { message = "Wrong email or password." }, statusCode: 401); } - var token = new Token - { - UserId = user.UserId, - Value = "lah-" + Guid.NewGuid().ToString(), - ValidUntil = DateTime.UtcNow.AddDays(7), - }; - - context.Tokens.Add(token); - await context.SaveChangesAsync(); + var token = await guh.CreateNewToken(user.UserId); return Results.Ok(new { @@ -47,6 +39,87 @@ namespace WebApp.Endpoints }); }); + group.MapPost("/logout", async (HttpContext httpContext, GeneralUseHelpers guh) => + { + var token = await guh.GetTokenFromHTTPContext(httpContext); + + if (token == null) + { + return Results.Json(new { message = "No valid token found." }, statusCode: 401); + } + + await guh.DeleteToken(token); + + httpContext.Response.Cookies.Delete("token"); + + return Results.Ok(new { success = true }); + }); + + group.MapGet("/my_account", async (HttpContext httpContext, GeneralUseHelpers guh) => + { + var token = await guh.GetTokenFromHTTPContext(httpContext); + + if(token == null) + { + return Results.Json(new { message = "No valid token found." }, statusCode: 401); + } + + User? user = await guh.GetUserFromToken(token); + + if(user == null) + { + return Results.Json(new {message = "No user found."}, statusCode: 404); + } + + return Results.Ok(user.ToUserSummaryDto()); + }) + .WithName(GetUserEndpointName); + + group.MapGet("/my_events", async (HttpContext httpContext, GeneralUseHelpers guh, ApplicationDbContext context) => + { + var token = await guh.GetTokenFromHTTPContext(httpContext); + + if (token == null) + { + return Results.Json(new { message = "No valid token found." }, statusCode: 401); + } + + User? user = await guh.GetUserFromToken(token); + + if (user == null) + { + return Results.Json(new { message = "No user found." }, statusCode: 404); + } + + if(!user.IsOrganisation) + { + var events = await context.EventRegistrations + .Where(er => er.VolunteerId == user.UserId) + .Select(er => er.Event.ToEventSummaryNoErDto()) + .ToListAsync(); + + return Results.Ok(events); + } + else + { + var org = await context.Organisations.FirstOrDefaultAsync(o => o.UserId == user.UserId); + + if(org == null) + { + return Results.Json(new { message = "No organisation found for this user." }, statusCode: 404); + } + + var events = await context.Events + .Where(e => e.OrganisationId == org.OrganisationId) + .Select(e => e.ToEventSummaryDto()) + .ToListAsync(); + + return Results.Ok(events); + } + + + }); + return group; } @@ -58,7 +131,6 @@ namespace WebApp.Endpoints byte[] hash = sha512.ComputeHash(bytes); string hashstring = BitConverter.ToString(hash).Replace("-", "").ToLower(); - Console.WriteLine($"Hashed Password: {hashstring}"); return hashstring; } } diff --git a/WebApp/Endpoints/GeneralUseHelperFunctions.cs b/WebApp/Endpoints/GeneralUseHelperFunctions.cs index 93eeedf..7dee31b 100644 --- a/WebApp/Endpoints/GeneralUseHelperFunctions.cs +++ b/WebApp/Endpoints/GeneralUseHelperFunctions.cs @@ -66,4 +66,25 @@ public class GeneralUseHelpers } return null; } + + public async Task CreateNewToken(int userId) + { + var token = new Token + { + UserId = userId, + Value = "lah-" + Guid.NewGuid().ToString(), + ValidUntil = DateTime.UtcNow.AddDays(7) + }; + + _context.Tokens.Add(token); + await _context.SaveChangesAsync(); + + return token; + } + + public async Task DeleteToken(Token token) + { + _context.Tokens.Remove(token); + await _context.SaveChangesAsync(); + } } diff --git a/WebApp/Mapping/EventMapping.cs b/WebApp/Mapping/EventMapping.cs index e617cbe..9b5f240 100644 --- a/WebApp/Mapping/EventMapping.cs +++ b/WebApp/Mapping/EventMapping.cs @@ -48,6 +48,19 @@ public static class EventMapping myEvent.EventRegistrations ); } + public static EventSummaryNoErDto ToEventSummaryNoErDto(this Event myEvent) + { + return new EventSummaryNoErDto( + myEvent.EventId, + myEvent.Organisation!.Name, + myEvent.OrganisationId, + myEvent.Title, + myEvent.Description, + myEvent.Location, + myEvent.EventDate, + myEvent.EventSkills + ); + } public static EventDetailsDto ToEventDetailsDto(this Event myEvent) { diff --git a/WebApp/Mapping/UserMapping.cs b/WebApp/Mapping/UserMapping.cs new file mode 100644 index 0000000..d92bb84 --- /dev/null +++ b/WebApp/Mapping/UserMapping.cs @@ -0,0 +1,20 @@ +using WebApp.DTOs; +using WebApp.Entities; + +namespace WebApp.Mapping +{ + public static class UserMapping + { + public static UserSummaryDto ToUserSummaryDto(this User user) + { + return new UserSummaryDto( + user.UserId, + user.Email, + user.FirstName, + user.LastName, + user.CreatedAt, + user.IsOrganisation + ); + } + } +}