175 lines
6.8 KiB
Plaintext
175 lines
6.8 KiB
Plaintext
@page "/login"
|
|
|
|
@* This is just a "virtual" route/page. The handling for that is
|
|
@* MainLayout doing for us. We need to put that here so the router
|
|
@* does not return the 404 page
|
|
*@
|
|
|
|
@using Moonlight.App.Services.Interop
|
|
@using Moonlight.App.Services
|
|
@using Moonlight.App.Exceptions
|
|
@using Logging.Net
|
|
@using Moonlight.App.Database.Entities
|
|
@using Moonlight.App.Models.Misc
|
|
@using Moonlight.App.Services.OAuth2
|
|
@using Moonlight.App.Services.Sessions
|
|
|
|
@inject AlertService AlertService
|
|
@inject UserService UserService
|
|
@inject SmartTranslateService SmartTranslateService
|
|
@inject CookieService CookieService
|
|
@inject NavigationManager NavigationManager
|
|
@inject GoogleOAuth2Service GoogleOAuth2Service
|
|
@inject DiscordOAuth2Service DiscordOAuth2Service
|
|
|
|
<div class="d-flex flex-center">
|
|
<div class="card rounded-3 w-md-550px">
|
|
<div class="card-body">
|
|
<div class="d-flex flex-center flex-column-fluid pb-15 pb-lg-20">
|
|
<SmartForm Model="User" OnValidSubmit="DoLogin">
|
|
@if (!TotpRequired)
|
|
{
|
|
<div class="text-center mt-3 mb-11">
|
|
<h1 class="text-dark fw-bolder mb-3">
|
|
<TL>Sign In</TL>
|
|
</h1>
|
|
<div class="text-gray-500 fw-semibold fs-6">
|
|
<TL>Sign in to start with moonlight</TL>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-3 mb-9">
|
|
<div class="col-md-6">
|
|
<a href="#" @onclick:preventDefault @onclick="DoDiscord" class="btn btn-flex btn-outline btn-text-gray-700 btn-active-color-primary bg-state-light flex-center text-nowrap w-100">
|
|
<div class="h-15px me-3">
|
|
<i class="mb-1 bx bx-md bxl-discord-alt"></i>
|
|
</div>
|
|
<TL>Sign in with Discord</TL>
|
|
</a>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<a href="#" @onclick:preventDefault @onclick="DoGoogle" class="btn btn-flex btn-outline btn-text-gray-700 btn-active-color-primary bg-state-light flex-center text-nowrap w-100">
|
|
<div class="h-15px me-3">
|
|
<i class="mb-1 bx bx-md bxl-google"></i>
|
|
</div>
|
|
<TL>Sign in with Google</TL>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="separator separator-content my-14">
|
|
<span class="w-125px text-gray-500 fw-semibold fs-7">
|
|
<TL>Or with email</TL>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="mt-3 mb-3">
|
|
<InputText @bind-Value="User.Email" type="email" placeholder="@(SmartTranslateService.Translate("Email"))" class="form-control bg-transparent"/>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<InputText @bind-Value="User.Password" type="password" placeholder="@(SmartTranslateService.Translate("Password"))" class="form-control bg-transparent"/>
|
|
</div>
|
|
|
|
<div class="d-flex flex-stack flex-wrap gap-3 fs-base fw-semibold mb-8">
|
|
<div></div>
|
|
|
|
<a href="/passwordreset" class="link-primary">
|
|
<TL>Forgot password?</TL>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="d-grid mb-10">
|
|
<button type="submit" class="btn btn-primary">
|
|
<TL>Sign-in</TL>
|
|
</button>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="fv-row mb-8 fv-plugins-icon-container">
|
|
<input type="number" class="form-control bg-transparent">
|
|
</div>
|
|
<div class="d-grid mb-10">
|
|
<WButton Text="@(SmartTranslateService.Translate("Sign-in"))"
|
|
WorkingText="@(SmartTranslateService.Translate("Working"))"
|
|
CssClasses="btn-primary"
|
|
OnClick="DoLogin">
|
|
</WButton>
|
|
</div>
|
|
}
|
|
|
|
<div class="text-gray-500 text-center fw-semibold fs-6">
|
|
<TL>Not registered yet?</TL>
|
|
|
|
<a href="/register" class="link-primary">
|
|
<TL>Sign up</TL>
|
|
</a>
|
|
</div>
|
|
</SmartForm>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
@code
|
|
{
|
|
private LoginDataModel User = new();
|
|
|
|
private bool TotpRequired = false;
|
|
private string TotpCode = "";
|
|
|
|
private async Task DoLogin()
|
|
{
|
|
try
|
|
{
|
|
User.Email = User.Email.ToLower().Trim();
|
|
|
|
TotpRequired = await UserService.CheckTotp(User.Email, User.Password);
|
|
|
|
if (!TotpRequired)
|
|
{
|
|
var token = await UserService.Login(User.Email, User.Password);
|
|
await CookieService.SetValue("token", token, 10);
|
|
|
|
if (NavigationManager.Uri.EndsWith("login"))
|
|
NavigationManager.NavigateTo("/", true);
|
|
else
|
|
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
|
}
|
|
else
|
|
{
|
|
await InvokeAsync(StateHasChanged);
|
|
}
|
|
}
|
|
catch (DisplayException e)
|
|
{
|
|
await AlertService.Error(
|
|
SmartTranslateService.Translate("Error"),
|
|
SmartTranslateService.Translate(e.Message)
|
|
);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
await AlertService.Error(
|
|
SmartTranslateService.Translate("Error"),
|
|
SmartTranslateService.Translate("An error occured while logging you in")
|
|
);
|
|
|
|
Logger.Error("Error while login");
|
|
Logger.Error(e);
|
|
}
|
|
}
|
|
|
|
private async Task DoGoogle()
|
|
{
|
|
var url = await GoogleOAuth2Service.GetUrl();
|
|
NavigationManager.NavigateTo(url, true);
|
|
}
|
|
|
|
private async Task DoDiscord()
|
|
{
|
|
var url = await DiscordOAuth2Service.GetUrl();
|
|
NavigationManager.NavigateTo(url, true);
|
|
}
|
|
} |