Initial commit - Auth.RCL

This commit is contained in:
2026-08-05 21:16:00 +03:00
commit 062ff0146a
231 changed files with 15819 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
@page "/user/basic-info"
@inject UserAPIConsumer userAPIConsumer
@inject NavigationManager nav
<Dialog ShowDialog="showNameDialog" OnCancel="ToggleNameDialog" OnSubmit="ChangeName" TitleName="@("Change Name")">
<div>
TEST TEST TEST
</div>
</Dialog>
@*
<Dialog OnCancel="ToggleEmailDialog" OnSubmit="ChangeEmail" TitleName="Change Email" ></Dialog>
<Dialog OnCancel="TogglePhoneNumberDialog" OnSubmit="ChangePhoneNumber" TitleName="Change Phone Number" ></Dialog>
<Dialog OnCancel="TogglePassword" OnSubmit="ChangePassword" TitleName="Change Password" ></Dialog> *@
<div class="grid grid-cols-1 md:grid-cols-2 p-20">
@*
<ToggleInput InputValue="userInfoUpdate.Name" OnSave="ChangeName" InputType="text" Label="Name"></ToggleInput>
<ToggleInput InputValue="userInfoUpdate.Email" OnSave="ChangeEmail" InputType="email" Label="Email"></ToggleInput>
<ToggleInput InputValue="userInfoUpdate.PhoneNumber" OnSave="ChangePhoneNumber" InputType="number" Label="Phone
Number"></ToggleInput>
<ToggleInput OnSave="ChangePassword" InputType="password" Label="Password"></ToggleInput> *@
<div class="flex flex-row justify-between">
<label>Name:</label>
<p>@user.Name</p>
<button @onclick="ToggleNameDialog" class="btn btn-primary">Change</button>
</div>
<div class="flex flex-row justify-between">
<label>Email:</label>
<p>@user.Email</p>
<button @onclick="ToggleEmailDialog" class="btn btn-primary">Change</button>
</div>
<div class="flex flex-row justify-between">
<label>PhoneNumber:</label>
<p>@user.PhoneNumber</p>
<button @onclick="TogglePhoneNumberDialog" class="btn btn-primary">Change</button>
</div>
<div class="flex flex-row justify-between">
<label>Password:</label>
<p>***********</p>
<button @onclick="TogglePasswordDialog" class="btn btn-primary">Change</button>
</div>
</div>
@code {
UserVM user = new();
[CascadingParameter] public Task<AuthenticationState> authStateTask { get; set; }
bool showNameDialog = false;
bool showEmailDialog = false;
bool showPhoneNumberDialog = false;
bool showPasswordDialog = false;
protected override async Task OnInitializedAsync()
{
var userId = (await authStateTask).User.Claims.FirstOrDefault(x => x.Type == "id").Value;
if (userId == null)
nav.NavigateTo("/signin");
user = await userAPIConsumer.GetUser(userId);
}
void ToggleNameDialog() => showNameDialog = !showNameDialog;
void ToggleEmailDialog() => showEmailDialog = !showEmailDialog;
void TogglePhoneNumberDialog() => showPhoneNumberDialog = !showPhoneNumberDialog;
void TogglePasswordDialog() => showPasswordDialog = !showPasswordDialog;
async Task ChangeName()
{
ToggleNameDialog();
}
async Task ChangeEmail()
{
ToggleEmailDialog();
}
async Task ChangePhoneNumber()
{
TogglePhoneNumberDialog();
}
async Task ChangePassword()
{
TogglePasswordDialog();
}
}
@@ -0,0 +1,17 @@
<div>
<h2>Write your new Email</h2>
<input class="input input-primary"/>
<button @onclick="Submit">change email</button>
</div>
@code{
async Task Submit()
{
//SendEmailConfirmationToken()
}
}
@@ -0,0 +1,83 @@
@layout EmptyLayout
@inject UserAPIConsumer userAPIConsumer
@inject NavigationManager nav
<PageTitle>Sign In</PageTitle>
<EditForm Model="@tokenRequestModel" OnValidSubmit="@OnValidSignIn" class="text-gray-600 body-font">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="container px-5 py-24 mx-auto flex flex-wrap items-center">
<div class="lg:w-3/5 md:w-1/2 md:pr-16 lg:pr-0 pr-0">
<h1 class="title-font font-medium text-3xl text-gray-900">Slow-carb next level shoindcgoitch ethical
authentic, poko scenester</h1>
<p class="leading-relaxed mt-4">Poke slow-carb mixtape knausgaard, typewriter street art gentrify hammock
starladder roathse. Craies vegan tousled etsy austin.</p>
</div>
<div class="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col md:ml-auto w-full mt-10 md:mt-0">
<h2 class="text-gray-900 text-lg font-medium title-font mb-5">Sign In</h2>
<div class="relative mb-4">
<label for="email" class="leading-7 text-sm text-gray-600">Email</label>
<InputText type="email" placeholder="Email" @bind-Value="tokenRequestModel.Email" id="email"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<div class="relative mb-4">
<label for="Password" class="leading-7 text-sm text-gray-600">Password</label>
<InputText type="password" placeholder="Password" @bind-Value="tokenRequestModel.Password" id="Password"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<button type="submit"
class="text-white mt-4 bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Sign
In</button>
<p class="text-xs text-red-500 mt-4">@errorMessage</p>
</div>
</div>
</EditForm>
@code {
[Parameter]
public EventCallback CarryOnRequest { get; set; }
private TokenRequestModel tokenRequestModel = new();
private string errorMessage = "";
[CascadingParameter] public Task<AuthenticationState> authStateTask { get; set; }
protected override async Task OnInitializedAsync()
{
}
public async Task OnValidSignIn()
{
var isSuccessful = await userAPIConsumer.Login(tokenRequestModel);
if (isSuccessful)
{
errorMessage = "Verifcation Email Sent to your Original Email.";
errorMessage = "Verifcation Email Sent to your Original Email.";
// TODO: Capture NewEmail from user input. Using placeholder for now.
userAPIConsumer.SendChangeEmailToken(new RequestChangeEmail { NewEmail = "placeholder@example.com" });
}
else
errorMessage = "Wrong Email or Password.";
}
}
//Modal with confirm username and password ... calls a event call back that will carry on the request
+47
View File
@@ -0,0 +1,47 @@
@page "/forgotpassword"
@* @using System.ComponentModel.DataAnnotations *@
@inject UserAPIConsumer userAPIConsumer
@layout EmptyLayout
<div class="container px-5 py-24 mx-auto flex flex-wrap items-center">
<div class="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col mx-auto w-full mt-10 md:mt-0">
<h2 class="text-gray-900 text-lg font-medium title-font mb-5">Reset your Password</h2>
<div class="relative mb-4">
<label for="email" class="leading-7 text-sm text-gray-600">Email</label>
<input type="email" placeholder="Email" @bind="Email" id="email"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<button @onclick="ResetPassword" type="button"
class="text-white mt-4 bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Reset
Password</button>
<p class='text-md text-center font-bold @(isSuccessful ? "text-green-500" : "text-red-500") mt-4'>@resultMessage
</p>
</div>
</div>
@code {
string resultMessage = "";
bool isSuccessful = false;
public string Email { get; set; }
async Task ResetPassword()
{
isSuccessful = await userAPIConsumer.RequestResetPassword(Email);
if (isSuccessful)
resultMessage = "Email Sent.";
else
resultMessage = "Error.";
}
}
+73
View File
@@ -0,0 +1,73 @@
@page "/account/reset-password/{*token}"
@layout EmptyLayout
@inject UserAPIConsumer userAPIConsumer
<EditForm EditContext="ec" OnValidSubmit="Reset" class="container px-5 py-24 mx-auto flex flex-wrap items-center">
<div class="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col mx-auto w-full mt-10 md:mt-0">
<h2 class="text-gray-900 text-lg font-medium title-font mb-5">Reset your Password</h2>
<div class="relative mb-4">
<label for="email" class="leading-7 text-sm text-gray-600">Email</label>
<InputText type="email" placeholder="Email" @bind-Value="passwordResetModel.Email" id="email"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<div class="relative mb-4">
<label for="password" class="leading-7 text-sm text-gray-600">Password</label>
<InputText type="password" placeholder="Password" @bind-Value="passwordResetModel.Password" id="password"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200 text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<button type="submit"
class="text-white mt-4 bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Reset
Password</button>
<p class='text-md text-center font-bold @(isSuccessful ? "text-green-500" : "text-red-500") mt-4'>@resultMessage
</p>
</div>
</EditForm>
@code {
[Parameter]
public string Token { get; set; }
PasswordResetModel passwordResetModel = new();
@* string status = "Confirming..."; *@
string resultMessage = "";
bool isSuccessful = false;
EditContext ec;
protected override async Task OnInitializedAsync()
{
ec = new EditContext(passwordResetModel);
}
async Task Reset()
{
resultMessage = "";
passwordResetModel.Token = Token;
if (ec.Validate())
{
isSuccessful = await userAPIConsumer.ResetPassword(passwordResetModel);
if (isSuccessful)
resultMessage = "Password reset successful.";
else
resultMessage = "Error, Try Again later";
}
}
}
@@ -0,0 +1,27 @@
@page "/confirm-phonenumber/{phoneNumber}/{token}"
@inject UserAPIConsumer userAPIConsumer
<h1>@message</h1>
@code {
[Parameter]
public string Token { get; set; }
[Parameter]
public string PhoneNumber { get; set; }
string message = "";
protected override async Task OnInitializedAsync()
{
var updatePhoneNumber = new UpdatePhoneNumber() { Token = Token, PhoneNumber = PhoneNumber };
var isSuccess = await userAPIConsumer.UpdatePhoneNumber(updatePhoneNumber);
if (isSuccess)
message = $"Phone Number Changed to {PhoneNumber} Successfully.";
else
message = $"Server Error or Token Expired.";
}
}
@@ -0,0 +1,33 @@
@page "/phone"
@inject UserAPIConsumer userAPIConsumer
@inject NavigationManager nav
<div class="flex flex-col w-full h-full p-20">
<input @bind="phoneNumber" class="input input-primary" />
<button @onclick="Submit" class="btn btn-primary">Submit</button>
<p class="text-red-500">@error</p>
</div>
@code {
string phoneNumber = "";
string error = "";
protected override async Task OnInitializedAsync()
{
}
async Task Submit()
{
@* var updatePhoneNumber = new UpdatePhoneNumber() { PhoneNumber= phoneNumber}; *@
var isSuccess = await userAPIConsumer.SendPhoneNumberToken(phoneNumber);
if (isSuccess)
nav.NavigateTo("/profile");
else
error = "Error updating Phone Number.";
}
}
+98
View File
@@ -0,0 +1,98 @@
@page "/email-confirmed"
@layout EmptyLayout
@inject UserAPIConsumer userAPIConsumer
@inject NavigationManager nav
<PageTitle>Email Confirmed</PageTitle>
<h1>Email Confirmed</h1>
@*
<EditForm Model="@tokenRequestModel" OnValidSubmit="@OnValidSignIn" class="text-gray-600 body-font">
<DataAnnotationsValidator />
<ValidationSummary />
<div class="container px-5 py-24 mx-auto flex flex-wrap items-center">
<div class="lg:w-3/5 md:w-1/2 md:pr-16 lg:pr-0 pr-0">
<h1 class="title-font font-medium text-3xl text-gray-900">Slow-carb next level shoindcgoitch ethical
authentic, poko scenester</h1>
<p class="leading-relaxed mt-4">Poke slow-carb mixtape knausgaard, typewriter street art gentrify hammock
starladder roathse. Craies vegan tousled etsy austin.</p>
</div>
<div class="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col md:ml-auto w-full mt-10 md:mt-0">
<h2 class="text-gray-900 text-lg font-medium title-font mb-5">Sign In</h2>
<div class="relative mb-4">
<label for="email" class="leading-7 text-sm text-gray-600">Email</label>
<InputText type="email" placeholder="Email" @bind-Value="tokenRequestModel.Email" id="email"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200
text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<div class="relative mb-4">
<label for="Password" class="leading-7 text-sm text-gray-600">Password</label>
<InputText type="password" placeholder="Password" @bind-Value="tokenRequestModel.Password" id="Password"
class="w-full bg-white rounded border border-gray-300 focus:border-indigo-500 focus:ring-2 focus:ring-indigo-200
text-base outline-none text-gray-700 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out" />
</div>
<button type="submit"
class="text-white mt-4 bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Sign
In</button>
<p class="text-xs text-red-500 mt-4">@errorMessage</p>
<NavLink href="/ForgotPassword">Forgot Password?</NavLink>
</div>
</div>
</EditForm>
@code {
[Parameter]
public string? Token { get; set; }
private TokenRequestModel tokenRequestModel = new();
private string errorMessage = "";
public async Task OnValidSignIn()
{
var isSuccessful = await userAPIConsumer.Login(tokenRequestModel);
if (!string.IsNullOrEmpty(Token))
{
if (isSuccessful)
{
var confirmSuccessful = await userAPIConsumer.ConfirmEmail(Token);
if (confirmSuccessful)
nav.NavigateTo("/");
else
{
errorMessage = "Error, confirming email. try again later.";
}
}
else
errorMessage = "Wrong Email or Password.";
}
errorMessage = result.Message;
}
} *@
+35
View File
@@ -0,0 +1,35 @@
@page "/home2"
<LanguageSwitcher></LanguageSwitcher>
<h1>@Localizer["Hello"]</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<h1>Hello World</h1>
<MediaUploadContainer></MediaUploadContainer>
@code {
}
+38
View File
@@ -0,0 +1,38 @@
@page "/resend"
@inject UserAPIConsumer userAPIConsumer
@layout EmptyLayout
<div class="container px-5 py-24 mx-auto flex flex-wrap items-center">
<div class="lg:w-2/6 md:w-1/2 bg-gray-100 rounded-lg p-8 flex flex-col w-full mt-10 md:mt-0">
<h2 class="text-gray-900 text-lg font-medium title-font mb-5">Verify your Email</h2>
<p>Didn't recieve an email? press the resend email button</p>
<button @onclick="ResendEmail" type="button"
class="text-white mt-4 bg-indigo-500 border-0 py-2 px-8 focus:outline-none hover:bg-indigo-600 rounded text-lg">Resend
Email</button>
<p class='text-md font-bold @(isSuccessful ? "text-green-500" : "text-red-500") mt-4'>@resultMessage</p>
</div>
</div>
@code {
string resultMessage = "";
bool isSuccessful = false;
async Task ResendEmail()
{
resultMessage = "";
isSuccessful = await userAPIConsumer.ResendConfirmation();
if (isSuccessful)
resultMessage = "Email Sent.";
else
resultMessage = "Error.";
}
}
+104
View File
@@ -0,0 +1,104 @@
@page "/SignIn"
@page "/confirm-account/{*token}"
@layout EmptyLayout
@inject UserAPIConsumer userAPIConsumer
@inject NavigationManager nav
<PageTitle>Sign In</PageTitle>
<EditForm Model="@tokenRequestModel" OnValidSubmit="@OnValidSignIn"
class="flex justify-center items-center h-screen bg-base-200">
<DataAnnotationsValidator />
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title text-2xl font-bold justify-center mb-6">Sign In</h2>
<div class="form-control w-full max-w-xs mx-auto">
<label class="label">
<span class="label-text">Email</span>
</label>
<InputText type="email" placeholder="email@example.com" @bind-Value="tokenRequestModel.Email"
class="input input-bordered w-full max-w-xs" />
</div>
<div class="form-control w-full max-w-xs mx-auto">
<label class="label">
<span class="label-text">Password</span>
</label>
<InputText type="password" placeholder="********" @bind-Value="tokenRequestModel.Password"
class="input input-bordered w-full max-w-xs" />
<label class="label">
<a href="/ForgotPassword" class="label-text-alt link link-hover">Forgot Password?</a>
</label>
</div>
<div class="card-actions justify-center mt-6">
<button type="submit" class="btn btn-primary w-full max-w-xs">Sign In</button>
</div>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-error mt-4">
<span>@errorMessage</span>
</div>
}
</div>
</div>
</EditForm>
@code {
[Parameter]
public string? Token { get; set; }
private TokenRequestModel tokenRequestModel = new();
private string errorMessage = "";
[CascadingParameter] public Task<AuthenticationState> authStateTask { get; set; }
protected override async Task OnInitializedAsync()
{
var user = (await authStateTask).User;
if (user != null)
if (user.Identity.IsAuthenticated)
nav.NavigateTo("/");
}
public async Task OnValidSignIn()
{
var isSuccessful = await userAPIConsumer.Login(tokenRequestModel);
if (isSuccessful)
{
if (!string.IsNullOrEmpty(Token))
{
var confirmSuccessful = await userAPIConsumer.ConfirmEmail(Token);
if (confirmSuccessful)
nav.NavigateTo("/email-confirmed");
else
{
errorMessage = "Error, confirming email. try again later.";
}
}
else
nav.NavigateTo("/");
}
else
errorMessage = "Wrong Email or Password.";
@* errorMessage = result.Message; *@
}
}
+75
View File
@@ -0,0 +1,75 @@
@page "/signUp"
@layout EmptyLayout
@inject UserAPIConsumer userAPIConsumer
@inject NavigationManager nav
<PageTitle>Sign Up</PageTitle>
<EditForm Model="@registerModel" OnValidSubmit="@OnValidSignUp"
class="flex justify-center items-center py-10 min-h-screen bg-base-200">
<DataAnnotationsValidator />
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title text-2xl font-bold justify-center mb-6">Sign Up</h2>
<div class="form-control w-full">
<label class="label"><span class="label-text">Full Name</span></label>
<InputText type="text" @bind-Value="registerModel.FullName" class="input input-bordered w-full" />
</div>
<div class="form-control w-full">
<label class="label"><span class="label-text">Email</span></label>
<InputText type="email" @bind-Value="registerModel.Email" class="input input-bordered w-full" />
</div>
<div class="form-control w-full">
<label class="label"><span class="label-text">Password</span></label>
<InputText type="password" @bind-Value="registerModel.Password" class="input input-bordered w-full" />
</div>
<div class="form-control w-full">
<label class="label"><span class="label-text">Confirm Password</span></label>
<InputText type="password" @bind-Value="registerModel.ConfirmPassword"
class="input input-bordered w-full" />
</div>
<div class="card-actions justify-center mt-6">
<button type="submit" class="btn btn-primary w-full">Sign Up</button>
</div>
@if (!string.IsNullOrEmpty(errorMessage))
{
<div class="alert alert-error mt-4">
<span>@errorMessage</span>
</div>
}
</div>
</div>
</EditForm>
@code {
private RegisterModel registerModel = new RegisterModel();
private string errorMessage = "";
[CascadingParameter] public Task<AuthenticationState> authStateTask { get; set; }
protected override async Task OnInitializedAsync()
{
var user = (await authStateTask).User;
if (user.Identity.IsAuthenticated)
nav.NavigateTo("/");
}
private async Task OnValidSignUp()
{
var result = await userAPIConsumer.Register(registerModel);
if (result.IsSuccessful)
nav.NavigateTo("SignIn");
else
errorMessage = result.Message;
}
}