aboutsummaryrefslogtreecommitdiffstats
path: root/code/api/src/Endpoints/Internal
diff options
context:
space:
mode:
authorivarlovlie <git@ivarlovlie.no>2022-10-30 16:40:03 +0100
committerivarlovlie <git@ivarlovlie.no>2022-10-30 16:40:03 +0100
commit0725e4f7cf4c6f723264b6d461b91c660d144cb7 (patch)
treeaae5876b5760c80679161d918c34d753ec0e2582 /code/api/src/Endpoints/Internal
parentd76c180c9631df015d37138045c79a46cca350e8 (diff)
downloadgreatoffice-0725e4f7cf4c6f723264b6d461b91c660d144cb7.tar.xz
greatoffice-0725e4f7cf4c6f723264b6d461b91c660d144cb7.zip
feat: Apiwork
Diffstat (limited to 'code/api/src/Endpoints/Internal')
-rw-r--r--code/api/src/Endpoints/Internal/Account/CreateAccountPayload.cs18
-rw-r--r--code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs68
-rw-r--r--code/api/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs52
-rw-r--r--code/api/src/Endpoints/Internal/Account/DeleteAccountRoute.cs77
-rw-r--r--code/api/src/Endpoints/Internal/Account/GetArchiveRoute.cs99
-rw-r--r--code/api/src/Endpoints/Internal/Account/GetRoute.cs8
-rw-r--r--code/api/src/Endpoints/Internal/Account/LoginRoute.cs57
-rw-r--r--code/api/src/Endpoints/Internal/Account/LogoutRoute.cs32
-rw-r--r--code/api/src/Endpoints/Internal/Account/UpdateAccountRoute.cs77
-rw-r--r--code/api/src/Endpoints/Internal/PasswordResetRequests/CreateResetRequestPayload.cs (renamed from code/api/src/Endpoints/Internal/PasswordResetRequests/Create/RequestModel.cs)4
-rw-r--r--code/api/src/Endpoints/Internal/PasswordResetRequests/CreateResetRequestRoute.cs (renamed from code/api/src/Endpoints/Internal/PasswordResetRequests/Create/Route.cs)33
-rw-r--r--code/api/src/Endpoints/Internal/PasswordResetRequests/FulfillResetRequestRoute.cs51
-rw-r--r--code/api/src/Endpoints/Internal/PasswordResetRequests/IsResetRequestValidRoute.cs42
-rw-r--r--code/api/src/Endpoints/Internal/Root/GetApplicationVersionRoute.cs29
-rw-r--r--code/api/src/Endpoints/Internal/Root/LogRoute.cs20
-rw-r--r--code/api/src/Endpoints/Internal/Root/ReadConfigurationRoute.cs22
-rw-r--r--code/api/src/Endpoints/Internal/Root/RefreshConfigurationRoute.cs18
17 files changed, 340 insertions, 367 deletions
diff --git a/code/api/src/Endpoints/Internal/Account/CreateAccountPayload.cs b/code/api/src/Endpoints/Internal/Account/CreateAccountPayload.cs
index dc73e68..1161af3 100644
--- a/code/api/src/Endpoints/Internal/Account/CreateAccountPayload.cs
+++ b/code/api/src/Endpoints/Internal/Account/CreateAccountPayload.cs
@@ -5,13 +5,13 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
/// </summary>
public class CreateAccountPayload
{
- /// <summary>
- /// Username for the new account.
- /// </summary>
- public string Username { get; set; }
+ /// <summary>
+ /// Username for the new account.
+ /// </summary>
+ public string Username { get; set; }
- /// <summary>
- /// Password for the new account.
- /// </summary>
- public string Password { get; set; }
-}
+ /// <summary>
+ /// Password for the new account.
+ /// </summary>
+ public string Password { get; set; }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs b/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs
index 0f4a383..f34056d 100644
--- a/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs
@@ -1,44 +1,42 @@
namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-/// <inheritdoc />
public class CreateAccountRoute : RouteBaseAsync.WithRequest<CreateAccountPayload>.WithActionResult
{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
+ private readonly MainAppDatabase _database;
+ private readonly UserService _userService;
- /// <inheritdoc />
- public CreateAccountRoute(UserService userService, AppDbContext context) {
- _userService = userService;
- _context = context;
- }
+ public CreateAccountRoute(UserService userService, MainAppDatabase database) {
+ _userService = userService;
+ _database = database;
+ }
- /// <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 KnownProblemModel("Invalid form", request.Username + " does not look like a valid email"));
- }
+ /// <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 KnownProblemModel("Invalid form", request.Username + " does not look like a valid email"));
+ }
- if (request.Password.Length < 6) {
- return BadRequest(new KnownProblemModel("Invalid form", "The password requires 6 or more characters."));
- }
+ if (request.Password.Length < 6) {
+ return BadRequest(new KnownProblemModel("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 KnownProblemModel("Username is not available", "There is already a user registered with email: " + username));
- }
+ var username = request.Username.Trim();
+ if (_database.Users.Any(c => c.Username == username)) {
+ return BadRequest(new KnownProblemModel("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();
- }
-}
+ var user = new User(username);
+ user.HashAndSetPassword(request.Password);
+ _database.Users.Add(user);
+ await _database.SaveChangesAsync(cancellationToken);
+ await _userService.LogInUser(HttpContext, user);
+ return Ok();
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs b/code/api/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs
index 13fbdf4..56ff9c6 100644
--- a/code/api/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/CreateInitialAccountRoute.cs
@@ -1,34 +1,32 @@
namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-/// <inheritdoc />
public class CreateInitialAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult
{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
+ private readonly MainAppDatabase _database;
+ private readonly UserService _userService;
- /// <inheritdoc />
- public CreateInitialAccountRoute(AppDbContext context, UserService userService) {
- _context = context;
- _userService = userService;
- }
+ public CreateInitialAccountRoute(MainAppDatabase database, UserService userService) {
+ _database = database;
+ _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();
- }
+ /// <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 (_database.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("/");
- }
-}
+ var user = new User("admin@ivarlovlie.no");
+ user.HashAndSetPassword("ivar123");
+ _database.Users.Add(user);
+ await _database.SaveChangesAsync(cancellationToken);
+ await _userService.LogInUser(HttpContext, user);
+ return Redirect("/");
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/DeleteAccountRoute.cs b/code/api/src/Endpoints/Internal/Account/DeleteAccountRoute.cs
index 2149e15..5df1fb6 100644
--- a/code/api/src/Endpoints/Internal/Account/DeleteAccountRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/DeleteAccountRoute.cs
@@ -2,48 +2,47 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
public class DeleteAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult
{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
+ private readonly MainAppDatabase _database;
+ private readonly UserService _userService;
- /// <inheritdoc />
- public DeleteAccountRoute(AppDbContext context, UserService userService) {
- _context = context;
- _userService = userService;
- }
+ public DeleteAccountRoute(MainAppDatabase database, UserService userService) {
+ _database = database;
+ _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();
- }
+ /// <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 = _database.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();
- }
+ 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);
+ var githubMappings = _database.TimeCategories.Where(c => c.UserId == user.Id);
+ var passwordResets = _database.ForgotPasswordRequests.Where(c => c.UserId == user.Id);
+ var entries = _database.TimeEntries.Where(c => c.UserId == user.Id);
+ var labels = _database.TimeLabels.Where(c => c.UserId == user.Id);
+ var categories = _database.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);
+ _database.TimeCategories.RemoveRange(githubMappings);
+ _database.ForgotPasswordRequests.RemoveRange(passwordResets);
+ _database.TimeEntries.RemoveRange(entries);
+ _database.TimeLabels.RemoveRange(labels);
+ _database.TimeCategories.RemoveRange(categories);
+ _database.Users.Remove(user);
- await _context.SaveChangesAsync(cancellationToken);
- await _userService.LogOutUser(HttpContext);
- return Ok();
- }
-}
+ await _database.SaveChangesAsync(cancellationToken);
+ await _userService.LogOutUser(HttpContext);
+ return Ok();
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/GetArchiveRoute.cs b/code/api/src/Endpoints/Internal/Account/GetArchiveRoute.cs
index f1b70f3..0d9f817 100644
--- a/code/api/src/Endpoints/Internal/Account/GetArchiveRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/GetArchiveRoute.cs
@@ -2,61 +2,60 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
public class GetAccountArchiveRoute : RouteBaseAsync.WithoutRequest.WithActionResult<UserArchiveDto>
{
- private readonly AppDbContext _context;
+ private readonly MainAppDatabase _database;
- /// <inheritdoc />
- public GetAccountArchiveRoute(AppDbContext context) {
- _context = context;
- }
+ public GetAccountArchiveRoute(MainAppDatabase database) {
+ _database = database;
+ }
- /// <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();
- }
+ /// <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 = _database.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 entries = _database.TimeEntries
+ .AsNoTracking()
+ .Include(c => c.Labels)
+ .Include(c => c.Category)
+ .Where(c => c.UserId == user.Id)
+ .ToList();
- var jsonOptions = new JsonSerializerOptions {
- WriteIndented = true
- };
+ 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
- },
- }));
+ 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();
+ dto.CountEntries();
- var entriesSerialized = JsonSerializer.SerializeToUtf8Bytes(dto, jsonOptions);
+ var entriesSerialized = JsonSerializer.SerializeToUtf8Bytes(dto, jsonOptions);
- return File(entriesSerialized,
- "application/json",
- user.Username + "-time-tracker-archive-" + AppDateTime.UtcNow.ToString("yyyyMMddTHHmmss") + ".json");
- }
-}
+ return File(entriesSerialized,
+ "application/json",
+ user.Username + "-time-tracker-archive-" + AppDateTime.UtcNow.ToString("yyyyMMddTHHmmss") + ".json");
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/GetRoute.cs b/code/api/src/Endpoints/Internal/Account/GetRoute.cs
index 1aa7ecb..8d6c50f 100644
--- a/code/api/src/Endpoints/Internal/Account/GetRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/GetRoute.cs
@@ -2,10 +2,10 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
public class GetAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult<LoggedInUserModel>
{
- private readonly AppDbContext _context;
+ private readonly MainAppDatabase _database;
- public GetAccountRoute(AppDbContext context) {
- _context = context;
+ public GetAccountRoute(MainAppDatabase database) {
+ _database = database;
}
/// <summary>
@@ -15,7 +15,7 @@ public class GetAccountRoute : RouteBaseAsync.WithoutRequest.WithActionResult<Lo
/// <returns></returns>
[HttpGet("~/_/account")]
public override async Task<ActionResult<LoggedInUserModel>> HandleAsync(CancellationToken cancellationToken = default) {
- var user = _context.Users
+ var user = _database.Users
.Select(x => new {x.Username, x.Id})
.SingleOrDefault(c => c.Id == LoggedInUser.Id);
if (user != default) {
diff --git a/code/api/src/Endpoints/Internal/Account/LoginRoute.cs b/code/api/src/Endpoints/Internal/Account/LoginRoute.cs
index e4ef54c..696c3c2 100644
--- a/code/api/src/Endpoints/Internal/Account/LoginRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/LoginRoute.cs
@@ -1,37 +1,34 @@
namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
-public class LoginRoute : RouteBaseAsync
- .WithRequest<LoginPayload>
- .WithActionResult
+public class LoginRoute : RouteBaseAsync.WithRequest<LoginPayload>.WithActionResult
{
- private readonly AppDbContext _context;
- private readonly UserService _userService;
+ private readonly MainAppDatabase _database;
+ private readonly UserService _userService;
- /// <inheritdoc />
- public LoginRoute(AppDbContext context, UserService userService) {
- _context = context;
- _userService = userService;
- }
+ public LoginRoute(MainAppDatabase database, UserService userService) {
+ _database = database;
+ _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);
- }
+ /// <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 KnownProblemModel("Invalid username or password"));
- }
+ var user = _database.Users.SingleOrDefault(u => u.Username == request.Username);
+ if (user == default || !user.VerifyPassword(request.Password)) {
+ return BadRequest(new KnownProblemModel("Invalid username or password"));
+ }
- await _userService.LogInUser(HttpContext, user, request.Persist);
- return Ok();
- }
-}
+ await _userService.LogInUser(HttpContext, user, request.Persist);
+ return Ok();
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/LogoutRoute.cs b/code/api/src/Endpoints/Internal/Account/LogoutRoute.cs
index 4a06f4a..042d729 100644
--- a/code/api/src/Endpoints/Internal/Account/LogoutRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/LogoutRoute.cs
@@ -2,21 +2,21 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
public class LogoutRoute : RouteBaseAsync.WithoutRequest.WithActionResult
{
- private readonly UserService _userService;
+ private readonly UserService _userService;
- public LogoutRoute(UserService userService) {
- _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();
- }
-}
+ /// <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();
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Account/UpdateAccountRoute.cs b/code/api/src/Endpoints/Internal/Account/UpdateAccountRoute.cs
index 31ff10b..02dc3f1 100644
--- a/code/api/src/Endpoints/Internal/Account/UpdateAccountRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/UpdateAccountRoute.cs
@@ -2,50 +2,49 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Account;
public class UpdateAccountRoute : RouteBaseAsync.WithRequest<UpdatePayload>.WithActionResult
{
- private readonly AppDbContext _context;
+ private readonly MainAppDatabase _database;
- /// <inheritdoc />
- public UpdateAccountRoute(AppDbContext context) {
- _context = context;
- }
+ public UpdateAccountRoute(MainAppDatabase database) {
+ _database = database;
+ }
- /// <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();
- }
+ /// <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 = _database.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 KnownProblemModel("Invalid request", "No data was submitted"));
- }
+ if (request.Password.IsNullOrWhiteSpace() && request.Username.IsNullOrWhiteSpace()) {
+ return BadRequest(new KnownProblemModel("Invalid request", "No data was submitted"));
+ }
- if (request.Password.HasValue() && request.Password.Length < 6) {
- return BadRequest(new KnownProblemModel("Invalid request",
- "The new password must contain at least 6 characters"));
- }
+ if (request.Password.HasValue() && request.Password.Length < 6) {
+ return BadRequest(new KnownProblemModel("Invalid request",
+ "The new password must contain at least 6 characters"));
+ }
- if (request.Password.HasValue()) {
- user.HashAndSetPassword(request.Password);
- }
+ if (request.Password.HasValue()) {
+ user.HashAndSetPassword(request.Password);
+ }
- if (request.Username.HasValue() && !request.Username.IsValidEmailAddress()) {
- return BadRequest(new KnownProblemModel("Invalid request",
- "The new username does not look like a valid email address"));
- }
+ if (request.Username.HasValue() && !request.Username.IsValidEmailAddress()) {
+ return BadRequest(new KnownProblemModel("Invalid request",
+ "The new username does not look like a valid email address"));
+ }
- if (request.Username.HasValue()) {
- user.Username = request.Username.Trim();
- }
+ if (request.Username.HasValue()) {
+ user.Username = request.Username.Trim();
+ }
- await _context.SaveChangesAsync(cancellationToken);
- return Ok();
- }
-}
+ await _database.SaveChangesAsync(cancellationToken);
+ return Ok();
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/PasswordResetRequests/Create/RequestModel.cs b/code/api/src/Endpoints/Internal/PasswordResetRequests/CreateResetRequestPayload.cs
index 236c650..1adb344 100644
--- a/code/api/src/Endpoints/Internal/PasswordResetRequests/Create/RequestModel.cs
+++ b/code/api/src/Endpoints/Internal/PasswordResetRequests/CreateResetRequestPayload.cs
@@ -1,6 +1,6 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.PasswordResetRequests.Create;
+namespace IOL.GreatOffice.Api.Endpoints.Internal.PasswordResetRequests;
-public class RequestModel
+public class CreateResetRequestPayload
{
public string Username { get; set; }
} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/PasswordResetRequests/Create/Route.cs b/code/api/src/Endpoints/Internal/PasswordResetRequests/CreateResetRequestRoute.cs
index f837fc0..bb72d38 100644
--- a/code/api/src/Endpoints/Internal/PasswordResetRequests/Create/Route.cs
+++ b/code/api/src/Endpoints/Internal/PasswordResetRequests/CreateResetRequestRoute.cs
@@ -1,15 +1,15 @@
-namespace IOL.GreatOffice.Api.Endpoints.Internal.PasswordResetRequests.Create;
+namespace IOL.GreatOffice.Api.Endpoints.Internal.PasswordResetRequests;
-public class Route : RouteBaseAsync.WithRequest<RequestModel>.WithActionResult
+public class Route : RouteBaseAsync.WithRequest<CreateResetRequestPayload>.WithActionResult
{
private readonly ILogger<Route> _logger;
private readonly PasswordResetService _passwordResetService;
- private readonly AppDbContext _context;
-
- public Route(ILogger<Route> logger, PasswordResetService passwordResetService, AppDbContext context) {
+ private readonly MainAppDatabase _database;
+
+ public Route(ILogger<Route> logger, PasswordResetService passwordResetService, MainAppDatabase database) {
_logger = logger;
_passwordResetService = passwordResetService;
- _context = context;
+ _database = database;
}
/// <summary>
@@ -20,30 +20,19 @@ public class Route : RouteBaseAsync.WithRequest<RequestModel>.WithActionResult
/// <returns></returns>
[AllowAnonymous]
[HttpPost("~/_/password-reset-request/create")]
- public override async Task<ActionResult> HandleAsync(RequestModel request, CancellationToken cancellationToken = default) {
+ public override async Task<ActionResult> HandleAsync(CreateResetRequestPayload request, CancellationToken cancellationToken = default) {
if (!request.Username.IsValidEmailAddress()) {
_logger.LogInformation("Username is invalid, not doing request for password change");
return KnownProblem("Invalid email address", request.Username + " looks like an invalid email address");
}
- Request.Headers.TryGetValue(AppHeaders.BROWSER_TIME_ZONE, out var timeZoneHeader);
- var tz = TimeZoneInfo.FindSystemTimeZoneById(timeZoneHeader.ToString().HasValue() ? timeZoneHeader.ToString() : "UTC");
- var offset = tz.BaseUtcOffset.Hours;
-
- // this is fine as long as the client is not connecting from Australia: Lord Howe Island
- // according to https://en.wikipedia.org/wiki/Daylight_saving_time_by_country
- if (tz.IsDaylightSavingTime(AppDateTime.UtcNow)) {
- offset++;
- }
-
- _logger.LogInformation("Request time zone (" + tz.Id + ") offset is: " + offset + " hours");
- var requestDateTime = TimeZoneInfo.ConvertTimeFromUtc(AppDateTime.UtcNow, tz);
- _logger.LogInformation("Creating forgot password request with date time: " + requestDateTime.ToString("u"));
+ var tz = GetRequestTimeZone(_logger);
+ _logger.LogInformation("Creating forgot password request with local date time: " + tz.LocalDateTime.ToString("u"));
try {
- var user = _context.Users.SingleOrDefault(c => c.Username.Equals(request.Username));
+ var user = _database.Users.SingleOrDefault(c => c.Username.Equals(request.Username));
if (user != default) {
- await _passwordResetService.AddRequestAsync(user, tz, cancellationToken);
+ await _passwordResetService.AddRequestAsync(user, tz.TimeZoneInfo, cancellationToken);
return Ok();
}
diff --git a/code/api/src/Endpoints/Internal/PasswordResetRequests/FulfillResetRequestRoute.cs b/code/api/src/Endpoints/Internal/PasswordResetRequests/FulfillResetRequestRoute.cs
index a0ad4d0..6f71b2f 100644
--- a/code/api/src/Endpoints/Internal/PasswordResetRequests/FulfillResetRequestRoute.cs
+++ b/code/api/src/Endpoints/Internal/PasswordResetRequests/FulfillResetRequestRoute.cs
@@ -1,34 +1,31 @@
-
namespace IOL.GreatOffice.Api.Endpoints.Internal.PasswordResetRequests;
-/// <inheritdoc />
public class FulfillResetRequestRoute : RouteBaseAsync.WithRequest<FulfillResetRequestPayload>.WithActionResult
{
- private readonly PasswordResetService _passwordResetService;
+ private readonly PasswordResetService _passwordResetService;
- /// <inheritdoc />
- public FulfillResetRequestRoute(PasswordResetService passwordResetService) {
- _passwordResetService = passwordResetService;
- }
+ public FulfillResetRequestRoute(PasswordResetService passwordResetService) {
+ _passwordResetService = passwordResetService;
+ }
- /// <summary>
- /// Fulfill a password reset request.
- /// </summary>
- /// <param name="request"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [AllowAnonymous]
- [HttpPost("~/_/password-reset-request/fulfill")]
- public override async Task<ActionResult> HandleAsync(FulfillResetRequestPayload request, CancellationToken cancellationToken = default) {
- try {
- var fulfilled = await _passwordResetService.FullFillRequestAsync(request.Id, request.NewPassword, cancellationToken);
- return Ok(fulfilled);
- } catch (Exception e) {
- if (e is ForgotPasswordRequestNotFoundException or UserNotFoundException) {
- return NotFound();
- }
+ /// <summary>
+ /// Fulfill a password reset request.
+ /// </summary>
+ /// <param name="request"></param>
+ /// <param name="cancellationToken"></param>
+ /// <returns></returns>
+ [AllowAnonymous]
+ [HttpPost("~/_/password-reset-request/fulfill")]
+ public override async Task<ActionResult> HandleAsync(FulfillResetRequestPayload request, CancellationToken cancellationToken = default) {
+ try {
+ var fulfilled = await _passwordResetService.FullFillRequestAsync(request.Id, request.NewPassword, cancellationToken);
+ return Ok(fulfilled);
+ } catch (Exception e) {
+ if (e is ForgotPasswordRequestNotFoundException or UserNotFoundException) {
+ return NotFound();
+ }
- throw;
- }
- }
-}
+ throw;
+ }
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/PasswordResetRequests/IsResetRequestValidRoute.cs b/code/api/src/Endpoints/Internal/PasswordResetRequests/IsResetRequestValidRoute.cs
index 917c4f0..687cef6 100644
--- a/code/api/src/Endpoints/Internal/PasswordResetRequests/IsResetRequestValidRoute.cs
+++ b/code/api/src/Endpoints/Internal/PasswordResetRequests/IsResetRequestValidRoute.cs
@@ -1,29 +1,27 @@
namespace IOL.GreatOffice.Api.Endpoints.Internal.PasswordResetRequests;
-/// <inheritdoc />
public class IsResetRequestValidRoute : RouteBaseAsync.WithRequest<Guid>.WithActionResult
{
- private readonly PasswordResetService _passwordResetService;
+ private readonly PasswordResetService _passwordResetService;
- /// <inheritdoc />
- public IsResetRequestValidRoute(PasswordResetService passwordResetService) {
- _passwordResetService = passwordResetService;
- }
+ public IsResetRequestValidRoute(PasswordResetService passwordResetService) {
+ _passwordResetService = passwordResetService;
+ }
- /// <summary>
- /// Check if a given password reset request is still valid.
- /// </summary>
- /// <param name="id"></param>
- /// <param name="cancellationToken"></param>
- /// <returns></returns>
- [AllowAnonymous]
- [HttpGet("~/_/password-reset-request/is-valid")]
- public override async Task<ActionResult> HandleAsync(Guid id, CancellationToken cancellationToken = default) {
- var request = await _passwordResetService.GetRequestAsync(id, cancellationToken);
- if (request == default) {
- return NotFound();
- }
+ /// <summary>
+ /// Check if a given password reset request is still valid.
+ /// </summary>
+ /// <param name="id"></param>
+ /// <param name="cancellationToken"></param>
+ /// <returns></returns>
+ [AllowAnonymous]
+ [HttpGet("~/_/password-reset-request/is-valid")]
+ public override async Task<ActionResult> HandleAsync(Guid id, CancellationToken cancellationToken = default) {
+ var request = await _passwordResetService.GetRequestAsync(id, cancellationToken);
+ if (request == default) {
+ return NotFound();
+ }
- return Ok(request.IsExpired == false);
- }
-}
+ return Ok(request.IsExpired == false);
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Root/GetApplicationVersionRoute.cs b/code/api/src/Endpoints/Internal/Root/GetApplicationVersionRoute.cs
index 5fb8213..34180d1 100644
--- a/code/api/src/Endpoints/Internal/Root/GetApplicationVersionRoute.cs
+++ b/code/api/src/Endpoints/Internal/Root/GetApplicationVersionRoute.cs
@@ -2,20 +2,19 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Root;
public class GetApplicationVersionRoute : RouteBaseSync.WithoutRequest.WithActionResult<string>
{
- private readonly IWebHostEnvironment _environment;
+ private readonly IWebHostEnvironment _environment;
- /// <inheritdoc />
- public GetApplicationVersionRoute(IWebHostEnvironment environment) {
- _environment = environment;
- }
+ public GetApplicationVersionRoute(IWebHostEnvironment environment) {
+ _environment = environment;
+ }
- /// <summary>
- /// Get the running api version number.
- /// </summary>
- /// <returns></returns>
- [HttpGet("~/_/version")]
- public override ActionResult<string> Handle() {
- var versionFilePath = Path.Combine(_environment.WebRootPath, "version.txt");
- return Ok(System.IO.File.ReadAllText(versionFilePath));
- }
-}
+ /// <summary>
+ /// Get the running api version number.
+ /// </summary>
+ /// <returns></returns>
+ [HttpGet("~/_/version")]
+ public override ActionResult<string> Handle() {
+ var versionFilePath = Path.Combine(_environment.WebRootPath, "version.txt");
+ return Ok(System.IO.File.ReadAllText(versionFilePath));
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Root/LogRoute.cs b/code/api/src/Endpoints/Internal/Root/LogRoute.cs
index 48b497a..2c69e94 100644
--- a/code/api/src/Endpoints/Internal/Root/LogRoute.cs
+++ b/code/api/src/Endpoints/Internal/Root/LogRoute.cs
@@ -2,15 +2,15 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Root;
public class LogRoute : RouteBaseSync.WithRequest<string>.WithoutResult
{
- private readonly ILogger<LogRoute> _logger;
+ private readonly ILogger<LogRoute> _logger;
- public LogRoute(ILogger<LogRoute> logger) {
- _logger = logger;
- }
+ public LogRoute(ILogger<LogRoute> logger) {
+ _logger = logger;
+ }
- [AllowAnonymous]
- [HttpPost("~/_/log")]
- public override void Handle([FromBody] string request) {
- _logger.LogInformation(request);
- }
-}
+ [AllowAnonymous]
+ [HttpPost("~/_/log")]
+ public override void Handle([FromBody] string request) {
+ _logger.LogInformation(request);
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Root/ReadConfigurationRoute.cs b/code/api/src/Endpoints/Internal/Root/ReadConfigurationRoute.cs
index e0dcca3..7270fd8 100644
--- a/code/api/src/Endpoints/Internal/Root/ReadConfigurationRoute.cs
+++ b/code/api/src/Endpoints/Internal/Root/ReadConfigurationRoute.cs
@@ -2,16 +2,16 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Root;
public class ReadConfigurationRoute : RouteBaseSync.WithoutRequest.WithActionResult
{
- private readonly VaultService _vaultService;
+ private readonly VaultService _vaultService;
- public ReadConfigurationRoute(VaultService vaultService) {
- _vaultService = vaultService;
- }
+ public ReadConfigurationRoute(VaultService vaultService) {
+ _vaultService = vaultService;
+ }
- [AllowAnonymous]
- [HttpGet("~/_/configuration")]
- public override ActionResult Handle() {
- var config = _vaultService.GetCurrentAppConfiguration();
- return Content(JsonSerializer.Serialize(config.GetPublicVersion()), "application/json");
- }
-}
+ [AllowAnonymous]
+ [HttpGet("~/_/configuration")]
+ public override ActionResult Handle() {
+ var config = _vaultService.GetCurrentAppConfiguration();
+ return Content(JsonSerializer.Serialize(config.GetPublicVersion()), "application/json");
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Root/RefreshConfigurationRoute.cs b/code/api/src/Endpoints/Internal/Root/RefreshConfigurationRoute.cs
index 4b1beec..a616c00 100644
--- a/code/api/src/Endpoints/Internal/Root/RefreshConfigurationRoute.cs
+++ b/code/api/src/Endpoints/Internal/Root/RefreshConfigurationRoute.cs
@@ -2,14 +2,14 @@ namespace IOL.GreatOffice.Api.Endpoints.Internal.Root;
public class RefreshConfigurationRoute : RouteBaseSync.WithoutRequest.WithoutResult
{
- private readonly VaultService _vaultService;
+ private readonly VaultService _vaultService;
- public RefreshConfigurationRoute(VaultService vaultService) {
- _vaultService = vaultService;
- }
+ public RefreshConfigurationRoute(VaultService vaultService) {
+ _vaultService = vaultService;
+ }
- [HttpGet("~/_/refresh-configuration")]
- public override void Handle() {
- _vaultService.RefreshCurrentAppConfiguration();
- }
-}
+ [HttpGet("~/_/refresh-configuration")]
+ public override void Handle() {
+ _vaultService.RefreshCurrentAppConfiguration();
+ }
+} \ No newline at end of file