diff --git a/Moonlight.ApiServer/Moonlight.ApiServer.csproj b/Moonlight.ApiServer/Moonlight.ApiServer.csproj index 3f3fe824..c17595e2 100644 --- a/Moonlight.ApiServer/Moonlight.ApiServer.csproj +++ b/Moonlight.ApiServer/Moonlight.ApiServer.csproj @@ -12,13 +12,14 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + + + - diff --git a/Moonlight.Client/Moonlight.Client.csproj b/Moonlight.Client/Moonlight.Client.csproj index 83c71079..a9e12ccc 100644 --- a/Moonlight.Client/Moonlight.Client.csproj +++ b/Moonlight.Client/Moonlight.Client.csproj @@ -10,10 +10,10 @@ - - + + - + diff --git a/Moonlight.Client/Program.cs b/Moonlight.Client/Program.cs index 87f09776..d9de2ab2 100644 --- a/Moonlight.Client/Program.cs +++ b/Moonlight.Client/Program.cs @@ -1,12 +1,11 @@ -using System.Net.Http.Headers; -using System.Net.Http.Json; -using System.Text.Json; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using MoonCore.Blazor.Extensions; +using MoonCore.Blazor.Services; using MoonCore.Blazor.Tailwind.Extensions; using MoonCore.Blazor.Tailwind.Forms; using MoonCore.Blazor.Tailwind.Forms.Components; -using MoonCore.Blazor.Tailwind.Services; +using MoonCore.Exceptions; using MoonCore.Extensions; using MoonCore.Helpers; using MoonCore.Models; @@ -55,42 +54,41 @@ builder.Logging.AddProviders(providers); builder.RootComponents.Add("#app"); builder.RootComponents.Add("head::after"); -builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); +builder.Services.AddScoped(_ => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); builder.Services.AddScoped(sp => { var httpClient = sp.GetRequiredService(); + var localStorageService = sp.GetRequiredService(); var result = new HttpApiClient(httpClient); - - result.UseBearerTokenConsumer(async () => + + result.AddLocalStorageTokenAuthentication(localStorageService, async refreshToken => { - var cookieService = sp.GetRequiredService(); + try + { + var httpApiClient = new HttpApiClient(httpClient); - return new TokenConsumer( - await cookieService.GetValue("kms-access", "x"), - await cookieService.GetValue("kms-refresh", "x"), - DateTimeOffset.FromUnixTimeSeconds(long.Parse(await cookieService.GetValue("kms-timestamp", "0"))).UtcDateTime, - async refreshToken => - { - var response = await httpClient.PostAsync("api/auth/refresh", new StringContent( - JsonSerializer.Serialize(new RefreshRequest() - { - RefreshToken = refreshToken - }), new MediaTypeHeaderValue("application/json") - )); - - var refreshRes = await response.ParseAsJson(); - - await cookieService.SetValue("kms-access", refreshRes.AccessToken, 10); - await cookieService.SetValue("kms-refresh", refreshRes.RefreshToken, 10); - await cookieService.SetValue("kms-timestamp", DateTimeOffset.UtcNow.AddSeconds(60).ToUnixTimeSeconds().ToString(), 10); - - return new TokenPair() + var response = await httpApiClient.PostJson( + "api/auth/refresh", + new RefreshRequest() { - AccessToken = await cookieService.GetValue("kms-access", "x"), - RefreshToken = await cookieService.GetValue("kms-refresh", "x") - }; - } - ); + RefreshToken = refreshToken + } + ); + + return (new TokenPair() + { + AccessToken = response.AccessToken, + RefreshToken = response.RefreshToken + }, response.ExpiresAt); + } + catch (HttpApiException) + { + return (new TokenPair() + { + AccessToken = "unset", + RefreshToken = "unset" + }, DateTime.MinValue); + } }); return result; @@ -98,6 +96,7 @@ builder.Services.AddScoped(sp => builder.Services.AddMoonCoreBlazorTailwind(); builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AutoAddServices(); diff --git a/Moonlight.Client/Services/IdentityService.cs b/Moonlight.Client/Services/IdentityService.cs index fef45c27..68489caa 100644 --- a/Moonlight.Client/Services/IdentityService.cs +++ b/Moonlight.Client/Services/IdentityService.cs @@ -1,7 +1,10 @@ using MoonCore.Attributes; +using MoonCore.Blazor.Services; using MoonCore.Blazor.Tailwind.Services; using MoonCore.Exceptions; using MoonCore.Helpers; +using MoonCore.Models; +using Moonlight.Shared.Http.Requests.Auth; using Moonlight.Shared.Http.Responses.Auth; namespace Moonlight.Client.Services; @@ -14,24 +17,20 @@ public class IdentityService public string[] Permissions { get; private set; } public bool IsLoggedIn { get; private set; } - public event Func OnStateChanged; + private readonly HttpApiClient HttpApiClient; + private readonly LocalStorageService LocalStorageService; - private readonly CookieService CookieService; - private readonly HttpApiClient ApiClient; - - public IdentityService(CookieService cookieService, HttpApiClient apiClient) + public IdentityService(HttpApiClient httpApiClient, LocalStorageService localStorageService) { - CookieService = cookieService; - ApiClient = apiClient; + HttpApiClient = httpApiClient; + LocalStorageService = localStorageService; } - #region Login / Logout - public async Task Check() { try { - var response = await ApiClient.GetJson("api/auth/check"); + var response = await HttpApiClient.GetJson("api/auth/check"); Username = response.Username; Email = response.Email; @@ -47,19 +46,12 @@ public class IdentityService //await OnStateChanged?.Invoke(); } - public async Task Login(string token) - { - await CookieService.SetValue("token", token, 30); - await Check(); - } - public async Task Logout() { - await CookieService.SetValue("token", "", 30); - await Check(); + await LocalStorageService.SetString("AccessToken", "unset"); + await LocalStorageService.SetString("RefreshToken", "unset"); + await LocalStorageService.Set("ExpiresAt", DateTime.MinValue); } - - #endregion public bool HasPermission(string requiredPermission) { diff --git a/Moonlight.Client/UI/Partials/AppHeader.razor b/Moonlight.Client/UI/Partials/AppHeader.razor index 7c7c299b..d6c810ef 100644 --- a/Moonlight.Client/UI/Partials/AppHeader.razor +++ b/Moonlight.Client/UI/Partials/AppHeader.razor @@ -3,6 +3,7 @@ @inject IdentityService IdentityService @inject ToastService ToastService +@inject NavigationManager Navigation
@if (Layout.ShowMobileNavigation) @@ -112,6 +113,7 @@ await IdentityService.Logout(); await ToastService.Info("Successfully logged out"); - await Layout.Load(); + //await Layout.Load(); + Navigation.NavigateTo(Navigation.Uri, true); } } diff --git a/Moonlight.Client/UI/Screens/AuthenticationScreen.razor b/Moonlight.Client/UI/Screens/AuthenticationScreen.razor index fec1a05f..62ae78ff 100644 --- a/Moonlight.Client/UI/Screens/AuthenticationScreen.razor +++ b/Moonlight.Client/UI/Screens/AuthenticationScreen.razor @@ -1,5 +1,6 @@ @page "/auth" +@using MoonCore.Blazor.Services @using MoonCore.Helpers @using Moonlight.Client.Services @using Moonlight.Shared.Http.Requests.Auth @@ -7,9 +8,9 @@ @inject NavigationManager Navigation @inject HttpApiClient HttpApiClient -@inject CookieService CookieService @inject WindowService WindowService @inject HttpClient HttpClient +@inject LocalStorageService LocalStorageService @if (Code == null) { @@ -95,9 +96,9 @@ else Code = Code }); - await CookieService.SetValue("kms-access", authHandleData.AccessToken, 10); - await CookieService.SetValue("kms-refresh", authHandleData.RefreshToken, 10); - await CookieService.SetValue("kms-timestamp", DateTimeOffset.UtcNow.AddSeconds(60).ToUnixTimeSeconds().ToString(), 10); + await LocalStorageService.SetString("AccessToken", authHandleData.AccessToken); + await LocalStorageService.SetString("RefreshToken", authHandleData.RefreshToken); + await LocalStorageService.Set("ExpiresAt", authHandleData.ExpiresAt); try { @@ -124,8 +125,8 @@ else await WindowService.Open( uri, "OAuth2 Flow", - 500, - 650 + 600, + 450 ); IsAuthenticating = true; @@ -139,17 +140,23 @@ else try { + if(!await LocalStorageService.ContainsKey("AccessToken")) + continue; + if (HttpClient.DefaultRequestHeaders.Contains("Authorization")) HttpClient.DefaultRequestHeaders.Remove("Authorization"); - - HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + await CookieService.GetValue("kms-access", "x")); + + HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + await LocalStorageService.GetString("AccessToken")); var res = await HttpClient.GetAsync("api/auth/check"); - - if(res.IsSuccessStatusCode) + + if (res.IsSuccessStatusCode) break; } - finally{} + catch (Exception e) + { + Console.WriteLine(e); + } } Navigation.NavigateTo(Navigation.Uri, true); diff --git a/Moonlight.Client/wwwroot/js/moonlight.js b/Moonlight.Client/wwwroot/js/moonlight.js index 051581ee..5b216873 100644 --- a/Moonlight.Client/wwwroot/js/moonlight.js +++ b/Moonlight.Client/wwwroot/js/moonlight.js @@ -1,25 +1,11 @@ window.moonlight = { window: { open: function (url, title, w, h) { - // Fixes dual-screen position Most browsers Firefox - const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : window.screenX; - const dualScreenTop = window.screenTop !== undefined ? window.screenTop : window.screenY; - - const width = window.innerWidth ? window.innerWidth : document.documentElement.clientWidth ? document.documentElement.clientWidth : screen.width; - const height = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight ? document.documentElement.clientHeight : screen.height; - - const systemZoom = width / window.screen.availWidth; - const left = (width - w) / 2 / systemZoom + dualScreenLeft - const top = (height - h) / 2 / systemZoom + dualScreenTop - const newWindow = window.open(url, title, - ` - scrollbars=yes, - width=${w / systemZoom}, - height=${h / systemZoom}, - top=${top}, - left=${left} - ` - ) + let height = w; + let width = h; + var left = (screen.width - width) / 2; + var top = (screen.height - height) / 2; + var newWindow = window.open(url, title, 'resizable = yes, width=' + width + ', height=' + height + ', top=' + top + ', left=' + left); if (window.focus) newWindow.focus(); },