aboutsummaryrefslogtreecommitdiffstats
path: root/server/src/Endpoints/Internal/Account
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/Endpoints/Internal/Account')
-rw-r--r--server/src/Endpoints/Internal/Account/CreateAccountPayload.cs17
-rw-r--r--server/src/Endpoints/Internal/Account/CreateAccountRoute.cs44
-rw-r--r--server/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs34
-rw-r--r--server/src/Endpoints/Internal/Account/DeleteAccountRoute.cs49
-rw-r--r--server/src/Endpoints/Internal/Account/GetArchiveRoute.cs62
-rw-r--r--server/src/Endpoints/Internal/Account/GetRoute.cs31
-rw-r--r--server/src/Endpoints/Internal/Account/LoginPayload.cs22
-rw-r--r--server/src/Endpoints/Internal/Account/LoginRoute.cs37
-rw-r--r--server/src/Endpoints/Internal/Account/LogoutRoute.cs22
-rw-r--r--server/src/Endpoints/Internal/Account/UpdateAccountPayload.cs17
-rw-r--r--server/src/Endpoints/Internal/Account/UpdateAccountRoute.cs51
11 files changed, 0 insertions, 386 deletions
diff --git a/server/src/Endpoints/Internal/Account/CreateAccountPayload.cs b/server/src/Endpoints/Internal/Account/CreateAccountPayload.cs
deleted file mode 100644
index dc73e68..0000000
--- a/server/src/Endpoints/Internal/Account/CreateAccountPayload.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-/// <summary>
-/// Payload for creating new user accounts.
-/// </summary>
-public class CreateAccountPayload
-{
- /// <summary>
- /// Username for the new account.
- /// </summary>
- public string Username { get; set; }
-
- /// <summary>
- /// Password for the new account.
- /// </summary>
- public string Password { get; set; }
-}
diff --git a/server/src/Endpoints/Internal/Account/CreateAccountRoute.cs b/server/src/Endpoints/Internal/Account/CreateAccountRoute.cs
deleted file mode 100644
index 954fbf5..0000000
--- a/server/src/Endpoints/Internal/Account/CreateAccountRoute.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-/// <inheritdoc />
-public class CreateAccountRoute : RouteBaseAsync.WithRequest<CreateAccountPayload>.WithActionResult
-{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
-
- /// <inheritdoc />
- public CreateAccountRoute(UserService userService, AppDbContext context) {
- _userService = userService;
- _context = context;
- }
-
- /// <summary>
- /// Create a new user account.
- /// </summary>
- /// <param name="request"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [AllowAnonymous]
- [HttpPost("~/_/account/create")]
- public override async Task<ActionResult> HandleAsync(CreateAccountPayload request, CancellationToken cancellationToken = default) {
- if (request.Username.IsValidEmailAddress() == false) {
- return BadRequest(new ErrorResult("Invalid form", request.Username + " does not look like a valid email"));
- }
-
- if (request.Password.Length < 6) {
- return BadRequest(new ErrorResult("Invalid form", "The password requires 6 or more characters."));
- }
-
- var username = request.Username.Trim();
- if (_context.Users.Any(c => c.Username == username)) {
- return BadRequest(new ErrorResult("Username is not available", "There is already a user registered with email: " + username));
- }
-
- var user = new User(username);
- user.HashAndSetPassword(request.Password);
- _context.Users.Add(user);
- await _context.SaveChangesAsync(cancellationToken);
- await _userService.LogInUser(HttpContext, user);
- return Ok();
- }
-}
diff --git a/server/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs b/server/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs
deleted file mode 100644
index 13fbdf4..0000000
--- a/server/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-/// <inheritdoc />
-public class CreateInitialAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult
-{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
-
- /// <inheritdoc />
- public CreateInitialAccountRoute(AppDbContext context, UserService userService) {
- _context = context;
- _userService = userService;
- }
-
- /// <summary>
- /// Create an initial user account.
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [AllowAnonymous]
- [HttpGet("~/_/account/create-initial")]
- public override async Task<ActionResult> HandleAsync(CancellationToken cancellationToken = default) {
- if (_context.Users.Any()) {
- return NotFound();
- }
-
- var user = new User("admin@ivarlovlie.no");
- user.HashAndSetPassword("ivar123");
- _context.Users.Add(user);
- await _context.SaveChangesAsync(cancellationToken);
- await _userService.LogInUser(HttpContext, user);
- return Redirect("/");
- }
-}
diff --git a/server/src/Endpoints/Internal/Account/DeleteAccountRoute.cs b/server/src/Endpoints/Internal/Account/DeleteAccountRoute.cs
deleted file mode 100644
index 2149e15..0000000
--- a/server/src/Endpoints/Internal/Account/DeleteAccountRoute.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-public class DeleteAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult
-{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
-
- /// <inheritdoc />
- public DeleteAccountRoute(AppDbContext context, UserService userService) {
- _context = context;
- _userService = userService;
- }
-
- /// <summary>
- /// Delete the logged on user's account.
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [HttpDelete("~/_/account/delete")]
- public override async Task<ActionResult> HandleAsync(CancellationToken cancellationToken = default) {
- var user = _context.Users.SingleOrDefault(c => c.Id == LoggedInUser.Id);
- if (user == default) {
- await _userService.LogOutUser(HttpContext);
- return Unauthorized();
- }
-
- if (user.Username == "demo@demo.demo") {
- await _userService.LogOutUser(HttpContext);
- return Ok();
- }
-
- var githubMappings = _context.TimeCategories.Where(c => c.UserId == user.Id);
- var passwordResets = _context.ForgotPasswordRequests.Where(c => c.UserId == user.Id);
- var entries = _context.TimeEntries.Where(c => c.UserId == user.Id);
- var labels = _context.TimeLabels.Where(c => c.UserId == user.Id);
- var categories = _context.TimeCategories.Where(c => c.UserId == user.Id);
-
- _context.TimeCategories.RemoveRange(githubMappings);
- _context.ForgotPasswordRequests.RemoveRange(passwordResets);
- _context.TimeEntries.RemoveRange(entries);
- _context.TimeLabels.RemoveRange(labels);
- _context.TimeCategories.RemoveRange(categories);
- _context.Users.Remove(user);
-
- await _context.SaveChangesAsync(cancellationToken);
- await _userService.LogOutUser(HttpContext);
- return Ok();
- }
-}
diff --git a/server/src/Endpoints/Internal/Account/GetArchiveRoute.cs b/server/src/Endpoints/Internal/Account/GetArchiveRoute.cs
deleted file mode 100644
index f1b70f3..0000000
--- a/server/src/Endpoints/Internal/Account/GetArchiveRoute.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-public class GetAccountArchiveRoute : RouteBaseAsync.WithoutRequest.WithActionResult<UserArchiveDto>
-{
- private readonly AppDbContext _context;
-
- /// <inheritdoc />
- public GetAccountArchiveRoute(AppDbContext context) {
- _context = context;
- }
-
- /// <summary>
- /// Get a data archive with the currently logged on user's data.
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [HttpGet("~/_/account/archive")]
- public override async Task<ActionResult<UserArchiveDto>> HandleAsync(CancellationToken cancellationToken = default) {
- var user = _context.Users.SingleOrDefault(c => c.Id == LoggedInUser.Id);
- if (user == default) {
- await HttpContext.SignOutAsync();
- return Unauthorized();
- }
-
- var entries = _context.TimeEntries
- .AsNoTracking()
- .Include(c => c.Labels)
- .Include(c => c.Category)
- .Where(c => c.UserId == user.Id)
- .ToList();
-
- var jsonOptions = new JsonSerializerOptions {
- WriteIndented = true
- };
-
- var dto = new UserArchiveDto(user);
- dto.Entries.AddRange(entries.Select(entry => new UserArchiveDto.EntryDto {
- CreatedAt = entry.CreatedAt.ToString("yyyy-MM-ddTHH:mm:ssZ"),
- StartDateTime = entry.Start,
- StopDateTime = entry.Stop,
- Description = entry.Description,
- Labels = entry.Labels
- .Select(c => new UserArchiveDto.LabelDto {
- Name = c.Name,
- Color = c.Color
- })
- .ToList(),
- Category = new UserArchiveDto.CategoryDto {
- Name = entry.Category.Name,
- Color = entry.Category.Color
- },
- }));
-
- dto.CountEntries();
-
- var entriesSerialized = JsonSerializer.SerializeToUtf8Bytes(dto, jsonOptions);
-
- return File(entriesSerialized,
- "application/json",
- user.Username + "-time-tracker-archive-" + AppDateTime.UtcNow.ToString("yyyyMMddTHHmmss") + ".json");
- }
-}
diff --git a/server/src/Endpoints/Internal/Account/GetRoute.cs b/server/src/Endpoints/Internal/Account/GetRoute.cs
deleted file mode 100644
index 1aa7ecb..0000000
--- a/server/src/Endpoints/Internal/Account/GetRoute.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-public class GetAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult<LoggedInUserModel>
-{
- private readonly AppDbContext _context;
-
- public GetAccountRoute(AppDbContext context) {
- _context = context;
- }
-
- /// <summary>
- /// Get the logged on user's session data.
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [HttpGet("~/_/account")]
- public override async Task<ActionResult<LoggedInUserModel>> HandleAsync(CancellationToken cancellationToken = default) {
- var user = _context.Users
- .Select(x => new {x.Username, x.Id})
- .SingleOrDefault(c => c.Id == LoggedInUser.Id);
- if (user != default) {
- return Ok(new LoggedInUserModel {
- Id = LoggedInUser.Id,
- Username = LoggedInUser.Username
- });
- }
-
- await HttpContext.SignOutAsync();
- return Unauthorized();
- }
-} \ No newline at end of file
diff --git a/server/src/Endpoints/Internal/Account/LoginPayload.cs b/server/src/Endpoints/Internal/Account/LoginPayload.cs
deleted file mode 100644
index 807662c..0000000
--- a/server/src/Endpoints/Internal/Account/LoginPayload.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-/// <summary>
-/// Payload for logging in a user.
-/// </summary>
-public class LoginPayload
-{
- /// <summary>
- /// Username of the user's account.
- /// </summary>
- public string Username { get; set; }
-
- /// <summary>
- /// Password of the user's account.
- /// </summary>
- public string Password { get; set; }
-
- /// <summary>
- /// Specify that the created session should be long lived and continually refreshed.
- /// </summary>
- public bool Persist { get; set; }
-}
diff --git a/server/src/Endpoints/Internal/Account/LoginRoute.cs b/server/src/Endpoints/Internal/Account/LoginRoute.cs
deleted file mode 100644
index 5b41c61..0000000
--- a/server/src/Endpoints/Internal/Account/LoginRoute.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-public class LoginRoute : RouteBaseAsync
- .WithRequest<LoginPayload>
- .WithActionResult
-{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
-
- /// <inheritdoc />
- public LoginRoute(AppDbContext context, UserService userService) {
- _context = context;
- _userService = userService;
- }
-
- /// <summary>
- /// Login a user.
- /// </summary>
- /// <param name="request"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [AllowAnonymous]
- [HttpPost("~/_/account/login")]
- public override async Task<ActionResult> HandleAsync(LoginPayload request, CancellationToken cancellationToken = default) {
- if (!ModelState.IsValid) {
- return BadRequest(ModelState);
- }
-
- var user = _context.Users.SingleOrDefault(u => u.Username == request.Username);
- if (user == default || !user.VerifyPassword(request.Password)) {
- return BadRequest(new ErrorResult("Invalid username or password"));
- }
-
- await _userService.LogInUser(HttpContext, user, request.Persist);
- return Ok();
- }
-}
diff --git a/server/src/Endpoints/Internal/Account/LogoutRoute.cs b/server/src/Endpoints/Internal/Account/LogoutRoute.cs
deleted file mode 100644
index 4a06f4a..0000000
--- a/server/src/Endpoints/Internal/Account/LogoutRoute.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-public class LogoutRoute : RouteBaseAsync.WithoutRequest.WithActionResult
-{
- private readonly UserService _userService;
-
- public LogoutRoute(UserService userService) {
- _userService = userService;
- }
-
- /// <summary>
- /// Logout a user.
- /// </summary>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [AllowAnonymous]
- [HttpGet("~/_/account/logout")]
- public override async Task<ActionResult> HandleAsync(CancellationToken cancellationToken = default) {
- await _userService.LogOutUser(HttpContext);
- return Ok();
- }
-}
diff --git a/server/src/Endpoints/Internal/Account/UpdateAccountPayload.cs b/server/src/Endpoints/Internal/Account/UpdateAccountPayload.cs
deleted file mode 100644
index 88a3237..0000000
--- a/server/src/Endpoints/Internal/Account/UpdateAccountPayload.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-/// <summary>
-/// Payload for updating an account.
-/// </summary>
-public class UpdatePayload
-{
- /// <summary>
- /// Username to set on the logged on user's account.
- /// </summary>
- public string Username { get; set; }
-
- /// <summary>
- /// Password to set on the logged on user's account.
- /// </summary>
- public string Password { get; set; }
-}
diff --git a/server/src/Endpoints/Internal/Account/UpdateAccountRoute.cs b/server/src/Endpoints/Internal/Account/UpdateAccountRoute.cs
deleted file mode 100644
index a997dcb..0000000
--- a/server/src/Endpoints/Internal/Account/UpdateAccountRoute.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-
-public class UpdateAccountRoute : RouteBaseAsync.WithRequest<UpdatePayload>.WithActionResult
-{
- private readonly AppDbContext _context;
-
- /// <inheritdoc />
- public UpdateAccountRoute(AppDbContext context) {
- _context = context;
- }
-
- /// <summary>
- /// Update the logged on user's data.
- /// </summary>
- /// <param name="request"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [HttpPost("~/_/account/update")]
- public override async Task<ActionResult> HandleAsync(UpdatePayload request, CancellationToken cancellationToken = default) {
- var user = _context.Users.SingleOrDefault(c => c.Id == LoggedInUser.Id);
- if (user == default) {
- await HttpContext.SignOutAsync();
- return Unauthorized();
- }
-
- if (request.Password.IsNullOrWhiteSpace() && request.Username.IsNullOrWhiteSpace()) {
- return BadRequest(new ErrorResult("Invalid request", "No data was submitted"));
- }
-
- if (request.Password.HasValue() && request.Password.Length < 6) {
- return BadRequest(new ErrorResult("Invalid request",
- "The new password must contain at least 6 characters"));
- }
-
- if (request.Password.HasValue()) {
- user.HashAndSetPassword(request.Password);
- }
-
- if (request.Username.HasValue() && !request.Username.IsValidEmailAddress()) {
- return BadRequest(new ErrorResult("Invalid request",
- "The new username does not look like a valid email address"));
- }
-
- if (request.Username.HasValue()) {
- user.Username = request.Username.Trim();
- }
-
- await _context.SaveChangesAsync(cancellationToken);
- return Ok();
- }
-}