login form validation

This commit is contained in:
Shaun Walker 2021-04-02 16:14:02 -04:00
parent 6606ebb58a
commit 61b73060e5
4 changed files with 102 additions and 64 deletions

View File

@ -11,26 +11,28 @@
} }
<AuthorizeView> <AuthorizeView>
<NotAuthorized> <NotAuthorized>
<div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))"> <form @ref="login" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
<div class="form-group"> <div class="container Oqtane-Modules-Admin-Login" @onkeypress="@(e => KeyPressed(e))">
<label for="Username" class="control-label">@Localizer["Username:"] </label> <div class="form-group">
<input type="text" @ref="username" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" /> <label for="Username" class="control-label">@Localizer["Username:"] </label>
</div> <input type="text" @ref="username" name="Username" class="form-control username" placeholder="Username" @bind="@_username" id="Username" required />
<div class="form-group">
<label for="Password" class="control-label">@Localizer["Password:"] </label>
<input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" />
</div>
<div class="form-group">
<div class="form-check form-check-inline">
<label class="form-check-label" for="Remember">@Localizer["Remember Me?"]</label>&nbsp;
<input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
</div> </div>
<div class="form-group">
<label for="Password" class="control-label">@Localizer["Password:"] </label>
<input type="password" name="Password" class="form-control password" placeholder="Password" @bind="@_password" id="Password" required />
</div>
<div class="form-group">
<div class="form-check form-check-inline">
<label class="form-check-label" for="Remember">@Localizer["Remember Me?"]</label>&nbsp;
<input type="checkbox" class="form-check-input" name="Remember" @bind="@_remember" id="Remember" />
</div>
</div>
<button type="button" class="btn btn-primary" @onclick="Login">@Localizer["Login"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
<br /><br />
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["Forgot Password"]</button>
</div> </div>
<button type="button" class="btn btn-primary" @onclick="Login">@Localizer["Login"]</button> </form>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@Localizer["Cancel"]</button>
<br /><br />
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["Forgot Password"]</button>
</div>
</NotAuthorized> </NotAuthorized>
</AuthorizeView> </AuthorizeView>
@ -41,6 +43,9 @@
private string _username = string.Empty; private string _username = string.Empty;
private string _password = string.Empty; private string _password = string.Empty;
private bool _remember = false; private bool _remember = false;
private bool validated = false;
private ElementReference login;
private ElementReference username; private ElementReference username;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous; public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
@ -91,50 +96,58 @@
private async Task Login() private async Task Login()
{ {
if (PageState.Runtime == Oqtane.Shared.Runtime.Server) validated = true;
var interop = new Interop(JSRuntime);
if (await interop.FormValid(login))
{ {
// server-side Blazor if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = _username;
user.Password = _password;
user = await UserService.LoginUserAsync(user, false, false);
if (user.IsAuthenticated)
{ {
await logger.LogInformation("Login Successful For Username {Username}", _username); // server-side Blazor
// complete the login on the server so that the cookies are set correctly on SignalR var user = new User();
var interop = new Interop(JSRuntime); user.SiteId = PageState.Site.SiteId;
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken"); user.Username = _username;
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl }; user.Password = _password;
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields); user = await UserService.LoginUserAsync(user, false, false);
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
// complete the login on the server so that the cookies are set correctly on SignalR
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
await interop.SubmitForm($"/{PageState.Alias.AliasId}/pages/login/", fields);
}
else
{
await logger.LogInformation("Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
}
} }
else else
{ {
await logger.LogInformation("Login Failed For Username {Username}", _username); // client-side Blazor
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Email Verification When They Initially Created."], MessageType.Error); var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = _username;
user.Password = _password;
user = await UserService.LoginUserAsync(user, true, _remember);
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
}
else
{
await logger.LogInformation("Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
}
} }
} }
else else
{ {
// client-side Blazor AddModuleMessage(Localizer["Please Provide Your Username And Password"], MessageType.Warning);
var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = _username;
user.Password = _password;
user = await UserService.LoginUserAsync(user, true, _remember);
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, "reload"));
}
else
{
await logger.LogInformation("Login Failed For Username {Username}", _username);
AddModuleMessage(Localizer["Login Failed. Please Remember That Passwords Are Case Sensitive And User Accounts Require Verification When They Are Initially Created So You May Wish To Check Your Email."], MessageType.Error);
}
} }
} }

View File

@ -1,3 +1,4 @@
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop; using Microsoft.JSInterop;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -232,5 +233,19 @@ namespace Oqtane.UI
return Task.CompletedTask; return Task.CompletedTask;
} }
} }
public ValueTask<bool> FormValid(ElementReference form)
{
try
{
return _jsRuntime.InvokeAsync<bool>(
"Oqtane.Interop.formValid",
form);
}
catch
{
return new ValueTask<bool>(Task.FromResult(false));
}
}
} }
} }

View File

@ -74,22 +74,29 @@
{ {
try try
{ {
if (PageState.Action == "Add") if (string.IsNullOrEmpty(_name))
{ {
[Module] [Module] = new [Module](); if (PageState.Action == "Add")
[Module].ModuleId = ModuleState.ModuleId; {
[Module].Name = _name; [Module] [Module] = new [Module]();
[Module] = await [Module]Service.Add[Module]Async([Module]); [Module].ModuleId = ModuleState.ModuleId;
await logger.LogInformation("[Module] Added {[Module]}", [Module]); [Module].Name = _name;
[Module] = await [Module]Service.Add[Module]Async([Module]);
await logger.LogInformation("[Module] Added {[Module]}", [Module]);
}
else
{
[Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId);
[Module].Name = _name;
await [Module]Service.Update[Module]Async([Module]);
await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
}
NavigationManager.NavigateTo(NavigateUrl());
} }
else else
{ {
[Module] [Module] = await [Module]Service.Get[Module]Async(_id, ModuleState.ModuleId); AddModuleMessage("The Name Is Required", MessageType.Warning);
[Module].Name = _name;
await [Module]Service.Update[Module]Async([Module]);
await logger.LogInformation("[Module] Updated {[Module]}", [Module]);
} }
NavigationManager.NavigateTo(NavigateUrl());
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@ -362,5 +362,8 @@ Oqtane.Interop = {
setInterval(function () { setInterval(function () {
window.location.href = url; window.location.href = url;
}, wait * 1000); }, wait * 1000);
},
formValid: function (formRef) {
return formRef.checkValidity();
} }
}; };