Merge branch 'dev' into 3805-stop-registration-redirect-without-verification
This commit is contained in:
commit
1c586d8811
@ -17,7 +17,6 @@ else
|
|||||||
|
|
||||||
<Pager Items="@_jobs" SearchProperties="Name">
|
<Pager Items="@_jobs" SearchProperties="Name">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
@ -28,7 +27,6 @@ else
|
|||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.JobId.ToString())" ResourceKey="EditJob" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.JobId.ToString())" ResourceKey="EditJob" /></td>
|
||||||
<td><ActionDialog Header="Delete Job" Message="Are You Sure You Wish To Delete This Job?" Action="Delete" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await DeleteJob(context))" ResourceKey="DeleteJob" /></td>
|
|
||||||
<td><ActionLink Action="Log" Class="btn btn-secondary" Parameters="@($"id=" + context.JobId.ToString())" ResourceKey="JobLog" /></td>
|
<td><ActionLink Action="Log" Class="btn btn-secondary" Parameters="@($"id=" + context.JobId.ToString())" ResourceKey="JobLog" /></td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@DisplayStatus(context.IsEnabled, context.IsExecuting)</td>
|
<td>@DisplayStatus(context.IsEnabled, context.IsExecuting)</td>
|
||||||
@ -53,7 +51,7 @@ else
|
|||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
public override SecurityAccessLevel SecurityAccessLevel { get { return SecurityAccessLevel.Host; } }
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_jobs = await JobService.GetJobsAsync();
|
_jobs = await JobService.GetJobsAsync();
|
||||||
if (_jobs.Count == 0)
|
if (_jobs.Count == 0)
|
||||||
@ -112,22 +110,6 @@ else
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task DeleteJob(Job job)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await JobService.DeleteJobAsync(job.JobId);
|
|
||||||
await logger.LogInformation("Job Deleted {Job}", job);
|
|
||||||
_jobs = await JobService.GetJobsAsync();
|
|
||||||
StateHasChanged();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
await logger.LogError(ex, "Error Deleting Job {Job} {Error}", job, ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Error.Job.Delete"], MessageType.Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task StartJob(int jobId)
|
private async Task StartJob(int jobId)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -48,6 +48,11 @@
|
|||||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Forgot">@Localizer["ForgotPassword"]</button>
|
||||||
|
@if (PageState.Site.AllowRegistration)
|
||||||
|
{
|
||||||
|
<br /><br />
|
||||||
|
<NavLink href="@NavigateUrl("register")">@Localizer["Register"]</NavLink>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -84,8 +89,6 @@
|
|||||||
private bool _alwaysremember = false;
|
private bool _alwaysremember = false;
|
||||||
private string _code = string.Empty;
|
private string _code = string.Empty;
|
||||||
|
|
||||||
private string _returnUrl = string.Empty;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
@ -103,11 +106,6 @@
|
|||||||
|
|
||||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
|
||||||
{
|
|
||||||
_returnUrl = PageState.QueryString["returnurl"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("name"))
|
if (PageState.QueryString.ContainsKey("name"))
|
||||||
{
|
{
|
||||||
_username = PageState.QueryString["name"];
|
_username = PageState.QueryString["name"];
|
||||||
@ -208,12 +206,12 @@
|
|||||||
// hybrid apps utilize an interactive login
|
// hybrid apps utilize an interactive login
|
||||||
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
var authstateprovider = (IdentityAuthenticationStateProvider)ServiceProvider.GetService(typeof(IdentityAuthenticationStateProvider));
|
||||||
authstateprovider.NotifyAuthenticationChanged();
|
authstateprovider.NotifyAuthenticationChanged();
|
||||||
NavigationManager.NavigateTo(NavigateUrl(WebUtility.UrlDecode(_returnUrl), true));
|
NavigationManager.NavigateTo(NavigateUrl(PageState.ReturnUrl, true));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// post back to the Login page so that the cookies are set correctly
|
// 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 };
|
var fields = new { __RequestVerificationToken = SiteState.AntiForgeryToken, username = _username, password = _password, remember = _remember, returnurl = WebUtility.UrlEncode(PageState.ReturnUrl) };
|
||||||
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
|
string url = Utilities.TenantUrl(PageState.Alias, "/pages/login/");
|
||||||
await interop.SubmitForm(url, fields);
|
await interop.SubmitForm(url, fields);
|
||||||
}
|
}
|
||||||
@ -255,7 +253,7 @@
|
|||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(WebUtility.UrlDecode(_returnUrl));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Forgot()
|
private async Task Forgot()
|
||||||
@ -323,7 +321,7 @@
|
|||||||
|
|
||||||
private void ExternalLogin()
|
private void ExternalLogin()
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(Utilities.TenantUrl(PageState.Alias, "/pages/external?returnurl=" + _returnUrl), true);
|
NavigationManager.NavigateTo(Utilities.TenantUrl(PageState.Alias, "/pages/external?returnurl=" + WebUtility.UrlEncode(PageState.ReturnUrl)), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -201,7 +201,7 @@
|
|||||||
@if (_themeSettingsType != null)
|
@if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
<TabPanel Name="ThemeSettings" Heading=@Localizer["Theme.Heading"] ResourceKey="ThemeSettings">
|
<TabPanel Name="ThemeSettings" Heading=@Localizer["Theme.Heading"] ResourceKey="ThemeSettings">
|
||||||
@ThemeSettingsComponent
|
@_themeSettingsComponent
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
}
|
}
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
@ -240,7 +240,7 @@
|
|||||||
private PermissionGrid _permissionGrid;
|
private PermissionGrid _permissionGrid;
|
||||||
private Type _themeSettingsType;
|
private Type _themeSettingsType;
|
||||||
private object _themeSettings;
|
private object _themeSettings;
|
||||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
private RenderFragment _themeSettingsComponent { get; set; }
|
||||||
private bool _refresh = false;
|
private bool _refresh = false;
|
||||||
protected Page _parent = null;
|
protected Page _parent = null;
|
||||||
protected Dictionary<string, string> _icons;
|
protected Dictionary<string, string> _icons;
|
||||||
@ -337,13 +337,14 @@
|
|||||||
private void ThemeSettings()
|
private void ThemeSettings()
|
||||||
{
|
{
|
||||||
_themeSettingsType = null;
|
_themeSettingsType = null;
|
||||||
|
_themeSettingsComponent = null;
|
||||||
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||||
{
|
{
|
||||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||||
if (_themeSettingsType != null)
|
if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
ThemeSettingsComponent = builder =>
|
_themeSettingsComponent = builder =>
|
||||||
{
|
{
|
||||||
builder.OpenComponent(0, _themeSettingsType);
|
builder.OpenComponent(0, _themeSettingsType);
|
||||||
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
||||||
|
@ -234,7 +234,7 @@
|
|||||||
@if (_themeSettingsType != null)
|
@if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
||||||
@ThemeSettingsComponent
|
@_themeSettingsComponent
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<br />
|
<br />
|
||||||
}
|
}
|
||||||
@ -278,7 +278,7 @@
|
|||||||
@if (_themeSettingsType != null)
|
@if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
<TabPanel Name="ThemeSettings" Heading="Theme Settings" ResourceKey="ThemeSettings">
|
||||||
@ThemeSettingsComponent
|
@_themeSettingsComponent
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<br />
|
<br />
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@
|
|||||||
private string _containertype = "-";
|
private string _containertype = "-";
|
||||||
private Type _themeSettingsType;
|
private Type _themeSettingsType;
|
||||||
private object _themeSettings;
|
private object _themeSettings;
|
||||||
private RenderFragment ThemeSettingsComponent { get; set; }
|
private RenderFragment _themeSettingsComponent { get; set; }
|
||||||
private string _headcontent;
|
private string _headcontent;
|
||||||
private string _bodycontent;
|
private string _bodycontent;
|
||||||
private List<Permission> _permissions = null;
|
private List<Permission> _permissions = null;
|
||||||
@ -478,13 +478,14 @@
|
|||||||
private void ThemeSettings()
|
private void ThemeSettings()
|
||||||
{
|
{
|
||||||
_themeSettingsType = null;
|
_themeSettingsType = null;
|
||||||
|
_themeSettingsComponent = null;
|
||||||
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
var theme = PageState.Site.Themes.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||||
{
|
{
|
||||||
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
_themeSettingsType = Type.GetType(theme.ThemeSettingsType);
|
||||||
if (_themeSettingsType != null)
|
if (_themeSettingsType != null)
|
||||||
{
|
{
|
||||||
ThemeSettingsComponent = builder =>
|
_themeSettingsComponent = builder =>
|
||||||
{
|
{
|
||||||
builder.OpenComponent(0, _themeSettingsType);
|
builder.OpenComponent(0, _themeSettingsType);
|
||||||
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
builder.AddComponentReferenceCapture(1, inst => { _themeSettings = Convert.ChangeType(inst, _themeSettingsType); });
|
||||||
@ -630,11 +631,11 @@
|
|||||||
await logger.LogInformation("Page Saved {Page}", _page);
|
await logger.LogInformation("Page Saved {Page}", _page);
|
||||||
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
NavigationManager.NavigateTo(PageState.ReturnUrl, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -62,6 +62,11 @@
|
|||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-primary" @onclick="Register">@Localizer["Register"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Register">@Localizer["Register"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
||||||
|
@if (_allowsitelogin)
|
||||||
|
{
|
||||||
|
<br /><br />
|
||||||
|
<NavLink href="@NavigateUrl("login")">@Localizer["Login"]</NavLink>
|
||||||
|
}
|
||||||
</form>
|
</form>
|
||||||
</NotAuthorized>
|
</NotAuthorized>
|
||||||
</AuthorizeView>
|
</AuthorizeView>
|
||||||
@ -84,12 +89,14 @@ else
|
|||||||
private string _email = string.Empty;
|
private string _email = string.Empty;
|
||||||
private string _displayname = string.Empty;
|
private string _displayname = string.Empty;
|
||||||
private bool _userCreated = false;
|
private bool _userCreated = false;
|
||||||
|
private bool _allowsitelogin = true;
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
|
||||||
|
_allowsitelogin = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:AllowSiteLogin", "true"));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
@ -158,7 +165,7 @@ else
|
|||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TogglePassword()
|
private void TogglePassword()
|
||||||
|
@ -579,9 +579,6 @@
|
|||||||
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
||||||
if (site != null)
|
if (site != null)
|
||||||
{
|
{
|
||||||
bool refresh = false;
|
|
||||||
bool reload = false;
|
|
||||||
|
|
||||||
site.Name = _name;
|
site.Name = _name;
|
||||||
site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
|
site.HomePageId = (_homepageid != "-" ? int.Parse(_homepageid) : null);
|
||||||
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
site.IsDeleted = (_isdeleted == null ? true : Boolean.Parse(_isdeleted));
|
||||||
@ -595,7 +592,6 @@
|
|||||||
if (logofileid != _logofileid)
|
if (logofileid != _logofileid)
|
||||||
{
|
{
|
||||||
_logofileid = logofileid;
|
_logofileid = logofileid;
|
||||||
refresh = true; // needs to be refreshed on client
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int? faviconFieldId = _faviconfilemanager.GetFileId();
|
int? faviconFieldId = _faviconfilemanager.GetFileId();
|
||||||
@ -603,17 +599,14 @@
|
|||||||
if (site.FaviconFileId != faviconFieldId)
|
if (site.FaviconFileId != faviconFieldId)
|
||||||
{
|
{
|
||||||
site.FaviconFileId = faviconFieldId;
|
site.FaviconFileId = faviconFieldId;
|
||||||
reload = true; // needs to be reloaded on server
|
|
||||||
}
|
}
|
||||||
if (site.DefaultThemeType != _themetype)
|
if (site.DefaultThemeType != _themetype)
|
||||||
{
|
{
|
||||||
site.DefaultThemeType = _themetype;
|
site.DefaultThemeType = _themetype;
|
||||||
refresh = true; // needs to be refreshed on client
|
|
||||||
}
|
}
|
||||||
if (site.DefaultContainerType != _containertype)
|
if (site.DefaultContainerType != _containertype)
|
||||||
{
|
{
|
||||||
site.DefaultContainerType = _containertype;
|
site.DefaultContainerType = _containertype;
|
||||||
refresh = true; // needs to be refreshed on client
|
|
||||||
}
|
}
|
||||||
site.AdminContainerType = _admincontainertype;
|
site.AdminContainerType = _admincontainertype;
|
||||||
|
|
||||||
@ -621,33 +614,28 @@
|
|||||||
if (site.HeadContent != _headcontent)
|
if (site.HeadContent != _headcontent)
|
||||||
{
|
{
|
||||||
site.HeadContent = _headcontent;
|
site.HeadContent = _headcontent;
|
||||||
reload = true;
|
|
||||||
}
|
}
|
||||||
if (site.BodyContent != _bodycontent)
|
if (site.BodyContent != _bodycontent)
|
||||||
{
|
{
|
||||||
site.BodyContent = _bodycontent;
|
site.BodyContent = _bodycontent;
|
||||||
reload = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PWA
|
// PWA
|
||||||
if (site.PwaIsEnabled.ToString() != _pwaisenabled)
|
if (site.PwaIsEnabled.ToString() != _pwaisenabled)
|
||||||
{
|
{
|
||||||
site.PwaIsEnabled = Boolean.Parse(_pwaisenabled);
|
site.PwaIsEnabled = Boolean.Parse(_pwaisenabled);
|
||||||
reload = true; // needs to be reloaded on server
|
|
||||||
}
|
}
|
||||||
int? pwaappiconfileid = _pwaappiconfilemanager.GetFileId();
|
int? pwaappiconfileid = _pwaappiconfilemanager.GetFileId();
|
||||||
if (pwaappiconfileid == -1) pwaappiconfileid = null;
|
if (pwaappiconfileid == -1) pwaappiconfileid = null;
|
||||||
if (site.PwaAppIconFileId != pwaappiconfileid)
|
if (site.PwaAppIconFileId != pwaappiconfileid)
|
||||||
{
|
{
|
||||||
site.PwaAppIconFileId = pwaappiconfileid;
|
site.PwaAppIconFileId = pwaappiconfileid;
|
||||||
reload = true; // needs to be reloaded on server
|
|
||||||
}
|
}
|
||||||
int? pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId();
|
int? pwasplashiconfileid = _pwasplashiconfilemanager.GetFileId();
|
||||||
if (pwasplashiconfileid == -1) pwasplashiconfileid = null;
|
if (pwasplashiconfileid == -1) pwasplashiconfileid = null;
|
||||||
if (site.PwaSplashIconFileId != pwasplashiconfileid)
|
if (site.PwaSplashIconFileId != pwasplashiconfileid)
|
||||||
{
|
{
|
||||||
site.PwaSplashIconFileId = pwasplashiconfileid;
|
site.PwaSplashIconFileId = pwasplashiconfileid;
|
||||||
reload = true; // needs to be reloaded on server
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// hosting model
|
// hosting model
|
||||||
@ -659,7 +647,6 @@
|
|||||||
site.Runtime = _runtime;
|
site.Runtime = _runtime;
|
||||||
site.Prerender = bool.Parse(_prerender);
|
site.Prerender = bool.Parse(_prerender);
|
||||||
site.Hybrid = bool.Parse(_hybrid);
|
site.Hybrid = bool.Parse(_hybrid);
|
||||||
reload = true; // needs to be reloaded on serve
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -686,15 +673,7 @@
|
|||||||
|
|
||||||
await logger.LogInformation("Site Settings Saved {Site}", site);
|
await logger.LogInformation("Site Settings Saved {Site}", site);
|
||||||
|
|
||||||
if (refresh || reload)
|
NavigationManager.NavigateTo(NavigateUrl(), true); // reload
|
||||||
{
|
|
||||||
NavigationManager.NavigateTo(NavigateUrl(true), reload); // refresh/reload
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
|
|
||||||
await ScrollToPageTop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -483,9 +483,9 @@
|
|||||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
||||||
await logger.LogInformation("User Profile Saved");
|
await logger.LogInformation("User Profile Saved");
|
||||||
|
|
||||||
if (PageState.QueryString.ContainsKey("returnurl"))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(WebUtility.UrlDecode(PageState.QueryString["returnurl"]));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
else // legacy behavior
|
else // legacy behavior
|
||||||
{
|
{
|
||||||
@ -551,7 +551,7 @@
|
|||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
NavigationManager.NavigateTo(PageState.ReturnUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
|
@ -6,20 +6,24 @@
|
|||||||
{
|
{
|
||||||
<div class="@_classname alert-dismissible fade show mb-3" role="alert">
|
<div class="@_classname alert-dismissible fade show mb-3" role="alert">
|
||||||
@((MarkupString)_message)
|
@((MarkupString)_message)
|
||||||
@if (Type == MessageType.Error && PageState != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
@if (PageState != null)
|
||||||
{
|
{
|
||||||
@((MarkupString)" ")<NavLink href="@NavigateUrl("admin/log")">View Details</NavLink>
|
@if (Type == MessageType.Error && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
|
{
|
||||||
|
<NavLink class="ms-2" href="@NavigateUrl("admin/log")">View Details</NavLink>
|
||||||
}
|
}
|
||||||
<form method="post" @onsubmit="DismissModal" @formname="@($"ModuleMessageForm{ModuleState.PageModuleId}")" data-enhance>
|
<form method="post" @onsubmit="DismissModal" @formname="@_formname" data-enhance>
|
||||||
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
<input type="hidden" name="__RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||||
<button type="submit" class="btn-close" aria-label="Close"></button>
|
<button type="submit" class="btn-close" aria-label="Close"></button>
|
||||||
</form>
|
</form>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _message = string.Empty;
|
private string _message = string.Empty;
|
||||||
private string _classname = string.Empty;
|
private string _classname = string.Empty;
|
||||||
|
private string _formname = "ModuleMessageForm";
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Message { get; set; }
|
public string Message { get; set; }
|
||||||
@ -27,6 +31,14 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public MessageType Type { get; set; }
|
public MessageType Type { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
if (ModuleState != null)
|
||||||
|
{
|
||||||
|
_formname += ModuleState.PageModuleId.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_message = Message;
|
_message = Message;
|
||||||
|
@ -10,7 +10,6 @@ using System.Collections.Generic;
|
|||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.Net.Http.Headers;
|
|
||||||
|
|
||||||
namespace Oqtane.Modules
|
namespace Oqtane.Modules
|
||||||
{
|
{
|
||||||
|
@ -144,18 +144,9 @@
|
|||||||
<data name="Month" xml:space="preserve">
|
<data name="Month" xml:space="preserve">
|
||||||
<value>Month(s)</value>
|
<value>Month(s)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Job.Delete" xml:space="preserve">
|
|
||||||
<value>Error Deleting Job</value>
|
|
||||||
</data>
|
|
||||||
<data name="ViewJobs.Text" xml:space="preserve">
|
<data name="ViewJobs.Text" xml:space="preserve">
|
||||||
<value>View Logs</value>
|
<value>View Logs</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DeleteJob.Header" xml:space="preserve">
|
|
||||||
<value>Delete Job</value>
|
|
||||||
</data>
|
|
||||||
<data name="DeleteJob.Message" xml:space="preserve">
|
|
||||||
<value>Are You Sure You Wish To Delete This Job?</value>
|
|
||||||
</data>
|
|
||||||
<data name="Frequency" xml:space="preserve">
|
<data name="Frequency" xml:space="preserve">
|
||||||
<value>Frequency</value>
|
<value>Frequency</value>
|
||||||
</data>
|
</data>
|
||||||
@ -165,9 +156,6 @@
|
|||||||
<data name="Stop" xml:space="preserve">
|
<data name="Stop" xml:space="preserve">
|
||||||
<value>Stop</value>
|
<value>Stop</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="DeleteJob.Text" xml:space="preserve">
|
|
||||||
<value>Delete</value>
|
|
||||||
</data>
|
|
||||||
<data name="EditJob.Text" xml:space="preserve">
|
<data name="EditJob.Text" xml:space="preserve">
|
||||||
<value>Edit</value>
|
<value>Edit</value>
|
||||||
</data>
|
</data>
|
||||||
|
@ -228,4 +228,7 @@
|
|||||||
<data name="ExternalLoginStatus.ReviewClaims" xml:space="preserve">
|
<data name="ExternalLoginStatus.ReviewClaims" xml:space="preserve">
|
||||||
<value>The Review Claims Option Was Enabled In External Login Settings. Please Visit The Event Log To View The Claims Returned By The Provider.</value>
|
<value>The Review Claims Option Was Enabled In External Login Settings. Please Visit The Event Log To View The Claims Returned By The Provider.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Register" xml:space="preserve">
|
||||||
|
<value>Register as new user?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -177,4 +177,7 @@
|
|||||||
<data name="Username.Text" xml:space="preserve">
|
<data name="Username.Text" xml:space="preserve">
|
||||||
<value>Username:</value>
|
<value>Username:</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Login" xml:space="preserve">
|
||||||
|
<value>Already have account? Login now.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -1,5 +1,4 @@
|
|||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.UI;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ namespace Oqtane.Services
|
|||||||
public interface IPageService
|
public interface IPageService
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Retuns a list of pages
|
/// Returns a list of pages
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="siteId"></param>
|
/// <param name="siteId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
|
@ -3,11 +3,8 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System;
|
|
||||||
using System.Reflection;
|
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using Oqtane.UI;
|
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// use existing value
|
// use existing value
|
||||||
loginurl = "?returnurl=" + PageState.QueryString["returnurl"];
|
loginurl += "?returnurl=" + PageState.QueryString["returnurl"];
|
||||||
}
|
}
|
||||||
|
|
||||||
// set logout url
|
// set logout url
|
||||||
|
@ -31,7 +31,16 @@
|
|||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_returnurl = WebUtility.UrlEncode(PageState.Route.PathAndQuery);
|
if (!PageState.QueryString.ContainsKey("returnurl"))
|
||||||
|
{
|
||||||
|
// remember current url
|
||||||
|
_returnurl += WebUtility.UrlEncode(PageState.Route.PathAndQuery);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use existing value
|
||||||
|
_returnurl += PageState.QueryString["returnurl"];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,9 +16,9 @@ namespace Oqtane.Themes.OqtaneTheme
|
|||||||
ContainerSettingsType = "Oqtane.Themes.OqtaneTheme.ContainerSettings, Oqtane.Client",
|
ContainerSettingsType = "Oqtane.Themes.OqtaneTheme.ContainerSettings, Oqtane.Client",
|
||||||
Resources = new List<Resource>()
|
Resources = new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.0/cyborg/bootstrap.min.css", Integrity = "sha512-jwIqEv8o/kTBMJVtbNCBrDqhBojl0YSUam+EFpLjVOC86Ci6t4ZciTnIkelFNOik+dEQVymKGcQLiaJZNAfWRg==", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.2/cyborg/bootstrap.min.css", Integrity = "sha512-RfNxVfFNFgqk9MXO4TCKXYXn9hgc+keHCg3xFFGbnp2q7Cifda+YYzMTDHwsQtNx4DuqIMgfvZead7XOtB9CDQ==", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js", Integrity = "sha512-VK2zcvntEufaimc+efOYi622VN5ZacdnufnmX7zIhCPmjhKnOi9ZDMtg1/ug5l183f19gG1/cBstPO4D8N/Img==", CrossOrigin = "anonymous" }
|
new Resource { ResourceType = ResourceType.Script, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/js/bootstrap.bundle.min.js", Integrity = "sha512-X/YkDZyjTf4wyc2Vy16YGCPHwAY8rZJY+POgokZjQB2mhIRFJCckEGc6YyX9eNsPfn0PzThEuNs+uaomE5CO6A==", CrossOrigin = "anonymous" }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
@using Oqtane.Shared
|
@using Oqtane.Shared
|
||||||
@inject SiteState SiteState
|
@inject SiteState SiteState
|
||||||
@implements IDisposable
|
@implements IDisposable
|
||||||
|
@* the following StreamRendering attribute is required - if it is removed the framework will not render the content in static rendering *@
|
||||||
|
@attribute [StreamRendering]
|
||||||
|
|
||||||
@if (!string.IsNullOrEmpty(_title))
|
@if (!string.IsNullOrEmpty(_title))
|
||||||
{
|
{
|
||||||
@ -17,6 +19,12 @@
|
|||||||
private string _title = "";
|
private string _title = "";
|
||||||
private string _content = "";
|
private string _content = "";
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string RenderMode { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string Runtime { get; set; }
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
((INotifyPropertyChanged)SiteState.Properties).PropertyChanged += PropertyChanged;
|
((INotifyPropertyChanged)SiteState.Properties).PropertyChanged += PropertyChanged;
|
||||||
@ -47,7 +55,7 @@
|
|||||||
|
|
||||||
private string RemoveScripts(string headcontent)
|
private string RemoveScripts(string headcontent)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(headcontent))
|
if (!string.IsNullOrEmpty(headcontent) && RenderMode == RenderModes.Interactive)
|
||||||
{
|
{
|
||||||
var index = headcontent.IndexOf("<script");
|
var index = headcontent.IndexOf("<script");
|
||||||
while (index >= 0)
|
while (index >= 0)
|
||||||
|
@ -17,7 +17,7 @@ namespace Oqtane.UI
|
|||||||
case Runtimes.Auto:
|
case Runtimes.Auto:
|
||||||
return new InteractiveAutoRenderMode(prerender: prerender);
|
return new InteractiveAutoRenderMode(prerender: prerender);
|
||||||
}
|
}
|
||||||
return new InteractiveServerRenderMode(prerender: prerender); // default to interactiver server
|
return new InteractiveServerRenderMode(prerender: prerender);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
@namespace Oqtane.UI
|
@namespace Oqtane.UI
|
||||||
@inject SiteState SiteState
|
@inject SiteState SiteState
|
||||||
|
|
||||||
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Static)
|
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Interactive)
|
||||||
{
|
{
|
||||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
<StreamRenderingDisabled ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="@InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, PageState.Site.Prerender)" />
|
<StreamRenderingEnabled ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
// this component is on the static side of the render mode boundary
|
// this component is on the static side of the render mode boundary
|
||||||
// it passes state as serializable parameters across the boundary so that the state can be used by downstream interactive components
|
// it passes state as serializable parameters across the boundary
|
||||||
|
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected PageState PageState { get; set; }
|
protected PageState PageState { get; set; }
|
||||||
@ -20,7 +20,8 @@ else
|
|||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
private Module ModuleState { get; set; }
|
private Module ModuleState { get; set; }
|
||||||
|
|
||||||
[Obsolete("AddModuleMessage is deprecated. Use ModuleBase.AddModuleMessage instead.", false)]
|
|
||||||
|
[Obsolete("AddModuleMessage is deprecated. Use AddModuleMessage in ModuleBase instead.", false)]
|
||||||
public void AddModuleMessage(string message, MessageType type)
|
public void AddModuleMessage(string message, MessageType type)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -30,12 +31,12 @@ else
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("ShowProgressIndicator is deprecated. Use ModuleBase.ShowProgressIndicator instead.", false)]
|
[Obsolete("ShowProgressIndicator is deprecated. Use ShowProgressIndicator in ModuleBase instead.", false)]
|
||||||
public void ShowProgressIndicator()
|
public void ShowProgressIndicator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("HideProgressIndicator is deprecated. Use ModuleBase.HideProgressIndicator instead.", false)]
|
[Obsolete("HideProgressIndicator is deprecated. Use HideProgressIndicator in ModuleBase instead.", false)]
|
||||||
public void HideProgressIndicator()
|
public void HideProgressIndicator()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -67,7 +67,7 @@ else
|
|||||||
// pane matches current pane
|
// pane matches current pane
|
||||||
if (Name.ToLower() == pane.ToLower())
|
if (Name.ToLower() == pane.ToLower())
|
||||||
{
|
{
|
||||||
if (module.ModuleId == PageState.ModuleId && PageState.Action != Constants.DefaultAction)
|
if (PageState.ModuleId == module.ModuleId && PageState.Action != Constants.DefaultAction)
|
||||||
{
|
{
|
||||||
var moduleType = Type.GetType(module.ModuleType);
|
var moduleType = Type.GetType(module.ModuleType);
|
||||||
if (moduleType != null)
|
if (moduleType != null)
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
@inject ILogService LoggingService
|
@inject ILogService LoggingService
|
||||||
@inherits ErrorBoundary
|
@inherits ErrorBoundary
|
||||||
|
|
||||||
|
<CascadingValue Value="@PageState">
|
||||||
|
<CascadingValue Value="@ModuleState">
|
||||||
@if (CurrentException is null)
|
@if (CurrentException is null)
|
||||||
{
|
{
|
||||||
@if (ModuleType != null)
|
@if (ModuleType != null)
|
||||||
{
|
{
|
||||||
<CascadingValue Value="@PageState">
|
|
||||||
<CascadingValue Value="@ModuleState">
|
|
||||||
@if (!string.IsNullOrEmpty(_messageContent) && _messagePosition == "top")
|
@if (!string.IsNullOrEmpty(_messageContent) && _messagePosition == "top")
|
||||||
{
|
{
|
||||||
<ModuleMessage Message="@_messageContent" Type="@_messageType" />
|
<ModuleMessage Message="@_messageContent" Type="@_messageType" />
|
||||||
@ -23,8 +23,6 @@
|
|||||||
{
|
{
|
||||||
<ModuleMessage Message="@_messageContent" Type="@_messageType" />
|
<ModuleMessage Message="@_messageContent" Type="@_messageType" />
|
||||||
}
|
}
|
||||||
</CascadingValue>
|
|
||||||
</CascadingValue>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -34,8 +32,13 @@ else
|
|||||||
<ModuleMessage Message="@_error" Type="@MessageType.Error" />
|
<ModuleMessage Message="@_error" Type="@MessageType.Error" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</CascadingValue>
|
||||||
|
</CascadingValue>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
// this component is on the interactive side of the render mode boundary
|
||||||
|
// it receives state as serializable parameters so that the state can be made available to downstream components
|
||||||
|
|
||||||
private Type ModuleType { get; set; }
|
private Type ModuleType { get; set; }
|
||||||
RenderFragment DynamicComponent { get; set; }
|
RenderFragment DynamicComponent { get; set; }
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
@inject IInstallationService InstallationService
|
@inject IInstallationService InstallationService
|
||||||
@inject IJSRuntime JSRuntime
|
@inject IJSRuntime JSRuntime
|
||||||
@inject SiteState SiteState
|
@inject SiteState SiteState
|
||||||
|
@* the following StreamRendering attribute is required - if it is removed the framework will not render the content in static rendering *@
|
||||||
@attribute [StreamRendering]
|
@attribute [StreamRendering]
|
||||||
|
|
||||||
@if (_initialized)
|
@if (_initialized)
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
{
|
{
|
||||||
if (PageState != null)
|
if (PageState != null && !PageState.Refresh)
|
||||||
{
|
{
|
||||||
builder.OpenComponent(0, typeof(ThemeBuilder));
|
builder.OpenComponent(0, typeof(ThemeBuilder));
|
||||||
builder.CloseComponent();
|
builder.CloseComponent();
|
||||||
@ -101,8 +101,8 @@
|
|||||||
_error = "";
|
_error = "";
|
||||||
|
|
||||||
Route route = new Route(_absoluteUri, SiteState.Alias.Path);
|
Route route = new Route(_absoluteUri, SiteState.Alias.Path);
|
||||||
int moduleid = (int.TryParse(route.ModuleId, out moduleid)) ? moduleid : -1;
|
int moduleid = int.Parse(route.ModuleId);
|
||||||
var action = (!string.IsNullOrEmpty(route.Action)) ? route.Action : Constants.DefaultAction;
|
var action = route.Action;
|
||||||
|
|
||||||
var querystring = Utilities.ParseQueryString(route.Query);
|
var querystring = Utilities.ParseQueryString(route.Query);
|
||||||
var returnurl = "";
|
var returnurl = "";
|
||||||
@ -567,9 +567,19 @@
|
|||||||
// ensure resource does not exist already
|
// ensure resource does not exist already
|
||||||
if (!pageresources.Exists(item => item.Url.ToLower() == resource.Url.ToLower()))
|
if (!pageresources.Exists(item => item.Url.ToLower() == resource.Url.ToLower()))
|
||||||
{
|
{
|
||||||
resource.Level = level;
|
pageresources.Add(new Resource
|
||||||
resource.Namespace = name;
|
{
|
||||||
pageresources.Add(resource);
|
ResourceType = resource.ResourceType,
|
||||||
|
Url = resource.Url,
|
||||||
|
Integrity = resource.Integrity,
|
||||||
|
CrossOrigin = resource.CrossOrigin,
|
||||||
|
Bundle = resource.Bundle,
|
||||||
|
Location = resource.Location,
|
||||||
|
ES6Module = resource.ES6Module,
|
||||||
|
Content = resource.Content,
|
||||||
|
Level = level,
|
||||||
|
Namespace = name
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
Oqtane.Client/UI/StreamRenderingDisabled.razor
Normal file
21
Oqtane.Client/UI/StreamRenderingDisabled.razor
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@attribute [StreamRendering(false)]
|
||||||
|
|
||||||
|
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Static)
|
||||||
|
{
|
||||||
|
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="@InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, PageState.Site.Prerender)" />
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public SiteState SiteState { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public PageState PageState { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Module ModuleState { get; set; }
|
||||||
|
}
|
21
Oqtane.Client/UI/StreamRenderingEnabled.razor
Normal file
21
Oqtane.Client/UI/StreamRenderingEnabled.razor
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@attribute [StreamRendering(true)]
|
||||||
|
|
||||||
|
@if (PageState.RenderMode == RenderModes.Interactive || ModuleState.RenderMode == RenderModes.Static)
|
||||||
|
{
|
||||||
|
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" />
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<RenderModeBoundary ModuleState="@ModuleState" PageState="@PageState" SiteState="@SiteState" @rendermode="@InteractiveRenderMode.GetInteractiveRenderMode(PageState.Site.Runtime, PageState.Site.Prerender)" />
|
||||||
|
}
|
||||||
|
|
||||||
|
@code {
|
||||||
|
[Parameter]
|
||||||
|
public SiteState SiteState { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public PageState PageState { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Module ModuleState { get; set; }
|
||||||
|
}
|
@ -53,30 +53,6 @@
|
|||||||
{
|
{
|
||||||
headcontent = AddHeadContent(headcontent, PageState.Page.HeadContent);
|
headcontent = AddHeadContent(headcontent, PageState.Page.HeadContent);
|
||||||
}
|
}
|
||||||
if (PageState.RenderMode == RenderModes.Static)
|
|
||||||
{
|
|
||||||
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
|
||||||
int count = 0;
|
|
||||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet && item.Level == ResourceLevel.Module))
|
|
||||||
{
|
|
||||||
// if (resource.Url.StartsWith("~"))
|
|
||||||
// {
|
|
||||||
// resource.Url = resource.Url.Replace("~", "/Themes/" + Utilities.GetTypeName(name) + "/").Replace("//", "/");
|
|
||||||
// }
|
|
||||||
if (!resource.Url.Contains("://") && PageState.Alias.BaseUrl != "" && !resource.Url.StartsWith(PageState.Alias.BaseUrl))
|
|
||||||
{
|
|
||||||
resource.Url = PageState.Alias.BaseUrl + resource.Url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!headcontent.Contains(resource.Url, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
string id = "id=\"app-stylesheet-" + resource.Level.ToString().ToLower() + "-" + batch + "-" + count.ToString("00") + "\" ";
|
|
||||||
headcontent += "<link " + id + "rel=\"stylesheet\" href=\"" + resource.Url + "\"" + (!string.IsNullOrEmpty(resource.Integrity) ? " integrity=\"" + resource.Integrity + "\"" : "") + (!string.IsNullOrEmpty(resource.CrossOrigin) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") + " type=\"text/css\"/>" + Environment.NewLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
SiteState.Properties.HeadContent = headcontent;
|
SiteState.Properties.HeadContent = headcontent;
|
||||||
|
|
||||||
DynamicComponent = builder =>
|
DynamicComponent = builder =>
|
||||||
@ -96,7 +72,7 @@
|
|||||||
while (index >= 0)
|
while (index >= 0)
|
||||||
{
|
{
|
||||||
var element = content.Substring(index, content.IndexOf(">", index) - index + 1);
|
var element = content.Substring(index, content.IndexOf(">", index) - index + 1);
|
||||||
if (!string.IsNullOrEmpty(element) && !element.ToLower().StartsWith("<script") && !element.ToLower().StartsWith("</script"))
|
if (!string.IsNullOrEmpty(element) && (PageState.RenderMode == RenderModes.Static || (!element.ToLower().StartsWith("<script") && !element.ToLower().StartsWith("</script"))))
|
||||||
{
|
{
|
||||||
if (!headcontent.Contains(element))
|
if (!headcontent.Contains(element))
|
||||||
{
|
{
|
||||||
@ -168,6 +144,7 @@
|
|||||||
string integrity = "";
|
string integrity = "";
|
||||||
string crossorigin = "";
|
string crossorigin = "";
|
||||||
string type = "";
|
string type = "";
|
||||||
|
var dataAttributes = new Dictionary<string, string>();
|
||||||
foreach (var attribute in attributes)
|
foreach (var attribute in attributes)
|
||||||
{
|
{
|
||||||
if (attribute.Contains("="))
|
if (attribute.Contains("="))
|
||||||
@ -190,6 +167,12 @@
|
|||||||
case "type":
|
case "type":
|
||||||
type = value[1];
|
type = value[1];
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
if(!string.IsNullOrWhiteSpace(value[0]) && value[0].StartsWith("data-"))
|
||||||
|
{
|
||||||
|
dataAttributes.Add(value[0], value[1]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +180,7 @@
|
|||||||
if (!string.IsNullOrEmpty(src))
|
if (!string.IsNullOrEmpty(src))
|
||||||
{
|
{
|
||||||
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
||||||
scripts.Add(new { href = src, bundle = "", integrity = integrity, crossorigin = crossorigin, es6module = (type == "module"), location = location.ToString().ToLower() });
|
scripts.Add(new { href = src, bundle = "", integrity = integrity, crossorigin = crossorigin, es6module = (type == "module"), location = location.ToString().ToLower(), dataAttributes = dataAttributes });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -217,4 +200,67 @@
|
|||||||
await interop.IncludeScripts(scripts.ToArray());
|
await interop.IncludeScripts(scripts.ToArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string ManageStyleSheets(List<Resource> resources, Alias alias)
|
||||||
|
{
|
||||||
|
var stylesheets = "";
|
||||||
|
if (resources != null)
|
||||||
|
{
|
||||||
|
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
||||||
|
int count = 0;
|
||||||
|
foreach (var resource in resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
|
{
|
||||||
|
if (resource.Url.StartsWith("~"))
|
||||||
|
{
|
||||||
|
resource.Url = resource.Url.Replace("~", "/Themes/" + Utilities.GetTypeName(resource.Namespace) + "/").Replace("//", "/");
|
||||||
|
}
|
||||||
|
if (!resource.Url.Contains("://") && alias.BaseUrl != "" && !resource.Url.StartsWith(alias.BaseUrl))
|
||||||
|
{
|
||||||
|
resource.Url = alias.BaseUrl + resource.Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stylesheets.Contains(resource.Url, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
string id = "id=\"app-stylesheet-" + ResourceLevel.Page.ToString().ToLower() + "-" + batch + "-" + count.ToString("00") + "\" ";
|
||||||
|
stylesheets += "<link " + id + "rel=\"stylesheet\" href=\"" + resource.Url + "\"" + (!string.IsNullOrEmpty(resource.Integrity) ? " integrity=\"" + resource.Integrity + "\"" : "") + (!string.IsNullOrEmpty(resource.CrossOrigin) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") + " type=\"text/css\"/>" + Environment.NewLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stylesheets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ManageScripts(List<Resource> resources, Alias alias)
|
||||||
|
{
|
||||||
|
var scripts = "";
|
||||||
|
if (resources != null)
|
||||||
|
{
|
||||||
|
foreach (var resource in resources.Where(item => item.ResourceType == ResourceType.Script && item.Location == ResourceLocation.Head))
|
||||||
|
{
|
||||||
|
var script = CreateScript(resource, alias);
|
||||||
|
if (!scripts.Contains(script, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
scripts += script + Environment.NewLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string CreateScript(Resource resource, Alias alias)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(resource.Url))
|
||||||
|
{
|
||||||
|
var url = (resource.Url.Contains("://")) ? resource.Url : alias.BaseUrl + resource.Url;
|
||||||
|
return "<script src=\"" + url + "\"" +
|
||||||
|
((!string.IsNullOrEmpty(resource.Integrity)) ? " integrity=\"" + resource.Integrity + "\"" : "") +
|
||||||
|
((!string.IsNullOrEmpty(resource.CrossOrigin)) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") +
|
||||||
|
"></script>";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// inline script
|
||||||
|
return "<script>" + resource.Content + "</script>";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.2" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,6 +1,16 @@
|
|||||||
<DynamicComponent Type="@ComponentType"></DynamicComponent>
|
@using Oqtane.Shared;
|
||||||
|
|
||||||
|
<DynamicComponent Type="@ComponentType" Parameters="@Parameters"></DynamicComponent>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
Type ComponentType = Type.GetType("Oqtane.UI.Head, Oqtane.Client");
|
Type ComponentType = Type.GetType("Oqtane.UI.Head, Oqtane.Client");
|
||||||
|
private IDictionary<string, object> Parameters { get; set; }
|
||||||
|
|
||||||
|
protected override void OnInitialized()
|
||||||
|
{
|
||||||
|
Parameters = new Dictionary<string, object>();
|
||||||
|
Parameters.Add(new KeyValuePair<string, object>("RenderMode", RenderModes.Interactive));
|
||||||
|
Parameters.Add(new KeyValuePair<string, object>("Runtime", Runtimes.Hybrid));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,17 +21,15 @@
|
|||||||
@inject IConfigManager ConfigManager
|
@inject IConfigManager ConfigManager
|
||||||
@inject ITenantManager TenantManager
|
@inject ITenantManager TenantManager
|
||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
@inject IPageRepository PageRepository
|
|
||||||
@inject IThemeRepository ThemeRepository
|
@inject IThemeRepository ThemeRepository
|
||||||
@inject ILanguageRepository LanguageRepository
|
@inject ILanguageRepository LanguageRepository
|
||||||
@inject IServerStateManager ServerStateManager
|
|
||||||
@inject ILocalizationManager LocalizationManager
|
@inject ILocalizationManager LocalizationManager
|
||||||
@inject IAliasRepository AliasRepository
|
@inject IAliasRepository AliasRepository
|
||||||
@inject IUrlMappingRepository UrlMappingRepository
|
@inject IUrlMappingRepository UrlMappingRepository
|
||||||
@inject IVisitorRepository VisitorRepository
|
@inject IVisitorRepository VisitorRepository
|
||||||
@inject IJwtManager JwtManager
|
@inject IJwtManager JwtManager
|
||||||
|
|
||||||
@if (_pageState != null)
|
@if (_initialized)
|
||||||
{
|
{
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="@_language">
|
<html lang="@_language">
|
||||||
@ -51,11 +49,11 @@
|
|||||||
<link id="app-stylesheet-module" />
|
<link id="app-stylesheet-module" />
|
||||||
@if (_renderMode == RenderModes.Static)
|
@if (_renderMode == RenderModes.Static)
|
||||||
{
|
{
|
||||||
<Head />
|
<Head RenderMode="@_renderMode" Runtime="@_runtime" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<Head @rendermode="InteractiveRenderMode.GetInteractiveRenderMode(_runtime, _prerender)" />
|
<Head RenderMode="@_renderMode" Runtime="@_runtime" @rendermode="InteractiveRenderMode.GetInteractiveRenderMode(_runtime, _prerender)" />
|
||||||
}
|
}
|
||||||
@((MarkupString)_headResources)
|
@((MarkupString)_headResources)
|
||||||
</head>
|
</head>
|
||||||
@ -93,6 +91,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private string _renderMode = RenderModes.Interactive;
|
private string _renderMode = RenderModes.Interactive;
|
||||||
private string _runtime = Runtimes.Server;
|
private string _runtime = Runtimes.Server;
|
||||||
private bool _prerender = true;
|
private bool _prerender = true;
|
||||||
@ -139,12 +138,19 @@
|
|||||||
_prerender = site.Prerender;
|
_prerender = site.Prerender;
|
||||||
|
|
||||||
Route route = new Route(url, alias.Path);
|
Route route = new Route(url, alias.Path);
|
||||||
var page = PageRepository.GetPage(route.PagePath, site.SiteId);
|
var page = site.Pages.FirstOrDefault(item => item.Path.Equals(route.PagePath, StringComparison.OrdinalIgnoreCase));
|
||||||
if (page == null && route.PagePath == "" && site.HomePageId != null)
|
if (page == null && route.PagePath == "") // naked path refers to site home page
|
||||||
{
|
{
|
||||||
page = PageRepository.GetPage(site.HomePageId.Value);
|
if (site.HomePageId != null)
|
||||||
|
{
|
||||||
|
page = site.Pages.FirstOrDefault(item => item.PageId == site.HomePageId);
|
||||||
|
}
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
|
// fallback to use the first page in the collection
|
||||||
|
page = site.Pages.FirstOrDefault();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page == null || page.IsDeleted)
|
if (page == null || page.IsDeleted)
|
||||||
{
|
{
|
||||||
HandlePageNotFound(site, page, route);
|
HandlePageNotFound(site, page, route);
|
||||||
@ -161,34 +167,15 @@
|
|||||||
CreateJwtToken(alias);
|
CreateJwtToken(alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stylesheets
|
// include stylesheets to prevent FOUC
|
||||||
var themes = ThemeRepository.GetThemes().ToList();
|
var resources = GetPageResources(alias, site, page, int.Parse(route.ModuleId), route.Action);
|
||||||
var resources = new List<Resource>();
|
ManageStyleSheets(resources);
|
||||||
if (string.IsNullOrEmpty(page.ThemeType))
|
|
||||||
{
|
// scripts
|
||||||
page.ThemeType = site.DefaultThemeType;
|
|
||||||
}
|
|
||||||
var theme = themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == page.ThemeType));
|
|
||||||
if (theme?.Resources != null)
|
|
||||||
{
|
|
||||||
resources.AddRange(theme.Resources);
|
|
||||||
}
|
|
||||||
var type = Type.GetType(page.ThemeType);
|
|
||||||
if (type != null)
|
|
||||||
{
|
|
||||||
var obj = Activator.CreateInstance(type) as IThemeControl;
|
|
||||||
if (obj?.Resources != null)
|
|
||||||
{
|
|
||||||
resources.AddRange(obj.Resources);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ManageStyleSheets(resources, alias, theme.ThemeName);
|
|
||||||
if (_renderMode == RenderModes.Static)
|
if (_renderMode == RenderModes.Static)
|
||||||
{
|
{
|
||||||
ManageScripts(resources, alias);
|
ManageScripts(resources, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
// scripts
|
|
||||||
if (_renderMode == RenderModes.Interactive && _runtime == Runtimes.Server)
|
if (_renderMode == RenderModes.Interactive && _runtime == Runtimes.Server)
|
||||||
{
|
{
|
||||||
_reconnectScript = CreateReconnectScript();
|
_reconnectScript = CreateReconnectScript();
|
||||||
@ -199,22 +186,16 @@
|
|||||||
}
|
}
|
||||||
_headResources += ParseScripts(site.HeadContent);
|
_headResources += ParseScripts(site.HeadContent);
|
||||||
_bodyResources += ParseScripts(site.BodyContent);
|
_bodyResources += ParseScripts(site.BodyContent);
|
||||||
var scripts = ServerStateManager.GetServerState(alias.SiteKey).Scripts;
|
|
||||||
foreach (var script in scripts)
|
|
||||||
{
|
|
||||||
AddScript(script, alias);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set culture if not specified
|
// set culture if not specified
|
||||||
string culture = Context.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
|
string culture = Context.Request.Cookies[CookieRequestCultureProvider.DefaultCookieName];
|
||||||
if (culture == null)
|
if (culture == null)
|
||||||
{
|
{
|
||||||
// get default language for site
|
// get default language for site
|
||||||
var languages = LanguageRepository.GetLanguages(alias.SiteId);
|
if (site.Languages.Any())
|
||||||
if (languages.Any())
|
|
||||||
{
|
{
|
||||||
// use default language if specified otherwise use first language in collection
|
// use default language if specified otherwise use first language in collection
|
||||||
culture = (languages.Where(l => l.IsDefault).SingleOrDefault() ?? languages.First()).Code;
|
culture = (site.Languages.Where(l => l.IsDefault).SingleOrDefault() ?? site.Languages.First()).Code;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -266,6 +247,7 @@
|
|||||||
_message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
|
_message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleDefaultAliasRedirect(Alias alias, string url)
|
private void HandleDefaultAliasRedirect(Alias alias, string url)
|
||||||
@ -562,24 +544,117 @@
|
|||||||
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)));
|
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ManageStyleSheets(List<Resource> resources, Alias alias, string name)
|
private List<Resource> GetPageResources(Alias alias, Site site, Page page, int moduleid, string action)
|
||||||
|
{
|
||||||
|
var resources = new List<Resource>();
|
||||||
|
|
||||||
|
var themeType = (string.IsNullOrEmpty(page.ThemeType)) ? site.DefaultThemeType : page.ThemeType;
|
||||||
|
var theme = site.Themes.FirstOrDefault(item => item.Themes.Any(item => item.TypeName == themeType));
|
||||||
|
if (theme != null)
|
||||||
|
{
|
||||||
|
resources = AddResources(resources, theme.Resources, ResourceLevel.Page, alias, "Themes", Utilities.GetTypeName(theme.ThemeName));
|
||||||
|
}
|
||||||
|
var type = Type.GetType(themeType);
|
||||||
|
if (type != null)
|
||||||
|
{
|
||||||
|
var obj = Activator.CreateInstance(type) as IThemeControl;
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
resources = AddResources(resources, obj.Resources, ResourceLevel.Page, alias, "Themes", type.Namespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Module module in site.Modules)
|
||||||
|
{
|
||||||
|
if (module.PageId == page.PageId || module.ModuleId == moduleid)
|
||||||
|
{
|
||||||
|
var typename = "";
|
||||||
|
if (module.ModuleDefinition != null)
|
||||||
|
{
|
||||||
|
typename = module.ModuleDefinition.ControlTypeTemplate;
|
||||||
|
resources = AddResources(resources, module.ModuleDefinition.Resources, ResourceLevel.Module, alias, "Modules", Utilities.GetTypeName(module.ModuleDefinition.ModuleDefinitionName));
|
||||||
|
}
|
||||||
|
if (Constants.DefaultModuleActions.Contains(action, StringComparer.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
typename = Constants.DefaultModuleActionsTemplate.Replace(Constants.ActionToken, action);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
typename = typename.Replace(Constants.ActionToken, action);
|
||||||
|
}
|
||||||
|
Type moduletype = Type.GetType(typename, false, true); // case insensitive
|
||||||
|
if (moduletype != null && moduletype.GetInterfaces().Contains(typeof(IModuleControl)))
|
||||||
|
{
|
||||||
|
module.ModuleType = Utilities.GetFullTypeName(moduletype.AssemblyQualifiedName); // get actual type name
|
||||||
|
}
|
||||||
|
if (moduletype != null && module.ModuleType != "")
|
||||||
|
{
|
||||||
|
var obj = Activator.CreateInstance(moduletype) as IModuleControl;
|
||||||
|
if (obj != null)
|
||||||
|
{
|
||||||
|
resources = AddResources(resources, obj.Resources, ResourceLevel.Module, alias, "Modules", type.Namespace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// site level resources for modules in site
|
||||||
|
var modules = site.Modules.GroupBy(item => item.ModuleDefinition.ModuleDefinitionName).Select(group => group.First()).ToList();
|
||||||
|
foreach (var module in modules)
|
||||||
|
{
|
||||||
|
if (module.ModuleDefinition.Resources != null)
|
||||||
|
{
|
||||||
|
resources = AddResources(resources, module.ModuleDefinition.Resources.Where(item => item.Level == ResourceLevel.Site).ToList(), ResourceLevel.Module, alias, "Modules", Utilities.GetTypeName(module.ModuleDefinition.ModuleDefinitionName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Resource> AddResources(List<Resource> pageresources, List<Resource> resources, ResourceLevel level, Alias alias, string type, string name)
|
||||||
|
{
|
||||||
|
if (resources != null)
|
||||||
|
{
|
||||||
|
foreach (var resource in resources)
|
||||||
|
{
|
||||||
|
if (resource.Url.StartsWith("~"))
|
||||||
|
{
|
||||||
|
resource.Url = resource.Url.Replace("~", "/" + type + "/" + name + "/").Replace("//", "/");
|
||||||
|
}
|
||||||
|
if (!resource.Url.Contains("://") && alias.BaseUrl != "" && !resource.Url.StartsWith(alias.BaseUrl))
|
||||||
|
{
|
||||||
|
resource.Url = alias.BaseUrl + resource.Url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure resource does not exist already
|
||||||
|
if (!pageresources.Exists(item => item.Url.ToLower() == resource.Url.ToLower()))
|
||||||
|
{
|
||||||
|
pageresources.Add(new Resource
|
||||||
|
{
|
||||||
|
ResourceType = resource.ResourceType,
|
||||||
|
Url = resource.Url,
|
||||||
|
Integrity = resource.Integrity,
|
||||||
|
CrossOrigin = resource.CrossOrigin,
|
||||||
|
Bundle = resource.Bundle,
|
||||||
|
Location = resource.Location,
|
||||||
|
ES6Module = resource.ES6Module,
|
||||||
|
Content = resource.Content,
|
||||||
|
Level = level,
|
||||||
|
Namespace = name
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pageresources;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ManageStyleSheets(List<Resource> resources)
|
||||||
{
|
{
|
||||||
if (resources != null)
|
if (resources != null)
|
||||||
{
|
{
|
||||||
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
||||||
int count = 0;
|
int count = 0;
|
||||||
foreach (var resource in resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
foreach (var resource in resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||||
{
|
|
||||||
if (resource.Url.StartsWith("~"))
|
|
||||||
{
|
|
||||||
resource.Url = resource.Url.Replace("~", "/Themes/" + Utilities.GetTypeName(name) + "/").Replace("//", "/");
|
|
||||||
}
|
|
||||||
if (!resource.Url.Contains("://") && alias.BaseUrl != "" && !resource.Url.StartsWith(alias.BaseUrl))
|
|
||||||
{
|
|
||||||
resource.Url = alias.BaseUrl + resource.Url;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_styleSheets.Contains(resource.Url, StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
string id = "id=\"app-stylesheet-" + ResourceLevel.Page.ToString().ToLower() + "-" + batch + "-" + count.ToString("00") + "\" ";
|
string id = "id=\"app-stylesheet-" + ResourceLevel.Page.ToString().ToLower() + "-" + batch + "-" + count.ToString("00") + "\" ";
|
||||||
@ -587,7 +662,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void ManageScripts(List<Resource> resources, Alias alias)
|
private void ManageScripts(List<Resource> resources, Alias alias)
|
||||||
{
|
{
|
||||||
|
@ -16,6 +16,7 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using Oqtane.Modules;
|
using Oqtane.Modules;
|
||||||
|
using Oqtane.Infrastructure.Interfaces;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -319,52 +320,33 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
private void ProcessTemplatesRecursively(DirectoryInfo current, string rootPath, string rootFolder, string templatePath, ModuleDefinition moduleDefinition)
|
private void ProcessTemplatesRecursively(DirectoryInfo current, string rootPath, string rootFolder, string templatePath, ModuleDefinition moduleDefinition)
|
||||||
{
|
{
|
||||||
|
var tokenReplace = InitializeTokenReplace(rootPath, rootFolder, moduleDefinition);
|
||||||
|
|
||||||
// process folder
|
// process folder
|
||||||
string folderPath = Utilities.PathCombine(rootPath, current.FullName.Replace(templatePath, ""));
|
var folderPath = Utilities.PathCombine(rootPath, current.FullName.Replace(templatePath, ""));
|
||||||
folderPath = folderPath.Replace("[Owner]", moduleDefinition.Owner);
|
folderPath = tokenReplace.ReplaceTokens(folderPath);
|
||||||
folderPath = folderPath.Replace("[Module]", moduleDefinition.Name);
|
|
||||||
if (!Directory.Exists(folderPath))
|
if (!Directory.Exists(folderPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(folderPath);
|
Directory.CreateDirectory(folderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo[] files = current.GetFiles("*.*");
|
tokenReplace.AddSource("Folder", folderPath);
|
||||||
|
var files = current.GetFiles("*.*");
|
||||||
if (files != null)
|
if (files != null)
|
||||||
{
|
{
|
||||||
foreach (FileInfo file in files)
|
foreach (FileInfo file in files)
|
||||||
{
|
{
|
||||||
// process file
|
// process file
|
||||||
string filePath = Path.Combine(folderPath, file.Name);
|
var filePath = Path.Combine(folderPath, file.Name);
|
||||||
filePath = filePath.Replace("[Owner]", moduleDefinition.Owner);
|
filePath = tokenReplace.ReplaceTokens(filePath);
|
||||||
filePath = filePath.Replace("[Module]", moduleDefinition.Name);
|
tokenReplace.AddSource("File", Path.GetFileName(filePath));
|
||||||
|
|
||||||
string text = System.IO.File.ReadAllText(file.FullName);
|
var text = System.IO.File.ReadAllText(file.FullName);
|
||||||
text = text.Replace("[Owner]", moduleDefinition.Owner);
|
text = tokenReplace.ReplaceTokens(text);
|
||||||
text = text.Replace("[Module]", moduleDefinition.Name);
|
|
||||||
text = text.Replace("[Description]", moduleDefinition.Description);
|
|
||||||
text = text.Replace("[RootPath]", rootPath);
|
|
||||||
text = text.Replace("[RootFolder]", rootFolder);
|
|
||||||
text = text.Replace("[ServerManagerType]", moduleDefinition.ServerManagerType);
|
|
||||||
text = text.Replace("[Folder]", folderPath);
|
|
||||||
text = text.Replace("[File]", Path.GetFileName(filePath));
|
|
||||||
if (moduleDefinition.Version == "local")
|
|
||||||
{
|
|
||||||
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
|
||||||
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll</HintPath></Reference>");
|
|
||||||
text = text.Replace("[ServerReference]", $"<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Server.dll</HintPath></Reference>");
|
|
||||||
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll</HintPath></Reference>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
text = text.Replace("[FrameworkVersion]", moduleDefinition.Version);
|
|
||||||
text = text.Replace("[ClientReference]", "<PackageReference Include=\"Oqtane.Client\" Version=\"" + moduleDefinition.Version + "\" />");
|
|
||||||
text = text.Replace("[ServerReference]", "<PackageReference Include=\"Oqtane.Server\" Version=\"" + moduleDefinition.Version + "\" />");
|
|
||||||
text = text.Replace("[SharedReference]", "<PackageReference Include=\"Oqtane.Shared\" Version=\"" + moduleDefinition.Version + "\" />");
|
|
||||||
}
|
|
||||||
System.IO.File.WriteAllText(filePath, text);
|
System.IO.File.WriteAllText(filePath, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryInfo[] folders = current.GetDirectories();
|
var folders = current.GetDirectories();
|
||||||
|
|
||||||
foreach (DirectoryInfo folder in folders.Reverse())
|
foreach (DirectoryInfo folder in folders.Reverse())
|
||||||
{
|
{
|
||||||
@ -372,5 +354,51 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ITokenReplace InitializeTokenReplace(string rootPath, string rootFolder, ModuleDefinition moduleDefinition)
|
||||||
|
{
|
||||||
|
var tokenReplace = _serviceProvider.GetService<ITokenReplace>();
|
||||||
|
tokenReplace.AddSource(() =>
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "RootPath", rootPath },
|
||||||
|
{ "RootFolder", rootFolder },
|
||||||
|
{ "Owner", moduleDefinition.Owner },
|
||||||
|
{ "Module", moduleDefinition.Name },
|
||||||
|
{ "Description", moduleDefinition.Description },
|
||||||
|
{ "ServerManagerType", moduleDefinition.ServerManagerType }
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
if (moduleDefinition.Version == "local")
|
||||||
|
{
|
||||||
|
tokenReplace.AddSource(() =>
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{ "FrameworkVersion", Constants.Version },
|
||||||
|
{ "ClientReference", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll</HintPath></Reference>" },
|
||||||
|
{ "ServerReference", $"<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Server.dll</HintPath></Reference>" },
|
||||||
|
{ "SharedReference", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll</HintPath></Reference>" },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokenReplace.AddSource(() =>
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{ "FrameworkVersion", moduleDefinition.Version },
|
||||||
|
{ "ClientReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{moduleDefinition.Version}\" />" },
|
||||||
|
{ "ServerReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{moduleDefinition.Version}\" />" },
|
||||||
|
{ "SharedReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{moduleDefinition.Version}\" />" },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenReplace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ using System.Text.Json;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
using System;
|
using System;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Oqtane.Infrastructure.Interfaces;
|
||||||
|
|
||||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||||
|
|
||||||
@ -29,8 +31,9 @@ namespace Oqtane.Controllers
|
|||||||
private readonly ISyncManager _syncManager;
|
private readonly ISyncManager _syncManager;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
private readonly Alias _alias;
|
private readonly Alias _alias;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
public ThemeController(IThemeRepository themes, IInstallationManager installationManager, IWebHostEnvironment environment, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
public ThemeController(IThemeRepository themes, IInstallationManager installationManager, IWebHostEnvironment environment, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IServiceProvider serviceProvider)
|
||||||
{
|
{
|
||||||
_themes = themes;
|
_themes = themes;
|
||||||
_installationManager = installationManager;
|
_installationManager = installationManager;
|
||||||
@ -39,6 +42,7 @@ namespace Oqtane.Controllers
|
|||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_alias = tenantManager.GetAlias();
|
_alias = tenantManager.GetAlias();
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/<controller>
|
// GET: api/<controller>
|
||||||
@ -208,54 +212,80 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
private void ProcessTemplatesRecursively(DirectoryInfo current, string rootPath, string rootFolder, string templatePath, Theme theme)
|
private void ProcessTemplatesRecursively(DirectoryInfo current, string rootPath, string rootFolder, string templatePath, Theme theme)
|
||||||
{
|
{
|
||||||
|
var tokenReplace = InitializeTokenReplace(rootPath, rootFolder, theme);
|
||||||
|
|
||||||
// process folder
|
// process folder
|
||||||
string folderPath = Utilities.PathCombine(rootPath, current.FullName.Replace(templatePath, ""));
|
var folderPath = Utilities.PathCombine(rootPath, current.FullName.Replace(templatePath, ""));
|
||||||
folderPath = folderPath.Replace("[Owner]", theme.Owner);
|
folderPath = tokenReplace.ReplaceTokens(folderPath);
|
||||||
folderPath = folderPath.Replace("[Theme]", theme.Name);
|
|
||||||
if (!Directory.Exists(folderPath))
|
if (!Directory.Exists(folderPath))
|
||||||
{
|
{
|
||||||
Directory.CreateDirectory(folderPath);
|
Directory.CreateDirectory(folderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInfo[] files = current.GetFiles("*.*");
|
tokenReplace.AddSource("Folder", folderPath);
|
||||||
|
var files = current.GetFiles("*.*");
|
||||||
if (files != null)
|
if (files != null)
|
||||||
{
|
{
|
||||||
foreach (FileInfo file in files)
|
foreach (FileInfo file in files)
|
||||||
{
|
{
|
||||||
// process file
|
// process file
|
||||||
string filePath = Path.Combine(folderPath, file.Name);
|
var filePath = Path.Combine(folderPath, file.Name);
|
||||||
filePath = filePath.Replace("[Owner]", theme.Owner);
|
filePath = tokenReplace.ReplaceTokens(filePath);
|
||||||
filePath = filePath.Replace("[Theme]", theme.Name);
|
tokenReplace.AddSource("File", Path.GetFileName(filePath));
|
||||||
|
|
||||||
string text = System.IO.File.ReadAllText(file.FullName);
|
var text = System.IO.File.ReadAllText(file.FullName);
|
||||||
text = text.Replace("[Owner]", theme.Owner);
|
text = tokenReplace.ReplaceTokens(text);
|
||||||
text = text.Replace("[Theme]", theme.Name);
|
|
||||||
text = text.Replace("[RootPath]", rootPath);
|
|
||||||
text = text.Replace("[RootFolder]", rootFolder);
|
|
||||||
text = text.Replace("[Folder]", folderPath);
|
|
||||||
text = text.Replace("[File]", Path.GetFileName(filePath));
|
|
||||||
if (theme.Version == "local")
|
|
||||||
{
|
|
||||||
text = text.Replace("[FrameworkVersion]", Constants.Version);
|
|
||||||
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll</HintPath></Reference>");
|
|
||||||
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll</HintPath></Reference>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
text = text.Replace("[FrameworkVersion]", theme.Version);
|
|
||||||
text = text.Replace("[ClientReference]", "<PackageReference Include=\"Oqtane.Client\" Version=\"" + theme.Version + "\" />");
|
|
||||||
text = text.Replace("[SharedReference]", "<PackageReference Include=\"Oqtane.Shared\" Version=\"" + theme.Version + "\" />");
|
|
||||||
}
|
|
||||||
System.IO.File.WriteAllText(filePath, text);
|
System.IO.File.WriteAllText(filePath, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
DirectoryInfo[] folders = current.GetDirectories();
|
var folders = current.GetDirectories();
|
||||||
|
|
||||||
foreach (DirectoryInfo folder in folders.Reverse())
|
foreach (DirectoryInfo folder in folders.Reverse())
|
||||||
{
|
{
|
||||||
ProcessTemplatesRecursively(folder, rootPath, rootFolder, templatePath, theme);
|
ProcessTemplatesRecursively(folder, rootPath, rootFolder, templatePath, theme);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ITokenReplace InitializeTokenReplace(string rootPath, string rootFolder, Theme theme)
|
||||||
|
{
|
||||||
|
var tokenReplace = _serviceProvider.GetService<ITokenReplace>();
|
||||||
|
tokenReplace.AddSource(() =>
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "RootPath", rootPath },
|
||||||
|
{ "RootFolder", rootFolder },
|
||||||
|
{ "Owner", theme.Owner },
|
||||||
|
{ "Theme", theme.Name }
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
if (theme.Version == "local")
|
||||||
|
{
|
||||||
|
tokenReplace.AddSource(() =>
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{ "FrameworkVersion", Constants.Version },
|
||||||
|
{ "ClientReference", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll</HintPath></Reference>" },
|
||||||
|
{ "SharedReference", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll</HintPath></Reference>" },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tokenReplace.AddSource(() =>
|
||||||
|
{
|
||||||
|
return new Dictionary<string, object>()
|
||||||
|
{
|
||||||
|
{ "FrameworkVersion", theme.Version },
|
||||||
|
{ "ClientReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{theme.Version}\" />" },
|
||||||
|
{ "SharedReference", $"<PackageReference Include=\"Oqtane.Client\" Version=\"{theme.Version}\" />" },
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokenReplace;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ using Microsoft.Extensions.Hosting;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
|
using Oqtane.Infrastructure.Interfaces;
|
||||||
using Oqtane.Managers;
|
using Oqtane.Managers;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Modules;
|
using Oqtane.Modules;
|
||||||
@ -150,6 +151,8 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||||||
// obsolete - replaced by ITenantManager
|
// obsolete - replaced by ITenantManager
|
||||||
services.AddTransient<ITenantResolver, TenantResolver>();
|
services.AddTransient<ITenantResolver, TenantResolver>();
|
||||||
|
|
||||||
|
services.AddTransient<ITokenReplace, TokenReplace>();
|
||||||
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,9 @@ namespace Oqtane.Extensions
|
|||||||
options.Password.RequireNonAlphanumeric = bool.Parse(sitesettings.GetValue("IdentityOptions:Password:RequireNonAlphanumeric", options.Password.RequireNonAlphanumeric.ToString()));
|
options.Password.RequireNonAlphanumeric = bool.Parse(sitesettings.GetValue("IdentityOptions:Password:RequireNonAlphanumeric", options.Password.RequireNonAlphanumeric.ToString()));
|
||||||
|
|
||||||
// lockout options
|
// lockout options
|
||||||
options.Lockout.MaxFailedAccessAttempts = int.Parse(sitesettings.GetValue("IdentityOptions:Password:MaxFailedAccessAttempts", options.Lockout.MaxFailedAccessAttempts.ToString()));
|
options.Lockout.MaxFailedAccessAttempts = int.Parse(sitesettings.GetValue("IdentityOptions:Lockout:MaxFailedAccessAttempts", options.Lockout.MaxFailedAccessAttempts.ToString()));
|
||||||
options.Lockout.DefaultLockoutTimeSpan = TimeSpan.Parse(sitesettings.GetValue("IdentityOptions:Password:DefaultLockoutTimeSpan", options.Lockout.DefaultLockoutTimeSpan.ToString()));
|
options.Lockout.DefaultLockoutTimeSpan = TimeZoneInfo.Local.GetUtcOffset(DateTime.UtcNow) + TimeSpan.Parse(sitesettings.GetValue("IdentityOptions:Lockout:DefaultLockoutTimeSpan", options.Lockout.DefaultLockoutTimeSpan.ToString()));
|
||||||
|
options.Lockout.AllowedForNewUsers = options.Lockout.MaxFailedAccessAttempts > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
|
27
Oqtane.Server/Infrastructure/Interfaces/ITokenReplace.cs
Normal file
27
Oqtane.Server/Infrastructure/Interfaces/ITokenReplace.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Oqtane.Interfaces;
|
||||||
|
|
||||||
|
namespace Oqtane.Infrastructure.Interfaces
|
||||||
|
{
|
||||||
|
public interface ITokenReplace
|
||||||
|
{
|
||||||
|
void AddSource(ITokenSource source);
|
||||||
|
|
||||||
|
void AddSource(Func<IDictionary<string, object>> sourceFunc);
|
||||||
|
|
||||||
|
void AddSource(IDictionary<string, object> source);
|
||||||
|
|
||||||
|
void AddSource(string key, object value);
|
||||||
|
|
||||||
|
void AddSource(string name, ITokenSource source);
|
||||||
|
|
||||||
|
void AddSource(string name, Func<IDictionary<string, object>> sourceFunc);
|
||||||
|
|
||||||
|
void AddSource(string name, IDictionary<string, object> source);
|
||||||
|
|
||||||
|
void AddSource(string name, string key, object value);
|
||||||
|
|
||||||
|
string ReplaceTokens(string source);
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,6 @@ namespace Oqtane.Infrastructure
|
|||||||
{
|
{
|
||||||
public string SiteKey { get; set; }
|
public string SiteKey { get; set; }
|
||||||
public List<string> Assemblies { get; set; } = new List<string>();
|
public List<string> Assemblies { get; set; } = new List<string>();
|
||||||
public List<Resource>Scripts { get; set; } = new List<Resource>();
|
|
||||||
public bool IsInitialized { get; set; } = false;
|
public bool IsInitialized { get; set; } = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Oqtane.Models;
|
|
||||||
|
|
||||||
namespace Oqtane.Infrastructure
|
namespace Oqtane.Infrastructure
|
||||||
{
|
{
|
||||||
@ -22,7 +21,6 @@ namespace Oqtane.Infrastructure
|
|||||||
serverState = new ServerState();
|
serverState = new ServerState();
|
||||||
serverState.SiteKey = siteKey;
|
serverState.SiteKey = siteKey;
|
||||||
serverState.Assemblies = new List<string>();
|
serverState.Assemblies = new List<string>();
|
||||||
serverState.Scripts = new List<Resource>();
|
|
||||||
serverState.IsInitialized = false;
|
serverState.IsInitialized = false;
|
||||||
_serverStates.Add(serverState);
|
_serverStates.Add(serverState);
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ namespace Oqtane.SiteTemplates
|
|||||||
},
|
},
|
||||||
Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>CMS</b> and <b>Application Framework</b> that provides advanced functionality for developing web, mobile, and desktop applications on .NET. It leverages Blazor to compose a <b>fully dynamic</b> digital experience. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles and patterns.</p>" +
|
Content = "<p><a href=\"https://www.oqtane.org\" target=\"_new\">Oqtane</a> is an open source <b>CMS</b> and <b>Application Framework</b> that provides advanced functionality for developing web, mobile, and desktop applications on .NET. It leverages Blazor to compose a <b>fully dynamic</b> digital experience. Whether you are looking for a platform to <b>accelerate your web development</b> efforts, or simply interested in exploring the anatomy of a large-scale Blazor application, Oqtane provides a solid foundation based on proven enterprise architectural principles and patterns.</p>" +
|
||||||
"<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img class=\"img-fluid\" src=\"oqtane-glow.png\"></a></p><p align=\"center\"><a class=\"btn btn-primary\" href=\"https://www.oqtane.org\" target=\"_new\">Join Our Community</a> <a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a></p>" +
|
"<p align=\"center\"><a href=\"https://www.oqtane.org\" target=\"_new\"><img class=\"img-fluid\" src=\"oqtane-glow.png\"></a></p><p align=\"center\"><a class=\"btn btn-primary\" href=\"https://www.oqtane.org\" target=\"_new\">Join Our Community</a> <a class=\"btn btn-primary\" href=\"https://github.com/oqtane/oqtane.framework\" target=\"_new\">Clone Our Repo</a></p>" +
|
||||||
"<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is an open source and cross-platform web UI framework for building single-page applications using .NET and C#. Blazor applications can be hosted in a variety of ways. Blazor Server uses SignalR (WebSockets) to host your application on a web server and provide a responsive and robust development experience. Blazor WebAssembly relies on Wasm, an open web standard that does not require plugins in order for applications to run natively in a web browser. Blazor Hybrid is part of .NET MAUI and uses a Web View to render components natively on mobile and desktop devices. Razor components can be shared across all of the hosting models without any modification.</p>" +
|
"<p><a href=\"https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor\" target=\"_new\">Blazor</a> is a modern front-end web framework based on HTML, CSS, and C# that helps you build web applications faster. Blazor provides a component-based architecture with server-side rendering and full client-side interactivity in a single solution, where you can switch between server-side and client-side rendering modes and even mix them in the same web page. For desktop or mobile scenarios, Blazor Hybrid is part of .NET MAUI and uses a Web View to render components natively on all modern devices.</p>" +
|
||||||
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET</a>, the popular cross platform development framework from Microsoft that provides powerful tools and libraries for building modern software applications.</p>"
|
"<p>Blazor is a feature of <a href=\"https://dotnet.microsoft.com/apps/aspnet\" target=\"_new\">ASP.NET</a>, the popular cross platform development framework from Microsoft that provides powerful tools and libraries for building modern software applications.</p>"
|
||||||
},
|
},
|
||||||
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "MIT License", Pane = PaneNames.Default,
|
new PageTemplateModule { ModuleDefinitionName = "Oqtane.Modules.HtmlText, Oqtane.Client", Title = "MIT License", Pane = PaneNames.Default,
|
||||||
|
158
Oqtane.Server/Infrastructure/TokenReplace.cs
Normal file
158
Oqtane.Server/Infrastructure/TokenReplace.cs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Text;
|
||||||
|
using Oqtane.Infrastructure.Interfaces;
|
||||||
|
using Oqtane.Interfaces;
|
||||||
|
using Oqtane.Models;
|
||||||
|
|
||||||
|
namespace Oqtane.Infrastructure
|
||||||
|
{
|
||||||
|
public class TokenReplace : ITokenReplace
|
||||||
|
{
|
||||||
|
public const string GenericName = "generic";
|
||||||
|
|
||||||
|
private const string TokenExpression = "(?:(?<text>\\[\\])|\\[(?:(?<source>[^{}\\]\\[:]+):(?<key>[^\\]\\[\\|]+)|(?<key>[^\\]\\[\\|]+))(?:\\|(?:(?<format>[^\\]\\[]+)\\|(?<empty>[^\\]\\\\[]+))|\\|(?:(?<format>[^\\|\\]\\[]+)))?\\])|(?<text>\\[[^\\]\\[]+\\])|(?<text>\\[{0,1}[^\\]\\[]+\\]{0,1})";
|
||||||
|
|
||||||
|
private Regex TokenizerRegex = new Regex(TokenExpression, RegexOptions.Compiled | RegexOptions.Singleline);
|
||||||
|
private IDictionary<string, IDictionary<string, object>> _tokens;
|
||||||
|
|
||||||
|
private readonly ILogManager _logger;
|
||||||
|
|
||||||
|
public TokenReplace(ILogManager logger)
|
||||||
|
{
|
||||||
|
_tokens = new Dictionary<string, IDictionary<string, object>>();
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(ITokenSource source)
|
||||||
|
{
|
||||||
|
this.AddSource(GenericName, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(Func<IDictionary<string, object>> sourceFunc)
|
||||||
|
{
|
||||||
|
this.AddSource(GenericName, sourceFunc);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(IDictionary<string, object> source)
|
||||||
|
{
|
||||||
|
this.AddSource(GenericName, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(string key, object value)
|
||||||
|
{
|
||||||
|
this.AddSource(GenericName, key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(string name, ITokenSource source)
|
||||||
|
{
|
||||||
|
var tokens = source.GetTokens();
|
||||||
|
this.AddSource(name, tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(string name, Func<IDictionary<string, object>> sourceFunc)
|
||||||
|
{
|
||||||
|
var tokens = sourceFunc();
|
||||||
|
this.AddSource(name, tokens);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(string name, IDictionary<string, object> source)
|
||||||
|
{
|
||||||
|
if(source != null)
|
||||||
|
{
|
||||||
|
foreach (var key in source.Keys)
|
||||||
|
{
|
||||||
|
this.AddSource(name, key, source[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSource(string name, string key, object value)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
name = GenericName;
|
||||||
|
}
|
||||||
|
|
||||||
|
var source = _tokens.ContainsKey(name.ToLower()) ? _tokens[name.ToLower()] : null;
|
||||||
|
if(source == null)
|
||||||
|
{
|
||||||
|
source = new Dictionary<string, object>();
|
||||||
|
}
|
||||||
|
source[key] = value;
|
||||||
|
|
||||||
|
_tokens[name.ToLower()] = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReplaceTokens(string source)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(source))
|
||||||
|
{
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = new StringBuilder();
|
||||||
|
foreach (Match match in this.TokenizerRegex.Matches(source))
|
||||||
|
{
|
||||||
|
var key = match.Result("${key}");
|
||||||
|
if (!string.IsNullOrWhiteSpace(key))
|
||||||
|
{
|
||||||
|
var sourceName = match.Result("${source}");
|
||||||
|
if (string.IsNullOrWhiteSpace(sourceName) || sourceName == "[")
|
||||||
|
{
|
||||||
|
sourceName = GenericName;
|
||||||
|
}
|
||||||
|
|
||||||
|
var format = match.Result("${format}");
|
||||||
|
var emptyReplacment = match.Result("${empty}");
|
||||||
|
var value = ReplaceTokenValue(sourceName, key, format);
|
||||||
|
if (string.IsNullOrWhiteSpace(value))
|
||||||
|
{
|
||||||
|
if(!string.IsNullOrWhiteSpace(emptyReplacment))
|
||||||
|
{
|
||||||
|
value = emptyReplacment;
|
||||||
|
}
|
||||||
|
else //keep the original content
|
||||||
|
{
|
||||||
|
value = match.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result.Append(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.Append(match.Result("${text}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ReplaceTokenValue(string sourceName, string key, string format)
|
||||||
|
{
|
||||||
|
if(!_tokens.ContainsKey(sourceName.ToLower()))
|
||||||
|
{
|
||||||
|
_logger.Log(Shared.LogLevel.Debug, this, Enums.LogFunction.Other, $"MissingSource:{sourceName}");
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tokens = _tokens[sourceName.ToLower()];
|
||||||
|
if(!tokens.ContainsKey(key))
|
||||||
|
{
|
||||||
|
_logger.Log(Shared.LogLevel.Debug, this, Enums.LogFunction.Other, $"MissingKey:{key}");
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = tokens[key];
|
||||||
|
if(value == null)
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: need to implement the format.
|
||||||
|
return value.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Oqtane.Extensions;
|
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
<DefineConstants>$(DefineConstants);OQTANE;OQTANE3</DefineConstants>
|
<DefineConstants>$(DefineConstants);OQTANE;OQTANE3</DefineConstants>
|
||||||
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -225,17 +225,6 @@ namespace Oqtane.Repository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// build list of scripts for site
|
|
||||||
if (moduledefinition.Resources != null)
|
|
||||||
{
|
|
||||||
foreach (var resource in moduledefinition.Resources.Where(item => item.ResourceType == ResourceType.Script && item.Level == ResourceLevel.Site))
|
|
||||||
{
|
|
||||||
if (!serverState.Scripts.Contains(resource))
|
|
||||||
{
|
|
||||||
serverState.Scripts.Add(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (permissions.Count == 0)
|
if (permissions.Count == 0)
|
||||||
|
@ -197,17 +197,6 @@ namespace Oqtane.Repository
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// build list of scripts for site
|
|
||||||
if (theme.Resources != null)
|
|
||||||
{
|
|
||||||
foreach (var resource in theme.Resources.Where(item => item.ResourceType == ResourceType.Script && item.Level == ResourceLevel.Site))
|
|
||||||
{
|
|
||||||
if (!serverState.Scripts.Contains(resource))
|
|
||||||
{
|
|
||||||
serverState.Scripts.Add(resource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,11 +27,11 @@ namespace Oqtane.Services
|
|||||||
private readonly ILanguageRepository _languages;
|
private readonly ILanguageRepository _languages;
|
||||||
private readonly IUserPermissions _userPermissions;
|
private readonly IUserPermissions _userPermissions;
|
||||||
private readonly ISettingRepository _settings;
|
private readonly ISettingRepository _settings;
|
||||||
|
private readonly ITenantManager _tenantManager;
|
||||||
private readonly ISyncManager _syncManager;
|
private readonly ISyncManager _syncManager;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
private readonly IMemoryCache _cache;
|
private readonly IMemoryCache _cache;
|
||||||
private readonly IHttpContextAccessor _accessor;
|
private readonly IHttpContextAccessor _accessor;
|
||||||
private readonly Alias _alias;
|
|
||||||
|
|
||||||
public ServerSiteService(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache, IHttpContextAccessor accessor)
|
public ServerSiteService(ISiteRepository sites, IPageRepository pages, IThemeRepository themes, IPageModuleRepository pageModules, IModuleDefinitionRepository moduleDefinitions, ILanguageRepository languages, IUserPermissions userPermissions, ISettingRepository settings, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger, IMemoryCache cache, IHttpContextAccessor accessor)
|
||||||
{
|
{
|
||||||
@ -43,11 +43,11 @@ namespace Oqtane.Services
|
|||||||
_languages = languages;
|
_languages = languages;
|
||||||
_userPermissions = userPermissions;
|
_userPermissions = userPermissions;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
_tenantManager = tenantManager;
|
||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_cache = cache;
|
_cache = cache;
|
||||||
_accessor = accessor;
|
_accessor = accessor;
|
||||||
_alias = tenantManager.GetAlias();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<List<Site>> GetSitesAsync()
|
public async Task<List<Site>> GetSitesAsync()
|
||||||
@ -80,8 +80,9 @@ namespace Oqtane.Services
|
|||||||
|
|
||||||
private Site GetSite(int siteid)
|
private Site GetSite(int siteid)
|
||||||
{
|
{
|
||||||
|
var alias = _tenantManager.GetAlias();
|
||||||
var site = _sites.GetSite(siteid);
|
var site = _sites.GetSite(siteid);
|
||||||
if (site != null && site.SiteId == _alias.SiteId)
|
if (site != null && site.SiteId == alias.SiteId)
|
||||||
{
|
{
|
||||||
// site settings
|
// site settings
|
||||||
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
||||||
@ -179,8 +180,9 @@ namespace Oqtane.Services
|
|||||||
{
|
{
|
||||||
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
||||||
{
|
{
|
||||||
|
var alias = _tenantManager.GetAlias();
|
||||||
site = _sites.AddSite(site);
|
site = _sites.AddSite(site);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Create);
|
_syncManager.AddSyncEvent(alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Create);
|
||||||
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Create, "Site Added {Site}", site);
|
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Create, "Site Added {Site}", site);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -194,17 +196,18 @@ namespace Oqtane.Services
|
|||||||
{
|
{
|
||||||
if (_accessor.HttpContext.User.IsInRole(RoleNames.Admin))
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Admin))
|
||||||
{
|
{
|
||||||
|
var alias = _tenantManager.GetAlias();
|
||||||
var current = _sites.GetSite(site.SiteId, false);
|
var current = _sites.GetSite(site.SiteId, false);
|
||||||
if (site.SiteId == _alias.SiteId && site.TenantId == _alias.TenantId && current != null)
|
if (site.SiteId == alias.SiteId && site.TenantId == alias.TenantId && current != null)
|
||||||
{
|
{
|
||||||
site = _sites.UpdateSite(site);
|
site = _sites.UpdateSite(site);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Update);
|
_syncManager.AddSyncEvent(alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Update);
|
||||||
string action = SyncEventActions.Refresh;
|
string action = SyncEventActions.Refresh;
|
||||||
if (current.RenderMode != site.RenderMode || current.Runtime != site.Runtime)
|
if (current.RenderMode != site.RenderMode || current.Runtime != site.Runtime)
|
||||||
{
|
{
|
||||||
action = SyncEventActions.Reload;
|
action = SyncEventActions.Reload;
|
||||||
}
|
}
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, action);
|
_syncManager.AddSyncEvent(alias.TenantId, EntityNames.Site, site.SiteId, action);
|
||||||
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site);
|
_logger.Log(site.SiteId, LogLevel.Information, this, LogFunction.Update, "Site Updated {Site}", site);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -224,11 +227,12 @@ namespace Oqtane.Services
|
|||||||
{
|
{
|
||||||
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
if (_accessor.HttpContext.User.IsInRole(RoleNames.Host))
|
||||||
{
|
{
|
||||||
|
var alias = _tenantManager.GetAlias();
|
||||||
var site = _sites.GetSite(siteId);
|
var site = _sites.GetSite(siteId);
|
||||||
if (site != null && site.SiteId == _alias.SiteId)
|
if (site != null && site.SiteId == alias.SiteId)
|
||||||
{
|
{
|
||||||
_sites.DeleteSite(siteId);
|
_sites.DeleteSite(siteId);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Delete);
|
_syncManager.AddSyncEvent(alias.TenantId, EntityNames.Site, site.SiteId, SyncEventActions.Delete);
|
||||||
_logger.Log(siteId, LogLevel.Information, this, LogFunction.Delete, "Site Deleted {SiteId}", siteId);
|
_logger.Log(siteId, LogLevel.Information, this, LogFunction.Delete, "Site Deleted {SiteId}", siteId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
|
AddModuleMessage(ex.Message, MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
|
AddModuleMessage(ex.Message, MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -197,7 +197,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767.98px) {
|
||||||
.app-logo {
|
.app-logo {
|
||||||
height: 80px;
|
height: 80px;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -96,7 +96,7 @@ div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu
|
|||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767.98px) {
|
||||||
|
|
||||||
.app-menu {
|
.app-menu {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
|
AddModuleMessage(ex.Message, MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +44,7 @@
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
ModuleInstance.AddModuleMessage(ex.Message, MessageType.Error);
|
AddModuleMessage(ex.Message, MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,9 @@ namespace [Owner].Theme.[Theme]
|
|||||||
Resources = new List<Resource>()
|
Resources = new List<Resource>()
|
||||||
{
|
{
|
||||||
// obtained from https://cdnjs.com/libraries
|
// obtained from https://cdnjs.com/libraries
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/css/bootstrap.min.css", Integrity = "sha512-t4GWSVZO1eC8BM339Xd7Uphw5s17a86tIZIj8qRxhnKub6WoyhnrxeCIMeAqBPgdZGlCcG2PrZjMc+Wr78+5Xg==", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css", Integrity = "sha512-b2QcS5SsA8tZodcDtGRELiGv5SaKSk1vDHDaQRda0htPYWZ6046lr3kJ5bAAQdpV2mmA/4v0wQF9MyU6/pDIAg==", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.0/js/bootstrap.bundle.min.js", Integrity = "sha512-VK2zcvntEufaimc+efOYi622VN5ZacdnufnmX7zIhCPmjhKnOi9ZDMtg1/ug5l183f19gG1/cBstPO4D8N/Img==", CrossOrigin = "anonymous" }
|
new Resource { ResourceType = ResourceType.Script, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/js/bootstrap.bundle.min.js", Integrity = "sha512-X/YkDZyjTf4wyc2Vy16YGCPHwAY8rZJY+POgokZjQB2mhIRFJCckEGc6YyX9eNsPfn0PzThEuNs+uaomE5CO6A==", CrossOrigin = "anonymous" }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ div.app-moduleactions a.dropdown-toggle, div.app-moduleactions div.dropdown-menu
|
|||||||
mix-blend-mode: difference;
|
mix-blend-mode: difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
@media (max-width: 767.98px) {
|
||||||
|
|
||||||
.app-menu {
|
.app-menu {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -206,21 +206,28 @@ Oqtane.Interop = {
|
|||||||
returnPromise: true,
|
returnPromise: true,
|
||||||
before: function (path, element) {
|
before: function (path, element) {
|
||||||
for (let s = 0; s < scripts.length; s++) {
|
for (let s = 0; s < scripts.length; s++) {
|
||||||
if (path === scripts[s].href && scripts[s].integrity !== '') {
|
if (path === scripts[s].href) {
|
||||||
|
if (scripts[s].integrity !== '') {
|
||||||
element.integrity = scripts[s].integrity;
|
element.integrity = scripts[s].integrity;
|
||||||
}
|
}
|
||||||
if (path === scripts[s].href && scripts[s].crossorigin !== '') {
|
if (scripts[s].crossorigin !== '') {
|
||||||
element.crossOrigin = scripts[s].crossorigin;
|
element.crossOrigin = scripts[s].crossorigin;
|
||||||
}
|
}
|
||||||
if (path === scripts[s].href && scripts[s].es6module === true) {
|
if (scripts[s].es6module === true) {
|
||||||
element.type = "module";
|
element.type = "module";
|
||||||
}
|
}
|
||||||
if (path === scripts[s].href && scripts[s].location === 'body') {
|
if (typeof scripts[s].dataAttributes !== "undefined" && scripts[s].dataAttributes !== null) {
|
||||||
|
for (var key in scripts[s].dataAttributes) {
|
||||||
|
element.setAttribute(key, scripts[s].dataAttributes[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (scripts[s].location === 'body') {
|
||||||
document.body.appendChild(element);
|
document.body.appendChild(element);
|
||||||
return false; // return false to bypass default DOM insertion mechanism
|
return false; // return false to bypass default DOM insertion mechanism
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.then(function () { resolve(true) })
|
.then(function () { resolve(true) })
|
||||||
.catch(function (pathsNotFound) { reject(false) });
|
.catch(function (pathsNotFound) { reject(false) });
|
||||||
|
@ -2,7 +2,7 @@ namespace Oqtane.Shared
|
|||||||
{
|
{
|
||||||
public enum ResourceLevel
|
public enum ResourceLevel
|
||||||
{
|
{
|
||||||
App,
|
Undefined,
|
||||||
Site,
|
Site,
|
||||||
Page,
|
Page,
|
||||||
Module
|
Module
|
||||||
|
13
Oqtane.Shared/Interfaces/ITokenSource.cs
Normal file
13
Oqtane.Shared/Interfaces/ITokenSource.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Oqtane.Interfaces
|
||||||
|
{
|
||||||
|
public interface ITokenSource
|
||||||
|
{
|
||||||
|
IDictionary<string, object> GetTokens();
|
||||||
|
}
|
||||||
|
}
|
@ -32,8 +32,8 @@ namespace Oqtane.Models
|
|||||||
PathAndQuery = uri.PathAndQuery;
|
PathAndQuery = uri.PathAndQuery;
|
||||||
AliasPath = aliaspath;
|
AliasPath = aliaspath;
|
||||||
PagePath = AbsolutePath;
|
PagePath = AbsolutePath;
|
||||||
ModuleId = "";
|
ModuleId = "-1";
|
||||||
Action = "";
|
Action = Constants.DefaultAction;
|
||||||
UrlParameters = "";
|
UrlParameters = "";
|
||||||
|
|
||||||
if (AliasPath.Length != 0 && PagePath.StartsWith("/" + AliasPath))
|
if (AliasPath.Length != 0 && PagePath.StartsWith("/" + AliasPath))
|
||||||
@ -58,7 +58,9 @@ namespace Oqtane.Models
|
|||||||
if (pos != -1)
|
if (pos != -1)
|
||||||
{
|
{
|
||||||
Action = ModuleId.Substring(pos + 1);
|
Action = ModuleId.Substring(pos + 1);
|
||||||
|
Action = (!string.IsNullOrEmpty(Action)) ? Action : Constants.DefaultAction;
|
||||||
ModuleId = ModuleId.Substring(0, pos);
|
ModuleId = ModuleId.Substring(0, pos);
|
||||||
|
ModuleId = (int.TryParse(ModuleId, out _)) ? ModuleId : "-1";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PagePath.StartsWith("/"))
|
if (PagePath.StartsWith("/"))
|
||||||
|
@ -5,7 +5,7 @@ namespace Oqtane.Shared
|
|||||||
public class Constants
|
public class Constants
|
||||||
{
|
{
|
||||||
public static readonly string Version = "5.1.0";
|
public static readonly string Version = "5.1.0";
|
||||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.1.0";
|
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0,5.0.1,5.0.2,5.0.3,5.1.0";
|
||||||
public const string PackageId = "Oqtane.Framework";
|
public const string PackageId = "Oqtane.Framework";
|
||||||
public const string ClientId = "Oqtane.Client";
|
public const string ClientId = "Oqtane.Client";
|
||||||
public const string UpdaterPackageId = "Oqtane.Updater";
|
public const string UpdaterPackageId = "Oqtane.Updater";
|
||||||
|
Reference in New Issue
Block a user