added support for Forgot Username and Use Login Link
This commit is contained in:
@@ -4,10 +4,8 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Security.Policy;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Oqtane.Enums;
|
||||
@@ -30,7 +28,8 @@ namespace Oqtane.Managers
|
||||
Task<User> LoginUser(User user, bool setCookie, bool isPersistent);
|
||||
Task LogoutUserEverywhere(User user);
|
||||
Task<User> VerifyEmail(User user, string token);
|
||||
Task ForgotPassword(User user);
|
||||
Task<User> ForgotPassword(User user);
|
||||
Task<User> ForgotUsername(User user);
|
||||
Task<User> ResetPassword(User user, string token);
|
||||
User VerifyTwoFactor(User user, string token);
|
||||
Task<UserValidateResult> ValidateUser(string username, string email, string password);
|
||||
@@ -42,6 +41,7 @@ namespace Oqtane.Managers
|
||||
Task<List<UserLogin>> GetLogins(int userId, int siteId);
|
||||
Task<User> AddLogin(User user, string token, string type, string key, string name);
|
||||
Task DeleteLogin(int userId, string provider, string key);
|
||||
Task<User> SendLoginLink(User user);
|
||||
}
|
||||
|
||||
public class UserManager : IUserManager
|
||||
@@ -519,14 +519,16 @@ namespace Oqtane.Managers
|
||||
}
|
||||
return user;
|
||||
}
|
||||
public async Task ForgotPassword(User user)
|
||||
|
||||
public async Task<User> ForgotPassword(User user)
|
||||
{
|
||||
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
||||
if (identityuser != null)
|
||||
{
|
||||
var alias = _tenantManager.GetAlias();
|
||||
user = _users.GetUser(user.Username);
|
||||
string token = await _identityUserManager.GeneratePasswordResetTokenAsync(identityuser);
|
||||
|
||||
var alias = _tenantManager.GetAlias();
|
||||
user = GetUser(user.Username, alias.SiteId);
|
||||
string url = alias.Protocol + alias.Name + "/reset?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||
string siteName = _sites.GetSite(alias.SiteId).Name;
|
||||
string subject = _localizer["ForgotPasswordEmailSubject"];
|
||||
@@ -537,11 +539,51 @@ namespace Oqtane.Managers
|
||||
body = body.Replace("[SiteName]", siteName);
|
||||
var notification = new Notification(_tenantManager.GetAlias().SiteId, user, subject, body);
|
||||
_notifications.AddNotification(notification);
|
||||
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset Notification Sent For {Username}", user.Username);
|
||||
return new User { UserId = user.UserId, Username = user.Username, Email = user.Email }; // minimal object
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Notification Failed For {Username}", user.Username);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<User> ForgotUsername(User user)
|
||||
{
|
||||
try
|
||||
{
|
||||
IdentityUser identityuser = await _identityUserManager.FindByEmailAsync(user.Email);
|
||||
if (identityuser != null)
|
||||
{
|
||||
var alias = _tenantManager.GetAlias();
|
||||
user = GetUser(identityuser.UserName, alias.SiteId);
|
||||
string url = alias.Protocol + alias.Name + "/login?name=" + user.Username;
|
||||
string siteName = _sites.GetSite(alias.SiteId).Name;
|
||||
string subject = _localizer["ForgotUsernameEmailSubject"];
|
||||
subject = subject.Replace("[SiteName]", siteName);
|
||||
string body = _localizer["ForgotUsernameEmailBody"].Value;
|
||||
body = body.Replace("[UserDisplayName]", user.DisplayName);
|
||||
body = body.Replace("[URL]", url);
|
||||
body = body.Replace("[SiteName]", siteName);
|
||||
var notification = new Notification(_tenantManager.GetAlias().SiteId, user, subject, body);
|
||||
_notifications.AddNotification(notification);
|
||||
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Forgot Username Notification Sent For {Email}", user.Email);
|
||||
return new User { UserId = user.UserId, Username = user.Username, Email = user.Email }; // minimal object
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Forgot Username Notification Failed For {Email}", user.Email);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// email may not be unique
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Forgot Username Notification Failed For {Email}", user.Email);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -588,6 +630,7 @@ namespace Oqtane.Managers
|
||||
}
|
||||
return user;
|
||||
}
|
||||
|
||||
public async Task<UserValidateResult> ValidateUser(string username, string email, string password)
|
||||
{
|
||||
var validateResult = new UserValidateResult { Succeeded = true };
|
||||
@@ -914,5 +957,49 @@ namespace Oqtane.Managers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<User> SendLoginLink(User user)
|
||||
{
|
||||
try
|
||||
{
|
||||
IdentityUser identityuser = await _identityUserManager.FindByEmailAsync(user.Email);
|
||||
if (identityuser != null)
|
||||
{
|
||||
var token = await _identityUserManager.GenerateTwoFactorTokenAsync(identityuser, "Email");
|
||||
|
||||
var alias = _tenantManager.GetAlias();
|
||||
user = GetUser(identityuser.UserName, alias.SiteId);
|
||||
user.TwoFactorCode = token;
|
||||
user.TwoFactorExpiry = DateTime.UtcNow.AddMinutes(10);
|
||||
_users.UpdateUser(user);
|
||||
|
||||
string url = alias.Protocol + alias.Name + "/pages/loginlink?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||
string siteName = _sites.GetSite(alias.SiteId).Name;
|
||||
string subject = _localizer["LoginLinkEmailSubject"];
|
||||
subject = subject.Replace("[SiteName]", siteName);
|
||||
string body = _localizer["LoginLinkEmailBody"].Value;
|
||||
body = body.Replace("[UserDisplayName]", user.DisplayName);
|
||||
body = body.Replace("[URL]", url);
|
||||
body = body.Replace("[SiteName]", siteName);
|
||||
var notification = new Notification(_tenantManager.GetAlias().SiteId, user, subject, body);
|
||||
_notifications.AddNotification(notification);
|
||||
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Login Link Notification Sent To {Email}", user.Email);
|
||||
return new User { UserId = user.UserId, Username = user.Username, Email = user.Email }; // minimal object
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Login Link Notification Failed For {Email}", user.Email);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// email may not be unique
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Login Link Notification Failed For {Email}", user.Email);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user