From 9c5ea692b01b19d773158bfa0a6b7f099898cb17 Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sun, 7 Sep 2025 17:43:13 +0100 Subject: [PATCH] Passwor re-init --- Directory.Packages.props | 4 +- .../YavscInfrastructureException.cs | 18 ++++++++ ...dels.Billing.NominativeServiceCommand.resx | 1 - .../Yavsc.Services.MailSender.en.resx | 1 - .../Yavsc.Services.MailSender.pt.resx | 1 - .../Resources/Yavsc.Services.MailSender.resx | 1 - src/Yavsc.Server/Services/MailSender.cs | 42 +++++++++---------- src/Yavsc.Server/Settings/SiteSettings.cs | 11 +++-- .../Accounting/AccountController.cs | 35 ++++++---------- .../Controllers/AccountController.en.resx | 2 + .../Controllers/AccountController.pt.resx | 2 + .../Controllers/AccountController.resx | 2 + .../Resources/Yavsc.YavscLocalisation.resx | 1 - src/Yavsc/tempkey.jwk | 1 + 14 files changed, 67 insertions(+), 55 deletions(-) create mode 100644 src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs create mode 100644 src/Yavsc/tempkey.jwk diff --git a/Directory.Packages.props b/Directory.Packages.props index 9705c859..1166d92f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,7 +16,7 @@ - + @@ -42,7 +42,7 @@ - + diff --git a/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs b/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs new file mode 100644 index 00000000..7888970c --- /dev/null +++ b/src/Yavsc.Server/Exceptions/YavscInfrastructureException.cs @@ -0,0 +1,18 @@ +namespace Yavsc.Services +{ + [Serializable] + internal class YavscInfrastructureException : Exception + { + public YavscInfrastructureException() + { + } + + public YavscInfrastructureException(string? message) : base(message) + { + } + + public YavscInfrastructureException(string? message, Exception? innerException) : base(message, innerException) + { + } + } +} diff --git a/src/Yavsc.Server/Resources/Models.Billing.NominativeServiceCommand.resx b/src/Yavsc.Server/Resources/Models.Billing.NominativeServiceCommand.resx index ba2fbfd1..98176f41 100644 --- a/src/Yavsc.Server/Resources/Models.Billing.NominativeServiceCommand.resx +++ b/src/Yavsc.Server/Resources/Models.Billing.NominativeServiceCommand.resx @@ -453,7 +453,6 @@ Confirmation du mot de passe L'envoi de de courrier pour confirmation de l'adresse e-mail a échoué. Un courrier a été envoyé pour confirmation de l'adresse e-mail . - S'il vous plait, confirmez votre addresse e-mail Vous avez créé avec succès votre compte {0}, mais votre adresse e-mail reste à confirmer. Pour ce faire, suivez le lien suivant : <{1}>. diff --git a/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.en.resx b/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.en.resx index ba192cb4..2ba52e4d 100644 --- a/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.en.resx +++ b/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.en.resx @@ -775,7 +775,6 @@ Valid caracters are: underscore '_', '-', 'a' - 'z', 'A' - 'Z', '0' - '9', th An email has been sent to confirm your addresse. - Please, confirm your e-mail You successfully created your {0} account, but your e-mail address is not yet confirmed. Please, in order to validate it, follow this link <{1}>. diff --git a/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.pt.resx b/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.pt.resx index 3295e42c..fbb26b30 100644 --- a/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.pt.resx +++ b/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.pt.resx @@ -437,7 +437,6 @@ Confirme sua senha O envio de e-mail para confirmação do endereço de e-mail falhou. Um e-mail foi enviado para confirmação do endereço de e-mail. - Por favor, confirme seu endereço de e-mail Você criou sua conta {0} com sucesso, mas o seu endereço de e-mail tem que ser confirmado. Para fazer isso, siga o seguinte link : <{1}>. diff --git a/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.resx b/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.resx index 4a04cfdd..fd6e1461 100644 --- a/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.resx +++ b/src/Yavsc.Server/Resources/Yavsc.Services.MailSender.resx @@ -230,7 +230,6 @@ Votre code dáctivation est : {4} Vour pourrez cochez la case "Se souvenir de ce navigateur" pour conserver cette authorisation pour ce navigateur. {0} - {2} <{3}> - S'il vous plait, confirmez votre addresse e-mail Vous avez créé avec succès votre compte {0}, mais votre adresse e-mail reste à confirmer. diff --git a/src/Yavsc.Server/Services/MailSender.cs b/src/Yavsc.Server/Services/MailSender.cs index e4d13fa0..cc2af555 100644 --- a/src/Yavsc.Server/Services/MailSender.cs +++ b/src/Yavsc.Server/Services/MailSender.cs @@ -14,14 +14,14 @@ using System.Web; namespace Yavsc.Services { - public class MailSender : IEmailSender, IEmailSender, ITrueEmailSender + public class MailSender : IEmailSender, IEmailSender, ITrueEmailSender { private readonly IStringLocalizer localizer; readonly SiteSettings siteSettings; readonly SmtpSettings smtpSettings; private readonly ILogger logger; public MailSender( - IOptions sitesOptions, + IOptions sitesOptions, IOptions smtpOptions, ILoggerFactory loggerFactory, IStringLocalizer localizer @@ -47,17 +47,15 @@ namespace Yavsc.Services /// a MessageWithPayloadResponse, /// bool somethingsent = (response.failure == 0 && response.success > 0) /// - - public async Task SendEmailAsync(string email, string subject, string htmlMessage) { - await SendEmailAsync("", email, subject, htmlMessage); + await SendEmailAsync("", email, subject, htmlMessage); } public async Task SendEmailAsync(string name, string email, string subject, string htmlMessage) { - logger.LogInformation($"SendEmail for {email} : {subject}"); - MimeMessage msg = new (); + logger.LogInformation($"SendEmail for {email} : {subject}"); + MimeMessage msg = new(); msg.From.Add(new MailboxAddress(siteSettings.Owner.Name, siteSettings.Owner.EMail)); msg.To.Add(new MailboxAddress(name, email)); @@ -69,20 +67,22 @@ namespace Yavsc.Services msg.MessageId = MimeKit.Utils.MimeUtils.GenerateMessageId( siteSettings.Authority ); - using (SmtpClient sc = new ()) + using (SmtpClient sc = new()) { sc.Connect( smtpSettings.Server, smtpSettings.Port, - SecureSocketOptions.Auto); - - if (smtpSettings.UserName!=null) { - NetworkCredential creds = new ( - smtpSettings.UserName, smtpSettings.Password); - await sc.AuthenticateAsync(System.Text.Encoding.UTF8, creds, System.Threading.CancellationToken.None); + SecureSocketOptions.Auto + ); + + if (smtpSettings.UserName != null) + { + sc.Authenticate(smtpSettings.UserName, smtpSettings.Password); } + await sc.SendAsync(msg); logger.LogInformation($"Sent : {msg.MessageId}"); + sc.Disconnect(true); } return msg.MessageId; } @@ -94,10 +94,10 @@ namespace Yavsc.Services public async Task SendPasswordResetCodeAsync(ApplicationUser user, string email, string resetCode) { - var callbackUrl = siteSettings.Audience + "/Account/ResetPassword/" + + var callbackUrl = siteSettings.Audience + "/Account/ResetPassword/" + HttpUtility.UrlEncode(user.Id) + "/" + HttpUtility.UrlEncode(resetCode); - - await SendEmailAsync(user.UserName, user.Email, + + await SendEmailAsync(user.UserName, user.Email, localizer["Reset Password"], localizer["Please reset your password by "] + " following this link"); @@ -106,10 +106,10 @@ namespace Yavsc.Services public async Task SendPasswordResetLinkAsync(ApplicationUser user, string email, string resetLink) { - await SendEmailAsync(user.UserName, user.Email, - localizer["Reset Password"], - localizer["Please reset your password by "] + " following this link"); + await SendEmailAsync(user.UserName, user.Email, + localizer["Reset Password"], + localizer["Please reset your password by "] + " following this link"); } } } diff --git a/src/Yavsc.Server/Settings/SiteSettings.cs b/src/Yavsc.Server/Settings/SiteSettings.cs index 92eea715..2a73b737 100644 --- a/src/Yavsc.Server/Settings/SiteSettings.cs +++ b/src/Yavsc.Server/Settings/SiteSettings.cs @@ -14,14 +14,17 @@ namespace Yavsc public string FavIcon { get; set; } = "favicon.ico"; public string Logo { get; set; } = "logo.png"; /// - /// Conceptually, - /// This authorisation server only has this present site as unique audience. /// /// public string Audience { get; set; } = "lua.pschneider.fr"; + /// - /// it's a very small company, with one domaine name only, - /// so let it be the same as in the Audience field. + /// External Url + /// + /// + public string ExternalUrl { get; set; } = "http://lua.pschneider.fr"; + /// + /// Must be a fqdn. /// /// public string Authority { get; set; } = "lua.pschneider.fr"; diff --git a/src/Yavsc/Controllers/Accounting/AccountController.cs b/src/Yavsc/Controllers/Accounting/AccountController.cs index 7c38246d..2bcda6a2 100644 --- a/src/Yavsc/Controllers/Accounting/AccountController.cs +++ b/src/Yavsc/Controllers/Accounting/AccountController.cs @@ -84,9 +84,7 @@ namespace Yavsc.Controllers _logger = loggerFactory.CreateLogger(); _dbContext = dbContext; - var type = typeof(AccountController); - var assemblyName = new AssemblyName(type.GetTypeInfo().Assembly.FullName); - _localizer = localizerFactory.Create(type); + _localizer = localizerFactory.Create(typeof(AccountController)); } @@ -865,11 +863,13 @@ namespace Yavsc.Controllers { ApplicationUser user; // Username should not contain any '@' - if (model.LoginOrEmail.Contains('@')) { + if (model.LoginOrEmail.Contains('@')) + { user = await _userManager.FindByEmailAsync(model.LoginOrEmail); } - else { - user = await _dbContext.Users.FirstOrDefaultAsync( u => u.UserName == model.LoginOrEmail); + else + { + user = await _dbContext.Users.FirstOrDefaultAsync(u => u.UserName == model.LoginOrEmail); } // Don't reveal that the user does not exist or is not confirmed @@ -892,14 +892,17 @@ namespace Yavsc.Controllers // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713 // Send an email with this link var code = await _userManager.GeneratePasswordResetTokenAsync(user); - var callbackUrl = _siteSettings.Audience + "/Account/ResetPassword/" + + var f = this.HttpContext.Features; + var callbackUrl = _siteSettings.ExternalUrl + "/Account/ResetPassword/" + HttpUtility.UrlEncode(user.Id) + "/" + HttpUtility.UrlEncode(code); - - + + var sent = await _emailSender.SendEmailAsync(user.UserName, user.Email, _localizer["Reset Password"], _localizer["Please reset your password by "] + " following this link"); return View("ForgotPasswordConfirmation", sent); + + } // If we got this far, something failed, redisplay form @@ -1133,10 +1136,6 @@ namespace Yavsc.Controllers return await _userManager.DeleteAsync(user); } - - - #region Helpers - private void AddErrors(IdentityResult result) { foreach (var error in result.Errors) @@ -1145,15 +1144,5 @@ namespace Yavsc.Controllers } } - private async Task GetCurrentUserAsync() - { - return await GetCurrentUserAsync(HttpContext.User.GetUserId()); - } - private async Task GetCurrentUserAsync(string id) - { - return await _userManager.FindByIdAsync(id); - } - - #endregion } } diff --git a/src/Yavsc/Resources/Controllers/AccountController.en.resx b/src/Yavsc/Resources/Controllers/AccountController.en.resx index 90119a70..855b6a59 100644 --- a/src/Yavsc/Resources/Controllers/AccountController.en.resx +++ b/src/Yavsc/Resources/Controllers/AccountController.en.resx @@ -87,4 +87,6 @@ Please, follow this link to confirm your account : <{1}>. -- {0} - {2} <{3}> + Ré-initialiser votre mot de passe + Confirmation de ré-initialisation du mot de passe diff --git a/src/Yavsc/Resources/Controllers/AccountController.pt.resx b/src/Yavsc/Resources/Controllers/AccountController.pt.resx index 06f9c55d..d8f0a741 100644 --- a/src/Yavsc/Resources/Controllers/AccountController.pt.resx +++ b/src/Yavsc/Resources/Controllers/AccountController.pt.resx @@ -61,4 +61,6 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + Ré-initialiser votre mot de passe + Confirmation de ré-initialisation du mot de passe diff --git a/src/Yavsc/Resources/Controllers/AccountController.resx b/src/Yavsc/Resources/Controllers/AccountController.resx index 31866923..f5da0e9b 100644 --- a/src/Yavsc/Resources/Controllers/AccountController.resx +++ b/src/Yavsc/Resources/Controllers/AccountController.resx @@ -89,4 +89,6 @@ Vour pourrez cochez la case "Se souvenir de ce navigateur" pour conserver cette Un courrier a été envoyé pour confirmation de l'adresse e-mail . + Ré-initialiser votre mot de passe + Confirmation de ré-initialisation du mot de passe diff --git a/src/Yavsc/Resources/Yavsc.YavscLocalisation.resx b/src/Yavsc/Resources/Yavsc.YavscLocalisation.resx index 31fc091d..2d854f59 100644 --- a/src/Yavsc/Resources/Yavsc.YavscLocalisation.resx +++ b/src/Yavsc/Resources/Yavsc.YavscLocalisation.resx @@ -471,7 +471,6 @@ Votre code dáctivation est : {4} Vour pourrez cochez la case "Se souvenir de ce navigateur" pour conserver cette authorisation pour ce navigateur. {0} - {2} <{3}> - S'il vous plait, confirmez votre addresse e-mail Taille maximale: {0} caractère. Ce champ est diff --git a/src/Yavsc/tempkey.jwk b/src/Yavsc/tempkey.jwk new file mode 100644 index 00000000..8142abc1 --- /dev/null +++ b/src/Yavsc/tempkey.jwk @@ -0,0 +1 @@ +{"AdditionalData":{},"Alg":"RS256","Crv":null,"D":"HQxDb0hC8hkvwiC9eL7Xgi3oxVuD2KhYRf2LgdVbTNNp7hof2ZxHQaRJBUjXXWu5dgjEFTbYHugydnsUb-y9fO-Q_k2mHYrCwwRGRR8_B1bqX6Or98PDKMLj8JOCoRWUe238hUjqdfm3X-wjLco9iEe86UUWnhPhsTKQ8hGuI7vo5c5BEF9Y3T9duITK0c3hgJQGujLUQLbCCP2MX0BR-tmvnBPV1mPe5fMkW79CymmlBdc8RjPNA_YLtLD4znZGoh7Fr_G1WpO6HdDyqnjqIof9QFSY9zjGissOhs6k5xZrTdego6giHk_hhxLsHvf9lekfL1XcOt97j28mooXGUQ","DP":"5gUJNJI-z3swRqAX0YSZxKjD1bbOl-HgEU9Bkrz_U6myVGziVnjrrLT92ymu7XiERwhRm4Hv-UNgCSipUA5wkTNw_qANbibcMAqjLqtXtC9OOraE9zw0fw72BzFp3BF2AvaUZlByyr45IJGyVVOg-AxCgaLinoWa15hjpVVLBck","DQ":"MVwIv2v0k93-nqLkTfU7UXe5lifNfqwK_h6wFrlPv2eRiPFs016-9epfAYz4w0KqHaFzZtK-_XDet_f6-Vommn4DjahTzBbyUWKPxo2jmu06hne8naoeLYP0VqRtbVVlq_rP5VKwb3SMnxj02FjpuDdSvbaEgJiCLjfv-mP3x8c","E":"AQAB","K":null,"KeyId":"31CBEC0AA49B244C218F53DA8D15FAF8","KeyOps":[],"Kid":"31CBEC0AA49B244C218F53DA8D15FAF8","Kty":"RSA","N":"vrBmdOxP7dksWCfJieoorbBgxiPlgcY1QpBbESso_7XpcGbtwK7Nmfbe_sy_jtdEi586MQBb6g7W663hnQyZ5j9etC6uNo5XkqJ4oAPvjWjjdx7HPyjhkSOgj6dS-mGNCzn36ZLkZacAxvDhxh409QGWEe7MpFB6ZRK9bj7hn77FMFvTnI71YU3sL3w35W3wjw30jyw4oaAA6cDA0dLLSc5wutu76KPxcyQGOhXtcOnUd0c1XYuOIAffg6EcmGSe5nF5iCZYk9Y7MuYKH07w6cVlPgKuOATSOuMSo7bp7Kgd-tuqvelJbGryNoAd4V_Fo6pgLbJoY8IeZDr9CDxZgw","Oth":[],"P":"8WfFywgbOmCiJwupMdgNF0VsdZ5VcgsAwlkrLSWAvIzihD99Fz3J9VPYnLtXW5b144CfJLz8nEnMDYPTqYw_dZ2rT9rsiUUvbVzeKvDVTjDLYNvdhZeseyoXIVfoHStoAdKXQqdhcVtDcuv3E0zszfuAP-jMMh0cwlTfscjauz0","Q":"yjexMUjUY5RvhN127pC4NKqkD5PABxDgt3w8ENuJZbAo-dJ72Ay2MFGAhNMVp-DZIijS_OntyqTNLADhFmf8nh6ZNRyvRYNPpvkvb0qf4QgSn2TiXm3wJrKG8mTJuuFWnUDTf3D2GLFAHk2MtAemh3-C34SezLHORjkaEvqLs78","QI":"KQRvX-At5Rb16A0R7hE0JOB2oNJKcbAoQHKttFBU9KeQo17TIBzt4R_ABswbWjmLRN_mzfaag8nrN-mOeeOzzgqt3xMjibRB4HJ0MBndt5wi4SEyHt3Me_-7fUN85SZR6DsNt2w05QTojsUBq4ah4RXAXIT5SqwcUE4ztBbM5Vw","Use":null,"X":null,"X5c":[],"X5t":null,"X5tS256":null,"X5u":null,"Y":null,"KeySize":2048,"HasPrivateKey":true,"CryptoProviderFactory":{"CryptoProviderCache":{},"CustomCryptoProvider":null,"CacheSignatureProviders":true,"SignatureProviderObjectPoolCacheSize":16}} \ No newline at end of file