aboutsummaryrefslogtreecommitdiffstats
path: root/code/api/src
diff options
context:
space:
mode:
Diffstat (limited to 'code/api/src')
-rw-r--r--code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs1
-rw-r--r--code/api/src/Endpoints/Internal/Root/IsAuthenticatedRoute.cs (renamed from code/api/src/Endpoints/Internal/Root/ValidSessionRoute.cs)4
-rw-r--r--code/api/src/Endpoints/Internal/Root/ValidateRoute.cs25
-rw-r--r--code/api/src/Resources/SharedResources.nb.Designer.cs6
-rw-r--r--code/api/src/Resources/SharedResources.nb.resx13
-rw-r--r--code/api/src/Services/UserService.cs45
6 files changed, 84 insertions, 10 deletions
diff --git a/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs b/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs
index 44b8376..c114bb8 100644
--- a/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs
+++ b/code/api/src/Endpoints/Internal/Account/CreateAccountRoute.cs
@@ -46,6 +46,7 @@ public class CreateAccountRoute : RouteBaseAsync.WithRequest<CreateAccountRoute.
_database.Users.Add(user);
await _database.SaveChangesAsync(cancellationToken);
await _userService.LogInUser(HttpContext, user);
+ Task.Run(() => _userService.SendValidationEmail(user), cancellationToken);
return Ok();
}
} \ No newline at end of file
diff --git a/code/api/src/Endpoints/Internal/Root/ValidSessionRoute.cs b/code/api/src/Endpoints/Internal/Root/IsAuthenticatedRoute.cs
index f377ff6..7bb0a86 100644
--- a/code/api/src/Endpoints/Internal/Root/ValidSessionRoute.cs
+++ b/code/api/src/Endpoints/Internal/Root/IsAuthenticatedRoute.cs
@@ -1,9 +1,9 @@
namespace IOL.GreatOffice.Api.Endpoints.Internal.Root;
-public class ValidSessionRoute : RouteBaseSync.WithoutRequest.WithActionResult
+public class IsAuthenticatedRoute : RouteBaseSync.WithoutRequest.WithActionResult
{
[Authorize]
- [HttpGet("~/_/valid-session")]
+ [HttpGet("~/_/is-authenticated")]
public override ActionResult Handle() {
return Ok();
}
diff --git a/code/api/src/Endpoints/Internal/Root/ValidateRoute.cs b/code/api/src/Endpoints/Internal/Root/ValidateRoute.cs
new file mode 100644
index 0000000..682a869
--- /dev/null
+++ b/code/api/src/Endpoints/Internal/Root/ValidateRoute.cs
@@ -0,0 +1,25 @@
+namespace IOL.GreatOffice.Api.Endpoints.Internal.Root;
+
+public class ValidateRoute : RouteBaseSync.WithRequest<ValidateRoute.QueryParams>.WithActionResult
+{
+ private readonly UserService _userService;
+ private readonly string _continueTo;
+
+ public ValidateRoute(UserService userService, VaultService vaultService) {
+ _userService = userService;
+ var c = vaultService.GetCurrentAppConfiguration();
+ _continueTo = c.CANONICAL_FRONTEND_URL + "/?act=email-validated";
+ }
+
+ public class QueryParams
+ {
+ [FromQuery]
+ public Guid Id { get; set; }
+ }
+
+ [HttpGet("~/_/validate")]
+ public override ActionResult Handle([FromQuery] QueryParams request) {
+ _userService.FulfillEmailValidationRequest(request.Id, LoggedInUser.Id);
+ return Redirect(_continueTo);
+ }
+} \ No newline at end of file
diff --git a/code/api/src/Resources/SharedResources.nb.Designer.cs b/code/api/src/Resources/SharedResources.nb.Designer.cs
index 37006f2..2613026 100644
--- a/code/api/src/Resources/SharedResources.nb.Designer.cs
+++ b/code/api/src/Resources/SharedResources.nb.Designer.cs
@@ -80,5 +80,11 @@ namespace IOL.GreatOffice.Api.Resources {
return ResourceManager.GetString("One or more validation errors occured", resourceCulture);
}
}
+
+ internal static string Greatoffice_Email_Validation {
+ get {
+ return ResourceManager.GetString("Greatoffice Email Validation", resourceCulture);
+ }
+ }
}
}
diff --git a/code/api/src/Resources/SharedResources.nb.resx b/code/api/src/Resources/SharedResources.nb.resx
index 880274e..ac31409 100644
--- a/code/api/src/Resources/SharedResources.nb.resx
+++ b/code/api/src/Resources/SharedResources.nb.resx
@@ -46,4 +46,17 @@
<data name="One or more validation errors occured" xml:space="preserve">
<value>En eller flere valideringsfeil har oppstått</value>
</data>
+ <data name="Hello, {0}.&#xA;&#xA;Validate your email address by opening this link in a browser {1}"
+ xml:space="preserve">
+ <value>Hei, {0}.
+
+Bekreft din e-postadresse ved å åpne denne lenken i en nettleser {1}</value>
+ <comment>Hello, {0}.
+
+ Validate your email address by opening this link in a browser {1}</comment>
+ </data>
+ <data name="Greatoffice Email Validation" xml:space="preserve">
+ <value>Greatoffice e-postaddresse bekreftelse</value>
+ <comment>Greatoffice Email Validation</comment>
+ </data>
</root> \ No newline at end of file
diff --git a/code/api/src/Services/UserService.cs b/code/api/src/Services/UserService.cs
index 8b925be..4c632be 100644
--- a/code/api/src/Services/UserService.cs
+++ b/code/api/src/Services/UserService.cs
@@ -10,15 +10,16 @@ public class UserService
private readonly ILogger<UserService> _logger;
private readonly IStringLocalizer<SharedResources> _localizer;
private readonly MainAppDatabase _database;
- private string EmailValidationUrl;
+ private readonly string EmailValidationUrl;
- public UserService(PasswordResetService passwordResetService, MailService mailService, IStringLocalizer<SharedResources> localizer, VaultService vaultService, MainAppDatabase database) {
+ public UserService(PasswordResetService passwordResetService, MailService mailService, IStringLocalizer<SharedResources> localizer, VaultService vaultService, MainAppDatabase database, ILogger<UserService> logger) {
_passwordResetService = passwordResetService;
_mailService = mailService;
_localizer = localizer;
_database = database;
+ _logger = logger;
var configuration = vaultService.GetCurrentAppConfiguration();
- EmailValidationUrl = configuration.CANONICAL_BACKEND_URL + "/validate";
+ EmailValidationUrl = configuration.CANONICAL_BACKEND_URL + "/_/validate";
}
public async Task LogInUser(HttpContext httpContext, User user, bool persist = false) {
@@ -49,7 +50,39 @@ public class UserService
_logger.LogInformation("Logged out user {0}", httpContext.User.FindFirst(AppClaims.USER_ID));
}
+ public bool FulfillEmailValidationRequest(Guid id, Guid userId) {
+ var item = _database.ValidationEmails.FirstOrDefault(c => c.Id == id);
+ if (item == default) {
+ _logger.LogDebug("Did not find email validation request with id: {0}", id);
+ return false;
+ }
+
+ if (item.UserId != userId) {
+ _logger.LogInformation("An unknown user tried to validate the email validation request {0}");
+ return false;
+ }
+
+ var user = _database.Users.FirstOrDefault(c => c.Id == item.UserId);
+ if (user == default) {
+ _database.ValidationEmails.Remove(item);
+ _database.SaveChanges();
+ _logger.LogInformation("Deleting request {0} because user does not exist anymore");
+ return false;
+ }
+
+ user.EmailLastValidated = DateTime.UtcNow;
+ user.SetModified();
+ _database.ValidationEmails.Remove(item);
+ _database.SaveChanges();
+ _logger.LogInformation("Successfully validated the email for user {0}", user.Id);
+ return true;
+ }
+
public async Task SendValidationEmail(User user) {
+ var queueItem = new ValidationEmail() {
+ UserId = user.Id,
+ Id = Guid.NewGuid()
+ };
var email = new MailService.PostmarkEmail() {
To = user.Username,
Subject = _localizer["Greatoffice Email Validation"],
@@ -57,11 +90,7 @@ public class UserService
Hello, {0}.
Validate your email address by opening this link in a browser {1}
-""", user.DisplayName(), EmailValidationUrl + "?email=" + user.Username]
- };
- var queueItem = new ValidationEmail() {
- UserId = user.Id,
- Id = Guid.NewGuid()
+""", user.DisplayName(), EmailValidationUrl + "?id=" + queueItem.Id]
};
await _mailService.SendMail(email);
queueItem.EmailSentAt = DateTime.UtcNow;