fix #2578 - error notification sent via email includes direct link to specific log item, however redirect was causing an infinite loop. This resolves the problem and also preserves url querystring parameters during login/logout.

This commit is contained in:
Shaun Walker 2023-02-06 16:44:25 -05:00
parent 1f2ad4e884
commit 56e4dcc11e
6 changed files with 33 additions and 16 deletions

View File

@ -1,3 +1,4 @@
@using System.Net
@namespace Oqtane.Modules.Admin.Login
@inherits ModuleBase
@inject NavigationManager NavigationManager
@ -205,7 +206,7 @@
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider
.GetService(typeof(IdentityAuthenticationStateProvider));
authstateprovider.NotifyAuthenticationChanged();
NavigationManager.NavigateTo(NavigateUrl(_returnUrl, true));
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
}
else
{

View File

@ -106,12 +106,6 @@ else
{
try
{
// external link to log item will display Details component
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id))
{
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}"));
}
if (UrlParameters.ContainsKey("level"))
{
_level = UrlParameters["level"];
@ -241,4 +235,15 @@ else
_page = page;
}
protected override void OnAfterRender(bool firstRender)
{
if (!firstRender)
{
// external link to log item will display Details component
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id))
{
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"/{id}"));
}
}
}
}

View File

@ -1,8 +1,10 @@
using System;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
using Oqtane.Enums;
using Oqtane.Models;
using Oqtane.Providers;
using Oqtane.Security;
using Oqtane.Services;
@ -22,20 +24,18 @@ namespace Oqtane.Themes.Controls
protected void LoginUser()
{
var returnurl = PageState.Alias.Path;
if (PageState.Page.Path != "/")
{
returnurl += "/" + PageState.Page.Path;
}
NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + returnurl));
Route route = new Route(PageState.Uri.AbsoluteUri, PageState.Alias.Path);
NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + WebUtility.UrlEncode(route.PathAndQuery)));
}
protected async Task LogoutUser()
{
await LoggingService.Log(PageState.Alias, PageState.Page.PageId, null, PageState.User?.UserId, GetType().AssemblyQualifiedName, "Logout", LogFunction.Security, LogLevel.Information, null, "User Logout For Username {Username}", PageState.User?.Username);
// check if anonymous user can access page
var url = PageState.Alias.Path + "/" + PageState.Page.Path;
Route route = new Route(PageState.Uri.AbsoluteUri, PageState.Alias.Path);
var url = route.PathAndQuery;
// verify if anonymous users can access page
if (!UserSecurity.IsAuthorized(null, PermissionNames.View, PageState.Page.Permissions))
{
url = PageState.Alias.Path;

View File

@ -250,7 +250,7 @@
if (user == null)
{
// redirect to login page if user not logged in as they may need to be authenticated
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + route.AbsolutePath));
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + WebUtility.UrlEncode(route.PathAndQuery)));
}
else
{

View File

@ -1,3 +1,4 @@
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
@ -43,6 +44,10 @@ namespace Oqtane.Pages
{
returnurl = "";
}
else
{
returnurl = WebUtility.UrlDecode(returnurl);
}
if (!returnurl.StartsWith("/"))
{
returnurl = "/" + returnurl;

View File

@ -24,6 +24,7 @@ namespace Oqtane.Models
Query = uri.Query;
Fragment = uri.Fragment;
AbsolutePath = uri.AbsolutePath;
PathAndQuery = uri.PathAndQuery;
AliasPath = aliaspath;
PagePath = AbsolutePath;
ModuleId = "";
@ -90,6 +91,11 @@ namespace Oqtane.Models
/// </summary>
public string AbsolutePath { get; set; }
/// <summary>
/// The absolute path for the route including the querystring
/// </summary>
public string PathAndQuery { get; set; }
/// <summary>
/// An absolute path may contain an alias path
/// </summary>