refactoring, enhancements, and some fixes

This commit is contained in:
Shaun Walker
2021-06-10 08:16:02 -04:00
parent 82c05a841f
commit bc720555c4
30 changed files with 436 additions and 244 deletions

View File

@ -1,4 +1,6 @@
@inject IInstallationService InstallationService
@inject IJSRuntime JSRuntime
@inject SiteState SiteState
@if (_initialized)
{
@ -20,21 +22,28 @@
{
<div class="app-alert">
@_installation.Message
</div>
</div>
}
}
}
@code {
private Installation _installation;
private bool _initialized;
private bool _initialized = false;
private Installation _installation = new Installation { Success = false, Message = "" };
private PageState PageState { get; set; }
protected override async Task OnParametersSetAsync()
protected override async Task OnAfterRenderAsync(bool firstRender)
{
_installation = await InstallationService.IsInstalled();
_initialized = true;
if (firstRender && !_initialized)
{
var interop = new Interop(JSRuntime);
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
_installation = await InstallationService.IsInstalled();
SiteState.Alias = _installation.Alias;
_initialized = true;
StateHasChanged();
}
}
private void ChangeState(PageState pageState)

View File

@ -3,6 +3,7 @@
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject IServiceProvider ServiceProvider
@inject SiteState SiteState
@inject IStringLocalizer<Index> Localizer
@if (_message != string.Empty)
@ -57,7 +58,7 @@
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
public override List<Resource> Resources => new List<Resource>()
{
{
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" }
};
@ -108,7 +109,6 @@
{
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
{
// server-side Blazor
var user = new User();
user.SiteId = PageState.Site.SiteId;
user.Username = _username;
@ -118,9 +118,8 @@
if (user.IsAuthenticated)
{
await logger.LogInformation("Login Successful For Username {Username}", _username);
// complete the login on the server so that the cookies are set correctly
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
var fields = new { __RequestVerificationToken = antiforgerytoken, username = _username, password = _password, remember = _remember, returnurl = _returnUrl };
// server-side Blazor needs to post 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);
}

View File

@ -21,14 +21,6 @@
<input id="name" class="form-control" @bind="@_name" />
</td>
</tr>
<tr>
<td>
<Label For="alias" HelpText="Enter the aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they can be separated by commas." ResourceKey="Aliases">Aliases: </Label>
</td>
<td>
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
</td>
</tr>
<tr>
<td>
<Label For="allowRegister" HelpText="Do you want the users to be able to register for an account on the site" ResourceKey="AllowRegistration">Allow User Registration? </Label>
@ -210,6 +202,18 @@
</Section>
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
<Section Name="Alias" Heading="Alias Management" ResourceKey="Alias">
<table class="table table-borderless">
<tr>
<td>
<Label For="alias" HelpText="Enter the aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they can be separated by commas." ResourceKey="Aliases">Aliases: </Label>
</td>
<td>
<textarea id="alias" class="form-control" @bind="@_urls" rows="3"></textarea>
</td>
</tr>
</table>
</Section>
<Section Name="TenantInformation" Heading="Tenant Information" ResourceKey="TenantInformation">
<table class="table table-borderless">
<tr>
@ -292,16 +296,24 @@
try
{
_themeList = await ThemeService.GetThemesAsync();
_aliasList = await AliasService.GetAliasesAsync();
Site site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
if (site != null)
{
_name = site.Name;
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
_allowregistration = site.AllowRegistration.ToString();
_isdeleted = site.IsDeleted.ToString();
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
_urls += alias.Name + ",";
_aliasList = await AliasService.GetAliasesAsync();
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{
_urls += alias.Name + ",";
}
_urls = _urls.Substring(0, _urls.Length - 1);
}
_urls = _urls.Substring(0, _urls.Length - 1);
if (site.LogoFileId != null)
{
_logofileid = site.LogoFileId.Value;
@ -317,7 +329,6 @@
_containers = ThemeService.GetContainerControls(_themeList, _themetype);
_containertype = (!string.IsNullOrEmpty(site.DefaultContainerType)) ? site.DefaultContainerType : Constants.DefaultContainer;
_admincontainertype = (!string.IsNullOrEmpty(site.AdminContainerType)) ? site.AdminContainerType : Constants.DefaultAdminContainer;
_allowregistration = site.AllowRegistration.ToString();
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
_smtphost = SettingService.GetSetting(settings, "SMTPHost", string.Empty);
@ -368,7 +379,6 @@
_modifiedon = site.ModifiedOn;
_deletedby = site.DeletedBy;
_deletedon = site.DeletedOn;
_isdeleted = site.IsDeleted.ToString();
_initialized = true;
}
@ -427,34 +437,30 @@
bool refresh = (site.DefaultThemeType != _themetype || site.DefaultContainerType != _containertype);
site.Name = _name;
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
site.LogoFileId = null;
var logofileid = _logofilemanager.GetFileId();
if (logofileid != -1)
{
site.LogoFileId = logofileid;
}
var faviconFieldId = _faviconfilemanager.GetFileId();
if (faviconFieldId != -1)
{
site.FaviconFileId = faviconFieldId;
}
site.DefaultThemeType = _themetype;
site.DefaultContainerType = _containertype;
site.AdminContainerType = _admincontainertype;
site.AllowRegistration = (_allowregistration == null ? true : Boolean.Parse(_allowregistration));
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
site.PwaIsEnabled = (_pwaisenabled == null ? true : Boolean.Parse(_pwaisenabled));
var pwaappiconfileid = _pwaappiconfilemanager.GetFileId();
if (pwaappiconfileid != -1)
{
site.PwaAppIconFileId = pwaappiconfileid;
}
var pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId();
if (pwasplashiconfileid != -1)
{
@ -463,27 +469,6 @@
site = await SiteService.UpdateSiteAsync(site);
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{
if (!names.Contains(alias.Name))
{
await AliasService.DeleteAliasAsync(alias.AliasId);
}
}
foreach (string name in names)
{
if (!_aliasList.Exists(item => item.Name == name))
{
Alias alias = new Alias();
alias.Name = name;
alias.TenantId = site.TenantId;
alias.SiteId = site.SiteId;
await AliasService.AddAliasAsync(alias);
}
}
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
@ -493,7 +478,32 @@
SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
{
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
{
if (!names.Contains(alias.Name))
{
await AliasService.DeleteAliasAsync(alias.AliasId);
}
}
foreach (string name in names)
{
if (!_aliasList.Exists(item => item.Name == name))
{
Alias alias = new Alias();
alias.Name = name;
alias.TenantId = site.TenantId;
alias.SiteId = site.SiteId;
await AliasService.AddAliasAsync(alias);
}
}
}
await logger.LogInformation("Site Settings Saved {Site}", site);
if (refresh)
{
NavigationManager.NavigateTo(NavigateUrl()); // refresh to show new theme or container

View File

@ -15,12 +15,14 @@ else
<Pager Items="@_sites">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["Name"]</th>
</Header>
<Row>
<td><NavLink class="btn btn-primary" href="@(_scheme + context.Name +"/admin/site")">@Localizer["Edit"]</NavLink></td>
<td><a href="@(_scheme + context.Name +"?reload")">@context.Name</a></td>
<td><button type="button" class="btn btn-primary" @onclick="@(async () => Edit(context.Name))">@Localizer["Edit"]</button></td>
<td><button type="button" class="btn btn-secondary" @onclick="@(async () => Browse(context.Name))">@Localizer["Browse"]</button></td>
<td>@context.Name</td>
</Row>
</Pager>
}
@ -46,4 +48,15 @@ else
}
}
}
private void Edit(string name)
{
NavigationManager.NavigateTo(_scheme + name + "/admin/site", true);
}
private void Browse(string name)
{
NavigationManager.NavigateTo(_scheme + name, true);
}
}

View File

@ -1,5 +1,3 @@
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Oqtane.Services;
@ -9,34 +7,35 @@ namespace Oqtane.Modules.HtmlText.Services
{
public class HtmlTextService : ServiceBase, IHtmlTextService, IService
{
private readonly SiteState _siteState;
public HtmlTextService(HttpClient http, SiteState siteState) : base(http, siteState) {}
public HtmlTextService(HttpClient http, SiteState siteState) : base(http)
{
_siteState = siteState;
}
private string ApiUrl => CreateApiUrl("HtmlText", _siteState.Alias);
private string ApiUrl => CreateApiUrl("HtmlText");
public async Task<Models.HtmlText> GetHtmlTextAsync(int moduleId)
{
var htmltext = await GetJsonAsync<List<Models.HtmlText>>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", new Dictionary<string, int>() { { EntityNames.Module, moduleId } }));
return htmltext.FirstOrDefault();
AddAuthorizationPolicyHeader(EntityNames.Module, moduleId);
return await GetJsonAsync<Models.HtmlText>($"{ApiUrl}/{moduleId}");
}
public async Task AddHtmlTextAsync(Models.HtmlText htmlText)
{
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", new Dictionary<string, int>() { { EntityNames.Module, htmlText.ModuleId } }), htmlText);
AddAntiForgeryToken();
AddAuthorizationPolicyHeader(EntityNames.Module, htmlText.ModuleId);
await PostJsonAsync($"{ApiUrl}", htmlText);
}
public async Task UpdateHtmlTextAsync(Models.HtmlText htmlText)
{
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", new Dictionary<string, int>() { { EntityNames.Module, htmlText.ModuleId } }), htmlText);
AddAntiForgeryToken();
AddAuthorizationPolicyHeader(EntityNames.Module, htmlText.ModuleId);
await PutJsonAsync($"{ApiUrl}/{htmlText.HtmlTextId}", htmlText);
}
public async Task DeleteHtmlTextAsync(int moduleId)
{
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", new Dictionary<string, int>() { { EntityNames.Module, moduleId } }));
AddAntiForgeryToken();
AddAuthorizationPolicyHeader(EntityNames.Module, moduleId);
await DeleteAsync($"{ApiUrl}/{moduleId}");
}
}
}

View File

@ -13,7 +13,6 @@ using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.JSInterop;
using Oqtane.Interfaces;
using Oqtane.Modules;
using Oqtane.Providers;
using Oqtane.Services;
@ -69,6 +68,8 @@ namespace Oqtane.Client
builder.Services.AddScoped<ISystemService, SystemService>();
builder.Services.AddScoped<ILocalizationService, LocalizationService>();
builder.Services.AddScoped<ILanguageService, LanguageService>();
builder.Services.AddScoped<IDatabaseService, DatabaseService>();
builder.Services.AddScoped<ISyncService, SyncService>();
await LoadClientAssemblies(httpClient);

View File

@ -30,14 +30,11 @@ namespace Oqtane.Providers
// get HttpClient lazily from IServiceProvider as you cannot use standard dependency injection due to the AuthenticationStateProvider being initialized prior to NavigationManager(https://github.com/aspnet/AspNetCore/issues/11867 )
var http = _serviceProvider.GetRequiredService<HttpClient>();
// get alias as SiteState has not been initialized ( cannot use AliasService as it is not yet registered )
var path = new Uri(_navigationManager.Uri).LocalPath.Substring(1);
var alias = await http.GetFromJsonAsync<Alias>($"/api/Alias/name/?path={WebUtility.UrlEncode(path)}&sync={DateTime.UtcNow.ToString("yyyyMMddHHmmssfff")}");
// get user
User user = await http.GetFromJsonAsync<User>(Utilities.TenantUrl(alias, "/api/User/authenticate"));
var siteState = _serviceProvider.GetRequiredService<SiteState>();
User user = await http.GetFromJsonAsync<User>(Utilities.TenantUrl(siteState.Alias, "/api/User/authenticate"));
if (user.IsAuthenticated)
{
identity = UserSecurity.CreateClaimsIdentity(alias, user);
identity = UserSecurity.CreateClaimsIdentity(siteState.Alias, user);
}
return new AuthenticationState(new ClaimsPrincipal(identity));

View File

@ -3,8 +3,6 @@ using System.Threading.Tasks;
using System.Net.Http;
using System.Linq;
using System.Collections.Generic;
using System.Net;
using System;
using Oqtane.Documentation;
using Oqtane.Shared;
@ -40,13 +38,6 @@ namespace Oqtane.Services
return await GetJsonAsync<Alias>($"{ApiUrl}/{aliasId}");
}
/// <inheritdoc />
public async Task<Alias> GetAliasAsync(string path, DateTime lastSyncDate)
{
// tenant agnostic as SiteState does not exist
return await GetJsonAsync<Alias>($"{CreateApiUrl("Alias", null)}/name/?path={WebUtility.UrlEncode(path)}&sync={lastSyncDate.ToString("yyyyMMddHHmmssfff")}");
}
/// <inheritdoc />
public async Task<Alias> AddAliasAsync(Alias alias)
{

View File

@ -3,19 +3,28 @@ using System.Threading.Tasks;
using System.Net.Http;
using Oqtane.Documentation;
using Oqtane.Shared;
using Microsoft.AspNetCore.Components;
using System;
using System.Net;
namespace Oqtane.Services
{
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
public class InstallationService : ServiceBase, IInstallationService
{
public InstallationService(HttpClient http) : base(http) {}
private readonly NavigationManager _navigationManager;
private string ApiUrl => CreateApiUrl("Installation", null); // tenant agnostic as SiteState does not exist
public InstallationService(HttpClient http, NavigationManager navigationManager) : base(http)
{
_navigationManager = navigationManager;
}
private string ApiUrl => CreateApiUrl("Installation", null, ControllerRoutes.ApiRoute); // tenant agnostic
public async Task<Installation> IsInstalled()
{
return await GetJsonAsync<Installation>($"{ApiUrl}/installed");
var path = new Uri(_navigationManager.Uri).LocalPath.Substring(1);
return await GetJsonAsync<Installation>($"{ApiUrl}/installed/?path={WebUtility.UrlEncode(path)}");
}
public async Task<Installation> Install(InstallConfig config)

View File

@ -23,14 +23,6 @@ namespace Oqtane.Services
/// <returns></returns>
Task<Alias> GetAliasAsync(int aliasId);
/// <summary>
/// Retrieve the Alias object of a URL.
/// </summary>
/// <param name="url">The URL - todoc - is this only the root, or can it be a longer path?</param>
/// <param name="lastSyncDate">todoc - unclear what this is for</param>
/// <returns></returns>
Task<Alias> GetAliasAsync(string url, DateTime lastSyncDate);
/// <summary>
/// Save another <see cref="Oqtane.Models.Alias"/> in the DB. It must already contain all the information incl. <see cref="Oqtane.Models.Tenant"/> it belongs to.
/// </summary>

View File

@ -0,0 +1,19 @@
using Oqtane.Models;
using System;
using System.Threading.Tasks;
namespace Oqtane.Services
{
/// <summary>
/// Service to retrieve <see cref="Sync"/> information.
/// </summary>
public interface ISyncService
{
/// <summary>
/// Get sync events
/// </summary>
/// <param name="lastSyncDate"></param>
/// <returns></returns>
Task<Sync> GetSyncAsync(DateTime lastSyncDate);
}
}

View File

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Oqtane.Documentation;
using Oqtane.Models;
using Oqtane.Shared;
@ -15,10 +17,25 @@ namespace Oqtane.Services
public class ServiceBase
{
private readonly HttpClient _http;
private readonly SiteState _siteState;
protected ServiceBase(HttpClient client)
protected ServiceBase(HttpClient client, SiteState siteState)
{
_http = client;
_siteState = siteState;
}
// should be used with new constructor
public string CreateApiUrl(string serviceName)
{
if (_siteState != null)
{
return CreateApiUrl(serviceName, _siteState.Alias, ControllerRoutes.ApiRoute);
}
else // legacy support (before 2.1.0)
{
return CreateApiUrl(serviceName, null, ControllerRoutes.Default);
}
}
public string CreateApiUrl(string serviceName, Alias alias)
@ -61,10 +78,10 @@ namespace Oqtane.Services
return CreateAuthorizationPolicyUrl(url, new Dictionary<string, int>() { { entityName, entityId } });
}
public string CreateAuthorizationPolicyUrl(string url, Dictionary<string, int> args)
public string CreateAuthorizationPolicyUrl(string url, Dictionary<string, int> authEntityId)
{
string qs = "";
foreach (KeyValuePair<string, int> kvp in args)
foreach (KeyValuePair<string, int> kvp in authEntityId)
{
qs += (qs != "") ? "&" : "";
qs += "auth" + kvp.Key.ToLower() + "id=" + kvp.Value.ToString();
@ -80,6 +97,33 @@ namespace Oqtane.Services
}
}
protected void AddRequestHeader(string name, string value)
{
if (_http.DefaultRequestHeaders.Contains(name))
{
_http.DefaultRequestHeaders.Remove(name);
}
_http.DefaultRequestHeaders.Add(name, value);
}
protected void AddAntiForgeryToken()
{
AddRequestHeader(Constants.AntiForgeryTokenHeaderName, _siteState.AntiForgeryToken);
}
public void AddAuthorizationPolicyHeader(string entityName, int entityId)
{
AddAuthorizationPolicyHeader(new Dictionary<string, int>() { { entityName, entityId } });
}
public void AddAuthorizationPolicyHeader(Dictionary<string, int> authEntityId)
{
foreach (KeyValuePair<string, int> kvp in authEntityId)
{
AddRequestHeader("auth" + kvp.Key.ToLower() + "id", kvp.Value.ToString());
}
}
protected async Task GetAsync(string uri)
{
var response = await _http.GetAsync(uri);
@ -194,10 +238,11 @@ namespace Oqtane.Services
return mediaType != null && mediaType.Equals("application/json", StringComparison.OrdinalIgnoreCase);
}
[Obsolete("This method is obsolete. Use CreateApiUrl(string serviceName, Alias alias) in conjunction with ControllerRoutes.ApiRoute in Controllers instead.", false)]
public string CreateApiUrl(string serviceName)
//[Obsolete("This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead.", false)]
// This constructor is obsolete. Use ServiceBase(HttpClient client, SiteState siteState) : base(http, siteState) {} instead.
protected ServiceBase(HttpClient client)
{
return CreateApiUrl(serviceName, null, ControllerRoutes.Default);
_http = client;
}
[Obsolete("This method is obsolete. Use CreateApiUrl(string serviceName, Alias alias) in conjunction with ControllerRoutes.ApiRoute in Controllers instead.", false)]

View File

@ -0,0 +1,33 @@
using Oqtane.Models;
using System.Threading.Tasks;
using System.Net.Http;
using System;
using Oqtane.Documentation;
using Oqtane.Shared;
namespace Oqtane.Services
{
/// <inheritdoc cref="ISyncService" />
[PrivateApi("Don't show in the documentation, as everything should use the Interface")]
public class SyncService : ServiceBase, ISyncService
{
private readonly SiteState _siteState;
/// <summary>
/// Constructor - should only be used by Dependency Injection
/// </summary>
public SyncService(HttpClient http, SiteState siteState) : base(http)
{
_siteState = siteState;
}
private string ApiUrl => CreateApiUrl("Sync", _siteState.Alias);
/// <inheritdoc />
public async Task<Sync> GetSyncAsync(DateTime lastSyncDate)
{
return await GetJsonAsync<Sync>($"{ApiUrl}/{lastSyncDate.ToString("yyyyMMddHHmmssfff")}");
}
}
}

View File

@ -115,7 +115,7 @@ namespace Oqtane.Themes.Controls
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, oldPane);
return url;
return NavigateUrl(url, "reload");
}
private async Task<string> DeleteModule(string url, PageModule pagemodule)
@ -123,7 +123,7 @@ namespace Oqtane.Themes.Controls
pagemodule.IsDeleted = true;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
return url;
return NavigateUrl(url, "reload");
}
private async Task<string> Settings(string url, PageModule pagemodule)
@ -174,7 +174,7 @@ namespace Oqtane.Themes.Controls
pagemodule.Order = 0;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
return s;
return NavigateUrl(s, "reload");
}
private async Task<string> MoveBottom(string s, PageModule pagemodule)
@ -182,7 +182,7 @@ namespace Oqtane.Themes.Controls
pagemodule.Order = int.MaxValue;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
return s;
return NavigateUrl(s, "reload");
}
private async Task<string> MoveUp(string s, PageModule pagemodule)
@ -190,7 +190,7 @@ namespace Oqtane.Themes.Controls
pagemodule.Order -= 3;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
return s;
return NavigateUrl(s, "reload");
}
private async Task<string> MoveDown(string s, PageModule pagemodule)
@ -198,7 +198,7 @@ namespace Oqtane.Themes.Controls
pagemodule.Order += 3;
await PageModuleService.UpdatePageModuleAsync(pagemodule);
await PageModuleService.UpdatePageModuleOrderAsync(pagemodule.PageId, pagemodule.Pane);
return s;
return NavigateUrl(s, "reload");
}
public class ActionViewModel

View File

@ -16,6 +16,7 @@ namespace Oqtane.Themes.Controls
[Inject] public IUserService UserService { get; set; }
[Inject] public IJSRuntime jsRuntime { get; set; }
[Inject] public IServiceProvider ServiceProvider { get; set; }
[Inject] public SiteState SiteState { get; set; }
protected void LoginUser()
{
@ -35,11 +36,10 @@ namespace Oqtane.Themes.Controls
if (PageState.Runtime == Oqtane.Shared.Runtime.Server)
{
// server-side Blazor
var interop = new Interop(jsRuntime);
string antiforgerytoken = await interop.GetElementByName("__RequestVerificationToken");
var fields = new { __RequestVerificationToken = antiforgerytoken, returnurl = !authorizedtoviewpage ? PageState.Alias.Path : PageState.Alias.Path + "/" + PageState.Page.Path };
// server-side Blazor needs to post to the Logout page
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, returnurl = !authorizedtoviewpage ? PageState.Alias.Path : PageState.Alias.Path + "/" + PageState.Page.Path };
string url = Utilities.TenantUrl(PageState.Alias, "/pages/logout/");
var interop = new Interop(jsRuntime);
await interop.SubmitForm(url, fields);
}
else

View File

@ -5,8 +5,7 @@
@inject SiteState SiteState
@inject NavigationManager NavigationManager
@inject INavigationInterception NavigationInterception
@inject IAliasService AliasService
@inject ITenantService TenantService
@inject ISyncService SyncService
@inject ISiteService SiteService
@inject IPageService PageService
@inject IUserService UserService
@ -69,7 +68,6 @@
[SuppressMessage("ReSharper", "StringIndexOfIsCultureSpecific.1")]
private async Task Refresh()
{
Alias alias = null;
Site site;
List<Page> pages;
Page page;
@ -103,27 +101,25 @@
lastsyncdate = PageState.LastSyncDate;
}
alias = await AliasService.GetAliasAsync(path, lastsyncdate);
SiteState.Alias = alias; // set state for services
lastsyncdate = alias.SyncDate;
// process any sync events
if (reload != Reload.Site && alias.SyncEvents.Any())
var sync = await SyncService.GetSyncAsync(lastsyncdate);
lastsyncdate = sync.SyncDate;
if (reload != Reload.Site && sync.SyncEvents.Any())
{
// if running on WebAssembly reload the client application if the server application was restarted
if (runtime == Shared.Runtime.WebAssembly && PageState != null && alias.SyncEvents.Exists(item => item.TenantId == -1))
if (runtime == Shared.Runtime.WebAssembly && PageState != null && sync.SyncEvents.Exists(item => item.TenantId == -1))
{
NavigationManager.NavigateTo(_absoluteUri + (!_absoluteUri.Contains("?") ? "?" : "&") + "reload", true);
}
if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == alias.SiteId))
if (sync.SyncEvents.Exists(item => item.EntityName == EntityNames.Site && item.EntityId == SiteState.Alias.SiteId))
{
reload = Reload.Site;
}
}
if (reload == Reload.Site || PageState == null || alias.SiteId != PageState.Alias.SiteId)
if (reload == Reload.Site || PageState == null || PageState.Alias.SiteId != SiteState.Alias.SiteId)
{
site = await SiteService.GetSiteAsync(alias.SiteId);
site = await SiteService.GetSiteAsync(SiteState.Alias.SiteId);
reload = Reload.Site;
}
else
@ -148,9 +144,9 @@
}
// process any sync events for user
if (reload != Reload.Site && user != null && alias.SyncEvents.Any())
if (reload != Reload.Site && user != null && sync.SyncEvents.Any())
{
if (alias.SyncEvents.Exists(item => item.EntityName == EntityNames.User && item.EntityId == user.UserId))
if (sync.SyncEvents.Exists(item => item.EntityName == EntityNames.User && item.EntityId == user.UserId))
{
reload = Reload.Site;
}
@ -173,9 +169,9 @@
path += "/";
}
if (alias.Path != "")
if (SiteState.Alias.Path != "")
{
path = path.Substring(alias.Path.Length + 1);
path = path.Substring(SiteState.Alias.Path.Length + 1);
}
// extract admin route elements from path
@ -281,7 +277,7 @@
_pagestate = new PageState
{
Alias = alias,
Alias = SiteState.Alias,
Site = site,
Pages = pages,
Page = page,
@ -305,7 +301,7 @@
if (user == null)
{
// redirect to login page
NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "login", "?returnurl=" + path));
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + path));
}
else
{
@ -313,7 +309,7 @@
if (path != "")
{
// redirect to home page
NavigationManager.NavigateTo(Utilities.NavigateUrl(alias.Path, "", ""));
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "", ""));
}
}
}