Merge remote-tracking branch 'upstream/dev' into dev

This commit is contained in:
Leigh Pointer
2025-10-03 18:33:52 +02:00
33 changed files with 2847 additions and 112 deletions

17
Directory.Build.props Normal file
View File

@@ -0,0 +1,17 @@
<Project>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Version>6.2.1</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
<Description>CMS and Application Framework for Blazor and .NET MAUI</Description>
<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/v6.2.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
</PropertyGroup>
</Project>

View File

@@ -329,6 +329,15 @@ else
</select>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="singlelogout" HelpText="Specify if users should be logged out of both the application and provider (the default is false indicating they will only be logged out of the application)" ResourceKey="SingleLogout">Use Single Logout?</Label>
<div class="col-sm-9">
<select id="singlelogout" class="form-select" @bind="@_singlelogout" required>
<option value="true">@SharedLocalizer["Yes"]</option>
<option value="false">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="scopes" HelpText="A list of Scopes to request from the provider (separated by commas). If none are specified, standard Scopes will be used by default." ResourceKey="Scopes">Scopes:</Label>
@@ -560,6 +569,7 @@ else
private string _toggleclientsecret = string.Empty;
private string _authresponsetype;
private string _requirenonce;
private string _singlelogout;
private string _scopes;
private string _parameters;
private string _pkce;
@@ -648,6 +658,7 @@ else
_toggleclientsecret = SharedLocalizer["ShowPassword"];
_authresponsetype = SettingService.GetSetting(settings, "ExternalLogin:AuthResponseType", "code");
_requirenonce = SettingService.GetSetting(settings, "ExternalLogin:RequireNonce", "true");
_singlelogout = SettingService.GetSetting(settings, "ExternalLogin:SingleLogout", "false");
_scopes = SettingService.GetSetting(settings, "ExternalLogin:Scopes", "");
_parameters = SettingService.GetSetting(settings, "ExternalLogin:Parameters", "");
_pkce = SettingService.GetSetting(settings, "ExternalLogin:PKCE", "false");
@@ -771,6 +782,7 @@ else
settings = SettingService.SetSetting(settings, "ExternalLogin:ClientSecret", _clientsecret, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:AuthResponseType", _authresponsetype, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:RequireNonce", _requirenonce, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:SingleLogout", _singlelogout, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:Scopes", _scopes, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:Parameters", _parameters, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:PKCE", _pkce, true);

View File

@@ -1,19 +1,23 @@
@namespace Oqtane.Modules.Controls
@using System.IO
@using Radzen
@using Radzen.Blazor
@inject DialogService DialogService
@inject IStringLocalizer<Oqtane.Modules.Controls.RadzenTextEditor> Localizer
<div class="d-flex">
@if (!string.IsNullOrEmpty(_message))
{
<div class="rz-html-editor-dialog-item">
<div class="alert alert-warning alert-dismissible fade show mb-3" role="alert">
@((MarkupString)_message)
</div>
</div>
}
<div class="rz-html-editor-dialog-item">
<FileManager @ref="_fileManager" Filter="@Filters" />
</div>
<div class="d-flex">
<ModuleMessage Message="@_message" Type="MessageType.Warning"></ModuleMessage>
</div>
<div class="mt-1 text-end">
<RadzenButton Text="OK" Click=@OnOkClick />
<RadzenButton Text="Cancel" Click=@OnCancelClick ButtonStyle="ButtonStyle.Secondary" />
<div class="rz-html-editor-dialog-buttons">
<RadzenButton Text="@Localizer["InsertImage"]" Click="InsertImage" />
<RadzenButton Text="@Localizer["Cancel"]" Click="() => DialogService.Close()" ButtonStyle="ButtonStyle.Secondary" />
</div>
@code {
private FileManager _fileManager;
@@ -22,12 +26,7 @@
[Parameter]
public string Filters { get; set; }
private void OnCancelClick()
{
DialogService.Close(null);
}
private void OnOkClick()
private void InsertImage()
{
_message = string.Empty;
var file = _fileManager.GetFile();

View File

@@ -0,0 +1,148 @@
@namespace Oqtane.Modules.Controls
@using Radzen
@using Radzen.Blazor
@using System.Text
@inject DialogService DialogService
@inject IStringLocalizer<Oqtane.Modules.Controls.RadzenTextEditor> Localizer
@if (_linkAttributes != null)
{
@if (!string.IsNullOrWhiteSpace(_message))
{
<div class="rz-html-editor-dialog-item">
<div class="alert alert-warning alert-dismissible fade show mb-3" role="alert">
@((MarkupString)_message)
</div>
</div>
}
<div class="rz-html-editor-dialog-item">
<RadzenDropDown TValue="int" class="form-control" PopupStyle="color: var(--rz-input-value-color);" @bind-Value="_linkType" Data="_linkTypes" TextProperty="Value" ValueProperty="Key" />
</div>
@if (_linkType == 0)
{
<div class="rz-html-editor-dialog-item">
<RadzenTextBox class="form-control" @bind-Value="@_linkAttributes.Href" Placeholder="@Localizer["WebAddress"]" />
</div>
}
else
{
<div class="rz-html-editor-dialog-item">
<FileManager @ref="_fileManager" OnSelectFile="SelectFile" OnSelectFolder="SelectFile" />
</div>
}
@if (_linkTextEditable)
{
<div class="rz-html-editor-dialog-item">
<RadzenTextBox class="form-control" @bind-Value="@_linkAttributes.InnerText" Placeholder="@Localizer["LinkText"]" />
</div>
}
<div class="rz-html-editor-dialog-item">
<RadzenDropDown TValue="bool" class="form-control" PopupStyle="color: var(--rz-input-value-color);" @bind-Value="_blank" Data="_linkTargets" TextProperty="Value" ValueProperty="Key" />
</div>
}
<div class="rz-html-editor-dialog-buttons">
<RadzenButton Text=@Localizer["InsertLink"] Click="InsertLink" />
<RadzenButton Text=@Localizer["Cancel"] Click="() => DialogService.Close()" ButtonStyle="ButtonStyle.Secondary" />
</div>
@code {
class LinkAttributes
{
public string InnerText { get; set; }
public string InnerHtml { get; set; }
public string Href { get; set; }
public string Target { get; set; }
}
[Parameter]
public RadzenHtmlEditor Editor { get; set; }
private IDictionary<int, string> _linkTypes;
private IDictionary<bool, string> _linkTargets;
private LinkAttributes _linkAttributes;
private bool _blank;
private int _linkType;
private string _message;
private bool _linkTextEditable;
private FileManager _fileManager;
private File _previousFile;
protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
_linkAttributes = await Editor.GetSelectionAttributes<LinkAttributes>("a", new[] { "innerText", "href", "target" });
if (_linkAttributes.Target == "_blank")
{
_blank = true;
}
_linkTextEditable = string.IsNullOrWhiteSpace(_linkAttributes.InnerHtml) || _linkAttributes.InnerHtml == "<br>";
_linkTypes = new Dictionary<int, string>
{
{ 0, Localizer["WebLink"] },
{ 1, Localizer["FileLink"] }
};
_linkTargets = new Dictionary<bool, string>
{
{ false, Localizer["OpenInCurrentWindow"] },
{ true, Localizer["OpenInNewWindow"] }
};
}
private void SelectFile()
{
var file = _fileManager.GetFile();
if(file != null)
{
_linkAttributes.Href = file.Url;
if ((string.IsNullOrWhiteSpace(_linkAttributes.InnerText) || _linkAttributes.InnerText == _previousFile?.Name) && _linkTextEditable)
{
_linkAttributes.InnerText = file.Name;
}
}
else
{
_linkAttributes.Href = string.Empty;
if (_linkAttributes.InnerText == _previousFile?.Name)
{
_linkAttributes.InnerText = string.Empty;
}
}
_previousFile = file;
StateHasChanged();
}
private void InsertLink()
{
_message = string.Empty;
if (string.IsNullOrWhiteSpace(_linkAttributes.Href))
{
_message = _linkType == 1 ? Localizer["Message.Require.File"] : Localizer["Message.Require.WebAddress"];
}
else if (string.IsNullOrWhiteSpace(_linkAttributes.InnerText) && _linkTextEditable)
{
_message = Localizer["Message.Require.LinkText"];
}
if (string.IsNullOrWhiteSpace(_message))
{
var html = new StringBuilder();
html.AppendFormat("<a href=\"{0}\"", _linkAttributes.Href);
if (_blank)
{
html.Append(" target=\"_blank\"");
}
html.AppendFormat(">{0}</a>", string.IsNullOrWhiteSpace(_linkAttributes.InnerText) ? _linkAttributes.InnerHtml : _linkAttributes.InnerText);
DialogService.Close(html.ToString());
}
else
{
StateHasChanged();
}
}
}

View File

@@ -147,13 +147,17 @@
private async Task OnExecute(HtmlEditorExecuteEventArgs args)
{
if (args.CommandName == "InsertImage")
switch(args.CommandName)
{
await InsertImage(args.Editor);
}
else if (args.CommandName == "Settings")
{
await UpdateSettings(args.Editor);
case "InsertImage":
await InsertImage(args.Editor);
break;
case "InsertLink":
await InsertLink(args.Editor);
break;
case "Settings":
await UpdateSettings(args.Editor);
break;
}
}
@@ -164,7 +168,24 @@
var result = await DialogService.OpenAsync<RadzenFileManagerDialog>(Localizer["DialogTitle.SelectImage"], new Dictionary<string, object>
{
{ "Filters", PageState.Site.ImageFiles }
});
}, new DialogOptions { CssClass = "rz-text-editor-dialog" });
await editor.RestoreSelectionAsync();
if (result != null)
{
await editor.ExecuteCommandAsync(HtmlEditorCommands.InsertHtml, result);
}
}
private async Task InsertLink(RadzenHtmlEditor editor)
{
await editor.SaveSelectionAsync();
var result = await DialogService.OpenAsync<RadzenInsertLinkDialog>(Localizer["DialogTitle.InsertLink"], new Dictionary<string, object>
{
{ "Editor", editor }
}, new DialogOptions { CssClass = "rz-text-editor-dialog" });
await editor.RestoreSelectionAsync();

View File

@@ -33,7 +33,7 @@ namespace Oqtane.Modules.Controls
{ "InsertImage", (builder, sequence) => CreateFragment(builder, sequence, "InsertImage", "RadzenHtmlEditorCustomTool", "InsertImage", "image") },
{ "Italic", (builder, sequence) => CreateFragment(builder, sequence, "Italic", "RadzenHtmlEditorItalic") },
{ "Justify", (builder, sequence) => CreateFragment(builder, sequence, "Justify", "RadzenHtmlEditorJustify") },
{ "Link", (builder, sequence) => CreateFragment(builder, sequence, "Link", "RadzenHtmlEditorLink") },
{ "Link", (builder, sequence) => CreateFragment(builder, sequence, "InsertLink", "RadzenHtmlEditorCustomTool", "InsertLink", "insert_link") },
{ "OrderedList", (builder, sequence) => CreateFragment(builder, sequence, "OrderedList", "RadzenHtmlEditorOrderedList") },
{ "Outdent", (builder, sequence) => CreateFragment(builder, sequence, "Outdent", "RadzenHtmlEditorOutdent") },
{ "Redo", (builder, sequence) => CreateFragment(builder, sequence, "Redo", "RadzenHtmlEditorRedo") },

View File

@@ -1,22 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<OutputType>Exe</OutputType>
<Configurations>Debug;Release</Configurations>
<Version>6.2.1</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
<Description>CMS and Application Framework for Blazor and .NET MAUI</Description>
<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/v6.2.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
<IsPackable>true</IsPackable>
<BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
</PropertyGroup>
@@ -26,7 +12,7 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.9" />
<PackageReference Include="Radzen.Blazor" Version="7.3.5" />
<PackageReference Include="Radzen.Blazor" Version="7.4.3" />
</ItemGroup>
<ItemGroup>

View File

@@ -181,9 +181,9 @@
<value>View License</value>
</data>
<data name="Theme.Heading" xml:space="preserve">
<value>Themex</value>
<value>Theme</value>
</data>
<data name="Permissions.Heading" xml:space="preserve">
<value>Permissionsx</value>
<value>Permissions</value>
</data>
</root>

View File

@@ -555,4 +555,10 @@
<data name="CookieDomain.HelpText" xml:space="preserve">
<value>If you would like to share cookies across subdomains you will need to specify a root domain with a leading dot (ie. '.example.com')</value>
</data>
<data name="SingleLogout.Text" xml:space="preserve">
<value>Allow Single Logout?</value>
</data>
<data name="SingleLogout.HelpText" xml:space="preserve">
<value>Specify if users should be logged out of both the application and provider (the default is false indicating they will only be logged out of the application)</value>
</data>
</root>

View File

@@ -216,4 +216,37 @@
<data name="Reset" xml:space="preserve">
<value>Reset</value>
</data>
<data name="InsertLink" xml:space="preserve">
<value>Insert Link</value>
</data>
<data name="DialogTitle.InsertLink" xml:space="preserve">
<value>Insert Link</value>
</data>
<data name="WebAddress" xml:space="preserve">
<value>Enter Web Address</value>
</data>
<data name="LinkText" xml:space="preserve">
<value>Enter Link Text</value>
</data>
<data name="OpenInNewWindow" xml:space="preserve">
<value>Open In New Window</value>
</data>
<data name="WebLink" xml:space="preserve">
<value>Web Link</value>
</data>
<data name="FileLink" xml:space="preserve">
<value>File Link</value>
</data>
<data name="OpenInCurrentWindow" xml:space="preserve">
<value>Open In Current Window</value>
</data>
<data name="Message.Require.WebAddress" xml:space="preserve">
<value>The Web Address is Empty</value>
</data>
<data name="Message.Require.LinkText" xml:space="preserve">
<value>The Link Text is Empty</value>
</data>
<data name="Message.Require.File" xml:space="preserve">
<value>You Must Select a File</value>
</data>
</root>

View File

@@ -6,17 +6,6 @@
<!-- <TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks> -->
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
<OutputType>Exe</OutputType>
<Version>6.2.1</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
<Description>Modular Application Framework for Blazor and MAUI</Description>
<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/v6.2.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane.Maui</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>

View File

@@ -286,3 +286,34 @@ app {
top: 0;
right: 5px;
}
.app-modulemessage-toast {
position: fixed;
width: 350px;
z-index: 1000;
animation: slide-in 0.5s ease-out, slide-out 0.5s ease-in 5s forwards;
}
@keyframes slide-in {
from {
transform: translateX(100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
@keyframes slide-out {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(100%);
opacity: 0;
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
.rz-text-editor {
outline: none !important;
}
.rz-html-editor-dropdown-items,
.rz-popup,
.rz-editor-dialog-wrapper {
z-index: 9999 !important;
}
.rz-html-editor-dropdown-items .rz-html-editor-dropdown-item,
.rz-html-editor-dropdown-items .rz-html-editor-dropdown-item > * {
color: var(--rz-editor-button-color);
}
.rz-text-editor .rz-html-editor-dropdown .rz-html-editor-dropdown-value,
.rz-text-editor .rz-html-editor-dropdown .rz-html-editor-dropdown-trigger,
.rz-text-editor .rz-html-editor-colorpicker .rz-html-editor-color {
color: var(--rz-editor-button-color);
}
.rz-text-editor .rz-colorpicker.rz-state-disabled {
border: none !important;
}
.rz-text-editor-dialog .rz-html-editor-dialog-item select{
border: var(--rz-input-border);
border-block-end: var(--rz-input-border-block-end);
border-radius: var(--rz-input-border-radius);
box-shadow: var(--rz-input-shadow);
background-color: var(--rz-input-background-color);
padding-block: var(--rz-input-padding-block);
padding-inline: var(--rz-input-padding-inline);
font-size: var(--rz-input-font-size);
color: var(--rz-input-value-color);
}
.rz-text-editor-dialog .rz-html-editor-dialog-item select:hover, .rz-text-edit-dialog .rz-html-editor-dialog-item select:active {
box-shadow: var(--rz-input-hover-shadow);
background-color: var(--rz-input-hover-background-color);
border: var(--rz-input-hover-border);
border-block-end: var(--rz-input-hover-border-block-end);
}
.rz-text-editor-dialog .alert form{
display: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,54 @@
var Oqtane = Oqtane || {};
Oqtane.RichTextEditor = {
createQuill: async function (
quillElement, toolBar, readOnly,
placeholder, theme, debugLevel) {
Quill.register('modules/blotFormatter', QuillBlotFormatter.default);
var options = {
debug: debugLevel,
modules: {
toolbar: toolBar,
blotFormatter: {}
},
placeholder: placeholder,
readOnly: readOnly,
theme: theme
};
new Quill(quillElement, options);
},
getQuillContent: function (editorElement) {
return JSON.stringify(editorElement.__quill.getContents());
},
getQuillText: function (editorElement) {
return editorElement.__quill.getText();
},
getQuillHTML: function (editorElement) {
return editorElement.__quill.root.innerHTML;
},
loadQuillContent: function (editorElement, editorContent) {
return editorElement.__quill.root.innerHTML = editorContent;
},
enableQuillEditor: function (editorElement, mode) {
editorElement.__quill.enable(mode);
},
getCurrentCursor: function (quillElement) {
var editorIndex = 0;
if (quillElement.__quill.getSelection() !== null) {
editorIndex = quillElement.__quill.getSelection().index;
}
return editorIndex;
},
insertQuillImage: function (quillElement, imageURL, altText, editorIndex) {
var Delta = Quill.import('delta');
return quillElement.__quill.updateContents(
new Delta()
.retain(editorIndex)
.insert({ image: imageURL },
{ alt: altText }));
}
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,47 @@
var Oqtane = Oqtane || {};
Oqtane.RadzenTextEditor = {
initialize: function (editor) {
if (typeof Radzen.openPopup === "function" && Radzen.openPopup !== Oqtane.RadzenTextEditor.openPopup) {
Oqtane.RadzenTextEditor.radzenOpenPopup = Radzen.openPopup;
Radzen.openPopup = Oqtane.RadzenTextEditor.openPopup;
}
},
openPopup: function () {
Oqtane.RadzenTextEditor.radzenOpenPopup.apply(this, arguments);
var id = arguments[1];
var popup = document.getElementById(id);
if (popup) {
Oqtane.RadzenTextEditor.updateButtonStyles(popup);
}
},
setBackgroundColor: function (editor, color) {
editor.getElementsByClassName("rz-html-editor-content")[0].style.backgroundColor = color;
},
updateDialogLayout: function (editor) {
var dialogs = editor.parentElement.getElementsByClassName('rz-dialog-wrapper');
for (var dialog of dialogs) {
document.body.appendChild(dialog);
dialog.classList.add('rz-editor-dialog-wrapper', 'text-dark');
this.updateButtonStyles(dialog);
}
},
updateButtonStyles: function (parent) {
var primaryBtns = parent.getElementsByClassName('rz-primary');
if (primaryBtns) {
for (var btn of primaryBtns) {
btn.classList.remove('rz-button', 'rz-primary');
btn.classList.add('btn', 'btn-primary');
}
}
var secondaryBtns = parent.getElementsByClassName('rz-secondary');
if (secondaryBtns) {
for (var btn of secondaryBtns) {
btn.classList.remove('rz-button', 'rz-secondary');
btn.classList.add('btn', 'btn-secondary');
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 72 KiB

View File

@@ -1,3 +0,0 @@
nuget.exe pack ..\Oqtane.Application\Oqtane.Application.Template.nuspec -NoDefaultExcludes
pause

View File

@@ -23,7 +23,7 @@
<dependency id="Microsoft.AspNetCore.Components.WebAssembly.Authentication" version="9.0.9" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="9.0.9" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Localization" version="9.0.9" exclude="Build,Analyzers" />
<dependency id="Radzen.Blazor" version="7.3.5" exclude="Build,Analyzers" />
<dependency id="Radzen.Blazor" version="7.4.3" exclude="Build,Analyzers" />
</group>
</dependencies>
</metadata>

View File

@@ -28,8 +28,8 @@
<dependency id="Microsoft.AspNetCore.Authentication.OpenIdConnect" version="9.0.9" exclude="Build,Analyzers" />
<dependency id="SixLabors.ImageSharp" version="3.1.11" exclude="Build,Analyzers" />
<dependency id="HtmlAgilityPack" version="1.12.3" exclude="Build,Analyzers" />
<dependency id="Swashbuckle.AspNetCore" version="9.0.4" exclude="Build,Analyzers" />
<dependency id="MailKit" version="4.13.0" exclude="Build,Analyzers" />
<dependency id="Swashbuckle.AspNetCore" version="9.0.5" exclude="Build,Analyzers" />
<dependency id="MailKit" version="4.14.0" exclude="Build,Analyzers" />
<dependency id="MySql.Data" version="9.4.0" exclude="Build,Analyzers" />
<dependency id="Pomelo.EntityFrameworkCore.MySql" version="9.0.0" exclude="Build,Analyzers" />
<dependency id="EFCore.NamingConventions" version="9.0.0" exclude="Build,Analyzers" />
@@ -55,7 +55,7 @@
<file src="..\Oqtane.Server\obj\Release\net9.0\staticwebassets\msbuild.build.Oqtane.Server.props" target="build\Oqtane.Server.props" />
<file src="..\Oqtane.Server\obj\Release\net9.0\staticwebassets\msbuild.buildMultiTargeting.Oqtane.Server.props" target="buildMultiTargeting\Oqtane.Server.props" />
<file src="..\Oqtane.Server\obj\Release\net9.0\staticwebassets\msbuild.buildTransitive.Oqtane.Server.props" target="buildTransitive\Oqtane.Server.props" />
<file src="..\Oqtane.Server\wwwroot\**\*" target="staticwebassets" />
<file src="..\Oqtane.Server\wwwroot\**\*" exclude="..\Oqtane.Server\wwwroot\Modules\Templates\**;..\Oqtane.Server\wwwroot\Themes\Templates\**" target="staticwebassets" />
<file src="icon.png" target="" />
<file src="readme.md" target="" />
</files>

View File

@@ -23,9 +23,9 @@ C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
del "..\Oqtane.Server\bin\Release\net9.0\publish\appsettings.json"
del "..\Oqtane.Server\bin\Release\net9.0\publish\web.config"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\upgrade.ps1"
dotnet clean -c Release ..\Oqtane.Updater.sln
dotnet build -c Release ..\Oqtane.Updater.sln
dotnet publish ..\Oqtane.Updater\Oqtane.Updater.csproj /p:Configuration=Release
nuget.exe pack Oqtane.Updater.nuspec
nuget.exe pack ..\Oqtane.Application\Oqtane.Application.Template.nuspec -NoDefaultExcludes
pause

View File

@@ -1,19 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Version>6.2.1</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
<Description>CMS and Application Framework for Blazor and .NET MAUI</Description>
<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/v6.2.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
<IsPackable>true</IsPackable>
<DefineConstants>$(DefineConstants);OQTANE</DefineConstants>
@@ -49,8 +36,8 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.9" />
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.11" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.3" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.4" />
<PackageReference Include="MailKit" Version="4.13.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.5" />
<PackageReference Include="MailKit" Version="4.14.0" />
</ItemGroup>
<ItemGroup>

View File

@@ -1,5 +1,8 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
@@ -8,6 +11,7 @@ using Oqtane.Extensions;
using Oqtane.Infrastructure;
using Oqtane.Managers;
using Oqtane.Shared;
using Radzen.Blazor.Markdown;
namespace Oqtane.Pages
{
@@ -28,6 +32,9 @@ namespace Oqtane.Pages
public async Task<IActionResult> OnPostAsync(string returnurl, string everywhere)
{
returnurl = (returnurl == null) ? "/" : returnurl;
returnurl = (!returnurl.StartsWith("/")) ? "/" + returnurl : returnurl;
if (HttpContext.User != null)
{
var alias = HttpContext.GetAlias();
@@ -43,13 +50,25 @@ namespace Oqtane.Pages
_logger.Log(LogLevel.Information, this, LogFunction.Security, "User Logout For Username {Username}", user.Username);
}
await HttpContext.SignOutAsync(Constants.AuthenticationScheme);
var authenticationProperties = new AuthenticationProperties
{
RedirectUri = returnurl
};
var authenticationSchemes = new List<string>();
authenticationSchemes.Add(Constants.AuthenticationScheme);
if (HttpContext.GetSiteSettings().GetValue("ExternalLogin:ProviderType", "") == AuthenticationProviderTypes.OpenIDConnect &&
HttpContext.GetSiteSettings().GetValue("ExternalLogin:SingleLogout", "false") == "true")
{
authenticationSchemes.Add(AuthenticationProviderTypes.OpenIDConnect);
}
return SignOut(authenticationProperties, authenticationSchemes.ToArray());
}
else
{
return LocalRedirect(Url.Content("~" + returnurl));
}
returnurl = (returnurl == null) ? "/" : returnurl;
returnurl = (!returnurl.StartsWith("/")) ? "/" + returnurl : returnurl;
return LocalRedirect(Url.Content("~" + returnurl));
}
}
}

View File

@@ -19,4 +19,24 @@
}
.rz-text-editor .rz-colorpicker.rz-state-disabled {
border: none !important;
}
.rz-text-editor-dialog .rz-html-editor-dialog-item select{
border: var(--rz-input-border);
border-block-end: var(--rz-input-border-block-end);
border-radius: var(--rz-input-border-radius);
box-shadow: var(--rz-input-shadow);
background-color: var(--rz-input-background-color);
padding-block: var(--rz-input-padding-block);
padding-inline: var(--rz-input-padding-inline);
font-size: var(--rz-input-font-size);
color: var(--rz-input-value-color);
}
.rz-text-editor-dialog .rz-html-editor-dialog-item select:hover, .rz-text-edit-dialog .rz-html-editor-dialog-item select:active {
box-shadow: var(--rz-input-hover-shadow);
background-color: var(--rz-input-hover-background-color);
border: var(--rz-input-hover-border);
border-block-end: var(--rz-input-hover-border-block-end);
}
.rz-text-editor-dialog .alert form{
display: none;
}

View File

@@ -1,21 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Version>6.2.1</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
<Description>CMS and Application Framework for Blazor and .NET MAUI</Description>
<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/v6.2.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
<IsPackable>true</IsPackable>
</PropertyGroup>
<ItemGroup>

View File

@@ -1,21 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<OutputType>Exe</OutputType>
<Version>6.2.1</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
<Description>Modular Application Framework for Blazor and MAUI</Description>
<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/v6.2.1</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>

View File

@@ -12,7 +12,7 @@ Oqtane is being developed based on some fundamental principles which are outline
# Latest Release
[6.2.0](https://github.com/oqtane/oqtane.framework/releases/tag/v6.2.0) was released on September 9, 2025 and is a major release including 57 pull requests by 4 different contributors, pushing the total number of project commits all-time over 7000. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
[6.2.1](https://github.com/oqtane/oqtane.framework/releases/tag/v6.2.1) was released on September 29, 2025 and is a maintenance release including 65 pull requests by 6 different contributors, pushing the total number of project commits all-time over 7100. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
# Try It Now!
@@ -35,20 +35,18 @@ cd Server
dotnet run
```
- Browse to http://localhost:5001 to run the application (the Install Wizard will be displayed the first time)
- Browse to http://localhost:5001 to run the application (an Installation Wizard screen will be displayed the first time you run the application)
- To develop/debug the application, open the MyCompany.MyProject.sln file in the root folder and hit F5
**Installing using source code from the Dev/Master branch:**
- Install **[.NET 9.0.9 SDK](https://dotnet.microsoft.com/en-us/download)**.
- Install Latest **[.NET 9.0 SDK](https://dotnet.microsoft.com/en-us/download)**.
- Install the latest edition (v17.12 or higher) of [Visual Studio 2022](https://visualstudio.microsoft.com/downloads) with the **ASP.NET and web development** workload enabled. Oqtane works with ALL editions of Visual Studio from Community to Enterprise. If you wish to use LocalDB for development ( not a requirement as Oqtane supports SQLite, mySQL, and PostgreSQL ) you must also install the **Data storage and processing**.
- Clone (or download) the Oqtane Master or Dev branch source code to your local system.
- Open the **Oqtane.sln** solution file.
- **Important:** Rebuild the entire solution before running it (ie. Build / Rebuild Solution).
- Make sure you specify Oqtane.Server as the Startup Project.
@@ -106,6 +104,9 @@ Connect with other developers, get support, and share ideas by joining the Oqtan
# Roadmap
This project is open source, and therefore is a work in progress...
[6.2.1](https://github.com/oqtane/oqtane.framework/releases/tag/v6.2.1) (Sep 29, 2025)
- [x] Stabilization improvements
[6.2.0](https://github.com/oqtane/oqtane.framework/releases/tag/v6.2.0) (Sep 9, 2025)
- [x] Oqtane Application Template
- [x] Radzen Text Editor

View File

@@ -220,7 +220,7 @@
"apiVersion": "2024-04-01",
"name": "[concat(parameters('BlazorWebsiteName'), '/ZipDeploy')]",
"properties": {
"packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v6.2.0/Oqtane.Framework.6.2.0.Install.zip"
"packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v6.2.1/Oqtane.Framework.6.2.1.Install.zip"
},
"dependsOn": [
"[resourceId('Microsoft.Web/sites', parameters('BlazorWebsiteName'))]"