commit
a703df40c0
|
@ -1,3 +1,5 @@
|
|||
using System;
|
||||
|
||||
namespace Microsoft.Extensions.Localization
|
||||
{
|
||||
public static class OqtaneLocalizationExtensions
|
||||
|
@ -18,5 +20,42 @@ namespace Microsoft.Extensions.Localization
|
|||
}
|
||||
return localizedValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an IStringLocalizer based on a type name. This extension method is useful in scenarios where the default IStringLocalizer is unable to locate the resources.
|
||||
/// </summary>
|
||||
/// <param name="localizerFactory"></param>
|
||||
/// <param name="fullTypeName">the full type name ie. GetType().FullName</param>
|
||||
/// <returns></returns>
|
||||
public static IStringLocalizer Create(this IStringLocalizerFactory localizerFactory, string fullTypeName)
|
||||
{
|
||||
var typename = fullTypeName;
|
||||
|
||||
// handle generic types
|
||||
var type = Type.GetType(fullTypeName);
|
||||
if (type.IsGenericType)
|
||||
{
|
||||
typename = type.GetGenericTypeDefinition().FullName;
|
||||
typename = typename.Substring(0, typename.IndexOf("`")); // remove generic type info
|
||||
}
|
||||
|
||||
// format typename
|
||||
if (typename.Contains(","))
|
||||
{
|
||||
typename = typename.Substring(0, typename.IndexOf(",")); // remove assembly info
|
||||
}
|
||||
|
||||
// remove rootnamespace
|
||||
var rootnamespace = "";
|
||||
var attributes = type.Assembly.GetCustomAttributes(typeof(RootNamespaceAttribute), false);
|
||||
if (attributes.Length > 0)
|
||||
{
|
||||
rootnamespace = ((RootNamespaceAttribute)attributes[0]).RootNamespace;
|
||||
}
|
||||
typename = typename.Replace(rootnamespace + ".", "");
|
||||
|
||||
// create IStringLocalizer using factory
|
||||
return localizerFactory.Create(typename, type.Assembly.GetName().Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,15 +28,8 @@
|
|||
{
|
||||
<select id="databasetype" class="form-select custom-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))">
|
||||
@foreach (var database in _databases)
|
||||
{
|
||||
if (database.IsDefault)
|
||||
{
|
||||
<option value="@database.Name" selected>@Localizer[@database.Name]</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@database.Name">@Localizer[@database.Name]</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
}
|
||||
|
@ -63,8 +56,8 @@
|
|||
<Label Class="col-sm-3" For="password" HelpText="Provide a password for the primary user account" ResourceKey="Password">Password:</Label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input id="password" type="@_passwordtype" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
||||
<input id="password" type="@_passwordType" class="form-control" @bind="@_hostPassword" autocomplete="new-password" />
|
||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglePassword</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -72,8 +65,8 @@
|
|||
<Label Class="col-sm-3" For="confirm" HelpText="Please confirm the password entered above by entering it again" ResourceKey="Confirm">Confirm:</Label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
||||
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword">@_togglepassword</button>
|
||||
<input id="confirm" type="@_confirmPasswordType" class="form-control" @bind="@_confirmPassword" autocomplete="new-password" />
|
||||
<button type="button" class="btn btn-secondary" @onclick="@ToggleConfirmPassword">@_toggleConfirmPassword</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -110,8 +103,10 @@
|
|||
|
||||
private string _hostUsername = string.Empty;
|
||||
private string _hostPassword = string.Empty;
|
||||
private string _passwordtype = "password";
|
||||
private string _togglepassword = string.Empty;
|
||||
private string _passwordType = "password";
|
||||
private string _confirmPasswordType = "password";
|
||||
private string _togglePassword = string.Empty;
|
||||
private string _toggleConfirmPassword = string.Empty;
|
||||
private string _confirmPassword = string.Empty;
|
||||
private string _hostEmail = string.Empty;
|
||||
private bool _register = true;
|
||||
|
@ -120,7 +115,9 @@
|
|||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||
_toggleConfirmPassword = SharedLocalizer["ShowPassword"];
|
||||
|
||||
_databases = await DatabaseService.GetDatabasesAsync();
|
||||
if (_databases.Exists(item => item.IsDefault))
|
||||
{
|
||||
|
@ -230,15 +227,29 @@
|
|||
|
||||
private void TogglePassword()
|
||||
{
|
||||
if (_passwordtype == "password")
|
||||
if (_passwordType == "password")
|
||||
{
|
||||
_passwordtype = "text";
|
||||
_togglepassword = SharedLocalizer["HidePassword"];
|
||||
_passwordType = "text";
|
||||
_togglePassword = SharedLocalizer["HidePassword"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_passwordtype = "password";
|
||||
_togglepassword = SharedLocalizer["ShowPassword"];
|
||||
_passwordType = "password";
|
||||
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||
}
|
||||
}
|
||||
|
||||
private void ToggleConfirmPassword()
|
||||
{
|
||||
if (_confirmPasswordType == "password")
|
||||
{
|
||||
_confirmPasswordType = "text";
|
||||
_toggleConfirmPassword = SharedLocalizer["HidePassword"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_confirmPasswordType = "password";
|
||||
_toggleConfirmPassword = SharedLocalizer["ShowPassword"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ else
|
|||
@if (_availableCultures.Count() == 0)
|
||||
{
|
||||
<ModuleMessage Type="MessageType.Info" Message="@_message"></ModuleMessage>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -47,9 +48,9 @@ else
|
|||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success" @onclick="SaveLanguage">@SharedLocalizer["Save"]</button>
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
</form>
|
||||
}
|
||||
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Download" ResourceKey="Download" Security="SecurityAccessLevel.Host">
|
||||
<div class="row justify-content-center mb-3">
|
||||
|
@ -78,6 +79,7 @@ else
|
|||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
||||
</td>
|
||||
<td style="width: 1px; vertical-align: middle;">
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@namespace Oqtane.Modules.Admin.Logs
|
||||
@inherits ModuleBase
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject ILogService LogService
|
||||
@inject ISettingService SettingService
|
||||
@inject IStringLocalizer<Index> Localizer
|
||||
|
@ -104,6 +105,10 @@ else
|
|||
{
|
||||
try
|
||||
{
|
||||
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int id))
|
||||
{
|
||||
NavigationManager.NavigateTo(EditUrl(PageState.Page.Path, ModuleState.ModuleId, "Detail", $"id={id}"));
|
||||
}
|
||||
if (PageState.QueryString.ContainsKey("level"))
|
||||
{
|
||||
_level = PageState.QueryString["level"];
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
||||
</td>
|
||||
<td style="width: 1px; vertical-align: middle;">
|
||||
|
|
|
@ -12,11 +12,32 @@
|
|||
}
|
||||
else
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="col-sm-6">
|
||||
<ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" />
|
||||
@((MarkupString)" ")
|
||||
<ActionLink Action="Create" Text="Create Module" ResourceKey="CreateModule" Class="btn btn-secondary" />
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" @onchange="(e => CategoryChanged(e))">
|
||||
@foreach (var category in _categories)
|
||||
{
|
||||
if (category == _category)
|
||||
{
|
||||
<option value="@category" selected>@category @Localizer["Modules"]</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@category">@category @Localizer["Modules"]</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Pager Items="@_moduleDefinitions">
|
||||
<Pager Items="@_moduleDefinitions.Where(item => item.Categories.Contains(_category))">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
|
@ -65,6 +86,8 @@ else
|
|||
@code {
|
||||
private List<ModuleDefinition> _moduleDefinitions;
|
||||
private List<Package> _packages;
|
||||
private List<string> _categories = new List<string>();
|
||||
private string _category = "Common";
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
|
@ -74,6 +97,7 @@ else
|
|||
{
|
||||
_moduleDefinitions = await ModuleDefinitionService.GetModuleDefinitionsAsync(PageState.Site.SiteId);
|
||||
_packages = await PackageService.GetPackagesAsync("module");
|
||||
_categories = _moduleDefinitions.SelectMany(m => m.Categories.Split(',')).Distinct().ToList();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -149,4 +173,10 @@ else
|
|||
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void CategoryChanged(ChangeEventArgs e)
|
||||
{
|
||||
_category = (string)e.Value;
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@
|
|||
|
||||
var module = ModuleState;
|
||||
module.AllPages = bool.Parse(_allPages);
|
||||
module.PageModuleId = ModuleState.PageModuleId;
|
||||
module.Permissions = _permissionGrid.GetPermissions();
|
||||
await ModuleService.UpdateModuleAsync(module);
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ else
|
|||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
_roles = await RoleService.GetRolesAsync(PageState.Site.SiteId, true);
|
||||
_roles = _roles.Where(item => item.Name != RoleNames.Everyone).ToList();
|
||||
_roles.RemoveAll(item => item.Name == RoleNames.Everyone || item.Name == RoleNames.Unauthenticated);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -172,20 +172,50 @@
|
|||
<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>
|
||||
<Label Class="col-sm-3" For="aliases" HelpText="The list of aliases for this site" 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())
|
||||
<button type="button" class="btn btn-primary" @onclick="AddAlias">@SharedLocalizer["Add"]</button>
|
||||
<Pager Items="@_aliases">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th>@Localizer["AliasName"]</th>
|
||||
<th>@Localizer["AliasDefault"]</th>
|
||||
</Header>
|
||||
<Row>
|
||||
@if (context.AliasId != _aliasid)
|
||||
{
|
||||
<option value="@name">@name</option>
|
||||
<td>
|
||||
@if (_aliasid == -1)
|
||||
{
|
||||
<button type="button" class="btn btn-primary" @onclick="@(() => EditAlias(context))">@SharedLocalizer["Edit"]</button>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (_aliasid == -1)
|
||||
{
|
||||
<ActionDialog Action="Delete" OnClick="@(async () => await DeleteAlias(context))" ResourceKey="DeleteModule" Class="btn btn-danger" Header="Delete Alias" Message="@string.Format(Localizer["Confirm.Alias.Delete", context.Name])" />
|
||||
}
|
||||
</td>
|
||||
<td>@context.Name</td>
|
||||
<td>@context.IsDefault</td>
|
||||
}
|
||||
else
|
||||
{
|
||||
<td><button type="button" class="btn btn-success" @onclick="@(async () => await SaveAlias())">@SharedLocalizer["Save"]</button></td>
|
||||
<td><button type="button" class="btn btn-secondary" @onclick="@(async () => await CancelAlias())">@SharedLocalizer["Cancel"]</button></td>
|
||||
<td>
|
||||
<input id="aliasname" class="form-control" @bind="@_aliasname" />
|
||||
</td>
|
||||
<td>
|
||||
<select id="defaultaias" class="form-select" @bind="@_defaultalias" required>
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
<option value="False">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</td>
|
||||
}
|
||||
</Row>
|
||||
</Pager>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -253,8 +283,9 @@
|
|||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
private string _name = string.Empty;
|
||||
private List<Alias> _aliases;
|
||||
private string _defaultalias = string.Empty;
|
||||
private string _urls = string.Empty;
|
||||
private int _aliasid = -1;
|
||||
private string _aliasname;
|
||||
private string _defaultalias;
|
||||
private string _runtime = "";
|
||||
private string _prerender = "";
|
||||
private int _logofileid = -1;
|
||||
|
@ -304,10 +335,7 @@
|
|||
_prerender = site.RenderMode.Replace(_runtime, "");
|
||||
_isdeleted = site.IsDeleted.ToString();
|
||||
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
await GetAliases();
|
||||
}
|
||||
|
||||
if (site.LogoFileId != null)
|
||||
{
|
||||
|
@ -408,24 +436,6 @@
|
|||
try
|
||||
{
|
||||
if (_name != string.Empty && _themetype != "-" && _containertype != "-")
|
||||
{
|
||||
var unique = true;
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
_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())
|
||||
{
|
||||
var alias = aliases.Where(item => item.Name == name).FirstOrDefault();
|
||||
if (alias != null && unique)
|
||||
{
|
||||
unique = (alias.TenantId == PageState.Site.TenantId && alias.SiteId == PageState.Site.SiteId);
|
||||
}
|
||||
}
|
||||
if (unique && string.IsNullOrEmpty(_defaultalias)) unique = false;
|
||||
}
|
||||
|
||||
if (unique)
|
||||
{
|
||||
var site = await SiteService.GetSiteAsync(PageState.Site.SiteId);
|
||||
if (site != null)
|
||||
|
@ -502,43 +512,6 @@
|
|||
settings = SettingService.SetSetting(settings, "NotificationRetention", _retention, true);
|
||||
await SettingService.UpdateSiteSettingsAsync(settings, site.SiteId);
|
||||
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
var names = _urls.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(sValue => sValue.Trim()).ToArray();
|
||||
foreach (Alias alias in _aliases)
|
||||
{
|
||||
if (!names.Contains(alias.Name.Trim()))
|
||||
{
|
||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
var alias = _aliases.Find(item => item.Name.Trim() == name);
|
||||
if (alias == null)
|
||||
{
|
||||
alias = new Alias();
|
||||
alias.Name = name;
|
||||
alias.TenantId = site.TenantId;
|
||||
alias.SiteId = site.SiteId;
|
||||
alias.IsDefault = (name == _defaultalias);
|
||||
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);
|
||||
|
||||
if (refresh || reload)
|
||||
|
@ -552,11 +525,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
else // deuplicate alias or default alias not specified
|
||||
{
|
||||
AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddModuleMessage(Localizer["Message.Required.SiteName"], MessageType.Warning);
|
||||
|
@ -578,19 +546,19 @@
|
|||
{
|
||||
try
|
||||
{
|
||||
var sites = await SiteService.GetSitesAsync();
|
||||
if (sites.Count > 1)
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
if (aliases.Any(item => item.SiteId != PageState.Site.SiteId || item.TenantId != PageState.Site.TenantId))
|
||||
{
|
||||
await SiteService.DeleteSiteAsync(PageState.Site.SiteId);
|
||||
await logger.LogInformation("Site Deleted {SiteId}", PageState.Site.SiteId);
|
||||
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
foreach (Alias a in aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId))
|
||||
foreach (Alias alias in aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId))
|
||||
{
|
||||
await AliasService.DeleteAliasAsync(a.AliasId);
|
||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||
}
|
||||
|
||||
NavigationManager.NavigateTo(NavigateUrl("admin/sites"));
|
||||
aliases = await AliasService.GetAliasesAsync();
|
||||
NavigationManager.NavigateTo(PageState.Uri.Scheme + "://" + aliases.First().Name, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -637,20 +605,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
private void ToggleSMTPPassword()
|
||||
{
|
||||
if (_smtppasswordtype == "password")
|
||||
|
@ -664,4 +618,84 @@
|
|||
_togglesmtppassword = SharedLocalizer["ShowPassword"];
|
||||
}
|
||||
}
|
||||
|
||||
private async Task GetAliases()
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
_aliases = await AliasService.GetAliasesAsync();
|
||||
_aliases = _aliases.Where(item => item.SiteId == PageState.Site.SiteId && item.TenantId == PageState.Site.TenantId).OrderBy(item => item.AliasId).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAlias()
|
||||
{
|
||||
_aliases.Add(new Alias { AliasId = 0, Name = "", IsDefault = false });
|
||||
_aliasid = 0;
|
||||
_aliasname = "";
|
||||
_defaultalias = "False";
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void EditAlias(Alias alias)
|
||||
{
|
||||
_aliasid = alias.AliasId;
|
||||
_aliasname = alias.Name;
|
||||
_defaultalias = alias.IsDefault.ToString();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private async Task DeleteAlias(Alias alias)
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
await AliasService.DeleteAliasAsync(alias.AliasId);
|
||||
await GetAliases();
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SaveAlias()
|
||||
{
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_aliasname))
|
||||
{
|
||||
var aliases = await AliasService.GetAliasesAsync();
|
||||
var alias = aliases.Where(item => item.Name == _aliasname).FirstOrDefault();
|
||||
bool unique = (alias == null || alias.AliasId == _aliasid);
|
||||
if (unique)
|
||||
{
|
||||
if (_aliasid == 0)
|
||||
{
|
||||
alias = new Alias { SiteId = PageState.Site.SiteId, TenantId = PageState.Site.TenantId, Name = _aliasname, IsDefault = bool.Parse(_defaultalias) };
|
||||
await AliasService.AddAliasAsync(alias);
|
||||
}
|
||||
else
|
||||
{
|
||||
alias = _aliases.Single(item => item.AliasId == _aliasid);
|
||||
alias.Name = _aliasname;
|
||||
alias.IsDefault = bool.Parse(_defaultalias);
|
||||
await AliasService.UpdateAliasAsync(alias);
|
||||
}
|
||||
}
|
||||
else // duplicate alias
|
||||
{
|
||||
AddModuleMessage(Localizer["Message.Aliases.Taken"], MessageType.Warning);
|
||||
}
|
||||
}
|
||||
await GetAliases();
|
||||
_aliasid = -1;
|
||||
_aliasname = "";
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CancelAlias()
|
||||
{
|
||||
await GetAliases();
|
||||
_aliasid = -1;
|
||||
_aliasname = "";
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,16 +130,9 @@ else
|
|||
<div class="col-sm-9">
|
||||
<select id="databaseType" class="form-select" value="@_databaseName" @onchange="(e => DatabaseChanged(e))" required>
|
||||
@foreach (var database in _databases)
|
||||
{
|
||||
if (database.IsDefault)
|
||||
{
|
||||
<option value="@database.Name" selected>@Localizer[@database.Name]</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@database.Name">@Localizer[@database.Name]</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -172,12 +165,11 @@ else
|
|||
private List<Database> _databases;
|
||||
private ElementReference form;
|
||||
private bool validated = false;
|
||||
private string _databaseName = "LocalDB";
|
||||
private string _databaseName;
|
||||
private Type _databaseConfigType;
|
||||
private object _databaseConfig;
|
||||
private RenderFragment DatabaseConfigComponent { get; set; }
|
||||
|
||||
|
||||
private List<Theme> _themeList;
|
||||
private List<ThemeControl> _themes = new List<ThemeControl>();
|
||||
private List<ThemeControl> _containers = new List<ThemeControl>();
|
||||
|
@ -208,7 +200,16 @@ else
|
|||
_themeList = await ThemeService.GetThemesAsync();
|
||||
_themes = ThemeService.GetThemeControls(_themeList);
|
||||
_siteTemplates = await SiteTemplateService.GetSiteTemplatesAsync();
|
||||
|
||||
_databases = await DatabaseService.GetDatabasesAsync();
|
||||
if (_databases.Exists(item => item.IsDefault))
|
||||
{
|
||||
_databaseName = _databases.Find(item => item.IsDefault).Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
_databaseName = "LocalDB";
|
||||
}
|
||||
LoadDatabaseConfigComponent();
|
||||
}
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@
|
|||
<ActionDialog Header="Restart Application" Message="Are You Sure You Wish To Restart The Application?" Action="Restart Application" Security="SecurityAccessLevel.Host" Class="btn btn-danger" OnClick="@(async () => await RestartApplication())" ResourceKey="RestartApplication" />
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
<br /><br />
|
||||
|
||||
@code {
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
<strong>@(String.Format("{0:n0}", context.Downloads))</strong> @SharedLocalizer["Search.Downloads"] |
|
||||
@SharedLocalizer["Search.Released"]: <strong>@context.ReleaseDate.ToString("MMM dd, yyyy")</strong> |
|
||||
@SharedLocalizer["Search.Version"]: <strong>@context.Version</strong>
|
||||
@((MarkupString)(!string.IsNullOrEmpty(context.PackageUrl) ? " | " + SharedLocalizer["Search.Source"] + ": <strong>" + new Uri(context.PackageUrl).Host + "</strong>" : ""))
|
||||
@((MarkupString)(context.TrialPeriod > 0 ? " | <strong>" + context.TrialPeriod + " " + @SharedLocalizer["Trial"] + "</strong>" : ""))
|
||||
</td>
|
||||
<td style="width: 1px; vertical-align: middle;">
|
||||
|
|
|
@ -88,15 +88,17 @@ else
|
|||
userid = Int32.Parse(PageState.QueryString["id"]);
|
||||
User user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
|
||||
name = user.DisplayName;
|
||||
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
roles = await RoleService.GetRolesAsync(PageState.Site.SiteId, true);
|
||||
roles = roles.Where(item => item.Name != RoleNames.Everyone).ToList();
|
||||
roles.RemoveAll(item => item.Name == RoleNames.Everyone || item.Name == RoleNames.Unauthenticated);
|
||||
}
|
||||
else
|
||||
{
|
||||
roles = await RoleService.GetRolesAsync(PageState.Site.SiteId);
|
||||
}
|
||||
|
||||
await GetUserRoles();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -310,6 +310,17 @@
|
|||
var interop = new Interop(JSRuntime);
|
||||
var upload = await interop.GetFiles(_fileinputid);
|
||||
if (upload.Length > 0)
|
||||
{
|
||||
string restricted = "";
|
||||
foreach (var file in upload)
|
||||
{
|
||||
var extension = (file.LastIndexOf(".") != -1) ? file.Substring(file.LastIndexOf(".") + 1) : "";
|
||||
if (!Constants.UploadableFiles.Split(',').Contains(extension.ToLower()))
|
||||
{
|
||||
restricted += (restricted == "" ? "" : ",") + extension;
|
||||
}
|
||||
}
|
||||
if (restricted == "")
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -360,6 +371,12 @@
|
|||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = string.Format(Localizer["Message.File.Restricted"], restricted);
|
||||
_messagetype = MessageType.Warning;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_message = Localizer["Message.File.NotSelected"];
|
||||
_messagetype = MessageType.Warning;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
using System;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Oqtane.Shared;
|
||||
|
||||
namespace Oqtane.Modules.Controls
|
||||
{
|
||||
public class LocalizableComponent : ModuleControlBase
|
||||
{
|
||||
[Inject] public IStringLocalizerFactory LocalizerFactory { get; set; }
|
||||
|
||||
private IStringLocalizer _localizer;
|
||||
|
||||
[Parameter]
|
||||
|
@ -30,48 +30,32 @@ namespace Oqtane.Modules.Controls
|
|||
var key = $"{ResourceKey}.{propertyName}";
|
||||
var value = Localize(key);
|
||||
|
||||
if (value == key)
|
||||
if (value == key || value == String.Empty)
|
||||
{
|
||||
// Returns default property value (English version) instead of ResourceKey.PropertyName
|
||||
return propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (value == String.Empty)
|
||||
{
|
||||
// Returns default property value (English version)
|
||||
// return default property value if key does not exist in resource file or value is empty
|
||||
return propertyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// return localized value
|
||||
return value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
IsLocalizable = false;
|
||||
|
||||
if (string.IsNullOrEmpty(ResourceType))
|
||||
if (String.IsNullOrEmpty(ResourceType))
|
||||
{
|
||||
ResourceType = ModuleState?.ModuleType;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(ResourceKey) && !string.IsNullOrEmpty(ResourceType))
|
||||
if (!String.IsNullOrEmpty(ResourceKey) && !String.IsNullOrEmpty(ResourceType))
|
||||
{
|
||||
var moduleType = Type.GetType(ResourceType);
|
||||
if (moduleType != null)
|
||||
{
|
||||
using (var scope = ServiceActivator.GetScope())
|
||||
{
|
||||
var localizerFactory = scope.ServiceProvider.GetService<IStringLocalizerFactory>();
|
||||
_localizer = localizerFactory.Create(moduleType);
|
||||
|
||||
_localizer = LocalizerFactory.Create(ResourceType);
|
||||
IsLocalizable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
@namespace Oqtane.Modules.Controls
|
||||
@inherits ModuleControlBase
|
||||
@inject IStringLocalizerFactory LocalizerFactory
|
||||
@typeparam TableItem
|
||||
|
||||
@if (ItemList != null)
|
||||
|
@ -48,7 +49,7 @@
|
|||
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" style="white-space: nowrap;">Page @_page of @_pages</a>
|
||||
<a class="page-link" style="white-space: nowrap;">@Localizer["PageOfPages", _page, _pages]</a>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
|
@ -156,13 +157,14 @@
|
|||
<a class="page-link" @onclick=@(async () => UpdateList(_pages))><span class="oi oi-media-step-forward" title="end" aria-hidden="true"></span></a>
|
||||
</li>
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" style="white-space: nowrap;">Page @_page of @_pages</a>
|
||||
<a class="page-link" style="white-space: nowrap;">@Localizer["PageOfPages", _page, _pages]</a>
|
||||
</li>
|
||||
</ul>
|
||||
}
|
||||
}
|
||||
|
||||
@code {
|
||||
private IStringLocalizer Localizer;
|
||||
private int _pages = 0;
|
||||
private int _page = 1;
|
||||
private int _maxItems = 10;
|
||||
|
@ -215,6 +217,11 @@
|
|||
|
||||
private IEnumerable<TableItem> ItemList { get; set; }
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
Localizer = LocalizerFactory.Create(GetType().FullName);
|
||||
}
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (string.IsNullOrEmpty(Format))
|
||||
|
|
|
@ -127,11 +127,10 @@
|
|||
_permissionnames = PermissionNames;
|
||||
}
|
||||
|
||||
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId);
|
||||
_roles.Insert(0, new Role { Name = RoleNames.Everyone });
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
_roles = await RoleService.GetRolesAsync(ModuleState.SiteId, true);
|
||||
if (!UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
_roles.Add(new Role { Name = RoleNames.Host });
|
||||
_roles.RemoveAll(item => item.Name == RoleNames.Host);
|
||||
}
|
||||
|
||||
_permissions = new List<PermissionString>();
|
||||
|
@ -254,6 +253,7 @@
|
|||
permission = _permissions[i];
|
||||
List<string> ids = permission.Permissions.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
ids.Remove("!" + RoleNames.Everyone); // remove deny all users
|
||||
ids.Remove("!" + RoleNames.Unauthenticated); // remove deny unauthenticated
|
||||
ids.Remove("!" + RoleNames.Registered); // remove deny registered users
|
||||
if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
|
|
|
@ -150,10 +150,6 @@
|
|||
// preserve a copy of the rich text content (Quill sanitizes content so we need to retrieve it from the editor)
|
||||
_originalrichhtml = await interop.GetHtml(_editorElement);
|
||||
}
|
||||
else
|
||||
{
|
||||
await interop.LoadEditorContent(_editorElement, _richhtml);
|
||||
}
|
||||
}
|
||||
|
||||
public void CloseFileManager()
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<OutputType>Exe</OutputType>
|
||||
<RazorLangVersion>3.0</RazorLangVersion>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -13,7 +13,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -150,4 +150,7 @@
|
|||
<data name="EditModule.Text" xml:space="preserve">
|
||||
<value>Edit</value>
|
||||
</data>
|
||||
<data name="Modules" xml:space="preserve">
|
||||
<value>Modules</value>
|
||||
</data>
|
||||
</root>
|
|
@ -142,7 +142,7 @@
|
|||
<value>Site Settings Saved</value>
|
||||
</data>
|
||||
<data name="Message.Aliases.Taken" xml:space="preserve">
|
||||
<value>The Default Alias Has Not Been Specified Or An Alias Was Specified That Has Already Been Used For Another Site</value>
|
||||
<value>An Alias Was Specified That Has Already Been Used For Another Site</value>
|
||||
</data>
|
||||
<data name="Message.Required.SiteName" xml:space="preserve">
|
||||
<value>You Must Provide A Site Name, Alias, And Default Theme/Container</value>
|
||||
|
@ -324,4 +324,13 @@
|
|||
<data name="Aliases.Heading" xml:space="preserve">
|
||||
<value>Aliases</value>
|
||||
</data>
|
||||
<data name="AliasName" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="AliasDefault" xml:space="preserve">
|
||||
<value>Default?</value>
|
||||
</data>
|
||||
<data name="Confirm.Alias.Delete" xml:space="preserve">
|
||||
<value>Are You Sure You Wish To Delete {0}?</value>
|
||||
</data>
|
||||
</root>
|
|
@ -219,4 +219,10 @@
|
|||
<data name="DeleteAllNotifications.Text" xml:space="preserve">
|
||||
<value>Delete ALL Notifications</value>
|
||||
</data>
|
||||
<data name="Notifications.Heading" xml:space="preserve">
|
||||
<value>Notifications</value>
|
||||
</data>
|
||||
<data name="Profile.Heading" xml:space="preserve">
|
||||
<value>Profile</value>
|
||||
</data>
|
||||
</root>
|
|
@ -141,4 +141,7 @@
|
|||
<data name="Success.File.Upload" xml:space="preserve">
|
||||
<value>File Upload Succeeded</value>
|
||||
</data>
|
||||
<data name="Message.File.Restricted" xml:space="preserve">
|
||||
<value>Files With Extension Of {0} Are Restricted From Upload. Please Contact Your Administrator For More Information.</value>
|
||||
</data>
|
||||
</root>
|
123
Oqtane.Client/Resources/Modules/Controls/Pager.resx
Normal file
123
Oqtane.Client/Resources/Modules/Controls/Pager.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<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:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="PageOfPages" xml:space="preserve">
|
||||
<value>Page {0} of {1}</value>
|
||||
</data>
|
||||
</root>
|
|
@ -327,4 +327,13 @@
|
|||
<data name="ShowPassword" xml:space="preserve">
|
||||
<value>Show</value>
|
||||
</data>
|
||||
<data name="PageOfPages" xml:space="preserve">
|
||||
<value>Page {0} of {1}</value>
|
||||
</data>
|
||||
<data name="Url Mappings" xml:space="preserve">
|
||||
<value>Url Mappings</value>
|
||||
</data>
|
||||
<data name="Visitor Management" xml:space="preserve">
|
||||
<value>Visitor Management</value>
|
||||
</data>
|
||||
</root>
|
|
@ -9,15 +9,19 @@
|
|||
if (childPage.PageId == PageState.Page.PageId)
|
||||
{
|
||||
<a class="nav-link active px-3" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="visually-hidden-focusable">(current)</span>
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a class="nav-link px-3" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +38,10 @@ else
|
|||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="visually-hidden-focusable">(current)</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
@ -43,8 +49,10 @@ else
|
|||
{
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
|
|
@ -9,8 +9,10 @@
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link active" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="visually-hidden-focusable">(current)</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
@ -18,8 +20,10 @@
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
@ -38,8 +42,10 @@ else
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link active" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name <span class="visually-hidden-focusable">(current)</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
@ -47,8 +53,10 @@ else
|
|||
{
|
||||
<li class="nav-item px-3" style="margin-left: @(childPage.Level * 15)px;">
|
||||
<a class="nav-link" href="@GetUrl(childPage)" target="@GetTarget(childPage)">
|
||||
<span class="w-100" data-bs-toggle="collapse" data-bs-target=".navbar-collapse.show">
|
||||
<span class="@childPage.Icon" aria-hidden="true" />
|
||||
@childPage.Name
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.MySQL</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane MySQL Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.PostgreSQL</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane PostgreSQL Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.SqlServer</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane SQL Server Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -10,7 +10,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Database.Sqlite</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane SQLite Provider</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -11,8 +11,8 @@
|
|||
<copyright>.NET Foundation</copyright>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.1.2/Oqtane.Framework.3.1.2.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v3.1.3/Oqtane.Framework.3.1.2.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane framework</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>Oqtane.Updater</id>
|
||||
<version>3.1.2</version>
|
||||
<version>3.1.3</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
|
@ -12,7 +12,7 @@
|
|||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</releaseNotes>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
</metadata>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.1.2.Install.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.1.3.Install.zip" -Force
|
|
@ -1 +1 @@
|
|||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.1.2.Upgrade.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net6.0\publish\*" -DestinationPath "Oqtane.Framework.3.1.3.Upgrade.zip" -Force
|
|
@ -255,7 +255,7 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "File Could Not Be Downloaded From Url {Url} {Error}", url, ex.Message);
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, ex, "File Could Not Be Downloaded From Url {Url} {Error}", url, ex.Message);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -276,9 +276,17 @@ namespace Oqtane.Controllers
|
|||
return;
|
||||
}
|
||||
|
||||
if (!formfile.FileName.IsPathOrFileValid())
|
||||
// ensure filename is valid
|
||||
string token = ".part_";
|
||||
if (!formfile.FileName.IsPathOrFileValid() || !formfile.FileName.Contains(token))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// check for allowable file extensions (ignore token)
|
||||
var extension = Path.GetExtension(formfile.FileName.Substring(0, formfile.FileName.IndexOf(token))).Replace(".", "");
|
||||
if (!Constants.UploadableFiles.Split(',').Contains(extension.ToLower()))
|
||||
{
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Conflict;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -331,9 +339,9 @@ namespace Oqtane.Controllers
|
|||
{
|
||||
string merged = "";
|
||||
|
||||
// parse the filename which is in the format of filename.ext.part_x_y
|
||||
// parse the filename which is in the format of filename.ext.part_001_999
|
||||
string token = ".part_";
|
||||
string parts = Path.GetExtension(filename)?.Replace(token, ""); // returns "x_y"
|
||||
string parts = Path.GetExtension(filename)?.Replace(token, ""); // returns "001_999"
|
||||
int totalparts = int.Parse(parts?.Substring(parts.IndexOf("_") + 1));
|
||||
|
||||
filename = Path.GetFileNameWithoutExtension(filename); // base filename
|
||||
|
@ -370,13 +378,6 @@ namespace Oqtane.Controllers
|
|||
System.IO.File.Delete(filepart);
|
||||
}
|
||||
|
||||
// check for allowable file extensions
|
||||
if (!Constants.UploadableFiles.Split(',').Contains(Path.GetExtension(filename)?.ToLower().Replace(".", "")))
|
||||
{
|
||||
System.IO.File.Delete(Path.Combine(folder, filename + ".tmp"));
|
||||
}
|
||||
else
|
||||
{
|
||||
// remove file if it already exists
|
||||
if (System.IO.File.Exists(Path.Combine(folder, filename)))
|
||||
{
|
||||
|
@ -386,7 +387,6 @@ namespace Oqtane.Controllers
|
|||
// rename file now that the entire process is completed
|
||||
System.IO.File.Move(Path.Combine(folder, filename + ".tmp"), Path.Combine(folder, filename));
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Create, "File Uploaded {File}", Path.Combine(folder, filename));
|
||||
}
|
||||
|
||||
merged = filename;
|
||||
}
|
||||
|
@ -394,8 +394,7 @@ namespace Oqtane.Controllers
|
|||
|
||||
// clean up file parts which are more than 2 hours old ( which can happen if a prior file upload failed )
|
||||
var cleanupFiles = Directory.EnumerateFiles(folder, "*" + token + "*")
|
||||
.Where(f => Path.GetExtension(f).StartsWith(token));
|
||||
|
||||
.Where(f => Path.GetExtension(f).StartsWith(token) && !Path.GetFileName(f).StartsWith(filename));
|
||||
foreach (var file in cleanupFiles)
|
||||
{
|
||||
var createdDate = System.IO.File.GetCreationTime(file).ToUniversalTime();
|
||||
|
@ -603,7 +602,7 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_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);
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, ex, "Error Creating Image For File {FilePath} {Width} {Height} {Mode} {Rotate} {Error}", filepath, width, height, mode, rotate, ex.Message);
|
||||
imagepath = "";
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,8 @@ namespace Oqtane.Controllers
|
|||
module.CreatedOn = pagemodule.Module.CreatedOn;
|
||||
module.ModifiedBy = pagemodule.Module.ModifiedBy;
|
||||
module.ModifiedOn = pagemodule.Module.ModifiedOn;
|
||||
module.DeletedBy = pagemodule.DeletedBy;
|
||||
module.DeletedOn = pagemodule.DeletedOn;
|
||||
module.IsDeleted = pagemodule.IsDeleted;
|
||||
|
||||
module.PageModuleId = pagemodule.PageModuleId;
|
||||
|
@ -139,24 +141,41 @@ namespace Oqtane.Controllers
|
|||
[Authorize(Roles = RoleNames.Registered)]
|
||||
public Module Put(int id, [FromBody] Module module)
|
||||
{
|
||||
if (ModelState.IsValid && module.SiteId == _alias.SiteId && _modules.GetModule(module.ModuleId, false) != null && _userPermissions.IsAuthorized(User, EntityNames.Module, module.ModuleId, PermissionNames.Edit))
|
||||
var _module = _modules.GetModule(module.ModuleId, false);
|
||||
|
||||
if (ModelState.IsValid && module.SiteId == _alias.SiteId && _module != null && _userPermissions.IsAuthorized(User, EntityNames.Module, module.ModuleId, PermissionNames.Edit))
|
||||
{
|
||||
module = _modules.UpdateModule(module);
|
||||
|
||||
if (_module.AllPages != module.AllPages)
|
||||
{
|
||||
var pageModules = _pageModules.GetPageModules(module.SiteId).ToList();
|
||||
if (module.AllPages)
|
||||
{
|
||||
var pageModule = _pageModules.GetPageModules(module.SiteId).FirstOrDefault(item => item.ModuleId == module.ModuleId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Updated {Module}", module);
|
||||
|
||||
var pageModule = _pageModules.GetPageModule(module.PageModuleId);
|
||||
var pages = _pages.GetPages(module.SiteId).ToList();
|
||||
foreach (Page page in pages)
|
||||
{
|
||||
if (page.PageId != pageModule.PageId && !page.Path.StartsWith("admin/"))
|
||||
if (!pageModules.Exists(item => item.ModuleId == module.ModuleId && item.PageId == page.PageId) && !page.Path.StartsWith("admin/"))
|
||||
{
|
||||
_pageModules.AddPageModule(new PageModule { PageId = page.PageId, ModuleId = pageModule.ModuleId, Title = pageModule.Title, Pane = pageModule.Pane, Order = pageModule.Order, ContainerType = pageModule.ContainerType });
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var pageModule in pageModules)
|
||||
{
|
||||
if (pageModule.ModuleId == module.ModuleId && pageModule.PageModuleId != module.PageModuleId)
|
||||
{
|
||||
_pageModules.DeletePageModule(pageModule.PageModuleId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Site, _alias.SiteId);
|
||||
_logger.Log(LogLevel.Information, this, LogFunction.Update, "Module Updated {Module}", module);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -53,7 +53,7 @@ namespace Oqtane.Controllers
|
|||
catch (Exception ex)
|
||||
{
|
||||
results.Add(new Dictionary<string, string>() { { "Error", ex.Message } });
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Other, "Sql Query {Query} Executed on Tenant {TenantId} Resulted In An Error {Error}", sqlquery.Query, sqlquery.TenantId, ex.Message);
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Other, ex, "Sql Query {Query} Executed on Tenant {TenantId} Resulted In An Error {Error}", sqlquery.Query, sqlquery.TenantId, ex.Message);
|
||||
}
|
||||
sqlquery.Results = results;
|
||||
return sqlquery;
|
||||
|
|
|
@ -39,23 +39,22 @@ namespace Oqtane.Controllers
|
|||
public IEnumerable<UserRole> Get(string siteid, string userid = null, string rolename = null)
|
||||
{
|
||||
int SiteId;
|
||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId)
|
||||
{
|
||||
int UserId = (int.TryParse(userid, out UserId)) ? UserId : -1;
|
||||
if (User.IsInRole(RoleNames.Admin) || ((userid == null || _userPermissions.GetUser().UserId == UserId) && (rolename == null || (User.IsInRole(rolename) && rolename != RoleNames.Registered))))
|
||||
if (int.TryParse(siteid, out SiteId) && SiteId == _alias.SiteId && (userid != null || rolename != null))
|
||||
{
|
||||
var userroles = _userRoles.GetUserRoles(SiteId).ToList();
|
||||
if (userid != null)
|
||||
{
|
||||
int UserId = int.TryParse(userid, out UserId) ? UserId : -1;
|
||||
userroles = userroles.Where(item => item.UserId == UserId).ToList();
|
||||
}
|
||||
if (rolename != null)
|
||||
{
|
||||
userroles = userroles.Where(item => item.Role.Name == rolename).ToList();
|
||||
}
|
||||
var user = _userPermissions.GetUser();
|
||||
for (int i = 0; i < userroles.Count(); i++)
|
||||
{
|
||||
userroles[i] = Filter(userroles[i]);
|
||||
userroles[i] = Filter(userroles[i], user.UserId);
|
||||
}
|
||||
return userroles.OrderBy(u => u.User.DisplayName);
|
||||
}
|
||||
|
@ -66,13 +65,6 @@ namespace Oqtane.Controllers
|
|||
return null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized UserRole Get Attempt For Site {SiteId} User {UserId} Role {RoleName}", siteid, userid, rolename);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// GET api/<controller>/5
|
||||
[HttpGet("{id}")]
|
||||
|
@ -82,16 +74,7 @@ namespace Oqtane.Controllers
|
|||
var userrole = _userRoles.GetUserRole(id);
|
||||
if (userrole != null && SiteValid(userrole.Role.SiteId))
|
||||
{
|
||||
if (User.IsInRole(RoleNames.Admin) || User.Identity.Name?.ToLower() != userrole.User.Username.ToLower() || User.IsInRole(userrole.Role.Name))
|
||||
{
|
||||
return Filter(userrole);
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Security, "Unauthorized User Role Get Attempt {UserRoleId}", id);
|
||||
HttpContext.Response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||
return null;
|
||||
}
|
||||
return Filter(userrole, _userPermissions.GetUser().UserId);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -101,7 +84,7 @@ namespace Oqtane.Controllers
|
|||
}
|
||||
}
|
||||
|
||||
private UserRole Filter(UserRole userrole)
|
||||
private UserRole Filter(UserRole userrole, int userid)
|
||||
{
|
||||
if (userrole != null)
|
||||
{
|
||||
|
@ -110,7 +93,7 @@ namespace Oqtane.Controllers
|
|||
userrole.User.TwoFactorCode = "";
|
||||
userrole.User.TwoFactorExpiry = null;
|
||||
|
||||
if (!User.IsInRole(RoleNames.Admin) && User.Identity.Name?.ToLower() != userrole.User.Username.ToLower())
|
||||
if (!User.IsInRole(RoleNames.Admin) && userid != userrole.User.UserId)
|
||||
{
|
||||
userrole.User.Email = "";
|
||||
userrole.User.PhotoFileId = null;
|
||||
|
|
|
@ -187,7 +187,7 @@ namespace Oqtane.Extensions
|
|||
catch (Exception ex)
|
||||
{
|
||||
var _logger = context.HttpContext.RequestServices.GetRequiredService<ILogManager>();
|
||||
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, "An Error Occurred Accessing The User Info Endpoint - {Error}", ex.Message);
|
||||
_logger.Log(LogLevel.Error, "ExternalLogin", Enums.LogFunction.Security, ex, "An Error Occurred Accessing The User Info Endpoint - {Error}", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,10 @@ namespace Oqtane.Infrastructure
|
|||
mailMessage.Body += "Subject: " + notification.Subject + "\n\n";
|
||||
mailMessage.Body += notification.Body;
|
||||
|
||||
// set encoding
|
||||
mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
|
||||
mailMessage.BodyEncoding = System.Text.Encoding.UTF8;
|
||||
|
||||
// send mail
|
||||
try
|
||||
{
|
||||
|
|
|
@ -203,12 +203,15 @@ namespace Oqtane.Infrastructure
|
|||
}
|
||||
if (Enum.Parse<LogLevel>(log.Level) >= notifylevel)
|
||||
{
|
||||
var alias = _tenantManager.GetAlias();
|
||||
foreach (var userrole in _userRoles.GetUserRoles(log.SiteId.Value))
|
||||
{
|
||||
if (userrole.Role.Name == RoleNames.Host)
|
||||
{
|
||||
var url = _accessor.HttpContext.Request.Scheme + "://" + _tenantManager.GetAlias().Name + "/admin/log";
|
||||
var notification = new Notification(log.SiteId.Value, userrole.User, "Site " + log.Level + " Notification", "Please visit " + url + " for more information");
|
||||
var subject = $"{alias.Name} Site {log.Level} Notification";
|
||||
var url = $"{_accessor.HttpContext.Request.Scheme}://{alias.Name}/admin/log?id={log.LogId}";
|
||||
string body = $"Log Message: {log.Message}\n\nPlease visit {url} for more information";
|
||||
var notification = new Notification(log.SiteId.Value, userrole.User, subject, body);
|
||||
_notifications.AddNotification(notification);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,9 @@ namespace Oqtane.Infrastructure
|
|||
case "3.0.1":
|
||||
Upgrade_3_0_1(tenant, scope);
|
||||
break;
|
||||
case "3.1.3":
|
||||
Upgrade_3_1_3(tenant, scope);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -182,5 +185,15 @@ namespace Oqtane.Infrastructure
|
|||
sites.CreatePages(site, pageTemplates);
|
||||
}
|
||||
}
|
||||
|
||||
private void Upgrade_3_1_3(Tenant tenant, IServiceScope scope)
|
||||
{
|
||||
var roles = scope.ServiceProvider.GetRequiredService<IRoleRepository>();
|
||||
if (!roles.GetRoles(-1, true).ToList().Where(item => item.Name == RoleNames.Unauthenticated).Any())
|
||||
{
|
||||
roles.AddRole(new Role { SiteId = null, Name = RoleNames.Unauthenticated, Description = RoleNames.Unauthenticated, IsAutoAssigned = false, IsSystem = true });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Oqtane.Migrations.EntityBuilders
|
|||
_migrationBuilder = migrationBuilder;
|
||||
ActiveDatabase = database;
|
||||
ForeignKeys = new List<ForeignKey<TEntityBuilder>>();
|
||||
Schema = null;
|
||||
}
|
||||
|
||||
protected IDatabase ActiveDatabase { get; }
|
||||
|
@ -30,6 +31,8 @@ namespace Oqtane.Migrations.EntityBuilders
|
|||
|
||||
protected List<ForeignKey<TEntityBuilder>> ForeignKeys { get; }
|
||||
|
||||
protected string Schema { get; init; }
|
||||
|
||||
private string RewriteName(string name)
|
||||
{
|
||||
return ActiveDatabase.RewriteName(name);
|
||||
|
@ -319,7 +322,7 @@ namespace Oqtane.Migrations.EntityBuilders
|
|||
/// </summary>
|
||||
public void Create()
|
||||
{
|
||||
_migrationBuilder.CreateTable(RewriteName(EntityTableName), BuildTable, null, AddKeys);
|
||||
_migrationBuilder.CreateTable(RewriteName(EntityTableName), BuildTable, Schema, AddKeys);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -94,16 +94,18 @@ namespace Oqtane.Repository
|
|||
List<Role> roles = _roleRepository.GetRoles(site.SiteId, true).ToList();
|
||||
if (!roles.Where(item => item.Name == RoleNames.Everyone).Any())
|
||||
{
|
||||
_roleRepository.AddRole(new Role {SiteId = null, Name = RoleNames.Everyone, Description = "All Users", IsAutoAssigned = false, IsSystem = true});
|
||||
_roleRepository.AddRole(new Role {SiteId = null, Name = RoleNames.Everyone, Description = RoleNames.Everyone, IsAutoAssigned = false, IsSystem = true});
|
||||
}
|
||||
if (!roles.Where(item => item.Name == RoleNames.Unauthenticated).Any())
|
||||
{
|
||||
_roleRepository.AddRole(new Role { SiteId = null, Name = RoleNames.Unauthenticated, Description = RoleNames.Unauthenticated, IsAutoAssigned = false, IsSystem = true });
|
||||
}
|
||||
|
||||
if (!roles.Where(item => item.Name == RoleNames.Host).Any())
|
||||
{
|
||||
_roleRepository.AddRole(new Role {SiteId = null, Name = RoleNames.Host, Description = "Application Administrators", IsAutoAssigned = false, IsSystem = true});
|
||||
_roleRepository.AddRole(new Role {SiteId = null, Name = RoleNames.Host, Description = RoleNames.Host, IsAutoAssigned = false, IsSystem = true});
|
||||
}
|
||||
|
||||
_roleRepository.AddRole(new Role {SiteId = site.SiteId, Name = RoleNames.Registered, Description = "Registered Users", IsAutoAssigned = true, IsSystem = true});
|
||||
_roleRepository.AddRole(new Role {SiteId = site.SiteId, Name = RoleNames.Admin, Description = "Site Administrators", IsAutoAssigned = false, IsSystem = true});
|
||||
_roleRepository.AddRole(new Role {SiteId = site.SiteId, Name = RoleNames.Registered, Description = RoleNames.Registered, IsAutoAssigned = true, IsSystem = true});
|
||||
_roleRepository.AddRole(new Role {SiteId = site.SiteId, Name = RoleNames.Admin, Description = RoleNames.Admin, IsAutoAssigned = false, IsSystem = true});
|
||||
|
||||
_profileRepository.AddProfile(new Profile
|
||||
{SiteId = site.SiteId, Name = "FirstName", Title = "First Name", Description = "Your First Or Given Name", Category = "Name", ViewOrder = 1, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = ""});
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -344,10 +344,17 @@ Oqtane.Interop = {
|
|||
progressinfo.innerHTML = file.name + ' 100%';
|
||||
progressbar.value = 1;
|
||||
};
|
||||
request.upload.onerror = function () {
|
||||
progressinfo.innerHTML = file.name + ' Error: ' + xhr.status;
|
||||
progressbar.value = 0;
|
||||
};
|
||||
request.send(data);
|
||||
}
|
||||
}
|
||||
|
||||
if (i === files.length - 1) {
|
||||
fileinput.value = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
refreshBrowser: function (reload, wait) {
|
||||
setInterval(function () {
|
||||
|
|
|
@ -60,6 +60,7 @@ namespace Oqtane.Models
|
|||
public Dictionary<string, string> Settings { get; set; }
|
||||
|
||||
#region PageModule properties
|
||||
|
||||
[NotMapped]
|
||||
public int PageModuleId { get; set; }
|
||||
|
||||
|
@ -68,6 +69,7 @@ namespace Oqtane.Models
|
|||
/// </summary>
|
||||
[NotMapped]
|
||||
public int PageId { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string Title { get; set; }
|
||||
|
||||
|
@ -76,8 +78,10 @@ namespace Oqtane.Models
|
|||
/// </summary>
|
||||
[NotMapped]
|
||||
public string Pane { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public int Order { get; set; }
|
||||
|
||||
[NotMapped]
|
||||
public string ContainerType { get; set; }
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -104,11 +104,14 @@ namespace Oqtane.Security
|
|||
|
||||
private static bool IsAllowed(int userId, string roles, string permission)
|
||||
{
|
||||
if (permission == RoleNames.Unauthenticated)
|
||||
{
|
||||
return userId == -1;
|
||||
}
|
||||
if ("[" + userId + "]" == permission)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (roles != null)
|
||||
{
|
||||
return roles.IndexOf(";" + permission + ";") != -1;
|
||||
|
|
|
@ -4,8 +4,8 @@ namespace Oqtane.Shared
|
|||
{
|
||||
public class Constants
|
||||
{
|
||||
public static readonly string Version = "3.1.2";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2";
|
||||
public static readonly string Version = "3.1.3";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3";
|
||||
public const string PackageId = "Oqtane.Framework";
|
||||
public const string UpdaterPackageId = "Oqtane.Updater";
|
||||
public const string PackageRegistryUrl = "https://www.oqtane.net";
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
namespace Oqtane.Shared {
|
||||
namespace Oqtane.Shared {
|
||||
public class RoleNames {
|
||||
public const string Everyone = "All Users";
|
||||
public const string Host = "Host Users";
|
||||
public const string Admin = "Administrators";
|
||||
public const string Registered = "Registered Users";
|
||||
public const string Unauthenticated = "Unauthenticated Users";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>3.1.2</Version>
|
||||
<Version>3.1.3</Version>
|
||||
<Product>Oqtane</Product>
|
||||
<Authors>Shaun Walker</Authors>
|
||||
<Company>.NET Foundation</Company>
|
||||
|
@ -11,7 +11,7 @@
|
|||
<Copyright>.NET Foundation</Copyright>
|
||||
<PackageProjectUrl>https://www.oqtane.org</PackageProjectUrl>
|
||||
<PackageLicenseUrl>https://github.com/oqtane/oqtane.framework/blob/dev/LICENSE</PackageLicenseUrl>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v3.1.3</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
|
10
README.md
10
README.md
|
@ -57,8 +57,14 @@ There is a separate [Documentation repository](https://github.com/oqtane/oqtane.
|
|||
# Roadmap
|
||||
This project is open source, and therefore is a work in progress...
|
||||
|
||||
Backlog (Not Yet Assigned)
|
||||
- [ ] Allow language specification in Url (#1731)
|
||||
V.4.0.0 ( Q4 2022 )
|
||||
- [ ] MAUI / Blazor Hybrid support
|
||||
|
||||
V.3.1.3 ( June 2022 )
|
||||
- [ ] Stabilization improvements
|
||||
|
||||
V.3.1.2 ( May 14, 2022 )
|
||||
- [x] Stabilization improvements
|
||||
|
||||
V.3.1.1 ( May 3, 2022 )
|
||||
- [x] Stabilization improvements
|
||||
|
|
Loading…
Reference in New Issue
Block a user