Upgraded the last forms to the new mooncore version
This commit is contained in:
@@ -1,9 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
|
|
||||||
namespace Moonlight.Core.Models.Forms;
|
|
||||||
|
|
||||||
public class ChangeCookiesForm
|
|
||||||
{
|
|
||||||
[Description("This specifies if you would like to personalize your experience with optional cookies.")]
|
|
||||||
public bool UseOptionalCookies { get; set; } = false;
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
@using MoonCore.Exceptions
|
@using MoonCore.Exceptions
|
||||||
|
|
||||||
@inject IdentityService IdentityService
|
@inject IdentityService IdentityService
|
||||||
|
@inject AlertService AlertService
|
||||||
@inject IAuthenticationProvider AuthenticationProvider
|
@inject IAuthenticationProvider AuthenticationProvider
|
||||||
|
|
||||||
@if (IdentityService.CurrentUser.Totp)
|
@if (IdentityService.CurrentUser.Totp)
|
||||||
@@ -61,15 +62,15 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<SmartForm Model="CodeForm" OnValidSubmit="VerifyAndEnable">
|
<div>
|
||||||
<input @bind="CodeForm.Code" type="number" class="form-control form-control-lg form-control-solid text-center my-8" placeholder="Enter authentication code" name="code">
|
<input @bind="CodeForm.Code" type="number" class="form-control form-control-lg form-control-solid text-center my-8" placeholder="Enter authentication code" name="code">
|
||||||
<div class="d-flex justify-content-center">
|
<div class="d-flex justify-content-center">
|
||||||
<button type="submit" class="btn btn-primary">
|
<WButton OnClick="VerifyAndEnable" CssClasses="btn btn-primary">
|
||||||
Continue
|
Continue
|
||||||
<i class="bx bx-sm bx-right-arrow-alt"></i>
|
<i class="bx bx-sm bx-right-arrow-alt"></i>
|
||||||
</button>
|
</WButton>
|
||||||
</div>
|
</div>
|
||||||
</SmartForm>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -170,7 +171,10 @@ else
|
|||||||
var correctCode = totp.ComputeTotp();
|
var correctCode = totp.ComputeTotp();
|
||||||
|
|
||||||
if (CodeForm.Code != correctCode)
|
if (CodeForm.Code != correctCode)
|
||||||
throw new DisplayException("Invalid code entered. Please try again");
|
{
|
||||||
|
await AlertService.Danger("Invalid code entered. Please try again");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Enable two factor auth for user
|
// Enable two factor auth for user
|
||||||
await AuthenticationProvider.SetTwoFactorSecret(IdentityService.CurrentUser, Key);
|
await AuthenticationProvider.SetTwoFactorSecret(IdentityService.CurrentUser, Key);
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
@page "/account"
|
@page "/account"
|
||||||
|
|
||||||
|
@using System.ComponentModel.DataAnnotations
|
||||||
@using Moonlight.Core.Services
|
@using Moonlight.Core.Services
|
||||||
@using Moonlight.Core.Models.Forms
|
@using Moonlight.Core.Models.Forms
|
||||||
@using Mappy.Net
|
@using Mappy.Net
|
||||||
|
@using Moonlight.Core.Database.Entities
|
||||||
@using Moonlight.Core.Models.Abstractions
|
@using Moonlight.Core.Models.Abstractions
|
||||||
@using Moonlight.Core.UI.Components.Navigations
|
@using Moonlight.Core.UI.Components.Navigations
|
||||||
|
|
||||||
@@ -22,53 +24,73 @@
|
|||||||
|
|
||||||
<AccountNavigation Index="0"/>
|
<AccountNavigation Index="0"/>
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<div class="row g-5">
|
||||||
|
<div class="col-md-3 col-12">
|
||||||
<div class="row g-5">
|
<div class="card card-body h-100">
|
||||||
<div class="col-md-3 col-12">
|
<div class="d-flex flex-column justify-content-center">
|
||||||
<div class="card card-body h-100">
|
<div class="d-flex justify-content-center">
|
||||||
<div class="d-flex flex-column justify-content-center">
|
<div class="symbol symbol-100px symbol-lg-160px symbol-fixed">
|
||||||
<div class="d-flex justify-content-center">
|
<img src="/api/core/avatar" alt="image">
|
||||||
<div class="symbol symbol-100px symbol-lg-160px symbol-fixed">
|
|
||||||
<img src="/api/core/avatar" alt="image">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="fs-4 mt-5 text-center">
|
|
||||||
To change your profile picture go to <a href="https://gravatar.com/">Gravatar</a> and
|
|
||||||
register with the same email address you are using here
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="fs-4 mt-5 text-center">
|
||||||
|
To change your profile picture go to <a href="https://gravatar.com/">Gravatar</a> and
|
||||||
|
register with the same email address you are using here
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9 col-12">
|
</div>
|
||||||
<div class="card">
|
<div class="col-md-9 col-12">
|
||||||
<SmartForm Model="Form" OnValidSubmit="Update">
|
<div class="card">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<AutoForm TForm="UpdateAccountForm" Columns="12" Model="Form"/>
|
<FastForm @ref="Form" Model="User" OnConfigure="OnConfigure" />
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer d-flex justify-content-end">
|
<div class="card-footer d-flex justify-content-end">
|
||||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
<WButton OnClick="SaveChanges" CssClasses="btn btn-primary">Save changes</WButton>
|
||||||
</div>
|
|
||||||
</SmartForm>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</LazyLoader>
|
</div>
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private UpdateAccountForm Form = new();
|
private User User;
|
||||||
|
private FastForm<User> Form;
|
||||||
|
|
||||||
private Task Load(LazyLoader _)
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
Form = Mapper.Map<UpdateAccountForm>(IdentityService.CurrentUser);
|
// Create a copy of the user
|
||||||
|
User = Mapper.Map<User>(IdentityService.CurrentUser);
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Update()
|
private void OnConfigure(FastFormConfiguration<User> configuration)
|
||||||
{
|
{
|
||||||
await AuthenticationProvider.ChangeDetails(IdentityService.CurrentUser, Form.Email, Form.Username);
|
configuration.AddProperty(x => x.Username)
|
||||||
|
.WithComponent<StringComponent>(component =>
|
||||||
|
{
|
||||||
|
component.ColumnsMd = 12;
|
||||||
|
})
|
||||||
|
.WithValidation(FastFormValidators.Required)
|
||||||
|
.WithValidation(RegexValidator.Create("^[a-z][a-z0-9]*$", "Usernames can only contain lowercase characters and numbers and should not start with a number"))
|
||||||
|
.WithValidation(x => x.Length >= 6 ? ValidationResult.Success : new("The username is too short"))
|
||||||
|
.WithValidation(x => x.Length <= 20 ? ValidationResult.Success : new("The username cannot be longer than 20 characters"));
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.Email)
|
||||||
|
.WithComponent<StringComponent>(component =>
|
||||||
|
{
|
||||||
|
component.ColumnsMd = 12;
|
||||||
|
component.Type = "email";
|
||||||
|
})
|
||||||
|
.WithValidation(FastFormValidators.Required)
|
||||||
|
.WithValidation(RegexValidator.Create("^.+@.+$", "You need to provide a valid email address"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task SaveChanges()
|
||||||
|
{
|
||||||
|
if(!await Form.Submit())
|
||||||
|
return;
|
||||||
|
|
||||||
|
await AuthenticationProvider.ChangeDetails(IdentityService.CurrentUser, User.Email, User.Username);
|
||||||
await ToastService.Success("Successfully updated details");
|
await ToastService.Success("Successfully updated details");
|
||||||
|
|
||||||
// This will trigger a re-render as well as an update of the model
|
// This will trigger a re-render as well as an update of the model
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
@page "/account/security"
|
@page "/account/security"
|
||||||
|
|
||||||
|
@using System.ComponentModel.DataAnnotations
|
||||||
@using Moonlight.Core.Services
|
@using Moonlight.Core.Services
|
||||||
@using Moonlight.Core.UI.Components.Navigations
|
@using Moonlight.Core.UI.Components.Navigations
|
||||||
@using Moonlight.Core.Models.Forms
|
@using Moonlight.Core.Models.Forms
|
||||||
@@ -23,74 +24,97 @@
|
|||||||
|
|
||||||
<AccountNavigation Index="1"/>
|
<AccountNavigation Index="1"/>
|
||||||
|
|
||||||
<LazyLoader Load="Load">
|
<div class="row g-5">
|
||||||
<div class="row g-5">
|
<div class="col-md-6 col-12">
|
||||||
<div class="col-md-6 col-12">
|
<div class="card">
|
||||||
<div class="card">
|
<div class="card-body">
|
||||||
<SmartForm Model="PasswordForm" OnValidSubmit="OnValidSubmitPassword">
|
<FastForm @ref="PasswordForm" Model="PasswordModel" OnConfigure="OnConfigurePasswordForm" />
|
||||||
<div class="card-body">
|
|
||||||
<div class="row">
|
|
||||||
<AutoForm Model="PasswordForm" Columns="12" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer d-flex justify-content-end">
|
|
||||||
<button class="btn btn-primary" type="submit">Save changes</button>
|
|
||||||
</div>
|
|
||||||
</SmartForm>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="card-footer d-flex justify-content-end">
|
||||||
<div class="col-md-6 col-12">
|
<WButton OnClick="ChangePassword" CssClasses="btn btn-primary">Save changes</WButton>
|
||||||
<div class="card h-100">
|
|
||||||
<div class="card-body">
|
|
||||||
<TwoFactorWizard />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6 col-12">
|
|
||||||
<div class="card h-100">
|
|
||||||
<SmartForm Model="CookiesForm" OnValidSubmit="OnValidSubmitCookie">
|
|
||||||
<div class="card-body">
|
|
||||||
<h3>Cookies</h3>
|
|
||||||
<div>
|
|
||||||
|
|
||||||
<AutoForm Model="CookiesForm"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-footer d-flex justify-content-end">
|
|
||||||
<button class="btn btn-primary" type="submit">Save changes</button>
|
|
||||||
</div>
|
|
||||||
</SmartForm>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</LazyLoader>
|
<div class="col-md-6 col-12">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<TwoFactorWizard />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-12">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3>Cookies</h3>
|
||||||
|
<p class="my-2 text-muted fs-5">
|
||||||
|
This specifies if you would like to personalize your experience with optional cookies.
|
||||||
|
</p>
|
||||||
|
<div class="form-check form-switch">
|
||||||
|
@if (CookieConsent)
|
||||||
|
{
|
||||||
|
<input @onclick="() => SetCookieConsent(false)" class="form-check-input" type="checkbox" role="switch" checked="checked">
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<input @onclick="() => SetCookieConsent(true)" class="form-check-input" type="checkbox" role="switch">
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
@code
|
@code
|
||||||
{
|
{
|
||||||
private readonly ChangePasswordForm PasswordForm = new();
|
private ChangePasswordForm PasswordModel = new();
|
||||||
|
private FastForm<ChangePasswordForm> PasswordForm;
|
||||||
private ChangeCookiesForm CookiesForm = new();
|
|
||||||
|
|
||||||
private async Task Load(LazyLoader lazyLoader)
|
private bool CookieConsent;
|
||||||
|
|
||||||
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
CookiesForm.UseOptionalCookies = await IdentityService.HasFlag("CookieConsent");
|
CookieConsent = await IdentityService.HasFlag("CookieConsent");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnValidSubmitPassword()
|
private async Task SetCookieConsent(bool flag)
|
||||||
{
|
{
|
||||||
if (PasswordForm.Password != PasswordForm.RepeatedPassword)
|
await IdentityService.SetFlag("CookieConsent", flag);
|
||||||
|
|
||||||
|
await ToastService.Success("Successfully changed cookie preferences");
|
||||||
|
await InvokeAsync(StateHasChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnConfigurePasswordForm(FastFormConfiguration<ChangePasswordForm> configuration)
|
||||||
|
{
|
||||||
|
configuration.AddProperty(x => x.Password)
|
||||||
|
.WithComponent<StringComponent>(component =>
|
||||||
|
{
|
||||||
|
component.ColumnsMd = 6;
|
||||||
|
component.Type = "password";
|
||||||
|
})
|
||||||
|
.WithValidation(FastFormValidators.Required)
|
||||||
|
.WithValidation(x => x.Length >= 8 ? ValidationResult.Success : new("The password must be at least 8 characters long"))
|
||||||
|
.WithValidation(x => x.Length <= 256 ? ValidationResult.Success : new("The password must not be longer than 256 characters"));
|
||||||
|
|
||||||
|
configuration.AddProperty(x => x.RepeatedPassword)
|
||||||
|
.WithComponent<StringComponent>(component =>
|
||||||
|
{
|
||||||
|
component.ColumnsMd = 6;
|
||||||
|
component.Type = "password";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task ChangePassword()
|
||||||
|
{
|
||||||
|
if(!await PasswordForm.Submit())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (PasswordModel.Password != PasswordModel.RepeatedPassword)
|
||||||
throw new DisplayException("The passwords do not match");
|
throw new DisplayException("The passwords do not match");
|
||||||
|
|
||||||
await AuthenticationProvider.ChangePassword(IdentityService.CurrentUser, PasswordForm.Password);
|
await AuthenticationProvider.ChangePassword(IdentityService.CurrentUser, PasswordModel.Password);
|
||||||
|
|
||||||
await ToastService.Success("Successfully changed password");
|
await ToastService.Success("Successfully changed password");
|
||||||
await IdentityService.Authenticate(true);
|
await IdentityService.Authenticate(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task OnValidSubmitCookie()
|
|
||||||
{
|
|
||||||
await IdentityService.SetFlag("CookieConsent", CookiesForm.UseOptionalCookies);
|
|
||||||
|
|
||||||
await InvokeAsync(StateHasChanged);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -217,6 +217,7 @@
|
|||||||
component.SearchFunc = x => $"{x.IpAddress}:{x.Port}";
|
component.SearchFunc = x => $"{x.IpAddress}:{x.Port}";
|
||||||
component.DisplayFunc = x => $"{x.IpAddress}:{x.Port}";
|
component.DisplayFunc = x => $"{x.IpAddress}:{x.Port}";
|
||||||
component.ItemsCallback = () =>GetAllocation(server);
|
component.ItemsCallback = () =>GetAllocation(server);
|
||||||
|
component.ColumnsMd = 6;
|
||||||
})
|
})
|
||||||
.WithPage("Network");
|
.WithPage("Network");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user