Blazor Hybrid / .NET MAUI support
This commit is contained in:
@ -16,7 +16,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
return services;
|
||||
}
|
||||
|
||||
internal static IServiceCollection AddOqtaneScopedServices(this IServiceCollection services)
|
||||
public static IServiceCollection AddOqtaneScopedServices(this IServiceCollection services)
|
||||
{
|
||||
services.AddScoped<SiteState>();
|
||||
services.AddScoped<IInstallationService, InstallationService>();
|
||||
|
@ -184,11 +184,12 @@
|
||||
var interop = new Interop(JSRuntime);
|
||||
if (await interop.FormValid(login))
|
||||
{
|
||||
var hybrid = (PageState.Runtime == Shared.Runtime.Hybrid);
|
||||
var user = new User { SiteId = PageState.Site.SiteId, Username = _username, Password = _password, LastIPAddress = SiteState.RemoteIPAddress};
|
||||
|
||||
|
||||
if (!twofactor)
|
||||
{
|
||||
user = await UserService.LoginUserAsync(user);
|
||||
user = await UserService.LoginUserAsync(user, hybrid, _remember);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -199,10 +200,20 @@
|
||||
{
|
||||
await logger.LogInformation(LogFunction.Security, "Login Successful For Username {Username}", _username);
|
||||
|
||||
// post back to the Login page so that the cookies are set correctly
|
||||
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
|
||||
await interop.SubmitForm(url, fields);
|
||||
if (hybrid)
|
||||
{
|
||||
// hybrid apps utilize an interactive login
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
authstateprovider.NotifyAuthenticationChanged();
|
||||
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
|
||||
}
|
||||
else
|
||||
{
|
||||
// post back to the Login page so that the cookies are set correctly
|
||||
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
|
||||
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
|
||||
await interop.SubmitForm(url, fields);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -336,7 +336,7 @@ else
|
||||
user.Username = _hostusername;
|
||||
user.Password = _hostpassword;
|
||||
user.LastIPAddress = PageState.RemoteIPAddress;
|
||||
user = await UserService.LoginUserAsync(user);
|
||||
user = await UserService.LoginUserAsync(user, false, false);
|
||||
if (user.IsAuthenticated)
|
||||
{
|
||||
var database = _databases.SingleOrDefault(d => d.Name == _databaseName);
|
||||
|
@ -55,7 +55,8 @@ namespace Oqtane.Modules
|
||||
var scripts = new List<object>();
|
||||
foreach (Resource resource in Resources.Where(item => item.ResourceType == ResourceType.Script))
|
||||
{
|
||||
scripts.Add(new { href = resource.Url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module });
|
||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + "/" + resource.Url;
|
||||
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module });
|
||||
}
|
||||
if (scripts.Any())
|
||||
{
|
||||
|
@ -33,7 +33,7 @@ namespace Oqtane.Client
|
||||
|
||||
builder.Services.AddOptions();
|
||||
|
||||
// Register localization services
|
||||
// register localization services
|
||||
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
// register auth services
|
||||
|
@ -54,8 +54,10 @@ namespace Oqtane.Services
|
||||
/// Note that this will probably not be a real User, but a user object where the `Username` and `Password` have been filled.
|
||||
/// </summary>
|
||||
/// <param name="user">A <see cref="User"/> object which should have at least the <see cref="User.Username"/> and <see cref="User.Password"/> set.</param>
|
||||
/// <param name="setCookie">Determines if the login cookie should be set (only relevant for Hybrid scenarios)</param>
|
||||
/// <param name="isPersistent">Determines if the login cookie should be persisted for a long time.</param>
|
||||
/// <returns></returns>
|
||||
Task<User> LoginUserAsync(User user);
|
||||
Task<User> LoginUserAsync(User user, bool setCookie, bool isPersistent);
|
||||
|
||||
/// <summary>
|
||||
/// Logout a <see cref="User"/>
|
||||
|
@ -39,9 +39,9 @@ namespace Oqtane.Services
|
||||
await DeleteAsync($"{Apiurl}/{userId}?siteid={siteId}");
|
||||
}
|
||||
|
||||
public async Task<User> LoginUserAsync(User user)
|
||||
public async Task<User> LoginUserAsync(User user, bool setCookie, bool isPersistent)
|
||||
{
|
||||
return await PostJsonAsync<User>($"{Apiurl}/login", user);
|
||||
return await PostJsonAsync<User>($"{Apiurl}/login?setcookie={setCookie}&persistent={isPersistent}", user);
|
||||
}
|
||||
|
||||
public async Task LogoutUserAsync(User user)
|
||||
|
@ -3,6 +3,7 @@ using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.JSInterop;
|
||||
using Oqtane.Enums;
|
||||
using Oqtane.Providers;
|
||||
using Oqtane.Security;
|
||||
using Oqtane.Services;
|
||||
using Oqtane.Shared;
|
||||
@ -38,12 +39,23 @@ namespace Oqtane.Themes.Controls
|
||||
if (!UserSecurity.IsAuthorized(null, PermissionNames.View, PageState.Page.Permissions))
|
||||
{
|
||||
url = PageState.Alias.Path;
|
||||
}
|
||||
}
|
||||
|
||||
// post to the Logout page to complete the logout process
|
||||
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = url };
|
||||
var interop = new Interop(jsRuntime);
|
||||
await interop.SubmitForm(Utilities.TenantUrl(PageState.Alias, "/pages/logout/"), fields);
|
||||
if (PageState.Runtime == Shared.Runtime.Hybrid)
|
||||
{
|
||||
// hybrid apps utilize an interactive logout
|
||||
await UserService.LogoutUserAsync(PageState.User);
|
||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||
authstateprovider.NotifyAuthenticationChanged();
|
||||
NavigationManager.NavigateTo(url, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// post to the Logout page to complete the logout process
|
||||
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = url };
|
||||
var interop = new Interop(jsRuntime);
|
||||
await interop.SubmitForm(Utilities.TenantUrl(PageState.Alias, "/pages/logout/"), fields);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,8 @@
|
||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||
{
|
||||
var prefix = "app-stylesheet-" + resource.Level.ToString().ToLower();
|
||||
links.Add(new { id = prefix + "-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = resource.Url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", insertbefore = prefix });
|
||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + "/" + resource.Url;
|
||||
links.Add(new { id = prefix + "-" + batch + "-" + (links.Count + 1).ToString("00"), rel = "stylesheet", href = url, type = "text/css", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", insertbefore = prefix });
|
||||
}
|
||||
if (links.Any())
|
||||
{
|
||||
|
Reference in New Issue
Block a user