Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
89a166ea9b | |||
391827222e | |||
c1721bd1a1 | |||
f6630ae241 | |||
424cab64a8 |
2
.deployment
Normal file
2
.deployment
Normal file
@ -0,0 +1,2 @@
|
||||
[config]
|
||||
project = Oqtane.Server/Oqtane.Server.csproj
|
25
.gitea/workflows/build-container.yml
Normal file
25
.gitea/workflows/build-container.yml
Normal file
@ -0,0 +1,25 @@
|
||||
name: build-docker-imge
|
||||
on:
|
||||
- push
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build the docker container
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "Git clone"
|
||||
run: git clone ${{ gitea.server_url }}/${{ gitea.repository }}.git .
|
||||
- name: "Git checkout"
|
||||
run: git checkout "${{ gitea.sha }}"
|
||||
- uses: aevea/action-kaniko@master
|
||||
name: Run Kaniko to build our api docker container.
|
||||
with:
|
||||
image: kocoded/oqtane.framework
|
||||
tag: ${{ git.workflow_sha }}
|
||||
tag_with_latest: github.ref == 'refs/heads/master'
|
||||
registry: git.kocoder.xyz
|
||||
username: ${{ secrets.CI_RUNNER_USER }}
|
||||
password: ${{ secrets.CI_RUNNER_TOKEN }}
|
||||
build_file: Dockerfile
|
||||
target: deploy
|
||||
|
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@ -0,0 +1,24 @@
|
||||
# Build
|
||||
FROM mcr.microsoft.com/dotnet/sdk:9.0 AS build
|
||||
|
||||
WORKDIR /source
|
||||
|
||||
COPY --link . .
|
||||
|
||||
RUN dotnet restore /source/Oqtane.sln
|
||||
|
||||
RUN dotnet build "/source/Oqtane.sln" -c Release -o /source/build/
|
||||
|
||||
# Publish
|
||||
FROM build AS publish
|
||||
|
||||
RUN dotnet publish "Oqtane.Server/Oqtane.Server.csproj" -c Release -o /source/publish/
|
||||
|
||||
# Deploy
|
||||
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS deploy
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
||||
COPY --from=publish /source/publish/ /app/
|
||||
ENTRYPOINT ["dotnet", "Oqtane.Server.dll"]
|
@ -1,119 +0,0 @@
|
||||
@namespace Oqtane.Installer.Controls
|
||||
@implements Oqtane.Interfaces.IDatabaseConfigControl
|
||||
@inject IStringLocalizer<SqlServerConfig> Localizer
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="server" HelpText="Enter the database server name. This might include a port number as well if you are using a cloud service." ResourceKey="Server">Server:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="server" type="text" class="form-control" @bind="@_server" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="database" HelpText="Enter the name of the database" ResourceKey="Database">Database:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="database" type="text" class="form-control" @bind="@_database" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="security" HelpText="Select your security method" ResourceKey="Security">Security:</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="security" class="form-select custom-select" @bind="@_security">
|
||||
<option value="integrated" selected>@Localizer["Integrated"]</option>
|
||||
<option value="custom">@Localizer["Custom"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@if (_security == "custom")
|
||||
{
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="uid" HelpText="Enter the username to use for the database" ResourceKey="Uid">User Id:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="uid" type="text" class="form-control" @bind="@_uid" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="pwd" HelpText="Enter the password to use for the database" ResourceKey="Pwd">Password:</Label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<input id="pwd" type="@_passwordType" class="form-control" @bind="@_pwd" autocomplete="new-password" />
|
||||
<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="encryption" HelpText="Specify if you are using an encrypted database connection. It is highly recommended to use encryption in a production environment." ResourceKey="Encryption">Encryption:</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="encryption" class="form-select custom-select" @bind="@_encryption">
|
||||
<option value="true">@SharedLocalizer["True"]</option>
|
||||
<option value="false">@SharedLocalizer["False"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@if (_encryption == "true")
|
||||
{
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="trustservercertificate" HelpText="Specify the type of certificate you are using for encryption. Verifiable is equivalent to False. Self Signed is equivalent to True." ResourceKey="TrustServerCertificate">Certificate:</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="encryption" class="form-select custom-select" @bind="@_trustservercertificate">
|
||||
<option value="true">@Localizer["Self Signed"]</option>
|
||||
<option value="false">@Localizer["Verifiable"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code {
|
||||
private string _server = "tcp:{SQL Server Name}.database.windows.net,1433";
|
||||
private string _database = "{SQL Database Name}";
|
||||
private string _security = "custom";
|
||||
private string _uid = "{SQL Administrator Login}";
|
||||
private string _pwd = String.Empty;
|
||||
private string _passwordType = "password";
|
||||
private string _togglePassword = string.Empty;
|
||||
private string _encryption = "true";
|
||||
private string _trustservercertificate = "false";
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||
}
|
||||
|
||||
public string GetConnectionString()
|
||||
{
|
||||
var connectionString = String.Empty;
|
||||
|
||||
if (!String.IsNullOrEmpty(_server) && !String.IsNullOrEmpty(_database))
|
||||
{
|
||||
connectionString = $"Data Source={_server};Initial Catalog={_database};";
|
||||
}
|
||||
|
||||
if (_security == "integrated")
|
||||
{
|
||||
connectionString += "Integrated Security=SSPI;";
|
||||
}
|
||||
else
|
||||
{
|
||||
connectionString += $"User ID={_uid};Password={_pwd};";
|
||||
}
|
||||
connectionString += $"Encrypt={_encryption};";
|
||||
connectionString += $"TrustServerCertificate={_trustservercertificate};";
|
||||
|
||||
return connectionString;
|
||||
}
|
||||
|
||||
private void TogglePassword()
|
||||
{
|
||||
if (_passwordType == "password")
|
||||
{
|
||||
_passwordType = "text";
|
||||
_togglePassword = SharedLocalizer["HidePassword"];
|
||||
}
|
||||
else
|
||||
{
|
||||
_passwordType = "password";
|
||||
_togglePassword = SharedLocalizer["ShowPassword"];
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
@inject IStringLocalizer<SharedResources> SharedLocalizer
|
||||
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="server" HelpText="Enter the database server name. This might include a port number as well if you are using a cloud service." ResourceKey="Server">Server:</Label>
|
||||
<Label Class="col-sm-3" For="server" HelpText="Enter the database server name. This might include a port number as well if you are using a cloud service (ie. servername.database.windows.net,1433) " ResourceKey="Server">Server:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="server" type="text" class="form-control" @bind="@_server" />
|
||||
</div>
|
||||
|
@ -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 @Environment.Version.Major)</div>
|
||||
<div style="font-weight: bold">@SharedLocalizer["Version"] @Constants.Version (.NET 9)</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="app-rule" />
|
||||
|
@ -45,7 +45,7 @@
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="retention" HelpText="Number of log entries to retain for this job" ResourceKey="RetentionLog">Retention Log (Items): </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="retention" type="number" min="0" step ="1" class="form-control" @bind="@_retentionHistory" maxlength="3" required />
|
||||
<input id="retention" type="number" min="0" step ="1" class="form-control" @bind="@_retentionHistory" maxlength="4" required />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
|
@ -44,12 +44,14 @@ else
|
||||
|
||||
private async Task GetJobLogs()
|
||||
{
|
||||
var jobId = -1;
|
||||
_jobLogs = await JobLogService.GetJobLogsAsync();
|
||||
|
||||
if (PageState.QueryString.ContainsKey("id"))
|
||||
{
|
||||
jobId = int.Parse(PageState.QueryString["id"]);
|
||||
_jobLogs = _jobLogs.Where(item => item.JobId == Int32.Parse(PageState.QueryString["id"])).ToList();
|
||||
}
|
||||
_jobLogs = await JobLogService.GetJobLogsAsync(jobId);
|
||||
|
||||
_jobLogs = _jobLogs.OrderByDescending(item => item.JobLogId).ToList();
|
||||
}
|
||||
|
||||
private string DisplayStatus(bool isExecuting, bool? succeeded)
|
||||
|
@ -73,7 +73,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="url" HelpText="The url of the module" ResourceKey="Url">Url: </Label>
|
||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the module" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</div>
|
||||
|
@ -13,32 +13,32 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="col-sm-6">
|
||||
<ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" />
|
||||
<ActionLink Action="Create" Text="Create Module" ResourceKey="CreateModule" Class="btn btn-secondary ps-2" />
|
||||
<button type="button" class="btn btn-secondary pw-2" @onclick="@Synchronize">@Localizer["Synchronize"]</button>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" @onchange="(e => CategoryChanged(e))">
|
||||
@foreach (var category in _categories)
|
||||
{
|
||||
if (category == _category)
|
||||
{
|
||||
<option value="@category" selected>@category @Localizer["Modules"]</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@category">@category @Localizer["Modules"]</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Pager Items="@_moduleDefinitions">
|
||||
<div class="container">
|
||||
<div class="row mb-3 align-items-center">
|
||||
<div class="col-sm-6">
|
||||
<ActionLink Action="Add" Text="Install Module" ResourceKey="InstallModule" />
|
||||
@((MarkupString)" ")
|
||||
<ActionLink Action="Create" Text="Create Module" ResourceKey="CreateModule" Class="btn btn-secondary" />
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<select class="form-select" @onchange="(e => CategoryChanged(e))">
|
||||
@foreach (var category in _categories)
|
||||
{
|
||||
if (category == _category)
|
||||
{
|
||||
<option value="@category" selected>@category @Localizer["Modules"]</option>
|
||||
}
|
||||
else
|
||||
{
|
||||
<option value="@category">@category @Localizer["Modules"]</option>
|
||||
}
|
||||
}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Pager Items="@_moduleDefinitions">
|
||||
<Header>
|
||||
<th style="width: 1px;"> </th>
|
||||
<th style="width: 1px;"> </th>
|
||||
@ -61,17 +61,17 @@ else
|
||||
<td>@context.Name</td>
|
||||
<td>@context.Version</td>
|
||||
<td>
|
||||
@if (context.IsEnabled)
|
||||
{
|
||||
<span>@SharedLocalizer["Yes"]</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@SharedLocalizer["No"]</span>
|
||||
}
|
||||
@if (context.IsEnabled)
|
||||
{
|
||||
<span>@SharedLocalizer["Yes"]</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
<span>@SharedLocalizer["No"]</span>
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (context.AssemblyName == Constants.ClientId || _modules.Where(m => m.ModuleDefinition?.ModuleDefinitionId == context.ModuleDefinitionId).FirstOrDefault() != null)
|
||||
@if (context.AssemblyName == Constants.ClientId || _modules.Where(m => m.ModuleDefinition?.ModuleDefinitionId == context.ModuleDefinitionId).FirstOrDefault() != null)
|
||||
{
|
||||
<span>@SharedLocalizer["Yes"]</span>
|
||||
}
|
||||
@ -87,9 +87,9 @@ else
|
||||
@((MarkupString)PurchaseLink(context.PackageName))
|
||||
</td>
|
||||
<td>
|
||||
@{
|
||||
var version = UpgradeAvailable(context.PackageName, context.Version);
|
||||
}
|
||||
@{
|
||||
var version = UpgradeAvailable(context.PackageName, context.Version);
|
||||
}
|
||||
@if (version != context.Version)
|
||||
{
|
||||
<button type="button" class="btn btn-success" @onclick=@(async () => await DownloadModule(context.PackageName, version))>@SharedLocalizer["Upgrade"]</button>
|
||||
@ -153,10 +153,10 @@ else
|
||||
link = "<a class=\"btn btn-primary\" style=\"text-decoration: none !important\" href=\"" + package.PaymentUrl + "\" target=\"_new\">" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "</a>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return link;
|
||||
}
|
||||
}
|
||||
}
|
||||
return link;
|
||||
}
|
||||
|
||||
private string SupportLink(string packagename, string version)
|
||||
{
|
||||
@ -172,75 +172,52 @@ else
|
||||
return link;
|
||||
}
|
||||
|
||||
private string UpgradeAvailable(string packagename, string version)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
||||
{
|
||||
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
||||
if (package != null && Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0)
|
||||
{
|
||||
return package.Version;
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
private string UpgradeAvailable(string packagename, string version)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(packagename) && _packages != null)
|
||||
{
|
||||
var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
|
||||
if (package != null && Version.Parse(package.Version).CompareTo(Version.Parse(version)) > 0)
|
||||
{
|
||||
return package.Version;
|
||||
}
|
||||
}
|
||||
return version;
|
||||
}
|
||||
|
||||
private async Task DownloadModule(string packagename, string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(packagename, version);
|
||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version} {Error}", packagename, version, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Download"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
private async Task DownloadModule(string packagename, string version)
|
||||
{
|
||||
try
|
||||
{
|
||||
await PackageService.DownloadPackageAsync(packagename, version);
|
||||
await logger.LogInformation("Module Downloaded {ModuleDefinitionName} {Version}", packagename, version);
|
||||
AddModuleMessage(string.Format(Localizer["Success.Module.Install"], NavigateUrl("admin/system")), MessageType.Success);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Downloading Module {ModuleDefinitionName} {Version} {Error}", packagename, version, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Download"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task DeleteModule(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||
AddModuleMessage(Localizer["Success.Module.Delete"], MessageType.Success);
|
||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Module {ModuleDefinition} {Error}", moduleDefinition, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
private async Task DeleteModule(ModuleDefinition moduleDefinition)
|
||||
{
|
||||
try
|
||||
{
|
||||
await ModuleDefinitionService.DeleteModuleDefinitionAsync(moduleDefinition.ModuleDefinitionId, moduleDefinition.SiteId);
|
||||
AddModuleMessage(Localizer["Success.Module.Delete"], MessageType.Success);
|
||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Deleting Module {ModuleDefinition} {Error}", moduleDefinition, ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Delete"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CategoryChanged(ChangeEventArgs e)
|
||||
{
|
||||
_category = (string)e.Value;
|
||||
private async Task CategoryChanged(ChangeEventArgs e)
|
||||
{
|
||||
_category = (string)e.Value;
|
||||
await LoadModuleDefinitions();
|
||||
}
|
||||
|
||||
private async Task Synchronize()
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
foreach (var moduleDefinition in _moduleDefinitions)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(moduleDefinition.PackageName) && !_packages.Any(item => item.PackageId == moduleDefinition.PackageName))
|
||||
{
|
||||
var package = await PackageService.GetPackageAsync(moduleDefinition.PackageName, moduleDefinition.Version, false);
|
||||
}
|
||||
}
|
||||
HideProgressIndicator();
|
||||
AddModuleMessage(Localizer["Success.Module.Synchronize"], MessageType.Success);
|
||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Synchronizing Modules {Error}", ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Module.Synchronize"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,19 @@
|
||||
<input id="displayname" class="form-control" @bind="@_displayname" maxlength="50" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="subject" HelpText="Deine Studien- oder Ausbildungsrichtung" ResourceKey="Subject">Fachrichtung:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="subject" class="form-control" @bind="@_subject" maxlength="100" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="graduationYear" HelpText="Dein voraussichtlicher Abschlussjahrgang" ResourceKey="GraduationYear">Abschlussjahrgang:</Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="graduationYear" type="number" class="form-control" @bind="@_graduationYear" min="1950" max="2100" step="1" required />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<br />
|
||||
<button type="button" class="btn btn-primary" @onclick="Register">@Localizer["Register"]</button>
|
||||
@ -89,6 +102,9 @@ else
|
||||
private string _displayname = string.Empty;
|
||||
private bool _userCreated = false;
|
||||
private bool _allowsitelogin = true;
|
||||
private string _subject = string.Empty;
|
||||
private int _graduationYear;
|
||||
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Anonymous;
|
||||
|
||||
@ -124,7 +140,10 @@ else
|
||||
Password = _password,
|
||||
Email = _email,
|
||||
DisplayName = (_displayname == string.Empty ? _username : _displayname),
|
||||
PhotoFileId = null
|
||||
PhotoFileId = null,
|
||||
Subject = _subject,
|
||||
GraduationYear = _graduationYear
|
||||
|
||||
};
|
||||
user = await UserService.AddUserAsync(user);
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="url" HelpText="The url of the theme" ResourceKey="Url">Url: </Label>
|
||||
<Label Class="col-sm-3" For="url" HelpText="The reference url of the theme" ResourceKey="ReferenceUrl">Reference Url: </Label>
|
||||
<div class="col-sm-9">
|
||||
<input id="url" class="form-control" @bind="@_url" disabled />
|
||||
</div>
|
||||
|
@ -15,8 +15,8 @@
|
||||
else
|
||||
{
|
||||
<ActionLink Action="Add" Text="Install Theme" ResourceKey="InstallTheme" />
|
||||
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" Class="btn btn-secondary ps-2" />
|
||||
<button type="button" class="btn btn-secondary pw-2" @onclick="@Synchronize">@Localizer["Synchronize"]</button>
|
||||
@((MarkupString)" ")
|
||||
<ActionLink Action="Create" Text="Create Theme" ResourceKey="CreateTheme" Class="btn btn-secondary" />
|
||||
|
||||
<Pager Items="@_themes">
|
||||
<Header>
|
||||
@ -173,27 +173,4 @@ else
|
||||
AddModuleMessage(Localizer["Error.Theme.Delete"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Synchronize()
|
||||
{
|
||||
try
|
||||
{
|
||||
ShowProgressIndicator();
|
||||
foreach (var theme in _themes)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(theme.PackageName) && !_packages.Any(item => item.PackageId == theme.PackageName))
|
||||
{
|
||||
await PackageService.GetPackageAsync(theme.PackageName, theme.Version, false);
|
||||
}
|
||||
}
|
||||
HideProgressIndicator();
|
||||
AddModuleMessage(Localizer["Success.Theme.Synchronize"], MessageType.Success);
|
||||
NavigationManager.NavigateTo(NavigateUrl(PageState.Page.Path, true));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await logger.LogError(ex, "Error Synchronizing Themes {Error}", ex.Message);
|
||||
AddModuleMessage(Localizer["Error.Theme.Synchronize"], MessageType.Error);
|
||||
}
|
||||
}
|
||||
}
|
@ -13,21 +13,9 @@
|
||||
<TabPanel Name="Download" ResourceKey="Download">
|
||||
@if (_package != null && _upgradeavailable)
|
||||
{
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" HelpText="Specify if you want to backup files during the upgrade process. Disabling this option will result in a better experience in some environments." ResourceKey="Backup">Backup Files? </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="backup" class="form-select" @bind="@_backup">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
<option value="False">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ModuleMessage Type="MessageType.Info" Message="Select The Download Button To Download The Framework Upgrade Package And Then Select Upgrade"></ModuleMessage>
|
||||
<button type="button" class="btn btn-primary" @onclick=@(async () => await Download(Constants.PackageId, @_package.Version))>@SharedLocalizer["Download"] @_package.Version</button>
|
||||
<button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
|
||||
<br /><br />
|
||||
<ModuleMessage Type="MessageType.Info" Message="Select The Download Button To Download The Framework Upgrade Package And Then Select Upgrade"></ModuleMessage>
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -35,6 +23,7 @@
|
||||
}
|
||||
</TabPanel>
|
||||
<TabPanel Name="Upload" ResourceKey="Upload">
|
||||
<ModuleMessage Type="MessageType.Info" Message=@Localizer["MessageUpgrade.Text"]></ModuleMessage>
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" HelpText="Upload A Framework Package And Then Select Upgrade" ResourceKey="Framework">Framework: </Label>
|
||||
@ -42,19 +31,8 @@
|
||||
<FileManager Folder="@Constants.PackagesFolder" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" HelpText="Specify if you want to backup files during the upgrade process. Disabling this option will result in a better experience in some environments." ResourceKey="Backup">Backup Files? </Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="backup" class="form-select" @bind="@_backup">
|
||||
<option value="True">@SharedLocalizer["Yes"]</option>
|
||||
<option value="False">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="btn btn-success" @onclick="Upgrade">@SharedLocalizer["Upgrade"]</button>
|
||||
<br /><br />
|
||||
<ModuleMessage Type="MessageType.Info" Message=@Localizer["MessageUpgrade.Text"]></ModuleMessage>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
}
|
||||
@ -63,7 +41,6 @@
|
||||
private bool _initialized = false;
|
||||
private Package _package;
|
||||
private bool _upgradeavailable = false;
|
||||
private string _backup = "True";
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Host;
|
||||
|
||||
@ -109,7 +86,7 @@
|
||||
ShowProgressIndicator();
|
||||
var interop = new Interop(JSRuntime);
|
||||
await interop.RedirectBrowser(NavigateUrl(), 10);
|
||||
await InstallationService.Upgrade(bool.Parse(_backup));
|
||||
await InstallationService.Upgrade();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
@ -421,18 +421,6 @@ else
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@if (UserSecurity.IsAuthorized(PageState.User, RoleNames.Host))
|
||||
{
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="allowhostrole" HelpText="Indicate if host roles are supported from the identity provider. Please use caution with this option as it allows the host user to administrate every site within your installation." ResourceKey="AllowHostRole">Allow Host Role?</Label>
|
||||
<div class="col-sm-9">
|
||||
<select id="allowhostrole" class="form-select" @bind="@_allowhostrole" required>
|
||||
<option value="true">@SharedLocalizer["Yes"]</option>
|
||||
<option value="false">@SharedLocalizer["No"]</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</Section>
|
||||
<Section Name="Token" Heading="Token Settings" ResourceKey="TokenSettings">
|
||||
@ -532,7 +520,6 @@ else
|
||||
private string _domainfilter;
|
||||
private string _createusers;
|
||||
private string _verifyusers;
|
||||
private string _allowhostrole;
|
||||
|
||||
private string _secret;
|
||||
private string _secrettype = "password";
|
||||
@ -615,7 +602,6 @@ else
|
||||
_domainfilter = SettingService.GetSetting(settings, "ExternalLogin:DomainFilter", "");
|
||||
_createusers = SettingService.GetSetting(settings, "ExternalLogin:CreateUsers", "true");
|
||||
_verifyusers = SettingService.GetSetting(settings, "ExternalLogin:VerifyUsers", "true");
|
||||
_allowhostrole = SettingService.GetSetting(settings, "ExternalLogin:AllowHostRole", "false");
|
||||
}
|
||||
|
||||
private async Task LoadUsersAsync(bool load)
|
||||
@ -719,7 +705,6 @@ else
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:DomainFilter", _domainfilter, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:CreateUsers", _createusers, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:VerifyUsers", _verifyusers, true);
|
||||
settings = SettingService.SetSetting(settings, "ExternalLogin:AllowHostRole", _allowhostrole, true);
|
||||
|
||||
settings = SettingService.SetSetting(settings, "JwtOptions:Secret", _secret, true);
|
||||
settings = SettingService.SetSetting(settings, "JwtOptions:Issuer", _issuer, true);
|
||||
|
@ -100,18 +100,6 @@ else
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
||||
</TabPanel>
|
||||
<TabPanel Name="Robots" Heading="Robots.txt" ResourceKey="Robots">
|
||||
<div class="container">
|
||||
<div class="row mb-1 align-items-center">
|
||||
<Label Class="col-sm-3" For="robots" HelpText="Specify your robots.txt instructions to provide bots with guidance on which parts of your site should be indexed" ResourceKey="Robots">Instructions: </Label>
|
||||
<div class="col-sm-9">
|
||||
<textarea id="robots" class="form-control" @bind="@_robots" rows="3"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
<button type="button" class="btn btn-success" @onclick="SaveSiteSettings">@SharedLocalizer["Save"]</button>
|
||||
</TabPanel>
|
||||
</TabStrip>
|
||||
}
|
||||
|
||||
@ -125,7 +113,6 @@ else
|
||||
private string _filter = "";
|
||||
private int _retention = 30;
|
||||
private string _correlation = "true";
|
||||
private string _robots = "";
|
||||
|
||||
public override SecurityAccessLevel SecurityAccessLevel => SecurityAccessLevel.Admin;
|
||||
|
||||
@ -152,8 +139,7 @@ else
|
||||
_filter = SettingService.GetSetting(settings, "VisitorFilter", Constants.DefaultVisitorFilter);
|
||||
_retention = int.Parse(SettingService.GetSetting(settings, "VisitorRetention", "30"));
|
||||
_correlation = SettingService.GetSetting(settings, "VisitorCorrelation", "true");
|
||||
_robots = SettingService.GetSetting(settings, "Robots", "");
|
||||
}
|
||||
}
|
||||
|
||||
private async void TypeChanged(ChangeEventArgs e)
|
||||
{
|
||||
@ -205,7 +191,6 @@ else
|
||||
settings = SettingService.SetSetting(settings, "VisitorFilter", _filter, true);
|
||||
settings = SettingService.SetSetting(settings, "VisitorRetention", _retention.ToString(), true);
|
||||
settings = SettingService.SetSetting(settings, "VisitorCorrelation", _correlation, true);
|
||||
settings = SettingService.SetSetting(settings, "Robots", _robots, true);
|
||||
await SettingService.UpdateSiteSettingsAsync(settings, PageState.Site.SiteId);
|
||||
|
||||
AddModuleMessage(Localizer["Success.SaveSiteSettings"], MessageType.Success);
|
||||
|
@ -163,13 +163,6 @@
|
||||
[Parameter]
|
||||
public EventCallback<int> OnUpload { get; set; } // optional - executes a method in the calling component when a file is uploaded
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> OnSelectFolder { get; set; } // optional - executes a method in the calling component when a folder is selected
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<int> OnSelectFile { get; set; } // optional - executes a method in the calling component when a file is selected
|
||||
|
||||
[Obsolete("Use OnSelectFile instead.")]
|
||||
[Parameter]
|
||||
public EventCallback<int> OnSelect { get; set; } // optional - executes a method in the calling component when a file is selected
|
||||
|
||||
@ -307,8 +300,6 @@
|
||||
FileId = -1;
|
||||
_file = null;
|
||||
_image = string.Empty;
|
||||
|
||||
await OnSelectFolder.InvokeAsync(FolderId);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -324,10 +315,7 @@
|
||||
_message = string.Empty;
|
||||
FileId = int.Parse((string)e.Value);
|
||||
await SetImage();
|
||||
#pragma warning disable CS0618
|
||||
await OnSelect.InvokeAsync(FileId);
|
||||
#pragma warning restore CS0618
|
||||
await OnSelectFile.InvokeAsync(FileId);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
@ -450,10 +438,7 @@
|
||||
{
|
||||
FileId = file.FileId;
|
||||
await SetImage();
|
||||
#pragma warning disable CS0618
|
||||
await OnSelect.InvokeAsync(FileId);
|
||||
#pragma warning restore CS0618
|
||||
await OnSelectFile.InvokeAsync(FileId);
|
||||
await OnUpload.InvokeAsync(FileId);
|
||||
}
|
||||
await GetFiles();
|
||||
@ -504,10 +489,7 @@
|
||||
await GetFiles();
|
||||
FileId = -1;
|
||||
await SetImage();
|
||||
#pragma warning disable CS0618
|
||||
await OnSelect.InvokeAsync(FileId);
|
||||
#pragma warning restore CS0618
|
||||
await OnSelectFile.InvokeAsync(FileId);
|
||||
StateHasChanged();
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -60,7 +60,7 @@
|
||||
@foreach (User user in _users)
|
||||
{
|
||||
<tr>
|
||||
<td>@user.DisplayName (@user.Username)</td>
|
||||
<td>@user.DisplayName</td>
|
||||
@foreach (var permissionname in _permissionnames)
|
||||
{
|
||||
<td style="text-align: center; width: 1px;">
|
||||
@ -270,8 +270,8 @@
|
||||
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.DisplayName.Contains(filter, StringComparison.OrdinalIgnoreCase) || item.User.Username.Contains(filter, StringComparison.OrdinalIgnoreCase))
|
||||
.ToDictionary(item => item.UserId.ToString(), item => item.User.DisplayName + " (" + item.User.Username + ")");
|
||||
return users.Where(item => item.User.DisplayName.Contains(filter, StringComparison.OrdinalIgnoreCase))
|
||||
.ToDictionary(item => item.UserId.ToString(), item => item.User.DisplayName);
|
||||
}
|
||||
|
||||
private async Task AddUser()
|
||||
|
@ -4,7 +4,7 @@
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
@ -22,22 +22,16 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Oqtane.Shared\Oqtane.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="Installer\Controls\AzureSqlConfig.razor">
|
||||
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<PublishTrimmed>false</PublishTrimmed>
|
||||
<BlazorEnableCompression>false</BlazorEnableCompression>
|
||||
|
@ -121,7 +121,7 @@
|
||||
<value>Server:</value>
|
||||
</data>
|
||||
<data name="Server.HelpText" xml:space="preserve">
|
||||
<value>Enter the database server name. This might include a port number as well if you are using a cloud service.</value>
|
||||
<value>Enter the database server name. This might include a port number as well if you are using a cloud service (ie. servername.database.windows.net,1433) </value>
|
||||
</data>
|
||||
<data name="Database.Text" xml:space="preserve">
|
||||
<value>Database:</value>
|
||||
|
@ -147,8 +147,8 @@
|
||||
<data name="Owner.HelpText" xml:space="preserve">
|
||||
<value>The owner or creator of the module</value>
|
||||
</data>
|
||||
<data name="Url.HelpText" xml:space="preserve">
|
||||
<value>The url of the module</value>
|
||||
<data name="ReferenceUrl.HelpText" xml:space="preserve">
|
||||
<value>The reference url of the module</value>
|
||||
</data>
|
||||
<data name="Contact.HelpText" xml:space="preserve">
|
||||
<value>The contact for the module</value>
|
||||
@ -171,8 +171,8 @@
|
||||
<data name="Owner.Text" xml:space="preserve">
|
||||
<value>Owner: </value>
|
||||
</data>
|
||||
<data name="Url.Text" xml:space="preserve">
|
||||
<value>Url: </value>
|
||||
<data name="ReferenceUrl.Text" xml:space="preserve">
|
||||
<value>Reference Url: </value>
|
||||
</data>
|
||||
<data name="Contact.Text" xml:space="preserve">
|
||||
<value>Contact: </value>
|
||||
|
@ -159,13 +159,4 @@
|
||||
<data name="Enabled" xml:space="preserve">
|
||||
<value>Enabled?</value>
|
||||
</data>
|
||||
<data name="Synchronize" xml:space="preserve">
|
||||
<value>Synchronize</value>
|
||||
</data>
|
||||
<data name="Success.Module.Synchronize" xml:space="preserve">
|
||||
<value>Modules Have Been Successfully Synchronized With The Marketplace</value>
|
||||
</data>
|
||||
<data name="Error.Module.Synchronize" xml:space="preserve">
|
||||
<value>Error Synchronizing Modules With The Marketplace</value>
|
||||
</data>
|
||||
</root>
|
@ -132,8 +132,8 @@
|
||||
<data name="Owner.Text" xml:space="preserve">
|
||||
<value>Owner: </value>
|
||||
</data>
|
||||
<data name="Url.Text" xml:space="preserve">
|
||||
<value>Url: </value>
|
||||
<data name="ReferenceUrl.Text" xml:space="preserve">
|
||||
<value>Reference Url: </value>
|
||||
</data>
|
||||
<data name="Contact.Text" xml:space="preserve">
|
||||
<value>Contact: </value>
|
||||
@ -153,8 +153,8 @@
|
||||
<data name="Owner.HelpText" xml:space="preserve">
|
||||
<value>The owner or creator of the theme</value>
|
||||
</data>
|
||||
<data name="Url.HelpText" xml:space="preserve">
|
||||
<value>The url of the theme</value>
|
||||
<data name="ReferenceUrl.HelpText" xml:space="preserve">
|
||||
<value>The reference url of the theme</value>
|
||||
</data>
|
||||
<data name="Contact.HelpText" xml:space="preserve">
|
||||
<value>The contact for the theme</value>
|
||||
|
@ -159,13 +159,4 @@
|
||||
<data name="Assign" xml:space="preserve">
|
||||
<value>Assign</value>
|
||||
</data>
|
||||
<data name="Synchronize" xml:space="preserve">
|
||||
<value>Synchronize</value>
|
||||
</data>
|
||||
<data name="Success.Theme.Synchronize" xml:space="preserve">
|
||||
<value>Themes Have Been Successfully Synchronized With The Marketplace</value>
|
||||
</data>
|
||||
<data name="Error.Theme.Synchronize" xml:space="preserve">
|
||||
<value>Error Synchronizing Themes With The Marketplace</value>
|
||||
</data>
|
||||
</root>
|
@ -151,12 +151,6 @@
|
||||
<value>You Cannot Perform A System Update In A Development Environment</value>
|
||||
</data>
|
||||
<data name="Disclaimer.Text" xml:space="preserve">
|
||||
<value>Please Note That The System Update Capability Is A Simplified Upgrade Process Intended For Small To Medium Sized Installations. For Larger Enterprise Installations You Will Want To Use A Manual Upgrade Process.</value>
|
||||
</data>
|
||||
<data name="Backup.Text" xml:space="preserve">
|
||||
<value>Backup Files?</value>
|
||||
</data>
|
||||
<data name="Backup.HelpText" xml:space="preserve">
|
||||
<value>Specify if you want to backup files during the upgrade process. Disabling this option will result in a better experience in some environments.</value>
|
||||
<value>Please Note That The System Update Capability Is A Simplified Upgrade Process Intended For Small To Medium Sized Installations. For Larger Enterprise Installations You Will Want To Use A Manual Upgrade Process. Also Note That The System Update Capability Is Not Recommended When Using Microsoft Azure Due To Environmental Limitations.</value>
|
||||
</data>
|
||||
</root>
|
@ -513,10 +513,4 @@
|
||||
<data name="LogoutEverywhere.HelpText" xml:space="preserve">
|
||||
<value>Do you want users to be logged out of every active session on any device, or only their current session?</value>
|
||||
</data>
|
||||
<data name="AllowHostRole.Text" xml:space="preserve">
|
||||
<value>Allow Host Role?</value>
|
||||
</data>
|
||||
<data name="AllowHostRole.HelpText" xml:space="preserve">
|
||||
<value>Indicate if host roles are supported from the identity provider. Please use caution with this option as it allows the host user to administrate every site within your installation.</value>
|
||||
</data>
|
||||
</root>
|
@ -198,13 +198,4 @@
|
||||
<data name="Duration.Text" xml:space="preserve">
|
||||
<value>Session Duration:</value>
|
||||
</data>
|
||||
<data name="Robots.Heading" xml:space="preserve">
|
||||
<value>Robots.txt</value>
|
||||
</data>
|
||||
<data name="Robots.Text" xml:space="preserve">
|
||||
<value>Instructions:</value>
|
||||
</data>
|
||||
<data name="Robots.HelpText" xml:space="preserve">
|
||||
<value>Specify your robots.txt instructions to provide bots with guidance on which parts of your site should be indexed</value>
|
||||
</data>
|
||||
</root>
|
@ -47,9 +47,9 @@ namespace Oqtane.Services
|
||||
return await PostJsonAsync<InstallConfig,Installation>(ApiUrl, config);
|
||||
}
|
||||
|
||||
public async Task<Installation> Upgrade(bool backup)
|
||||
public async Task<Installation> Upgrade()
|
||||
{
|
||||
return await GetJsonAsync<Installation>($"{ApiUrl}/upgrade/?backup={backup}");
|
||||
return await GetJsonAsync<Installation>($"{ApiUrl}/upgrade");
|
||||
}
|
||||
|
||||
public async Task RestartAsync()
|
||||
|
@ -26,9 +26,8 @@ namespace Oqtane.Services
|
||||
/// <summary>
|
||||
/// Starts the upgrade process
|
||||
/// </summary>
|
||||
/// <param name="backup">indicates if files should be backed up during upgrade</param>
|
||||
/// <returns>internal status/message object</returns>
|
||||
Task<Installation> Upgrade(bool backup);
|
||||
Task<Installation> Upgrade();
|
||||
|
||||
/// <summary>
|
||||
/// Restarts the installation
|
||||
|
@ -10,11 +10,10 @@ namespace Oqtane.Services
|
||||
public interface IJobLogService
|
||||
{
|
||||
/// <summary>
|
||||
/// Return a list of <see cref="JobLog"/> entries
|
||||
/// Return a list of all <see cref="JobLog"/> entries
|
||||
/// </summary>
|
||||
/// <param name="jobId"></param>
|
||||
/// <returns></returns>
|
||||
Task<List<JobLog>> GetJobLogsAsync(int jobId);
|
||||
Task<List<JobLog>> GetJobLogsAsync();
|
||||
|
||||
/// <summary>
|
||||
/// Return a <see cref="JobLog"/> entry for the given Id
|
||||
|
@ -15,9 +15,10 @@ namespace Oqtane.Services
|
||||
|
||||
private string Apiurl => CreateApiUrl("JobLog");
|
||||
|
||||
public async Task<List<JobLog>> GetJobLogsAsync(int jobId)
|
||||
public async Task<List<JobLog>> GetJobLogsAsync()
|
||||
{
|
||||
return await GetJsonAsync<List<JobLog>>($"{Apiurl}?jobid={jobId}");
|
||||
List<JobLog> joblogs = await GetJsonAsync<List<JobLog>>(Apiurl);
|
||||
return joblogs.OrderBy(item => item.StartDate).ToList();
|
||||
}
|
||||
|
||||
public async Task<JobLog> GetJobLogAsync(int jobLogId)
|
||||
|
@ -6,7 +6,8 @@
|
||||
|
||||
@if (_enabled && !Hidden)
|
||||
{
|
||||
<div class="gdpr-consent-bar bg-light text-dark @(_showBanner ? "px-0 py-3 pt-5 pt-sm-3 pe-sm-5 ps-sm-3" : "p-0") fixed-bottom">
|
||||
|
||||
<div class="gdpr-consent-bar bg-light text-dark @(_showBanner ? "p-3" : "p-0") pe-5 fixed-bottom">
|
||||
<form method="post" @formname="CookieConsentForm" @onsubmit="async () => await AcceptPolicy()" data-enhance>
|
||||
@if (_showBanner)
|
||||
{
|
||||
|
@ -2,18 +2,19 @@
|
||||
@using System.Net
|
||||
@inherits ThemeControlBase
|
||||
@inject IStringLocalizer<UserProfile> Localizer
|
||||
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<span class="app-profile">
|
||||
@if (PageState.User != null)
|
||||
{
|
||||
<a href="@_profileurl" class="@CssClass">@PageState.User.Username</a>
|
||||
<a href="@NavigateUrl("profile", "returnurl=" + _returnurl)" class="@CssClass">@PageState.User.Username</a>
|
||||
}
|
||||
else
|
||||
{
|
||||
@if (ShowRegister && PageState.Site.AllowRegistration)
|
||||
{
|
||||
<a href="@_registerurl" class="@CssClass">@Localizer["Register"]</a>
|
||||
<a href="@NavigateUrl("register", "returnurl=" + _returnurl)" class="@CssClass">@Localizer["Register"]</a>
|
||||
}
|
||||
}
|
||||
</span>
|
||||
@ -22,50 +23,23 @@
|
||||
|
||||
[Parameter]
|
||||
public bool ShowRegister { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string CssClass { get; set; } = "btn btn-primary";
|
||||
|
||||
[Parameter]
|
||||
public string RegisterUrl { get; set; } // optional parameter to specify a custom registration url
|
||||
|
||||
[Parameter]
|
||||
public string ProfileUrl { get; set; } // optional parameter to specify a custom user profile url
|
||||
|
||||
private string _registerurl = "";
|
||||
private string _profileurl = "";
|
||||
private string _returnurl = "";
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
if (!PageState.QueryString.ContainsKey("returnurl"))
|
||||
{
|
||||
// remember current url
|
||||
_returnurl = WebUtility.UrlEncode(PageState.Route.PathAndQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use existing value
|
||||
_returnurl = PageState.QueryString["returnurl"];
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(RegisterUrl))
|
||||
{
|
||||
_registerurl = RegisterUrl + "?returnurl=" + (RegisterUrl.Contains("://") ? WebUtility.UrlEncode(PageState.Route.RootUrl) + _returnurl : _returnurl);
|
||||
}
|
||||
else
|
||||
{
|
||||
_registerurl = NavigateUrl("register", "returnurl=" + _returnurl);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(ProfileUrl))
|
||||
{
|
||||
_registerurl = ProfileUrl + "?returnurl=" + (ProfileUrl.Contains("://") ? WebUtility.UrlEncode(PageState.Route.RootUrl) + _returnurl : _returnurl);
|
||||
}
|
||||
else
|
||||
{
|
||||
_registerurl = NavigateUrl("profile", "returnurl=" + _returnurl);
|
||||
}
|
||||
{
|
||||
if (!PageState.QueryString.ContainsKey("returnurl"))
|
||||
{
|
||||
// remember current url
|
||||
_returnurl = WebUtility.UrlEncode(PageState.Route.PathAndQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
// use existing value
|
||||
_returnurl = PageState.QueryString["returnurl"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,7 +623,7 @@
|
||||
}
|
||||
|
||||
// ensure resource does not exist already
|
||||
if (!pageresources.Exists(item => Utilities.GetUrlPath(item.Url).ToLower() == Utilities.GetUrlPath(resource.Url).ToLower()))
|
||||
if (!pageresources.Exists(item => item.Url.ToLower() == resource.Url.ToLower()))
|
||||
{
|
||||
pageresources.Add(resource.Clone(level, name, fingerprint));
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -42,7 +42,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<MySQLFiles Include="$(OutputPath)Oqtane.Database.MySQL.dll;$(OutputPath)Oqtane.Database.MySQL.pdb;$(OutputPath)Pomelo.EntityFrameworkCore.MySql.dll;$(OutputPath)MySqlConnector.dll;$(OutputPath)MySql.Data.dll" DestinationPath="..\Oqtane.Server\bin\$(Configuration)\net9.0\%(Filename)%(Extension)" />
|
||||
<MySQLFiles Include="$(OutputPath)Oqtane.Database.MySQL.dll;$(OutputPath)Oqtane.Database.MySQL.pdb;$(OutputPath)Pomelo.EntityFrameworkCore.MySql.dll;$(OutputPath)MySql.Data.dll" DestinationPath="..\Oqtane.Server\bin\$(Configuration)\net9.0\%(Filename)%(Extension)" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PublishProvider" AfterTargets="PostBuildEvent" Inputs="@(MySQLFiles)" Outputs="@(MySQLFiles->'%(DestinationPath)')">
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="EFCore.NamingConventions" Version="9.0.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.3" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -33,7 +33,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||
@ -33,7 +33,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -6,7 +6,7 @@
|
||||
<!-- <TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks> -->
|
||||
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane.Maui</RootNamespace>
|
||||
@ -30,7 +30,7 @@
|
||||
<ApplicationId>com.oqtane.maui</ApplicationId>
|
||||
|
||||
<!-- Versions -->
|
||||
<ApplicationDisplayVersion>6.1.2</ApplicationDisplayVersion>
|
||||
<ApplicationDisplayVersion>6.1.1</ApplicationDisplayVersion>
|
||||
<ApplicationVersion>1</ApplicationVersion>
|
||||
|
||||
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
|
||||
@ -67,14 +67,14 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.50" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.50" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.50" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls" Version="9.0.40" />
|
||||
<PackageReference Include="Microsoft.Maui.Controls.Compatibility" Version="9.0.40" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="9.0.40" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Client</id>
|
||||
<version>6.1.2</version>
|
||||
<version>6.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Framework</id>
|
||||
<version>6.1.2</version>
|
||||
<version>6.1.1</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/v6.1.2/Oqtane.Framework.6.1.2.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.2</releaseNotes>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework/releases/download/v6.1.1/Oqtane.Framework.6.1.1.Upgrade.zip</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane framework</tags>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Server</id>
|
||||
<version>6.1.2</version>
|
||||
<version>6.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Shared</id>
|
||||
<version>6.1.2</version>
|
||||
<version>6.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<package>
|
||||
<metadata>
|
||||
<id>Oqtane.Updater</id>
|
||||
<version>6.1.2</version>
|
||||
<version>6.1.1</version>
|
||||
<authors>Shaun Walker</authors>
|
||||
<owners>.NET Foundation</owners>
|
||||
<title>Oqtane Framework</title>
|
||||
@ -12,7 +12,7 @@
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<license type="expression">MIT</license>
|
||||
<projectUrl>https://github.com/oqtane/oqtane.framework</projectUrl>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.2</releaseNotes>
|
||||
<releaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</releaseNotes>
|
||||
<readme>readme.md</readme>
|
||||
<icon>icon.png</icon>
|
||||
<tags>oqtane</tags>
|
||||
|
@ -1 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net9.0\publish\*" -DestinationPath "Oqtane.Framework.6.1.2.Install.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net9.0\publish\*" -DestinationPath "Oqtane.Framework.6.1.1.Install.zip" -Force
|
||||
|
@ -1 +1 @@
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net9.0\publish\*" -DestinationPath "Oqtane.Framework.6.1.2.Upgrade.zip" -Force
|
||||
Compress-Archive -Path "..\Oqtane.Server\bin\Release\net9.0\publish\*" -DestinationPath "Oqtane.Framework.6.1.1.Upgrade.zip" -Force
|
||||
|
@ -764,7 +764,7 @@
|
||||
}
|
||||
|
||||
// ensure resource does not exist already
|
||||
if (!pageresources.Exists(item => Utilities.GetUrlPath(item.Url).ToLower() == Utilities.GetUrlPath(resource.Url).ToLower()))
|
||||
if (!pageresources.Exists(item => item.Url.ToLower() == resource.Url.ToLower()))
|
||||
{
|
||||
pageresources.Add(resource.Clone(level, name, fingerprint));
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ using System.IO.Compression;
|
||||
using Oqtane.Services;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
// ReSharper disable StringIndexOfIsCultureSpecific.1
|
||||
|
||||
@ -736,10 +735,6 @@ namespace Oqtane.Controllers
|
||||
}
|
||||
if (!string.IsNullOrEmpty(imagepath))
|
||||
{
|
||||
if (!string.IsNullOrEmpty(file.Folder.CacheControl))
|
||||
{
|
||||
HttpContext.Response.Headers.Append(HeaderNames.CacheControl, value: file.Folder.CacheControl);
|
||||
}
|
||||
return PhysicalFile(imagepath, file.GetMimeType());
|
||||
}
|
||||
else
|
||||
|
@ -280,14 +280,9 @@ namespace Oqtane.Controllers
|
||||
var folder = _folders.GetFolder(id, false);
|
||||
if (folder != null && folder.SiteId == _alias.SiteId && _userPermissions.IsAuthorized(User, folder.SiteId, EntityNames.Folder, id, PermissionNames.Edit))
|
||||
{
|
||||
var folderPath = _folders.GetFolderPath(folder);
|
||||
if (Directory.Exists(folderPath))
|
||||
if (Directory.Exists(_folders.GetFolderPath(folder)))
|
||||
{
|
||||
foreach (var filePath in Directory.GetFiles(folderPath))
|
||||
{
|
||||
System.IO.File.Delete(filePath);
|
||||
}
|
||||
Directory.Delete(folderPath);
|
||||
Directory.Delete(_folders.GetFolderPath(folder));
|
||||
}
|
||||
_folders.DeleteFolder(id);
|
||||
_syncManager.AddSyncEvent(_alias, EntityNames.Folder, folder.FolderId, SyncEventActions.Delete);
|
||||
|
@ -88,10 +88,10 @@ namespace Oqtane.Controllers
|
||||
|
||||
[HttpGet("upgrade")]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public Installation Upgrade(string backup)
|
||||
public Installation Upgrade()
|
||||
{
|
||||
var installation = new Installation { Success = true, Message = "" };
|
||||
_installationManager.UpgradeFramework(bool.Parse(backup));
|
||||
_installationManager.UpgradeFramework();
|
||||
return installation;
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,12 @@ namespace Oqtane.Controllers
|
||||
_jobLogs = jobLogs;
|
||||
}
|
||||
|
||||
// GET: api/<controller>?jobid=x
|
||||
// GET: api/<controller>
|
||||
[HttpGet]
|
||||
[Authorize(Roles = RoleNames.Host)]
|
||||
public IEnumerable<JobLog> Get(string jobid)
|
||||
public IEnumerable<JobLog> Get()
|
||||
{
|
||||
return _jobLogs.GetJobLogs(int.Parse(jobid));
|
||||
return _jobLogs.GetJobLogs();
|
||||
}
|
||||
|
||||
// GET api/<controller>/5
|
||||
|
@ -90,26 +90,33 @@ namespace Oqtane.Controllers
|
||||
package = await GetJson<Package>(client, url + $"/api/registry/package/?id={_configManager.GetInstallationId()}&package={packageid}&version={version}&download={download}&email={WebUtility.UrlEncode(GetPackageRegistryEmail())}");
|
||||
}
|
||||
|
||||
if (package != null && bool.Parse(install))
|
||||
if (package != null)
|
||||
{
|
||||
using (var httpClient = new HttpClient())
|
||||
if (bool.Parse(install))
|
||||
{
|
||||
var folder = Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder);
|
||||
var response = await httpClient.GetAsync(package.PackageUrl).ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode)
|
||||
using (var httpClient = new HttpClient())
|
||||
{
|
||||
string filename = packageid + "." + version + ".nupkg";
|
||||
using (var fileStream = new FileStream(Path.Combine(Constants.PackagesFolder, filename), FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
var folder = Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder);
|
||||
var response = await httpClient.GetAsync(package.PackageUrl).ConfigureAwait(false);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
string filename = packageid + "." + version + ".nupkg";
|
||||
using (var fileStream = new FileStream(Path.Combine(Constants.PackagesFolder, filename), FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
await response.Content.CopyToAsync(fileStream).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "Could Not Download {PackageUrl}", package.PackageUrl);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "Could Not Download {PackageUrl}", package.PackageUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_logger.Log(LogLevel.Error, this, LogFunction.Create, "Package {PackageId}.{Version} Is Not Registered In The Marketplace", packageid, version);
|
||||
}
|
||||
}
|
||||
return package;
|
||||
}
|
||||
|
@ -532,9 +532,8 @@ namespace Oqtane.Extensions
|
||||
// external roles
|
||||
if (claimsPrincipal.Claims.Any(item => item.Type == httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimType", "")))
|
||||
{
|
||||
var _roles = httpContext.RequestServices.GetRequiredService<IRoleRepository>();
|
||||
var allowhostrole = bool.Parse(httpContext.GetSiteSettings().GetValue("ExternalLogin:AllowHostRole", "false"));
|
||||
var roles = _roles.GetRoles(user.SiteId, allowhostrole).ToList();
|
||||
var _roles = httpContext.RequestServices.GetRequiredService<IRoleRepository>();
|
||||
var roles = _roles.GetRoles(user.SiteId).ToList(); // global roles excluded ie. host users cannot be added/deleted
|
||||
|
||||
var mappings = httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimMappings", "").Split(',');
|
||||
foreach (var claim in claimsPrincipal.Claims.Where(item => item.Type == httpContext.GetSiteSettings().GetValue("ExternalLogin:RoleClaimType", "")))
|
||||
@ -584,9 +583,8 @@ namespace Oqtane.Extensions
|
||||
}
|
||||
}
|
||||
|
||||
var host = userRoles.FirstOrDefault(item => item.Role.Name == RoleNames.Host);
|
||||
var registered = userRoles.FirstOrDefault(item => item.Role.Name == RoleNames.Registered);
|
||||
if (!user.IsDeleted && (host != null || registered != null && Utilities.IsEffectiveAndNotExpired(registered.EffectiveDate, registered.ExpiryDate)))
|
||||
var userrole = userRoles.FirstOrDefault(item => item.Role.Name == RoleNames.Registered);
|
||||
if (!user.IsDeleted && userrole != null && Utilities.IsEffectiveAndNotExpired(userrole.EffectiveDate, userrole.ExpiryDate))
|
||||
{
|
||||
// update user
|
||||
user.LastLoginOn = DateTime.UtcNow;
|
||||
|
@ -731,7 +731,6 @@ namespace Oqtane.Infrastructure
|
||||
{
|
||||
_configManager.AddOrUpdateSetting($"{SettingKeys.DatabaseSection}:{SettingKeys.DatabaseTypeKey}", Constants.DefaultDBType, true);
|
||||
}
|
||||
|
||||
if (!_configManager.GetSection(SettingKeys.AvailableDatabasesSection).Exists())
|
||||
{
|
||||
string databases = "[";
|
||||
@ -743,19 +742,6 @@ namespace Oqtane.Infrastructure
|
||||
databases += "]";
|
||||
_configManager.AddOrUpdateSetting(SettingKeys.AvailableDatabasesSection, databases, true);
|
||||
}
|
||||
var availabledatabases = _configManager.GetSection(SettingKeys.AvailableDatabasesSection).GetChildren();
|
||||
if (!availabledatabases.Any(item => item.GetSection("Name").Value == "Azure SQL"))
|
||||
{
|
||||
// Azure SQL added in 6.1.2
|
||||
string databases = "[";
|
||||
foreach (var database in availabledatabases)
|
||||
{
|
||||
databases += "{ " + $"\"Name\": \"{database["Name"]}\", \"ControlType\": \"{database["ControlType"]}\", \"DBTYpe\": \"{database["DBType"]}\"" + " },";
|
||||
}
|
||||
databases += "{ \"Name\": \"Azure SQL\", \"ControlType\": \"Oqtane.Installer.Controls.AzureSqlConfig, Oqtane.Client\", \"DBTYpe\": \"Oqtane.Database.SqlServer.SqlServerDatabase, Oqtane.Database.SqlServer\" }";
|
||||
databases += "]";
|
||||
_configManager.AddOrUpdateSetting(SettingKeys.AvailableDatabasesSection, databases, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -380,7 +380,7 @@ namespace Oqtane.Infrastructure
|
||||
File.WriteAllText(assemblyLogPath, JsonSerializer.Serialize(assemblies, new JsonSerializerOptions { WriteIndented = true }));
|
||||
}
|
||||
|
||||
public async Task UpgradeFramework(bool backup)
|
||||
public async Task UpgradeFramework()
|
||||
{
|
||||
string folder = Path.Combine(_environment.ContentRootPath, Constants.PackagesFolder);
|
||||
if (Directory.Exists(folder))
|
||||
@ -448,14 +448,14 @@ namespace Oqtane.Infrastructure
|
||||
// install Oqtane.Upgrade zip package
|
||||
if (File.Exists(upgradepackage))
|
||||
{
|
||||
FinishUpgrade(backup);
|
||||
FinishUpgrade();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void FinishUpgrade(bool backup)
|
||||
private void FinishUpgrade()
|
||||
{
|
||||
// check if updater application exists
|
||||
string Updater = Constants.UpdaterPackageId + ".dll";
|
||||
@ -469,7 +469,7 @@ namespace Oqtane.Infrastructure
|
||||
{
|
||||
WorkingDirectory = folder,
|
||||
FileName = "dotnet",
|
||||
Arguments = Path.Combine(folder, Updater) + " \"" + _environment.ContentRootPath + "\" \"" + _environment.WebRootPath + "\" \"" + backup.ToString() + "\"",
|
||||
Arguments = Path.Combine(folder, Updater) + " \"" + _environment.ContentRootPath + "\" \"" + _environment.WebRootPath + "\"",
|
||||
UseShellExecute = false,
|
||||
ErrorDialog = false,
|
||||
CreateNoWindow = true,
|
||||
|
@ -7,7 +7,7 @@ namespace Oqtane.Infrastructure
|
||||
void InstallPackages();
|
||||
bool UninstallPackage(string PackageName);
|
||||
int RegisterAssemblies();
|
||||
Task UpgradeFramework(bool backup);
|
||||
Task UpgradeFramework();
|
||||
void RestartApplication();
|
||||
}
|
||||
}
|
||||
|
@ -46,8 +46,6 @@ namespace Oqtane.Infrastructure
|
||||
|
||||
protected async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
await Task.Yield(); // required so that this method does not block startup
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
using (var scope = _serviceScopeFactory.CreateScope())
|
||||
@ -172,7 +170,8 @@ namespace Oqtane.Infrastructure
|
||||
jobs.UpdateJob(job);
|
||||
|
||||
// trim the job log
|
||||
List<JobLog> logs = jobLogs.GetJobLogs(job.JobId).ToList();
|
||||
List<JobLog> logs = jobLogs.GetJobLogs().Where(item => item.JobId == job.JobId)
|
||||
.OrderByDescending(item => item.JobLogId).ToList();
|
||||
for (int i = logs.Count; i > job.RetentionHistory; i--)
|
||||
{
|
||||
jobLogs.DeleteJobLog(logs[i - 1].JobLogId);
|
||||
|
@ -130,12 +130,7 @@ namespace Oqtane.Infrastructure
|
||||
mailMessage.Subject = notification.Subject;
|
||||
|
||||
//body
|
||||
mailMessage.Body = notification.Body;
|
||||
if (!mailMessage.Body.Contains("<") || !mailMessage.Body.Contains(">"))
|
||||
{
|
||||
// plain text messages should convert line breaks to HTML tags to preserve formatting
|
||||
mailMessage.Body = mailMessage.Body.Replace("\n", "<br />");
|
||||
}
|
||||
mailMessage.Body = notification.Body.Replace("\n", "<br />");
|
||||
|
||||
// encoding
|
||||
mailMessage.SubjectEncoding = System.Text.Encoding.UTF8;
|
||||
|
@ -74,21 +74,8 @@ namespace Oqtane.Infrastructure
|
||||
// handle robots.txt root request (does not support subfolder aliases)
|
||||
if (context.Request.Path.StartsWithSegments("/robots.txt") && string.IsNullOrEmpty(alias.Path))
|
||||
{
|
||||
string robots = "";
|
||||
if (sitesettings.ContainsKey("Robots") && !string.IsNullOrEmpty(sitesettings["Robots"]))
|
||||
{
|
||||
robots = sitesettings["Robots"];
|
||||
}
|
||||
else
|
||||
{
|
||||
// allow all user agents by default
|
||||
robots = $"User-agent: *";
|
||||
}
|
||||
if (!robots.ToLower().Contains("Sitemap:"))
|
||||
{
|
||||
// add sitemap if not specified
|
||||
robots += $"\n\nSitemap: {context.Request.Scheme}://{alias.Name}/sitemap.xml";
|
||||
}
|
||||
// allow all user agents and specify site map
|
||||
var robots = $"User-agent: *\n\nSitemap: {context.Request.Scheme}://{alias.Name}/sitemap.xml";
|
||||
context.Response.ContentType = "text/plain";
|
||||
await context.Response.WriteAsync(robots);
|
||||
return;
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
|
||||
@ -181,7 +182,6 @@ namespace Oqtane.Infrastructure.SiteTemplates
|
||||
Name = "Privacy",
|
||||
Parent = "",
|
||||
Path = "privacy",
|
||||
Order = seed + 11,
|
||||
Icon = Icons.Eye,
|
||||
IsNavigation = false,
|
||||
IsPersonalizable = false,
|
||||
@ -212,7 +212,6 @@ namespace Oqtane.Infrastructure.SiteTemplates
|
||||
Name = "Terms",
|
||||
Parent = "",
|
||||
Path = "terms",
|
||||
Order = seed + 13,
|
||||
Icon = Icons.List,
|
||||
IsNavigation = false,
|
||||
IsPersonalizable = false,
|
||||
@ -243,7 +242,7 @@ namespace Oqtane.Infrastructure.SiteTemplates
|
||||
Name = "Not Found",
|
||||
Parent = "",
|
||||
Path = "404",
|
||||
Order = seed + 15,
|
||||
Order = seed + 11,
|
||||
Icon = Icons.X,
|
||||
IsNavigation = false,
|
||||
IsPersonalizable = false,
|
||||
|
@ -2,6 +2,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Repository;
|
||||
using Oqtane.Shared;
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Documentation;
|
||||
using Oqtane.Infrastructure;
|
||||
using Oqtane.Models;
|
||||
using Oqtane.Shared;
|
||||
|
||||
|
@ -473,7 +473,6 @@ namespace Oqtane.Infrastructure
|
||||
Name = "Privacy",
|
||||
Parent = "",
|
||||
Path = "privacy",
|
||||
Order = 1011,
|
||||
Icon = Icons.Eye,
|
||||
IsNavigation = false,
|
||||
IsPersonalizable = false,
|
||||
@ -503,7 +502,6 @@ namespace Oqtane.Infrastructure
|
||||
Name = "Terms",
|
||||
Parent = "",
|
||||
Path = "terms",
|
||||
Order = 1013,
|
||||
Icon = Icons.List,
|
||||
IsNavigation = false,
|
||||
IsPersonalizable = false,
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
@ -34,21 +34,21 @@
|
||||
<EmbeddedResource Include="Scripts\MigrateTenant.sql" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.4">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="9.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.3" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.11" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.7" />
|
||||
<PackageReference Include="HtmlAgilityPack" Version="1.12.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="7.3.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Oqtane.Client\Oqtane.Client.csproj" />
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using Oqtane.Models;
|
||||
|
||||
namespace Oqtane.Repository
|
||||
@ -6,7 +6,6 @@ namespace Oqtane.Repository
|
||||
public interface IJobLogRepository
|
||||
{
|
||||
IEnumerable<JobLog> GetJobLogs();
|
||||
IEnumerable<JobLog> GetJobLogs(int jobId);
|
||||
JobLog AddJobLog(JobLog jobLog);
|
||||
JobLog UpdateJobLog(JobLog jobLog);
|
||||
JobLog GetJobLog(int jobLogId);
|
||||
|
@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Oqtane.Models;
|
||||
@ -15,17 +15,9 @@ namespace Oqtane.Repository
|
||||
}
|
||||
|
||||
public IEnumerable<JobLog> GetJobLogs()
|
||||
{
|
||||
return GetJobLogs(-1);
|
||||
}
|
||||
|
||||
public IEnumerable<JobLog> GetJobLogs(int jobId)
|
||||
{
|
||||
return _db.JobLog
|
||||
.AsNoTracking()
|
||||
.Where(item => item.JobId == jobId || jobId == -1)
|
||||
.Include(item => item.Job) // eager load jobs
|
||||
.OrderByDescending(item => item.JobLogId)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,6 @@ namespace Oqtane.Repository
|
||||
|
||||
public UserRole AddUserRole(UserRole userRole)
|
||||
{
|
||||
userRole.EffectiveDate = userRole.EffectiveDate.HasValue ? DateTime.SpecifyKind(userRole.EffectiveDate.Value, DateTimeKind.Utc) : userRole.EffectiveDate;
|
||||
userRole.ExpiryDate = userRole.ExpiryDate.HasValue ? DateTime.SpecifyKind(userRole.ExpiryDate.Value, DateTimeKind.Utc) : userRole.ExpiryDate;
|
||||
|
||||
using var db = _dbContextFactory.CreateDbContext();
|
||||
db.UserRole.Add(userRole);
|
||||
db.SaveChanges();
|
||||
@ -87,9 +84,6 @@ namespace Oqtane.Repository
|
||||
|
||||
public UserRole UpdateUserRole(UserRole userRole)
|
||||
{
|
||||
userRole.EffectiveDate = userRole.EffectiveDate.HasValue ? DateTime.SpecifyKind(userRole.EffectiveDate.Value, DateTimeKind.Utc) : userRole.EffectiveDate;
|
||||
userRole.ExpiryDate = userRole.ExpiryDate.HasValue ? DateTime.SpecifyKind(userRole.ExpiryDate.Value, DateTimeKind.Utc) : userRole.ExpiryDate;
|
||||
|
||||
using var db = _dbContextFactory.CreateDbContext();
|
||||
db.Entry(userRole).State = EntityState.Modified;
|
||||
db.SaveChanges();
|
||||
|
@ -70,6 +70,7 @@ namespace Oqtane
|
||||
services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
services.AddOptions<List<Database>>().Bind(Configuration.GetSection(SettingKeys.AvailableDatabasesSection));
|
||||
services.Configure<HostOptions>(opts => opts.ShutdownTimeout = TimeSpan.FromSeconds(10)); // increase from default of 5 seconds
|
||||
|
||||
// register scoped core services
|
||||
services.AddScoped<IAuthorizationHandler, PermissionHandler>()
|
||||
|
@ -2,10 +2,10 @@
|
||||
"RenderMode": "Interactive",
|
||||
"Runtime": "Server",
|
||||
"Database": {
|
||||
"DefaultDBType": ""
|
||||
"DefaultDBType": "Oqtane.Database.Sqlite.SqliteDatabase, Oqtane.Database.Sqlite"
|
||||
},
|
||||
"ConnectionStrings": {
|
||||
"DefaultConnection": ""
|
||||
"DefaultConnection": "Data Source=Oqtane-202507152139.db;"
|
||||
},
|
||||
"Installation": {
|
||||
"DefaultAlias": "",
|
||||
@ -54,5 +54,9 @@
|
||||
"LogLevel": {
|
||||
"Default": "Information"
|
||||
}
|
||||
}
|
||||
},
|
||||
"InstallationId": "e0b3aaed-a33d-4756-bd08-a83403d0c437",
|
||||
"InstallationVersion": "6.1.1",
|
||||
"InstallationDate": "202507152140",
|
||||
"PackageRegistryEmail": "ismail.hasimoglu@edu.szu.at"
|
||||
}
|
@ -13,11 +13,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.4" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.3" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -19,10 +19,10 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.MySQL.nupkg
Normal file
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.MySQL.nupkg
Normal file
Binary file not shown.
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.PostgreSQL.nupkg
Normal file
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.PostgreSQL.nupkg
Normal file
Binary file not shown.
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.SqlServer.nupkg
Normal file
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.SqlServer.nupkg
Normal file
Binary file not shown.
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.Sqlite.nupkg
Normal file
BIN
Oqtane.Server/wwwroot/Packages/Oqtane.Database.Sqlite.nupkg
Normal file
Binary file not shown.
@ -13,9 +13,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Authentication" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -4,4 +4,4 @@ set ProjectName=%2
|
||||
|
||||
del "*.nupkg"
|
||||
"..\..\[RootFolder]\oqtane.package\nuget.exe" pack %ProjectName%.nuspec -Properties targetframework=%TargetFramework%;projectname=%ProjectName%
|
||||
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\Packages\" /Y
|
||||
XCOPY "*.nupkg" "..\..\[RootFolder]\Oqtane.Server\wwwroot\Packages\" /Y
|
@ -32,6 +32,10 @@ namespace Oqtane.Models
|
||||
/// <summary>
|
||||
/// Reference to a <see cref="File"/> containing the users photo.
|
||||
/// </summary>
|
||||
|
||||
public string Subject { get; set; }
|
||||
public int GraduationYear { get; set; }
|
||||
|
||||
public int? PhotoFileId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</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="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.3" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="9.0.3" />
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.4" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -4,8 +4,8 @@ namespace Oqtane.Shared
|
||||
{
|
||||
public class Constants
|
||||
{
|
||||
public static readonly string Version = "6.1.2";
|
||||
public const string ReleaseVersions = "1.0.0,1.0.1,1.0.2,1.0.3,1.0.4,2.0.0,2.0.1,2.0.2,2.1.0,2.2.0,2.3.0,2.3.1,3.0.0,3.0.1,3.0.2,3.0.3,3.1.0,3.1.1,3.1.2,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,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0,6.0.1,6.1.0,6.1.1,6.1.2";
|
||||
public static readonly string Version = "6.1.1";
|
||||
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,5.0.1,5.0.2,5.0.3,5.1.0,5.1.1,5.1.2,5.2.0,5.2.1,5.2.2,5.2.3,5.2.4,6.0.0,6.0.1,6.1.0,6.1.1";
|
||||
public const string PackageId = "Oqtane.Framework";
|
||||
public const string ClientId = "Oqtane.Client";
|
||||
public const string UpdaterPackageId = "Oqtane.Updater";
|
||||
|
@ -121,17 +121,6 @@ namespace Oqtane.Shared
|
||||
return $"{alias?.BaseUrl}{url}{Constants.ImageUrl}{fileId}/{width}/{height}/{mode}/{position}/{background}/{rotate}/{recreate}";
|
||||
}
|
||||
|
||||
public static string ImageUrl(Alias alias, string folderpath, string filename, int width, int height, string mode, string position, string background, int rotate, string format, bool recreate)
|
||||
{
|
||||
var aliasUrl = (alias != null && !string.IsNullOrEmpty(alias.Path)) ? "/" + alias.Path : "";
|
||||
mode = string.IsNullOrEmpty(mode) ? "crop" : mode;
|
||||
position = string.IsNullOrEmpty(position) ? "center" : position;
|
||||
background = string.IsNullOrEmpty(background) ? "transparent" : background;
|
||||
format = string.IsNullOrEmpty(format) ? "png" : format;
|
||||
var querystring = $"?width={width}&height={height}&mode={mode}&position={position}&background={background}&rotate={rotate}&format={format}&recreate={recreate}";
|
||||
return $"{alias?.BaseUrl}{aliasUrl}{Constants.FileUrl}{folderpath.Replace("\\", "/")}{filename}{querystring}";
|
||||
}
|
||||
|
||||
public static string TenantUrl(Alias alias, string url)
|
||||
{
|
||||
url = (!url.StartsWith("/")) ? "/" + url : url;
|
||||
@ -491,15 +480,6 @@ namespace Oqtane.Shared
|
||||
return querystring;
|
||||
}
|
||||
|
||||
public static string GetUrlPath(string url)
|
||||
{
|
||||
if (url.Contains("?"))
|
||||
{
|
||||
url = url.Substring(0, url.IndexOf("?"));
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
public static string LogMessage(object @class, string message)
|
||||
{
|
||||
return $"[{@class.GetType()}] {message}";
|
||||
|
@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<Version>6.1.2</Version>
|
||||
<Version>6.1.1</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/v6.1.2</PackageReleaseNotes>
|
||||
<PackageReleaseNotes>https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1</PackageReleaseNotes>
|
||||
<RepositoryUrl>https://github.com/oqtane/oqtane.framework</RepositoryUrl>
|
||||
<RepositoryType>Git</RepositoryType>
|
||||
<RootNamespace>Oqtane</RootNamespace>
|
||||
|
@ -15,19 +15,17 @@ namespace Oqtane.Updater
|
||||
/// <param name="args"></param>
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// requires 3 arguments - the ContentRootPath, the WebRootPath of the site, and a backup flag
|
||||
// requires 2 arguments - the ContentRootPath and the WebRootPath of the site
|
||||
|
||||
// for testing purposes you can uncomment and modify the logic below
|
||||
//Array.Resize(ref args, 3);
|
||||
//Array.Resize(ref args, 2);
|
||||
//args[0] = @"C:\yourpath\oqtane.framework\Oqtane.Server";
|
||||
//args[1] = @"C:\yourpath\oqtane.framework\Oqtane.Server\wwwroot";
|
||||
//args[2] = @"true";
|
||||
|
||||
if (args.Length == 3)
|
||||
if (args.Length == 2)
|
||||
{
|
||||
string contentrootfolder = args[0];
|
||||
string webrootfolder = args[1];
|
||||
bool backup = bool.Parse(args[2]);
|
||||
|
||||
string deployfolder = Path.Combine(contentrootfolder, "Packages");
|
||||
string backupfolder = Path.Combine(contentrootfolder, "Backup");
|
||||
@ -51,7 +49,6 @@ namespace Oqtane.Updater
|
||||
WriteLog(logFilePath, "Upgrade Process Started: " + DateTime.UtcNow.ToString() + Environment.NewLine);
|
||||
WriteLog(logFilePath, "ContentRootPath: " + contentrootfolder + Environment.NewLine);
|
||||
WriteLog(logFilePath, "WebRootPath: " + webrootfolder + Environment.NewLine);
|
||||
|
||||
if (packagename != "" && File.Exists(Path.Combine(webrootfolder, "app_offline.bak")))
|
||||
{
|
||||
WriteLog(logFilePath, "Located Upgrade Package: " + packagename + Environment.NewLine);
|
||||
@ -77,12 +74,12 @@ namespace Oqtane.Updater
|
||||
}
|
||||
|
||||
bool success = true;
|
||||
|
||||
if (backup)
|
||||
// ensure files are not locked
|
||||
if (CanAccessFiles(files))
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 10, "Preparing Backup Folder");
|
||||
WriteLog(logFilePath, "Preparing Backup Folder: " + backupfolder + Environment.NewLine);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
// clear out backup folder
|
||||
@ -115,28 +112,8 @@ namespace Oqtane.Updater
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(filename));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// try optimistically to backup the file
|
||||
File.Copy(file, filename);
|
||||
WriteLog(logFilePath, "Copy File: " + filename + Environment.NewLine);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if the file is locked, wait until it is unlocked
|
||||
if (CanAccessFile(file))
|
||||
{
|
||||
File.Copy(file, filename);
|
||||
WriteLog(logFilePath, "Copy File: " + filename + Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
// file could not be backed up, upgrade unsuccessful
|
||||
success = false;
|
||||
WriteLog(logFilePath, "Error Backing Up Files" + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
File.Copy(file, filename);
|
||||
WriteLog(logFilePath, "Copy File: " + filename + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -148,20 +125,17 @@ namespace Oqtane.Updater
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// extract files
|
||||
if (success)
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 50, "Extracting Files From Upgrade Package");
|
||||
WriteLog(logFilePath, "Extracting Files From Upgrade Package..." + Environment.NewLine);
|
||||
try
|
||||
// extract files
|
||||
if (success)
|
||||
{
|
||||
using (ZipArchive archive = ZipFile.OpenRead(packagename))
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 50, "Extracting Files From Upgrade Package");
|
||||
WriteLog(logFilePath, "Extracting Files From Upgrade Package..." + Environment.NewLine);
|
||||
try
|
||||
{
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
using (ZipArchive archive = ZipFile.OpenRead(packagename))
|
||||
{
|
||||
if (success)
|
||||
foreach (ZipArchiveEntry entry in archive.Entries)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(entry.Name))
|
||||
{
|
||||
@ -170,42 +144,20 @@ namespace Oqtane.Updater
|
||||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(filename));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// try optimistically to extract the file
|
||||
entry.ExtractToFile(filename, true);
|
||||
WriteLog(logFilePath, "Exact File: " + filename + Environment.NewLine);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// if the file is locked, wait until it is unlocked
|
||||
if (CanAccessFile(filename))
|
||||
{
|
||||
entry.ExtractToFile(filename, true);
|
||||
WriteLog(logFilePath, "Exact File: " + filename + Environment.NewLine);
|
||||
}
|
||||
else
|
||||
{
|
||||
// file could not be extracted, upgrade unsuccessful
|
||||
success = false;
|
||||
WriteLog(logFilePath, "Error Extracting Files From Upgrade Package" + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
entry.ExtractToFile(filename, true);
|
||||
WriteLog(logFilePath, "Exact File: " + filename + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
success = false;
|
||||
WriteLog(logFilePath, "Error Extracting Files From Upgrade Package: " + ex.Message + Environment.NewLine);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
success = false;
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 95, "Error Extracting Files From Upgrade Package", "bg-danger");
|
||||
WriteLog(logFilePath, "Error Extracting Files From Upgrade Package: " + ex.Message + Environment.NewLine);
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (backup)
|
||||
if (success)
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 90, "Removing Backup Folder");
|
||||
WriteLog(logFilePath, "Removing Backup Folder..." + Environment.NewLine);
|
||||
@ -222,12 +174,7 @@ namespace Oqtane.Updater
|
||||
WriteLog(logFilePath, "Error Removing Backup Folder: " + ex.Message + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 95, "Error Extracting Files From Upgrade Package", "bg-danger");
|
||||
|
||||
if (backup)
|
||||
else
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 50, "Upgrade Failed, Restoring Files From Backup Folder", "bg-warning");
|
||||
WriteLog(logFilePath, "Restoring Files From Backup Folder..." + Environment.NewLine);
|
||||
@ -254,14 +201,18 @@ namespace Oqtane.Updater
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 95, "Upgrade Failed: Could Not Backup Files", "bg-danger");
|
||||
WriteLog(logFilePath, "Upgrade Failed: Could Not Backup Files" + Environment.NewLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 95, "Upgrade Failed: Could Not Backup Files", "bg-danger");
|
||||
WriteLog(logFilePath, "Upgrade Failed: Could Not Backup Files" + Environment.NewLine);
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 95, "Upgrade Failed: Some Files Are Locked By The Hosting Environment", "bg-danger");
|
||||
WriteLog(logFilePath, "Upgrade Failed: Some Files Are Locked By The Hosting Environment" + Environment.NewLine);
|
||||
}
|
||||
|
||||
|
||||
UpdateOfflineContent(offlineFilePath, offlineTemplate, 100, "Upgrade Process Finished, Reloading", success ? "" : "bg-danger");
|
||||
Thread.Sleep(3000); //wait for 3 seconds to complete the upgrade process.
|
||||
// bring the app back online
|
||||
@ -289,45 +240,55 @@ namespace Oqtane.Updater
|
||||
}
|
||||
}
|
||||
|
||||
private static bool CanAccessFile(string filepath)
|
||||
private static bool CanAccessFiles(List<string> files)
|
||||
{
|
||||
// ensure file is not locked by another process
|
||||
// ensure files are not locked by another process
|
||||
// the IIS ShutdownTimeLimit defines the duration for app shutdown (default is 90 seconds)
|
||||
// websockets can delay application shutdown (ie. Blazor Server)
|
||||
int retries = 60;
|
||||
int sleep = 2;
|
||||
int attempts = 0;
|
||||
|
||||
bool canAccess = true;
|
||||
FileStream stream = null;
|
||||
|
||||
bool locked = true;
|
||||
while (attempts < retries && locked)
|
||||
int i = 0;
|
||||
while (i < (files.Count - 1) && canAccess)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(filepath))
|
||||
{
|
||||
stream = File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.None);
|
||||
locked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
locked = false;
|
||||
}
|
||||
}
|
||||
catch // file is locked by another process
|
||||
{
|
||||
Thread.Sleep(sleep * 1000); // wait
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream?.Close();
|
||||
}
|
||||
attempts += 1;
|
||||
}
|
||||
if (locked)
|
||||
{
|
||||
Console.WriteLine("File Locked: " + filepath);
|
||||
}
|
||||
string filepath = files[i];
|
||||
int attempts = 0;
|
||||
bool locked = true;
|
||||
|
||||
return !locked;
|
||||
while (attempts < retries && locked)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (File.Exists(filepath))
|
||||
{
|
||||
stream = File.Open(filepath, FileMode.Open, FileAccess.Read, FileShare.None);
|
||||
locked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
locked = false;
|
||||
}
|
||||
}
|
||||
catch // file is locked by another process
|
||||
{
|
||||
Thread.Sleep(sleep * 1000); // wait
|
||||
}
|
||||
finally
|
||||
{
|
||||
stream?.Close();
|
||||
}
|
||||
attempts += 1;
|
||||
}
|
||||
if (locked)
|
||||
{
|
||||
canAccess = false;
|
||||
Console.WriteLine("File Locked: " + filepath);
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
return canAccess;
|
||||
}
|
||||
|
||||
private static void UpdateOfflineContent(string filePath, string contentTemplate, int progress, string status, string progressClass = "")
|
||||
|
10
README.md
10
README.md
@ -1,4 +1,4 @@
|
||||
# Oqtane Framework
|
||||
# Oqtane Framewo
|
||||
|
||||

|
||||
|
||||
@ -14,14 +14,6 @@ Oqtane is being developed based on some fundamental principles which are outline
|
||||
|
||||
[6.1.1](https://github.com/oqtane/oqtane.framework/releases/tag/v6.1.1) was released on March 12, 2025 and is a maintenance release including 46 pull requests by 4 different contributors, pushing the total number of project commits all-time to over 6400. The Oqtane framework continues to evolve at a rapid pace to meet the needs of .NET developers.
|
||||
|
||||
# Try It Now!
|
||||
|
||||
Microsoft's Public Cloud (requires an Azure account)
|
||||
[](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Foqtane%2Foqtane.framework%2Fdev%2Fazuredeploy.json)
|
||||
|
||||
A free ASP.NET hosting account. No hidden fees. No credit card required.
|
||||
[](https://www.monsterasp.net/)
|
||||
|
||||
# Getting Started (Version 6.1.1)
|
||||
|
||||
**Installing using source code from the Dev/Master branch:**
|
||||
|
131
azuredeploy.json
131
azuredeploy.json
@ -2,24 +2,6 @@
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.2",
|
||||
"parameters": {
|
||||
"sqlServerName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The SQL Server name (must be unique). If you have an existing SQL Server in your resource group, you can specify its name and include its login credentials below."
|
||||
}
|
||||
},
|
||||
"sqlAdministratorLogin": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The Administrator login username for the SQL Server specified above"
|
||||
}
|
||||
},
|
||||
"sqlAdministratorLoginPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "The Administrator login password for the SQL Server specified above"
|
||||
}
|
||||
},
|
||||
"sqlDatabaseEditionTierDtuCapacity": {
|
||||
"type": "string",
|
||||
"defaultValue": "Basic-Basic-5-2",
|
||||
@ -44,19 +26,37 @@
|
||||
"GeneralPurpose-GP_S_Gen5_2-2-250"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "The SQL Database Configuration (Edition-Tier-DTU-Capacity)"
|
||||
"description": "Describes the database Edition, Tier, Dtu, Gigabytes (Edition-Tier-Dtu-Gigabytes)"
|
||||
}
|
||||
},
|
||||
"sqlServerName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the sql server. It has to be unique."
|
||||
}
|
||||
},
|
||||
"sqlDatabaseName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The SQL Database name (must be unique)"
|
||||
"description": "The name of the sql database. It has to be unique."
|
||||
}
|
||||
},
|
||||
"sqlAdministratorLogin": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The admin user of the SQL Server."
|
||||
}
|
||||
},
|
||||
"sqlAdministratorLoginPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "The password of the admin user of the SQL Server."
|
||||
}
|
||||
},
|
||||
"BlazorWebsiteName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The App Service name for the Blazor Website (must be unique). If you use the same name as the SQL Database specified above, it will make it easier to associate the resources later."
|
||||
"description": "The name of the website. It has to be unique."
|
||||
}
|
||||
},
|
||||
"BlazorSKU": {
|
||||
@ -77,12 +77,28 @@
|
||||
],
|
||||
"defaultValue": "B1",
|
||||
"metadata": {
|
||||
"description": "The App Service SKU for the Blazor Website"
|
||||
"description": "The SKU for the App Service Plan"
|
||||
}
|
||||
},
|
||||
"BlazorSKUCapacity": {
|
||||
"type": "int",
|
||||
"defaultValue": 1,
|
||||
"maxValue": 3,
|
||||
"minValue": 1,
|
||||
"metadata": {
|
||||
"description": "Describes plan's instance count"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"defaultValue": "[resourceGroup().location]",
|
||||
"metadata": {
|
||||
"description": "Location for all resources."
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"hostingPlanName": "[concat('Oqtane-HostingPlan-', uniqueString(resourceGroup().id))]",
|
||||
"hostingPlanName": "[concat('Oqtane-hostingplan-', uniqueString(resourceGroup().id))]",
|
||||
"databaseCollation": "SQL_Latin1_General_CP1_CI_AS",
|
||||
"databaseEditionTierDtuCapacity": "[split(parameters('sqlDatabaseEditionTierDtuCapacity'),'-')]",
|
||||
"databaseEdition": "[variables('databaseEditionTierDtuCapacity')[0]]",
|
||||
@ -99,9 +115,9 @@
|
||||
// ------------------------------------------------------
|
||||
{
|
||||
"type": "Microsoft.Sql/servers",
|
||||
"apiVersion": "2022-05-01-preview",
|
||||
"apiVersion": "2022-05-01-preview", // Updated API version
|
||||
"name": "[parameters('sqlServerName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"location": "[parameters('location')]",
|
||||
"tags": {
|
||||
"displayName": "SQL Server"
|
||||
},
|
||||
@ -116,9 +132,9 @@
|
||||
// ------------------------------------------------------
|
||||
{
|
||||
"type": "Microsoft.Sql/servers/databases",
|
||||
"apiVersion": "2022-05-01-preview",
|
||||
"apiVersion": "2022-05-01-preview", // Updated API version
|
||||
"name": "[format('{0}/{1}', parameters('sqlServerName'), parameters('sqlDatabaseName'))]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"location": "[parameters('location')]",
|
||||
"tags": {
|
||||
"displayName": "Database"
|
||||
},
|
||||
@ -153,11 +169,11 @@
|
||||
]
|
||||
},
|
||||
// ------------------------------------------------------
|
||||
// Firewall Rule
|
||||
// Firewall Rule (renamed to 'AllowAllMicrosoftAzureIps')
|
||||
// ------------------------------------------------------
|
||||
{
|
||||
"type": "Microsoft.Sql/servers/firewallRules",
|
||||
"apiVersion": "2022-05-01-preview",
|
||||
"apiVersion": "2022-05-01-preview", // Updated API version
|
||||
"name": "[format('{0}/{1}', parameters('sqlServerName'), 'AllowAllMicrosoftAzureIps')]",
|
||||
"properties": {
|
||||
"endIpAddress": "0.0.0.0",
|
||||
@ -172,15 +188,16 @@
|
||||
// ------------------------------------------------------
|
||||
{
|
||||
"type": "Microsoft.Web/serverfarms",
|
||||
"apiVersion": "2022-03-01",
|
||||
"apiVersion": "2022-03-01", // Updated API version
|
||||
"name": "[variables('hostingPlanName')]",
|
||||
"location": "[resourceGroup().location]",
|
||||
"location": "[parameters('location')]",
|
||||
"tags": {
|
||||
"displayName": "Blazor"
|
||||
},
|
||||
"sku": {
|
||||
"name": "[parameters('BlazorSKU')]",
|
||||
"capacity": "1"
|
||||
// If you want to auto-map to certain "tier" strings, you can do so. Here we just set the capacity:
|
||||
"capacity": "[parameters('BlazorSKUCapacity')]"
|
||||
},
|
||||
"properties": {
|
||||
"name": "[variables('hostingPlanName')]",
|
||||
@ -192,11 +209,13 @@
|
||||
// Web App
|
||||
// ------------------------------------------------------
|
||||
{
|
||||
"type": "Microsoft.Web/sites",
|
||||
"apiVersion": "2022-03-01",
|
||||
"apiVersion": "2022-03-01", // Updated API version
|
||||
"name": "[parameters('BlazorWebsiteName')]",
|
||||
"kind": "app",
|
||||
"location": "[resourceGroup().location]",
|
||||
"type": "Microsoft.Web/sites",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"[variables('hostingPlanName')]"
|
||||
],
|
||||
"tags": {
|
||||
"[concat('hidden-related:', resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName')))]": "empty",
|
||||
"displayName": "Website"
|
||||
@ -205,26 +224,44 @@
|
||||
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]",
|
||||
"siteConfig": {
|
||||
"webSocketsEnabled": true,
|
||||
// Updated .NET version "v9.0" from second snippet
|
||||
"netFrameworkVersion": "v9.0"
|
||||
}
|
||||
},
|
||||
"dependsOn": [
|
||||
"[variables('hostingPlanName')]"
|
||||
],
|
||||
"resources": [
|
||||
// --------------------------------------------------
|
||||
// ZIP Deploy
|
||||
// Source Control for your Web App
|
||||
// --------------------------------------------------
|
||||
{
|
||||
"type": "Microsoft.Web/sites/extensions",
|
||||
"apiVersion": "2024-04-01",
|
||||
"name": "[concat(parameters('BlazorWebsiteName'), '/ZipDeploy')]",
|
||||
"properties": {
|
||||
"packageUri": "https://github.com/oqtane/oqtane.framework/releases/download/v6.1.1/Oqtane.Framework.6.1.1.Install.zip"
|
||||
},
|
||||
"type": "sourcecontrols",
|
||||
"apiVersion": "2022-03-01",
|
||||
"name": "web",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites', parameters('BlazorWebsiteName'))]"
|
||||
]
|
||||
],
|
||||
"properties": {
|
||||
"repoUrl": "https://github.com/oqtane/oqtane.framework.git",
|
||||
"branch": "master",
|
||||
"isManualIntegration": true
|
||||
}
|
||||
},
|
||||
// --------------------------------------------------
|
||||
// Connection Strings (to use FQDN)
|
||||
// --------------------------------------------------
|
||||
{
|
||||
"type": "config",
|
||||
"apiVersion": "2022-03-01",
|
||||
"name": "connectionstrings",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Web/sites', parameters('BlazorWebsiteName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"DefaultConnection": {
|
||||
"value": "[concat('Data Source=tcp:', reference(resourceId('Microsoft.Sql/servers', parameters('sqlServerName'))).fullyQualifiedDomainName, ',1433;Initial Catalog=', parameters('sqlDatabaseName'), ';User Id=', parameters('sqlAdministratorLogin'), '@', reference(resourceId('Microsoft.Sql/servers', parameters('sqlServerName'))).fullyQualifiedDomainName, ';Password=', parameters('sqlAdministratorLoginPassword'), ';')]",
|
||||
"type": "SQLAzure"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Reference in New Issue
Block a user