Implemented Email Confirmation links

This commit is contained in:
Mia Rose Winter 2024-02-12 17:29:13 +01:00
parent dcbe1a266a
commit c0afba7554
Signed by: miawinter
GPG key ID: 4B6F6A83178F595E
3 changed files with 61 additions and 1 deletions

View file

@ -1,14 +1,19 @@
@page "/Email/Subscribe"
@page "/Email/Confirm"
@using Microsoft.Extensions.Options
@using Wave.Data
@using System.ComponentModel.DataAnnotations
@using System.Net
@using Microsoft.AspNetCore.Identity.UI.Services
@using Microsoft.EntityFrameworkCore
@using Microsoft.Extensions.Caching.Distributed
@using Wave.Services
@inject ILogger<EmailSignup> Logger
@inject IStringLocalizer<EmailSignup> Localizer
@inject IDbContextFactory<ApplicationDbContext> ContextFactory
@inject IDistributedCache TokenCache
@inject IOptions<Features> Features
@inject IOptions<Customization> Customizations
@inject NavigationManager Navigation
@ -48,11 +53,44 @@
[SupplyParameterFromForm(FormName = "email-signup")]
private InputModel Model { get; set; } = new();
[Parameter, SupplyParameterFromQuery(Name = "user")]
public string? Id { get; set; }
[Parameter, SupplyParameterFromQuery(Name = "token")]
public string? Token { get; set; }
private string Message { get; set; } = string.Empty;
protected override void OnInitialized() {
if (Features.Value.EmailSubscriptions is not true)
throw new ApplicationException("Email subscriptions not enabled.");
if (Id is null || Token is null) return;
try {
string cacheKey = "subscribe-" + Id;
byte[]? tokenInCache = TokenCache.Get(cacheKey);
if (tokenInCache is null || Token != Convert.ToBase64String(tokenInCache)) {
Message = Localizer["Failure_Message"];
return;
}
var realId = new Guid(Convert.FromBase64String(Id));
using var context = ContextFactory.CreateDbContext();
var subscriber = context.Set<EmailSubscriber>().IgnoreQueryFilters().FirstOrDefault(s => s.Id == realId);
if (subscriber is null) {
Message = Localizer["Failure_Message"];
return;
}
subscriber.Unsubscribed = false;
context.SaveChanges();
TokenCache.Remove(cacheKey);
Message = Localizer["Success_Message"];
} catch (Exception ex) {
Logger.LogError(ex, "Error trying to confirm subscriber.");
Message = Localizer["Failure_Message"];
}
}
private async Task OnValidSubmit() {
@ -74,7 +112,17 @@
await context.SaveChangesAsync();
if (subscriber.Unsubscribed) {
string confirmLink = Navigation.ToAbsoluteUri("#").AbsoluteUri; // TODO
string id = Convert.ToBase64String(subscriber.Id.ToByteArray());
string token = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
await TokenCache.SetAsync("subscribe-" + id,
Convert.FromBase64String(token),
new DistributedCacheEntryOptions {
AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(1)
});
string confirmLink = Navigation.ToAbsoluteUri(
$"/Email/Confirm?user={WebUtility.UrlEncode(id)}&token={WebUtility.UrlEncode(token)}").AbsoluteUri;
var customization = Customizations.Value;
string body = TemplateService.Default(

View file

@ -122,4 +122,10 @@
<data name="ConfirmEmailTitle" xml:space="preserve">
<value>E-Mail Bestätigen</value>
</data>
<data name="Failure_Message" xml:space="preserve">
<value>Fehler beim bestätigen der E-Mail. Ihr Token ist möglicherweise falsch oder abgelaufen. Sollte dieser Fehler weiterhin bestehen, fordern Sie eine neue Bestätigungsmail an, indem Sie das untenstehende Formular erneut ausfüllen.</value>
</data>
<data name="Success_Message" xml:space="preserve">
<value>Ihre E-Mail wurde erfolgreich bestätigt. Sie werden nun in zukunft Benachrichtigungen zu neuen Artikeln erhalten.</value>
</data>
</root>

View file

@ -128,4 +128,10 @@
<data name="ConfirmEmailBody" xml:space="preserve">
<value>Please follow the following link to confirm that you want to subscribe to the newsletter of {0} for free. If this has not been you, you can ignore this Email. You can unsubscribe at any point. </value>
</data>
<data name="Failure_Message" xml:space="preserve">
<value>Failed to confirm Email. Your token might be wrong or expired. If this error persists, please request a new confirmation mail by filling out this form again.</value>
</data>
<data name="Success_Message" xml:space="preserve">
<value>Your Email has been confirmed successfully. You will not receive notifications about future articles.</value>
</data>
</root>