commit
acc4099ac8
@ -93,45 +93,53 @@
|
|||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_togglepassword = Localizer["ShowPassword"];
|
try
|
||||||
|
|
||||||
if (PageState.Site.Settings.ContainsKey("LoginOptions:AllowSiteLogin") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]))
|
|
||||||
{
|
{
|
||||||
_allowsitelogin = bool.Parse(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]);
|
_togglepassword = Localizer["ShowPassword"];
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.Site.Settings.ContainsKey("ExternalLogin:ProviderType") && !string.IsNullOrEmpty(PageState.Site.Settings["ExternalLogin:ProviderType"]))
|
if (PageState.Site.Settings.ContainsKey("LoginOptions:AllowSiteLogin") && !string.IsNullOrEmpty(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]))
|
||||||
{
|
|
||||||
_allowexternallogin = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
|
||||||
{
|
|
||||||
_returnUrl = PageState.QueryString["returnurl"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("name"))
|
|
||||||
{
|
|
||||||
_username = PageState.QueryString["name"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("token"))
|
|
||||||
{
|
|
||||||
var user = new User();
|
|
||||||
user.SiteId = PageState.Site.SiteId;
|
|
||||||
user.Username = _username;
|
|
||||||
user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]);
|
|
||||||
|
|
||||||
if (user != null)
|
|
||||||
{
|
{
|
||||||
await logger.LogInformation(LogFunction.Security, "Email Verified For For Username {Username}", _username);
|
_allowsitelogin = bool.Parse(PageState.Site.Settings["LoginOptions:AllowSiteLogin"]);
|
||||||
AddModuleMessage(Localizer["Success.Account.Verified"], MessageType.Info);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (PageState.Site.Settings.ContainsKey("ExternalLogin:ProviderType") && !string.IsNullOrEmpty(PageState.Site.Settings["ExternalLogin:ProviderType"]))
|
||||||
{
|
{
|
||||||
await logger.LogError(LogFunction.Security, "Email Verification Failed For Username {Username}", _username);
|
_allowexternallogin = true;
|
||||||
AddModuleMessage(Localizer["Message.Account.NotVerfied"], MessageType.Warning);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PageState.QueryString.ContainsKey("returnurl"))
|
||||||
|
{
|
||||||
|
_returnUrl = PageState.QueryString["returnurl"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PageState.QueryString.ContainsKey("name"))
|
||||||
|
{
|
||||||
|
_username = PageState.QueryString["name"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PageState.QueryString.ContainsKey("token"))
|
||||||
|
{
|
||||||
|
var user = new User();
|
||||||
|
user.SiteId = PageState.Site.SiteId;
|
||||||
|
user.Username = _username;
|
||||||
|
user = await UserService.VerifyEmailAsync(user, PageState.QueryString["token"]);
|
||||||
|
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
await logger.LogInformation(LogFunction.Security, "Email Verified For For Username {Username}", _username);
|
||||||
|
AddModuleMessage(Localizer["Success.Account.Verified"], MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await logger.LogError(LogFunction.Security, "Email Verification Failed For Username {Username}", _username);
|
||||||
|
AddModuleMessage(Localizer["Message.Account.NotVerfied"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Login {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.LoadLogin"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,65 +153,73 @@
|
|||||||
|
|
||||||
private async Task Login()
|
private async Task Login()
|
||||||
{
|
{
|
||||||
validated = true;
|
try
|
||||||
var interop = new Interop(JSRuntime);
|
|
||||||
if (await interop.FormValid(login))
|
|
||||||
{
|
{
|
||||||
var user = new User { SiteId = PageState.Site.SiteId, Username = _username, Password = _password};
|
validated = true;
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
if (!twofactor)
|
if (await interop.FormValid(login))
|
||||||
{
|
{
|
||||||
user = await UserService.LoginUserAsync(user, false, false);
|
var user = new User { SiteId = PageState.Site.SiteId, Username = _username, Password = _password};
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
user = await UserService.VerifyTwoFactorAsync(user, _code);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user.IsAuthenticated)
|
if (!twofactor)
|
||||||
{
|
|
||||||
await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username);
|
|
||||||
|
|
||||||
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
|
|
||||||
{
|
{
|
||||||
// server-side Blazor needs to post to the Login page so that the cookies are set correctly
|
user = await UserService.LoginUserAsync(user, false, false);
|
||||||
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
|
||||||
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
|
|
||||||
await interop.SubmitForm(url, fields);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
user = await UserService.VerifyTwoFactorAsync(user, _code);
|
||||||
authstateprovider.NotifyAuthenticationChanged();
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
if (user.IsAuthenticated)
|
||||||
{
|
|
||||||
if (user.TwoFactorRequired)
|
|
||||||
{
|
{
|
||||||
twofactor = true;
|
await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username);
|
||||||
validated = false;
|
|
||||||
AddModuleMessage(Localizer["Message.TwoFactor"], MessageType.Info);
|
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!twofactor)
|
|
||||||
{
|
{
|
||||||
await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username);
|
// server-side Blazor needs to post to the Login page so that the cookies are set correctly
|
||||||
AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);
|
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||||
|
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
|
||||||
|
await interop.SubmitForm(url, fields);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await logger.LogInformation(LogFunction.Security, "Two Factor Verification Failed For Username {Username}", _username);
|
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||||
AddModuleMessage(Localizer["Error.TwoFactor.Fail"], MessageType.Error);
|
authstateprovider.NotifyAuthenticationChanged();
|
||||||
|
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (user.TwoFactorRequired)
|
||||||
|
{
|
||||||
|
twofactor = true;
|
||||||
|
validated = false;
|
||||||
|
AddModuleMessage(Localizer["Message.TwoFactor"], MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!twofactor)
|
||||||
|
{
|
||||||
|
await logger.LogInformation(LogFunction.Security, "Login Failed For Username {Username}", _username);
|
||||||
|
AddModuleMessage(Localizer["Error.Login.Fail"], MessageType.Error);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await logger.LogInformation(LogFunction.Security, "Two Factor Verification Failed For Username {Username}", _username);
|
||||||
|
AddModuleMessage(Localizer["Error.TwoFactor.Fail"], MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Required.UserInfo"], MessageType.Warning);
|
await logger.LogError(ex, "Error Performing Login {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Login"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,26 +230,34 @@
|
|||||||
|
|
||||||
private async Task Forgot()
|
private async Task Forgot()
|
||||||
{
|
{
|
||||||
if (_username != string.Empty)
|
try
|
||||||
{
|
{
|
||||||
var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId);
|
if (_username != string.Empty)
|
||||||
if (user != null)
|
|
||||||
{
|
{
|
||||||
await UserService.ForgotPasswordAsync(user);
|
var user = await UserService.GetUserAsync(_username, PageState.Site.SiteId);
|
||||||
await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username);
|
if (user != null)
|
||||||
AddModuleMessage(Localizer["Message.ForgotUser"], MessageType.Info);
|
{
|
||||||
|
await UserService.ForgotPasswordAsync(user);
|
||||||
|
await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username);
|
||||||
|
AddModuleMessage(Localizer["Message.ForgotUser"], MessageType.Info);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.UserDoesNotExist"], MessageType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.UserDoesNotExist"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.ForgotPassword"], MessageType.Info);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Message.ForgotPassword"], MessageType.Info);
|
|
||||||
}
|
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Resetting Password {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.ResetPassword"], MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Reset()
|
private void Reset()
|
||||||
|
@ -155,7 +155,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.PageId != null && log.ModuleId != null)
|
if (log.PageId != null && log.ModuleId != null && log.ModuleId != -1)
|
||||||
{
|
{
|
||||||
var pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value);
|
var pagemodule = await PageModuleService.GetPageModuleAsync(log.PageId.Value, log.ModuleId.Value);
|
||||||
if (pagemodule != null)
|
if (pagemodule != null)
|
||||||
|
@ -192,4 +192,13 @@
|
|||||||
<data name="Use" xml:space="preserve">
|
<data name="Use" xml:space="preserve">
|
||||||
<value>Use</value>
|
<value>Use</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error.LoadLogin" xml:space="preserve">
|
||||||
|
<value>Error Loading Login</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.Login" xml:space="preserve">
|
||||||
|
<value>Error Performing Login</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.ResetPassword" xml:space="preserve">
|
||||||
|
<value>Error Resetting Password</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -34,7 +34,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
protected async Task LogoutUser()
|
protected async Task LogoutUser()
|
||||||
{
|
{
|
||||||
await UserService.LogoutUserAsync(PageState.User);
|
await UserService.LogoutUserAsync(PageState.User);
|
||||||
await LoggingService.Log(PageState.Alias, PageState.Page.PageId, PageState.ModuleId, PageState.User.UserId, GetType().AssemblyQualifiedName, "Logout", LogFunction.Security, LogLevel.Information, null, "User Logout For Username {Username}", PageState.User.Username);
|
await LoggingService.Log(PageState.Alias, PageState.Page.PageId, null, PageState.User.UserId, GetType().AssemblyQualifiedName, "Logout", LogFunction.Security, LogLevel.Information, null, "User Logout For Username {Username}", PageState.User.Username);
|
||||||
PageState.User = null;
|
PageState.User = null;
|
||||||
|
|
||||||
var url = PageState.Alias.Path + "/" + PageState.Page.Path;
|
var url = PageState.Alias.Path + "/" + PageState.Page.Path;
|
||||||
|
@ -184,7 +184,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
options.SignIn.RequireConfirmedPhoneNumber = false;
|
options.SignIn.RequireConfirmedPhoneNumber = false;
|
||||||
|
|
||||||
// User settings
|
// User settings
|
||||||
options.User.RequireUniqueEmail = true;
|
options.User.RequireUniqueEmail = false; // changing to true will cause issues for legacy data
|
||||||
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
|
options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -199,56 +199,73 @@ namespace Oqtane.Extensions
|
|||||||
}
|
}
|
||||||
User user = null;
|
User user = null;
|
||||||
|
|
||||||
var identityuser = await _identityUserManager.FindByEmailAsync(email);
|
bool duplicates = false;
|
||||||
|
IdentityUser identityuser = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
identityuser = await _identityUserManager.FindByEmailAsync(email);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// FindByEmailAsync will throw an error if the email matches multiple user accounts
|
||||||
|
duplicates = true;
|
||||||
|
}
|
||||||
if (identityuser == null)
|
if (identityuser == null)
|
||||||
{
|
{
|
||||||
if (bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:CreateUsers", "true")))
|
if (duplicates)
|
||||||
{
|
{
|
||||||
identityuser = new IdentityUser();
|
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, "Multiple Users Exist With Email Address {Email}. Login Denied.", email);
|
||||||
identityuser.UserName = email;
|
}
|
||||||
identityuser.Email = email;
|
else
|
||||||
identityuser.EmailConfirmed = true;
|
{
|
||||||
var result = await _identityUserManager.CreateAsync(identityuser, DateTime.UtcNow.ToString("yyyy-MMM-dd-HH-mm-ss"));
|
if (bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:CreateUsers", "true")))
|
||||||
if (result.Succeeded)
|
|
||||||
{
|
{
|
||||||
user = new User
|
identityuser = new IdentityUser();
|
||||||
|
identityuser.UserName = email;
|
||||||
|
identityuser.Email = email;
|
||||||
|
identityuser.EmailConfirmed = true;
|
||||||
|
var result = await _identityUserManager.CreateAsync(identityuser, DateTime.UtcNow.ToString("yyyy-MMM-dd-HH-mm-ss"));
|
||||||
|
if (result.Succeeded)
|
||||||
{
|
{
|
||||||
SiteId = httpContext.GetAlias().SiteId,
|
user = new User
|
||||||
Username = email,
|
{
|
||||||
DisplayName = email,
|
SiteId = httpContext.GetAlias().SiteId,
|
||||||
Email = email,
|
Username = email,
|
||||||
LastLoginOn = null,
|
DisplayName = email,
|
||||||
LastIPAddress = ""
|
Email = email,
|
||||||
};
|
LastLoginOn = null,
|
||||||
user = _users.AddUser(user);
|
LastIPAddress = ""
|
||||||
|
};
|
||||||
|
user = _users.AddUser(user);
|
||||||
|
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
|
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
|
||||||
string url = httpContext.Request.Scheme + "://" + httpContext.GetAlias().Name;
|
string url = httpContext.Request.Scheme + "://" + httpContext.GetAlias().Name;
|
||||||
string body = "You Recently Used An External Account To Sign In To Our Site.\n\n" + url + "\n\nThank You!";
|
string body = "You Recently Used An External Account To Sign In To Our Site.\n\n" + url + "\n\nThank You!";
|
||||||
var notification = new Notification(user.SiteId, user, "User Account Notification", body);
|
var notification = new Notification(user.SiteId, user, "User Account Notification", body);
|
||||||
_notifications.AddNotification(notification);
|
_notifications.AddNotification(notification);
|
||||||
|
|
||||||
// add user login
|
// add user login
|
||||||
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType, providerKey, ""));
|
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType, providerKey, ""));
|
||||||
|
|
||||||
_logger.Log(user.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "User Added {User}", user);
|
_logger.Log(user.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "User Added {User}", user);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(user.SiteId, LogLevel.Error, "ExternalLogin", Enums.LogFunction.Create, "Unable To Add User {Email}", email);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(user.SiteId, LogLevel.Error, "ExternalLogin", Enums.LogFunction.Create, "Unable To Add User {Email}", email);
|
_logger.Log(user.SiteId, LogLevel.Error, "ExternalLogin", Enums.LogFunction.Create, "Unable To Add Identity User {Email} {Error}", email, result.Errors.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(user.SiteId, LogLevel.Error, "ExternalLogin", Enums.LogFunction.Create, "Unable To Add Identity User {Email} {Error}", email, result.Errors.ToString());
|
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, "Creation Of New Users Is Disabled For This Site. User With Email Address {Email} Will First Need To Be Registered On The Site.", email);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, "Creation Of New Users Is Disabled For This Site. User With Email Address {Email} Will First Need To Be Registered On The Site.", email);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user