Merge pull request #3457 from oqtane/net8

Merging net8 branch into dev in preparation for Oqtane 5.0 release next week
This commit is contained in:
Shaun Walker
2023-11-06 15:04:53 -05:00
committed by GitHub
62 changed files with 694 additions and 620 deletions

View File

@ -15,7 +15,7 @@
<div class="row">
<div class="mx-auto text-center">
<img src="oqtane-black.png" />
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET 7)</div>
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET 8)</div>
</div>
</div>
<hr class="app-rule" />

View File

@ -93,23 +93,16 @@
{
try
{
_allowexternallogin = (SettingService.GetSetting(PageState.Site.Settings, "ExternalLogin:ProviderType", "") != "") ? true : false;
_allowsitelogin = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:AllowSiteLogin", "true"));
_togglepassword = SharedLocalizer["ShowPassword"];
if (PageState.QueryString.ContainsKey("returnurl"))
{
_returnUrl = PageState.QueryString["returnurl"];
}
_allowexternallogin = (SettingService.GetSetting(PageState.Site.Settings, "ExternalLogin:ProviderType", "") != "") ? true : false;
_allowsitelogin = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:AllowSiteLogin", "true"));
if (_allowexternallogin && !_allowsitelogin)
{
// redirect to external login
NavigationManager.NavigateTo(Utilities.TenantUrl(PageState.Alias, "/pages/external?returnurl=" + _returnUrl), true);
return;
}
_togglepassword = SharedLocalizer["ShowPassword"];
if (PageState.QueryString.ContainsKey("name"))
{
_username = PageState.QueryString["name"];

View File

@ -22,7 +22,7 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="description" HelpText="The help text displayed to the user for this profile item" ResourceKey="Description">Description: </Label>
<div class="col-sm-9">
<textarea id="description" class="form-control" @bind="@_description" rows="3" maxlength="256" required ></textarea>
<textarea id="description" class="form-control" @bind="@_description" rows="3" maxlength="256" required></textarea>
</div>
</div>
<div class="row mb-1 align-items-center">
@ -34,25 +34,25 @@
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="order" HelpText="The index order of where this profile item should be displayed" ResourceKey="Order">Order: </Label>
<div class="col-sm-9">
<input id="order" class="form-control" @bind="@_vieworder" maxlength="4" required />
<input id="order" class="form-control" @bind="@_vieworder" min="0" max="99" type="number" required />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="length" HelpText="The max number of characters this profile item should accept (enter zero for unlimited)" ResourceKey="Length">Length: </Label>
<div class="col-sm-9">
<input id="length" class="form-control" @bind="@_maxlength" maxlength="4" required />
<input id="length" class="form-control" @bind="@_maxlength" min="0" max="524288" type="number" required />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="rows" HelpText="The number of rows for text entry (one is the default)" ResourceKey="Rows">Rows: </Label>
<div class="col-sm-9">
<input id="rows" class="form-control" @bind="@_rows" maxlength="2" required />
<input id="rows" class="form-control" @bind="@_rows" min="1" max="10" type="number" required />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="defaultVal" HelpText="The default value for this profile item" ResourceKey="DefaultValue">Default Value: </Label>
<div class="col-sm-9">
<input id="defaultVal" class="form-control" @bind="@_defaultvalue" maxlength="2000"/>
<input id="defaultVal" class="form-control" @bind="@_defaultvalue" maxlength="2000" />
</div>
</div>
<div class="row mb-1 align-items-center">

View File

@ -2,6 +2,7 @@
@inherits ModuleBase
@inject NavigationManager NavigationManager
@inject IUserService UserService
@inject IUserRoleService UserRoleService
@inject INotificationService NotificationService
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@ -10,10 +11,10 @@
{
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="to" HelpText="Enter the username you wish to send a message to" ResourceKey="To">To: </Label>
<Label Class="col-sm-3" For="to" HelpText="Enter the user you wish to send a message to" ResourceKey="To">To: </Label>
<div class="col-sm-9">
<input id="to" class="form-control" @bind="@username" />
</div>
<AutoComplete OnSearch="GetUsers" Placeholder="@Localizer["Username.Enter"]" @ref="username" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="subject" HelpText="Enter the subject of the message" ResourceKey="Subject">Subject: </Label>
@ -30,11 +31,11 @@
</div>
<br/>
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
private string username = "";
private AutoComplete username;
private string subject = "";
private string body = "";
@ -42,21 +43,35 @@
public override string Title => "Send Notification";
private async Task<Dictionary<string, string>> GetUsers(string filter)
{
var users = await UserRoleService.GetUserRolesAsync(PageState.Site.SiteId, RoleNames.Registered);
return users.Where(item => item.User.Username.Contains(filter, StringComparison.OrdinalIgnoreCase))
.ToDictionary(item => item.UserId.ToString(), item => item.User.Username);
}
private async Task Send()
{
try
{
var user = await UserService.GetUserAsync(username, PageState.Site.SiteId);
if (user != null)
if (!string.IsNullOrEmpty(username.Key) && !string.IsNullOrEmpty(subject))
{
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body);
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
var user = await UserService.GetUserAsync(int.Parse(username.Key), ModuleState.SiteId);
if (user != null)
{
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body);
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(PageState.ReturnUrl);
}
else
{
AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
}
}
else
{
AddModuleMessage(Localizer["Message.User.Invalid"], MessageType.Warning);
AddModuleMessage(Localizer["Message.Required"], MessageType.Warning);
}
}
catch (Exception ex)

View File

@ -11,18 +11,18 @@
@inject IStringLocalizer<Index> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null && photo != null)
@if (_initialized)
{
<img src="@ImageUrl(photofileid, 400, 400)" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
else
{
<br />
}
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
@if (profiles != null && settings != null)
{
@if (PageState.User != null && photo != null)
{
<img src="@ImageUrl(photofileid, 400, 400)" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
else
{
<br />
}
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
<div class="container">
<div class="row mb-1 align-items-center">
@ -33,34 +33,34 @@ else
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="password" HelpText="If you wish to change your password you can enter it here. Please choose a sufficiently secure password." ResourceKey="Password"></Label>
<div class="col-sm-9">
<div class="col-sm-9">
<div class="input-group">
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="confirm" HelpText="If you are changing your password you must enter it again to confirm it matches" ResourceKey="Confirm"></Label>
<div class="col-sm-9">
<div class="input-group">
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
</div>
@if (allowtwofactor)
{
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="twofactor" HelpText="Indicates if you are using two factor authentication. Two factor authentication requires you to enter a verification code sent via email after you sign in." ResourceKey="TwoFactor"></Label>
<div class="col-sm-9">
<select id="twofactor" class="form-select" @bind="@twofactor" required>
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
}
@if (allowtwofactor)
{
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="twofactor" HelpText="Indicates if you are using two factor authentication. Two factor authentication requires you to enter a verification code sent via email after you sign in." ResourceKey="TwoFactor"></Label>
<div class="col-sm-9">
<select id="twofactor" class="form-select" @bind="@twofactor" 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="email" HelpText="Your email address where you wish to receive notifications" ResourceKey="Email"></Label>
<div class="col-sm-9">
@ -83,11 +83,8 @@ else
<br />
<button type="button" class="btn btn-success" @onclick="Save">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
}
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
@if (profiles != null && settings != null)
{
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
<div class="container">
<div class="row mb-1 align-items-center">
@foreach (Profile profile in profiles)
@ -104,8 +101,8 @@ else
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
{
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
@ -154,134 +151,151 @@ else
</div>
<button type="button" class="btn btn-success" @onclick="Save">@SharedLocalizer["Save"]</button>
<button type="button" class="btn btn-secondary" @onclick="Cancel">@SharedLocalizer["Cancel"]</button>
}
</TabPanel>
<TabPanel Name="Notifications" ResourceKey="Notifications">
@if (notifications != null)
{
</TabPanel>
<TabPanel Name="Notifications" ResourceKey="Notifications">
<ActionLink Action="Add" Text="Send Notification" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="SendNotification" ReturnUrl="@NavigateUrl(PageState.Page.Path, "tab=Notifications")" />
<br />
<br />
<select class="form-select" @onchange="(e => FilterChanged(e))">
<option value="to">@Localizer["Inbox"]</option>
<option value="from">@Localizer["Items.Sent"]</option>
</select>
<br />
<ActionLink Action="Add" Text="Send Notification" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="SendNotification" />
<br /><br />
@if (filter == "to")
{
<Pager Items="@notifications">
<Header>
@if (notifications.Any())
{
<Pager Items="@notifications">
<Header>
<th style="width: 1px;">&nbsp;</th>
<th style="width: 1px;">&nbsp;</th>
<th>@Localizer["From"]</th>
<th>@Localizer["Subject"]</th>
<th>@Localizer["Received"]</th>
</Header>
<Row>
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
@if (context.IsRead)
{
<td>@context.FromDisplayName</td>
<td>@context.Subject</td>
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
}
else
{
<td><b>@context.FromDisplayName</b></td>
<td><b>@context.Subject</b></td>
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
}
</Row>
<Detail>
<td colspan="2"></td>
<td colspan="3">
@{
string input = "___";
if (context.Body.Contains(input))
{
context.Body = context.Body.Split(input)[0];
context.Body = context.Body.Replace("\n", "");
context.Body = context.Body.Replace("\r", "");
}
notificationSummary = context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body;
}
</Header>
<Row>
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" ReturnUrl="@NavigateUrl(PageState.Page.Path, "tab=Notifications")" /></td>
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
@if (context.IsRead)
{
@notificationSummary
<td>@context.FromDisplayName</td>
<td>@context.Subject</td>
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
}
else
{
<b>@notificationSummary</b>
<td><b>@context.FromDisplayName</b></td>
<td><b>@context.Subject</b></td>
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
}
</td>
</Detail>
</Pager>
</Row>
<Detail>
<td colspan="2"></td>
<td colspan="3">
@{
string input = "___";
if (context.Body.Contains(input))
{
context.Body = context.Body.Split(input)[0];
context.Body = context.Body.Replace("\n", "");
context.Body = context.Body.Replace("\r", "");
}
notificationSummary = context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body;
}
@if (context.IsRead)
{
@notificationSummary
}
else
{
<b>@notificationSummary</b>
}
</td>
</Detail>
</Pager>
<br />
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
}
else
{
<div class="no-notifications-text">
@Localizer["NoNotificationsReceived.Text"]
</div>
}
}
else
{
<Pager Items="@notifications">
<Header>
<th>&nbsp;</th>
<th>&nbsp;</th>
@if (notifications.Any())
{
<Pager Items="@notifications">
<Header>
<th style="width: 1px;"></th>
<th style="width: 1px;"></th>
<th>@Localizer["To"]</th>
<th>@Localizer["Subject"]</th>
<th>@Localizer["Sent"]</th>
</Header>
<Row>
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" /></td>
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
</Header>
<Row>
<td><ActionLink Action="View" Parameters="@($"id=" + context.NotificationId.ToString())" Security="SecurityAccessLevel.View" EditMode="false" ResourceKey="ViewNotification" ReturnUrl="@NavigateUrl(PageState.Page.Path, "tab=Notifications")" /></td>
<td><ActionDialog Header="Delete Notification" Message="Are You Sure You Wish To Delete This Notification?" Action="Delete" Security="SecurityAccessLevel.View" Class="btn btn-danger" OnClick="@(async () => await Delete(context))" EditMode="false" ResourceKey="DeleteNotification" /></td>
@if (context.IsRead)
{
<td>@context.ToDisplayName</td>
<td>@context.Subject</td>
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
}
else
{
<td><b>@context.ToDisplayName</b></td>
<td><b>@context.Subject</b></td>
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
}
</Row>
<Detail>
<td colspan="2"></td>
<td colspan="3">
@{
string input = "___";
if (context.Body.Contains(input))
{
context.Body = context.Body.Split(input)[0];
context.Body = context.Body.Replace("\n", "");
context.Body = context.Body.Replace("\r", "");
}
notificationSummary = context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body;
}
@if (context.IsRead)
{
@notificationSummary
<td>@context.ToDisplayName</td>
<td>@context.Subject</td>
<td>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</td>
}
else
else
{
<b>@notificationSummary</b>
}
</td>
</Detail>
</Pager>
<td><b>@context.ToDisplayName</b></td>
<td><b>@context.Subject</b></td>
<td><b>@string.Format("{0:dd-MMM-yyyy HH:mm:ss}", @context.CreatedOn)</b></td>
}
</Row>
<Detail>
<td colspan="2"></td>
<td colspan="3">
@{
string input = "___";
if (context.Body.Contains(input))
{
context.Body = context.Body.Split(input)[0];
context.Body = context.Body.Replace("\n", "");
context.Body = context.Body.Replace("\r", "");
}
notificationSummary = context.Body.Length > 100 ? (context.Body.Substring(0, 97) + "...") : context.Body;
}
@if (context.IsRead)
{
@notificationSummary
}
else
{
<b>@notificationSummary</b>
}
</td>
</Detail>
</Pager>
<br />
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
}
else
{
<div class="no-notifications-text">
@Localizer["NoNotificationsSent.Text"]
</div>
}
}
@if (notifications.Any())
{
<br />
<ActionDialog Header="Clear Notifications" Message="Are You Sure You Wish To Permanently Delete All Notifications ?" Action="Delete All Notifications" Security="SecurityAccessLevel.Admin" Class="btn btn-danger" OnClick="@(async () => await DeleteAllNotifications())" ResourceKey="DeleteAllNotifications" />
}
}
</TabPanel>
</TabStrip>
<br /><br />
</TabPanel>
</TabStrip>
<br />
<br />
}
@code {
private bool _initialized = false;
private string _passwordrequirements;
private string username = string.Empty;
private string _password = string.Empty;
@ -307,15 +321,14 @@ else
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
protected override async Task OnParametersSetAsync()
protected override async Task OnInitializedAsync()
{
try
{
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
_togglepassword = SharedLocalizer["ShowPassword"];
allowtwofactor = (SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:TwoFactor", "false") == "true");
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
if (PageState.User != null)
{
@ -342,10 +355,11 @@ else
photo = null;
}
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
settings = await SettingService.GetUserSettingsAsync(PageState.User.UserId);
await LoadNotificationsAsync();
_initialized = true;
}
else
{
@ -445,13 +459,14 @@ else
{
foreach (Profile profile in profiles)
{
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
var value = GetProfileValue(profile.Name, string.Empty);
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
{
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
}
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
if (profile.IsRequired && string.IsNullOrEmpty(value))
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
return false;
@ -459,7 +474,7 @@ else
if (!string.IsNullOrEmpty(profile.Validation))
{
Regex regex = new Regex(profile.Validation);
bool valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
bool valid = regex.Match(value).Success;
if (!valid)
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);
@ -510,7 +525,6 @@ else
private async void FilterChanged(ChangeEventArgs e)
{
filter = (string)e.Value;
await LoadNotificationsAsync();
StateHasChanged();
}

View File

@ -8,94 +8,71 @@
@if (PageState.User != null)
{
<div class="container">
<div class="row mb-1 align-items-center">
<label Class="col-sm-3">@Localizer["Title"] </label>
@if (title == "From")
{
<div class="col-sm-3">
<input class="form-control" @bind="@username" readonly />
</div>
}
@if (title == "To")
{
<div class="col-sm-3">
<input class="form-control" @bind="@username" />
</div>
}
</div>
<div class="row mb-1 align-items-center">
<label Class="col-sm-3">@Localizer["Subject"] </label>
@if (title == "From")
{
<div class="col-sm-3">
<input class="form-control" @bind="@subject" readonly />
</div>
}
@if (title == "To")
{
<div class="col-sm-3">
<input class="form-control" @bind="@subject" />
</div>
}
</div>
</div>
<div class="container">
@if (title == "From")
{
@if (title == "From")
{
<div class="container">
<div class="row mb-1 align-items-center">
<label class="col-sm-3">@Localizer["Date"] </label>
<Label Class="col-sm-3" For="username" HelpText="The user who sent the message" ResourceKey="From">From:</Label>
<div class="col-sm-9">
<input class="form-control" @bind="@createdon" readonly />
<input id="username" class="form-control" @bind="@username" readonly />
</div>
</div>
}
@if (title == "From")
{
<div class="row mb-1 align-items-center">
<label class="col-sm-3">@Localizer["Message"] </label>
<div class="col-sm-9">
<textarea id="txtFrom" class="form-control" @bind="@body" rows="5" readonly />
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="subject" HelpText="The subject of the message" ResourceKey="Subject">Subject:</Label>
<div class="col-sm-9">
<input id="subject" class="form-control" @bind="@subject" readonly />
</div>
}
@if (title == "To")
{
<div class="row mb-1 align-items-center">
<label class="col-sm-3">@Localizer["Message"] </label>
<div class="col-sm-9">
<textarea id="txtTo" class="form-control" @bind="@body" rows="5" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label class="col-sm-3" For="date" HelpText="The date the message was sent" ResourceKey="Date">Sent:</Label>
<div class="col-sm-9">
<input id="date" class="form-control" @bind="@createdon" readonly />
</div>
}
</div>
@if (reply != string.Empty)
{
<button type="button" class="btn btn-primary" @onclick="Send">@SharedLocalizer["Send"]</button>
</div>
<div class="row mb-1 align-items-center">
<Label class="col-sm-3" For="message" HelpText="The contents of the message" ResourceKey="Message">Message:</Label>
<div class="col-sm-9">
<textarea id="message" class="form-control" @bind="@body" rows="5" readonly />
</div>
</div>
</div>
}
else
{
if (title == "From")
{
<button type="button" class="btn btn-primary" @onclick="Reply">@Localizer["Reply"]</button>
}
}
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
@if (title == "To")
{
<div class="control-group">
<label class="control-label">@Localizer["OriginalMessage"] </label>
<textarea id="txtReply" class="form-control" @bind="@reply" rows="5" readonly />
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="username" HelpText="The user who will be the recipient of the message" ResourceKey="To">To:</Label>
<div class="col-sm-9">
<input id="username" class="form-control" @bind="@username" readonly />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="subject" HelpText="The subject of the message" ResourceKey="Subject">Subject:</Label>
<div class="col-sm-9">
<input id="subject" class="form-control" @bind="@subject" readonly="@(!reply)" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label class="col-sm-3" For="message" HelpText="The content of the message" ResourceKey="Message">Message:</Label>
<div class="col-sm-9">
<textarea id="message" class="form-control" @bind="@body" rows="5" readonly="@(!reply)" />
</div>
</div>
</div>
}
@if (reply)
{
<button type="button" class="btn btn-primary me-2" @onclick="Send">@SharedLocalizer["Send"]</button>
}
else
{
if (title == "From" && username != Localizer["System"])
{
<button type="button" class="btn btn-primary me-2" @onclick="Reply">@Localizer["Reply"]</button>
}
}
<NavLink class="btn btn-secondary" href="@PageState.ReturnUrl">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
@ -105,7 +82,7 @@
private string subject = string.Empty;
private string createdon = string.Empty;
private string body = string.Empty;
private string reply = string.Empty;
private bool reply = false;
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.View;
public override string Title => "View Notification";
@ -118,9 +95,6 @@
Notification notification = await NotificationService.GetNotificationAsync(notificationid);
if (notification != null)
{
notification.IsRead = true;
notification = await NotificationService.UpdateNotificationAsync(notification);
int userid = -1;
if (notification.ToUserId == PageState.User.UserId)
{
@ -148,11 +122,17 @@
}
if (username == "")
{
username = "System";
username = Localizer["System"];
}
subject = notification.Subject;
createdon = notification.CreatedOn.ToString();
body = notification.Body;
if (title == "From")
{
notification.IsRead = true;
notification = await NotificationService.UpdateNotificationAsync(notification);
}
}
}
catch (Exception ex)
@ -165,12 +145,16 @@
private void Reply()
{
title = "To";
if (!subject.Contains("RE:"))
if (!subject.Contains(Localizer["RE:"]))
{
subject = "RE: " + subject;
subject = Localizer["RE"] + " " + subject;
}
reply = body;
body = "\n\n____________________________________________\nSent: " + createdon + "\nSubject: " + subject + "\n\n" + body;
body = $"\n\n____________________________________________\n" +
$"{Localizer["From.Text"]} {username}\n" +
$"{Localizer["Date.Text"]} {createdon}\n" +
$"{Localizer["Subject.Text"]} {subject}\n\n" +
body;
reply = true;
StateHasChanged();
}
@ -184,7 +168,7 @@
var notification = new Notification(PageState.Site.SiteId, PageState.User, user, subject, body, notificationid);
notification = await NotificationService.AddNotificationAsync(notification);
await logger.LogInformation("Notification Created {NotificationId}", notification.NotificationId);
NavigationManager.NavigateTo(NavigateUrl());
NavigationManager.NavigateTo(PageState.ReturnUrl);
}
else
{

View File

@ -8,63 +8,63 @@
@inject IStringLocalizer<Add> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
@if (profiles != null)
{
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="username" HelpText="A unique username for a user. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
<div class="col-sm-9">
<input id="username" class="form-control" @bind="@_username" />
@if (_initialized)
{
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
@if (profiles != null)
{
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
<div class="container">
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="username" HelpText="A unique username for a user. Note that this field can not be modified once it is saved." ResourceKey="Username"></Label>
<div class="col-sm-9">
<input id="username" class="form-control" @bind="@_username" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="password" HelpText="The user's password. Please choose a password which is sufficiently secure." ResourceKey="Password"></Label>
<div class="col-sm-9">
<div class="input-group">
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
<div class="col-sm-9">
<div class="input-group">
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
<div class="col-sm-9">
<input id="email" class="form-control" @bind="@_email" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
<div class="col-sm-9">
<input id="displayname" class="form-control" @bind="@_displayname" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="notify" HelpText="Indicate if new users should receive an email notification" ResourceKey="Notify">Notify? </Label>
<div class="col-sm-9">
<select id="notify" class="form-select" @bind="@_notify" required>
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="password" HelpText="The user's password. Please choose a password which is sufficiently secure." ResourceKey="Password"></Label>
<div class="col-sm-9">
<div class="input-group">
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" required />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
<div class="col-sm-9">
<div class="input-group">
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@_confirm" autocomplete="new-password" required />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="email" HelpText="The email address where the user will receive notifications" ResourceKey="Email"></Label>
<div class="col-sm-9">
<input id="email" class="form-control" @bind="@_email" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="displayname" HelpText="The full name of the user" ResourceKey="DisplayName"></Label>
<div class="col-sm-9">
<input id="displayname" class="form-control" @bind="@_displayname" />
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="notify" HelpText="Indicate if new users should receive an email notification" ResourceKey="Notify">Notify? </Label>
<div class="col-sm-9">
<select id="notify" class="form-select" @bind="@_notify" required>
<option value="True">@SharedLocalizer["Yes"]</option>
<option value="False">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
</div>
}
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
@if (profiles != null)
{
}
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
<div class="container">
<div class="row mb-1 align-items-center">
@foreach (Profile profile in profiles)
@ -79,8 +79,8 @@
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
{
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
@ -100,25 +100,11 @@
{
@if (p.Rows == 1)
{
@if (p.IsRequired)
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
}
else
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
}
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
}
else
{
@if (p.IsRequired)
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
else
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
}
</div>
@ -126,15 +112,17 @@
}
</div>
</div>
}
</TabPanel>
</TabStrip>
<br />
<br />
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
</TabPanel>
</TabStrip>
<br />
<br />
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
}
@code {
private bool _initialized = false;
private string _passwordrequirements;
private string _username = string.Empty;
private string _password = string.Empty;
@ -158,6 +146,7 @@
_togglepassword = SharedLocalizer["ShowPassword"];
profiles = await ProfileService.GetProfilesAsync(ModuleState.SiteId);
settings = new Dictionary<string, string>();
_initialized = true;
}
catch (Exception ex)
{
@ -231,13 +220,14 @@
{
foreach (Profile profile in profiles)
{
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
var value = GetProfileValue(profile.Name, string.Empty);
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
{
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
}
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
if (profile.IsRequired && string.IsNullOrEmpty(value))
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
return false;
@ -245,7 +235,7 @@
if (!string.IsNullOrEmpty(profile.Validation))
{
Regex regex = new Regex(profile.Validation);
bool valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
bool valid = regex.Match(value).Success;
if (!valid)
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);

View File

@ -9,18 +9,10 @@
@inject IStringLocalizer<Edit> Localizer
@inject IStringLocalizer<SharedResources> SharedLocalizer
@if (PageState.User != null && photo != null)
@if (_initialized)
{
<img src="@photo.Url" alt="@displayname" style="max-width: 400px" class="rounded-circle mx-auto d-block">
}
else
{
<br />
}
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
@if (profiles != null)
{
<TabStrip>
<TabPanel Name="Identity" ResourceKey="Identity">
<ModuleMessage Message="@_passwordrequirements" Type="MessageType.Info" />
<div class="container">
<div class="row mb-1 align-items-center">
@ -31,20 +23,20 @@ else
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="password" HelpText="The user's password. Please choose a password which is sufficiently secure." ResourceKey="Password"></Label>
<div class="col-sm-9">
<div class="col-sm-9">
<div class="input-group">
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
<input id="password" type="@_passwordtype" class="form-control" @bind="@_password" autocomplete="new-password" />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="confirm" HelpText="Please enter the password again to confirm it matches with the value above" ResourceKey="Confirm"></Label>
<div class="col-sm-9">
<div class="input-group">
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
<input id="confirm" type="@_passwordtype" class="form-control" @bind="@confirm" autocomplete="new-password" />
<button type="button" class="btn btn-secondary" @onclick="@TogglePassword" tabindex="-1">@_togglepassword</button>
</div>
</div>
</div>
</div>
<div class="row mb-1 align-items-center">
@ -87,11 +79,8 @@ else
</div>
</div>
</div>
}
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
@if (profiles != null)
{
</TabPanel>
<TabPanel Name="Profile" ResourceKey="Profile">
<div class="container">
<div class="row mb-1 align-items-center">
@foreach (Profile profile in profiles)
@ -106,8 +95,8 @@ else
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="@p.Name" HelpText="@p.Description">@p.Title</Label>
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
<div class="col-sm-9">
@if (!string.IsNullOrEmpty(p.Options))
{
<select id="@p.Name" class="form-select" @onchange="@(e => ProfileChanged(e, p.Name))">
@foreach (var option in p.Options.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
@ -127,25 +116,11 @@ else
{
@if (p.Rows == 1)
{
@if (p.IsRequired)
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))" />
}
else
{
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
}
<input id="@p.Name" class="form-control" maxlength="@p.MaxLength" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))" />
}
else
{
@if (p.IsRequired)
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" required @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
else
{
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
<textarea id="@p.Name" class="form-control" maxlength="@p.MaxLength" rows="@p.Rows" value="@GetProfileValue(p.Name, p.DefaultValue)" @onchange="@(e => ProfileChanged(e, p.Name))"></textarea>
}
}
</div>
@ -153,17 +128,18 @@ else
}
</div>
</div>
}
</TabPanel>
</TabStrip>
</TabPanel>
</TabStrip>
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
<button type="button" class="btn btn-success" @onclick="SaveUser">@SharedLocalizer["Save"]</button>
<NavLink class="btn btn-secondary" href="@NavigateUrl()">@SharedLocalizer["Cancel"]</NavLink>
<br />
<br />
<AuditInfo CreatedBy="@createdby" CreatedOn="@createdon" ModifiedBy="@modifiedby" ModifiedOn="@modifiedon" DeletedBy="@deletedby" DeletedOn="@deletedon"></AuditInfo>
}
@code {
@code {
private bool _initialized = false;
private string _passwordrequirements;
private int userid;
private string username = string.Empty;
@ -175,7 +151,6 @@ else
private string displayname = string.Empty;
private FileManager filemanager;
private int photofileid = -1;
private File photo = null;
private string isdeleted;
private string lastlogin;
private string lastipaddress;
@ -193,16 +168,17 @@ else
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Edit;
protected override async Task OnParametersSetAsync()
protected override async Task OnInitializedAsync()
{
try
{
if (PageState.QueryString.ContainsKey("id"))
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
_togglepassword = SharedLocalizer["ShowPassword"];
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
if (PageState.QueryString.ContainsKey("id") && int.TryParse(PageState.QueryString["id"], out int UserId))
{
_passwordrequirements = await UserService.GetPasswordRequirementsAsync(PageState.Site.SiteId);
_togglepassword = SharedLocalizer["ShowPassword"];
profiles = await ProfileService.GetProfilesAsync(PageState.Site.SiteId);
userid = Int32.Parse(PageState.QueryString["id"]);
userid = UserId;
var user = await UserService.GetUserAsync(userid, PageState.Site.SiteId);
if (user != null)
{
@ -212,12 +188,10 @@ else
if (user.PhotoFileId != null)
{
photofileid = user.PhotoFileId.Value;
photo = await FileService.GetFileAsync(photofileid);
}
else
{
photofileid = -1;
photo = null;
}
isdeleted = user.IsDeleted.ToString();
lastlogin = string.Format("{0:MMM dd yyyy HH:mm:ss}", user.LastLoginOn);
@ -232,6 +206,8 @@ else
deletedon = user.DeletedOn;
}
}
_initialized = true;
}
catch (Exception ex)
{
@ -309,13 +285,14 @@ else
{
foreach (Profile profile in profiles)
{
if (string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)) && !string.IsNullOrEmpty(profile.DefaultValue))
var value = GetProfileValue(profile.Name, string.Empty);
if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(profile.DefaultValue))
{
settings = SettingService.SetSetting(settings, profile.Name, profile.DefaultValue);
}
if (!profile.IsPrivate || UserSecurity.IsAuthorized(PageState.User, RoleNames.Admin))
{
if (profile.IsRequired && string.IsNullOrEmpty(SettingService.GetSetting(settings, profile.Name, string.Empty)))
if (profile.IsRequired && string.IsNullOrEmpty(value))
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileRequired"], profile.Title), MessageType.Warning);
return false;
@ -323,7 +300,7 @@ else
if (!string.IsNullOrEmpty(profile.Validation))
{
Regex regex = new Regex(profile.Validation);
bool valid = regex.Match(SettingService.GetSetting(settings, profile.Name, string.Empty)).Success;
bool valid = regex.Match(value).Success;
if (!valid)
{
AddModuleMessage(string.Format(SharedLocalizer["ProfileInvalid"], profile.Title), MessageType.Warning);

View File

@ -323,7 +323,16 @@ else
</select>
</div>
</div>
}
<div class="row mb-1 align-items-center">
<Label Class="col-sm-3" For="verifyusers" HelpText="Do you want existing users to perform an additional email verification step to link their external login? If you disable this option, existing users will be linked automatically." ResourceKey="VerifyUsers">Verify Existing Users?</Label>
<div class="col-sm-9">
<select id="verifyusers" class="form-select" @bind="@_verifyusers">
<option value="true">@SharedLocalizer["Yes"]</option>
<option value="false">@SharedLocalizer["No"]</option>
</select>
</div>
</div>
}
</Section>
<Section Name="Token" Heading="Token Settings" ResourceKey="TokenSettings">
<div class="row mb-1 align-items-center">
@ -410,6 +419,7 @@ else
private string _profileclaimtypes;
private string _domainfilter;
private string _createusers;
private string _verifyusers;
private string _secret;
private string _secrettype = "password";
@ -468,6 +478,7 @@ else
_profileclaimtypes = SettingService.GetSetting(settings, "ExternalLogin:ProfileClaimTypes", "");
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
_verifyusers = SettingService.GetSetting(settings, "ExternalLogin:VerifyUsers", "true");
_secret = SettingService.GetSetting(settings, "JwtOptions:Secret", "");
_togglesecret = SharedLocalizer["ShowPassword"];
@ -556,6 +567,7 @@ else
settings = SettingService.SetSetting(settings, "ExternalLogin:ProfileClaimTypes", _profileclaimtypes, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
settings = SettingService.SetSetting(settings, "ExternalLogin:VerifyUsers", _verifyusers, true);
if (!string.IsNullOrEmpty(_secret) && _secret.Length < 16) _secret = (_secret + "????????????????").Substring(0, 16);
settings = SettingService.SetSetting(settings, "JwtOptions:Secret", _secret, true);

View File

@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<Configurations>Debug;Release</Configurations>
<Version>4.0.6</Version>
<Version>5.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -12,7 +12,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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
@ -21,12 +21,12 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-rc.2.23480.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
</ItemGroup>

View File

@ -187,6 +187,12 @@
<value>Optionally provide a regular expression (RegExp) for validating the value entered</value>
</data>
<data name="Validation.Text" xml:space="preserve">
<value>Validation:</value>
<value>Validation: </value>
</data>
</root>
<data name="Rows.HelpText" xml:space="preserve">
<value>The number of rows for text entry (one is the default)</value>
</data>
<data name="Rows.Text" xml:space="preserve">
<value>Rows: </value>
</data>
</root>

View File

@ -121,7 +121,7 @@
<value>Message: </value>
</data>
<data name="Message.User.Invalid" xml:space="preserve">
<value>User Does Not Exist. Please Verify That The Username Provided Is Correct.</value>
<value>The User Specified Does Not Exist</value>
</data>
<data name="Error.Notification.Add" xml:space="preserve">
<value>Error Adding Notification</value>
@ -133,7 +133,7 @@
<value>Enter the subject of the message</value>
</data>
<data name="Message.HelpText" xml:space="preserve">
<value>Enter the message</value>
<value>Enter the message content</value>
</data>
<data name="To.Text" xml:space="preserve">
<value>To: </value>
@ -144,4 +144,10 @@
<data name="Send Notification" xml:space="preserve">
<value>Send Notification</value>
</data>
<data name="Message.Required" xml:space="preserve">
<value>You Must Enter All Required Information</value>
</data>
<data name="Username.Enter" xml:space="preserve">
<value>Enter Username</value>
</data>
</root>

View File

@ -233,5 +233,11 @@
</data>
<data name="DeleteNotification.Text" xml:space="preserve">
<value>Delete</value>
</data>
</data>
<data name="NoNotificationsReceived.Text" xml:space="preserve">
<value>No notifications have been received</value>
</data>
<data name="NoNotificationsSent.Text" xml:space="preserve">
<value>No notifications have been sent</value>
</data>
</root>

View File

@ -126,25 +126,43 @@
<data name="Error.Notification.Add" xml:space="preserve">
<value>Error Adding Notification</value>
</data>
<data name="Title" xml:space="preserve">
<value>Title:</value>
</data>
<data name="Subject" xml:space="preserve">
<value>Subject:</value>
</data>
<data name="Date" xml:space="preserve">
<value>Date:</value>
</data>
<data name="Message" xml:space="preserve">
<value>Message:</value>
</data>
<data name="Reply" xml:space="preserve">
<value>Reply</value>
</data>
<data name="OriginalMessage" xml:space="preserve">
<value>Original Message</value>
</data>
<data name="View Notification" xml:space="preserve">
<value>View Notification</value>
</data>
<data name="Date.HelpText" xml:space="preserve">
<value>The date the message was sent</value>
</data>
<data name="Date.Text" xml:space="preserve">
<value>Sent:</value>
</data>
<data name="From.HelpText" xml:space="preserve">
<value>The user who sent the message</value>
</data>
<data name="From.Text" xml:space="preserve">
<value>From:</value>
</data>
<data name="Message.HelpText" xml:space="preserve">
<value>The content of the message</value>
</data>
<data name="Message.Text" xml:space="preserve">
<value>Message:</value>
</data>
<data name="RE" xml:space="preserve">
<value>RE:</value>
</data>
<data name="Subject.HelpText" xml:space="preserve">
<value>The subject of the message</value>
</data>
<data name="Subject.Text" xml:space="preserve">
<value>Subject:</value>
</data>
<data name="System" xml:space="preserve">
<value>System</value>
</data>
<data name="To.HelpText" xml:space="preserve">
<value>The user who will be the recipient of the message</value>
</data>
<data name="To.Text" xml:space="preserve">
<value>To:</value>
</data>
</root>

View File

@ -435,4 +435,10 @@
<data name="AuthResponseType" xml:space="preserve">
<value>Authorization Response Type</value>
</data>
<data name="VerifyUsers.HelpText" xml:space="preserve">
<value>Do you want existing users to perform an additional email verification step to link their external login? If you disable this option, existing users will be linked automatically.</value>
</data>
<data name="VerifyUsers.Text" xml:space="preserve">
<value>Verify Existing Users?</value>
</data>
</root>

View File

@ -23,8 +23,23 @@ namespace Oqtane.Themes.Controls
protected void LoginUser()
{
var allowexternallogin = (SettingService.GetSetting(PageState.Site.Settings, "ExternalLogin:ProviderType", "") != "") ? true : false;
var allowsitelogin = bool.Parse(SettingService.GetSetting(PageState.Site.Settings, "LoginOptions:AllowSiteLogin", "true"));
Route route = new Route(PageState.Uri.AbsoluteUri, PageState.Alias.Path);
NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + WebUtility.UrlEncode(route.PathAndQuery)));
var returnurl = WebUtility.UrlEncode(route.PathAndQuery);
if (allowexternallogin && !allowsitelogin)
{
// external login
NavigationManager.NavigateTo(Utilities.TenantUrl(PageState.Alias, "/pages/external?returnurl=" + returnurl), true);
}
else
{
// local login
NavigationManager.NavigateTo(NavigateUrl("login", "?returnurl=" + returnurl));
}
}
protected async Task LogoutUser()

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>4.0.6</Version>
<TargetFramework>net8.0</TargetFramework>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MySql.EntityFrameworkCore" Version="7.0.2" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="7.0.5" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.MySQL</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane MySQL Provider</title>
@ -12,15 +12,15 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net7.0\Oqtane.Database.MySQL.dll" target="lib\net7.0" />
<file src="bin\net7.0\Oqtane.Database.MySQL.pdb" target="lib\net7.0" />
<file src="bin\net7.0\Mysql.EntityFrameworkCore.dll" target="lib\net7.0" />
<file src="bin\net7.0\Mysql.Data.dll" target="lib\net7.0" />
<file src="bin\net8.0\Oqtane.Database.MySQL.dll" target="lib\net8.0" />
<file src="bin\net8.0\Oqtane.Database.MySQL.pdb" target="lib\net8.0" />
<file src="bin\net8.0\Mysql.EntityFrameworkCore.dll" target="lib\net8.0" />
<file src="bin\net8.0\Mysql.Data.dll" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>4.0.6</Version>
<TargetFramework>net8.0</TargetFramework>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -30,8 +30,8 @@
<ItemGroup>
<PackageReference Include="EFCore.NamingConventions" Version="7.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.5" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="7.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.0-rc.2.23480.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0-rc.2" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.PostgreSQL</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane PostgreSQL Provider</title>
@ -12,16 +12,16 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net7.0\Oqtane.Database.PostgreSQL.dll" target="lib\net7.0" />
<file src="bin\net7.0\Oqtane.Database.PostgreSQL.pdb" target="lib\net7.0" />
<file src="bin\net7.0\EFCore.NamingConventions.dll" target="lib\net7.0" />
<file src="bin\net7.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll" target="lib\net7.0" />
<file src="bin\net7.0\Npgsql.dll" target="lib\net7.0" />
<file src="bin\net8.0\Oqtane.Database.PostgreSQL.dll" target="lib\net8.0" />
<file src="bin\net8.0\Oqtane.Database.PostgreSQL.pdb" target="lib\net8.0" />
<file src="bin\net8.0\EFCore.NamingConventions.dll" target="lib\net8.0" />
<file src="bin\net8.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll" target="lib\net8.0" />
<file src="bin\net8.0\Npgsql.dll" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>4.0.6</Version>
<TargetFramework>net8.0</TargetFramework>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.0-rc.2.23480.1" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.SqlServer</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane SQL Server Provider</title>
@ -12,14 +12,14 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net7.0\Oqtane.Database.SqlServer.dll" target="lib\net7.0" />
<file src="bin\net7.0\Oqtane.Database.SqlServer.pdb" target="lib\net7.0" />
<file src="bin\net7.0\Microsoft.EntityFrameworkCore.SqlServer.dll" target="lib\net7.0" />
<file src="bin\net8.0\Oqtane.Database.SqlServer.dll" target="lib\net8.0" />
<file src="bin\net8.0\Oqtane.Database.SqlServer.pdb" target="lib\net8.0" />
<file src="bin\net8.0\Microsoft.EntityFrameworkCore.SqlServer.dll" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Version>4.0.6</Version>
<TargetFramework>net8.0</TargetFramework>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
@ -29,7 +29,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.0-rc.2.23480.1" />
</ItemGroup>
<ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Database.Sqlite</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane SQLite Provider</title>
@ -12,14 +12,14 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="bin\net7.0\Oqtane.Database.Sqlite.dll" target="lib\net7.0" />
<file src="bin\net7.0\Oqtane.Database.Sqlite.pdb" target="lib\net7.0" />
<file src="bin\net7.0\Microsoft.EntityFrameworkCore.Sqlite.dll" target="lib\net7.0" />
<file src="bin\net8.0\Oqtane.Database.Sqlite.dll" target="lib\net8.0" />
<file src="bin\net8.0\Oqtane.Database.Sqlite.pdb" target="lib\net8.0" />
<file src="bin\net8.0\Microsoft.EntityFrameworkCore.Sqlite.dll" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net7.0-windows10.0.19041.0</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net8.0-windows10.0.19041.0</TargetFrameworks>
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
<!-- <TargetFrameworks>net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks> -->
<!-- <TargetFrameworks>$(TargetFrameworks);net7.0-tizen</TargetFrameworks> -->
<!-- <TargetFrameworks>net8.0-android;net8.0-ios;net8.0-maccatalyst</TargetFrameworks> -->
<!-- <TargetFrameworks>$(TargetFrameworks);net8.0-tizen</TargetFrameworks> -->
<OutputType>Exe</OutputType>
<Version>4.0.6</Version>
<Version>5.0.0</Version>
<Product>Oqtane</Product>
<Authors>Shaun Walker</Authors>
<Company>.NET Foundation</Company>
@ -14,7 +14,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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane.Maui</RootNamespace>
@ -31,7 +31,7 @@
<ApplicationIdGuid>0E29FC31-1B83-48ED-B6E0-9F3C67B775D4</ApplicationIdGuid>
<!-- Versions -->
<ApplicationDisplayVersion>4.0.6</ApplicationDisplayVersion>
<ApplicationDisplayVersion>5.0.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">14.2</SupportedOSPlatformVersion>
@ -65,20 +65,20 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.Extensions.Http" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0-rc.2.23479.6" />
</ItemGroup>
<ItemGroup>
<Reference Include="Oqtane.Client">
<HintPath>..\Oqtane.Server\bin\Debug\net7.0\Oqtane.Client.dll</HintPath>
<HintPath>..\Oqtane.Server\bin\Debug\net8.0\Oqtane.Client.dll</HintPath>
</Reference>
<Reference Include="Oqtane.Shared">
<HintPath>..\Oqtane.Server\bin\Debug\net7.0\Oqtane.Shared.dll</HintPath>
<HintPath>..\Oqtane.Server\bin\Debug\net8.0\Oqtane.Shared.dll</HintPath>
</Reference>
</ItemGroup>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Client</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,13 +12,13 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Client\bin\Release\net7.0\Oqtane.Client.dll" target="lib\net7.0" />
<file src="..\Oqtane.Client\bin\Release\net7.0\Oqtane.Client.pdb" target="lib\net7.0" />
<file src="..\Oqtane.Client\bin\Release\net8.0\Oqtane.Client.dll" target="lib\net8.0" />
<file src="..\Oqtane.Client\bin\Release\net8.0\Oqtane.Client.pdb" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Framework</id>
<version>4.0.6</version>
<version>5.0.0</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/v4.0.6/Oqtane.Framework.4.0.6.Upgrade.zip</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v4.0.6</releaseNotes>
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v5.0.0Oqtane.Framework.5.0.0.Upgrade.zip</projectUrl>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane framework</tags>
</metadata>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Server</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,13 +12,13 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Server\bin\Release\net7.0\Oqtane.Server.dll" target="lib\net7.0" />
<file src="..\Oqtane.Server\bin\Release\net7.0\Oqtane.Server.pdb" target="lib\net7.0" />
<file src="..\Oqtane.Server\bin\Release\net8.0\Oqtane.Server.dll" target="lib\net8.0" />
<file src="..\Oqtane.Server\bin\Release\net8.0\Oqtane.Server.pdb" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Shared</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,13 +12,13 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Shared\bin\Release\net7.0\Oqtane.Shared.dll" target="lib\net7.0" />
<file src="..\Oqtane.Shared\bin\Release\net7.0\Oqtane.Shared.pdb" target="lib\net7.0" />
<file src="..\Oqtane.Shared\bin\Release\net8.0\Oqtane.Shared.dll" target="lib\net8.0" />
<file src="..\Oqtane.Shared\bin\Release\net8.0\Oqtane.Shared.pdb" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Oqtane.Updater</id>
<version>4.0.6</version>
<version>5.0.0</version>
<authors>Shaun Walker</authors>
<owners>.NET Foundation</owners>
<title>Oqtane Framework</title>
@ -12,12 +12,12 @@
<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/v4.0.6</releaseNotes>
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</releaseNotes>
<icon>icon.png</icon>
<tags>oqtane</tags>
</metadata>
<files>
<file src="..\Oqtane.Updater\bin\Release\net7.0\publish\*.*" target="lib\net7.0" />
<file src="..\Oqtane.Updater\bin\Release\net8.0\publish\*.*" target="lib\net8.0" />
<file src="icon.png" target="" />
</files>
</package>

View File

@ -1 +1 @@
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.6.Install.zip" -Force
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.0.0.Install.zip" -Force

View File

@ -8,14 +8,14 @@ nuget.exe pack Oqtane.Client.nuspec
nuget.exe pack Oqtane.Server.nuspec
nuget.exe pack Oqtane.Shared.nuspec
nuget.exe pack Oqtane.Framework.nuspec
del /F/Q/S "..\Oqtane.Server\bin\Release\net7.0\publish" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net7.0\publish"
del /F/Q/S "..\Oqtane.Server\bin\Release\net8.0\publish" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net8.0\publish"
dotnet publish ..\Oqtane.Server\Oqtane.Server.csproj /p:Configuration=Release
del /F/Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Content"
del /F/Q/S "..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Content" > NUL
rmdir /Q/S "..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Content"
setlocal ENABLEDELAYEDEXPANSION
set retain=Oqtane.Modules.Admin.Login,Oqtane.Modules.HtmlText
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Modules\*") do (
for /D %%i in ("..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Modules\*") do (
set /A found=0
for %%j in (%retain%) do (
if "%%~nxi" == "%%j" set /A found=1
@ -23,18 +23,18 @@ if "%%~nxi" == "%%j" set /A found=1
if not !found! == 1 rmdir /Q/S "%%i"
)
set retain=Oqtane.Themes.BlazorTheme,Oqtane.Themes.OqtaneTheme
for /D %%i in ("..\Oqtane.Server\bin\Release\net7.0\publish\wwwroot\Themes\*") do (
for /D %%i in ("..\Oqtane.Server\bin\Release\net8.0\publish\wwwroot\Themes\*") do (
set /A found=0
for %%j in (%retain%) do (
if "%%~nxi" == "%%j" set /A found=1
)
if not !found! == 1 rmdir /Q/S "%%i"
)
del "..\Oqtane.Server\bin\Release\net7.0\publish\appsettings.json"
ren "..\Oqtane.Server\bin\Release\net7.0\publish\appsettings.release.json" "appsettings.json"
del "..\Oqtane.Server\bin\Release\net8.0\publish\appsettings.json"
ren "..\Oqtane.Server\bin\Release\net8.0\publish\appsettings.release.json" "appsettings.json"
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe ".\install.ps1"
del "..\Oqtane.Server\bin\Release\net7.0\publish\appsettings.json"
del "..\Oqtane.Server\bin\Release\net7.0\publish\web.config"
del "..\Oqtane.Server\bin\Release\net8.0\publish\appsettings.json"
del "..\Oqtane.Server\bin\Release\net8.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

View File

@ -1 +1 @@
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net7.0\publish\*" -DestinationPath "Oqtane.Framework.4.0.6.Upgrade.zip" -Force
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net8.0\publish\*" -DestinationPath "Oqtane.Framework.5.0.0.Upgrade.zip" -Force

View File

@ -350,9 +350,9 @@ namespace Oqtane.Controllers
if (moduleDefinition.Version == "local")
{
text = text.Replace("[FrameworkVersion]", Constants.Version);
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[ServerReference]", $"<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Server.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Shared.dll</HintPath></Reference>");
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[ServerReference]", $"<Reference Include=\"Oqtane.Server\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Server.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll</HintPath></Reference>");
}
else
{

View File

@ -179,7 +179,7 @@ namespace Oqtane.Controllers
[Authorize(Roles = RoleNames.Registered)]
public Notification Put(int id, [FromBody] Notification notification)
{
if (ModelState.IsValid && notification.SiteId == _alias.SiteId && _notifications.GetNotification(notification.NotificationId, false) != null && IsAuthorized(notification.FromUserId))
if (ModelState.IsValid && notification.SiteId == _alias.SiteId && _notifications.GetNotification(notification.NotificationId, false) != null && (IsAuthorized(notification.FromUserId) || IsAuthorized(notification.ToUserId)))
{
notification = _notifications.UpdateNotification(notification);
_syncManager.AddSyncEvent(_alias.TenantId, EntityNames.Notification, notification.NotificationId, SyncEventActions.Update);

View File

@ -237,8 +237,8 @@ namespace Oqtane.Controllers
if (theme.Version == "local")
{
text = text.Replace("[FrameworkVersion]", Constants.Version);
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net7.0\\Oqtane.Shared.dll</HintPath></Reference>");
text = text.Replace("[ClientReference]", $"<Reference Include=\"Oqtane.Client\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Client.dll</HintPath></Reference>");
text = text.Replace("[SharedReference]", $"<Reference Include=\"Oqtane.Shared\"><HintPath>..\\..\\{rootFolder}\\Oqtane.Server\\bin\\Debug\\net8.0\\Oqtane.Shared.dll</HintPath></Reference>");
}
else
{

View File

@ -298,6 +298,7 @@ namespace Oqtane.Extensions
if (identityuser != null)
{
user = _users.GetUser(identityuser.UserName);
user.SiteId = alias.SiteId;
}
else
{
@ -351,7 +352,7 @@ namespace Oqtane.Extensions
_notifications.AddNotification(notification);
// add user login
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType + ":" + alias.SiteId.ToString(), id, providerName));
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType + ":" + user.SiteId.ToString(), id, providerName));
_logger.Log(user.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "User Added {User}", user);
}
@ -380,18 +381,38 @@ namespace Oqtane.Extensions
var login = logins.FirstOrDefault(item => item.LoginProvider == (providerType + ":" + alias.SiteId.ToString()));
if (login == null)
{
// new external login using existing user account - verification required
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
string url = httpContext.Request.Scheme + "://" + alias.Name;
url += $"/login?name={identityuser.UserName}&token={WebUtility.UrlEncode(token)}&key={WebUtility.UrlEncode(id)}";
string body = $"You Recently Signed In To Our Site With {providerName} Using The Email Address {email}. ";
body += "In Order To Complete The Linkage Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!";
var notification = new Notification(alias.SiteId, email, email, "External Login Linkage", body);
_notifications.AddNotification(notification);
if (bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:VerifyUsers", "true")))
{
// external login using existing user account - verification required
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
string token = await _identityUserManager.GenerateEmailConfirmationTokenAsync(identityuser);
string url = httpContext.Request.Scheme + "://" + alias.Name;
url += $"/login?name={identityuser.UserName}&token={WebUtility.UrlEncode(token)}&key={WebUtility.UrlEncode(id)}";
string body = $"You Recently Signed In To Our Site With {providerName} Using The Email Address {email}. ";
body += "In Order To Complete The Linkage Of Your User Account Please Click The Link Displayed Below:\n\n" + url + "\n\nThank You!";
var notification = new Notification(alias.SiteId, email, email, "External Login Linkage", body);
_notifications.AddNotification(notification);
identity.Label = ExternalLoginStatus.VerificationRequired;
_logger.Log(alias.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Verification For Provider {Provider} Sent To {Email}", providerName, email);
identity.Label = ExternalLoginStatus.VerificationRequired;
_logger.Log(alias.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Verification For Provider {Provider} Sent To {Email}", providerName, email);
}
else
{
// external login using existing user account - link automatically
user = _users.GetUser(identityuser.UserName);
user.SiteId = alias.SiteId;
var _notifications = httpContext.RequestServices.GetRequiredService<INotificationRepository>();
string url = httpContext.Request.Scheme + "://" + alias.Name;
string body = "You Recently Used An External Account To Sign In To Our Site.\n\n" + url + "\n\nThank You!";
var notification = new Notification(user.SiteId, user, "User Account Notification", body);
_notifications.AddNotification(notification);
// add user login
await _identityUserManager.AddLoginAsync(identityuser, new UserLoginInfo(providerType + ":" + user.SiteId.ToString(), id, providerName));
_logger.Log(user.SiteId, LogLevel.Information, "ExternalLogin", Enums.LogFunction.Create, "External Login Linkage Created For User {Username} And Provider {Provider}", user.Username, providerName);
}
}
else
{

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Version>4.0.6</Version>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
@ -32,20 +32,20 @@
<EmbeddedResource Include="Scripts\MigrateTenant.sql" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.1" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.5">
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.0-preview3.23201.1" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="8.0.0-rc.2.23480.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0-rc.2.23480.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.0-rc.2.23480.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.0" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.4" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.6" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="8.0.0-rc.2.23480.2" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" />

View File

@ -3,6 +3,7 @@ using System.IO;
using System.Net;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
@ -96,7 +97,7 @@ namespace Oqtane.Pages
}
else
{
HttpContext.Response.Headers.Add(HeaderNames.ETag, etag);
HttpContext.Response.Headers.Append(HeaderNames.ETag, etag);
return PhysicalFile(filepath, file.GetMimeType());
}
}

View File

@ -224,21 +224,21 @@ namespace Oqtane.Repository
_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 = ""});
{ 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 = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{SiteId = site.SiteId, Name = "LastName", Title = "Last Name", Description = "Your Last Or Family Name", Category = "Name", ViewOrder = 2, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
{ SiteId = site.SiteId, Name = "LastName", Title = "Last Name", Description = "Your Last Or Family Name", Category = "Name", ViewOrder = 2, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{SiteId = site.SiteId, Name = "Street", Title = "Street", Description = "Street Or Building Address", Category = "Address", ViewOrder = 3, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
_profileRepository.AddProfile(
new Profile {SiteId = site.SiteId, Name = "City", Title = "City", Description = "City", Category = "Address", ViewOrder = 4, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
{ SiteId = site.SiteId, Name = "Street", Title = "Street", Description = "Street Or Building Address", Category = "Address", ViewOrder = 3, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{ SiteId = site.SiteId, Name = "City", Title = "City", Description = "City", Category = "Address", ViewOrder = 4, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{SiteId = site.SiteId, Name = "Region", Title = "Region", Description = "State Or Province", Category = "Address", ViewOrder = 5, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
{ SiteId = site.SiteId, Name = "Region", Title = "Region", Description = "State Or Province", Category = "Address", ViewOrder = 5, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{SiteId = site.SiteId, Name = "Country", Title = "Country", Description = "Country", Category = "Address", ViewOrder = 6, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
{ SiteId = site.SiteId, Name = "Country", Title = "Country", Description = "Country", Category = "Address", ViewOrder = 6, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{SiteId = site.SiteId, Name = "PostalCode", Title = "Postal Code", Description = "Postal Code Or Zip Code", Category = "Address", ViewOrder = 7, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
{ SiteId = site.SiteId, Name = "PostalCode", Title = "Postal Code", Description = "Postal Code Or Zip Code", Category = "Address", ViewOrder = 7, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
_profileRepository.AddProfile(new Profile
{SiteId = site.SiteId, Name = "Phone", Title = "Phone Number", Description = "Phone Number", Category = "Contact", ViewOrder = 8, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "" });
{ SiteId = site.SiteId, Name = "Phone", Title = "Phone Number", Description = "Phone Number", Category = "Contact", ViewOrder = 8, MaxLength = 50, DefaultValue = "", IsRequired = false, IsPrivate = false, Options = "", Rows = 1 });
Folder folder = _folderRepository.AddFolder(new Folder
{

View File

@ -1,7 +1,7 @@
{
"Runtime": "Server",
"RenderMode": "ServerPrerendered",
"Database": {
"Database": {
"DefaultDBType": ""
},
"ConnectionStrings": {
@ -44,5 +44,15 @@
"ControlType": "Oqtane.Installer.Controls.PostgreSQLConfig, Oqtane.Client",
"DBType": "Oqtane.Database.PostgreSQL.PostgreSQLDatabase, Oqtane.Database.PostgreSQL"
}
]
],
"Logging": {
"FileLogger": {
"LogLevel": {
"Default": "Error"
}
},
"LogLevel": {
"Default": "Information"
}
}
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Version>1.0.0</Version>
<Authors>[Owner]</Authors>
<Company>[Owner]</Company>
@ -13,11 +13,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-rc.2.23480.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.2.0" />
</ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>

View File

@ -20,13 +20,13 @@
</dependencies>
</metadata>
<files>
<file src="..\Client\bin\Release\net7.0\[Owner].Module.[Module].Client.Oqtane.dll" target="lib\net7.0" />
<file src="..\Client\bin\Release\net7.0\[Owner].Module.[Module].Client.Oqtane.pdb" target="lib\net7.0" />
<file src="..\Server\bin\Release\net7.0\[Owner].Module.[Module].Server.Oqtane.dll" target="lib\net7.0" />
<file src="..\Server\bin\Release\net7.0\[Owner].Module.[Module].Server.Oqtane.pdb" target="lib\net7.0" />
<file src="..\Shared\bin\Release\net7.0\[Owner].Module.[Module].Shared.Oqtane.dll" target="lib\net7.0" />
<file src="..\Shared\bin\Release\net7.0\[Owner].Module.[Module].Shared.Oqtane.pdb" target="lib\net7.0" />
<file src="..\Client\bin\Release\net8.0\[Owner].Module.[Module].Client.Oqtane.dll" target="lib\net8.0" />
<file src="..\Client\bin\Release\net8.0\[Owner].Module.[Module].Client.Oqtane.pdb" target="lib\net8.0" />
<file src="..\Server\bin\Release\net8.0\[Owner].Module.[Module].Server.Oqtane.dll" target="lib\net8.0" />
<file src="..\Server\bin\Release\net8.0\[Owner].Module.[Module].Server.Oqtane.pdb" target="lib\net8.0" />
<file src="..\Shared\bin\Release\net8.0\[Owner].Module.[Module].Shared.Oqtane.dll" target="lib\net8.0" />
<file src="..\Shared\bin\Release\net8.0\[Owner].Module.[Module].Shared.Oqtane.pdb" target="lib\net8.0" />
<file src="..\Server\wwwroot\**\*.*" target="wwwroot" />
<file src="icon.png" target="" />
</files>
</package>
</package>

View File

@ -1,7 +1,7 @@
XCOPY "..\Client\bin\Debug\net7.0\[Owner].Module.[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Client\bin\Debug\net7.0\[Owner].Module.[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Server\bin\Debug\net7.0\[Owner].Module.[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Server\bin\Debug\net7.0\[Owner].Module.[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Shared\bin\Debug\net7.0\[Owner].Module.[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Shared\bin\Debug\net7.0\[Owner].Module.[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Client\bin\Debug\net8.0\[Owner].Module.[Module].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Client\bin\Debug\net8.0\[Owner].Module.[Module].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Server\bin\Debug\net8.0\[Owner].Module.[Module].Server.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Server\bin\Debug\net8.0\[Owner].Module.[Module].Server.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Shared\bin\Debug\net8.0\[Owner].Module.[Module].Shared.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Shared\bin\Debug\net8.0\[Owner].Module.[Module].Shared.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Server\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I

View File

@ -1,7 +1,7 @@
cp -f "../Client/bin/Debug/net7.0/[Owner].Module.[Module].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -f "../Client/bin/Debug/net7.0/[Owner].Module.[Module].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -f "../Server/bin/Debug/net7.0/[Owner].Module.[Module].Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -f "../Server/bin/Debug/net7.0/[Owner].Module.[Module].Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -f "../Shared/bin/Debug/net7.0/[Owner].Module.[Module].Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -f "../Shared/bin/Debug/net7.0/[Owner].Module.[Module].Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/"
cp -f "../Client/bin/Debug/net8.0/[Owner].Module.[Module].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -f "../Client/bin/Debug/net8.0/[Owner].Module.[Module].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -f "../Server/bin/Debug/net8.0/[Owner].Module.[Module].Server.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -f "../Server/bin/Debug/net8.0/[Owner].Module.[Module].Server.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -f "../Shared/bin/Debug/net8.0/[Owner].Module.[Module].Shared.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -f "../Shared/bin/Debug/net8.0/[Owner].Module.[Module].Shared.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/"

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
<Version>1.0.0</Version>
<Product>[Owner].Module.[Module]</Product>
@ -19,10 +19,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0-rc.2.23480.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-rc.2.23480.2" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Version>1.0.0</Version>
<Product>[Owner].Module.[Module]</Product>
<Authors>[Owner]</Authors>

View File

@ -1,6 +1,6 @@
{
"Title": "Default Module Template",
"Type": "External",
"Version": "4.0.3",
"Version": "5.0.0",
"Namespace": "[Owner].Module.[Module]"
}

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Version>1.0.0</Version>
<Authors>[Owner]</Authors>
<Company>[Owner]</Company>
@ -12,11 +12,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.5" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.5" />
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-rc.2.23480.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.0-rc.2.23480.2" />
<PackageReference Include="System.Net.Http.Json" Version="8.0.0-rc.2.23479.6" />
</ItemGroup>
<ItemGroup>

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
</PropertyGroup>

View File

@ -20,9 +20,9 @@
</dependencies>
</metadata>
<files>
<file src="..\Client\bin\Release\net7.0\[Owner].Theme.[Theme].Client.Oqtane.dll" target="lib\net7.0" />
<file src="..\Client\bin\Release\net7.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" target="lib\net7.0" />
<file src="..\Client\bin\Release\net8.0\[Owner].Theme.[Theme].Client.Oqtane.dll" target="lib\net8.0" />
<file src="..\Client\bin\Release\net8.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" target="lib\net8.0" />
<file src="..\Client\wwwroot\**\*.*" target="wwwroot" />
<file src="icon.png" target="" />
</files>
</package>
</package>

View File

@ -1,3 +1,3 @@
XCOPY "..\Client\bin\Debug\net7.0\[Owner].Theme.[Theme].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Client\bin\Debug\net7.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net7.0\" /Y
XCOPY "..\Client\bin\Debug\net8.0\[Owner].Theme.[Theme].Client.Oqtane.dll" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Client\bin\Debug\net8.0\[Owner].Theme.[Theme].Client.Oqtane.pdb" "..\..\[RootFolder]\Oqtane.Server\bin\Debug\net8.0\" /Y
XCOPY "..\Client\wwwroot\*" "..\..\[RootFolder]\Oqtane.Server\wwwroot\" /Y /S /I

View File

@ -1,3 +1,3 @@
cp -f "../Client/bin/Debug/net7.0/[Owner].Theme.[Theme].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -f "../Client/bin/Debug/net7.0/[Owner].Theme.[Theme].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net7.0/"
cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/"
cp -f "../Client/bin/Debug/net8.0/[Owner].Theme.[Theme].Client.Oqtane.dll" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -f "../Client/bin/Debug/net8.0/[Owner].Theme.[Theme].Client.Oqtane.pdb" "../../oqtane.framework/Oqtane.Server/bin/Debug/net8.0/"
cp -rf "../Server/wwwroot/"* "../../oqtane.framework/Oqtane.Server/wwwroot/"

View File

@ -1,6 +1,6 @@
{
"Title": "Default Theme Template",
"Type": "External",
"Version": "4.0.3",
"Version": "5.0.0",
"Namespace": "[Owner].Theme.[Theme]"
}

View File

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<Configurations>Debug;Release</Configurations>
<Version>4.0.6</Version>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>
@ -19,11 +19,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="7.0.5" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0-rc.2.23480.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.0-rc.2.23480.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0-rc.2.23479.6" />
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.2" />
<PackageReference Include="System.Text.Json" Version="8.0.0-rc.2.23479.6" />
</ItemGroup>
</Project>

View File

@ -7,8 +7,8 @@ namespace Oqtane.Shared
{
public class Constants
{
public static readonly string Version = "4.0.6";
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6";
public static readonly string Version = "5.0.0";
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,3.1.3,3.1.4,3.2.0,3.2.1,3.3.0,3.3.1,3.4.0,3.4.1,3.4.2,3.4.3,4.0.0,4.0.1,4.0.2,4.0.3,4.0.4,4.0.5,4.0.6,5.0.0";
public const string PackageId = "Oqtane.Framework";
public const string ClientId = "Oqtane.Client";
public const string UpdaterPackageId = "Oqtane.Updater";

View File

@ -1,9 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<Version>4.0.6</Version>
<Version>5.0.0</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/v4.0.6</PackageReleaseNotes>
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v5.0.0</PackageReleaseNotes>
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
<RepositoryType>Git</RepositoryType>
<RootNamespace>Oqtane</RootNamespace>