fix #5005 - adds versioning (ie. fingerprinting) for static assets - core, modules, and themes.

This commit is contained in:
sbwalker
2025-01-27 16:34:47 -05:00
parent 7a9c637e03
commit 153a689bdb
15 changed files with 145 additions and 60 deletions

View File

@ -65,7 +65,7 @@ namespace Oqtane.Models
public string Categories { get; set; }
/// <summary>
/// Version information of this Module based on the DLL / NuGet package.
/// Version information of this Module based on the information stored in its assembly
/// </summary>
public string Version { get; set; }
@ -144,6 +144,9 @@ namespace Oqtane.Models
[NotMapped]
public bool IsPortable { get; set; }
[NotMapped]
public string Hash { get; set; }
#region Deprecated Properties
[Obsolete("The Permissions property is deprecated. Use PermissionList instead", false)]

View File

@ -83,7 +83,21 @@ namespace Oqtane.Models
/// </summary>
public string Namespace { get; set; }
public Resource Clone(ResourceLevel level, string name)
/// <summary>
/// The version of the theme or module that declared the resource - only used in SiteRouter
/// </summary>
public string Version
{
set
{
if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(Url) && !Url.Contains("?"))
{
Url += "?v=" + value;
}
}
}
public Resource Clone(ResourceLevel level, string name, string version)
{
var resource = new Resource();
resource.ResourceType = ResourceType;
@ -106,6 +120,7 @@ namespace Oqtane.Models
}
resource.Level = level;
resource.Namespace = name;
resource.Version = version;
return resource;
}

View File

@ -187,6 +187,12 @@ namespace Oqtane.Models
[NotMapped]
public List<Theme> Themes { get; set; }
/// <summary>
/// hash code for static assets
/// </summary>
[NotMapped]
public string Hash { get; set; }
public Site Clone()
{
return new Site
@ -227,7 +233,8 @@ namespace Oqtane.Models
Settings = Settings.ToDictionary(setting => setting.Key, setting => setting.Value),
Pages = Pages.ConvertAll(page => page.Clone()),
Languages = Languages.ConvertAll(language => language.Clone()),
Themes = Themes
Themes = Themes,
Hash = Hash
};
}

View File

@ -40,10 +40,13 @@ namespace Oqtane.Models
/// </summary>
public string Name { get; set; }
// additional ITheme properties
[NotMapped]
/// <summary>
/// Version information of this Theme based on the information stored in its assembly
/// </summary>
public string Version { get; set; }
// additional ITheme properties
[NotMapped]
public string Owner { get; set; }
@ -78,17 +81,25 @@ namespace Oqtane.Models
// internal properties
[NotMapped]
public int SiteId { get; set; }
[NotMapped]
public bool IsEnabled { get; set; }
[NotMapped]
public string AssemblyName { get; set; }
[NotMapped]
public List<ThemeControl> Themes { get; set; }
[NotMapped]
public List<ThemeControl> Containers { get; set; }
[NotMapped]
public string Template { get; set; }
[NotMapped]
public string Hash { get; set; }
#region Obsolete Properties
[Obsolete("This property is obsolete. Use Themes instead.", false)]

View File

@ -575,7 +575,6 @@ namespace Oqtane.Shared
}
else if (expiryDate.HasValue)
{
// Include equality check here
return currentUtcTime <= expiryDate.Value;
}
else
@ -586,32 +585,40 @@ namespace Oqtane.Shared
public static bool ValidateEffectiveExpiryDates(DateTime? effectiveDate, DateTime? expiryDate)
{
// Treat DateTime.MinValue as null
effectiveDate ??= DateTime.MinValue;
expiryDate ??= DateTime.MinValue;
// Check if both effectiveDate and expiryDate have values
if (effectiveDate != DateTime.MinValue && expiryDate != DateTime.MinValue)
{
return effectiveDate <= expiryDate;
}
// Check if only effectiveDate has a value
else if (effectiveDate != DateTime.MinValue)
{
return true;
}
// Check if only expiryDate has a value
else if (expiryDate != DateTime.MinValue)
{
return true;
}
// If neither effectiveDate nor expiryDate has a value, consider the page/module visible
else
{
return true;
}
}
public static string GenerateSimpleHash(string text)
{
unchecked // prevent overflow exception
{
int hash = 23;
foreach (char c in text)
{
hash = hash * 31 + c;
}
return hash.ToString("X8");
}
}
[Obsolete("ContentUrl(Alias alias, int fileId) is deprecated. Use FileUrl(Alias alias, int fileId) instead.", false)]
public static string ContentUrl(Alias alias, int fileId)
{