diff options
| author | Jake Mannens <jake@asger.xyz> | 2023-09-13 16:01:02 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2023-09-13 16:01:02 +1000 |
| commit | e6e43b943143d55581ef442b61ed6cbdbb40c642 (patch) | |
| tree | 82dc5ba12d2761baf8b9290804d3481cdf4eb4cb | |
| parent | bd46d1ff8f2bbe43a92e935aafadc1a63b3a1a5b (diff) | |
Added logon page
| -rw-r--r-- | MainLayout.razor | 22 | ||||
| -rw-r--r-- | MainLayout.razor.css | 53 | ||||
| -rw-r--r-- | Pages/Component/Titlebar.razor | 64 | ||||
| -rw-r--r-- | Pages/Component/Titlebar.razor.css | 79 | ||||
| -rw-r--r-- | Pages/Login.razor | 5 | ||||
| -rw-r--r-- | Pages/Login.razor.css | 6 | ||||
| -rw-r--r-- | Pages/ViewMedia.razor | 2 | ||||
| -rw-r--r-- | Program.cs | 4 | ||||
| -rw-r--r-- | Services/GlobalUserService.cs | 7 | ||||
| -rw-r--r-- | Services/UserService.cs | 42 | ||||
| -rw-r--r-- | wwwroot/images/loginbg.webp | bin | 0 -> 2247672 bytes | |||
| -rw-r--r-- | wwwroot/js/keyboard.js | 4 |
12 files changed, 210 insertions, 78 deletions
diff --git a/MainLayout.razor b/MainLayout.razor index 2d3cadc..5d68b65 100644 --- a/MainLayout.razor +++ b/MainLayout.razor @@ -2,28 +2,8 @@ <link href="@(nameof(HyperBooru)).styles.css" rel="stylesheet" /> -<div id="navbar"> - <a href="/">Home</a> - <a href="/TagDefinitions">Tags</a> - <a href="/Gallery?ingest=true">Ingest</a> - <a href="/Upload">Upload</a> - <a href="javascript:;" @onclick=@(() => aboutDialog.Show())>About</a> - - <p id="nsfw-label">NSFW</p> - <div id="nsfw-switch"> - <NsfwSwitch/> - </div> - <form action="/Gallery" method="get"> - <input type="text" name="q" placeholder="Search"/> - </form> -</div> +<Titlebar/> <div id="content"> @Body </div> - -<AboutDialog @ref=aboutDialog/> - -@code { - private AboutDialog aboutDialog; -} diff --git a/MainLayout.razor.css b/MainLayout.razor.css index b0dea4e..0ce15c2 100644 --- a/MainLayout.razor.css +++ b/MainLayout.razor.css @@ -1,55 +1,4 @@ -div#navbar { - background: var(--col-navbar-bg); - box-shadow: rgba(0, 0, 0, 0.5) 0px 10px 10px; - display: flex; - z-index: 100; -} - -div#navbar > a { - color: white; - display: inline-block; - padding: 20px 20px 20px 20px; -} - -div#navbar > a:hover { - background: rgba(255, 255, 255, 0.4); - filter: none; -} - -div#navbar > a:active { - background: #fff; - color: var(--col-navbar-bg); -} - -p#nsfw-label { - align-self: center; - font-size: 9pt; - margin-left: auto; -} - -div#nsfw-switch { - align-self: center; - margin-left: 10px; -} - -div#navbar form { - display: flex; - margin: 0 20px 0 20px; - min-width: 30%; -} - -div#navbar input[type="text"] { - align-self: center; - background: var(--col-bg); - border-radius: 0; - color: white; - font-size: 12pt; - height: 40px !important; - margin: 0; - width: 100%; -} - -#content { +#content { flex: 1 1 calc(100vh - 59px); overflow-x: hidden; overflow-y: auto; diff --git a/Pages/Component/Titlebar.razor b/Pages/Component/Titlebar.razor new file mode 100644 index 0000000..71f3bd0 --- /dev/null +++ b/Pages/Component/Titlebar.razor @@ -0,0 +1,64 @@ +@inject IUserService userService +@inject NavigationManager navigationManager +@inject IJSRuntime jsRuntime + +@if(authorized) { + <div id="navbar"> + <a href="/">Home</a> + <a href="/TagDefinitions">Tags</a> + <a href="/Gallery?ingest=true">Ingest</a> + <a href="/Upload">Upload</a> + <a href="javascript:;" @onclick=@(() => aboutDialog.Show())>About</a> + + <p id="nsfw-label">NSFW</p> + <div id="nsfw-switch"> + <NsfwSwitch/> + </div> + <form action="/Gallery" method="get"> + <input type="text" name="q" placeholder="Search"/> + </form> + <a href="javascript:;" @onclick=userService.Logout>Logout</a> + </div> + <AboutDialog @ref=aboutDialog/> +} else { + <div id="navbar"> + <h2>Login</h2> + <form @onsubmit=Login class="login"> + <input @bind=username name="username" placeholder="Username" type="text"/> + <input @bind=password name="password" placeholder="Password" type="password"/> + </form> + <a href="javascript:;" @onclick=Login>Login</a> + <a href="javascript:;" @onclick=userService.Logout>Logout</a> + </div> + <script suppress-error="BL9992"> + function warnBadLogin() { + var form = document.querySelector('form.login'); + form.classList.remove('bad-login'); + @* TODO: improve this hacky method of triggering reflow *@ + form.offsetWidth; + form.classList.add('bad-login'); + document.querySelector('form.login input').focus(); + } + </script> +} + +@code { + private bool authorized = false; + + private string username; + private string password; + + private AboutDialog aboutDialog; + + private void Login() { + if(userService.Login(username, password)) + navigationManager.NavigateTo("/"); + else + WarnBadLogin(); + } + + private void WarnBadLogin() { + jsRuntime.InvokeVoidAsync("warnBadLogin"); + username = password = ""; + } +} diff --git a/Pages/Component/Titlebar.razor.css b/Pages/Component/Titlebar.razor.css new file mode 100644 index 0000000..ea10740 --- /dev/null +++ b/Pages/Component/Titlebar.razor.css @@ -0,0 +1,79 @@ +div#navbar { + align-items: center; + background: var(--col-navbar-bg); + box-shadow: rgba(0, 0, 0, 0.5) 0px 10px 10px; + display: flex; + height: 59px; + z-index: 100; +} + +div#navbar > h2 { + margin-left: 20px; +} + +div#navbar > a { + align-items: center; + color: white; + display: flex; + height: 100%; + padding: 0 20px 0 20px; +} + +div#navbar > a:hover { + background: rgba(255, 255, 255, 0.4); + filter: none; +} + +div#navbar > a:active { + background: #fff; + color: var(--col-navbar-bg); +} + +p#nsfw-label { + align-self: center; + font-size: 9pt; + margin-left: auto; +} + +div#nsfw-switch { + align-self: center; + margin-left: 10px; +} + +form { + display: flex; + margin: 0 20px 0 20px; + min-width: 30%; +} + +form.login { + margin-left: auto; +} + +form.login.bad-login { + animation-iteration-count: 3; + animation-timing-function: linear; + animation: bad-login 0.2s; +} + +@keyframes bad-login { + 0% { transform: translateX(0); } + 33% { transform: translateX(-20px); } + 66% { transform: translateX(+20px); } + 100% { transform: translateX(0); } +} + +input[type="text"], input[type="password"] { + align-self: center; + background: var(--col-bg); + border-radius: 0; + color: white; + font-size: 12pt; + height: 40px !important; + margin: 0; + width: 100%; +} + +input[type="password"] { + margin-left: 20px; +} diff --git a/Pages/Login.razor b/Pages/Login.razor new file mode 100644 index 0000000..2970731 --- /dev/null +++ b/Pages/Login.razor @@ -0,0 +1,5 @@ +@page "/Login" + +<PageTitle>HyperBooru Login</PageTitle> + +<div/>
\ No newline at end of file diff --git a/Pages/Login.razor.css b/Pages/Login.razor.css new file mode 100644 index 0000000..fc8c8ca --- /dev/null +++ b/Pages/Login.razor.css @@ -0,0 +1,6 @@ +div { + background: url('/images/loginbg.webp'); + filter: brightness(0.6); + height: 100%; + width: 100%; +}
\ No newline at end of file diff --git a/Pages/ViewMedia.razor b/Pages/ViewMedia.razor index 444fbc5..1b6f959 100644 --- a/Pages/ViewMedia.razor +++ b/Pages/ViewMedia.razor @@ -4,7 +4,7 @@ @inject IDbContextFactory<HBContext> dbFactory @inject ITagService tagService @inject IMediaService mediaService -@attribute [Authorize] +@*@attribute [Authorize]*@ <PageTitle>@title</PageTitle> @@ -7,6 +7,7 @@ namespace HyperBooru; public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); + builder.Services.AddHttpContextAccessor(); builder.Services.AddControllers().AddJsonOptions(o => { var converter = new JsonStringEnumConverter(); o.JsonSerializerOptions.Converters.Add(converter); @@ -20,7 +21,8 @@ public class Program { builder.Services.AddScoped<ISearchService, SearchService>(); builder.Services.AddScoped<ITagService, TagService>(); builder.Services.AddScoped<IMediaService, MediaService>(); - builder.Services.AddSingleton<IUserService, UserService>(); + builder.Services.AddSingleton<IGlobalUserService, GlobalUserService>(); + builder.Services.AddScoped<IUserService, UserService>(); builder.Services.AddHostedService<OcrService>(); var app = builder.Build(); diff --git a/Services/GlobalUserService.cs b/Services/GlobalUserService.cs new file mode 100644 index 0000000..adafce2 --- /dev/null +++ b/Services/GlobalUserService.cs @@ -0,0 +1,7 @@ +namespace HyperBooru.Services; + +public interface IGlobalUserService { +} + +public class GlobalUserService : IGlobalUserService { +} diff --git a/Services/UserService.cs b/Services/UserService.cs index d2abea3..db62553 100644 --- a/Services/UserService.cs +++ b/Services/UserService.cs @@ -1,9 +1,17 @@ -namespace HyperBooru.Services; +using Microsoft.AspNetCore.Authentication; +using System.Runtime.InteropServices; +using System.Security.Claims; +using System.Security.Principal; + +namespace HyperBooru.Services; public interface IUserService { public bool ShowNsfw { get; set; } public event EventHandler<bool> ShowNsfwChanged; + + public bool Login(string username, string password); + public void Logout(); } public class UserService : IUserService { @@ -18,4 +26,36 @@ public class UserService : IUserService { public event EventHandler<bool> ShowNsfwChanged; private bool showNsfw = false; + + private IGlobalUserService globalUserService; + private IHttpContextAccessor httpContextAccessor; + + public UserService( + IGlobalUserService globalUserService, + IHttpContextAccessor httpContextAccessor) { + + this.globalUserService = globalUserService; + this.httpContextAccessor = httpContextAccessor; + } + + public bool Login(string username, string password) { + var claims = new Claim[] { + }; + + var claimsIdentity = new ClaimsIdentity(claims); + + var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); + + if(httpContextAccessor.HttpContext is null) + return false; + + httpContextAccessor.HttpContext.SignInAsync(claimsPrincipal) + .GetAwaiter() + .GetResult(); + + return true; + } + + public void Logout() { + } } diff --git a/wwwroot/images/loginbg.webp b/wwwroot/images/loginbg.webp Binary files differnew file mode 100644 index 0000000..759e666 --- /dev/null +++ b/wwwroot/images/loginbg.webp diff --git a/wwwroot/js/keyboard.js b/wwwroot/js/keyboard.js index 4c8e722..8086418 100644 --- a/wwwroot/js/keyboard.js +++ b/wwwroot/js/keyboard.js @@ -1,7 +1,7 @@ async function keyDownHandler(e) { function isDialogChild(e) { - while (e = e.parentElement) - if (e.tagName == 'DIV' && e.classList.contains('dialog')) + while(e = e.parentElement) + if(e.tagName == 'DIV' && e.classList.contains('dialog')) return true; return false; } |
