Compare commits
122 Commits
Author | SHA1 | Date | |
---|---|---|---|
a84b497fae | |||
c33d1bcd3c | |||
4071e14a7e | |||
b5b3f190b7 | |||
d43a3e132c | |||
a90c21f80a | |||
2b768165e5 | |||
e8425ba03a | |||
b0a6f402e9 | |||
02e86a940b | |||
79d03eb43e | |||
b564955f85 | |||
5aed64f614 | |||
a823a4d9b7 | |||
4eed2193f4 | |||
48e7a41af6 | |||
bba5caecf7 | |||
ede6a45f15 | |||
9c65d23229 | |||
5dedfe9295 | |||
95d8c368c8 | |||
49fbfb8bbc | |||
aa3d2a5289 | |||
48ae6df4b7 | |||
c635351a12 | |||
d9ff77fd9a | |||
e1a7954307 | |||
efe6421133 | |||
79b62f4407 | |||
9d17804ac7 | |||
5986355504 | |||
192e6fde92 | |||
ad090e62cc | |||
5c072fea62 | |||
fd01a40810 | |||
7b9a83a273 | |||
f964e0e502 | |||
22acb7c74b | |||
6a99e81e75 | |||
93b6de1caf | |||
1fbab5db2b | |||
950e852dee | |||
826898e3fe | |||
1268149d83 | |||
908299970f | |||
861dde8627 | |||
cc9802a0d8 | |||
69d1f3aa53 | |||
ea4587d842 | |||
fb4c95f945 | |||
95a27af5f2 | |||
9d7b25ade6 | |||
3a8f4199cd | |||
11002efc02 | |||
367c1c3568 | |||
9e04230d99 | |||
21304db7c9 | |||
f4f6e98045 | |||
ad41eff38a | |||
dbd6cc4148 | |||
dda71e5ccd | |||
cfe8059176 | |||
8b00784ecc | |||
9bcc6bbad0 | |||
ce7995966d | |||
cea5f86df4 | |||
0912253b1b | |||
5aecc4be03 | |||
e09178c14c | |||
477ded6a4a | |||
311c48becb | |||
ec924a7ddf | |||
e39416a786 | |||
51b356cc0e | |||
66b13bdb8b | |||
4ade58da01 | |||
efcfc0783c | |||
aa22db7fe5 | |||
5e0f008b65 | |||
eaf840e1da | |||
fc9e47778b | |||
35edf78aed | |||
07718f0449 | |||
6759156519 | |||
e2688e6feb | |||
65ba6423b1 | |||
a2f8fe3694 | |||
5273a17ab6 | |||
f7c1e7b706 | |||
45bbc4c681 | |||
6af5682548 | |||
24ed06626d | |||
eeff4af167 | |||
17f46afe14 | |||
224618cf21 | |||
ea93ab2a83 | |||
b9f7c39550 | |||
86b4b8e43a | |||
f54d07548e | |||
037db8a3e4 | |||
8f00e85abd | |||
9ccc4c4059 | |||
8408f98693 | |||
cde271fd5b | |||
c21a097fd2 | |||
83c32d4963 | |||
22c2d56da0 | |||
bd8d6e0480 | |||
825eb700b1 | |||
e59ee70f88 | |||
1173a29ed5 | |||
6a2ff369ea | |||
e22606ae79 | |||
bf56c2a9fa | |||
6567b55ea3 | |||
20e90c0de4 | |||
2892d5ec6f | |||
e034811e92 | |||
ee18bbd145 | |||
e3ebbde767 | |||
6a57980439 | |||
765760f3a5 |
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2018-2021 .NET Foundation
|
Copyright (c) 2018-2022 .NET Foundation
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public int VisitorId { get; set; }
|
public int VisitorId { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string RemoteIPAddress { get; set; }
|
||||||
|
|
||||||
private bool _initialized = false;
|
private bool _initialized = false;
|
||||||
private string _display = "display: none;";
|
private string _display = "display: none;";
|
||||||
private Installation _installation = new Installation { Success = false, Message = "" };
|
private Installation _installation = new Installation { Success = false, Message = "" };
|
||||||
@ -50,6 +53,7 @@
|
|||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
|
SiteState.RemoteIPAddress = RemoteIPAddress;
|
||||||
SiteState.AntiForgeryToken = AntiForgeryToken;
|
SiteState.AntiForgeryToken = AntiForgeryToken;
|
||||||
InstallationService.SetAntiForgeryTokenHeader(AntiForgeryToken);
|
InstallationService.SetAntiForgeryTokenHeader(AntiForgeryToken);
|
||||||
|
|
||||||
@ -58,10 +62,6 @@
|
|||||||
{
|
{
|
||||||
SiteState.Alias = _installation.Alias;
|
SiteState.Alias = _installation.Alias;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
_installation.Message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
|
|
||||||
}
|
|
||||||
_initialized = true;
|
_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,6 @@
|
|||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
var admin = PageState.Pages.FirstOrDefault(item => item.Path == "admin");
|
||||||
_pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId).ToList();
|
_pages = PageState.Pages.Where(item => item.ParentId == admin?.PageId && !item.IsDeleted).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,9 @@
|
|||||||
<option value="m">@Localizer["Minute(s)"]</option>
|
<option value="m">@Localizer["Minute(s)"]</option>
|
||||||
<option value="H">@Localizer["Hour(s)"]</option>
|
<option value="H">@Localizer["Hour(s)"]</option>
|
||||||
<option value="d">@Localizer["Day(s)"]</option>
|
<option value="d">@Localizer["Day(s)"]</option>
|
||||||
|
<option value="w">@Localizer["Week(s)"]</option>
|
||||||
<option value="M">@Localizer["Month(s)"]</option>
|
<option value="M">@Localizer["Month(s)"]</option>
|
||||||
|
<option value="O">@Localizer["Once"]</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -170,7 +172,14 @@
|
|||||||
job.JobType = _jobType;
|
job.JobType = _jobType;
|
||||||
job.IsEnabled = Boolean.Parse(_isEnabled);
|
job.IsEnabled = Boolean.Parse(_isEnabled);
|
||||||
job.Frequency = _frequency;
|
job.Frequency = _frequency;
|
||||||
|
if (job.Frequency == "O") // once
|
||||||
|
{
|
||||||
|
job.Interval = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
job.Interval = int.Parse(_interval);
|
job.Interval = int.Parse(_interval);
|
||||||
|
}
|
||||||
job.StartDate = _startDate;
|
job.StartDate = _startDate;
|
||||||
if (job.StartDate != null)
|
if (job.StartDate != null)
|
||||||
{
|
{
|
||||||
|
@ -83,28 +83,28 @@ else
|
|||||||
|
|
||||||
private string DisplayFrequency(int interval, string frequency)
|
private string DisplayFrequency(int interval, string frequency)
|
||||||
{
|
{
|
||||||
var result = $"{Localizer["Every"]} {interval.ToString()} ";
|
var result = "";
|
||||||
switch (frequency)
|
switch (frequency)
|
||||||
{
|
{
|
||||||
case "m":
|
case "m":
|
||||||
result += Localizer["Minute"];
|
result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Minute"];
|
||||||
break;
|
break;
|
||||||
case "H":
|
case "H":
|
||||||
result += Localizer["Hour"];
|
result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Hour"];
|
||||||
break;
|
break;
|
||||||
case "d":
|
case "d":
|
||||||
result += Localizer["Day"];
|
result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Day"];
|
||||||
|
break;
|
||||||
|
case "w":
|
||||||
|
result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Week"];
|
||||||
break;
|
break;
|
||||||
case "M":
|
case "M":
|
||||||
result += Localizer["Month"];
|
result = $"{Localizer["Every"]} {interval.ToString()} " + Localizer["Month"];
|
||||||
|
break;
|
||||||
|
case "O":
|
||||||
|
result = Localizer["Once"];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interval > 1)
|
|
||||||
{
|
|
||||||
result += Localizer["s"];
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +114,7 @@ else
|
|||||||
{
|
{
|
||||||
await JobService.DeleteJobAsync(job.JobId);
|
await JobService.DeleteJobAsync(job.JobId);
|
||||||
await logger.LogInformation("Job Deleted {Job}", job);
|
await logger.LogInformation("Job Deleted {Job}", job);
|
||||||
|
_jobs = await JobService.GetJobsAsync();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -124,13 +125,37 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task StartJob(int jobId)
|
private async Task StartJob(int jobId)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
await JobService.StartJobAsync(jobId);
|
await JobService.StartJobAsync(jobId);
|
||||||
|
await logger.LogInformation("Job Started {JobId}", jobId);
|
||||||
|
AddModuleMessage(Localizer["Message.Job.Start"], MessageType.Success);
|
||||||
|
_jobs = await JobService.GetJobsAsync();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Starting Job {JobId} {Error}", jobId, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Job.Start"], MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task StopJob(int jobId)
|
private async Task StopJob(int jobId)
|
||||||
|
{
|
||||||
|
try
|
||||||
{
|
{
|
||||||
await JobService.StopJobAsync(jobId);
|
await JobService.StopJobAsync(jobId);
|
||||||
|
await logger.LogInformation("Job Stopped {JobId}", jobId);
|
||||||
|
AddModuleMessage(Localizer["Message.Job.Stop"], MessageType.Success);
|
||||||
|
_jobs = await JobService.GetJobsAsync();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Stopping Job {JobId} {Error}", jobId, ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Job.Stop"], MessageType.Error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task Refresh()
|
private async Task Refresh()
|
||||||
|
@ -177,17 +177,17 @@
|
|||||||
{
|
{
|
||||||
await UserService.ForgotPasswordAsync(user);
|
await UserService.ForgotPasswordAsync(user);
|
||||||
await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username);
|
await logger.LogInformation(LogFunction.Security, "Password Reset Notification Sent For Username {Username}", _username);
|
||||||
_message = "Please Check The Email Address Associated To Your User Account For A Password Reset Notification";
|
_message = Localizer["Message.ForgotUser"];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_message = "User Does Not Exist";
|
_message = Localizer["Message.UserDoesNotExist"];
|
||||||
_type = MessageType.Warning;
|
_type = MessageType.Warning;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_message = "Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again";
|
_message = Localizer["Message.ForgotPassword"];
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
@inject IStringLocalizer<Detail> Localizer
|
@inject IStringLocalizer<Detail> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="dateTime" HelpText="The date and time of this log" ResourceKey="DateTime">Date/Time: </Label>
|
<Label Class="col-sm-3" For="dateTime" HelpText="The date and time of this log" ResourceKey="DateTime">Date/Time: </Label>
|
||||||
@ -107,10 +109,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@CloseUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private int _logId;
|
private int _logId;
|
||||||
private string _logDate = string.Empty;
|
private string _logDate = string.Empty;
|
||||||
private string _level = string.Empty;
|
private string _level = string.Empty;
|
||||||
@ -176,6 +179,7 @@
|
|||||||
_exception = log.Exception;
|
_exception = log.Exception;
|
||||||
_properties = log.Properties;
|
_properties = log.Properties;
|
||||||
_server = log.Server;
|
_server = log.Server;
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -184,4 +188,16 @@
|
|||||||
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Log.Load"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string CloseUrl()
|
||||||
|
{
|
||||||
|
if (!PageState.QueryString.ContainsKey("level"))
|
||||||
|
{
|
||||||
|
return NavigateUrl();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NavigateUrl(PageState.Page.Path, "level=" + PageState.QueryString["level"] + "&function=" + PageState.QueryString["function"] + "&rows=" + PageState.QueryString["rows"] + "&page=" + PageState.QueryString["page"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Logs
|
@namespace Oqtane.Modules.Admin.Logs
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject ILogService LogService
|
@inject ILogService LogService
|
||||||
|
@inject ISettingService SettingService
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@ -10,11 +11,13 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
<TabStrip>
|
||||||
|
<TabPanel Name="Events" Heading="Events" ResourceKey="Events">
|
||||||
<div class="container g-0">
|
<div class="container g-0">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<Label For="level" HelpText="Select the log level for event log items" ResourceKey="Level">Level: </Label><br /><br />
|
<Label For="level" HelpText="Select the log level for event log items" ResourceKey="Level">Level: </Label><br /><br />
|
||||||
<select id="level" class="form-select" @onchange="(e => LevelChanged(e))">
|
<select id="level" class="form-select" value="@_level" @onchange="(e => LevelChanged(e))">
|
||||||
<option value="-"><@Localizer["AllLevels"]></option>
|
<option value="-"><@Localizer["AllLevels"]></option>
|
||||||
<option value="Trace">@Localizer["Trace"]</option>
|
<option value="Trace">@Localizer["Trace"]</option>
|
||||||
<option value="Debug">@Localizer["Debug"]</option>
|
<option value="Debug">@Localizer["Debug"]</option>
|
||||||
@ -26,7 +29,7 @@ else
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<Label For="function" HelpText="Select the function for event log items" ResourceKey="Function">Function: </Label><br /><br />
|
<Label For="function" HelpText="Select the function for event log items" ResourceKey="Function">Function: </Label><br /><br />
|
||||||
<select id="function" class="form-select" @onchange="(e => FunctionChanged(e))">
|
<select id="function" class="form-select" value="@_function" @onchange="(e => FunctionChanged(e))">
|
||||||
<option value="-"><@Localizer["AllFunctions"]></option>
|
<option value="-"><@Localizer["AllFunctions"]></option>
|
||||||
<option value="Create">@Localizer["Create"]</option>
|
<option value="Create">@Localizer["Create"]</option>
|
||||||
<option value="Read">@Localizer["Read"]</option>
|
<option value="Read">@Localizer["Read"]</option>
|
||||||
@ -38,7 +41,7 @@ else
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<Label For="rows" HelpText="Select the maximum number of event log items to review. Please note that if you choose more than 10 items the information will be split into pages." ResourceKey="Rows">Maximum Items: </Label><br /><br />
|
<Label For="rows" HelpText="Select the maximum number of event log items to review. Please note that if you choose more than 10 items the information will be split into pages." ResourceKey="Rows">Maximum Items: </Label><br /><br />
|
||||||
<select id="rows" class="form-select" @onchange="(e => RowsChanged(e))">
|
<select id="rows" class="form-select" value="@_rows" @onchange="(e => RowsChanged(e))">
|
||||||
<option value="10">10</option>
|
<option value="10">10</option>
|
||||||
<option value="50">50</option>
|
<option value="50">50</option>
|
||||||
<option value="100">100</option>
|
<option value="100">100</option>
|
||||||
@ -46,10 +49,11 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<br />
|
||||||
|
|
||||||
@if (_logs.Any())
|
@if (_logs.Any())
|
||||||
{
|
{
|
||||||
<Pager Items="@_logs">
|
<Pager Items="@_logs" CurrentPage="@_page.ToString()" OnPageChange="OnPageChange">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@Localizer["Date"]</th>
|
<th>@Localizer["Date"]</th>
|
||||||
@ -58,7 +62,7 @@ else
|
|||||||
<th>@Localizer["Function"]</th>
|
<th>@Localizer["Function"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td class="@GetClass(context.Function)"><ActionLink Action="Detail" Parameters="@($"id=" + context.LogId.ToString())" ResourceKey="LogDetails" /></td>
|
<td class="@GetClass(context.Function)"><ActionLink Action="Detail" Parameters="@($"id=" + context.LogId.ToString() + "&level=" + _level + "&function=" + _function + "&rows=" + _rows + "&page=" + _page.ToString())" ResourceKey="LogDetails" /></td>
|
||||||
<td class="@GetClass(context.Function)">@context.LogDate</td>
|
<td class="@GetClass(context.Function)">@context.LogDate</td>
|
||||||
<td class="@GetClass(context.Function)">@context.Level</td>
|
<td class="@GetClass(context.Function)">@context.Level</td>
|
||||||
<td class="@GetClass(context.Function)">@context.Feature</td>
|
<td class="@GetClass(context.Function)">@context.Feature</td>
|
||||||
@ -70,13 +74,29 @@ else
|
|||||||
{
|
{
|
||||||
<p><em>@Localizer["NoLogs"]</em></p>
|
<p><em>@Localizer["NoLogs"]</em></p>
|
||||||
}
|
}
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="retention" HelpText="Number of days of events to retain" ResourceKey="Retention">Retention (Days): </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="retention" class="form-control" @bind="@_retention" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
||||||
|
</TabPanel>
|
||||||
|
</TabStrip>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _level = "-";
|
private string _level = "-";
|
||||||
private string _function = "-";
|
private string _function = "-";
|
||||||
private string _rows = "10";
|
private string _rows = "10";
|
||||||
|
private int _page = 1;
|
||||||
private List<Log> _logs;
|
private List<Log> _logs;
|
||||||
|
private string _retention = "";
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
@ -84,7 +104,27 @@ else
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (PageState.QueryString.ContainsKey("level"))
|
||||||
|
{
|
||||||
|
_level = PageState.QueryString["level"];
|
||||||
|
}
|
||||||
|
if (PageState.QueryString.ContainsKey("function"))
|
||||||
|
{
|
||||||
|
_function = PageState.QueryString["function"];
|
||||||
|
}
|
||||||
|
if (PageState.QueryString.ContainsKey("rows"))
|
||||||
|
{
|
||||||
|
_rows = PageState.QueryString["rows"];
|
||||||
|
}
|
||||||
|
if (PageState.QueryString.ContainsKey("page") && int.TryParse(PageState.QueryString["page"], out int page))
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
}
|
||||||
|
|
||||||
await GetLogs();
|
await GetLogs();
|
||||||
|
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
_retention = SettingService.GetSetting(settings, "LogRetention", "30");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@ -170,4 +210,27 @@ else
|
|||||||
}
|
}
|
||||||
return classname;
|
return classname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task SaveSiteSettings()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
settings = SettingService.SetSetting(settings, "LogRetention", _retention, true);
|
||||||
|
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
||||||
|
|
||||||
|
AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Saving Site Settings {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPageChange(int page)
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,7 @@ else
|
|||||||
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
|
var moduleDefinition = new ModuleDefinition { Owner = _owner, Name = _module, Description = _description, Template = _template, Version = _reference };
|
||||||
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
|
moduleDefinition = await ModuleDefinitionService.CreateModuleDefinitionAsync(moduleDefinition);
|
||||||
|
|
||||||
var settings = ModuleState.Settings;
|
var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
||||||
SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName);
|
SettingService.SetSetting(settings, "ModuleDefinitionName", moduleDefinition.ModuleDefinitionName);
|
||||||
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ else
|
|||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.Version</td>
|
<td>@context.Version</td>
|
||||||
<td>
|
<td>
|
||||||
@if(context.AssemblyName == "Oqtane.Client" || PageState.Modules.Where(m => m.ModuleDefinition.ModuleDefinitionId == context.ModuleDefinitionId).Count() > 0)
|
@if(context.AssemblyName == "Oqtane.Client" || PageState.Modules.Where(m => m.ModuleDefinition?.ModuleDefinitionId == context.ModuleDefinitionId).FirstOrDefault() != null)
|
||||||
{
|
{
|
||||||
<span>@SharedLocalizer["Yes"]</span>
|
<span>@SharedLocalizer["Yes"]</span>
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,12 @@
|
|||||||
<input id="title" class="form-control" @bind="@_title" />
|
<input id="title" class="form-control" @bind="@_title" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="meta" HelpText="Optionally enter meta tags (in exactly the form you want them to be included in the page output)." ResourceKey="Meta">Meta: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="meta" class="form-control" @bind="@_meta" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -164,6 +170,7 @@
|
|||||||
private List<Page> _pageList;
|
private List<Page> _pageList;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _title;
|
private string _title;
|
||||||
|
private string _meta;
|
||||||
private string _path = string.Empty;
|
private string _path = string.Empty;
|
||||||
private string _parentid = "-1";
|
private string _parentid = "-1";
|
||||||
private string _insert = ">>";
|
private string _insert = ">>";
|
||||||
@ -370,6 +377,7 @@
|
|||||||
page.Permissions = _permissionGrid.GetPermissions();
|
page.Permissions = _permissionGrid.GetPermissions();
|
||||||
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
page.IsPersonalizable = (_ispersonalizable == null ? false : Boolean.Parse(_ispersonalizable));
|
||||||
page.UserId = null;
|
page.UserId = null;
|
||||||
|
page.Meta = _meta;
|
||||||
|
|
||||||
page = await PageService.AddPageAsync(page);
|
page = await PageService.AddPageAsync(page);
|
||||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||||
|
@ -102,6 +102,12 @@
|
|||||||
<input id="title" class="form-control" @bind="@_title" maxlength="200"/>
|
<input id="title" class="form-control" @bind="@_title" maxlength="200"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="meta" HelpText="Optionally enter meta tags (in exactly the form you want them to be included in the page output)." ResourceKey="Meta">Meta: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="meta" class="form-control" @bind="@_meta" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
<Label Class="col-sm-3" For="theme" HelpText="Select the theme for this page" ResourceKey="Theme">Theme: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -200,6 +206,7 @@
|
|||||||
private int _pageId;
|
private int _pageId;
|
||||||
private string _name;
|
private string _name;
|
||||||
private string _title;
|
private string _title;
|
||||||
|
private string _meta;
|
||||||
private string _path;
|
private string _path;
|
||||||
private string _currentparentid;
|
private string _currentparentid;
|
||||||
private string _parentid = "-1";
|
private string _parentid = "-1";
|
||||||
@ -243,6 +250,7 @@
|
|||||||
{
|
{
|
||||||
_name = page.Name;
|
_name = page.Name;
|
||||||
_title = page.Title;
|
_title = page.Title;
|
||||||
|
_meta = page.Meta;
|
||||||
_path = page.Path;
|
_path = page.Path;
|
||||||
_pageModules = PageState.Modules.Where(m => m.PageId == page.PageId && m.IsDeleted == false).ToList();
|
_pageModules = PageState.Modules.Where(m => m.PageId == page.PageId && m.IsDeleted == false).ToList();
|
||||||
|
|
||||||
@ -384,6 +392,8 @@
|
|||||||
private void ThemeSettings()
|
private void ThemeSettings()
|
||||||
{
|
{
|
||||||
_themeSettingsType = null;
|
_themeSettingsType = null;
|
||||||
|
if (PageState.QueryString.ContainsKey("cp")) // can only be displayed if invoked from Control Panel
|
||||||
|
{
|
||||||
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
var theme = _themeList.FirstOrDefault(item => item.Themes.Any(themecontrol => themecontrol.TypeName.Equals(_themetype)));
|
||||||
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
if (theme != null && !string.IsNullOrEmpty(theme.ThemeSettingsType))
|
||||||
{
|
{
|
||||||
@ -400,6 +410,7 @@
|
|||||||
_refresh = true;
|
_refresh = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SavePage()
|
private async Task SavePage()
|
||||||
{
|
{
|
||||||
@ -490,6 +501,7 @@
|
|||||||
page.Permissions = _permissionGrid.GetPermissions();
|
page.Permissions = _permissionGrid.GetPermissions();
|
||||||
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
page.IsPersonalizable = (_ispersonalizable != null && Boolean.Parse(_ispersonalizable));
|
||||||
page.UserId = null;
|
page.UserId = null;
|
||||||
|
page.Meta = _meta;
|
||||||
|
|
||||||
page = await PageService.UpdatePageAsync(page);
|
page = await PageService.UpdatePageAsync(page);
|
||||||
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
await PageService.UpdatePageOrderAsync(page.SiteId, page.PageId, page.ParentId);
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
<th>@Localizer["DeletedOn"]</th>
|
<th>@Localizer["DeletedOn"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><button type="button" @onclick="@(() => RestorePage(context))" class="btn btn-info" title="Restore">Restore</button></td>
|
<td><button type="button" @onclick="@(() => RestorePage(context))" class="btn btn-success" title="Restore">Restore</button></td>
|
||||||
<td><ActionDialog Header="Delete Page" Message="@string.Format(Localizer["Confirm.Page.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
|
<td><ActionDialog Header="Delete Page" Message="@string.Format(Localizer["Confirm.Page.Delete"], context.Name)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeletePage(context))" ResourceKey="DeletePage" /></td>
|
||||||
<td>@context.Name</td>
|
<td>@context.Name</td>
|
||||||
<td>@context.DeletedBy</td>
|
<td>@context.DeletedBy</td>
|
||||||
@ -56,7 +56,7 @@
|
|||||||
<th>@Localizer["DeletedOn"]</th>
|
<th>@Localizer["DeletedOn"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><button type="button" @onclick="@(() => RestoreModule(context))" class="btn btn-info" title="Restore">@Localizer["Restore"]</button></td>
|
<td><button type="button" @onclick="@(() => RestoreModule(context))" class="btn btn-success" title="Restore">@Localizer["Restore"]</button></td>
|
||||||
<td><ActionDialog Header="Delete Module" Message="@string.Format(Localizer["Confirm.Module.Delete"], context.Title)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
|
<td><ActionDialog Header="Delete Module" Message="@string.Format(Localizer["Confirm.Module.Delete"], context.Title)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteModule(context))" ResourceKey="DeleteModule" /></td>
|
||||||
<td>@PageState.Pages.Find(item => item.PageId == context.PageId).Name</td>
|
<td>@PageState.Pages.Find(item => item.PageId == context.PageId).Name</td>
|
||||||
<td>@context.Title</td>
|
<td>@context.Title</td>
|
||||||
|
@ -7,21 +7,28 @@
|
|||||||
|
|
||||||
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
<form @ref="form" class="@(validated ? "was-validated" : "needs-validation")" novalidate>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="form-group">
|
<div class="row mb-1 align-items-center">
|
||||||
<label for="Username" class="control-label">@SharedLocalizer["Username"] </label>
|
<Label Class="col-sm-3" For="username" HelpText="Your username will be populated from the link you received in the password reset notification" ResourceKey="Username">Username: </Label>
|
||||||
<input type="text" class="form-control" placeholder="Username" @bind="@_username" readonly id="Username" />
|
<div class="col-sm-9">
|
||||||
|
<input id="username" type="text" class="form-control" @bind="@_username" readonly />
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
|
||||||
<label for="Password" class="control-label">@SharedLocalizer["Password"] </label>
|
|
||||||
<input type="password" class="form-control" placeholder="Password" @bind="@_password" id="Password" required />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="row mb-1 align-items-center">
|
||||||
<label for="Confirm" class="control-label">@Localizer["Password.Confirm"] </label>
|
<Label Class="col-sm-3" For="password" HelpText="The new password. It must satisfy complexity rules for the site." ResourceKey="Password">Password: </Label>
|
||||||
<input type="password" class="form-control" placeholder="Password" @bind="@_confirm" id="Confirm" required />
|
<div class="col-sm-9">
|
||||||
|
<input id="password" type="password" class="form-control" @bind="@_password" required />
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="confirm" HelpText="Enter the password again. It must exactly match the password entered above." ResourceKey="Confirm">Confirm: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="confirm" type="password" class="form-control" @bind="@_confirm" required />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
<button type="button" class="btn btn-primary" @onclick="Reset">@Localizer["Password.Reset"]</button>
|
<button type="button" class="btn btn-primary" @onclick="Reset">@Localizer["Password.Reset"]</button>
|
||||||
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
@ -33,7 +40,7 @@
|
|||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token"))
|
if (PageState.QueryString.ContainsKey("name") && PageState.QueryString.ContainsKey("token"))
|
||||||
{
|
{
|
||||||
@ -41,7 +48,8 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(string.Empty));
|
await logger.LogError(LogFunction.Security, "Invalid Attempt To Access User Password Reset");
|
||||||
|
NavigationManager.NavigateTo(NavigateUrl("")); // home page
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,14 @@ else
|
|||||||
<Pager Items="@userroles">
|
<Pager Items="@userroles">
|
||||||
<Header>
|
<Header>
|
||||||
<th>@Localizer["Users"]</th>
|
<th>@Localizer["Users"]</th>
|
||||||
|
<th>@SharedLocalizer["Username"]</th>
|
||||||
<th>@Localizer["Effective"]</th>
|
<th>@Localizer["Effective"]</th>
|
||||||
<th>@Localizer["Expiry"]</th>
|
<th>@Localizer["Expiry"]</th>
|
||||||
<th> </th>
|
<th> </th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>@context.User.DisplayName</td>
|
<td>@context.User.DisplayName</td>
|
||||||
|
<td>@context.User.Username</td>
|
||||||
<td>@context.EffectiveDate</td>
|
<td>@context.EffectiveDate</td>
|
||||||
<td>@context.ExpiryDate</td>
|
<td>@context.ExpiryDate</td>
|
||||||
<td>
|
<td>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Site
|
@namespace Oqtane.Modules.Admin.Site
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
|
@using System.Text.RegularExpressions
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
@inject ITenantService TenantService
|
@inject ITenantService TenantService
|
||||||
@ -21,31 +22,6 @@
|
|||||||
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
<input id="name" class="form-control" @bind="@_name" maxlength="200" required />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="alias" HelpText="The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they should be separated by commas." ResourceKey="Aliases">Aliases: </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
|
||||||
{
|
|
||||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" required></textarea>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" readonly></textarea>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row mb-1 align-items-center">
|
|
||||||
<Label Class="col-sm-3" For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Is Deleted? </Label>
|
|
||||||
<div class="col-sm-9">
|
|
||||||
<select id="isDeleted" class="form-select" @bind="@_isdeleted" required>
|
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Section Name="Appearance" Heading="Appearance" ResourceKey="Appearance">
|
|
||||||
<div class="container">
|
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
<Label Class="col-sm-3" For="logo" HelpText="Specify a logo for the site" ResourceKey="Logo">Logo: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
@ -94,9 +70,17 @@
|
|||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="isDeleted" HelpText="Is this site deleted?" ResourceKey="IsDeleted">Deleted? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="isDeleted" class="form-select" @bind="@_isdeleted" required>
|
||||||
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
|
||||||
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
<Section Name="SMTP" Heading="SMTP Settings" ResourceKey="SMTPSettings">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -174,8 +158,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Section>
|
</Section>
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
@if (_aliases != null && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
|
<Section Name="Aliases" Heading="Aliases" ResourceKey="Aliases">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="alias" HelpText="The aliases for the site. An alias can be a domain name (www.site.com) or a virtual folder (ie. www.site.com/folder). If a site has multiple aliases they should be separated by commas." ResourceKey="Aliases">Aliases: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="alias" class="form-control" @bind="@_urls" rows="3" required></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="defaultalias" HelpText="The default alias for the site. Requests for non-default aliases will be redirected to the default alias." ResourceKey="DefaultAlias">Default Alias: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="defaultalias" class="form-select" @bind="@_defaultalias" required>
|
||||||
|
@foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray())
|
||||||
|
{
|
||||||
|
<option value="@name">@name</option>
|
||||||
|
}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Section>
|
||||||
<Section Name="Hosting" Heading="Hosting Model" ResourceKey="Hosting">
|
<Section Name="Hosting" Heading="Hosting Model" ResourceKey="Hosting">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
@ -238,7 +243,8 @@
|
|||||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||||
private string _name = string.Empty;
|
private string _name = string.Empty;
|
||||||
private List<Alias> _aliasList;
|
private List<Alias> _aliases;
|
||||||
|
private string _defaultalias = string.Empty;
|
||||||
private string _urls = string.Empty;
|
private string _urls = string.Empty;
|
||||||
private string _runtime = "";
|
private string _runtime = "";
|
||||||
private string _prerender = "";
|
private string _prerender = "";
|
||||||
@ -288,13 +294,7 @@
|
|||||||
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
_aliasList = await AliasService.GetAliasesAsync();
|
await GetAliases();
|
||||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
|
||||||
{
|
|
||||||
_urls += alias.Name + ",";
|
|
||||||
}
|
|
||||||
_urls = _urls.Substring(0, _urls.Length - 1);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site.LogoFileId != null)
|
if (site.LogoFileId != null)
|
||||||
@ -398,13 +398,17 @@
|
|||||||
var unique = true;
|
var unique = true;
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
_urls = Regex.Replace(_urls, @"\r\n?|\n", ","); // convert line breaks to commas
|
||||||
|
var aliases = await AliasService.GetAliasesAsync();
|
||||||
|
foreach (string name in _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(sValue => sValue.Trim()).ToArray())
|
||||||
{
|
{
|
||||||
if (_aliasList.Exists(item => item.Name == name && item.SiteId != PageState.Alias.SiteId && item.TenantId != PageState.Alias.TenantId))
|
var alias = aliases.Where(item => item.Name == name).FirstOrDefault();
|
||||||
|
if (alias != null && unique)
|
||||||
{
|
{
|
||||||
unique = false;
|
unique = (alias.TenantId == PageState.Site.TenantId && alias.SiteId == PageState.Site.SiteId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (unique && string.IsNullOrEmpty(_defaultalias)) unique = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unique)
|
if (unique)
|
||||||
@ -422,7 +426,6 @@
|
|||||||
{
|
{
|
||||||
site.Runtime = _runtime;
|
site.Runtime = _runtime;
|
||||||
site.RenderMode = _runtime + _prerender;
|
site.RenderMode = _runtime + _prerender;
|
||||||
refresh = true;
|
|
||||||
reload = true; // needs to be reloaded on server
|
reload = true; // needs to be reloaded on server
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -476,20 +479,21 @@
|
|||||||
site = await SiteService.UpdateSiteAsync(site);
|
site = await SiteService.UpdateSiteAsync(site);
|
||||||
|
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
var settings = await SettingService.GetSiteSettingsAsync(site.SiteId);
|
||||||
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
|
SettingService.SetSetting(settings, "SMTPHost", _smtphost, true);
|
||||||
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
|
SettingService.SetSetting(settings, "SMTPPort", _smtpport, true);
|
||||||
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
|
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl, true);
|
||||||
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
|
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true);
|
||||||
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
|
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true);
|
||||||
SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
|
SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true);
|
||||||
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
||||||
|
|
||||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
{
|
{
|
||||||
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||||
foreach (Alias alias in _aliasList.Where(item => item.SiteId == site.SiteId && item.TenantId == site.TenantId).ToList())
|
.Select(sValue => sValue.Trim()).ToArray();
|
||||||
|
foreach (Alias alias in _aliases)
|
||||||
{
|
{
|
||||||
if (!names.Contains(alias.Name))
|
if (!names.Contains(alias.Name.Trim()))
|
||||||
{
|
{
|
||||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||||
}
|
}
|
||||||
@ -497,30 +501,43 @@
|
|||||||
|
|
||||||
foreach (string name in names)
|
foreach (string name in names)
|
||||||
{
|
{
|
||||||
if (!_aliasList.Exists(item => item.Name == name))
|
var alias = _aliases.Find(item => item.Name.Trim() == name);
|
||||||
|
if (alias == null)
|
||||||
{
|
{
|
||||||
Alias alias = new Alias();
|
alias = new Alias();
|
||||||
alias.Name = name;
|
alias.Name = name;
|
||||||
alias.TenantId = site.TenantId;
|
alias.TenantId = site.TenantId;
|
||||||
alias.SiteId = site.SiteId;
|
alias.SiteId = site.SiteId;
|
||||||
|
alias.IsDefault = (name == _defaultalias);
|
||||||
await AliasService.AddAliasAsync(alias);
|
await AliasService.AddAliasAsync(alias);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (alias.Name != name || alias.IsDefault != (alias.Name.Trim() == _defaultalias))
|
||||||
|
{
|
||||||
|
alias.Name = name;
|
||||||
|
alias.IsDefault = (name == _defaultalias);
|
||||||
|
await AliasService.UpdateAliasAsync(alias);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
await GetAliases();
|
||||||
|
}
|
||||||
|
|
||||||
await logger.LogInformation("Site Settings Saved {Site}", site);
|
await logger.LogInformation("Site Settings Saved {Site}", site);
|
||||||
|
|
||||||
if (refresh)
|
if (refresh || reload)
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(NavigateUrl(true), reload); // refresh/reload
|
NavigationManager.NavigateTo(NavigateUrl(true), reload); // refresh/reload
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
|
AddModuleMessage(Localizer["Success.Settings.SaveSite"], MessageType.Success);
|
||||||
|
await interop.ScrollTo(0, 0, "smooth");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // deuplicate alias or default alias not specified
|
||||||
{
|
{
|
||||||
AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
@ -579,12 +596,12 @@
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
SettingService.SetSetting(settings, "SMTPHost", _smtphost);
|
SettingService.SetSetting(settings, "SMTPHost", _smtphost, true);
|
||||||
SettingService.SetSetting(settings, "SMTPPort", _smtpport);
|
SettingService.SetSetting(settings, "SMTPPort", _smtpport, true);
|
||||||
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl);
|
SettingService.SetSetting(settings, "SMTPSSL", _smtpssl, true);
|
||||||
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername);
|
SettingService.SetSetting(settings, "SMTPUsername", _smtpusername, true);
|
||||||
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword);
|
SettingService.SetSetting(settings, "SMTPPassword", _smtppassword, true);
|
||||||
SettingService.SetSetting(settings, "SMTPSender", _smtpsender);
|
SettingService.SetSetting(settings, "SMTPSender", _smtpsender, true);
|
||||||
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
||||||
await logger.LogInformation("Site SMTP Settings Saved");
|
await logger.LogInformation("Site SMTP Settings Saved");
|
||||||
|
|
||||||
@ -602,4 +619,18 @@
|
|||||||
AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning);
|
AddModuleMessage(Localizer["Message.required.Smtp"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task GetAliases()
|
||||||
|
{
|
||||||
|
_urls = string.Empty;
|
||||||
|
_defaultalias = string.Empty;
|
||||||
|
_aliases = await AliasService.GetAliasesAsync();
|
||||||
|
_aliases = _aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId).OrderBy(item => item.AliasId).ToList();
|
||||||
|
foreach (Alias alias in _aliases)
|
||||||
|
{
|
||||||
|
_urls += (_urls == string.Empty) ? alias.Name.Trim() : ", " + alias.Name.Trim();
|
||||||
|
if (alias.IsDefault && string.IsNullOrEmpty(_defaultalias)) _defaultalias = alias.Name.Trim();
|
||||||
|
}
|
||||||
|
if (string.IsNullOrEmpty(_defaultalias)) _defaultalias = _aliases.First().Name.Trim();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
@namespace Oqtane.Modules.Admin.Sites
|
@namespace Oqtane.Modules.Admin.Sites
|
||||||
@using Oqtane.Interfaces
|
@using Oqtane.Interfaces
|
||||||
|
@using System.Text.RegularExpressions
|
||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject NavigationManager NavigationManager
|
@inject NavigationManager NavigationManager
|
||||||
@inject ITenantService TenantService
|
@inject ITenantService TenantService
|
||||||
@ -282,6 +283,7 @@ else
|
|||||||
{
|
{
|
||||||
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-" && _sitetemplatetype != "-")
|
if (_tenantid != "-" && _name != string.Empty && _urls != string.Empty && _themetype != "-" && _containertype != "-" && _sitetemplatetype != "-")
|
||||||
{
|
{
|
||||||
|
_urls = Regex.Replace(_urls, @"\r\n?|\n", ",");
|
||||||
var duplicates = new List<string>();
|
var duplicates = new List<string>();
|
||||||
var aliases = await AliasService.GetAliasesAsync();
|
var aliases = await AliasService.GetAliasesAsync();
|
||||||
foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
foreach (string name in _urls.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
|
||||||
@ -370,8 +372,7 @@ else
|
|||||||
if (installation.Success)
|
if (installation.Success)
|
||||||
{
|
{
|
||||||
var aliasname = config.Aliases.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
var aliasname = config.Aliases.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
||||||
var uri = new Uri(NavigationManager.Uri);
|
NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + aliasname, true);
|
||||||
NavigationManager.NavigateTo(uri.Scheme + "://" + aliasname, true);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -30,20 +30,16 @@ else
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<Alias> _sites;
|
private List<Alias> _sites;
|
||||||
private string _scheme;
|
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
var uri = new Uri(NavigationManager.Uri);
|
|
||||||
_scheme = uri.Scheme + "://";
|
|
||||||
|
|
||||||
var aliases = await AliasService.GetAliasesAsync();
|
var aliases = await AliasService.GetAliasesAsync();
|
||||||
_sites = new List<Alias>();
|
_sites = new List<Alias>();
|
||||||
foreach (Alias alias in aliases)
|
foreach (Alias alias in aliases)
|
||||||
{
|
{
|
||||||
if (!_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
|
if (alias.IsDefault && !_sites.Exists(item => item.TenantId == alias.TenantId && item.SiteId == alias.SiteId))
|
||||||
{
|
{
|
||||||
_sites.Add(alias);
|
_sites.Add(alias);
|
||||||
}
|
}
|
||||||
@ -52,16 +48,11 @@ else
|
|||||||
|
|
||||||
private void Edit(string name)
|
private void Edit(string name)
|
||||||
{
|
{
|
||||||
if (name.Equals("*"))
|
NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + name + "/admin/site", true);
|
||||||
{
|
|
||||||
var uri = new Uri(NavigationManager.Uri);
|
|
||||||
name = uri.Authority;
|
|
||||||
}
|
|
||||||
NavigationManager.NavigateTo(_scheme + name + "/admin/site/?reload");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Browse(string name)
|
private void Browse(string name)
|
||||||
{
|
{
|
||||||
NavigationManager.NavigateTo(_scheme + name + "/?reload");
|
NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + name, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,6 @@ else
|
|||||||
{
|
{
|
||||||
@if (_results.Count > 0)
|
@if (_results.Count > 0)
|
||||||
{
|
{
|
||||||
<div class="table-responsive">
|
|
||||||
<Pager Class="table table-bordered" Items="@_results">
|
<Pager Class="table table-bordered" Items="@_results">
|
||||||
<Header>
|
<Header>
|
||||||
@foreach (KeyValuePair<string, string> kvp in _results.First())
|
@foreach (KeyValuePair<string, string> kvp in _results.First())
|
||||||
@ -72,7 +71,6 @@ else
|
|||||||
}
|
}
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
</div>
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="servertime" HelpText="Server Time" ResourceKey="ServerTime">Server Time: </Label>
|
<Label Class="col-sm-3" For="servertime" HelpText="Server Date/Time (in UTC)" ResourceKey="ServerTime">Server Date/Time: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="servertime" class="form-control" @bind="@_servertime" readonly />
|
<input id="servertime" class="form-control" @bind="@_servertime" readonly />
|
||||||
</div>
|
</div>
|
||||||
@ -123,7 +123,7 @@
|
|||||||
_clrversion = systeminfo["clrversion"];
|
_clrversion = systeminfo["clrversion"];
|
||||||
_osversion = systeminfo["osversion"];
|
_osversion = systeminfo["osversion"];
|
||||||
_serverpath = systeminfo["serverpath"];
|
_serverpath = systeminfo["serverpath"];
|
||||||
_servertime = systeminfo["servertime"];
|
_servertime = systeminfo["servertime"] + " UTC";
|
||||||
_installationid = systeminfo["installationid"];
|
_installationid = systeminfo["installationid"];
|
||||||
|
|
||||||
_detailederrors = systeminfo["detailederrors"];
|
_detailederrors = systeminfo["detailederrors"];
|
||||||
|
@ -40,13 +40,21 @@
|
|||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
if (await interop.FormValid(form))
|
if (await interop.FormValid(form))
|
||||||
{
|
{
|
||||||
var route = new Route(_url, PageState.Alias.Path);
|
if (_url != _mappedurl)
|
||||||
var url = route.SiteUrl + "/" + route.PagePath;
|
{
|
||||||
|
var url = PageState.Uri.Scheme + "://" + PageState.Uri.Authority + "/";
|
||||||
|
url = url + (!string.IsNullOrEmpty(PageState.Alias.Path) ? PageState.Alias.Path + "/" : "");
|
||||||
|
|
||||||
|
_url = (_url.StartsWith("/")) ? _url.Substring(1) : _url;
|
||||||
|
_url = (!_url.StartsWith("http")) ? url + _url : _url;
|
||||||
|
|
||||||
|
if (_url.StartsWith(url))
|
||||||
|
{
|
||||||
var urlmapping = new UrlMapping();
|
var urlmapping = new UrlMapping();
|
||||||
urlmapping.SiteId = PageState.Site.SiteId;
|
urlmapping.SiteId = PageState.Site.SiteId;
|
||||||
urlmapping.Url = url;
|
var route = new Route(_url, PageState.Alias.Path);
|
||||||
urlmapping.MappedUrl = _mappedurl;
|
urlmapping.Url = route.PagePath;
|
||||||
|
urlmapping.MappedUrl = _mappedurl.Replace(url, "");
|
||||||
urlmapping.Requests = 0;
|
urlmapping.Requests = 0;
|
||||||
urlmapping.CreatedOn = DateTime.UtcNow;
|
urlmapping.CreatedOn = DateTime.UtcNow;
|
||||||
urlmapping.RequestedOn = DateTime.UtcNow;
|
urlmapping.RequestedOn = DateTime.UtcNow;
|
||||||
@ -64,6 +72,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.SaveUrlMapping"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.DuplicateUrlMapping"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
|
@ -60,23 +60,32 @@
|
|||||||
var interop = new Interop(JSRuntime);
|
var interop = new Interop(JSRuntime);
|
||||||
if (await interop.FormValid(form))
|
if (await interop.FormValid(form))
|
||||||
{
|
{
|
||||||
var urlmapping = await UrlMappingService.GetUrlMappingAsync(_urlmappingid);
|
if (_url != _mappedurl)
|
||||||
urlmapping.MappedUrl = _mappedurl;
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var url = PageState.Uri.Scheme + "://" + PageState.Uri.Authority + "/";
|
||||||
|
url = url + (!string.IsNullOrEmpty(PageState.Alias.Path) ? PageState.Alias.Path + "/" : "");
|
||||||
|
|
||||||
|
var urlmapping = await UrlMappingService.GetUrlMappingAsync(_urlmappingid);
|
||||||
|
urlmapping.MappedUrl = _mappedurl.Replace(url, "");
|
||||||
urlmapping = await UrlMappingService.UpdateUrlMappingAsync(urlmapping);
|
urlmapping = await UrlMappingService.UpdateUrlMappingAsync(urlmapping);
|
||||||
await logger.LogInformation("UrlMapping Saved {UrlMapping}", urlmapping);
|
await logger.LogInformation("UrlMapping Saved {UrlMapping}", urlmapping);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
await logger.LogError(ex, "Error Saving UrlMapping {UrlMapping} {Error}", urlmapping, ex.Message);
|
await logger.LogError(ex, "Error Saving UrlMapping {UrlMappingId} {Error}", _urlmappingid, ex.Message);
|
||||||
AddModuleMessage(Localizer["Error.SaveUrlMapping"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.SaveUrlMapping"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
AddModuleMessage(Localizer["Message.DuplicateUrlMapping"], MessageType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
AddModuleMessage(SharedLocalizer["Message.InfoRequired"], MessageType.Warning);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,10 +40,10 @@ else
|
|||||||
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.UrlMappingId.ToString())" ResourceKey="Edit" /></td>
|
<td><ActionLink Action="Edit" Parameters="@($"id=" + context.UrlMappingId.ToString())" ResourceKey="Edit" /></td>
|
||||||
<td><ActionDialog Header="Delete Url Mapping" Message="@string.Format(Localizer["Confirm.DeleteUrlMapping"], context.Url)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUrlMapping(context))" ResourceKey="DeleteUrlMapping" /></td>
|
<td><ActionDialog Header="Delete Url Mapping" Message="@string.Format(Localizer["Confirm.DeleteUrlMapping"], context.Url)" Action="Delete" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteUrlMapping(context))" ResourceKey="DeleteUrlMapping" /></td>
|
||||||
<td>
|
<td>
|
||||||
<a href="" onclick="@(() => BrowseUrl(context.Url))">@context.Url</a>
|
<a href="@Utilities.TenantUrl(PageState.Alias, context.Url)">@context.Url</a>
|
||||||
@if (_mapped)
|
@if (_mapped)
|
||||||
{
|
{
|
||||||
@((MarkupString)"<br />>> ")<a href="" onclick="@(() => BrowseUrl(context.MappedUrl))">@context.MappedUrl</a>
|
@((MarkupString)"<br />>> ")<a href="@((context.MappedUrl.StartsWith("http") ? context.MappedUrl : Utilities.TenantUrl(PageState.Alias, context.MappedUrl)))">@context.MappedUrl</a>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>@context.Requests</td>
|
<td>@context.Requests</td>
|
||||||
@ -96,11 +96,6 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BrowseUrl(string url)
|
|
||||||
{
|
|
||||||
NavigationManager.NavigateTo(url, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task DeleteUrlMapping(UrlMapping urlMapping)
|
private async Task DeleteUrlMapping(UrlMapping urlMapping)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<Label Class="col-sm-3" For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
|
<Label Class="col-sm-3" For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input id="to" class="form-control" @bind="@username" />
|
<input id="to" class="form-control" @bind="@username" />
|
||||||
</div> >
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="subject" HelpText="Enter the subject of the message" ResourceKey="Subject">Subject: </Label>
|
<Label Class="col-sm-3" For="subject" HelpText="Enter the subject of the message" ResourceKey="Subject">Subject: </Label>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
@if (PageState.User != null && photo != null)
|
@if (PageState.User != null && photo != null)
|
||||||
{
|
{
|
||||||
<img src="@ImageUrl(photofileid, 400, 400, "crop")" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
<img src="@ImageUrl(photofileid, 400, 400)" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -36,6 +36,7 @@ else
|
|||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@SharedLocalizer["Name"]</th>
|
<th>@SharedLocalizer["Name"]</th>
|
||||||
|
<th>@SharedLocalizer["Username"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td>
|
<td>
|
||||||
@ -48,6 +49,7 @@ else
|
|||||||
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" />
|
<ActionLink Action="Roles" Parameters="@($"id=" + context.UserId.ToString())" ResourceKey="Roles" />
|
||||||
</td>
|
</td>
|
||||||
<td>@context.User.DisplayName</td>
|
<td>@context.User.DisplayName</td>
|
||||||
|
<td>@context.User.Username</td>
|
||||||
</Row>
|
</Row>
|
||||||
</Pager>
|
</Pager>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
@ -89,7 +91,7 @@ else
|
|||||||
{
|
{
|
||||||
var results = allroles.Where(item => item.Role.Name == RoleNames.Registered || (item.Role.Name == RoleNames.Host && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)));
|
var results = allroles.Where(item => item.Role.Name == RoleNames.Registered || (item.Role.Name == RoleNames.Host && UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)));
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(_search))
|
if (!string.IsNullOrEmpty(_search))
|
||||||
{
|
{
|
||||||
results = results.Where(item =>
|
results = results.Where(item =>
|
||||||
(
|
(
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
@inject IStringLocalizer<Detail> Localizer
|
@inject IStringLocalizer<Detail> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
@if (_initialized)
|
||||||
|
{
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="ip" HelpText="The last recorded IP address for this visitor" ResourceKey="IP">IP Address: </Label>
|
<Label Class="col-sm-3" For="ip" HelpText="The last recorded IP address for this visitor" ResourceKey="IP">IP Address: </Label>
|
||||||
@ -66,10 +68,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@CloseUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private bool _initialized = false;
|
||||||
private int _visitorId;
|
private int _visitorId;
|
||||||
private string _ip = string.Empty;
|
private string _ip = string.Empty;
|
||||||
private string _language = string.Empty;
|
private string _language = string.Empty;
|
||||||
@ -108,6 +112,7 @@
|
|||||||
_user = user.DisplayName;
|
_user = user.DisplayName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_initialized = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -120,4 +125,16 @@
|
|||||||
AddModuleMessage(Localizer["Error.LoadVisitor"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.LoadVisitor"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string CloseUrl()
|
||||||
|
{
|
||||||
|
if (!PageState.QueryString.ContainsKey("type"))
|
||||||
|
{
|
||||||
|
return NavigateUrl();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NavigateUrl(PageState.Page.Path, "type=" + PageState.QueryString["type"] + "&days=" + PageState.QueryString["days"] + "&page=" + PageState.QueryString["page"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
@inherits ModuleBase
|
@inherits ModuleBase
|
||||||
@inject IVisitorService VisitorService
|
@inject IVisitorService VisitorService
|
||||||
@inject ISiteService SiteService
|
@inject ISiteService SiteService
|
||||||
|
@inject ISettingService SettingService
|
||||||
@inject IStringLocalizer<Index> Localizer
|
@inject IStringLocalizer<Index> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
@ -16,13 +17,13 @@ else
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<select id="type" class="form-select custom-select" @onchange="(e => TypeChanged(e))">
|
<select id="type" class="form-select custom-select" value="@_type" @onchange="(e => TypeChanged(e))">
|
||||||
<option value="false">@Localizer["AllVisitors"]</option>
|
<option value="visitors">@Localizer["AllVisitors"]</option>
|
||||||
<option value="true">@Localizer["UsersOnly"]</option>
|
<option value="users">@Localizer["UsersOnly"]</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<select id="type" class="form-select custom-select" @onchange="(e => DateChanged(e))">
|
<select id="days" class="form-select custom-select" value="@_days" @onchange="(e => DaysChanged(e))">
|
||||||
<option value="1">@Localizer["PastDay"]</option>
|
<option value="1">@Localizer["PastDay"]</option>
|
||||||
<option value="7">@Localizer["PastWeek"]</option>
|
<option value="7">@Localizer["PastWeek"]</option>
|
||||||
<option value="30">@Localizer["PastMonth"]</option>
|
<option value="30">@Localizer["PastMonth"]</option>
|
||||||
@ -31,7 +32,7 @@ else
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br/>
|
<br/>
|
||||||
<Pager Items="@_visitors">
|
<Pager Items="@_visitors" CurrentPage="@_page.ToString()" OnPageChange="OnPageChange">
|
||||||
<Header>
|
<Header>
|
||||||
<th style="width: 1px;"> </th>
|
<th style="width: 1px;"> </th>
|
||||||
<th>@Localizer["IP"]</th>
|
<th>@Localizer["IP"]</th>
|
||||||
@ -42,7 +43,7 @@ else
|
|||||||
<th>@Localizer["Created"]</th>
|
<th>@Localizer["Created"]</th>
|
||||||
</Header>
|
</Header>
|
||||||
<Row>
|
<Row>
|
||||||
<td><ActionLink Action="Detail" Parameters="@($"id=" + context.VisitorId.ToString())" ResourceKey="Details" /></td>
|
<td><ActionLink Action="Detail" Parameters="@($"id=" + context.VisitorId.ToString() + "&type=" + _type.ToString() + "&days=" + _days.ToString() + "&page=" + _page.ToString())" ResourceKey="Details" /></td>
|
||||||
<td>@context.IPAddress</td>
|
<td>@context.IPAddress</td>
|
||||||
<td>
|
<td>
|
||||||
@if (context.UserId != null)
|
@if (context.UserId != null)
|
||||||
@ -60,14 +61,35 @@ else
|
|||||||
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
|
<TabPanel Name="Settings" Heading="Settings" ResourceKey="Settings">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="visitortracking" HelpText="Specify if visitor tracking is enabled" ResourceKey="VisitorTracking">Visitor Tracking Enabled? </Label>
|
<Label Class="col-sm-3" For="tracking" HelpText="Specify if visitor tracking is enabled" ResourceKey="Tracking">Tracking Enabled? </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="visitortracking" class="form-select" @bind="@_visitortracking" >
|
<select id="tracking" class="form-select" @bind="@_tracking" >
|
||||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||||
<option value="False">@SharedLocalizer["No"]</option>
|
<option value="False">@SharedLocalizer["No"]</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="filter" HelpText="Comma delimited list of terms which may exist in IP addresses, user agents, or languages identifying visitors which should not be tracked" ResourceKey="Filter">Filter: </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea id="filter" class="form-control" @bind="@_filter" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="retention" HelpText="Number of days of visitor activity to retain" ResourceKey="Retention">Retention (Days): </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input id="retention" class="form-control" @bind="@_retention" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-1 align-items-center">
|
||||||
|
<Label Class="col-sm-3" For="correlation" HelpText="Indicate if new visitors to this site should be correlated based on their IP Address" ResourceKey="Correlation">Correlate Visitors? </Label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<select id="correlation" class="form-select" @bind="@_correlation">
|
||||||
|
<option value="true">@SharedLocalizer["True"]</option>
|
||||||
|
<option value="false">@SharedLocalizer["False"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
||||||
@ -76,24 +98,46 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private bool _users = false;
|
private string _type = "visitors";
|
||||||
private int _days = 1;
|
private int _days = 1;
|
||||||
|
private int _page = 1;
|
||||||
private List<Visitor> _visitors;
|
private List<Visitor> _visitors;
|
||||||
private string _visitortracking;
|
private string _tracking;
|
||||||
|
private string _filter = "";
|
||||||
|
private string _retention = "";
|
||||||
|
private string _correlation = "true";
|
||||||
|
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
|
if (PageState.QueryString.ContainsKey("type"))
|
||||||
|
{
|
||||||
|
_type = PageState.QueryString["type"];
|
||||||
|
}
|
||||||
|
if (PageState.QueryString.ContainsKey("days") && int.TryParse(PageState.QueryString["days"], out int days))
|
||||||
|
{
|
||||||
|
_days = days;
|
||||||
|
}
|
||||||
|
if (PageState.QueryString.ContainsKey("page") && int.TryParse(PageState.QueryString["page"], out int page))
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
}
|
||||||
|
|
||||||
await GetVisitors();
|
await GetVisitors();
|
||||||
_visitortracking = PageState.Site.VisitorTracking.ToString();
|
|
||||||
|
_tracking = PageState.Site.VisitorTracking.ToString();
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
_filter = SettingService.GetSetting(settings, "VisitorFilter", Constants.DefaultVisitorFilter);
|
||||||
|
_retention = SettingService.GetSetting(settings, "VisitorRetention", "30");
|
||||||
|
_correlation = SettingService.GetSetting(settings, "VisitorCorrelation", "true");
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void TypeChanged(ChangeEventArgs e)
|
private async void TypeChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_users = bool.Parse(e.Value.ToString());
|
_type = e.Value.ToString();
|
||||||
await GetVisitors();
|
await GetVisitors();
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
@ -103,7 +147,7 @@ else
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void DateChanged(ChangeEventArgs e)
|
private async void DaysChanged(ChangeEventArgs e)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -120,7 +164,7 @@ else
|
|||||||
private async Task GetVisitors()
|
private async Task GetVisitors()
|
||||||
{
|
{
|
||||||
_visitors = await VisitorService.GetVisitorsAsync(PageState.Site.SiteId, DateTime.UtcNow.AddDays(-_days));
|
_visitors = await VisitorService.GetVisitorsAsync(PageState.Site.SiteId, DateTime.UtcNow.AddDays(-_days));
|
||||||
if (_users)
|
if (_type == "users")
|
||||||
{
|
{
|
||||||
_visitors = _visitors.Where(item => item.UserId != null).ToList();
|
_visitors = _visitors.Where(item => item.UserId != null).ToList();
|
||||||
}
|
}
|
||||||
@ -131,8 +175,15 @@ else
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var site = PageState.Site;
|
var site = PageState.Site;
|
||||||
site.VisitorTracking = bool.Parse(_visitortracking);
|
site.VisitorTracking = bool.Parse(_tracking);
|
||||||
await SiteService.UpdateSiteAsync(site);
|
await SiteService.UpdateSiteAsync(site);
|
||||||
|
|
||||||
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
|
settings = SettingService.SetSetting(settings, "VisitorFilter", _filter, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "VisitorRetention", _retention, true);
|
||||||
|
settings = SettingService.SetSetting(settings, "VisitorCorrelation", _correlation, true);
|
||||||
|
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
||||||
|
|
||||||
AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success);
|
AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -141,4 +192,9 @@ else
|
|||||||
AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.SaveSiteSettings"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnPageChange(int page)
|
||||||
|
{
|
||||||
|
_page = page;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ else
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string HelpText { get; set; } // optional - tooltip for this label
|
public string HelpText { get; set; } // optional - tooltip for this label
|
||||||
|
|
||||||
private string _spanclass = "app-tooltip";
|
private string _spanclass;
|
||||||
private string _labelclass = "form-label";
|
private string _labelclass;
|
||||||
private string _helptext = string.Empty;
|
private string _helptext = string.Empty;
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
@ -36,11 +36,15 @@ else
|
|||||||
if (!string.IsNullOrEmpty(HelpText))
|
if (!string.IsNullOrEmpty(HelpText))
|
||||||
{
|
{
|
||||||
_helptext = Localize(nameof(HelpText), HelpText);
|
_helptext = Localize(nameof(HelpText), HelpText);
|
||||||
_spanclass += (!string.IsNullOrEmpty(Class)) ? " " + Class : "";
|
_labelclass = "form-label";
|
||||||
|
|
||||||
|
var spanclass = (!string.IsNullOrEmpty(Class)) ? " " + Class : "";
|
||||||
|
_spanclass = "app-tooltip" + spanclass;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_labelclass += (!string.IsNullOrEmpty(Class)) ? " " + Class : "";
|
var labelclass = (!string.IsNullOrEmpty(Class)) ? " " + Class : "";
|
||||||
|
_labelclass = "form-label" + labelclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
var text = Localize("Text", String.Empty);
|
var text = Localize("Text", String.Empty);
|
||||||
|
@ -13,6 +13,9 @@ namespace Oqtane.Modules.Controls
|
|||||||
[Parameter]
|
[Parameter]
|
||||||
public string ResourceKey { get; set; }
|
public string ResourceKey { get; set; }
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string ResourceType { get; set; }
|
||||||
|
|
||||||
protected bool IsLocalizable { get; private set; }
|
protected bool IsLocalizable { get; private set; }
|
||||||
|
|
||||||
protected string Localize(string name) => _localizer?[name] ?? name;
|
protected string Localize(string name) => _localizer?[name] ?? name;
|
||||||
@ -50,9 +53,14 @@ namespace Oqtane.Modules.Controls
|
|||||||
{
|
{
|
||||||
IsLocalizable = false;
|
IsLocalizable = false;
|
||||||
|
|
||||||
if (!String.IsNullOrEmpty(ResourceKey) && ModuleState?.ModuleType != null)
|
if (string.IsNullOrEmpty(ResourceType))
|
||||||
{
|
{
|
||||||
var moduleType = Type.GetType(ModuleState.ModuleType);
|
ResourceType = ModuleState?.ModuleType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.IsNullOrEmpty(ResourceKey) && !string.IsNullOrEmpty(ResourceType))
|
||||||
|
{
|
||||||
|
var moduleType = Type.GetType(ResourceType);
|
||||||
if (moduleType != null)
|
if (moduleType != null)
|
||||||
{
|
{
|
||||||
using (var scope = ServiceActivator.GetScope())
|
using (var scope = ServiceActivator.GetScope())
|
||||||
|
@ -54,14 +54,15 @@
|
|||||||
}
|
}
|
||||||
@if (Format == "Table" && Row != null)
|
@if (Format == "Table" && Row != null)
|
||||||
{
|
{
|
||||||
|
<div class="table-responsive">
|
||||||
<table class="@Class">
|
<table class="@Class">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>@Header</tr>
|
<tr class="@RowClass">@Header</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@foreach (var item in ItemList)
|
@foreach (var item in ItemList)
|
||||||
{
|
{
|
||||||
<tr>@Row(item)</tr>
|
<tr class="@RowClass">@Row(item)</tr>
|
||||||
@if (Detail != null)
|
@if (Detail != null)
|
||||||
{
|
{
|
||||||
<tr>@Detail(item)</tr>
|
<tr>@Detail(item)</tr>
|
||||||
@ -69,32 +70,42 @@
|
|||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
@if (Format == "Grid" && Row != null)
|
@if (Format == "Grid" && Row != null)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
int rows = 0;
|
||||||
|
int cols = 0;
|
||||||
if (ItemList != null)
|
if (ItemList != null)
|
||||||
|
{
|
||||||
|
if (_columns == 0)
|
||||||
|
{
|
||||||
|
count = ItemList.Count();
|
||||||
|
rows = 1;
|
||||||
|
cols = count;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
count = (int)Math.Ceiling(ItemList.Count() / (decimal)_columns) * _columns;
|
count = (int)Math.Ceiling(ItemList.Count() / (decimal)_columns) * _columns;
|
||||||
|
rows = count / _columns;
|
||||||
|
cols = _columns;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
<div class="@Class">
|
<div class="@Class">
|
||||||
@if (Header != null)
|
@for (int row = 0; row < rows; row++)
|
||||||
{
|
{
|
||||||
<div class="row"><div class="col">@Header</div></div>
|
<div class="@RowClass">
|
||||||
}
|
@for (int col = 0; col < cols; col++)
|
||||||
@for (int row = 0; row < (count / _columns); row++)
|
|
||||||
{
|
|
||||||
<div class="row">
|
|
||||||
@for (int col = 0; col < _columns; col++)
|
|
||||||
{
|
{
|
||||||
int index = (row * _columns) + col;
|
int index = (row * _columns) + col;
|
||||||
if (index < ItemList.Count())
|
if (index < ItemList.Count())
|
||||||
{
|
{
|
||||||
<div class="col">@Row(ItemList.ElementAt(index))</div>
|
<div class="@ColumnClass">@Row(ItemList.ElementAt(index))</div>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<div class="col"> </div>
|
<div> </div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -107,7 +118,7 @@
|
|||||||
<li class="page-item@((_page > 1) ? "" : " disabled")">
|
<li class="page-item@((_page > 1) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="start" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => UpdateList(1))><span class="oi oi-media-step-backward" title="start" aria-hidden="true"></span></a>
|
||||||
</li>
|
</li>
|
||||||
@if (_pages > _displayPages)
|
@if (_pages > _displayPages && _displayPages > 1)
|
||||||
{
|
{
|
||||||
<li class="page-item@((_page > _displayPages) ? "" : " disabled")">
|
<li class="page-item@((_page > _displayPages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => SkipPages("back"))><span class="oi oi-media-skip-backward" title="skip back" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => SkipPages("back"))><span class="oi oi-media-skip-backward" title="skip back" aria-hidden="true"></span></a>
|
||||||
@ -135,7 +146,7 @@
|
|||||||
<li class="page-item@((_page < _pages) ? "" : " disabled")">
|
<li class="page-item@((_page < _pages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => NavigateToPage("next"))><span class="oi oi-chevron-right" title="next" aria-hidden="true"></span></a>
|
||||||
</li>
|
</li>
|
||||||
@if (_pages > _displayPages)
|
@if (_pages > _displayPages && _displayPages > 1)
|
||||||
{
|
{
|
||||||
<li class="page-item@((_endPage < _pages) ? "" : " disabled")">
|
<li class="page-item@((_endPage < _pages) ? "" : " disabled")">
|
||||||
<a class="page-link" @onclick=@(async () => SkipPages("forward"))><span class="oi oi-media-skip-forward" title="skip forward" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => SkipPages("forward"))><span class="oi oi-media-skip-forward" title="skip forward" aria-hidden="true"></span></a>
|
||||||
@ -145,7 +156,7 @@
|
|||||||
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
|
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="page-item disabled">
|
<li class="page-item disabled">
|
||||||
<a class="page-link">Page @_page of @_pages</a>
|
<a class="page-link" style="white-space: nowrap;">Page @_page of @_pages</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
}
|
}
|
||||||
@ -158,7 +169,7 @@
|
|||||||
private int _displayPages = 5;
|
private int _displayPages = 5;
|
||||||
private int _startPage = 0;
|
private int _startPage = 0;
|
||||||
private int _endPage = 0;
|
private int _endPage = 0;
|
||||||
private int _columns = 1;
|
private int _columns = 0;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Format { get; set; } // Table or Grid
|
public string Format { get; set; } // Table or Grid
|
||||||
@ -167,10 +178,10 @@
|
|||||||
public string Toolbar { get; set; } // Top, Bottom or Both
|
public string Toolbar { get; set; } // Top, Bottom or Both
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment Header { get; set; } = null;
|
public RenderFragment Header { get; set; } = null; // only applicable to Table layouts
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment<TableItem> Row { get; set; } = null;
|
public RenderFragment<TableItem> Row { get; set; } = null; // required
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public RenderFragment<TableItem> Detail { get; set; } = null; // only applicable to Table layouts
|
public RenderFragment<TableItem> Detail { get; set; } = null; // only applicable to Table layouts
|
||||||
@ -182,16 +193,25 @@
|
|||||||
public string PageSize { get; set; } // number of items to display on a page
|
public string PageSize { get; set; } // number of items to display on a page
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Columns { get; set; } // only applicable to Grid layouts
|
public string Columns { get; set; } // only applicable to Grid layouts - default is zero indicating use responsive behavior
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string CurrentPage { get; set; } // optional property to set the initial page to display
|
public string CurrentPage { get; set; } // sets the initial page to display
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string DisplayPages { get; set; } // maximum number of page numbers to display for user selection
|
public string DisplayPages { get; set; } // maximum number of page numbers to display for user selection
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
public string Class { get; set; }
|
public string Class { get; set; } // class for the containing element - ie. <table> for Table or <div> for Grid
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string RowClass { get; set; } // class for row element - ie. <tr> for Table or <div> for Grid
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public string ColumnClass { get; set; } // class for column element - only applicable to Grid format
|
||||||
|
|
||||||
|
[Parameter]
|
||||||
|
public Action<int> OnPageChange { get; set; } // a method to be executed in the calling component when the page changes
|
||||||
|
|
||||||
private IEnumerable<TableItem> ItemList { get; set; }
|
private IEnumerable<TableItem> ItemList { get; set; }
|
||||||
|
|
||||||
@ -215,7 +235,31 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Class = "container-fluid px-0";
|
Class = "container-fluid";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(RowClass))
|
||||||
|
{
|
||||||
|
if (Format == "Table")
|
||||||
|
{
|
||||||
|
RowClass = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RowClass = "row";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(ColumnClass))
|
||||||
|
{
|
||||||
|
if (Format == "Table")
|
||||||
|
{
|
||||||
|
ColumnClass = "";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ColumnClass = "col";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,6 +310,7 @@
|
|||||||
{
|
{
|
||||||
_endPage = _pages;
|
_endPage = _pages;
|
||||||
}
|
}
|
||||||
|
OnPageChange?.Invoke(_page);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +129,10 @@
|
|||||||
|
|
||||||
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
|
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
|
||||||
_roles.Insert(0, new Role { Name = RoleNames.Everyone });
|
_roles.Insert(0, new Role { Name = RoleNames.Everyone });
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
|
{
|
||||||
|
_roles.Add(new Role { Name = RoleNames.Host });
|
||||||
|
}
|
||||||
|
|
||||||
_permissions = new List<PermissionString>();
|
_permissions = new List<PermissionString>();
|
||||||
|
|
||||||
@ -186,9 +190,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool GetPermissionDisabled(string roleName)
|
private bool GetPermissionDisabled(string roleName)
|
||||||
=> roleName == RoleNames.Admin
|
=> (roleName == RoleNames.Admin && !UserSecurity.IsAuthorized(PageState.User, RoleNames.Host)) ? true : false;
|
||||||
? true
|
|
||||||
: false;
|
|
||||||
|
|
||||||
private async Task AddUser()
|
private async Task AddUser()
|
||||||
{
|
{
|
||||||
@ -253,6 +255,16 @@
|
|||||||
List<string> ids = permission.Permissions.Split(';').ToList();
|
List<string> ids = permission.Permissions.Split(';').ToList();
|
||||||
ids.Remove("!" + RoleNames.Everyone); // remove deny all users
|
ids.Remove("!" + RoleNames.Everyone); // remove deny all users
|
||||||
ids.Remove("!" + RoleNames.Registered); // remove deny registered users
|
ids.Remove("!" + RoleNames.Registered); // remove deny registered users
|
||||||
|
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||||
|
{
|
||||||
|
ids.Remove("!" + RoleNames.Admin); // remove deny administrators
|
||||||
|
ids.Remove("!" + RoleNames.Host); // remove deny host users
|
||||||
|
if (!ids.Contains(RoleNames.Host) && !ids.Contains(RoleNames.Admin))
|
||||||
|
{
|
||||||
|
// add administrators role if host user role is not assigned
|
||||||
|
ids.Add(RoleNames.Admin);
|
||||||
|
}
|
||||||
|
}
|
||||||
permission.Permissions = string.Join(";", ids.ToArray());
|
permission.Permissions = string.Join(";", ids.ToArray());
|
||||||
_permissions[i] = permission;
|
_permissions[i] = permission;
|
||||||
}
|
}
|
||||||
|
@ -71,11 +71,11 @@
|
|||||||
</div>
|
</div>
|
||||||
@if (ReadOnly)
|
@if (ReadOnly)
|
||||||
{
|
{
|
||||||
<textarea class="form-control" placeholder="@Placeholder" @bind="@_content" rows="10" readonly></textarea>
|
<textarea class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10" readonly></textarea>
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
<textarea class="form-control" placeholder="@Placeholder" @bind="@_content" rows="10"></textarea>
|
<textarea class="form-control" placeholder="@Placeholder" @bind="@_rawhtml" rows="10"></textarea>
|
||||||
}
|
}
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
</TabStrip>
|
</TabStrip>
|
||||||
@ -87,8 +87,10 @@
|
|||||||
private ElementReference _toolBar;
|
private ElementReference _toolBar;
|
||||||
private bool _filemanagervisible = false;
|
private bool _filemanagervisible = false;
|
||||||
private FileManager _fileManager;
|
private FileManager _fileManager;
|
||||||
private string _content = string.Empty;
|
private string _richhtml = string.Empty;
|
||||||
private string _original = string.Empty;
|
private string _originalrichhtml = string.Empty;
|
||||||
|
private string _rawhtml = string.Empty;
|
||||||
|
private string _originalrawhtml = string.Empty;
|
||||||
private string _message = string.Empty;
|
private string _message = string.Empty;
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
@ -115,24 +117,26 @@
|
|||||||
|
|
||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill1.3.7.min.js" },
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill.min.js" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-blot-formatter.min.js" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Quill", Url = "js/quill-interop.js" }
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override void OnParametersSet()
|
protected override void OnParametersSet()
|
||||||
{
|
{
|
||||||
_content = Content; // raw HTML
|
_richhtml = Content;
|
||||||
|
_rawhtml = Content;
|
||||||
|
_originalrawhtml = _rawhtml; // preserve for comparison later
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
{
|
||||||
|
await base.OnAfterRenderAsync(firstRender);
|
||||||
|
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
|
|
||||||
if (firstRender)
|
if (firstRender)
|
||||||
{
|
{
|
||||||
await base.OnAfterRenderAsync(firstRender);
|
|
||||||
|
|
||||||
await interop.CreateEditor(
|
await interop.CreateEditor(
|
||||||
_editorElement,
|
_editorElement,
|
||||||
_toolBar,
|
_toolBar,
|
||||||
@ -140,15 +144,16 @@
|
|||||||
Placeholder,
|
Placeholder,
|
||||||
Theme,
|
Theme,
|
||||||
DebugLevel);
|
DebugLevel);
|
||||||
}
|
|
||||||
|
|
||||||
await interop.LoadEditorContent(_editorElement, Content);
|
await interop.LoadEditorContent(_editorElement, _richhtml);
|
||||||
|
|
||||||
_content = Content; // raw HTML
|
|
||||||
|
|
||||||
// preserve a copy of the rich text content (Quill sanitizes content so we need to retrieve it from the editor)
|
// preserve a copy of the rich text content (Quill sanitizes content so we need to retrieve it from the editor)
|
||||||
_original = await interop.GetHtml(_editorElement);
|
_originalrichhtml = await interop.GetHtml(_editorElement);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await interop.LoadEditorContent(_editorElement, _richhtml);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void CloseFileManager()
|
public void CloseFileManager()
|
||||||
@ -158,34 +163,40 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshRichText()
|
public void RefreshRichText()
|
||||||
{
|
{
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
_richhtml = _rawhtml;
|
||||||
await interop.LoadEditorContent(_editorElement, _content);
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshRawHtml()
|
public async Task RefreshRawHtml()
|
||||||
{
|
{
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
_content = await interop.GetHtml(_editorElement);
|
_rawhtml = await interop.GetHtml(_editorElement);
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<string> GetHtml()
|
public async Task<string> GetHtml()
|
||||||
{
|
{
|
||||||
// get rich text content
|
// evaluate raw html content as first priority
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
if (_rawhtml != _originalrawhtml)
|
||||||
string content = await interop.GetHtml(_editorElement);
|
|
||||||
|
|
||||||
if (_original != content)
|
|
||||||
{
|
{
|
||||||
// rich text content has changed - return it
|
return _rawhtml;
|
||||||
return content;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// return raw html content
|
// return rich text content if it has changed
|
||||||
return _content;
|
var interop = new RichTextEditorInterop(JSRuntime);
|
||||||
|
var richhtml = await interop.GetHtml(_editorElement);
|
||||||
|
if (richhtml != _originalrichhtml)
|
||||||
|
{
|
||||||
|
return richhtml;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// return original raw html content
|
||||||
|
return _originalrawhtml;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,23 +223,4 @@
|
|||||||
}
|
}
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// other rich text editor methods which can be used by developers
|
|
||||||
public async Task<string> GetText()
|
|
||||||
{
|
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
|
||||||
return await interop.GetText(_editorElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetContent()
|
|
||||||
{
|
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
|
||||||
return await interop.GetContent(_editorElement);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task EnableEditor(bool mode)
|
|
||||||
{
|
|
||||||
var interop = new RichTextEditorInterop(JSRuntime);
|
|
||||||
await interop.EnableEditor(_editorElement, mode);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,12 @@
|
|||||||
@inject IStringLocalizer<Edit> Localizer
|
@inject IStringLocalizer<Edit> Localizer
|
||||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||||
|
|
||||||
|
<TabStrip>
|
||||||
|
<TabPanel Name="Edit" Heading="Edit" ResourceKey="Edit">
|
||||||
@if (_content != null)
|
@if (_content != null)
|
||||||
{
|
{
|
||||||
<RichTextEditor Content="@_content" AllowFileManagement="@_allowfilemanagement" @ref="@RichTextEditorHtml"></RichTextEditor>
|
<RichTextEditor Content="@_content" AllowFileManagement="@_allowfilemanagement" @ref="@RichTextEditorHtml"></RichTextEditor>
|
||||||
|
<br />
|
||||||
<button type="button" class="btn btn-success" @onclick="SaveContent">@SharedLocalizer["Save"]</button>
|
<button type="button" class="btn btn-success" @onclick="SaveContent">@SharedLocalizer["Save"]</button>
|
||||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||||
@if (!string.IsNullOrEmpty(_content))
|
@if (!string.IsNullOrEmpty(_content))
|
||||||
@ -21,6 +24,27 @@
|
|||||||
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
<AuditInfo CreatedBy="@_createdby" CreatedOn="@_createdon" ModifiedBy="@_modifiedby" ModifiedOn="@_modifiedon"></AuditInfo>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
</TabPanel>
|
||||||
|
<TabPanel Name="Versions" Heading="Versions" ResourceKey="Versions">
|
||||||
|
<Pager Items="@_htmltexts">
|
||||||
|
<Header>
|
||||||
|
<th style="width: 1px;"> </th>
|
||||||
|
<th style="width: 1px;"> </th>
|
||||||
|
<th style="width: 1px;"> </th>
|
||||||
|
<th>@SharedLocalizer["CreatedOn"]</th>
|
||||||
|
<th>@SharedLocalizer["CreatedBy"]</th>
|
||||||
|
</Header>
|
||||||
|
<Row>
|
||||||
|
<td><ActionLink Action="View" Security="SecurityAccessLevel.Edit" OnClick="@(async () => await View(context))" ResourceKey="View" /></td>
|
||||||
|
<td><ActionDialog Header="Restore Version" Message="@string.Format(Localizer["Confirm.Restore"], context.CreatedOn)" Action="Restore" Security="SecurityAccessLevel.Edit" Class="btn btn-success" OnClick="@(async () => await Restore(context))" ResourceKey="Restore" /></td>
|
||||||
|
<td><ActionDialog Header="Delete Version" Message="@string.Format(Localizer["Confirm.Delete"], context.CreatedOn)" Action="Delete" Security="SecurityAccessLevel.Edit" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" ResourceKey="Delete" /></td>
|
||||||
|
<td>@context.CreatedOn</td>
|
||||||
|
<td>@context.CreatedBy</td>
|
||||||
|
</Row>
|
||||||
|
</Pager>
|
||||||
|
@((MarkupString)_view)
|
||||||
|
</TabPanel>
|
||||||
|
</TabStrip>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
|
||||||
@ -30,8 +54,8 @@
|
|||||||
public override List<Resource> Resources => new List<Resource>()
|
public override List<Resource> Resources => new List<Resource>()
|
||||||
{
|
{
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ModulePath() + "Module.css" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.7.bubble.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.bubble.css" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill1.3.7.snow.css" }
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "css/quill/quill.snow.css" }
|
||||||
};
|
};
|
||||||
|
|
||||||
private RichTextEditor RichTextEditorHtml;
|
private RichTextEditor RichTextEditorHtml;
|
||||||
@ -41,13 +65,25 @@
|
|||||||
private DateTime _createdon;
|
private DateTime _createdon;
|
||||||
private string _modifiedby;
|
private string _modifiedby;
|
||||||
private DateTime _modifiedon;
|
private DateTime _modifiedon;
|
||||||
|
private List<Models.HtmlText> _htmltexts;
|
||||||
|
private string _view = "";
|
||||||
|
|
||||||
protected override async Task OnInitializedAsync()
|
protected override async Task OnInitializedAsync()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_allowfilemanagement = bool.Parse(SettingService.GetSetting(ModuleState.Settings, "AllowFileManagement", "true"));
|
_allowfilemanagement = bool.Parse(SettingService.GetSetting(ModuleState.Settings, "AllowFileManagement", "true"));
|
||||||
|
await LoadContent();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Loading Content {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Content.Load"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task LoadContent()
|
||||||
|
{
|
||||||
var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId);
|
var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId);
|
||||||
if (htmltext != null)
|
if (htmltext != null)
|
||||||
{
|
{
|
||||||
@ -62,12 +98,11 @@
|
|||||||
{
|
{
|
||||||
_content = string.Empty;
|
_content = string.Empty;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
_htmltexts = await HtmlTextService.GetHtmlTextsAsync(ModuleState.ModuleId);
|
||||||
{
|
_htmltexts = _htmltexts.OrderByDescending(item => item.CreatedOn).ToList();
|
||||||
await logger.LogError(ex, "Error Loading Content {Error}", ex.Message);
|
|
||||||
AddModuleMessage(Localizer["Error.Content.Load"], MessageType.Error);
|
_view = "";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveContent()
|
private async Task SaveContent()
|
||||||
@ -77,19 +112,10 @@
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var htmltext = await HtmlTextService.GetHtmlTextAsync(ModuleState.ModuleId);
|
var htmltext = new HtmlText();
|
||||||
if (htmltext != null)
|
|
||||||
{
|
|
||||||
htmltext.Content = content;
|
|
||||||
await HtmlTextService.UpdateHtmlTextAsync(htmltext);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
htmltext = new HtmlText();
|
|
||||||
htmltext.ModuleId = ModuleState.ModuleId;
|
htmltext.ModuleId = ModuleState.ModuleId;
|
||||||
htmltext.Content = content;
|
htmltext.Content = content;
|
||||||
await HtmlTextService.AddHtmlTextAsync(htmltext);
|
await HtmlTextService.AddHtmlTextAsync(htmltext);
|
||||||
}
|
|
||||||
|
|
||||||
await logger.LogInformation("Content Saved {HtmlText}", htmltext);
|
await logger.LogInformation("Content Saved {HtmlText}", htmltext);
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
@ -100,4 +126,69 @@
|
|||||||
AddModuleMessage(Localizer["Error.Content.Save"], MessageType.Error);
|
AddModuleMessage(Localizer["Error.Content.Save"], MessageType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task View(Models.HtmlText htmltext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
htmltext = await HtmlTextService.GetHtmlTextAsync(htmltext.HtmlTextId, htmltext.ModuleId);
|
||||||
|
if (htmltext != null)
|
||||||
|
{
|
||||||
|
_view = htmltext.Content;
|
||||||
|
_view = Utilities.FormatContent(_view, PageState.Alias, "render");
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Viewing Content {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Content.View"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Restore(Models.HtmlText htmltext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
htmltext = await HtmlTextService.GetHtmlTextAsync(htmltext.HtmlTextId, ModuleState.ModuleId);
|
||||||
|
if (htmltext != null)
|
||||||
|
{
|
||||||
|
var content = htmltext.Content;
|
||||||
|
htmltext = new HtmlText();
|
||||||
|
htmltext.ModuleId = ModuleState.ModuleId;
|
||||||
|
htmltext.Content = content;
|
||||||
|
await HtmlTextService.AddHtmlTextAsync(htmltext);
|
||||||
|
await logger.LogInformation("Content Restored {HtmlText}", htmltext);
|
||||||
|
AddModuleMessage(Localizer["Message.Content.Restored"], MessageType.Success);
|
||||||
|
await LoadContent();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Restoring Content {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Content.Restore"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Delete(Models.HtmlText htmltext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
htmltext = await HtmlTextService.GetHtmlTextAsync(htmltext.HtmlTextId, ModuleState.ModuleId);
|
||||||
|
if (htmltext != null)
|
||||||
|
{
|
||||||
|
await HtmlTextService.DeleteHtmlTextAsync(htmltext.HtmlTextId, htmltext.ModuleId);
|
||||||
|
await logger.LogInformation("Content Deleted {HtmlText}", htmltext);
|
||||||
|
AddModuleMessage(Localizer["Message.Content.Deleted"], MessageType.Success);
|
||||||
|
await LoadContent();
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
await logger.LogError(ex, "Error Deleting Content {Error}", ex.Message);
|
||||||
|
AddModuleMessage(Localizer["Error.Content.Delete"], MessageType.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
@ -13,24 +15,29 @@ namespace Oqtane.Modules.HtmlText.Services
|
|||||||
|
|
||||||
private string ApiUrl => CreateApiUrl("HtmlText");
|
private string ApiUrl => CreateApiUrl("HtmlText");
|
||||||
|
|
||||||
|
public async Task<List<Models.HtmlText>> GetHtmlTextsAsync(int moduleId)
|
||||||
|
{
|
||||||
|
return await GetJsonAsync<List<Models.HtmlText>>(CreateAuthorizationPolicyUrl($"{ApiUrl}?moduleid={moduleId}", EntityNames.Module, moduleId));
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Models.HtmlText> GetHtmlTextAsync(int moduleId)
|
public async Task<Models.HtmlText> GetHtmlTextAsync(int moduleId)
|
||||||
{
|
{
|
||||||
return await GetJsonAsync<Models.HtmlText>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", EntityNames.Module, moduleId));
|
return await GetJsonAsync<Models.HtmlText>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", EntityNames.Module, moduleId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Models.HtmlText> GetHtmlTextAsync(int htmlTextId, int moduleId)
|
||||||
|
{
|
||||||
|
return await GetJsonAsync<Models.HtmlText>(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlTextId}/{moduleId}", EntityNames.Module, moduleId));
|
||||||
|
}
|
||||||
|
|
||||||
public async Task AddHtmlTextAsync(Models.HtmlText htmlText)
|
public async Task AddHtmlTextAsync(Models.HtmlText htmlText)
|
||||||
{
|
{
|
||||||
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", EntityNames.Module, htmlText.ModuleId), htmlText);
|
await PostJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}", EntityNames.Module, htmlText.ModuleId), htmlText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UpdateHtmlTextAsync(Models.HtmlText htmlText)
|
public async Task DeleteHtmlTextAsync(int htmlTextId, int moduleId)
|
||||||
{
|
{
|
||||||
await PutJsonAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlText.HtmlTextId}", EntityNames.Module, htmlText.ModuleId), htmlText);
|
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{htmlTextId}/{moduleId}", EntityNames.Module, moduleId));
|
||||||
}
|
|
||||||
|
|
||||||
public async Task DeleteHtmlTextAsync(int moduleId)
|
|
||||||
{
|
|
||||||
await DeleteAsync(CreateAuthorizationPolicyUrl($"{ApiUrl}/{moduleId}", EntityNames.Module, moduleId));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,20 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Modules.HtmlText.Models;
|
|
||||||
|
|
||||||
namespace Oqtane.Modules.HtmlText.Services
|
namespace Oqtane.Modules.HtmlText.Services
|
||||||
{
|
{
|
||||||
[PrivateApi("Mark HtmlText classes as private, since it's not very useful in the public docs")]
|
[PrivateApi("Mark HtmlText classes as private, since it's not very useful in the public docs")]
|
||||||
public interface IHtmlTextService
|
public interface IHtmlTextService
|
||||||
{
|
{
|
||||||
Task<Models.HtmlText> GetHtmlTextAsync(int ModuleId);
|
Task<List<Models.HtmlText>> GetHtmlTextsAsync(int moduleId);
|
||||||
|
|
||||||
|
Task<Models.HtmlText> GetHtmlTextAsync(int moduleId);
|
||||||
|
|
||||||
|
Task<Models.HtmlText> GetHtmlTextAsync(int htmlTextId, int moduleId);
|
||||||
|
|
||||||
Task AddHtmlTextAsync(Models.HtmlText htmltext);
|
Task AddHtmlTextAsync(Models.HtmlText htmltext);
|
||||||
|
|
||||||
Task UpdateHtmlTextAsync(Models.HtmlText htmltext);
|
Task DeleteHtmlTextAsync(int htmlTextId, int moduleId);
|
||||||
|
|
||||||
Task DeleteHtmlTextAsync(int ModuleId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="files" ResourceKey="Allow File Management" HelpText="Specify If Editors Can Upload and Select Files">Allow File Management: </Label>
|
<Label Class="col-sm-3" For="files" ResourceKey="AllowFileManagement" ResourceType="@resourceType" HelpText="Specify If Editors Can Upload and Select Files">Allow File Management: </Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="files" class="form-select" @bind="@_allowfilemanagement">
|
<select id="files" class="form-select" @bind="@_allowfilemanagement">
|
||||||
<option value="true">@SharedLocalizer["Yes"]</option>
|
<option value="true">@SharedLocalizer["Yes"]</option>
|
||||||
@ -18,6 +18,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string resourceType = "Oqtane.Modules.HtmlText.Settings, Oqtane.Client"; // for localization
|
||||||
private string _allowfilemanagement;
|
private string _allowfilemanagement;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
@ -36,7 +37,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var settings = ModuleState.Settings;
|
var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
||||||
settings = SettingService.SetSetting(settings, "AllowFileManagement", _allowfilemanagement);
|
settings = SettingService.SetSetting(settings, "AllowFileManagement", _allowfilemanagement);
|
||||||
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
await SettingService.UpdateModuleSettingsAsync(settings, ModuleState.ModuleId);
|
||||||
}
|
}
|
||||||
|
@ -134,14 +134,19 @@ namespace Oqtane.Modules
|
|||||||
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ImageUrl(int fileid, int width, int height, string mode)
|
public string ImageUrl(int fileid, int width, int height)
|
||||||
{
|
{
|
||||||
return ImageUrl(fileid, width, height, mode, 0);
|
return ImageUrl(fileid, width, height, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ImageUrl(int fileid, int width, int height, string mode, int rotate)
|
public string ImageUrl(int fileid, int width, int height, string mode)
|
||||||
{
|
{
|
||||||
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, rotate);
|
return ImageUrl(fileid, width, height, mode, "", "", 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ImageUrl(int fileid, int width, int height, string mode, string position, string background, int rotate, bool recreate)
|
||||||
|
{
|
||||||
|
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
public virtual Dictionary<string, string> GetUrlParameters(string parametersTemplate = "")
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RazorLangVersion>3.0</RazorLangVersion>
|
<RazorLangVersion>3.0</RazorLangVersion>
|
||||||
<Configurations>Debug;Release</Configurations>
|
<Configurations>Debug;Release</Configurations>
|
||||||
<Version>3.0.1</Version>
|
<Version>3.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -13,7 +13,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<RootNamespace>Oqtane</RootNamespace>
|
<RootNamespace>Oqtane</RootNamespace>
|
||||||
|
@ -186,4 +186,10 @@
|
|||||||
<data name="NextExecution.Text" xml:space="preserve">
|
<data name="NextExecution.Text" xml:space="preserve">
|
||||||
<value>Next Execution: </value>
|
<value>Next Execution: </value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Week(s)" xml:space="preserve">
|
||||||
|
<value>Week(s)</value>
|
||||||
|
</data>
|
||||||
|
<data name="Once" xml:space="preserve">
|
||||||
|
<value>Execute Once</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -133,19 +133,16 @@
|
|||||||
<value>Every</value>
|
<value>Every</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Minute" xml:space="preserve">
|
<data name="Minute" xml:space="preserve">
|
||||||
<value>Minute</value>
|
<value>Minute(s)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Hour" xml:space="preserve">
|
<data name="Hour" xml:space="preserve">
|
||||||
<value>Hour</value>
|
<value>Hour(s)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Day" xml:space="preserve">
|
<data name="Day" xml:space="preserve">
|
||||||
<value>Day</value>
|
<value>Day(s)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Month" xml:space="preserve">
|
<data name="Month" xml:space="preserve">
|
||||||
<value>Month</value>
|
<value>Month(s)</value>
|
||||||
</data>
|
|
||||||
<data name="s" xml:space="preserve">
|
|
||||||
<value>s</value>
|
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Job.Delete" xml:space="preserve">
|
<data name="Error.Job.Delete" xml:space="preserve">
|
||||||
<value>Error Deleting Job</value>
|
<value>Error Deleting Job</value>
|
||||||
@ -177,4 +174,22 @@
|
|||||||
<data name="JobLog.Text" xml:space="preserve">
|
<data name="JobLog.Text" xml:space="preserve">
|
||||||
<value>Log</value>
|
<value>Log</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error.Job.Start" xml:space="preserve">
|
||||||
|
<value>An error occurred when starting the job</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.Job.Stop" xml:space="preserve">
|
||||||
|
<value>An error occurred when stopping the job</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Job.Start" xml:space="preserve">
|
||||||
|
<value>The process responsible for executing this job has been started. The next execution will be based on the schedule criteria for the job.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Job.Stop" xml:space="preserve">
|
||||||
|
<value>The process responsible for executing this job has been stopped. In order to restart the process you will need to use the Start button or restart the application.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Week" xml:space="preserve">
|
||||||
|
<value>Week(s)</value>
|
||||||
|
</data>
|
||||||
|
<data name="Once" xml:space="preserve">
|
||||||
|
<value>Execute Once</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -138,4 +138,13 @@
|
|||||||
<data name="Info.SignedIn" xml:space="preserve">
|
<data name="Info.SignedIn" xml:space="preserve">
|
||||||
<value>You Are Already Signed In</value>
|
<value>You Are Already Signed In</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.ForgotPassword" xml:space="preserve">
|
||||||
|
<value>Please Enter The Username Related To Your Account And Then Select The Forgot Password Option Again</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.ForgotUser" xml:space="preserve">
|
||||||
|
<value>Please Check The Email Address Associated To Your User Account For A Password Reset Notification</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.UserDoesNotExist" xml:space="preserve">
|
||||||
|
<value>User Does Not Exist</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -192,4 +192,22 @@
|
|||||||
<data name="LogDetails.Text" xml:space="preserve">
|
<data name="LogDetails.Text" xml:space="preserve">
|
||||||
<value>Details</value>
|
<value>Details</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error.SaveSiteSettings" xml:space="preserve">
|
||||||
|
<value>Error Saving Settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="Events.Heading" xml:space="preserve">
|
||||||
|
<value>Events</value>
|
||||||
|
</data>
|
||||||
|
<data name="Retention.HelpText" xml:space="preserve">
|
||||||
|
<value>Number of days of events to retain</value>
|
||||||
|
</data>
|
||||||
|
<data name="Retention.Text" xml:space="preserve">
|
||||||
|
<value>Retention (Days):</value>
|
||||||
|
</data>
|
||||||
|
<data name="Settings.Heading" xml:space="preserve">
|
||||||
|
<value>Settings</value>
|
||||||
|
</data>
|
||||||
|
<data name="Success.SaveSiteSettings" xml:space="preserve">
|
||||||
|
<value>Settings Saved Successfully</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -231,4 +231,10 @@
|
|||||||
<data name="Message.Page.Deleted" xml:space="preserve">
|
<data name="Message.Page.Deleted" xml:space="preserve">
|
||||||
<value>A page with path {0} already exists for the selected parent page in the Recycle Bin. Either recover the page or remove from the Recycle Bin and create it again.</value>
|
<value>A page with path {0} already exists for the selected parent page in the Recycle Bin. Either recover the page or remove from the Recycle Bin and create it again.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Meta.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally enter meta tags (in exactly the form you want them to be included in the page output).</value>
|
||||||
|
</data>
|
||||||
|
<data name="Meta.Text" xml:space="preserve">
|
||||||
|
<value>Meta:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -258,13 +258,16 @@
|
|||||||
<data name="ThemeSettings.Heading" xml:space="preserve">
|
<data name="ThemeSettings.Heading" xml:space="preserve">
|
||||||
<value>Theme Settings</value>
|
<value>Theme Settings</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Appearance.Hea" xml:space="preserve">
|
|
||||||
<value />
|
|
||||||
</data>
|
|
||||||
<data name="Clickable.HelpText" xml:space="preserve">
|
<data name="Clickable.HelpText" xml:space="preserve">
|
||||||
<value>Select whether the link in the site navigation is enabled or disabled</value>
|
<value>Select whether the link in the site navigation is enabled or disabled</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Clickable.Text" xml:space="preserve">
|
<data name="Clickable.Text" xml:space="preserve">
|
||||||
<value>Clickable?</value>
|
<value>Clickable?</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Meta.HelpText" xml:space="preserve">
|
||||||
|
<value>Optionally enter meta tags (in exactly the form you want them to be included in the page output).</value>
|
||||||
|
</data>
|
||||||
|
<data name="Meta.Text" xml:space="preserve">
|
||||||
|
<value>Meta:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -117,22 +117,37 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
<data name="Password.Confirm" xml:space="preserve">
|
|
||||||
<value>Confirm Password:</value>
|
|
||||||
</data>
|
|
||||||
<data name="Message.Password.NoMatch" xml:space="preserve">
|
<data name="Message.Password.NoMatch" xml:space="preserve">
|
||||||
<value>Passwords Entered Do Not Match</value>
|
<value>Passwords Entered Do Not Match</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Required.UserInfo" xml:space="preserve">
|
<data name="Message.Required.UserInfo" xml:space="preserve">
|
||||||
<value>You Must Provide A Username, Password, and Email Address</value>
|
<value>You Must Provide The Password And Confirmation</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Password.Reset" xml:space="preserve">
|
<data name="Password.Reset" xml:space="preserve">
|
||||||
<value>Reset Password</value>
|
<value>Reset Password</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Password.ResetInfo" xml:space="preserve">
|
<data name="Error.Password.ResetInfo" xml:space="preserve">
|
||||||
<value>Error Resetting User Password. Please Ensure Password Meets Complexity Requirements.</value>
|
<value>Error Resetting User Password. Please Ensure The Request To Reset Your Password Was Made Within The Past 24 Hours And The New Password Meets The Complexity Requirements.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Error.Password.Reset" xml:space="preserve">
|
<data name="Error.Password.Reset" xml:space="preserve">
|
||||||
<value>Error Resetting User Password</value>
|
<value>Error Resetting User Password</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Confirm.Text" xml:space="preserve">
|
||||||
|
<value>Confirm:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Conform.HelpText" xml:space="preserve">
|
||||||
|
<value>Enter the password again. It must exactly match the password entered above.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.HelpText" xml:space="preserve">
|
||||||
|
<value>The new password. It must satisfy complexity rules for the site.</value>
|
||||||
|
</data>
|
||||||
|
<data name="Password.Text" xml:space="preserve">
|
||||||
|
<value>Password:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Username.HelpText" xml:space="preserve">
|
||||||
|
<value>Your username will be populated from the link you received in the password reset notification</value>
|
||||||
|
</data>
|
||||||
|
<data name="Username.Text" xml:space="preserve">
|
||||||
|
<value>Username:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -129,9 +129,6 @@
|
|||||||
<data name="DefaultContainer.Text" xml:space="preserve">
|
<data name="DefaultContainer.Text" xml:space="preserve">
|
||||||
<value>Default Container: </value>
|
<value>Default Container: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Appearance.Heading" xml:space="preserve">
|
|
||||||
<value>Appearance</value>
|
|
||||||
</data>
|
|
||||||
<data name="DefaultAdminContainer" xml:space="preserve">
|
<data name="DefaultAdminContainer" xml:space="preserve">
|
||||||
<value>Default Admin Container</value>
|
<value>Default Admin Container</value>
|
||||||
</data>
|
</data>
|
||||||
@ -145,7 +142,7 @@
|
|||||||
<value>Site Settings Saved</value>
|
<value>Site Settings Saved</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Aliases.Taken" xml:space="preserve">
|
<data name="Message.Aliases.Taken" xml:space="preserve">
|
||||||
<value>An Alias Specified Has Already Been Used For Another Site</value>
|
<value>The Default Alias Has Not Been Specified Or An Alias Was Specified That Has Already Been Used For Another Site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Message.Required.SiteName" xml:space="preserve">
|
<data name="Message.Required.SiteName" xml:space="preserve">
|
||||||
<value>You Must Provide A Site Name, Alias, And Default Theme/Container</value>
|
<value>You Must Provide A Site Name, Alias, And Default Theme/Container</value>
|
||||||
@ -223,7 +220,7 @@
|
|||||||
<value>Aliases: </value>
|
<value>Aliases: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IsDeleted.Text" xml:space="preserve">
|
<data name="IsDeleted.Text" xml:space="preserve">
|
||||||
<value>Is Deleted? </value>
|
<value>Deleted? </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Logo.Text" xml:space="preserve">
|
<data name="Logo.Text" xml:space="preserve">
|
||||||
<value>Logo: </value>
|
<value>Logo: </value>
|
||||||
@ -318,4 +315,13 @@
|
|||||||
<data name="DeleteSite.Text" xml:space="preserve">
|
<data name="DeleteSite.Text" xml:space="preserve">
|
||||||
<value>Delete Site</value>
|
<value>Delete Site</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="DefaultAlias.HelpText" xml:space="preserve">
|
||||||
|
<value>The default alias for the site. Requests for non-default aliases will be redirected to the default alias.</value>
|
||||||
|
</data>
|
||||||
|
<data name="DefaultAlias.Text" xml:space="preserve">
|
||||||
|
<value>Default Alias: </value>
|
||||||
|
</data>
|
||||||
|
<data name="Aliases.Heading" xml:space="preserve">
|
||||||
|
<value>Aliases</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -133,7 +133,7 @@
|
|||||||
<value>Server Path</value>
|
<value>Server Path</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ServerTime.HelpText" xml:space="preserve">
|
<data name="ServerTime.HelpText" xml:space="preserve">
|
||||||
<value>Server Time</value>
|
<value>Server Date/Time (in UTC)</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="FrameworkVersion.Text" xml:space="preserve">
|
<data name="FrameworkVersion.Text" xml:space="preserve">
|
||||||
<value>Framework Version: </value>
|
<value>Framework Version: </value>
|
||||||
@ -148,7 +148,7 @@
|
|||||||
<value>Server Path: </value>
|
<value>Server Path: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="ServerTime.Text" xml:space="preserve">
|
<data name="ServerTime.Text" xml:space="preserve">
|
||||||
<value>Server Time: </value>
|
<value>Server Date/Time: </value>
|
||||||
</data>
|
</data>
|
||||||
<data name="RestartApplication.Header" xml:space="preserve">
|
<data name="RestartApplication.Header" xml:space="preserve">
|
||||||
<value>Restart Application</value>
|
<value>Restart Application</value>
|
||||||
|
@ -121,10 +121,10 @@
|
|||||||
<value>Redirect To:</value>
|
<value>Redirect To:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MappedUrl.HelpText" xml:space="preserve">
|
<data name="MappedUrl.HelpText" xml:space="preserve">
|
||||||
<value>A fully qualified Url where the user will be redirected</value>
|
<value>A relative or absolute Url where the user will be redirected</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Url.HelpText" xml:space="preserve">
|
<data name="Url.HelpText" xml:space="preserve">
|
||||||
<value>A fully qualified Url for this site</value>
|
<value>An absolute Url identifying a path to a specific page in the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Url.Text" xml:space="preserve">
|
<data name="Url.Text" xml:space="preserve">
|
||||||
<value>Url:</value>
|
<value>Url:</value>
|
||||||
@ -135,4 +135,10 @@
|
|||||||
<data name="Message.InfoRequired" xml:space="preserve">
|
<data name="Message.InfoRequired" xml:space="preserve">
|
||||||
<value>Please Provide All Required Information</value>
|
<value>Please Provide All Required Information</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.DuplicateUrlMapping" xml:space="preserve">
|
||||||
|
<value>The Url and Redirect To cannot be the same</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.SaveUrlMapping" xml:space="preserve">
|
||||||
|
<value>The Url must belong to the current site</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -121,10 +121,10 @@
|
|||||||
<value>Redirect To:</value>
|
<value>Redirect To:</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MappedUrl.HelpText" xml:space="preserve">
|
<data name="MappedUrl.HelpText" xml:space="preserve">
|
||||||
<value>A fully qualified Url where the user will be redirected</value>
|
<value>A relative or absolute Url where the user will be redirected</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Url.HelpText" xml:space="preserve">
|
<data name="Url.HelpText" xml:space="preserve">
|
||||||
<value>A fully qualified Url for this site</value>
|
<value>A relative Url identifying a path to a specific page in the site</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Url.Text" xml:space="preserve">
|
<data name="Url.Text" xml:space="preserve">
|
||||||
<value>Url:</value>
|
<value>Url:</value>
|
||||||
@ -138,4 +138,7 @@
|
|||||||
<data name="Message.InfoRequired" xml:space="preserve">
|
<data name="Message.InfoRequired" xml:space="preserve">
|
||||||
<value>Please Provide All Required Information</value>
|
<value>Please Provide All Required Information</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Message.DuplicateUrlMapping" xml:space="preserve">
|
||||||
|
<value>The Url and Redirect To cannot be the same</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -156,11 +156,11 @@
|
|||||||
<data name="Visitors.Heading" xml:space="preserve">
|
<data name="Visitors.Heading" xml:space="preserve">
|
||||||
<value>Visitors</value>
|
<value>Visitors</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="VisitorTracking.HelpText" xml:space="preserve">
|
<data name="Tracking.HelpText" xml:space="preserve">
|
||||||
<value>Specify if visitor tracking is enabled</value>
|
<value>Specify if visitor tracking is enabled</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="VisitorTracking.Text" xml:space="preserve">
|
<data name="Tracking.Text" xml:space="preserve">
|
||||||
<value>Visitor Tracking Enabled?</value>
|
<value>Tracking Enabled?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="IP" xml:space="preserve">
|
<data name="IP" xml:space="preserve">
|
||||||
<value>IP</value>
|
<value>IP</value>
|
||||||
@ -171,4 +171,25 @@
|
|||||||
<data name="Created" xml:space="preserve">
|
<data name="Created" xml:space="preserve">
|
||||||
<value>Created</value>
|
<value>Created</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Details.Text" xml:space="preserve">
|
||||||
|
<value>Details</value>
|
||||||
|
</data>
|
||||||
|
<data name="Filter.HelpText" xml:space="preserve">
|
||||||
|
<value>Comma delimited list of terms which may exist in IP addresses, user agents, or languages identifying visitors which should not be tracked</value>
|
||||||
|
</data>
|
||||||
|
<data name="Filter.Text" xml:space="preserve">
|
||||||
|
<value>Filter:</value>
|
||||||
|
</data>
|
||||||
|
<data name="Retention.HelpText" xml:space="preserve">
|
||||||
|
<value>Number of days of visitor activity to retain</value>
|
||||||
|
</data>
|
||||||
|
<data name="Retention.Text" xml:space="preserve">
|
||||||
|
<value>Retention (Days):</value>
|
||||||
|
</data>
|
||||||
|
<data name="Correlation.HelpText" xml:space="preserve">
|
||||||
|
<value>Indicate if new visitors to this site should be correlated based on their IP Address</value>
|
||||||
|
</data>
|
||||||
|
<data name="Correlation.Text" xml:space="preserve">
|
||||||
|
<value>Correlate Visitors?</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -117,10 +117,52 @@
|
|||||||
<resheader name="writer">
|
<resheader name="writer">
|
||||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
</resheader>
|
</resheader>
|
||||||
|
<data name="Confirm.Delete" xml:space="preserve">
|
||||||
|
<value>Are You Sure You Wish To Delete The {0} Version?</value>
|
||||||
|
</data>
|
||||||
|
<data name="Confirm.Restore" xml:space="preserve">
|
||||||
|
<value>Are You Sure You Wish To Restore The {0} Version?</value>
|
||||||
|
</data>
|
||||||
|
<data name="CreatedBy" xml:space="preserve">
|
||||||
|
<value>Created By</value>
|
||||||
|
</data>
|
||||||
|
<data name="CreatedOn" xml:space="preserve">
|
||||||
|
<value>Created On</value>
|
||||||
|
</data>
|
||||||
|
<data name="Delete.Header" xml:space="preserve">
|
||||||
|
<value>Delete Version</value>
|
||||||
|
</data>
|
||||||
|
<data name="Delete.Text" xml:space="preserve">
|
||||||
|
<value>Delete</value>
|
||||||
|
</data>
|
||||||
|
<data name="Error.Content.Delete" xml:space="preserve">
|
||||||
|
<value>Error Deleting Version</value>
|
||||||
|
</data>
|
||||||
<data name="Error.Content.Load" xml:space="preserve">
|
<data name="Error.Content.Load" xml:space="preserve">
|
||||||
<value>An Error Occurred Loading Content</value>
|
<value>An Error Occurred Loading Content</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error.Content.Restore" xml:space="preserve">
|
||||||
|
<value>Error Restoring Version</value>
|
||||||
|
</data>
|
||||||
<data name="Error.Content.Save" xml:space="preserve">
|
<data name="Error.Content.Save" xml:space="preserve">
|
||||||
<value>An Error Occurred Saving Content</value>
|
<value>An Error Occurred Saving Content</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Error.Content.View" xml:space="preserve">
|
||||||
|
<value>Error Viewing Version</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Content.Deleted" xml:space="preserve">
|
||||||
|
<value>Version Deleted</value>
|
||||||
|
</data>
|
||||||
|
<data name="Message.Content.Restored" xml:space="preserve">
|
||||||
|
<value>Version Restored</value>
|
||||||
|
</data>
|
||||||
|
<data name="Restore.Header" xml:space="preserve">
|
||||||
|
<value>Restore Version</value>
|
||||||
|
</data>
|
||||||
|
<data name="Restore.Text" xml:space="preserve">
|
||||||
|
<value>Restore</value>
|
||||||
|
</data>
|
||||||
|
<data name="View.Text" xml:space="preserve">
|
||||||
|
<value>View</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -259,7 +259,7 @@
|
|||||||
<value>Upgrade</value>
|
<value>Upgrade</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Username" xml:space="preserve">
|
<data name="Username" xml:space="preserve">
|
||||||
<value>Username:</value>
|
<value>Username</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Version" xml:space="preserve">
|
<data name="Version" xml:space="preserve">
|
||||||
<value>Version</value>
|
<value>Version</value>
|
||||||
|
@ -177,4 +177,13 @@
|
|||||||
<data name="System.Update" xml:space="preserve">
|
<data name="System.Update" xml:space="preserve">
|
||||||
<value>Check For System Updates</value>
|
<value>Check For System Updates</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="Visibility" xml:space="preserve">
|
||||||
|
<value>Visibility:</value>
|
||||||
|
</data>
|
||||||
|
<data name="VisibilityEdit" xml:space="preserve">
|
||||||
|
<value>Page Editors Only</value>
|
||||||
|
</data>
|
||||||
|
<data name="VisibilityView" xml:space="preserve">
|
||||||
|
<value>Same As Page</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -59,7 +59,7 @@
|
|||||||
: using a System.ComponentModel.TypeConverter
|
: using a System.ComponentModel.TypeConverter
|
||||||
: and then encoded with base64 encoding.
|
: and then encoded with base64 encoding.
|
||||||
-->
|
-->
|
||||||
<xsd:schema xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="root">
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||||
<xsd:element name="root" msdata:IsDataSet="true">
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
@ -121,7 +121,7 @@
|
|||||||
<value>Specify if a Footer pane should always be displayed in a fixed location at the bottom of the page.</value>
|
<value>Specify if a Footer pane should always be displayed in a fixed location at the bottom of the page.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Footer.Text" xml:space="preserve">
|
<data name="Footer.Text" xml:space="preserve">
|
||||||
<value>Display Footer?</value>
|
<value>Display Fixed Footer?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="Login.HelpText" xml:space="preserve">
|
<data name="Login.HelpText" xml:space="preserve">
|
||||||
<value>Specify if a Login option should be displayed, Note that this option does not prevent the login page from being accessible via a direct url.</value>
|
<value>Specify if a Login option should be displayed, Note that this option does not prevent the login page from being accessible via a direct url.</value>
|
@ -206,7 +206,7 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue);
|
Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue);
|
||||||
|
|
||||||
Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue, bool isPublic);
|
Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue, bool isPrivate);
|
||||||
|
|
||||||
Dictionary<string, string> MergeSettings(Dictionary<string, string> settings1, Dictionary<string, string> settings2);
|
Dictionary<string, string> MergeSettings(Dictionary<string, string> settings1, Dictionary<string, string> settings2);
|
||||||
|
|
||||||
|
@ -24,6 +24,14 @@ namespace Oqtane.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<UrlMapping> GetUrlMappingAsync(int urlMappingId);
|
Task<UrlMapping> GetUrlMappingAsync(int urlMappingId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get one specific <see cref="UrlMapping"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="siteId">ID-reference of a <see cref="Site"/></param>
|
||||||
|
/// <param name="url">A url</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<UrlMapping> GetUrlMappingAsync(int siteId, string url);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add / save a new <see cref="UrlMapping"/> to the database.
|
/// Add / save a new <see cref="UrlMapping"/> to the database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -131,14 +131,21 @@ namespace Oqtane.Services
|
|||||||
foreach (KeyValuePair<string, string> kvp in settings)
|
foreach (KeyValuePair<string, string> kvp in settings)
|
||||||
{
|
{
|
||||||
string value = kvp.Value;
|
string value = kvp.Value;
|
||||||
bool ispublic = false;
|
bool modified = false;
|
||||||
|
bool isprivate = false;
|
||||||
|
|
||||||
|
// manage settings modified with SetSetting method
|
||||||
|
if (value.StartsWith("[Private]"))
|
||||||
|
{
|
||||||
|
modified = true;
|
||||||
|
isprivate = true;
|
||||||
|
value = value.Substring(9);
|
||||||
|
}
|
||||||
if (value.StartsWith("[Public]"))
|
if (value.StartsWith("[Public]"))
|
||||||
{
|
{
|
||||||
if (entityName == EntityNames.Site)
|
modified = true;
|
||||||
{
|
isprivate = false;
|
||||||
ispublic = true;
|
value = value.Substring(8);
|
||||||
}
|
|
||||||
value = value.Substring(8); // remove [Public]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Setting setting = settingsList.FirstOrDefault(item => item.SettingName.Equals(kvp.Key, StringComparison.OrdinalIgnoreCase));
|
Setting setting = settingsList.FirstOrDefault(item => item.SettingName.Equals(kvp.Key, StringComparison.OrdinalIgnoreCase));
|
||||||
@ -149,22 +156,21 @@ namespace Oqtane.Services
|
|||||||
setting.EntityId = entityId;
|
setting.EntityId = entityId;
|
||||||
setting.SettingName = kvp.Key;
|
setting.SettingName = kvp.Key;
|
||||||
setting.SettingValue = value;
|
setting.SettingValue = value;
|
||||||
setting.IsPublic = ispublic;
|
setting.IsPrivate = isprivate;
|
||||||
setting = await AddSettingAsync(setting);
|
setting = await AddSettingAsync(setting);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (setting.SettingValue != kvp.Value)
|
if (setting.SettingValue != value || (modified && setting.IsPrivate != isprivate))
|
||||||
{
|
{
|
||||||
setting.SettingValue = value;
|
setting.SettingValue = value;
|
||||||
setting.IsPublic = ispublic;
|
setting.IsPrivate = isprivate;
|
||||||
setting = await UpdateSettingAsync(setting);
|
setting = await UpdateSettingAsync(setting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public async Task<Setting> GetSettingAsync(string entityName, int settingId)
|
public async Task<Setting> GetSettingAsync(string entityName, int settingId)
|
||||||
{
|
{
|
||||||
return await GetJsonAsync<Setting>($"{Apiurl}/{settingId}/{entityName}");
|
return await GetJsonAsync<Setting>($"{Apiurl}/{settingId}/{entityName}");
|
||||||
@ -201,13 +207,13 @@ namespace Oqtane.Services
|
|||||||
return SetSetting(settings, settingName, settingValue, false);
|
return SetSetting(settings, settingName, settingValue, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue, bool isPublic)
|
public Dictionary<string, string> SetSetting(Dictionary<string, string> settings, string settingName, string settingValue, bool isPrivate)
|
||||||
{
|
{
|
||||||
if (settings == null)
|
if (settings == null)
|
||||||
{
|
{
|
||||||
settings = new Dictionary<string, string>();
|
settings = new Dictionary<string, string>();
|
||||||
}
|
}
|
||||||
settingValue = (isPublic) ? "[Public]" + settingValue : settingValue;
|
settingValue = (isPrivate) ? "[Private]" + settingValue : "[Public]" + settingValue;
|
||||||
if (settings.ContainsKey(settingName))
|
if (settings.ContainsKey(settingName))
|
||||||
{
|
{
|
||||||
settings[settingName] = settingValue;
|
settings[settingName] = settingValue;
|
||||||
|
@ -5,6 +5,7 @@ using System.Linq;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Oqtane.Documentation;
|
using Oqtane.Documentation;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
@ -33,6 +34,11 @@ namespace Oqtane.Services
|
|||||||
return await GetJsonAsync<UrlMapping>($"{Apiurl}/{urlMappingId}");
|
return await GetJsonAsync<UrlMapping>($"{Apiurl}/{urlMappingId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<UrlMapping> GetUrlMappingAsync(int siteId, string url)
|
||||||
|
{
|
||||||
|
return await GetJsonAsync<UrlMapping>($"{Apiurl}/url/{siteId}?url={WebUtility.UrlEncode(url)}");
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<UrlMapping> AddUrlMappingAsync(UrlMapping role)
|
public async Task<UrlMapping> AddUrlMappingAsync(UrlMapping role)
|
||||||
{
|
{
|
||||||
return await PostJsonAsync<UrlMapping>(Apiurl, role);
|
return await PostJsonAsync<UrlMapping>(Apiurl, role);
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
@namespace Oqtane.Themes.BlazorTheme
|
@namespace Oqtane.Themes.BlazorTheme
|
||||||
@inherits ContainerBase
|
@inherits ContainerBase
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
@if (ModuleState.Title != "-")
|
||||||
|
{
|
||||||
<div class="row p-4">
|
<div class="row p-4">
|
||||||
<div class="d-flex flex-nowrap">
|
<div class="d-flex flex-nowrap">
|
||||||
<ModuleActions /><h2><ModuleTitle /></h2>
|
<ModuleActions /><h2><ModuleTitle /></h2>
|
||||||
</div>
|
</div>
|
||||||
<hr class="app-rule" />
|
<hr class="app-rule" />
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<ModuleActions />
|
||||||
|
}
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<ModuleInstance />
|
<ModuleInstance />
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
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.0.2/css/bootstrap.min.css", Integrity = "sha512-usVBAd66/NpVNfBge19gws2j6JZinnca12rAe2l+d+QkLU9fiG02O1X8Q6hepIpr/EYKZvKx/I9WsnujJuOmBA==", CrossOrigin = "anonymous" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/css/bootstrap.min.css", Integrity = "sha512-GQGU0fMMi238uA+a/bdWJfpUGKUkBdgfFdgBm72SUQ6BeyWjoY/ton0tEjH+OSH9iP4Dfh+7HM0I9f5eR0L/4w==", CrossOrigin = "anonymous" },
|
||||||
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
new Resource { ResourceType = ResourceType.Stylesheet, Url = ThemePath() + "Theme.css" },
|
||||||
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js", Integrity = "sha512-pax4MlgXjHEPfCwcJLQhigY7+N8rt6bVvWLFyUMuxShv170X53TRzGPmPkZmGBhk+jikR8WBM4yl7A9WMHHqvg==", CrossOrigin = "anonymous" }
|
new Resource { ResourceType = ResourceType.Script, Bundle = "Bootstrap", Url = "https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.bundle.min.js", Integrity = "sha512-pax4MlgXjHEPfCwcJLQhigY7+N8rt6bVvWLFyUMuxShv170X53TRzGPmPkZmGBhk+jikR8WBM4yl7A9WMHHqvg==", CrossOrigin = "anonymous" }
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
@attribute [OqtaneIgnore]
|
@attribute [OqtaneIgnore]
|
||||||
|
|
||||||
<span class="app-moduletitle">
|
<span class="app-moduletitle">
|
||||||
|
<a id="@ModuleState.PageModuleId.ToString()">
|
||||||
@((MarkupString)title)
|
@((MarkupString)title)
|
||||||
|
</a>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
@ -61,14 +61,13 @@
|
|||||||
<label class="control-label">@Localizer["Page.Manage"] </label>
|
<label class="control-label">@Localizer["Page.Manage"] </label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row d-flex">
|
<div class="row d-flex mb-2">
|
||||||
<div class="col d-flex justify-content-between">
|
<div class="col d-flex justify-content-between">
|
||||||
<button type="button" class="btn btn-secondary col me-1" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Add"))>@SharedLocalizer["Add"]</button>
|
<button type="button" class="btn btn-secondary col me-1" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Add"))>@SharedLocalizer["Add"]</button>
|
||||||
<button type="button" class="btn btn-secondary col" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Edit"))>@SharedLocalizer["Edit"]</button>
|
<button type="button" class="btn btn-secondary col" data-bs-dismiss="offcanvas" @onclick=@(async () => Navigate("Edit"))>@SharedLocalizer["Edit"]</button>
|
||||||
<button type="button" class="btn btn-danger col ms-1" @onclick="ConfirmDelete">@SharedLocalizer["Delete"]</button>
|
<button type="button" class="btn btn-danger col ms-1" @onclick="ConfirmDelete">@SharedLocalizer["Delete"]</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
|
||||||
<div class="row d-flex">
|
<div class="row d-flex">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
@if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone))
|
@if (UserSecurity.GetPermissionStrings(PageState.Page.Permissions).FirstOrDefault(item => item.PermissionName == PermissionNames.View).Permissions.Split(';').Contains(RoleNames.Everyone))
|
||||||
@ -150,7 +149,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</select>
|
</select>
|
||||||
@((MarkupString) Description)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -203,21 +201,23 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<div class="row">
|
||||||
<button type="button" class="btn btn-primary col-12" @onclick="@AddModule">@Localizer["Page.Module.Add"]</button>
|
<div class="col text-center">
|
||||||
|
<label for="visibility" class="control-label">@Localizer["Visibility"]</label>
|
||||||
|
<select class="form-select" @bind="@Visibility">
|
||||||
|
<option value="edit" selected>@Localizer["VisibilityEdit"]</option>
|
||||||
|
<option value="view">@Localizer["VisibilityView"]</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-primary col-12 mt-4" @onclick="@AddModule">@Localizer["Page.Module.Add"]</button>
|
||||||
@((MarkupString) Message)
|
@((MarkupString) Message)
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
|
||||||
{
|
|
||||||
<hr class="app-rule" />
|
|
||||||
<NavLink class="btn btn-info col-12" data-bs-dismiss="offcanvas" href="@NavigateUrl("admin/update")">@Localizer["System.Update"]</NavLink>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code{
|
@code{
|
||||||
|
|
||||||
private bool _deleteConfirmation = false;
|
private bool _deleteConfirmation = false;
|
||||||
private List<string> _categories = new List<string>();
|
private List<string> _categories = new List<string>();
|
||||||
private List<ModuleDefinition> _allModuleDefinitions;
|
private List<ModuleDefinition> _allModuleDefinitions;
|
||||||
@ -242,7 +242,7 @@
|
|||||||
_category = value;
|
_category = value;
|
||||||
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
_moduleDefinitions = _allModuleDefinitions.Where(item => item.Categories.Contains(Category)).ToList();
|
||||||
ModuleDefinitionName = "-";
|
ModuleDefinitionName = "-";
|
||||||
Description = "";
|
Message = "";
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
_ = UpdateSettingsAsync();
|
_ = UpdateSettingsAsync();
|
||||||
}
|
}
|
||||||
@ -262,11 +262,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected string Description { get; private set; } = "";
|
|
||||||
|
|
||||||
protected string Title { get; private set; } = "";
|
protected string Title { get; private set; } = "";
|
||||||
protected string ContainerType { get; private set; } = "";
|
protected string ContainerType { get; private set; } = "";
|
||||||
|
protected string Visibility { get; private set; } = "edit";
|
||||||
protected string Message { get; private set; } = "";
|
protected string Message { get; private set; } = "";
|
||||||
|
|
||||||
[Parameter]
|
[Parameter]
|
||||||
@ -320,13 +318,12 @@
|
|||||||
if (ModuleDefinitionName != "-")
|
if (ModuleDefinitionName != "-")
|
||||||
{
|
{
|
||||||
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName);
|
var moduleDefinition = _moduleDefinitions.FirstOrDefault(item => item.ModuleDefinitionName == ModuleDefinitionName);
|
||||||
Description = "<br /><div class=\"alert alert-info\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
Message = "<div class=\"alert alert-info mt-2 text-center\" role=\"alert\">" + moduleDefinition.Description + "</div>";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Description = "";
|
Message = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,9 +356,17 @@
|
|||||||
module.ModuleDefinitionName = ModuleDefinitionName;
|
module.ModuleDefinitionName = ModuleDefinitionName;
|
||||||
module.AllPages = false;
|
module.AllPages = false;
|
||||||
|
|
||||||
// set module view permissions to page edit permissions
|
|
||||||
List<PermissionString> permissions = UserSecurity.GetPermissionStrings(PageState.Page.Permissions);
|
List<PermissionString> permissions = UserSecurity.GetPermissionStrings(PageState.Page.Permissions);
|
||||||
|
if (Visibility == "view")
|
||||||
|
{
|
||||||
|
// set module view permissions to page view permissions
|
||||||
|
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// set module view permissions to page edit permissions
|
||||||
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.Edit).Permissions;
|
permissions.Find(p => p.PermissionName == PermissionNames.View).Permissions = permissions.Find(p => p.PermissionName == PermissionNames.Edit).Permissions;
|
||||||
|
}
|
||||||
module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
module.Permissions = UserSecurity.SetPermissionStrings(permissions);
|
||||||
|
|
||||||
module = await ModuleService.AddModuleAsync(module);
|
module = await ModuleService.AddModuleAsync(module);
|
||||||
@ -399,6 +404,7 @@
|
|||||||
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
await PageModuleService.UpdatePageModuleOrderAsync(pageModule.PageId, pageModule.Pane);
|
||||||
|
|
||||||
Message = $"<div class=\"alert alert-success mt-2 text-center\" role=\"alert\">{Localizer["Success.Page.ModuleAdd"]}</div>";
|
Message = $"<div class=\"alert alert-success mt-2 text-center\" role=\"alert\">{Localizer["Success.Page.ModuleAdd"]}</div>";
|
||||||
|
Title = "";
|
||||||
NavigationManager.NavigateTo(NavigateUrl());
|
NavigationManager.NavigateTo(NavigateUrl());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2,6 +2,7 @@ using System;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
|
using Oqtane.Enums;
|
||||||
using Oqtane.Providers;
|
using Oqtane.Providers;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using Oqtane.Services;
|
using Oqtane.Services;
|
||||||
@ -17,6 +18,7 @@ namespace Oqtane.Themes.Controls
|
|||||||
[Inject] public IJSRuntime jsRuntime { get; set; }
|
[Inject] public IJSRuntime jsRuntime { get; set; }
|
||||||
[Inject] public IServiceProvider ServiceProvider { get; set; }
|
[Inject] public IServiceProvider ServiceProvider { get; set; }
|
||||||
[Inject] public SiteState SiteState { get; set; }
|
[Inject] public SiteState SiteState { get; set; }
|
||||||
|
[Inject] public ILogService LoggingService { get; set; }
|
||||||
|
|
||||||
protected void LoginUser()
|
protected void LoginUser()
|
||||||
{
|
{
|
||||||
@ -31,6 +33,8 @@ namespace Oqtane.Themes.Controls
|
|||||||
protected async Task LogoutUser()
|
protected async Task LogoutUser()
|
||||||
{
|
{
|
||||||
await UserService.LogoutUserAsync(PageState.User);
|
await UserService.LogoutUserAsync(PageState.User);
|
||||||
|
await LoggingService.Log(PageState.Alias, PageState.Page.PageId, PageState.ModuleId, PageState.User.UserId, GetType().AssemblyQualifiedName, "Logout", LogFunction.Security, LogLevel.Information, null, "User Logout For Username {Username}", PageState.User.Username);
|
||||||
|
|
||||||
PageState.User = null;
|
PageState.User = null;
|
||||||
bool authorizedtoviewpage = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, PageState.Page.Permissions);
|
bool authorizedtoviewpage = UserSecurity.IsAuthorized(PageState.User, PermissionNames.View, PageState.Page.Permissions);
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
@inject ISettingService SettingService
|
@inject ISettingService SettingService
|
||||||
|
|
||||||
<div class="@_classes">
|
<div class="@_classes">
|
||||||
@if (_title)
|
@if (_title && ModuleState.Title != "-")
|
||||||
{
|
{
|
||||||
<div class="row px-4">
|
<div class="row px-4">
|
||||||
<div class="d-flex flex-nowrap">
|
<div class="d-flex flex-nowrap">
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="title" ResourceKey="Title" HelpText="Specify If The Module Title Should Be Displayed">Display Title?</Label>
|
<Label Class="col-sm-3" For="title" ResourceKey="Title" ResourceType="@resourceType" HelpText="Specify If The Module Title Should Be Displayed">Display Title?</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="title" class="form-select" @bind="@_title">
|
<select id="title" class="form-select" @bind="@_title">
|
||||||
<option value="true">Yes</option>
|
<option value="true">Yes</option>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="background\" ResourceKey="Background" HelpText="Optionally Specify A Background Color For The Container">Background Color:</Label>
|
<Label Class="col-sm-3" For="background\" ResourceKey="Background" ResourceType="@resourceType" HelpText="Optionally Specify A Background Color For The Container">Background Color:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="background" class="form-select" @bind="@_background">
|
<select id="background" class="form-select" @bind="@_background">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="text" ResourceKey="Text" HelpText="Optionally Specify A Text Color For The Container">Text Color:</Label>
|
<Label Class="col-sm-3" For="text" ResourceKey="Text" ResourceType="@resourceType" HelpText="Optionally Specify A Text Color For The Container">Text Color:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="text" class="form-select" @bind="@_text">
|
<select id="text" class="form-select" @bind="@_text">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="border" ResourceKey="Border" HelpText="Optionally Specify A Border For The Container">Border Color:</Label>
|
<Label Class="col-sm-3" For="border" ResourceKey="Border" ResourceType="@resourceType" HelpText="Optionally Specify A Border For The Container">Border Color:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="border" class="form-select" @bind="@_border">
|
<select id="border" class="form-select" @bind="@_border">
|
||||||
<option value="">None</option>
|
<option value="">None</option>
|
||||||
@ -66,6 +66,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string resourceType = "Oqtane.Themes.OqtaneTheme.ContainerSettings, Oqtane.Client"; // for localization
|
||||||
private string _title = "true";
|
private string _title = "true";
|
||||||
private string _background = "";
|
private string _background = "";
|
||||||
private string _text = "";
|
private string _text = "";
|
||||||
@ -90,7 +91,7 @@
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var settings = ModuleState.Settings;
|
var settings = await SettingService.GetModuleSettingsAsync(ModuleState.ModuleId);
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Title", _title);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Title", _title);
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Background", _background);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Background", _background);
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Text", _text);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Text", _text);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="scope" ResourceKey="Scope" HelpText="Specify if the settings are applicable to this page or the entire site.">Setting Scope:</Label>
|
<Label Class="col-sm-3" For="scope" ResourceKey="Scope" ResourceType="@resourceType" HelpText="Specify if the settings are applicable to this page or the entire site.">Setting Scope:</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="scope" class="form-select" value="@_scope" @onchange="(e => ScopeChanged(e))">
|
<select id="scope" class="form-select" value="@_scope" @onchange="(e => ScopeChanged(e))">
|
||||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="login" ResourceKey="Login" HelpText="Specify if a Login option should be displayed. Note that this option does not prevent the login page from being accessible via a direct url.">Show Login?</Label>
|
<Label Class="col-sm-3" For="login" ResourceKey="Login" ResourceType="@resourceType" HelpText="Specify if a Login option should be displayed. Note that this option does not prevent the login page from being accessible via a direct url.">Show Login?</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="login" class="form-select" @bind="@_login">
|
<select id="login" class="form-select" @bind="@_login">
|
||||||
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
||||||
@ -30,7 +30,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="register" ResourceKey="Register" HelpText="Specify if a Register option should be displayed. Note that this option is also dependent on the Allow Registration option in Site Settings.">Show Register?</Label>
|
<Label Class="col-sm-3" For="register" ResourceKey="Register" ResourceType="@resourceType" HelpText="Specify if a Register option should be displayed. Note that this option is also dependent on the Allow Registration option in Site Settings.">Show Register?</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="register" class="form-select" @bind="@_register">
|
<select id="register" class="form-select" @bind="@_register">
|
||||||
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row mb-1 align-items-center">
|
<div class="row mb-1 align-items-center">
|
||||||
<Label Class="col-sm-3" For="footer" ResourceKey="Footer" HelpText="Specify if a Footer pane should always be displayed in a fixed location at the bottom of the page">Display Fixed Footer?</Label>
|
<Label Class="col-sm-3" For="footer" ResourceKey="Footer" ResourceType="@resourceType" HelpText="Specify if a Footer pane should always be displayed in a fixed location at the bottom of the page">Display Fixed Footer?</Label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<select id="footer" class="form-select" @bind="@_footer">
|
<select id="footer" class="form-select" @bind="@_footer">
|
||||||
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
<option value="-"><@SharedLocalizer["Not Specified"]></option>
|
||||||
@ -52,6 +52,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
private string resourceType = "Oqtane.Themes.OqtaneTheme.ThemeSettings, Oqtane.Client"; // for localization
|
||||||
private string _scope = "page";
|
private string _scope = "page";
|
||||||
private string _login = "-";
|
private string _login = "-";
|
||||||
private string _register = "-";
|
private string _register = "-";
|
||||||
@ -110,7 +111,7 @@
|
|||||||
{
|
{
|
||||||
if (_scope == "site")
|
if (_scope == "site")
|
||||||
{
|
{
|
||||||
var settings = PageState.Site.Settings;
|
var settings = await SettingService.GetSiteSettingsAsync(PageState.Site.SiteId);
|
||||||
if (_login != "-")
|
if (_login != "-")
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login, true);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login, true);
|
||||||
@ -127,7 +128,7 @@
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var settings = PageState.Page.Settings;
|
var settings = await SettingService.GetPageSettingsAsync(PageState.Page.PageId);
|
||||||
if (_login != "-")
|
if (_login != "-")
|
||||||
{
|
{
|
||||||
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
|
settings = SettingService.SetSetting(settings, GetType().Namespace + ":Login", _login);
|
||||||
|
@ -104,14 +104,19 @@ namespace Oqtane.Themes
|
|||||||
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
return Utilities.ContentUrl(PageState.Alias, fileid, asAttachment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ImageUrl(int fileid, int width, int height, string mode)
|
public string ImageUrl(int fileid, int width, int height)
|
||||||
{
|
{
|
||||||
return ImageUrl(fileid, width, height, mode, 0);
|
return ImageUrl(fileid, width, height, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ImageUrl(int fileid, int width, int height, string mode, int rotate)
|
public string ImageUrl(int fileid, int width, int height, string mode)
|
||||||
{
|
{
|
||||||
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, rotate);
|
return ImageUrl(fileid, width, height, mode, "", "", 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ImageUrl(int fileid, int width, int height, string mode, string position, string background, int rotate, bool recreate)
|
||||||
|
{
|
||||||
|
return Utilities.ImageUrl(PageState.Alias, fileid, width, height, mode, position, background, rotate, recreate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,5 +262,36 @@ namespace Oqtane.UI
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task ScrollTo(int top, int left, string behavior)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(behavior)) behavior = "smooth";
|
||||||
|
_jsRuntime.InvokeVoidAsync(
|
||||||
|
"Oqtane.Interop.scrollTo",
|
||||||
|
top, left, behavior);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task ScrollToId(string id)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_jsRuntime.InvokeVoidAsync(
|
||||||
|
"Oqtane.Interop.scrollToId",
|
||||||
|
id);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,5 +21,6 @@ namespace Oqtane.UI
|
|||||||
public DateTime LastSyncDate { get; set; }
|
public DateTime LastSyncDate { get; set; }
|
||||||
public Oqtane.Shared.Runtime Runtime { get; set; }
|
public Oqtane.Shared.Runtime Runtime { get; set; }
|
||||||
public int VisitorId { get; set; }
|
public int VisitorId { get; set; }
|
||||||
|
public string RemoteIPAddress { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,9 @@
|
|||||||
@inject IPageService PageService
|
@inject IPageService PageService
|
||||||
@inject IUserService UserService
|
@inject IUserService UserService
|
||||||
@inject IModuleService ModuleService
|
@inject IModuleService ModuleService
|
||||||
|
@inject IUrlMappingService UrlMappingService
|
||||||
@inject ILogService LogService
|
@inject ILogService LogService
|
||||||
|
@inject IJSRuntime JSRuntime
|
||||||
@implements IHandleAfterRender
|
@implements IHandleAfterRender
|
||||||
|
|
||||||
@DynamicComponent
|
@DynamicComponent
|
||||||
@ -139,9 +141,12 @@
|
|||||||
if (authState.User.Identity.IsAuthenticated)
|
if (authState.User.Identity.IsAuthenticated)
|
||||||
{
|
{
|
||||||
user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId);
|
user = await UserService.GetUserAsync(authState.User.Identity.Name, site.SiteId);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
user.IsAuthenticated = authState.User.Identity.IsAuthenticated;
|
user.IsAuthenticated = authState.User.Identity.IsAuthenticated;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
user = PageState.User;
|
user = PageState.User;
|
||||||
@ -225,17 +230,28 @@
|
|||||||
EditMode = editmode,
|
EditMode = editmode,
|
||||||
LastSyncDate = lastsyncdate,
|
LastSyncDate = lastsyncdate,
|
||||||
Runtime = runtime,
|
Runtime = runtime,
|
||||||
VisitorId = VisitorId
|
VisitorId = VisitorId,
|
||||||
|
RemoteIPAddress = SiteState.RemoteIPAddress
|
||||||
};
|
};
|
||||||
|
|
||||||
OnStateChange?.Invoke(_pagestate);
|
OnStateChange?.Invoke(_pagestate);
|
||||||
|
await ScrollToFragment(_pagestate.Uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else // page not found
|
||||||
|
{
|
||||||
|
// look for url mapping
|
||||||
|
var urlMapping = await UrlMappingService.GetUrlMappingAsync(site.SiteId, route.PagePath);
|
||||||
|
if (urlMapping != null && !string.IsNullOrEmpty(urlMapping.MappedUrl))
|
||||||
|
{
|
||||||
|
var url = (urlMapping.MappedUrl.StartsWith("http")) ? urlMapping.MappedUrl : route.SiteUrl + "/" + urlMapping.MappedUrl;
|
||||||
|
NavigationManager.NavigateTo(url, false);
|
||||||
|
}
|
||||||
|
else // not mapped
|
||||||
{
|
{
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
// redirect to login page
|
// redirect to login page if user not logged in as they may need to be authenticated
|
||||||
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + route.AbsolutePath));
|
NavigationManager.NavigateTo(Utilities.NavigateUrl(SiteState.Alias.Path, "login", "?returnurl=" + route.AbsolutePath));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -249,6 +265,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// site does not exist
|
// site does not exist
|
||||||
@ -481,4 +498,25 @@
|
|||||||
}
|
}
|
||||||
return pageresources;
|
return pageresources;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ScrollToFragment(Uri uri)
|
||||||
|
{
|
||||||
|
var fragment = uri.Fragment;
|
||||||
|
if (fragment.StartsWith('#'))
|
||||||
|
{
|
||||||
|
// handle text fragment (https://example.org/#test:~:text=foo)
|
||||||
|
var id = fragment.Substring(1);
|
||||||
|
var index = id.IndexOf(":~:", StringComparison.Ordinal);
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
id = id.Substring(0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(id))
|
||||||
|
{
|
||||||
|
var interop = new Interop(JSRuntime);
|
||||||
|
await interop.ScrollToId(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,23 +27,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||||
{
|
|
||||||
if (!firstRender)
|
|
||||||
{
|
{
|
||||||
var interop = new Interop(JsRuntime);
|
var interop = new Interop(JsRuntime);
|
||||||
|
|
||||||
// set page title
|
|
||||||
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
|
||||||
{
|
|
||||||
await interop.UpdateTitle(PageState.Page.Title);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
|
||||||
}
|
|
||||||
|
|
||||||
// manage stylesheets for this page
|
// manage stylesheets for this page
|
||||||
string batch = DateTime.Now.ToString("yyyyMMddHHmmssfff");
|
string batch = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");
|
||||||
var links = new List<object>();
|
var links = new List<object>();
|
||||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet && item.Declaration != ResourceDeclaration.Global))
|
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet && item.Declaration != ResourceDeclaration.Global))
|
||||||
{
|
{
|
||||||
@ -54,6 +42,15 @@
|
|||||||
await interop.IncludeLinks(links.ToArray());
|
await interop.IncludeLinks(links.ToArray());
|
||||||
}
|
}
|
||||||
await interop.RemoveElementsById("app-stylesheet", "", "app-stylesheet-" + batch + "-00");
|
await interop.RemoveElementsById("app-stylesheet", "", "app-stylesheet-" + batch + "-00");
|
||||||
|
|
||||||
|
// set page title
|
||||||
|
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
||||||
|
{
|
||||||
|
await interop.UpdateTitle(PageState.Page.Title);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.0.1</Version>
|
<Version>3.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Database.MySQL</id>
|
<id>Oqtane.Database.MySQL</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane MySQL Provider</title>
|
<title>Oqtane MySQL Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.0.1</Version>
|
<Version>3.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Database.PostgreSQL</id>
|
<id>Oqtane.Database.PostgreSQL</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane PostgreSQL Provider</title>
|
<title>Oqtane PostgreSQL Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.0.1</Version>
|
<Version>3.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Database.SqlServer</id>
|
<id>Oqtane.Database.SqlServer</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane SQL Server Provider</title>
|
<title>Oqtane SQL Server Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<Version>3.0.1</Version>
|
<Version>3.0.3</Version>
|
||||||
<Product>Oqtane</Product>
|
<Product>Oqtane</Product>
|
||||||
<Authors>Shaun Walker</Authors>
|
<Authors>Shaun Walker</Authors>
|
||||||
<Company>.NET Foundation</Company>
|
<Company>.NET Foundation</Company>
|
||||||
@ -10,7 +10,7 @@
|
|||||||
<Copyright>.NET Foundation</Copyright>
|
<Copyright>.NET Foundation</Copyright>
|
||||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</PackageReleaseNotes>
|
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</PackageReleaseNotes>
|
||||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||||
<RepositoryType>Git</RepositoryType>
|
<RepositoryType>Git</RepositoryType>
|
||||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Database.Sqlite</id>
|
<id>Oqtane.Database.Sqlite</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane SQLite Provider</title>
|
<title>Oqtane SQLite Provider</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -30,6 +30,11 @@ namespace Oqtane.Database.Sqlite
|
|||||||
return table.Column<int>(name: name, nullable: false).Annotation("Sqlite:Autoincrement", true);
|
return table.Column<int>(name: name, nullable: false).Annotation("Sqlite:Autoincrement", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void DropColumn(MigrationBuilder builder, string name, string table)
|
||||||
|
{
|
||||||
|
// not implemented as SQLite does not support dropping columns
|
||||||
|
}
|
||||||
|
|
||||||
public override string ConcatenateSql(params string[] values)
|
public override string ConcatenateSql(params string[] values)
|
||||||
{
|
{
|
||||||
var returnValue = String.Empty;
|
var returnValue = String.Empty;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Client</id>
|
<id>Oqtane.Client</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Framework</id>
|
<id>Oqtane.Framework</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -11,8 +11,8 @@
|
|||||||
<copyright>.NET Foundation</copyright>
|
<copyright>.NET Foundation</copyright>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.0.1/Oqtane.Framework.3.0.1.Upgrade.zip</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.0.3/Oqtane.Framework.3.0.3.Upgrade.zip</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane framework</tags>
|
<tags>oqtane framework</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Server</id>
|
<id>Oqtane.Server</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Shared</id>
|
<id>Oqtane.Shared</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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>Oqtane.Updater</id>
|
<id>Oqtane.Updater</id>
|
||||||
<version>3.0.1</version>
|
<version>3.0.3</version>
|
||||||
<authors>Shaun Walker</authors>
|
<authors>Shaun Walker</authors>
|
||||||
<owners>.NET Foundation</owners>
|
<owners>.NET Foundation</owners>
|
||||||
<title>Oqtane Framework</title>
|
<title>Oqtane Framework</title>
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<license type="expression">MIT</license>
|
<license type="expression">MIT</license>
|
||||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.1</releaseNotes>
|
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.0.3</releaseNotes>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<tags>oqtane</tags>
|
<tags>oqtane</tags>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
@ -1 +1 @@
|
|||||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.0.1.Install.zip" -Force
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.0.3.Install.zip" -Force
|
@ -1 +1 @@
|
|||||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.0.1.Upgrade.zip" -Force
|
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.0.3.Upgrade.zip" -Force
|
@ -19,7 +19,6 @@ using Oqtane.Extensions;
|
|||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.Processing;
|
using SixLabors.ImageSharp.Processing;
|
||||||
using SixLabors.ImageSharp.Formats.Png;
|
using SixLabors.ImageSharp.Formats.Png;
|
||||||
using SixLabors.ImageSharp.PixelFormats;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
|
||||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||||
@ -508,8 +507,8 @@ namespace Oqtane.Controllers
|
|||||||
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("image/{id}/{width}/{height}/{mode?}/{rotate?}")]
|
[HttpGet("image/{id}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}")]
|
||||||
public IActionResult GetImage(int id, int width, int height, string mode, string rotate)
|
public IActionResult GetImage(int id, int width, int height, string mode, string position, string background, string rotate, string recreate)
|
||||||
{
|
{
|
||||||
var file = _files.GetFile(id);
|
var file = _files.GetFile(id);
|
||||||
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
if (file != null && file.Folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, file.Folder.Permissions))
|
||||||
@ -519,21 +518,25 @@ namespace Oqtane.Controllers
|
|||||||
var filepath = _files.GetFilePath(file);
|
var filepath = _files.GetFilePath(file);
|
||||||
if (System.IO.File.Exists(filepath))
|
if (System.IO.File.Exists(filepath))
|
||||||
{
|
{
|
||||||
mode = (string.IsNullOrEmpty(mode)) ? "crop" : mode;
|
// validation
|
||||||
rotate = (string.IsNullOrEmpty(rotate)) ? "0" : rotate;
|
if (!Enum.TryParse(mode, true, out ResizeMode _)) mode = "crop";
|
||||||
|
if (!Enum.TryParse(position, true, out AnchorPositionMode _)) position = "center";
|
||||||
|
if (!Color.TryParseHex("#" + background, out _)) background = "000000";
|
||||||
|
if (!int.TryParse(rotate, out _)) rotate = "0";
|
||||||
|
rotate = (int.Parse(rotate) < 0 || int.Parse(rotate) > 360) ? "0" : rotate;
|
||||||
|
if (!bool.TryParse(recreate, out _)) recreate = "false";
|
||||||
|
|
||||||
string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + width.ToString() + "x" + height.ToString() + "." + mode.ToLower() + ".png");
|
string imagepath = filepath.Replace(Path.GetExtension(filepath), "." + width.ToString() + "x" + height.ToString() + ".png");
|
||||||
if (!System.IO.File.Exists(imagepath))
|
if (!System.IO.File.Exists(imagepath) || bool.Parse(recreate))
|
||||||
{
|
{
|
||||||
if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.Permissions) ||
|
if ((_userPermissions.IsAuthorized(User, PermissionNames.Edit, file.Folder.Permissions) ||
|
||||||
!string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(width.ToString() + "x" + height.ToString()))
|
!string.IsNullOrEmpty(file.Folder.ImageSizes) && file.Folder.ImageSizes.ToLower().Split(",").Contains(width.ToString() + "x" + height.ToString())))
|
||||||
&& Enum.TryParse(mode, true, out ResizeMode resizemode))
|
|
||||||
{
|
{
|
||||||
imagepath = CreateImage(filepath, width, height, resizemode.ToString(), rotate, imagepath);
|
imagepath = CreateImage(filepath, width, height, mode, position, background, rotate, imagepath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Invalid Image Size For Folder Or Invalid Mode Specification {Folder} {Width} {Height} {Mode}", file.Folder, width, height, mode);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Invalid Image Size For Folder {Folder} {Width} {Height}", file.Folder, width, height);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -569,35 +572,37 @@ namespace Oqtane.Controllers
|
|||||||
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
return System.IO.File.Exists(errorPath) ? PhysicalFile(errorPath, MimeUtilities.GetMimeType(errorPath)) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private string CreateImage(string filepath, int width, int height, string mode, string rotate, string imagepath)
|
private string CreateImage(string filepath, int width, int height, string mode, string position, string background, string rotate, string imagepath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FileStream stream = new FileStream(filepath, FileMode.Open, FileAccess.Read);
|
using (var stream = new FileStream(filepath, FileMode.Open, FileAccess.Read))
|
||||||
using (Image image = Image.Load(stream))
|
|
||||||
{
|
{
|
||||||
|
stream.Position = 0;
|
||||||
|
using (var image = Image.Load(stream))
|
||||||
|
{
|
||||||
|
int.TryParse(rotate, out int angle);
|
||||||
Enum.TryParse(mode, true, out ResizeMode resizemode);
|
Enum.TryParse(mode, true, out ResizeMode resizemode);
|
||||||
|
Enum.TryParse(position, true, out AnchorPositionMode anchorpositionmode);
|
||||||
|
|
||||||
image.Mutate(x =>
|
image.Mutate(x => x
|
||||||
x.Resize(new ResizeOptions
|
.AutoOrient() // auto orient the image
|
||||||
|
.Rotate(angle)
|
||||||
|
.Resize(new ResizeOptions
|
||||||
{
|
{
|
||||||
Size = new Size(width, height),
|
Mode = resizemode,
|
||||||
Mode = resizemode
|
Position = anchorpositionmode,
|
||||||
|
Size = new Size(width, height)
|
||||||
})
|
})
|
||||||
.BackgroundColor(new Rgba32(255, 255, 255, 0)));
|
.BackgroundColor(Color.ParseHex("#" + background)));
|
||||||
|
|
||||||
if (rotate != "0" && int.TryParse(rotate, out int angle))
|
|
||||||
{
|
|
||||||
image.Mutate(x => x.Rotate(angle));
|
|
||||||
}
|
|
||||||
|
|
||||||
image.Save(imagepath, new PngEncoder());
|
image.Save(imagepath, new PngEncoder());
|
||||||
}
|
}
|
||||||
stream.Close();
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Error Creating Image For File {FilePath} {Width} {Height} {Mode} {Error}", filepath, width, height, mode, ex.Message);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Error Creating Image For File {FilePath} {Width} {Height} {Mode} {Rotate} {Error}", filepath, width, height, mode, rotate, ex.Message);
|
||||||
imagepath = "";
|
imagepath = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Post Attempt {Alias}", job);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Post Attempt {Job}", job);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
job = null;
|
job = null;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Put Attempt {Alias}", job);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Job Put Attempt {Job}", job);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
job = null;
|
job = null;
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,7 @@ namespace Oqtane.Controllers
|
|||||||
|
|
||||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||||
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
module.Settings = settings.Where(item => item.EntityId == pagemodule.ModuleId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, pagemodule.Module.Permissions))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
|
|
||||||
modules.Add(module);
|
modules.Add(module);
|
||||||
@ -101,6 +102,7 @@ namespace Oqtane.Controllers
|
|||||||
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
List<ModuleDefinition> moduledefinitions = _moduleDefinitions.GetModuleDefinitions(module.SiteId).ToList();
|
||||||
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
module.ModuleDefinition = moduledefinitions.Find(item => item.ModuleDefinitionName == module.ModuleDefinitionName);
|
||||||
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
module.Settings = _settings.GetSettings(EntityNames.Module, id)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, module.Permissions))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
@ -171,7 +173,7 @@ namespace Oqtane.Controllers
|
|||||||
public void Delete(int id)
|
public void Delete(int id)
|
||||||
{
|
{
|
||||||
var module = _modules.GetModule(id);
|
var module = _modules.GetModule(id);
|
||||||
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, EntityNames.Page, module.ModuleId, PermissionNames.Edit))
|
if (module != null && module.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, EntityNames.Module, module.ModuleId, PermissionNames.Edit))
|
||||||
{
|
{
|
||||||
_modules.DeleteModule(id);
|
_modules.DeleteModule(id);
|
||||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
|
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
|
||||||
|
@ -57,6 +57,7 @@ namespace Oqtane.Controllers
|
|||||||
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
if (_userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
||||||
{
|
{
|
||||||
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
page.Settings = settings.Where(item => item.EntityId == page.PageId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
pages.Add(page);
|
pages.Add(page);
|
||||||
}
|
}
|
||||||
@ -85,15 +86,16 @@ namespace Oqtane.Controllers
|
|||||||
{
|
{
|
||||||
page = _pages.GetPage(id, int.Parse(userid));
|
page = _pages.GetPage(id, int.Parse(userid));
|
||||||
}
|
}
|
||||||
if (_userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions))
|
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions))
|
||||||
{
|
{
|
||||||
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {Page}", page);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {PageId} {UserId}", id, userid);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -104,24 +106,16 @@ namespace Oqtane.Controllers
|
|||||||
public Page Get(string path, int siteid)
|
public Page Get(string path, int siteid)
|
||||||
{
|
{
|
||||||
Page page = _pages.GetPage(WebUtility.UrlDecode(path), siteid);
|
Page page = _pages.GetPage(WebUtility.UrlDecode(path), siteid);
|
||||||
if (page != null && page.SiteId == _alias.SiteId)
|
if (page != null && page.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, PermissionNames.View, page.Permissions))
|
||||||
{
|
|
||||||
if (_userPermissions.IsAuthorized(User,PermissionNames.View, page.Permissions))
|
|
||||||
{
|
{
|
||||||
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
page.Settings = _settings.GetSettings(EntityNames.Page, page.PageId)
|
||||||
|
.Where(item => !item.IsPrivate || _userPermissions.IsAuthorized(User, PermissionNames.Edit, page.Permissions))
|
||||||
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {Page}", page);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {SiteId} {Path}", siteid, path);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized Page Get Attempt {Path} for Site {SiteId}", path, siteid);
|
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -267,11 +261,10 @@ namespace Oqtane.Controllers
|
|||||||
// save url mapping if page path changed
|
// save url mapping if page path changed
|
||||||
if (currentPage.Path != page.Path)
|
if (currentPage.Path != page.Path)
|
||||||
{
|
{
|
||||||
var url = HttpContext.Request.Scheme + "://" + _alias.Name + "/";
|
|
||||||
var urlMapping = new UrlMapping();
|
var urlMapping = new UrlMapping();
|
||||||
urlMapping.SiteId = page.SiteId;
|
urlMapping.SiteId = page.SiteId;
|
||||||
urlMapping.Url = url + currentPage.Path;
|
urlMapping.Url = currentPage.Path;
|
||||||
urlMapping.MappedUrl = url + page.Path;
|
urlMapping.MappedUrl = page.Path;
|
||||||
urlMapping.Requests = 0;
|
urlMapping.Requests = 0;
|
||||||
urlMapping.CreatedOn = System.DateTime.UtcNow;
|
urlMapping.CreatedOn = System.DateTime.UtcNow;
|
||||||
urlMapping.RequestedOn = System.DateTime.UtcNow;
|
urlMapping.RequestedOn = System.DateTime.UtcNow;
|
||||||
|
@ -20,6 +20,7 @@ namespace Oqtane.Controllers
|
|||||||
private readonly ISyncManager _syncManager;
|
private readonly ISyncManager _syncManager;
|
||||||
private readonly ILogManager _logger;
|
private readonly ILogManager _logger;
|
||||||
private readonly Alias _alias;
|
private readonly Alias _alias;
|
||||||
|
private readonly string _visitorCookie;
|
||||||
|
|
||||||
public SettingController(ISettingRepository settings, IPageModuleRepository pageModules, IUserPermissions userPermissions, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
public SettingController(ISettingRepository settings, IPageModuleRepository pageModules, IUserPermissions userPermissions, ITenantManager tenantManager, ISyncManager syncManager, ILogManager logger)
|
||||||
{
|
{
|
||||||
@ -29,39 +30,25 @@ namespace Oqtane.Controllers
|
|||||||
_syncManager = syncManager;
|
_syncManager = syncManager;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
_alias = tenantManager.GetAlias();
|
_alias = tenantManager.GetAlias();
|
||||||
|
_visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET: api/<controller>
|
// GET: api/<controller>
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IEnumerable<Setting> Get(string entityName, int entityid)
|
public IEnumerable<Setting> Get(string entityName, int entityId)
|
||||||
{
|
{
|
||||||
List<Setting> settings = new List<Setting>();
|
List<Setting> settings = new List<Setting>();
|
||||||
if (IsAuthorized(entityName, entityid, PermissionNames.View))
|
if (IsAuthorized(entityName, entityId, PermissionNames.View))
|
||||||
{
|
{
|
||||||
settings = _settings.GetSettings(entityName, entityid).ToList();
|
settings = _settings.GetSettings(entityName, entityId).ToList();
|
||||||
|
if (FilterPrivate(entityName, entityId))
|
||||||
// ispublic filter
|
|
||||||
switch (entityName)
|
|
||||||
{
|
{
|
||||||
case EntityNames.Tenant:
|
settings = settings.Where(item => !item.IsPrivate).ToList();
|
||||||
case EntityNames.ModuleDefinition:
|
|
||||||
case EntityNames.Host:
|
|
||||||
if (!User.IsInRole(RoleNames.Host))
|
|
||||||
{
|
|
||||||
settings = settings.Where(item => item.IsPublic).ToList();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EntityNames.Site:
|
|
||||||
if (!User.IsInRole(RoleNames.Admin))
|
|
||||||
{
|
|
||||||
settings = settings.Where(item => item.IsPublic).ToList();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Settings {EntityName} {EntityId}", entityName, entityid);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Settings {EntityName} {EntityId}", entityName, entityId);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
}
|
}
|
||||||
return settings;
|
return settings;
|
||||||
@ -74,30 +61,15 @@ namespace Oqtane.Controllers
|
|||||||
Setting setting = _settings.GetSetting(entityName, id);
|
Setting setting = _settings.GetSetting(entityName, id);
|
||||||
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.View))
|
if (IsAuthorized(setting.EntityName, setting.EntityId, PermissionNames.View))
|
||||||
{
|
{
|
||||||
// ispublic filter
|
if (FilterPrivate(entityName, id) && setting.IsPrivate)
|
||||||
switch (entityName)
|
|
||||||
{
|
|
||||||
case EntityNames.Tenant:
|
|
||||||
case EntityNames.ModuleDefinition:
|
|
||||||
case EntityNames.Host:
|
|
||||||
if (!User.IsInRole(RoleNames.Host) && !setting.IsPublic)
|
|
||||||
{
|
{
|
||||||
setting = null;
|
setting = null;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case EntityNames.Site:
|
|
||||||
if (!User.IsInRole(RoleNames.Admin) && !setting.IsPublic)
|
|
||||||
{
|
|
||||||
setting = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return setting;
|
return setting;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Setting {Setting}", setting);
|
_logger.Log(LogLevel.Error, this, LogFunction.Read, "User Not Authorized To Access Setting {EntityName} {SettingId}", entityName, id);
|
||||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -204,20 +176,67 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EntityNames.Visitor:
|
case EntityNames.Visitor:
|
||||||
var visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
|
authorized = User.IsInRole(RoleNames.Admin);
|
||||||
if (int.TryParse(Request.Cookies[visitorCookie], out int visitorId))
|
if (!authorized)
|
||||||
|
{
|
||||||
|
if (int.TryParse(Request.Cookies[_visitorCookie], out int visitorId))
|
||||||
{
|
{
|
||||||
authorized = (visitorId == entityId);
|
authorized = (visitorId == entityId);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // custom entity
|
||||||
|
if (permissionName == PermissionNames.Edit)
|
||||||
|
{
|
||||||
|
authorized = User.IsInRole(RoleNames.Admin) || _userPermissions.IsAuthorized(User, entityName, entityId, permissionName);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
authorized = User.IsInRole(RoleNames.Admin);
|
authorized = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return authorized;
|
return authorized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool FilterPrivate(string entityName, int entityId)
|
||||||
|
{
|
||||||
|
bool filter = false;
|
||||||
|
switch (entityName)
|
||||||
|
{
|
||||||
|
case EntityNames.Tenant:
|
||||||
|
case EntityNames.ModuleDefinition:
|
||||||
|
case EntityNames.Host:
|
||||||
|
filter = !User.IsInRole(RoleNames.Host);
|
||||||
|
break;
|
||||||
|
case EntityNames.Site:
|
||||||
|
filter = !User.IsInRole(RoleNames.Admin);
|
||||||
|
break;
|
||||||
|
case EntityNames.Page:
|
||||||
|
case EntityNames.Module:
|
||||||
|
case EntityNames.Folder:
|
||||||
|
filter = !_userPermissions.IsAuthorized(User, entityName, entityId, PermissionNames.Edit);
|
||||||
|
break;
|
||||||
|
case EntityNames.User:
|
||||||
|
filter = !User.IsInRole(RoleNames.Admin) && _userPermissions.GetUser(User).UserId != entityId;
|
||||||
|
break;
|
||||||
|
case EntityNames.Visitor:
|
||||||
|
if (!User.IsInRole(RoleNames.Admin))
|
||||||
|
{
|
||||||
|
filter = true;
|
||||||
|
if (int.TryParse(Request.Cookies[_visitorCookie], out int visitorId))
|
||||||
|
{
|
||||||
|
filter = (visitorId != entityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: // custom entity
|
||||||
|
filter = !User.IsInRole(RoleNames.Admin) && !_userPermissions.IsAuthorized(User, entityName, entityId, PermissionNames.Edit);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
private void AddSyncEvent(string EntityName)
|
private void AddSyncEvent(string EntityName)
|
||||||
{
|
{
|
||||||
switch (EntityName)
|
switch (EntityName)
|
||||||
|
@ -44,12 +44,9 @@ namespace Oqtane.Controllers
|
|||||||
var site = _sites.GetSite(id);
|
var site = _sites.GetSite(id);
|
||||||
if (site.SiteId == _alias.SiteId)
|
if (site.SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
var settings = _settings.GetSettings(EntityNames.Site, site.SiteId);
|
site.Settings = _settings.GetSettings(EntityNames.Site, site.SiteId)
|
||||||
if (!User.IsInRole(RoleNames.Admin))
|
.Where(item => !item.IsPrivate || User.IsInRole(RoleNames.Admin))
|
||||||
{
|
.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
||||||
settings = settings.Where(item => item.IsPublic);
|
|
||||||
}
|
|
||||||
site.Settings = settings.ToDictionary(setting => setting.SettingName, setting => setting.SettingValue);
|
|
||||||
return site;
|
return site;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -31,7 +31,7 @@ namespace Oqtane.Controllers
|
|||||||
systeminfo.Add("osversion", Environment.OSVersion.ToString());
|
systeminfo.Add("osversion", Environment.OSVersion.ToString());
|
||||||
systeminfo.Add("machinename", Environment.MachineName);
|
systeminfo.Add("machinename", Environment.MachineName);
|
||||||
systeminfo.Add("serverpath", _environment.ContentRootPath);
|
systeminfo.Add("serverpath", _environment.ContentRootPath);
|
||||||
systeminfo.Add("servertime", DateTime.Now.ToString());
|
systeminfo.Add("servertime", DateTime.UtcNow.ToString());
|
||||||
systeminfo.Add("installationid", _configManager.GetInstallationId());
|
systeminfo.Add("installationid", _configManager.GetInstallationId());
|
||||||
|
|
||||||
systeminfo.Add("runtime", _configManager.GetSetting("Runtime", "Server"));
|
systeminfo.Add("runtime", _configManager.GetSetting("Runtime", "Server"));
|
||||||
|
@ -48,7 +48,7 @@ namespace Oqtane.Controllers
|
|||||||
public UrlMapping Get(int id)
|
public UrlMapping Get(int id)
|
||||||
{
|
{
|
||||||
var urlMapping = _urlMappings.GetUrlMapping(id);
|
var urlMapping = _urlMappings.GetUrlMapping(id);
|
||||||
if (urlMapping != null && (urlMapping.SiteId == _alias.SiteId))
|
if (urlMapping != null && urlMapping.SiteId == _alias.SiteId)
|
||||||
{
|
{
|
||||||
return urlMapping;
|
return urlMapping;
|
||||||
}
|
}
|
||||||
@ -60,6 +60,23 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GET api/<controller>/url/x?url=y
|
||||||
|
[HttpGet("url/{siteid}")]
|
||||||
|
public UrlMapping Get(int siteid, string url)
|
||||||
|
{
|
||||||
|
var urlMapping = _urlMappings.GetUrlMapping(siteid, WebUtility.UrlDecode(url));
|
||||||
|
if (urlMapping != null && urlMapping.SiteId == _alias.SiteId)
|
||||||
|
{
|
||||||
|
return urlMapping;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized UrlMapping Get Attempt {SiteId} {Url}", siteid, url);
|
||||||
|
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// POST api/<controller>
|
// POST api/<controller>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize(Roles = RoleNames.Admin)]
|
[Authorize(Roles = RoleNames.Admin)]
|
||||||
|
@ -389,7 +389,7 @@ namespace Oqtane.Controllers
|
|||||||
if (ModelState.IsValid)
|
if (ModelState.IsValid)
|
||||||
{
|
{
|
||||||
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
||||||
if (identityuser != null)
|
if (identityuser != null && !string.IsNullOrEmpty(token))
|
||||||
{
|
{
|
||||||
var result = await _identityUserManager.ConfirmEmailAsync(identityuser, token);
|
var result = await _identityUserManager.ConfirmEmailAsync(identityuser, token);
|
||||||
if (result.Succeeded)
|
if (result.Succeeded)
|
||||||
@ -398,13 +398,13 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Email Verification Failed For {Username}", user.Username);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Email Verification Failed For {Username} - Error {Error}", user.Username, result.Errors.ToString());
|
||||||
user = null;
|
user = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Email Verification Failed For {Username}", user.Username);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Email Verification Failed For {Username}And Token {Token}", user.Username, token);
|
||||||
user = null;
|
user = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -420,9 +420,14 @@ namespace Oqtane.Controllers
|
|||||||
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
IdentityUser identityuser = await _identityUserManager.FindByNameAsync(user.Username);
|
||||||
if (identityuser != null)
|
if (identityuser != null)
|
||||||
{
|
{
|
||||||
|
user = _users.GetUser(user.Username);
|
||||||
string token = await _identityUserManager.GeneratePasswordResetTokenAsync(identityuser);
|
string token = await _identityUserManager.GeneratePasswordResetTokenAsync(identityuser);
|
||||||
string url = HttpContext.Request.Scheme + "://" + _alias.Name + "/reset?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
string url = HttpContext.Request.Scheme + "://" + _alias.Name + "/reset?name=" + user.Username + "&token=" + WebUtility.UrlEncode(token);
|
||||||
string body = "Dear " + user.DisplayName + ",\n\nPlease Click The Link Displayed Below To Reset Your Password:\n\n" + url + "\n\nThank You!";
|
string body = "Dear " + user.DisplayName + ",\n\nYou recently requested to reset your password. Please use the link below to complete the process:\n\n" + url +
|
||||||
|
"\n\nPlease note that the link is only valid for 24 hours so if you are unable to take action within that time period, you should initiate another password reset on the site." +
|
||||||
|
"\n\nIf you did not request to reset your password you can safely ignore this message." +
|
||||||
|
"\n\nThank You!";
|
||||||
|
|
||||||
var notification = new Notification(user.SiteId, null, user, "User Password Reset", body, null);
|
var notification = new Notification(user.SiteId, null, user, "User Password Reset", body, null);
|
||||||
_notifications.AddNotification(notification);
|
_notifications.AddNotification(notification);
|
||||||
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset Notification Sent For {Username}", user.Username);
|
_logger.Log(LogLevel.Information, this, LogFunction.Security, "Password Reset Notification Sent For {Username}", user.Username);
|
||||||
@ -451,13 +456,13 @@ namespace Oqtane.Controllers
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Failed For {Username}", user.Username);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Failed For {Username} - Error {Error}", user.Username, result.Errors.ToString());
|
||||||
user = null;
|
user = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Failed For {Username}", user.Username);
|
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Password Reset Failed For {Username} And Token {Token}", user.Username, token);
|
||||||
user = null;
|
user = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,15 +47,14 @@ namespace Oqtane.Controllers
|
|||||||
[HttpGet("{id}")]
|
[HttpGet("{id}")]
|
||||||
public Visitor Get(int id)
|
public Visitor Get(int id)
|
||||||
{
|
{
|
||||||
bool authorized;
|
bool authorized = User.IsInRole(RoleNames.Admin);
|
||||||
|
if (!authorized)
|
||||||
|
{
|
||||||
var visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
|
var visitorCookie = "APP_VISITOR_" + _alias.SiteId.ToString();
|
||||||
if (int.TryParse(Request.Cookies[visitorCookie], out int visitorId))
|
if (int.TryParse(Request.Cookies[visitorCookie], out int visitorId))
|
||||||
{
|
{
|
||||||
authorized = (visitorId == id);
|
authorized = (visitorId == id);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
authorized = User.IsInRole(RoleNames.Admin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var visitor = _visitors.GetVisitor(id);
|
var visitor = _visitors.GetVisitor(id);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
||||||
using Oqtane.Databases.Interfaces;
|
using Oqtane.Databases.Interfaces;
|
||||||
@ -75,6 +76,11 @@ namespace Oqtane.Databases
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void DropColumn(MigrationBuilder builder, string name, string table)
|
||||||
|
{
|
||||||
|
builder.DropColumn(name, table);
|
||||||
|
}
|
||||||
|
|
||||||
public abstract DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString);
|
public abstract DbContextOptionsBuilder UseDatabase(DbContextOptionsBuilder optionsBuilder, string connectionString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user