From 53e5728ad22d29cc04f47fc0d50a44ae9ad68f47 Mon Sep 17 00:00:00 2001
From: Shaun Walker
Date: Fri, 10 Sep 2021 08:24:05 -0400
Subject: [PATCH] fix #1640 to resolve issue with server prerendering, upgrade
Installer to Bootstrap5, add more defensive logic and logging to
DatabaseManager, fix file logger issue, update Pager to use Bootstrap5
pagination, add expiry date support for commercial extensions
---
Oqtane.Client/App.razor | 27 +--
Oqtane.Client/Installer/Installer.razor | 3 +-
.../Modules/Admin/Languages/Index.razor | 21 --
.../Admin/ModuleDefinitions/Index.razor | 50 ++---
.../Modules/Admin/SystemInfo/Index.razor | 22 ---
.../Modules/Admin/Themes/Index.razor | 54 +++---
Oqtane.Client/Modules/Controls/Pager.razor | 94 ++++++---
Oqtane.Client/Resources/SharedResources.resx | 6 +
.../Infrastructure/DatabaseManager.cs | 180 ++++++++++--------
.../Infrastructure/Logging/FileLogger.cs | 2 +-
Oqtane.Shared/Models/Package.cs | 7 +-
11 files changed, 257 insertions(+), 209 deletions(-)
diff --git a/Oqtane.Client/App.razor b/Oqtane.Client/App.razor
index 01022680..ccb64327 100644
--- a/Oqtane.Client/App.razor
+++ b/Oqtane.Client/App.razor
@@ -33,23 +33,26 @@
private PageState PageState { get; set; }
+ protected override async Task OnParametersSetAsync()
+ {
+ _installation = await InstallationService.IsInstalled();
+ if (_installation.Alias != null)
+ {
+ SiteState.Alias = _installation.Alias;
+ }
+ else
+ {
+ _installation.Message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
+ }
+ _initialized = true;
+ }
+
protected override async Task OnAfterRenderAsync(bool firstRender)
{
- if (firstRender && !_initialized)
+ if (firstRender)
{
var interop = new Interop(JSRuntime);
SiteState.AntiForgeryToken = await interop.GetElementByName(Constants.RequestVerificationToken);
- _installation = await InstallationService.IsInstalled();
- if (_installation.Alias != null)
- {
- SiteState.Alias = _installation.Alias;
- }
- else
- {
- _installation.Message = "Site Not Configured Correctly - No Matching Alias Exists For Host Name";
- }
- _initialized = true;
- StateHasChanged();
}
}
diff --git a/Oqtane.Client/Installer/Installer.razor b/Oqtane.Client/Installer/Installer.razor
index 45ad895a..7c656e13 100644
--- a/Oqtane.Client/Installer/Installer.razor
+++ b/Oqtane.Client/Installer/Installer.razor
@@ -150,7 +150,8 @@
if (firstRender)
{
var interop = new Interop(JSRuntime);
- await interop.IncludeLink("app-stylesheet", "stylesheet", "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css", "text/css", "sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T", "anonymous", "");
+ await interop.IncludeLink("", "stylesheet", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css", "text/css", "sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC", "anonymous", "");
+ await interop.IncludeScript("", "https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js", "sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM", "anonymous", "", "head", "");
}
}
diff --git a/Oqtane.Client/Modules/Admin/Languages/Index.razor b/Oqtane.Client/Modules/Admin/Languages/Index.razor
index 1bca6f2c..08fc569b 100644
--- a/Oqtane.Client/Modules/Admin/Languages/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Languages/Index.razor
@@ -32,10 +32,6 @@ else
{
}
- else
- {
- @((MarkupString)PurchaseLink(context.Code))
- }
@@ -95,23 +91,6 @@ else
return upgradeavailable;
}
- private string PurchaseLink(string code)
- {
- string link = "";
- if (_packages != null)
- {
- var package = _packages.Where(item => item.PackageId == (Constants.PackageId + ".Client." + code)).FirstOrDefault();
- if (package != null)
- {
- if (package.Price > 0 && !string.IsNullOrEmpty(package.PaymentUrl))
- {
- link = "" + package.Price.ToString("$#,##0.00") + "";
- }
- }
- }
- return link;
- }
-
private async Task DownloadLanguage(string code)
{
try
diff --git a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
index 4b6cfca9..abce34a4 100644
--- a/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
+++ b/Oqtane.Client/Modules/Admin/ModuleDefinitions/Index.razor
@@ -22,27 +22,27 @@ else
|
@SharedLocalizer["Name"] |
@SharedLocalizer["Version"] |
+ @SharedLocalizer["Expires"] |
|
|
@if (context.AssemblyName != "Oqtane.Client")
- {
+ {
- }
+ }
|
@context.Name |
@context.Version |
+
+ @((MarkupString)PurchaseLink(context.PackageName))
+ |
@if (UpgradeAvailable(context.PackageName, context.Version))
{
}
- else
- {
- @((MarkupString)PurchaseLink(context.PackageName))
- }
|
@@ -71,6 +71,27 @@ else
}
}
+ private string PurchaseLink(string packagename)
+ {
+ string link = "";
+ if (!string.IsNullOrEmpty(packagename) && _packages != null)
+ {
+ var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
+ if (package != null)
+ {
+ if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
+ {
+ link += "" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "";
+ if (!string.IsNullOrEmpty(package.PaymentUrl))
+ {
+ link += " " + SharedLocalizer["Extend"] + "";
+ }
+ }
+ }
+ }
+ return link;
+ }
+
private bool UpgradeAvailable(string packagename, string version)
{
var upgradeavailable = false;
@@ -86,23 +107,6 @@ else
return upgradeavailable;
}
- private string PurchaseLink(string packagename)
- {
- string link = "";
- if (!string.IsNullOrEmpty(packagename) && _packages != null)
- {
- var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
- if (package != null)
- {
- if (package.Price > 0 && !string.IsNullOrEmpty(package.PaymentUrl))
- {
- link = "" + package.Price.ToString("$#,##0.00") + "";
- }
- }
- }
- return link;
- }
-
private async Task DownloadModule(string packagename, string version)
{
try
diff --git a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor
index 257a690d..9cd52ff2 100644
--- a/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor
+++ b/Oqtane.Client/Modules/Admin/SystemInfo/Index.razor
@@ -44,12 +44,6 @@
-
-
-
-
RegisterChecked(e))" /> @Localizer["Register"]
-
-
@@ -196,20 +190,4 @@
await logger.LogError(ex, "Error Restarting Application");
}
}
-
- private async Task RegisterChecked(ChangeEventArgs e)
- {
- try
- {
- if ((bool)e.Value)
- {
- await InstallationService.RegisterAsync(PageState.User.Email);
- AddModuleMessage(Localizer["Success.Register"], MessageType.Success);
- }
- }
- catch (Exception ex)
- {
- await logger.LogError(ex, "Error On Register");
- }
- }
}
\ No newline at end of file
diff --git a/Oqtane.Client/Modules/Admin/Themes/Index.razor b/Oqtane.Client/Modules/Admin/Themes/Index.razor
index f04e77aa..e656d4c6 100644
--- a/Oqtane.Client/Modules/Admin/Themes/Index.razor
+++ b/Oqtane.Client/Modules/Admin/Themes/Index.razor
@@ -21,29 +21,29 @@ else
|
|
- @SharedLocalizer["Name"] |
- @SharedLocalizer["Version"] |
+ @SharedLocalizer["Name"] |
+ @SharedLocalizer["Version"] |
+ @SharedLocalizer["Expires"] |
|
|
@if (context.AssemblyName != "Oqtane.Client")
- {
+ {
- }
+ }
|
@context.Name |
@context.Version |
+
+ @((MarkupString)PurchaseLink(context.PackageName))
+ |
@if (UpgradeAvailable(context.PackageName, context.Version))
{
}
- else
- {
- @((MarkupString)PurchaseLink(context.PackageName))
- }
|
|
@@ -73,6 +73,27 @@ else
}
}
+ private string PurchaseLink(string packagename)
+ {
+ string link = "";
+ if (!string.IsNullOrEmpty(packagename) && _packages != null)
+ {
+ var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
+ if (package != null)
+ {
+ if (package.ExpiryDate != null && package.ExpiryDate.Value.Date != DateTime.MaxValue.Date)
+ {
+ link += "" + package.ExpiryDate.Value.Date.ToString("MMM dd, yyyy") + "";
+ if (!string.IsNullOrEmpty(package.PaymentUrl))
+ {
+ link += " " + SharedLocalizer["Extend"] + "";
+ }
+ }
+ }
+ }
+ return link;
+ }
+
private bool UpgradeAvailable(string packagename, string version)
{
var upgradeavailable = false;
@@ -103,23 +124,6 @@ else
}
}
- private string PurchaseLink(string packagename)
- {
- string link = "";
- if (!string.IsNullOrEmpty(packagename) && _packages != null)
- {
- var package = _packages.Where(item => item.PackageId == packagename).FirstOrDefault();
- if (package != null)
- {
- if (package.Price > 0 && !string.IsNullOrEmpty(package.PaymentUrl))
- {
- link = "" + package.Price.ToString("$#,##0.00") + "";
- }
- }
- }
- return link;
- }
-
private async Task DeleteTheme(Theme Theme)
{
try
diff --git a/Oqtane.Client/Modules/Controls/Pager.razor b/Oqtane.Client/Modules/Controls/Pager.razor
index c0b285b7..3f128785 100644
--- a/Oqtane.Client/Modules/Controls/Pager.razor
+++ b/Oqtane.Client/Modules/Controls/Pager.razor
@@ -5,40 +5,63 @@
@if (Toolbar == "Top")
{
-
+
+
}
@if (Format == "Table")
{
@@ -74,40 +97,63 @@
}
@if (Toolbar == "Bottom")
{
-
+
+
}
diff --git a/Oqtane.Client/Resources/SharedResources.resx b/Oqtane.Client/Resources/SharedResources.resx
index ca38d971..86a88e73 100644
--- a/Oqtane.Client/Resources/SharedResources.resx
+++ b/Oqtane.Client/Resources/SharedResources.resx
@@ -303,4 +303,10 @@
Day Trial
+
+ Expires
+
+
+ Extend
+
\ No newline at end of file
diff --git a/Oqtane.Server/Infrastructure/DatabaseManager.cs b/Oqtane.Server/Infrastructure/DatabaseManager.cs
index 5d7c9c0a..1b8ec468 100644
--- a/Oqtane.Server/Infrastructure/DatabaseManager.cs
+++ b/Oqtane.Server/Infrastructure/DatabaseManager.cs
@@ -250,6 +250,7 @@ namespace Oqtane.Infrastructure
catch (Exception ex)
{
result.Message = ex.Message;
+ _filelogger.LogError(Utilities.LogMessage(this, result.Message));
}
return result;
@@ -288,6 +289,7 @@ namespace Oqtane.Infrastructure
catch (Exception ex)
{
result.Message = ex.Message;
+ _filelogger.LogError(Utilities.LogMessage(this, result.Message));
}
}
else
@@ -328,6 +330,7 @@ namespace Oqtane.Infrastructure
catch (Exception ex)
{
result.Message = ex.Message;
+ _filelogger.LogError(Utilities.LogMessage(this, result.Message));
}
}
}
@@ -432,6 +435,7 @@ namespace Oqtane.Infrastructure
catch (Exception ex)
{
result.Message = ex.Message;
+ _filelogger.LogError(Utilities.LogMessage(this, result.Message));
}
// execute any version specific upgrade logic
@@ -539,6 +543,10 @@ namespace Oqtane.Infrastructure
{
result.Success = true;
}
+ else
+ {
+ _filelogger.LogError(Utilities.LogMessage(this, result.Message));
+ }
return result;
}
@@ -549,110 +557,124 @@ namespace Oqtane.Infrastructure
if (!string.IsNullOrEmpty(install.TenantName) && !string.IsNullOrEmpty(install.Aliases) && !string.IsNullOrEmpty(install.SiteName))
{
- using (var scope = _serviceScopeFactory.CreateScope())
+ try
{
- // set the alias explicitly so the tenant can be resolved
- var aliases = scope.ServiceProvider.GetRequiredService();
- var firstAlias = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
- var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
- var tenantManager = scope.ServiceProvider.GetRequiredService();
- tenantManager.SetAlias(alias);
-
- var sites = scope.ServiceProvider.GetRequiredService();
- var site = sites.GetSites().FirstOrDefault(item => item.Name == install.SiteName);
- if (site == null)
+ using (var scope = _serviceScopeFactory.CreateScope())
{
- var tenants = scope.ServiceProvider.GetRequiredService();
- var users = scope.ServiceProvider.GetRequiredService();
- var roles = scope.ServiceProvider.GetRequiredService();
- var userRoles = scope.ServiceProvider.GetRequiredService();
- var folders = scope.ServiceProvider.GetRequiredService();
- var log = scope.ServiceProvider.GetRequiredService();
- var identityUserManager = scope.ServiceProvider.GetRequiredService>();
+ // set the alias explicitly so the tenant can be resolved
+ var aliases = scope.ServiceProvider.GetRequiredService();
+ var firstAlias = install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0];
+ var alias = aliases.GetAliases().FirstOrDefault(item => item.Name == firstAlias);
+ var tenantManager = scope.ServiceProvider.GetRequiredService();
+ tenantManager.SetAlias(alias);
- var tenant = tenants.GetTenants().FirstOrDefault(item => item.Name == install.TenantName);
-
- site = new Site
+ var sites = scope.ServiceProvider.GetRequiredService();
+ var site = sites.GetSites().FirstOrDefault(item => item.Name == install.SiteName);
+ if (site == null)
{
- TenantId = tenant.TenantId,
- Name = install.SiteName,
- LogoFileId = null,
- DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
- DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
- AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
- SiteTemplateType = install.SiteTemplate
- };
- site = sites.AddSite(site);
+ var tenants = scope.ServiceProvider.GetRequiredService();
+ var users = scope.ServiceProvider.GetRequiredService();
+ var roles = scope.ServiceProvider.GetRequiredService();
+ var userRoles = scope.ServiceProvider.GetRequiredService();
+ var folders = scope.ServiceProvider.GetRequiredService();
+ var log = scope.ServiceProvider.GetRequiredService();
+ var identityUserManager = scope.ServiceProvider.GetRequiredService>();
- if (!string.IsNullOrEmpty(install.HostUsername))
- {
- var identityUser = identityUserManager.FindByNameAsync(install.HostUsername).GetAwaiter().GetResult();
- if (identityUser == null)
+ var tenant = tenants.GetTenants().FirstOrDefault(item => item.Name == install.TenantName);
+
+ site = new Site
{
- identityUser = new IdentityUser { UserName = install.HostUsername, Email = install.HostEmail, EmailConfirmed = true };
- var create = identityUserManager.CreateAsync(identityUser, install.HostPassword).GetAwaiter().GetResult();
- if (create.Succeeded)
+ TenantId = tenant.TenantId,
+ Name = install.SiteName,
+ LogoFileId = null,
+ DefaultThemeType = (!string.IsNullOrEmpty(install.DefaultTheme)) ? install.DefaultTheme : Constants.DefaultTheme,
+ DefaultContainerType = (!string.IsNullOrEmpty(install.DefaultContainer)) ? install.DefaultContainer : Constants.DefaultContainer,
+ AdminContainerType = (!string.IsNullOrEmpty(install.DefaultAdminContainer)) ? install.DefaultAdminContainer : Constants.DefaultAdminContainer,
+ SiteTemplateType = install.SiteTemplate
+ };
+ site = sites.AddSite(site);
+
+ if (!string.IsNullOrEmpty(install.HostUsername))
+ {
+ var identityUser = identityUserManager.FindByNameAsync(install.HostUsername).GetAwaiter().GetResult();
+ if (identityUser == null)
{
- var user = new User
+ identityUser = new IdentityUser { UserName = install.HostUsername, Email = install.HostEmail, EmailConfirmed = true };
+ var create = identityUserManager.CreateAsync(identityUser, install.HostPassword).GetAwaiter().GetResult();
+ if (create.Succeeded)
{
- SiteId = site.SiteId,
- Username = install.HostUsername,
- Password = install.HostPassword,
- Email = install.HostEmail,
- DisplayName = install.HostName,
- LastIPAddress = "",
- LastLoginOn = null
- };
-
- user = users.AddUser(user);
- var hostRoleId = roles.GetRoles(user.SiteId, true).FirstOrDefault(item => item.Name == RoleNames.Host)?.RoleId ?? 0;
- var userRole = new UserRole { UserId = user.UserId, RoleId = hostRoleId, EffectiveDate = null, ExpiryDate = null };
- userRoles.AddUserRole(userRole);
-
- // add user folder
- var folder = folders.GetFolder(user.SiteId, Utilities.PathCombine("Users", Path.DirectorySeparatorChar.ToString()));
- if (folder != null)
- {
- folders.AddFolder(new Folder
+ var user = new User
{
- SiteId = folder.SiteId,
- ParentId = folder.FolderId,
- Name = "My Folder",
- Type = FolderTypes.Private,
- Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
- Order = 1,
- IsSystem = true,
- Permissions = new List
+ SiteId = site.SiteId,
+ Username = install.HostUsername,
+ Password = install.HostPassword,
+ Email = install.HostEmail,
+ DisplayName = install.HostName,
+ LastIPAddress = "",
+ LastLoginOn = null
+ };
+
+ user = users.AddUser(user);
+ var hostRoleId = roles.GetRoles(user.SiteId, true).FirstOrDefault(item => item.Name == RoleNames.Host)?.RoleId ?? 0;
+ var userRole = new UserRole { UserId = user.UserId, RoleId = hostRoleId, EffectiveDate = null, ExpiryDate = null };
+ userRoles.AddUserRole(userRole);
+
+ // add user folder
+ var folder = folders.GetFolder(user.SiteId, Utilities.PathCombine("Users", Path.DirectorySeparatorChar.ToString()));
+ if (folder != null)
+ {
+ folders.AddFolder(new Folder
+ {
+ SiteId = folder.SiteId,
+ ParentId = folder.FolderId,
+ Name = "My Folder",
+ Type = FolderTypes.Private,
+ Path = Utilities.PathCombine(folder.Path, user.UserId.ToString(), Path.DirectorySeparatorChar.ToString()),
+ Order = 1,
+ IsSystem = true,
+ Permissions = new List
{
new Permission(PermissionNames.Browse, user.UserId, true),
new Permission(PermissionNames.View, RoleNames.Everyone, true),
new Permission(PermissionNames.Edit, user.UserId, true),
}.EncodePermissions(),
- });
+ });
+ }
}
}
}
- }
- foreach (var aliasName in install.Aliases.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries))
- {
- alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
- if (alias != null)
+ foreach (var aliasName in install.Aliases.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
- alias.SiteId = site.SiteId;
- aliases.UpdateAlias(alias);
+ alias = aliases.GetAliases().FirstOrDefault(item => item.Name == aliasName);
+ if (alias != null)
+ {
+ alias.SiteId = site.SiteId;
+ aliases.UpdateAlias(alias);
+ }
}
+
+ tenant.Version = Constants.Version;
+ tenants.UpdateTenant(tenant);
+
+ if (site != null) log.Log(site.SiteId, Shared.LogLevel.Information, this, LogFunction.Create, "Site Created {Site}", site);
}
-
- tenant.Version = Constants.Version;
- tenants.UpdateTenant(tenant);
-
- if (site != null) log.Log(site.SiteId, Shared.LogLevel.Information, this, LogFunction.Create, "Site Created {Site}", site);
}
}
+ catch (Exception ex)
+ {
+ result.Message = "An Error Occurred Creating Site - " + ex.Message;
+ }
}
- result.Success = true;
+ if (string.IsNullOrEmpty(result.Message))
+ {
+ result.Success = true;
+ }
+ else
+ {
+ _filelogger.LogError(Utilities.LogMessage(this, result.Message));
+ }
return result;
}
diff --git a/Oqtane.Server/Infrastructure/Logging/FileLogger.cs b/Oqtane.Server/Infrastructure/Logging/FileLogger.cs
index d793e631..91f1f948 100644
--- a/Oqtane.Server/Infrastructure/Logging/FileLogger.cs
+++ b/Oqtane.Server/Infrastructure/Logging/FileLogger.cs
@@ -55,7 +55,7 @@ namespace Oqtane.Infrastructure
var filepath = Path.Combine(folder, "error.log");
// only retain an error log for the current day as it is intended for development purposes
- if (File.GetCreationTime(filepath).ToUniversalTime().Date < DateTime.UtcNow.Date && File.Exists(filepath))
+ if (File.Exists(filepath) && File.GetLastWriteTimeUtc(filepath).Date < DateTime.UtcNow.Date)
{
File.Delete(filepath);
}
diff --git a/Oqtane.Shared/Models/Package.cs b/Oqtane.Shared/Models/Package.cs
index 83450574..859bd4ab 100644
--- a/Oqtane.Shared/Models/Package.cs
+++ b/Oqtane.Shared/Models/Package.cs
@@ -68,7 +68,7 @@ namespace Oqtane.Models
public int Vulnerabilities { get; set; }
///
- /// The price of the package
+ /// The price of the package ( if commercial )
///
public decimal Price { get; set; }
@@ -81,5 +81,10 @@ namespace Oqtane.Models
/// The trial period in days ( if commercial )
///
public int TrialPeriod { get; set; }
+
+ ///
+ /// The expiry date of the package ( if commercial )
+ ///
+ public DateTime? ExpiryDate { get; set; }
}
}