Compare commits
79 Commits
revert-482
...
v6.0.1
Author | SHA1 | Date | |
---|---|---|---|
8d7845a44d | |||
3a15e6e5e9 | |||
3b8a51e855 | |||
f2cb34cc35 | |||
723ce62a34 | |||
2c9a2ea021 | |||
2be008d6d1 | |||
7fb51bdd0a | |||
abdbe3694f | |||
bd87e5012f | |||
55e18f2364 | |||
655e84072d | |||
ab5409d5b6 | |||
5a5da6486c | |||
7e99252429 | |||
10e0dcef8b | |||
80c8433aad | |||
5b0ae372f8 | |||
b5a1b529ab | |||
af821dcd9a | |||
10d3c81520 | |||
e3811b453a | |||
ca0fb05baa | |||
2b4b01bf6e | |||
3a1244bddc | |||
b8fd922b19 | |||
03f856025e | |||
45f04d24c3 | |||
2435d610c7 | |||
06572bcd14 | |||
3fab79afc0 | |||
2b7dd3fed5 | |||
d65efed032 | |||
c6896ea936 | |||
b7a41bddec | |||
6fd80c3737 | |||
0aa690b3b1 | |||
6d5bcfc6ed | |||
b60de69fa5 | |||
d991b57d08 | |||
1133d7fcba | |||
6fbf0383bb | |||
0296230219 | |||
dedfbba27a | |||
dc5441da07 | |||
585648b7f3 | |||
cd0ee1c26d | |||
d7a7be5af4 | |||
13e4267c11 | |||
15bc47e3e8 | |||
1a4380dcd7 | |||
5ace34b5cd | |||
f010c0f1fa | |||
2c721ad5dd | |||
8a7c2ce2c2 | |||
b2a7b813de | |||
e85cf04b99 | |||
ab6fa48172 | |||
c81905882f | |||
f0d31c1114 | |||
497b255216 | |||
d96286d771 | |||
2441647d75 | |||
77b780d631 | |||
cdd03bf3d4 | |||
e786c35f7d | |||
e83399acb1 | |||
ffea9e3210 | |||
f71a3a1ce3 | |||
784f3771b3 | |||
80316824f7 | |||
cbaebb7b7c | |||
97d3764b6e | |||
4c937be884 | |||
c25cce4398 | |||
58c422285a | |||
f2f22f35e8 | |||
15867a7807 | |||
e2c404d8bb |
@ -316,10 +316,11 @@
|
|||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThemeChanged(ChangeEventArgs e)
|
private async Task ThemeChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||||
@ -330,6 +331,7 @@
|
|||||||
if (ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName)
|
if (ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName)
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["ThemeChanged.Message"], MessageType.Warning);
|
AddModuleMessage(Localizer["ThemeChanged.Message"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,6 +347,7 @@
|
|||||||
if (!Utilities.ValidateEffectiveExpiryDates(_effectivedate, _expirydate))
|
if (!Utilities.ValidateEffectiveExpiryDates(_effectivedate, _expirydate))
|
||||||
{
|
{
|
||||||
AddModuleMessage(SharedLocalizer["Message.EffectiveExpiryDateError"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.EffectiveExpiryDateError"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(_themetype) && !string.IsNullOrEmpty(_containertype))
|
if (!string.IsNullOrEmpty(_themetype) && !string.IsNullOrEmpty(_containertype))
|
||||||
@ -395,12 +398,14 @@
|
|||||||
if (_pages.Any(item => item.Path == page.Path))
|
if (_pages.Any(item => item.Path == page.Path))
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Message.Page.Exists"], _path), MessageType.Warning);
|
AddModuleMessage(string.Format(Localizer["Message.Page.Exists"], _path), MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page.ParentId == null && Constants.ReservedRoutes.Contains(page.Name.ToLower()))
|
if (page.ParentId == null && Constants.ReservedRoutes.Contains(page.Name.ToLower()))
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning);
|
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], page.Name), MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,6 +473,7 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -475,11 +481,13 @@
|
|||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
|
await logger.LogError(ex, "Error Saving Page {Page} {Error}", page, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,10 +479,11 @@
|
|||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
await logger.LogError(ex, "Error Loading Child Pages For Parent {PageId} {Error}", _parentid, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.ChildPage.Load"], MessageType.Error);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThemeChanged(ChangeEventArgs e)
|
private async Task ThemeChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
_themetype = (string)e.Value;
|
_themetype = (string)e.Value;
|
||||||
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
_containers = ThemeService.GetContainerControls(PageState.Site.Themes, _themetype);
|
||||||
@ -494,6 +495,7 @@
|
|||||||
if (ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName)
|
if (ThemeService.GetTheme(PageState.Site.Themes, _themetype)?.ThemeName != ThemeService.GetTheme(PageState.Site.Themes, PageState.Site.DefaultThemeType)?.ThemeName)
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["ThemeChanged.Message"], MessageType.Warning);
|
AddModuleMessage(Localizer["ThemeChanged.Message"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -531,6 +533,7 @@
|
|||||||
if (!Utilities.ValidateEffectiveExpiryDates(_effectivedate, _expirydate))
|
if (!Utilities.ValidateEffectiveExpiryDates(_effectivedate, _expirydate))
|
||||||
{
|
{
|
||||||
AddModuleMessage(SharedLocalizer["Message.EffectiveExpiryDateError"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.EffectiveExpiryDateError"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
if (!string.IsNullOrEmpty(_themetype) && _containertype != "-")
|
||||||
@ -581,12 +584,14 @@
|
|||||||
if (_pages.Any(item => item.Path == _page.Path && item.PageId != _page.PageId))
|
if (_pages.Any(item => item.Path == _page.Path && item.PageId != _page.PageId))
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
|
AddModuleMessage(string.Format(Localizer["Mesage.Page.PathExists"], _path), MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_page.ParentId == null && Constants.ReservedRoutes.Contains(_page.Name.ToLower()))
|
if (_page.ParentId == null && Constants.ReservedRoutes.Contains(_page.Name.ToLower()))
|
||||||
{
|
{
|
||||||
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], _page.Name), MessageType.Warning);
|
AddModuleMessage(string.Format(Localizer["Message.Page.Reserved"], _page.Name), MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -671,17 +676,20 @@
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Required.PageInfo"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Saving Page {Page} {Error}", _page, ex.Message);
|
await logger.LogError(ex, "Error Saving Page {Page} {Error}", _page, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Page.Save"], MessageType.Error);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
|
await ScrollToPageTop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,22 +149,26 @@
|
|||||||
{
|
{
|
||||||
@if (p.IsRequired)
|
@if (p.IsRequired)
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete" />
|
<input id="@p.Name" class="form-control" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete" />
|
<input id="@p.Name" class="form-control" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@if (p.IsRequired)
|
@if (p.IsRequired)
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)" />
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -174,22 +178,26 @@
|
|||||||
{
|
{
|
||||||
@if (p.IsRequired)
|
@if (p.IsRequired)
|
||||||
{
|
{
|
||||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"></textarea>
|
<textarea id="@p.Name" class="form-control" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)"></textarea>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"></textarea>
|
<textarea id="@p.Name" class="form-control" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" autocomplete="@p.Autocomplete"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)"></textarea>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@if (p.IsRequired)
|
@if (p.IsRequired)
|
||||||
{
|
{
|
||||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
<textarea id="@p.Name" class="form-control" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)"></textarea>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
<textarea id="@p.Name" class="form-control" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"
|
||||||
|
@attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)"></textarea>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,13 +238,13 @@
|
|||||||
|
|
||||||
@if (context.IsRead)
|
@if (context.IsRead)
|
||||||
{
|
{
|
||||||
<td>@context.FromDisplayName</td>
|
<td>@(string.IsNullOrEmpty(context.FromDisplayName) ? SharedLocalizer["System"] : context.FromDisplayName)</td>
|
||||||
<td>@context.Subject</td>
|
<td>@context.Subject</td>
|
||||||
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
|
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<td><b>@context.FromDisplayName</b></td>
|
<td><b>@(string.IsNullOrEmpty(context.FromDisplayName) ? SharedLocalizer["System"] : context.FromDisplayName)</b></td>
|
||||||
<td><b>@context.Subject</b></td>
|
<td><b>@context.Subject</b></td>
|
||||||
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
|
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
|
||||||
}
|
}
|
||||||
@ -363,7 +371,7 @@
|
|||||||
private File photo = null;
|
private File photo = null;
|
||||||
private string _ImageFiles = string.Empty;
|
private string _ImageFiles = string.Empty;
|
||||||
private List<Profile> profiles;
|
private List<Profile> profiles;
|
||||||
private Dictionary<string, string> settings;
|
private Dictionary<string, string> userSettings;
|
||||||
private string category = string.Empty;
|
private string category = string.Empty;
|
||||||
|
|
||||||
private string filter = "to";
|
private string filter = "to";
|
||||||
@ -411,9 +419,9 @@
|
|||||||
photo = null;
|
photo = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
|
userSettings = PageState.User.Settings;
|
||||||
var sitesettings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
var sitesettings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
_ImageFiles = SettingService.GetSetting(settings, "ImageFiles", Constants.ImageFiles);
|
_ImageFiles = SettingService.GetSetting(userSettings, "ImageFiles", Constants.ImageFiles);
|
||||||
_ImageFiles = (string.IsNullOrEmpty(_ImageFiles)) ? Constants.ImageFiles : _ImageFiles;
|
_ImageFiles = (string.IsNullOrEmpty(_ImageFiles)) ? Constants.ImageFiles : _ImageFiles;
|
||||||
|
|
||||||
await LoadNotificationsAsync();
|
await LoadNotificationsAsync();
|
||||||
@ -440,7 +448,7 @@
|
|||||||
|
|
||||||
private string GetProfileValue(string SettingName, string DefaultValue)
|
private string GetProfileValue(string SettingName, string DefaultValue)
|
||||||
{
|
{
|
||||||
string value = SettingService.GetSetting(settings, SettingName, DefaultValue);
|
string value = SettingService.GetSetting(userSettings, SettingName, DefaultValue);
|
||||||
if (value.Contains("]"))
|
if (value.Contains("]"))
|
||||||
{
|
{
|
||||||
value = value.Substring(value.IndexOf("]") + 1);
|
value = value.Substring(value.IndexOf("]") + 1);
|
||||||
@ -483,7 +491,7 @@
|
|||||||
user = await UserService.UpdateUserAsync(user);
|
user = await UserService.UpdateUserAsync(user);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
await SettingService.UpdateUserSettingsAsync(settings, PageState.User.UserId);
|
await SettingService.UpdateUserSettingsAsync(userSettings, PageState.User.UserId);
|
||||||
await logger.LogInformation("User Profile Saved");
|
await logger.LogInformation("User Profile Saved");
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
if (!string.IsNullOrEmpty(PageState.ReturnUrl))
|
||||||
@ -554,7 +562,7 @@
|
|||||||
var value = GetProfileValue(profile.Name, string.Empty);
|
var value = GetProfileValue(profile.Name, string.Empty);
|
||||||
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
userSettings = SettingService.SetSetting(userSettings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
@ -586,7 +594,7 @@
|
|||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
{
|
{
|
||||||
var value = (string)e.Value;
|
var value = (string)e.Value;
|
||||||
settings = SettingService.SetSetting(settings, SettingName, value);
|
userSettings = SettingService.SetSetting(userSettings, SettingName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Delete(Notification Notification)
|
private async Task Delete(Notification Notification)
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
createdon = notification.CreatedOn.ToString();
|
createdon = notification.CreatedOn.ToString();
|
||||||
body = notification.Body;
|
body = notification.Body;
|
||||||
|
|
||||||
if (title == "From")
|
if (title == "From" && !notification.IsRead)
|
||||||
{
|
{
|
||||||
notification.IsRead = true;
|
notification.IsRead = true;
|
||||||
notification = await NotificationService.UpdateNotificationAsync(notification);
|
notification = await NotificationService.UpdateNotificationAsync(notification);
|
||||||
|
@ -81,11 +81,11 @@
|
|||||||
{
|
{
|
||||||
@if (p.Rows == 1)
|
@if (p.Rows == 1)
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" @attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
<textarea id="@p.Name" class="form-control" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" @attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)"></textarea>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -110,11 +110,11 @@
|
|||||||
{
|
{
|
||||||
@if (p.Rows == 1)
|
@if (p.Rows == 1)
|
||||||
{
|
{
|
||||||
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
|
<input id="@p.Name" class="form-control" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" @attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)" />
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
|
<textarea id="@p.Name" class="form-control" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" @attributes="@(p.MaxLength > 0 ? new Dictionary<string, object> {{"maxlength", p.MaxLength }} : null)"></textarea>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -132,7 +132,7 @@
|
|||||||
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
|
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private bool _initialized = false;
|
private bool _initialized = false;
|
||||||
private string _passwordrequirements;
|
private string _passwordrequirements;
|
||||||
private int userid;
|
private int userid;
|
||||||
@ -148,7 +148,7 @@
|
|||||||
private string lastipaddress;
|
private string lastipaddress;
|
||||||
|
|
||||||
private List<Profile> profiles;
|
private List<Profile> profiles;
|
||||||
private Dictionary<string, string> settings;
|
private Dictionary<string, string> userSettings;
|
||||||
private string category = string.Empty;
|
private string category = string.Empty;
|
||||||
|
|
||||||
private string createdby;
|
private string createdby;
|
||||||
@ -181,7 +181,7 @@
|
|||||||
lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn);
|
lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn);
|
||||||
lastipaddress = user.LastIPAddress;
|
lastipaddress = user.LastIPAddress;
|
||||||
|
|
||||||
settings = await SettingService.GetUserSettingsAsync(user.UserId);
|
userSettings = user.Settings;
|
||||||
createdby = user.CreatedBy;
|
createdby = user.CreatedBy;
|
||||||
createdon = user.CreatedOn;
|
createdon = user.CreatedOn;
|
||||||
modifiedby = user.ModifiedBy;
|
modifiedby = user.ModifiedBy;
|
||||||
@ -202,7 +202,7 @@
|
|||||||
|
|
||||||
private string GetProfileValue(string SettingName, string DefaultValue)
|
private string GetProfileValue(string SettingName, string DefaultValue)
|
||||||
{
|
{
|
||||||
string value = SettingService.GetSetting(settings, SettingName, DefaultValue);
|
string value = SettingService.GetSetting(userSettings, SettingName, DefaultValue);
|
||||||
if (value.Contains("]"))
|
if (value.Contains("]"))
|
||||||
{
|
{
|
||||||
value = value.Substring(value.IndexOf("]") + 1);
|
value = value.Substring(value.IndexOf("]") + 1);
|
||||||
@ -232,7 +232,7 @@
|
|||||||
user = await UserService.UpdateUserAsync(user);
|
user = await UserService.UpdateUserAsync(user);
|
||||||
if (user != null)
|
if (user != null)
|
||||||
{
|
{
|
||||||
await SettingService.UpdateUserSettingsAsync(settings, user.UserId);
|
await SettingService.UpdateUserSettingsAsync(userSettings, user.UserId);
|
||||||
await logger.LogInformation("User Saved {User}", user);
|
await logger.LogInformation("User Saved {User}", user);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
@ -266,7 +266,7 @@
|
|||||||
var value = GetProfileValue(profile.Name, string.Empty);
|
var value = GetProfileValue(profile.Name, string.Empty);
|
||||||
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
|
userSettings = SettingService.SetSetting(userSettings, profile.Name, profile.DefaultValue);
|
||||||
}
|
}
|
||||||
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
@ -293,7 +293,7 @@
|
|||||||
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
private void ProfileChanged(ChangeEventArgs e, string SettingName)
|
||||||
{
|
{
|
||||||
var value = (string)e.Value;
|
var value = (string)e.Value;
|
||||||
settings = SettingService.SetSetting(settings, SettingName, value);
|
userSettings = SettingService.SetSetting(userSettings, SettingName, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TogglePassword()
|
private void TogglePassword()
|
||||||
|
@ -98,17 +98,17 @@ namespace Oqtane.Modules
|
|||||||
var inline = 0;
|
var inline = 0;
|
||||||
foreach (Resource resource in resources)
|
foreach (Resource resource in resources)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(resource.RenderMode) || resource.RenderMode == RenderModes.Interactive)
|
if ((string.IsNullOrEmpty(resource.RenderMode) || resource.RenderMode == RenderModes.Interactive) && !resource.Reload)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(resource.Url))
|
if (!string.IsNullOrEmpty(resource.Url))
|
||||||
{
|
{
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
||||||
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module, location = resource.Location.ToString().ToLower() });
|
scripts.Add(new { href = url, type = resource.Type ?? "", bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", location = resource.Location.ToString().ToLower(), dataAttributes = resource.DataAttributes });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inline += 1;
|
inline += 1;
|
||||||
await interop.IncludeScript(GetType().Namespace.ToLower() + inline.ToString(), "", "", "", resource.Content, resource.Location.ToString().ToLower());
|
await interop.IncludeScript(GetType().Namespace.ToLower() + inline.ToString(), "", "", "", resource.Type ?? "", resource.Content, resource.Location.ToString().ToLower());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,4 +435,7 @@
|
|||||||
<data name="Functionality" xml:space="preserve">
|
<data name="Functionality" xml:space="preserve">
|
||||||
<value>Functionality</value>
|
<value>Functionality</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="System" xml:space="preserve">
|
||||||
|
<value>System</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -37,11 +37,8 @@
|
|||||||
public override List<Resource> Resources => new List<Resource>()
|
public override 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.3/css/bootstrap.min.css",
|
new Stylesheet("https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.3/css/bootstrap.min.css", "sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg==", "anonymous"),
|
||||||
Integrity = "sha512-jnSuA4Ss2PkkikSOLtYs8BlYIeeIK1h99ty4YfvRPAlzr377vr3CXDb7sb7eEEBYjDtcYj+AjBH3FLv5uSJuXg==",
|
new Stylesheet(ThemePath() + "Theme.css"),
|
||||||
CrossOrigin = "anonymous" },
|
new Script(Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous")
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = Constants.BootstrapScriptUrl, Integrity = Constants.BootstrapScriptIntegrity, CrossOrigin = "anonymous", Location = ResourceLocation.Body },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<LanguageSwitcher ButtonClass="@ButtonClass" DropdownAlignment="@LanguageDropdownAlignment" />
|
<LanguageSwitcher ButtonClass="@ButtonClass" DropdownAlignment="@LanguageDropdownAlignment" />
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (_showEditMode || (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered)))
|
@if (ShowEditMode && (_showEditMode || (PageState.Page.IsPersonalizable && PageState.User != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Registered))))
|
||||||
{
|
{
|
||||||
<form method="post" class="app-form-inline" @formname="EditModeForm" @onsubmit="@(async () => await ToggleEditMode(PageState.EditMode))" data-enhance>
|
<form method="post" class="app-form-inline" @formname="EditModeForm" @onsubmit="@(async () => await ToggleEditMode(PageState.EditMode))" data-enhance>
|
||||||
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
<input type="hidden" name="@Constants.RequestVerificationToken" value="@SiteState.AntiForgeryToken" />
|
||||||
@ -59,9 +59,15 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string LanguageDropdownAlignment { get; set; } = string.Empty; // Empty or Left or Right
|
public string LanguageDropdownAlignment { get; set; } = string.Empty; // Empty or Left or Right
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ability to hide the Edit Mode toggle button
|
||||||
|
/// </summary>
|
||||||
|
[Parameter]
|
||||||
|
public bool ShowEditMode { get; set; } = true;
|
||||||
|
|
||||||
private PageState _pageState;
|
private PageState _pageState;
|
||||||
private bool _canViewAdminDashboard = false;
|
private bool _canViewAdminDashboard = false;
|
||||||
private bool _showEditMode = false;
|
private bool _showEditMode = false; // internal state (not the same as ShowEditMode parameter)
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
@inject ILogService LoggingService
|
@inject ILogService LoggingService
|
||||||
@inject IStringLocalizer<ControlPanelInteractive> Localizer
|
@inject IStringLocalizer<ControlPanelInteractive> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
@inject IServiceProvider ServiceProvider
|
|
||||||
|
|
||||||
<button type="button" class="btn @ButtonClass ms-1" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel" @onclick="ClearMessage">
|
<button type="button" class="btn @ButtonClass ms-1" data-bs-toggle="offcanvas" data-bs-target="#offcanvasControlPanel" aria-controls="offcanvasControlPanel" @onclick="ClearMessage">
|
||||||
<span class="oi oi-cog"></span>
|
<span class="oi oi-cog"></span>
|
||||||
|
@ -17,11 +17,9 @@ namespace Oqtane.Themes.OqtaneTheme
|
|||||||
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/bootswatch/5.3.3/cyborg/bootstrap.min.css",
|
new Stylesheet("https://cdnjs.cloudflare.com/ajax/libs/bootswatch/5.3.3/cyborg/bootstrap.min.css", "sha512-M+Wrv9LTvQe81gFD2ZE3xxPTN5V2n1iLCXsldIxXvfs6tP+6VihBCwCMBkkjkQUZVmEHBsowb9Vqsq1et1teEg==", "anonymous"),
|
||||||
Integrity = "sha512-M+Wrv9LTvQe81gFD2ZE3xxPTN5V2n1iLCXsldIxXvfs6tP+6VihBCwCMBkkjkQUZVmEHBsowb9Vqsq1et1teEg==",
|
new Stylesheet("~/Theme.css"),
|
||||||
CrossOrigin = "anonymous" },
|
new Script(Constants.BootstrapScriptUrl, Constants.BootstrapScriptIntegrity, "anonymous")
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "~/Theme.css" },
|
|
||||||
new Resource { ResourceType = ResourceType.Script, Url = Constants.BootstrapScriptUrl, Integrity = Constants.BootstrapScriptIntegrity, CrossOrigin = "anonymous", Location = ResourceLocation.Body }
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -62,17 +62,17 @@ namespace Oqtane.Themes
|
|||||||
var inline = 0;
|
var inline = 0;
|
||||||
foreach (Resource resource in resources)
|
foreach (Resource resource in resources)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(resource.RenderMode) || resource.RenderMode == RenderModes.Interactive)
|
if ((string.IsNullOrEmpty(resource.RenderMode) || resource.RenderMode == RenderModes.Interactive) && !resource.Reload)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(resource.Url))
|
if (!string.IsNullOrEmpty(resource.Url))
|
||||||
{
|
{
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
||||||
scripts.Add(new { href = url, bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", es6module = resource.ES6Module, location = resource.Location.ToString().ToLower() });
|
scripts.Add(new { href = url, type = resource.Type ?? "", bundle = resource.Bundle ?? "", integrity = resource.Integrity ?? "", crossorigin = resource.CrossOrigin ?? "", location = resource.Location.ToString().ToLower(), dataAttributes = resource.DataAttributes });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
inline += 1;
|
inline += 1;
|
||||||
await interop.IncludeScript(GetType().Namespace.ToLower() + inline.ToString(), "", "", "", resource.Content, resource.Location.ToString().ToLower());
|
await interop.IncludeScript(GetType().Namespace.ToLower() + inline.ToString(), "", "", "", resource.Type ?? "", resource.Content, resource.Location.ToString().ToLower());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "HeadContent":
|
case "HeadContent":
|
||||||
var content = RemoveScripts(SiteState.Properties.HeadContent) + "\n";
|
var content = FormatScripts(SiteState.Properties.HeadContent) + "\n";
|
||||||
if (content != _content)
|
if (content != _content)
|
||||||
{
|
{
|
||||||
_content = content;
|
_content = content;
|
||||||
@ -51,16 +51,30 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string RemoveScripts(string headcontent)
|
private string FormatScripts(string headcontent)
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(headcontent) && RenderMode == RenderModes.Interactive)
|
if (!string.IsNullOrEmpty(headcontent))
|
||||||
{
|
{
|
||||||
var index = headcontent.IndexOf("<script");
|
var index = headcontent.IndexOf("<script");
|
||||||
while (index >= 0)
|
while (index >= 0)
|
||||||
{
|
{
|
||||||
headcontent = headcontent.Remove(index, headcontent.IndexOf("</script>") + 9 - index);
|
var script = headcontent.Substring(index, headcontent.IndexOf("</script>", index) - index + 9);
|
||||||
|
if (RenderMode == RenderModes.Interactive)
|
||||||
|
{
|
||||||
|
// remove scripts when interactive rendering
|
||||||
|
headcontent = headcontent.Remove(index, script.Length);
|
||||||
index = headcontent.IndexOf("<script");
|
index = headcontent.IndexOf("<script");
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!script.Contains("><") && !script.Contains("data-reload"))
|
||||||
|
{
|
||||||
|
// add data-reload attribute to inline script
|
||||||
|
headcontent = headcontent.Replace(script, script.Replace("<script", "<script data-reload=\"true\""));
|
||||||
|
}
|
||||||
|
index = headcontent.IndexOf("<script", index + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return headcontent;
|
return headcontent;
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,17 @@ namespace Oqtane.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string type, string content, string location)
|
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string type, string content, string location)
|
||||||
|
{
|
||||||
|
return IncludeScript(id, src, integrity, crossorigin, type, content, location, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task IncludeScript(string id, string src, string integrity, string crossorigin, string type, string content, string location, Dictionary<string, string> dataAttributes)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_jsRuntime.InvokeVoidAsync(
|
_jsRuntime.InvokeVoidAsync(
|
||||||
"Oqtane.Interop.includeScript",
|
"Oqtane.Interop.includeScript",
|
||||||
id, src, integrity, crossorigin, type, content, location);
|
id, src, integrity, crossorigin, type, content, location, dataAttributes);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
RenderFragment DynamicComponent { get; set; }
|
RenderFragment DynamicComponent { get; set; }
|
||||||
|
|
||||||
|
private string lastPagePath = "";
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
// handle page redirection
|
// handle page redirection
|
||||||
@ -90,8 +92,16 @@
|
|||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
if (!firstRender)
|
if (!firstRender && PageState.Page.Path != lastPagePath)
|
||||||
{
|
{
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Site.HeadContent) && PageState.Site.HeadContent.Contains("<script"))
|
||||||
|
{
|
||||||
|
await InjectScripts(PageState.Site.HeadContent, ResourceLocation.Head);
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Site.BodyContent) && PageState.Site.BodyContent.Contains("<script"))
|
||||||
|
{
|
||||||
|
await InjectScripts(PageState.Site.BodyContent, ResourceLocation.Body);
|
||||||
|
}
|
||||||
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
|
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
|
||||||
{
|
{
|
||||||
await InjectScripts(PageState.Page.HeadContent, ResourceLocation.Head);
|
await InjectScripts(PageState.Page.HeadContent, ResourceLocation.Head);
|
||||||
@ -100,6 +110,7 @@
|
|||||||
{
|
{
|
||||||
await InjectScripts(PageState.Page.BodyContent, ResourceLocation.Body);
|
await InjectScripts(PageState.Page.BodyContent, ResourceLocation.Body);
|
||||||
}
|
}
|
||||||
|
lastPagePath = PageState.Page.Path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// style sheets
|
// style sheets
|
||||||
@ -176,18 +187,20 @@
|
|||||||
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(), dataAttributes = dataAttributes });
|
scripts.Add(new { href = src, type = type, bundle = "", integrity = integrity, crossorigin = crossorigin, location = location.ToString().ToLower(), dataAttributes = dataAttributes });
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// inline script must have an id attribute
|
if (dataAttributes == null || !dataAttributes.ContainsKey("data-reload") || dataAttributes["data-reload"] != "false")
|
||||||
|
{
|
||||||
if (id == "")
|
if (id == "")
|
||||||
{
|
{
|
||||||
count += 1;
|
count += 1;
|
||||||
id = $"page{PageState.Page.PageId}-script{count}";
|
id = $"page{PageState.Page.PageId}-script{count}";
|
||||||
}
|
}
|
||||||
index = script.IndexOf(">") + 1;
|
var pos = script.IndexOf(">") + 1;
|
||||||
await interop.IncludeScript(id, "", "", "", "", script.Substring(index, script.IndexOf("</script>") - index), location.ToString().ToLower());
|
await interop.IncludeScript(id, "", "", "", type, script.Substring(pos, script.IndexOf("</script>") - pos), location.ToString().ToLower(), dataAttributes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
index = content.IndexOf("<script", index + 1);
|
index = content.IndexOf("<script", index + 1);
|
||||||
}
|
}
|
||||||
|
@ -29,12 +29,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
<NoWarn>1701;1702;EF1001;AD0001;NU1608</NoWarn>
|
<NoWarn>1701;1702;EF1001;AD0001</NoWarn>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
|
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
|
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0" />
|
||||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.1" />
|
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -36,7 +36,6 @@ if "%%~nxi" == "%%j" set /A found=1
|
|||||||
)
|
)
|
||||||
if not !found! == 1 rmdir /Q/S "%%i"
|
if not !found! == 1 rmdir /Q/S "%%i"
|
||||||
)
|
)
|
||||||
del "..\Oqtane.Server\bin\Release\net9.0\publish\Oqtane.Server.staticwebassets.endpoints.json"
|
|
||||||
del "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.json"
|
del "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.json"
|
||||||
ren "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.release.json" "appsettings.json"
|
ren "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.release.json" "appsettings.json"
|
||||||
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
|
||||||
|
@ -76,6 +76,10 @@
|
|||||||
|
|
||||||
@((MarkupString)_scripts)
|
@((MarkupString)_scripts)
|
||||||
@((MarkupString)_bodyResources)
|
@((MarkupString)_bodyResources)
|
||||||
|
@if (_renderMode == RenderModes.Static)
|
||||||
|
{
|
||||||
|
<page-script src="./js/reload.js"></page-script>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -188,9 +192,6 @@
|
|||||||
_scripts += CreateScrollPositionScript();
|
_scripts += CreateScrollPositionScript();
|
||||||
}
|
}
|
||||||
|
|
||||||
_headResources += ParseScripts(site.HeadContent);
|
|
||||||
_bodyResources += ParseScripts(site.BodyContent);
|
|
||||||
|
|
||||||
// set culture if not specified
|
// set culture if not specified
|
||||||
string cultureCookie = Context.Request.Cookies[Shared.CookieRequestCultureProvider.DefaultCookieName];
|
string cultureCookie = Context.Request.Cookies[Shared.CookieRequestCultureProvider.DefaultCookieName];
|
||||||
if (cultureCookie == null)
|
if (cultureCookie == null)
|
||||||
@ -510,26 +511,10 @@
|
|||||||
"</script>" + Environment.NewLine;
|
"</script>" + Environment.NewLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ParseScripts(string content)
|
|
||||||
{
|
|
||||||
var scripts = "";
|
|
||||||
// in interactive render mode, parse scripts from content and inject into page
|
|
||||||
if (_renderMode == RenderModes.Interactive && !string.IsNullOrEmpty(content))
|
|
||||||
{
|
|
||||||
var index = content.IndexOf("<script");
|
|
||||||
while (index >= 0)
|
|
||||||
{
|
|
||||||
scripts += content.Substring(index, content.IndexOf("</script>", index) + 9 - index);
|
|
||||||
index = content.IndexOf("<script", index + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return scripts;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void AddScript(Resource resource, Alias alias)
|
private void AddScript(Resource resource, Alias alias)
|
||||||
{
|
{
|
||||||
var script = CreateScript(resource, alias);
|
var script = CreateScript(resource, alias);
|
||||||
if (resource.Location == Shared.ResourceLocation.Head)
|
if (resource.Location == Shared.ResourceLocation.Head && !resource.Reload)
|
||||||
{
|
{
|
||||||
if (!_headResources.Contains(script))
|
if (!_headResources.Contains(script))
|
||||||
{
|
{
|
||||||
@ -546,38 +531,31 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string CreateScript(Resource resource, Alias alias)
|
private string CreateScript(Resource resource, Alias alias)
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(resource.Url))
|
|
||||||
{
|
{
|
||||||
if (!resource.Reload)
|
if (!resource.Reload)
|
||||||
{
|
{
|
||||||
var url = (resource.Url.Contains("://")) ? resource.Url : alias.BaseUrl + resource.Url;
|
var url = (resource.Url.Contains("://")) ? resource.Url : alias.BaseUrl + resource.Url;
|
||||||
return "<script" +
|
|
||||||
|
var dataAttributes = "";
|
||||||
|
if (resource.DataAttributes != null && resource.DataAttributes.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var attribute in resource.DataAttributes)
|
||||||
|
{
|
||||||
|
dataAttributes += " " + attribute.Key + "=\"" + attribute.Value + "\"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<script src=\"" + url + "\"" +
|
||||||
|
((!string.IsNullOrEmpty(resource.Type)) ? " type=\"" + resource.Type + "\"" : "") +
|
||||||
((!string.IsNullOrEmpty(resource.Integrity)) ? " integrity=\"" + resource.Integrity + "\"" : "") +
|
((!string.IsNullOrEmpty(resource.Integrity)) ? " integrity=\"" + resource.Integrity + "\"" : "") +
|
||||||
((!string.IsNullOrEmpty(resource.CrossOrigin)) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") +
|
((!string.IsNullOrEmpty(resource.CrossOrigin)) ? " crossorigin=\"" + resource.CrossOrigin + "\"" : "") +
|
||||||
((resource.ES6Module) ? " type=\"module\"" : "") +
|
((!string.IsNullOrEmpty(dataAttributes)) ? dataAttributes : "") +
|
||||||
" src=\"" + url + "\"></script>"; // src at end of element due to enhanced navigation patch algorithm
|
"></script>";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
// use custom element which can execute script on every page transition
|
|
||||||
@if (string.IsNullOrEmpty(resource.Integrity) && string.IsNullOrEmpty(resource.CrossOrigin))
|
|
||||||
{
|
{
|
||||||
return "<page-script src=\"" + resource.Url + "\"></page-script>";
|
return "<page-script src=\"" + resource.Url + "\"></page-script>";
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
// use modulepreload for external resources
|
|
||||||
return "<link rel=\"modulepreload\" href=\"" + resource.Url + "\" integrity=\"" + resource.Integrity + "\" crossorigin=\"" + resource.CrossOrigin + "\" />\n" +
|
|
||||||
"<page-script src=\"" + resource.Url + "\"></page-script>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// inline script
|
|
||||||
return "<script>" + resource.Content + "</script>";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetLocalizationCookie(string cookieValue)
|
private void SetLocalizationCookie(string cookieValue)
|
||||||
|
@ -183,7 +183,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
if (ModelState.IsValid && notification.SiteId == _alias.SiteId && notification.NotificationId == id && _notifications.GetNotification(notification.NotificationId, false) != null && (IsAuthorized(notification.FromUserId) || IsAuthorized(notification.ToUserId)))
|
if (ModelState.IsValid && notification.SiteId == _alias.SiteId && notification.NotificationId == id && _notifications.GetNotification(notification.NotificationId, false) != null && (IsAuthorized(notification.FromUserId) || IsAuthorized(notification.ToUserId)))
|
||||||
{
|
{
|
||||||
if (!User.IsInRole(RoleNames.Admin))
|
if (!User.IsInRole(RoleNames.Admin) && notification.FromUserId != null)
|
||||||
{
|
{
|
||||||
// content must be HTML encoded for non-admins to prevent HTML injection
|
// content must be HTML encoded for non-admins to prevent HTML injection
|
||||||
notification.Subject = WebUtility.HtmlEncode(notification.Subject);
|
notification.Subject = WebUtility.HtmlEncode(notification.Subject);
|
||||||
@ -223,7 +223,7 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
private bool IsAuthorized(int? userid)
|
private bool IsAuthorized(int? userid)
|
||||||
{
|
{
|
||||||
bool authorized = true;
|
bool authorized = false;
|
||||||
if (userid != null)
|
if (userid != null)
|
||||||
{
|
{
|
||||||
authorized = (_userPermissions.GetUser(User).UserId == userid);
|
authorized = (_userPermissions.GetUser(User).UserId == userid);
|
||||||
|
@ -9,7 +9,7 @@ using System.Net;
|
|||||||
using Oqtane.Enums;
|
using Oqtane.Enums;
|
||||||
using Oqtane.Infrastructure;
|
using Oqtane.Infrastructure;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using System.IO;
|
using System;
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
|
@ -269,11 +269,7 @@ namespace Oqtane.Controllers
|
|||||||
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, permissionName);
|
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, permissionName);
|
||||||
break;
|
break;
|
||||||
case EntityNames.User:
|
case EntityNames.User:
|
||||||
authorized = true;
|
|
||||||
if (permissionName == PermissionNames.Edit)
|
|
||||||
{
|
|
||||||
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, -1, PermissionNames.Write, RoleNames.Admin) || (_userPermissions.GetUser(User).UserId == entityId);
|
authorized = _userPermissions.IsAuthorized(User, _alias.SiteId, entityName, -1, PermissionNames.Write, RoleNames.Admin) || (_userPermissions.GetUser(User).UserId == entityId);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case EntityNames.Visitor:
|
case EntityNames.Visitor:
|
||||||
authorized = User.IsInRole(RoleNames.Admin);
|
authorized = User.IsInRole(RoleNames.Admin);
|
||||||
@ -319,7 +315,7 @@ namespace Oqtane.Controllers
|
|||||||
filter = !_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, PermissionNames.Edit);
|
filter = !_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, entityId, PermissionNames.Edit);
|
||||||
break;
|
break;
|
||||||
case EntityNames.User:
|
case EntityNames.User:
|
||||||
filter = !User.IsInRole(RoleNames.Admin) && _userPermissions.GetUser(User).UserId != entityId;
|
filter = !_userPermissions.IsAuthorized(User, _alias.SiteId, entityName, -1, PermissionNames.Write, RoleNames.Admin) && _userPermissions.GetUser(User).UserId != entityId;
|
||||||
break;
|
break;
|
||||||
case EntityNames.Visitor:
|
case EntityNames.Visitor:
|
||||||
if (!User.IsInRole(RoleNames.Admin))
|
if (!User.IsInRole(RoleNames.Admin))
|
||||||
|
@ -28,9 +28,10 @@ namespace Oqtane.Controllers
|
|||||||
private readonly IJwtManager _jwtManager;
|
private readonly IJwtManager _jwtManager;
|
||||||
private readonly IFileRepository _files;
|
private readonly IFileRepository _files;
|
||||||
private readonly ISettingRepository _settings;
|
private readonly ISettingRepository _settings;
|
||||||
|
private readonly ISyncManager _syncManager;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
|
|
||||||
public UserController(IUserRepository users, ITenantManager tenantManager, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, IFileRepository files, ISettingRepository settings, ILogManager logger)
|
public UserController(IUserRepository users, ITenantManager tenantManager, IUserManager userManager, ISiteRepository sites, IUserPermissions userPermissions, IJwtManager jwtManager, IFileRepository files, ISettingRepository settings, ISyncManager syncManager, ILogManager logger)
|
||||||
{
|
{
|
||||||
_users = users;
|
_users = users;
|
||||||
_tenantManager = tenantManager;
|
_tenantManager = tenantManager;
|
||||||
@ -40,6 +41,7 @@ namespace Oqtane.Controllers
|
|||||||
_jwtManager = jwtManager;
|
_jwtManager = jwtManager;
|
||||||
_files = files;
|
_files = files;
|
||||||
_settings = settings;
|
_settings = settings;
|
||||||
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,20 +147,7 @@ namespace Oqtane.Controllers
|
|||||||
filtered.DeletedBy = user.DeletedBy;
|
filtered.DeletedBy = user.DeletedBy;
|
||||||
filtered.DeletedOn = user.DeletedOn;
|
filtered.DeletedOn = user.DeletedOn;
|
||||||
filtered.IsDeleted = user.IsDeleted;
|
filtered.IsDeleted = user.IsDeleted;
|
||||||
}
|
filtered.Settings = user.Settings; // include all settings
|
||||||
|
|
||||||
// if authenticated user is accessing their own user account
|
|
||||||
if (_userPermissions.GetUser(User).UserId == user.UserId)
|
|
||||||
{
|
|
||||||
// include all settings
|
|
||||||
filtered.Settings = user.Settings;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// include only public settings
|
|
||||||
filtered.Settings = _settings.GetSettings(EntityNames.User, user.UserId)
|
|
||||||
.Where(item => !item.IsPrivate)
|
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +255,7 @@ namespace Oqtane.Controllers
|
|||||||
if (_userPermissions.GetUser(User).UserId == user.UserId)
|
if (_userPermissions.GetUser(User).UserId == user.UserId)
|
||||||
{
|
{
|
||||||
await HttpContext.SignOutAsync(Constants.AuthenticationScheme);
|
await HttpContext.SignOutAsync(Constants.AuthenticationScheme);
|
||||||
|
_syncManager.AddSyncEvent(_tenantManager.GetAlias(), EntityNames.User, user.UserId, "Logout");
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Logout {Username}", (user != null) ? user.Username : "");
|
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Logout {Username}", (user != null) ? user.Username : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -279,6 +269,7 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
await _userManager.LogoutUserEverywhere(user);
|
await _userManager.LogoutUserEverywhere(user);
|
||||||
await HttpContext.SignOutAsync(Constants.AuthenticationScheme);
|
await HttpContext.SignOutAsync(Constants.AuthenticationScheme);
|
||||||
|
_syncManager.AddSyncEvent(_tenantManager.GetAlias(), EntityNames.User, user.UserId, "Logout");
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Logout Everywhere {Username}", (user != null) ? user.Username : "");
|
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Logout Everywhere {Username}", (user != null) ? user.Username : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ using System.Linq;
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using System;
|
using System;
|
||||||
using Oqtane.Modules.Admin.Roles;
|
|
||||||
|
|
||||||
namespace Oqtane.Controllers
|
namespace Oqtane.Controllers
|
||||||
{
|
{
|
||||||
@ -40,12 +39,14 @@ namespace Oqtane.Controllers
|
|||||||
public IEnumerable<UserRole> Get(string siteid, string userid = null, string rolename = null)
|
public IEnumerable<UserRole> Get(string siteid, string userid = null, string rolename = null)
|
||||||
{
|
{
|
||||||
int SiteId;
|
int SiteId;
|
||||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId && (userid != null || rolename != null))
|
int UserId = -1;
|
||||||
|
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId && (userid != null && int.TryParse(userid, out UserId) || rolename != null))
|
||||||
|
{
|
||||||
|
if (IsAuthorized(UserId, rolename))
|
||||||
{
|
{
|
||||||
var userroles = _userRoles.GetUserRoles(SiteId).ToList();
|
var userroles = _userRoles.GetUserRoles(SiteId).ToList();
|
||||||
if (userid != null)
|
if (UserId != -1)
|
||||||
{
|
{
|
||||||
int UserId = int.TryParse(userid, out UserId) ? UserId : -1;
|
|
||||||
userroles = userroles.Where(item => item.UserId == UserId).ToList();
|
userroles = userroles.Where(item => item.UserId == UserId).ToList();
|
||||||
}
|
}
|
||||||
if (rolename != null)
|
if (rolename != null)
|
||||||
@ -58,6 +59,14 @@ namespace Oqtane.Controllers
|
|||||||
userroles[i] = Filter(userroles[i], user.UserId);
|
userroles[i] = Filter(userroles[i], user.UserId);
|
||||||
}
|
}
|
||||||
return userroles.OrderBy(u => u.User.DisplayName);
|
return userroles.OrderBy(u => u.User.DisplayName);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized UserRole Get Attempt For Site {SiteId} User {UserId} Role {RoleName}", siteid, userid, rolename);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -73,7 +82,7 @@ namespace Oqtane.Controllers
|
|||||||
public UserRole Get(int id)
|
public UserRole Get(int id)
|
||||||
{
|
{
|
||||||
var userrole = _userRoles.GetUserRole(id);
|
var userrole = _userRoles.GetUserRole(id);
|
||||||
if (userrole != null && SiteValid(userrole.Role.SiteId))
|
if (userrole != null && SiteValid(userrole.Role.SiteId) && IsAuthorized(userrole.UserId, userrole.Role.Name))
|
||||||
{
|
{
|
||||||
return Filter(userrole, _userPermissions.GetUser().UserId);
|
return Filter(userrole, _userPermissions.GetUser().UserId);
|
||||||
}
|
}
|
||||||
@ -92,33 +101,57 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsAuthorized(int userId, string roleName)
|
||||||
|
{
|
||||||
|
bool authorized = true;
|
||||||
|
if (userId != -1)
|
||||||
|
{
|
||||||
|
authorized = _userPermissions.GetUser(User).UserId == userId;
|
||||||
|
}
|
||||||
|
if (authorized && !string.IsNullOrEmpty(roleName))
|
||||||
|
{
|
||||||
|
authorized = User.IsInRole(roleName);
|
||||||
|
}
|
||||||
|
return authorized;
|
||||||
|
}
|
||||||
|
|
||||||
private UserRole Filter(UserRole userrole, int userid)
|
private UserRole Filter(UserRole userrole, int userid)
|
||||||
{
|
{
|
||||||
|
// clone object to avoid mutating cache
|
||||||
|
UserRole filtered = null;
|
||||||
|
|
||||||
if (userrole != null)
|
if (userrole != null)
|
||||||
{
|
{
|
||||||
userrole.User.Password = "";
|
filtered = new UserRole();
|
||||||
userrole.User.IsAuthenticated = false;
|
|
||||||
userrole.User.TwoFactorCode = "";
|
|
||||||
userrole.User.TwoFactorExpiry = null;
|
|
||||||
|
|
||||||
if (!_userPermissions.IsAuthorized(User, userrole.User.SiteId, EntityNames.User, -1, PermissionNames.Write, RoleNames.Admin) && userid != userrole.User.UserId)
|
// public properties
|
||||||
|
filtered.UserRoleId = userrole.UserRoleId;
|
||||||
|
filtered.UserId = userrole.UserId;
|
||||||
|
filtered.RoleId = userrole.RoleId;
|
||||||
|
|
||||||
|
filtered.User = new User();
|
||||||
|
filtered.User.SiteId = userrole.User.SiteId;
|
||||||
|
filtered.User.UserId = userrole.User.UserId;
|
||||||
|
filtered.User.Username = userrole.User.Username;
|
||||||
|
filtered.User.DisplayName = userrole.User.DisplayName;
|
||||||
|
|
||||||
|
filtered.Role = new Role();
|
||||||
|
filtered.Role.SiteId = userrole.Role.SiteId;
|
||||||
|
filtered.Role.RoleId = userrole.Role.RoleId;
|
||||||
|
filtered.Role.Name = userrole.Role.Name;
|
||||||
|
|
||||||
|
// include private properties if administrator
|
||||||
|
if (_userPermissions.IsAuthorized(User, filtered.User.SiteId, EntityNames.UserRole, -1, PermissionNames.Write, RoleNames.Admin))
|
||||||
{
|
{
|
||||||
userrole.User.Email = "";
|
filtered.User.Email = userrole.User.Email;
|
||||||
userrole.User.PhotoFileId = null;
|
filtered.User.PhotoFileId = userrole.User.PhotoFileId;
|
||||||
userrole.User.LastLoginOn = DateTime.MinValue;
|
filtered.User.LastLoginOn = userrole.User.LastLoginOn;
|
||||||
userrole.User.LastIPAddress = "";
|
filtered.User.LastIPAddress = userrole.User.LastIPAddress;
|
||||||
userrole.User.Roles = "";
|
filtered.User.CreatedOn = userrole.User.CreatedOn;
|
||||||
userrole.User.CreatedBy = "";
|
|
||||||
userrole.User.CreatedOn = DateTime.MinValue;
|
|
||||||
userrole.User.ModifiedBy = "";
|
|
||||||
userrole.User.ModifiedOn = DateTime.MinValue;
|
|
||||||
userrole.User.DeletedBy = "";
|
|
||||||
userrole.User.DeletedOn = DateTime.MinValue;
|
|
||||||
userrole.User.IsDeleted = false;
|
|
||||||
userrole.User.TwoFactorRequired = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return userrole;
|
|
||||||
|
return filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
// POST api/<controller>
|
// POST api/<controller>
|
||||||
|
@ -645,6 +645,9 @@ namespace Oqtane.Extensions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _syncManager = httpContext.RequestServices.GetRequiredService<ISyncManager>();
|
||||||
|
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, "Login");
|
||||||
|
|
||||||
_logger.Log(LogLevel.Information, "ExternalLogin", Enums.LogFunction.Security, "External User Login Successful For {Username} From IP Address {IPAddress} Using Provider {Provider}", user.Username, httpContext.Connection.RemoteIpAddress.ToString(), providerName);
|
_logger.Log(LogLevel.Information, "ExternalLogin", Enums.LogFunction.Security, "External User Login Successful For {Username} From IP Address {IPAddress} Using Provider {Provider}", user.Username, httpContext.Connection.RemoteIpAddress.ToString(), providerName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ namespace Oqtane.Infrastructure
|
|||||||
if (userid != null && username != null)
|
if (userid != null && username != null)
|
||||||
{
|
{
|
||||||
var _users = context.RequestServices.GetService(typeof(IUserManager)) as IUserManager;
|
var _users = context.RequestServices.GetService(typeof(IUserManager)) as IUserManager;
|
||||||
var user = _users.GetUser(userid, alias.SiteId); // cached
|
var user = _users.GetUser(int.Parse(userid), alias.SiteId); // cached
|
||||||
if (user != null && !user.IsDeleted)
|
if (user != null && !user.IsDeleted)
|
||||||
{
|
{
|
||||||
var claimsidentity = UserSecurity.CreateClaimsIdentity(alias, user);
|
var claimsidentity = UserSecurity.CreateClaimsIdentity(alias, user);
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
using Oqtane.Models;
|
using Oqtane.Models;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
@ -17,12 +17,14 @@ namespace Oqtane.Infrastructure
|
|||||||
private readonly IServiceScopeFactory _serviceScopeFactory;
|
private readonly IServiceScopeFactory _serviceScopeFactory;
|
||||||
private readonly IWebHostEnvironment _environment;
|
private readonly IWebHostEnvironment _environment;
|
||||||
private readonly IConfigManager _configManager;
|
private readonly IConfigManager _configManager;
|
||||||
|
private readonly ILogger<UpgradeManager> _filelogger;
|
||||||
|
|
||||||
public UpgradeManager(IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment, IConfigManager configManager)
|
public UpgradeManager(IServiceScopeFactory serviceScopeFactory, IWebHostEnvironment environment, IConfigManager configManager, ILogger<UpgradeManager> filelogger)
|
||||||
{
|
{
|
||||||
_serviceScopeFactory = serviceScopeFactory;
|
_serviceScopeFactory = serviceScopeFactory;
|
||||||
_environment = environment;
|
_environment = environment;
|
||||||
_configManager = configManager;
|
_configManager = configManager;
|
||||||
|
_filelogger = filelogger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Upgrade(Tenant tenant, string version)
|
public void Upgrade(Tenant tenant, string version)
|
||||||
@ -91,7 +93,7 @@ namespace Oqtane.Infrastructure
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// error deleting directory
|
// error deleting directory
|
||||||
Debug.WriteLine($"Oqtane Error: Error In 2.0.2 Upgrade Logic - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: Error In 2.0.2 Upgrade Logic - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +111,7 @@ namespace Oqtane.Infrastructure
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// error populating guid
|
// error populating guid
|
||||||
Debug.WriteLine($"Oqtane Error: Error In 2.0.2 Upgrade Logic - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: Error In 2.0.2 Upgrade Logic - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,7 +279,7 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"Oqtane Error: Error In 3.2.0 Upgrade Logic - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: Error In 3.2.0 Upgrade Logic - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +315,7 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"Oqtane Error: Error In 3.2.1 Upgrade Logic - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: Error In 3.2.1 Upgrade Logic - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +359,7 @@ namespace Oqtane.Infrastructure
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Debug.WriteLine($"Oqtane Error: Error In 3.3.0 Upgrade Logic - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: Error In 3.3.0 Upgrade Logic - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +386,7 @@ namespace Oqtane.Infrastructure
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// error deleting file
|
// error deleting file
|
||||||
Debug.WriteLine($"Oqtane Error: Error In 5.1.0 Upgrade Logic - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: Error In 5.1.0 Upgrade Logic - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -487,7 +489,7 @@ namespace Oqtane.Infrastructure
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// error deleting asesmbly
|
// error deleting asesmbly
|
||||||
Debug.WriteLine($"Oqtane Error: 6.0.1 Upgrade Error Removing {assembly} - {ex}");
|
_filelogger.LogError(Utilities.LogMessage(this, $"Oqtane Error: 6.0.1 Upgrade Error Removing {assembly} - {ex}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -374,6 +374,8 @@ namespace Oqtane.Managers
|
|||||||
_users.UpdateUser(user);
|
_users.UpdateUser(user);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Login Successful For {Username} From IP Address {IPAddress}", user.Username, LastIPAddress);
|
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Login Successful For {Username} From IP Address {IPAddress}", user.Username, LastIPAddress);
|
||||||
|
|
||||||
|
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, "Login");
|
||||||
|
|
||||||
if (setCookie)
|
if (setCookie)
|
||||||
{
|
{
|
||||||
await _identitySignInManager.SignInAsync(identityuser, isPersistent);
|
await _identitySignInManager.SignInAsync(identityuser, isPersistent);
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
<DefineConstants>$(DefineConstants);OQTANE;OQTANE3</DefineConstants>
|
<DefineConstants>$(DefineConstants);OQTANE;OQTANE3</DefineConstants>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>none</SatelliteResourceLanguages>
|
||||||
|
<CompressionEnabled>false</CompressionEnabled>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Remove="wwwroot\Modules\Templates\**" />
|
<Compile Remove="wwwroot\Modules\Templates\**" />
|
||||||
|
@ -35,6 +35,7 @@ namespace Oqtane.Pages
|
|||||||
{
|
{
|
||||||
await _userManager.LogoutUserEverywhere(user);
|
await _userManager.LogoutUserEverywhere(user);
|
||||||
}
|
}
|
||||||
|
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, "Logout");
|
||||||
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, SyncEventActions.Reload);
|
_syncManager.AddSyncEvent(alias, EntityNames.User, user.UserId, SyncEventActions.Reload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -31,7 +32,47 @@ namespace Oqtane.Repository
|
|||||||
{
|
{
|
||||||
page.PermissionList = permissions.Where(item => item.EntityId == page.PageId).ToList();
|
page.PermissionList = permissions.Where(item => item.EntityId == page.PageId).ToList();
|
||||||
}
|
}
|
||||||
return pages;
|
return GetPagesHierarchy(pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Page> GetPagesHierarchy(List<Page> pages)
|
||||||
|
{
|
||||||
|
List<Page> hierarchy = new List<Page>();
|
||||||
|
Action<List<Page>, Page> getPath = null;
|
||||||
|
getPath = (pageList, page) =>
|
||||||
|
{
|
||||||
|
IEnumerable<Page> children;
|
||||||
|
int level;
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
|
level = -1;
|
||||||
|
children = pages.Where(item => item.ParentId == null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
level = page.Level;
|
||||||
|
children = pages.Where(item => item.ParentId == page.PageId);
|
||||||
|
}
|
||||||
|
foreach (Page child in children)
|
||||||
|
{
|
||||||
|
child.Level = level + 1;
|
||||||
|
child.HasChildren = pages.Any(item => item.ParentId == child.PageId && !item.IsDeleted && item.IsNavigation);
|
||||||
|
hierarchy.Add(child);
|
||||||
|
getPath(pageList, child);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
pages = pages.OrderBy(item => item.Order).ToList();
|
||||||
|
getPath(pages, null);
|
||||||
|
|
||||||
|
// add any non-hierarchical items to the end of the list
|
||||||
|
foreach (Page page in pages)
|
||||||
|
{
|
||||||
|
if (hierarchy.Find(item => item.PageId == page.PageId) == null)
|
||||||
|
{
|
||||||
|
hierarchy.Add(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hierarchy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Page AddPage(Page page)
|
public Page AddPage(Page page)
|
||||||
|
@ -127,7 +127,6 @@ namespace Oqtane.Services
|
|||||||
.ToDictionary(setting => setting.SettingName, setting => (setting.IsPrivate ? _private : "") + setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => (setting.IsPrivate ? _private : "") + setting.SettingValue);
|
||||||
site.Pages.Add(page);
|
site.Pages.Add(page);
|
||||||
}
|
}
|
||||||
site.Pages = GetPagesHierarchy(site.Pages);
|
|
||||||
|
|
||||||
// framework modules
|
// framework modules
|
||||||
var modules = GetPageModules(site.SiteId);
|
var modules = GetPageModules(site.SiteId);
|
||||||
|
@ -20,10 +20,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="debug.cmd" />
|
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="debug.cmd $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="bash $(ProjectDir)debug.sh" />
|
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="bash $(ProjectDir)debug.sh $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Release'" Command="release.cmd" />
|
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Release'" Command="release.cmd $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Release'" Command="bash $(ProjectDir)release.sh" />
|
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Release'" Command="bash $(ProjectDir)release.sh $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>[Owner].Module.[Module]</id>
|
<id>$projectname$</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<authors>[Owner]</authors>
|
<authors>[Owner]</authors>
|
||||||
<owners>[Owner]</owners>
|
<owners>[Owner]</owners>
|
||||||
@ -20,12 +20,12 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Client\bin\Release\net9.0\[Owner].Module.[Module].Client.Oqtane.dll" target="lib\net9.0" />
|
<file src="..\Client\bin\Release\$targetframework$\$ProjectName$.Client.Oqtane.dll" target="lib\$targetframework$" />
|
||||||
<file src="..\Client\bin\Release\net9.0\[Owner].Module.[Module].Client.Oqtane.pdb" target="lib\net9.0" />
|
<file src="..\Client\bin\Release\$targetframework$\$ProjectName$.Client.Oqtane.pdb" target="lib\$targetframework$" />
|
||||||
<file src="..\Server\bin\Release\net9.0\[Owner].Module.[Module].Server.Oqtane.dll" target="lib\net9.0" />
|
<file src="..\Server\bin\Release\$targetframework$\$ProjectName$.Server.Oqtane.dll" target="lib\$targetframework$" />
|
||||||
<file src="..\Server\bin\Release\net9.0\[Owner].Module.[Module].Server.Oqtane.pdb" target="lib\net9.0" />
|
<file src="..\Server\bin\Release\$targetframework$\$ProjectName$.Server.Oqtane.pdb" target="lib\$targetframework$" />
|
||||||
<file src="..\Shared\bin\Release\net9.0\[Owner].Module.[Module].Shared.Oqtane.dll" target="lib\net9.0" />
|
<file src="..\Shared\bin\Release\$targetframework$\$ProjectName$.Shared.Oqtane.dll" target="lib\$targetframework$" />
|
||||||
<file src="..\Shared\bin\Release\net9.0\[Owner].Module.[Module].Shared.Oqtane.pdb" target="lib\net9.0" />
|
<file src="..\Shared\bin\Release\$targetframework$\$ProjectName$.Shared.Oqtane.pdb" target="lib\$targetframework$" />
|
||||||
<file src="..\Server\wwwroot\**\*.*" target="wwwroot" />
|
<file src="..\Server\wwwroot\**\*.*" target="wwwroot" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
XCOPY "..\Client\bin\Debug\net9.0\[Owner].Module.[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
@echo off
|
||||||
XCOPY "..\Client\bin\Debug\net9.0\[Owner].Module.[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
set TargetFramework=%1
|
||||||
XCOPY "..\Server\bin\Debug\net9.0\[Owner].Module.[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
set ProjectName=%2
|
||||||
XCOPY "..\Server\bin\Debug\net9.0\[Owner].Module.[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
|
||||||
XCOPY "..\Shared\bin\Debug\net9.0\[Owner].Module.[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
XCOPY "..\Client\bin\Debug\%TargetFramework%\%ProjectName%.Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
XCOPY "..\Shared\bin\Debug\net9.0\[Owner].Module.[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
XCOPY "..\Client\bin\Debug\%TargetFramework%\%ProjectName%.Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
|
XCOPY "..\Server\bin\Debug\%TargetFramework%\%ProjectName%.Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
|
XCOPY "..\Server\bin\Debug\%TargetFramework%\%ProjectName%.Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
|
XCOPY "..\Shared\bin\Debug\%TargetFramework%\%ProjectName%.Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
|
XCOPY "..\Shared\bin\Debug\%TargetFramework%\%ProjectName%.Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
XCOPY "..\Server\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I
|
XCOPY "..\Server\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I
|
@ -1,7 +1,12 @@
|
|||||||
cp -f "../Client/bin/Debug/net9.0/[Owner].Module.[Module].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
#!/bin/bash
|
||||||
cp -f "../Client/bin/Debug/net9.0/[Owner].Module.[Module].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
|
||||||
cp -f "../Server/bin/Debug/net9.0/[Owner].Module.[Module].Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
TargetFramework=$1
|
||||||
cp -f "../Server/bin/Debug/net9.0/[Owner].Module.[Module].Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
ProjectName=$2
|
||||||
cp -f "../Shared/bin/Debug/net9.0/[Owner].Module.[Module].Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
|
||||||
cp -f "../Shared/bin/Debug/net9.0/[Owner].Module.[Module].Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.dll" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/"
|
cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.pdb" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName$.Server.Oqtane.dll" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -f "../Server/bin/Debug/$TargetFramework/$ProjectName$.Server.Oqtane.pdb" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName$.Shared.Oqtane.dll" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -f "../Shared/bin/Debug/$TargetFramework/$ProjectName$.Shared.Oqtane.pdb" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -rf "../Server/wwwroot/"* "../../[RootFolder]/Oqtane.Server/wwwroot/"
|
@ -1,4 +1,7 @@
|
|||||||
del "*.nupkg"
|
@echo off
|
||||||
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack [Owner].Module.[Module].nuspec
|
set TargetFramework=%1
|
||||||
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\Packages\" /Y
|
set ProjectName=%2
|
||||||
|
|
||||||
|
del "*.nupkg"
|
||||||
|
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
|
||||||
|
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\Packages\" /Y
|
@ -1,2 +1,5 @@
|
|||||||
"..\..\oqtane.framework\oqtane.package\nuget.exe" pack [Owner].Module.[Module].nuspec
|
TargetFramework=$1
|
||||||
cp -f "*.nupkg" "..\..\oqtane.framework\Oqtane.Server\Packages\"
|
ProjectName=$2
|
||||||
|
|
||||||
|
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
|
||||||
|
cp -f "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\Packages\"
|
@ -18,10 +18,10 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
<Target Name="PostBuild" AfterTargets="PostBuildEvent">
|
||||||
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="debug.cmd" />
|
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="debug.cmd $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="bash $(ProjectDir)debug.sh" />
|
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Debug'" Command="bash $(ProjectDir)debug.sh $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Release'" Command="release.cmd" />
|
<Exec Condition="'$(OS)' == 'Windows_NT' And '$(Configuration)' == 'Release'" Command="release.cmd $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Release'" Command="bash $(ProjectDir)release.sh" />
|
<Exec Condition="'$(OS)' != 'Windows_NT' And '$(Configuration)' == 'Release'" Command="bash $(ProjectDir)release.sh $(TargetFramework) $([System.String]::Copy('$(MSBuildProjectName)').Replace('.Package',''))" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||||
<metadata>
|
<metadata>
|
||||||
<id>[Owner].Theme.[Theme]</id>
|
<id>$projectname$</id>
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
<authors>[Owner]</authors>
|
<authors>[Owner]</authors>
|
||||||
<owners>[Owner]</owners>
|
<owners>[Owner]</owners>
|
||||||
@ -20,8 +20,8 @@
|
|||||||
</dependencies>
|
</dependencies>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
<file src="..\Client\bin\Release\net9.0\[Owner].Theme.[Theme].Client.Oqtane.dll" target="lib\net9.0" />
|
<file src="..\Client\bin\Release\$targetframework$\$projectname$.Client.Oqtane.dll" target="lib\$targetframework$" />
|
||||||
<file src="..\Client\bin\Release\net9.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" target="lib\net9.0" />
|
<file src="..\Client\bin\Release\$targetframework$\$projectname$.Client.Oqtane.pdb" target="lib\$targetframework$" />
|
||||||
<file src="..\Client\wwwroot\**\*.*" target="wwwroot" />
|
<file src="..\Client\wwwroot\**\*.*" target="wwwroot" />
|
||||||
<file src="icon.png" target="" />
|
<file src="icon.png" target="" />
|
||||||
</files>
|
</files>
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
XCOPY "..\Client\bin\Debug\net9.0\[Owner].Theme.[Theme].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
@echo off
|
||||||
XCOPY "..\Client\bin\Debug\net9.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net9.0\" /Y
|
set TargetFramework=%1
|
||||||
|
set ProjectName=%2
|
||||||
|
|
||||||
|
XCOPY "..\Client\bin\Debug\%TargetFramework%\%ProjectName%.Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
|
XCOPY "..\Client\bin\Debug\%TargetFramework%\%ProjectName%.Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\%TargetFramework%\" /Y
|
||||||
XCOPY "..\Client\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I
|
XCOPY "..\Client\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I
|
@ -1,3 +1,8 @@
|
|||||||
cp -f "../Client/bin/Debug/net9.0/[Owner].Theme.[Theme].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
#!/bin/bash
|
||||||
cp -f "../Client/bin/Debug/net9.0/[Owner].Theme.[Theme].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net9.0/"
|
|
||||||
cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/"
|
TargetFramework=$1
|
||||||
|
ProjectName=$2
|
||||||
|
|
||||||
|
cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.dll" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -f "../Client/bin/Debug/$TargetFramework/$ProjectName$.Client.Oqtane.pdb" "../../[RootFolder]/Oqtane.Server/bin/Debug/$TargetFramework/"
|
||||||
|
cp -rf "../Server/wwwroot/"* "../../[RootFolder]/Oqtane.Server/wwwroot/"
|
@ -1,3 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
set TargetFramework=%1
|
||||||
|
set ProjectName=%2
|
||||||
|
|
||||||
del "*.nupkg"
|
del "*.nupkg"
|
||||||
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack [Owner].Theme.[Theme].nuspec
|
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
|
||||||
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Packages\" /Y
|
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Packages\" /Y
|
@ -1,2 +1,5 @@
|
|||||||
"..\..\oqtane.framework\oqtane.package\nuget.exe" pack [Owner].Theme.[Theme].nuspec
|
TargetFramework=$1
|
||||||
cp -f "*.nupkg" "..\..\oqtane.framework\Oqtane.Server\Packages\"
|
ProjectName=$2
|
||||||
|
|
||||||
|
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
|
||||||
|
cp -f "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\Packages\"
|
@ -120,13 +120,22 @@ Oqtane.Interop = {
|
|||||||
this.includeLink(links[i].id, links[i].rel, links[i].href, links[i].type, links[i].integrity, links[i].crossorigin, links[i].insertbefore);
|
this.includeLink(links[i].id, links[i].rel, links[i].href, links[i].type, links[i].integrity, links[i].crossorigin, links[i].insertbefore);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
includeScript: function (id, src, integrity, crossorigin, type, content, location) {
|
includeScript: function (id, src, integrity, crossorigin, type, content, location, dataAttributes) {
|
||||||
var script;
|
var script;
|
||||||
if (src !== "") {
|
if (src !== "") {
|
||||||
script = document.querySelector("script[src=\"" + CSS.escape(src) + "\"]");
|
script = document.querySelector("script[src=\"" + CSS.escape(src) + "\"]");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if (id !== "") {
|
||||||
script = document.getElementById(id);
|
script = document.getElementById(id);
|
||||||
|
} else {
|
||||||
|
const scripts = document.querySelectorAll("script:not([src])");
|
||||||
|
for (let i = 0; i < scripts.length; i++) {
|
||||||
|
if (scripts[i].textContent.includes(content)) {
|
||||||
|
script = scripts[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (script !== null) {
|
if (script !== null) {
|
||||||
script.remove();
|
script.remove();
|
||||||
@ -152,37 +161,36 @@ Oqtane.Interop = {
|
|||||||
else {
|
else {
|
||||||
script.innerHTML = content;
|
script.innerHTML = content;
|
||||||
}
|
}
|
||||||
script.async = false;
|
if (dataAttributes !== null) {
|
||||||
this.addScript(script, location)
|
for (var key in dataAttributes) {
|
||||||
.then(() => {
|
script.setAttribute(key, dataAttributes[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.addScript(script, location);
|
||||||
|
} catch (error) {
|
||||||
if (src !== "") {
|
if (src !== "") {
|
||||||
console.log(src + ' loaded');
|
console.error("Failed to load external script: ${src}", error);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to load inline script: ${content}", error);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
console.log(id + ' loaded');
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
if (src !== "") {
|
|
||||||
console.error(src + ' failed');
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.error(id + ' failed');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addScript: function (script, location) {
|
addScript: function (script, location) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
script.async = false;
|
||||||
|
script.defer = false;
|
||||||
|
|
||||||
|
script.onload = () => resolve();
|
||||||
|
script.onerror = (error) => reject(error);
|
||||||
|
|
||||||
if (location === 'head') {
|
if (location === 'head') {
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
}
|
} else {
|
||||||
if (location === 'body') {
|
|
||||||
document.body.appendChild(script);
|
document.body.appendChild(script);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise((res, rej) => {
|
|
||||||
script.onload = res();
|
|
||||||
script.onerror = rej();
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
includeScripts: async function (scripts) {
|
includeScripts: async function (scripts) {
|
||||||
@ -222,10 +230,10 @@ Oqtane.Interop = {
|
|||||||
if (scripts[s].crossorigin !== '') {
|
if (scripts[s].crossorigin !== '') {
|
||||||
element.crossOrigin = scripts[s].crossorigin;
|
element.crossOrigin = scripts[s].crossorigin;
|
||||||
}
|
}
|
||||||
if (scripts[s].es6module === true) {
|
if (scripts[s].type !== '') {
|
||||||
element.type = "module";
|
element.type = scripts[s].type;
|
||||||
}
|
}
|
||||||
if (typeof scripts[s].dataAttributes !== "undefined" && scripts[s].dataAttributes !== null) {
|
if (scripts[s].dataAttributes !== null) {
|
||||||
for (var key in scripts[s].dataAttributes) {
|
for (var key in scripts[s].dataAttributes) {
|
||||||
element.setAttribute(key, scripts[s].dataAttributes[key]);
|
element.setAttribute(key, scripts[s].dataAttributes[key]);
|
||||||
}
|
}
|
||||||
|
80
Oqtane.Server/wwwroot/js/reload.js
Normal file
80
Oqtane.Server/wwwroot/js/reload.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
const scriptInfoBySrc = new Map();
|
||||||
|
|
||||||
|
function getKey(script) {
|
||||||
|
if (script.hasAttribute("src") && script.src !== "") {
|
||||||
|
return script.src;
|
||||||
|
} else {
|
||||||
|
return script.innerHTML;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function onUpdate() {
|
||||||
|
let timestamp = Date.now();
|
||||||
|
let enhancedNavigation = scriptInfoBySrc.size !== 0;
|
||||||
|
|
||||||
|
// iterate over all script elements in page
|
||||||
|
const scripts = document.getElementsByTagName("script");
|
||||||
|
for (const script of Array.from(scripts)) {
|
||||||
|
let key = getKey(script);
|
||||||
|
let scriptInfo = scriptInfoBySrc.get(key);
|
||||||
|
if (!scriptInfo) {
|
||||||
|
// new script added
|
||||||
|
scriptInfo = { timestamp: timestamp };
|
||||||
|
scriptInfoBySrc.set(key, scriptInfo);
|
||||||
|
if (enhancedNavigation) {
|
||||||
|
reloadScript(script);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// existing script
|
||||||
|
scriptInfo.timestamp = timestamp;
|
||||||
|
if (script.hasAttribute("data-reload") && script.getAttribute("data-reload") === "true") {
|
||||||
|
reloadScript(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove scripts that are no longer referenced
|
||||||
|
for (const [key, scriptInfo] of scriptInfoBySrc) {
|
||||||
|
if (scriptInfo.timestamp !== timestamp) {
|
||||||
|
scriptInfoBySrc.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadScript(script) {
|
||||||
|
try {
|
||||||
|
replaceScript(script);
|
||||||
|
} catch (error) {
|
||||||
|
if (script.hasAttribute("src") && script.src !== "") {
|
||||||
|
console.error("Failed to load external script: ${script.src}", error);
|
||||||
|
} else {
|
||||||
|
console.error("Failed to load inline script: ${script.innerHtml}", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function replaceScript(script) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
var newScript = document.createElement("script");
|
||||||
|
|
||||||
|
// replicate attributes and content
|
||||||
|
for (let i = 0; i < script.attributes.length; i++) {
|
||||||
|
newScript.setAttribute(script.attributes[i].name, script.attributes[i].value);
|
||||||
|
}
|
||||||
|
newScript.innerHTML = script.innerHTML;
|
||||||
|
|
||||||
|
// dynamically injected scripts cannot be async or deferred
|
||||||
|
newScript.async = false;
|
||||||
|
newScript.defer = false;
|
||||||
|
|
||||||
|
newScript.onload = () => resolve();
|
||||||
|
newScript.onerror = (error) => reject(error);
|
||||||
|
|
||||||
|
// remove existing script
|
||||||
|
script.remove();
|
||||||
|
|
||||||
|
// replace with new script to force reload in Blazor
|
||||||
|
document.head.appendChild(newScript);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 72 KiB |
@ -144,25 +144,25 @@ namespace Oqtane.Models
|
|||||||
{
|
{
|
||||||
FromUserId = from.UserId;
|
FromUserId = from.UserId;
|
||||||
FromDisplayName = from.DisplayName;
|
FromDisplayName = from.DisplayName;
|
||||||
FromEmail = from.Email;
|
FromEmail = from.Email ?? "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FromUserId = null;
|
FromUserId = null;
|
||||||
FromDisplayName = fromDisplayName;
|
FromDisplayName = fromDisplayName;
|
||||||
FromEmail = fromEmail;
|
FromEmail = fromEmail ?? "";
|
||||||
}
|
}
|
||||||
if (to != null)
|
if (to != null)
|
||||||
{
|
{
|
||||||
ToUserId = to.UserId;
|
ToUserId = to.UserId;
|
||||||
ToDisplayName = to.DisplayName;
|
ToDisplayName = to.DisplayName;
|
||||||
ToEmail = to.Email;
|
ToEmail = to.Email ?? "";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ToUserId = null;
|
ToUserId = null;
|
||||||
ToDisplayName = toDisplayName;
|
ToDisplayName = toDisplayName;
|
||||||
ToEmail = toEmail;
|
ToEmail = toEmail ?? "";
|
||||||
}
|
}
|
||||||
Subject = subject;
|
Subject = subject;
|
||||||
Body = body;
|
Body = body;
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
|
||||||
namespace Oqtane.Models
|
namespace Oqtane.Models
|
||||||
@ -27,6 +29,11 @@ namespace Oqtane.Models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For Scripts this allows type to be specified - not applicable to Stylesheets
|
||||||
|
/// </summary>
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Integrity checks to increase the security of resources accessed. Especially common in CDN resources.
|
/// Integrity checks to increase the security of resources accessed. Especially common in CDN resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -52,11 +59,6 @@ namespace Oqtane.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public ResourceLocation Location { get; set; }
|
public ResourceLocation Location { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// For Scripts this allows type="module" registrations - not applicable to Stylesheets
|
|
||||||
/// </summary>
|
|
||||||
public bool ES6Module { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Allows specification of inline script - not applicable to Stylesheets
|
/// Allows specification of inline script - not applicable to Stylesheets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -72,6 +74,11 @@ namespace Oqtane.Models
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Reload { get; set; }
|
public bool Reload { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Cusotm data-* attributes for scripts - not applicable to Stylesheets
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, string> DataAttributes { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The namespace of the component that declared the resource - only used in SiteRouter
|
/// The namespace of the component that declared the resource - only used in SiteRouter
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -82,14 +89,22 @@ namespace Oqtane.Models
|
|||||||
var resource = new Resource();
|
var resource = new Resource();
|
||||||
resource.ResourceType = ResourceType;
|
resource.ResourceType = ResourceType;
|
||||||
resource.Url = Url;
|
resource.Url = Url;
|
||||||
|
resource.Type = Type;
|
||||||
resource.Integrity = Integrity;
|
resource.Integrity = Integrity;
|
||||||
resource.CrossOrigin = CrossOrigin;
|
resource.CrossOrigin = CrossOrigin;
|
||||||
resource.Bundle = Bundle;
|
resource.Bundle = Bundle;
|
||||||
resource.Location = Location;
|
resource.Location = Location;
|
||||||
resource.ES6Module = ES6Module;
|
|
||||||
resource.Content = Content;
|
resource.Content = Content;
|
||||||
resource.RenderMode = RenderMode;
|
resource.RenderMode = RenderMode;
|
||||||
resource.Reload = Reload;
|
resource.Reload = Reload;
|
||||||
|
resource.DataAttributes = new Dictionary<string, string>();
|
||||||
|
if (DataAttributes != null && DataAttributes.Count > 0)
|
||||||
|
{
|
||||||
|
foreach (var kvp in DataAttributes)
|
||||||
|
{
|
||||||
|
resource.DataAttributes.Add(kvp.Key, kvp.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
resource.Level = level;
|
resource.Level = level;
|
||||||
resource.Namespace = name;
|
resource.Namespace = name;
|
||||||
return resource;
|
return resource;
|
||||||
@ -97,5 +112,18 @@ namespace Oqtane.Models
|
|||||||
|
|
||||||
[Obsolete("ResourceDeclaration is deprecated", false)]
|
[Obsolete("ResourceDeclaration is deprecated", false)]
|
||||||
public ResourceDeclaration Declaration { get; set; }
|
public ResourceDeclaration Declaration { get; set; }
|
||||||
|
|
||||||
|
[Obsolete("ES6Module is deprecated. Use Type property instead for scripts.", false)]
|
||||||
|
public bool ES6Module
|
||||||
|
{
|
||||||
|
get => (Type == "module");
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
Type = "module";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
53
Oqtane.Shared/Models/Script.cs
Normal file
53
Oqtane.Shared/Models/Script.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
namespace Oqtane.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Script inherits from Resource and offers constructors with parameters specific to Scripts
|
||||||
|
/// </summary>
|
||||||
|
public class Script : Resource
|
||||||
|
{
|
||||||
|
private void SetDefaults()
|
||||||
|
{
|
||||||
|
this.ResourceType = ResourceType.Script;
|
||||||
|
this.Location = ResourceLocation.Body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script(string Src)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
this.Url = Src;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script(string Content, string Type)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
this.Content = Content;
|
||||||
|
this.Type = Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script(string Src, string Integrity, string CrossOrigin)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
this.Url = Src;
|
||||||
|
this.Integrity = Integrity;
|
||||||
|
this.CrossOrigin = CrossOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script(string Src, string Integrity, string CrossOrigin, string Type, string Content, ResourceLocation Location, string Bundle, bool Reload, Dictionary<string, string> DataAttributes, string RenderMode)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
this.Url = Src;
|
||||||
|
this.Integrity = Integrity;
|
||||||
|
this.CrossOrigin = CrossOrigin;
|
||||||
|
this.Type = Type;
|
||||||
|
this.Content = Content;
|
||||||
|
this.Location = Location;
|
||||||
|
this.Bundle = Bundle;
|
||||||
|
this.Reload = Reload;
|
||||||
|
this.DataAttributes = DataAttributes;
|
||||||
|
this.RenderMode = RenderMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
30
Oqtane.Shared/Models/Stylesheet.cs
Normal file
30
Oqtane.Shared/Models/Stylesheet.cs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
namespace Oqtane.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stylesheet inherits from Resource and offers constructors with parameters specific to Stylesheets
|
||||||
|
/// </summary>
|
||||||
|
public class Stylesheet : Resource
|
||||||
|
{
|
||||||
|
private void SetDefaults()
|
||||||
|
{
|
||||||
|
this.ResourceType = ResourceType.Stylesheet;
|
||||||
|
this.Location = ResourceLocation.Head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stylesheet(string Href)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
this.Url = Href;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stylesheet(string Href, string Integrity, string CrossOrigin)
|
||||||
|
{
|
||||||
|
SetDefaults();
|
||||||
|
this.Url = Href;
|
||||||
|
this.Integrity = Integrity;
|
||||||
|
this.CrossOrigin = CrossOrigin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user