From c0afba7554f3049408ebe7f2179e9ebe817b7843 Mon Sep 17 00:00:00 2001 From: Mia Winter Date: Mon, 12 Feb 2024 17:29:13 +0100 Subject: [PATCH] Implemented Email Confirmation links --- Wave/Components/Pages/EmailSignup.razor | 50 ++++++++++++++++++- .../Components/Pages/EmailSignup.de-DE.resx | 6 +++ .../Components/Pages/EmailSignup.resx | 6 +++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/Wave/Components/Pages/EmailSignup.razor b/Wave/Components/Pages/EmailSignup.razor index 21cbe6a..1b04b21 100644 --- a/Wave/Components/Pages/EmailSignup.razor +++ b/Wave/Components/Pages/EmailSignup.razor @@ -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 Logger @inject IStringLocalizer Localizer @inject IDbContextFactory ContextFactory +@inject IDistributedCache TokenCache @inject IOptions Features @inject IOptions 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().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( diff --git a/Wave/Resources/Components/Pages/EmailSignup.de-DE.resx b/Wave/Resources/Components/Pages/EmailSignup.de-DE.resx index 9a871bb..9c061dd 100644 --- a/Wave/Resources/Components/Pages/EmailSignup.de-DE.resx +++ b/Wave/Resources/Components/Pages/EmailSignup.de-DE.resx @@ -122,4 +122,10 @@ E-Mail Bestätigen + + 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. + + + Ihre E-Mail wurde erfolgreich bestätigt. Sie werden nun in zukunft Benachrichtigungen zu neuen Artikeln erhalten. + \ No newline at end of file diff --git a/Wave/Resources/Components/Pages/EmailSignup.resx b/Wave/Resources/Components/Pages/EmailSignup.resx index 04de437..21e7bc3 100644 --- a/Wave/Resources/Components/Pages/EmailSignup.resx +++ b/Wave/Resources/Components/Pages/EmailSignup.resx @@ -128,4 +128,10 @@ 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. + + 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. + + + Your Email has been confirmed successfully. You will not receive notifications about future articles. + \ No newline at end of file