diff --git a/Directory.Build.props b/Directory.Build.props
index 52635c8fc2..f9fb83457d 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -14,6 +14,7 @@
en-US
enable
nullable
+ true
enable
true
false
diff --git a/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj b/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj
index 10cc87c013..a1bd4e1694 100644
--- a/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj
+++ b/src/Umbraco.Cms.Api.Common/Umbraco.Cms.Api.Common.csproj
@@ -3,7 +3,6 @@
Umbraco CMS - API Common
Contains the bits and pieces that are shared between the Umbraco CMS APIs.
-
diff --git a/src/Umbraco.Cms.Api.Delivery/Umbraco.Cms.Api.Delivery.csproj b/src/Umbraco.Cms.Api.Delivery/Umbraco.Cms.Api.Delivery.csproj
index 8948a49a1a..5e32b81eeb 100644
--- a/src/Umbraco.Cms.Api.Delivery/Umbraco.Cms.Api.Delivery.csproj
+++ b/src/Umbraco.Cms.Api.Delivery/Umbraco.Cms.Api.Delivery.csproj
@@ -3,7 +3,10 @@
Umbraco CMS - Delivery API
Contains the presentation layer for the Umbraco CMS Delivery API.
-
+
+
+ ASP0019
+
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs
index b64c252a1a..97131adcb9 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Indexer/RebuildIndexerController.cs
@@ -1,4 +1,4 @@
-using Asp.Versioning;
+using Asp.Versioning;
using Examine;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
@@ -38,7 +38,7 @@ public class RebuildIndexerController : IndexerControllerBase
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task Rebuild(CancellationToken cancellationToken, string indexName)
{
- if (!_examineManager.TryGetIndex(indexName, out var index))
+ if (!_examineManager.TryGetIndex(indexName, out IIndex? index))
{
var invalidModelProblem = new ProblemDetails
{
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/BuildModelsBuilderController.cs b/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/BuildModelsBuilderController.cs
index 9d5f67cb1f..14adb70c3b 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/BuildModelsBuilderController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/ModelsBuilder/BuildModelsBuilderController.cs
@@ -1,8 +1,9 @@
-using System;
+using System;
using System.Threading.Tasks;
using Asp.Versioning;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Infrastructure.ModelsBuilder;
@@ -16,12 +17,13 @@ public class BuildModelsBuilderController : ModelsBuilderControllerBase
{
private ModelsBuilderSettings _modelsBuilderSettings;
private readonly ModelsGenerationError _mbErrors;
- private readonly ModelsGenerator _modelGenerator;
+ private readonly IModelsGenerator _modelGenerator;
+ [ActivatorUtilitiesConstructor]
public BuildModelsBuilderController(
IOptionsMonitor modelsBuilderSettings,
ModelsGenerationError mbErrors,
- ModelsGenerator modelGenerator)
+ IModelsGenerator modelGenerator)
{
_mbErrors = mbErrors;
_modelGenerator = modelGenerator;
@@ -30,6 +32,26 @@ public class BuildModelsBuilderController : ModelsBuilderControllerBase
modelsBuilderSettings.OnChange(x => _modelsBuilderSettings = x);
}
+ [Obsolete("Please use the constructor that accepts IModelsGenerator only. Will be removed in V16.")]
+ public BuildModelsBuilderController(
+ IOptionsMonitor modelsBuilderSettings,
+ ModelsGenerationError mbErrors,
+ ModelsGenerator modelGenerator)
+ : this(modelsBuilderSettings, mbErrors, (IModelsGenerator)modelGenerator)
+ {
+ }
+
+ // this constructor is required for the DI, otherwise it'll throw an "Ambiguous Constructor" errors at boot time.
+ [Obsolete("Please use the constructor that accepts IModelsGenerator only. Will be removed in V16.")]
+ public BuildModelsBuilderController(
+ IOptionsMonitor modelsBuilderSettings,
+ ModelsGenerationError mbErrors,
+ IModelsGenerator modelGenerator,
+ ModelsGenerator notUsed)
+ : this(modelsBuilderSettings, mbErrors, modelGenerator)
+ {
+ }
+
[HttpPost("build")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status428PreconditionRequired)]
diff --git a/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs b/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs
index fd6d9116c5..5a247a647c 100644
--- a/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs
+++ b/src/Umbraco.Cms.Api.Management/Controllers/Security/BackOfficeController.cs
@@ -1,4 +1,4 @@
-using System.Security.Claims;
+using System.Security.Claims;
using Asp.Versioning;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Authentication;
@@ -217,7 +217,7 @@ public class BackOfficeController : SecurityControllerBase
///
/// Called when a user links an external login provider in the back office
///
- ///
+ ///
///
// This method is marked as AllowAnonymous and protected with a secret (linkKey) inside the model for the following reasons
// - when a js client uses the fetch api (or old ajax requests) they can send a bearer token
diff --git a/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs
index 11b2d18134..c5cd70ed49 100644
--- a/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs
+++ b/src/Umbraco.Cms.Api.Management/Factories/MediaTypeEditingPresentationFactory.cs
@@ -1,5 +1,4 @@
-using Umbraco.Cms.Api.Management.ViewModels.MediaType;
-using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Api.Management.ViewModels.MediaType;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentTypeEditing;
using Umbraco.Cms.Core.Services;
diff --git a/src/Umbraco.Cms.Api.Management/Umbraco.Cms.Api.Management.csproj b/src/Umbraco.Cms.Api.Management/Umbraco.Cms.Api.Management.csproj
index 37ab3611de..88ee0cef62 100644
--- a/src/Umbraco.Cms.Api.Management/Umbraco.Cms.Api.Management.csproj
+++ b/src/Umbraco.Cms.Api.Management/Umbraco.Cms.Api.Management.csproj
@@ -7,7 +7,10 @@
Umbraco.Cms.Api.Management
Umbraco.Cms.Api.Management
-
+
+
+ false
+
diff --git a/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj b/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj
index 549ea5cb40..77aed066d8 100644
--- a/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj
+++ b/src/Umbraco.Cms.Imaging.ImageSharp/Umbraco.Cms.Imaging.ImageSharp.csproj
@@ -3,7 +3,6 @@
Umbraco CMS - Imaging - ImageSharp
Adds imaging support using ImageSharp/ImageSharp.Web to Umbraco CMS.
-
diff --git a/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj b/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj
index c513082675..16bac191d5 100644
--- a/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj
+++ b/src/Umbraco.Cms.Imaging.ImageSharp2/Umbraco.Cms.Imaging.ImageSharp2.csproj
@@ -3,7 +3,6 @@
Umbraco CMS - Imaging - ImageSharp 2
Adds imaging support using ImageSharp/ImageSharp.Web version 2 to Umbraco CMS.
-
diff --git a/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj b/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj
index d663ef0197..a1864f636f 100644
--- a/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj
+++ b/src/Umbraco.Cms.Persistence.EFCore.SqlServer/Umbraco.Cms.Persistence.EFCore.SqlServer.csproj
@@ -3,7 +3,6 @@
Umbraco CMS - Persistence - Entity Framework Core - SQL Server migrations
Adds support for Entity Framework Core SQL Server migrations to Umbraco CMS.
-
diff --git a/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj b/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj
index 36751bb869..f847ef4786 100644
--- a/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj
+++ b/src/Umbraco.Cms.Persistence.EFCore.Sqlite/Umbraco.Cms.Persistence.EFCore.Sqlite.csproj
@@ -3,7 +3,6 @@
Umbraco CMS - Persistence - Entity Framework Core - SQLite migrations
Adds support for Entity Framework Core SQLite migrations to Umbraco CMS.
-
diff --git a/src/Umbraco.Cms.Persistence.EFCore/Locking/SqliteEFCoreDistributedLockingMechanism.cs b/src/Umbraco.Cms.Persistence.EFCore/Locking/SqliteEFCoreDistributedLockingMechanism.cs
index 23b3d8d410..8308ae4d3a 100644
--- a/src/Umbraco.Cms.Persistence.EFCore/Locking/SqliteEFCoreDistributedLockingMechanism.cs
+++ b/src/Umbraco.Cms.Persistence.EFCore/Locking/SqliteEFCoreDistributedLockingMechanism.cs
@@ -115,12 +115,7 @@ internal class SqliteEFCoreDistributedLockingMechanism : IDistributedLockingM
// Mostly no-op just check that we didn't end up ReadUncommitted for real.
private void ObtainReadLock()
{
- IEfCoreScope? efCoreScope = _parent._efCoreScopeAccessor.Value.AmbientScope;
-
- if (efCoreScope is null)
- {
- throw new PanicException("No current ambient scope");
- }
+ IEfCoreScope? efCoreScope = _parent._efCoreScopeAccessor.Value.AmbientScope ?? throw new PanicException("No current ambient scope");
efCoreScope.ExecuteWithContextAsync(async database =>
{
@@ -136,12 +131,7 @@ internal class SqliteEFCoreDistributedLockingMechanism : IDistributedLockingM
// lock occurs for entire database as opposed to row/table.
private void ObtainWriteLock()
{
- IEfCoreScope? efCoreScope = _parent._efCoreScopeAccessor.Value.AmbientScope;
-
- if (efCoreScope is null)
- {
- throw new PanicException("No ambient scope");
- }
+ IEfCoreScope? efCoreScope = _parent._efCoreScopeAccessor.Value.AmbientScope ?? throw new PanicException("No ambient scope");
efCoreScope.ExecuteWithContextAsync(async database =>
{
diff --git a/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj b/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj
index 4500c2812b..d5fc7229b0 100644
--- a/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj
+++ b/src/Umbraco.Cms.Persistence.EFCore/Umbraco.Cms.Persistence.EFCore.csproj
@@ -3,8 +3,12 @@
Umbraco CMS - Persistence - Entity Framework Core
Adds support for Entity Framework Core to Umbraco CMS.
-
-
+
+
+ IDE0270,CS0108,CS1998
+
+
diff --git a/src/Umbraco.Cms.Persistence.SqlServer/LocalDb.cs b/src/Umbraco.Cms.Persistence.SqlServer/LocalDb.cs
index 6fcdfca76a..a8a6480c89 100644
--- a/src/Umbraco.Cms.Persistence.SqlServer/LocalDb.cs
+++ b/src/Umbraco.Cms.Persistence.SqlServer/LocalDb.cs
@@ -420,7 +420,13 @@ public class LocalDb
///
public bool CreateDatabase(string databaseName, string filesPath)
{
- GetDatabaseFiles(databaseName, filesPath, out var logName, out _, out _, out var mdfFilename,
+ GetDatabaseFiles(
+ databaseName,
+ filesPath,
+ out var logName,
+ out _,
+ out _,
+ out var mdfFilename,
out var ldfFilename);
using (var conn = new SqlConnection(_masterCstr))
@@ -463,7 +469,9 @@ public class LocalDb
{
conn.Open();
- SetCommand(cmd, @"
+ SetCommand(
+ cmd,
+ @"
SELECT name, filename FROM master.dbo.sysdatabases WHERE ('[' + name + ']' = @0 OR name = @0)",
databaseName);
@@ -554,11 +562,7 @@ public class LocalDb
{
conn.Open();
- var mdf = GetDatabase(cmd, databaseName);
- if (mdf == null)
- {
- throw new InvalidOperationException("Database does not exist.");
- }
+ var mdf = GetDatabase(cmd, databaseName) ?? throw new InvalidOperationException("Database does not exist.");
DetachDatabase(cmd, databaseName);
@@ -597,9 +601,12 @@ public class LocalDb
/// The LDF logical name.
/// The MDF filename.
/// The LDF filename.
- public void GetFilenames(string databaseName,
- out string? mdfName, out string? ldfName,
- out string? mdfFilename, out string? ldfFilename)
+ public void GetFilenames(
+ string databaseName,
+ out string? mdfName,
+ out string? ldfName,
+ out string? mdfFilename,
+ out string? ldfFilename)
{
using (var conn = new SqlConnection(_masterCstr))
using (SqlCommand? cmd = conn.CreateCommand())
@@ -621,7 +628,9 @@ public class LocalDb
{
conn.Open();
- SetCommand(cmd, @"
+ SetCommand(
+ cmd,
+ @"
DECLARE @sql VARCHAR(MAX);
SELECT @sql = COALESCE(@sql,'') + 'kill ' + CONVERT(VARCHAR, SPId) + ';'
FROM master.sys.sysprocesses
@@ -640,7 +649,9 @@ public class LocalDb
/// The full filename of the MDF file, if the database exists, otherwise null.
private static string? GetDatabase(SqlCommand cmd, string databaseName)
{
- SetCommand(cmd, @"
+ SetCommand(
+ cmd,
+ @"
SELECT name, filename FROM master.dbo.sysdatabases WHERE ('[' + name + ']' = @0 OR name = @0)",
databaseName);
@@ -707,7 +718,7 @@ public class LocalDb
File.Delete(mdf);
}
- ldf = ldf ?? GetLogFilename(mdf);
+ ldf ??= GetLogFilename(mdf);
if (File.Exists(ldf))
{
File.Delete(ldf);
@@ -726,7 +737,7 @@ public class LocalDb
throw new ArgumentException("Not a valid MDF filename (no .mdf extension).", nameof(mdfFilename));
}
- return mdfFilename.Substring(0, mdfFilename.Length - ".mdf".Length) + "_log.ldf";
+ return mdfFilename[..^".mdf".Length] + "_log.ldf";
}
///
@@ -743,7 +754,9 @@ public class LocalDb
var unused1 = cmd.ExecuteNonQuery();
- SetCommand(cmd, @"
+ SetCommand(
+ cmd,
+ @"
EXEC sp_detach_db @dbname=@0",
databaseName);
@@ -758,8 +771,14 @@ public class LocalDb
/// The directory containing database files.
private static void AttachDatabase(SqlCommand cmd, string databaseName, string filesPath)
{
- GetDatabaseFiles(databaseName, filesPath,
- out var logName, out _, out _, out var mdfFilename, out var ldfFilename);
+ GetDatabaseFiles(
+ databaseName,
+ filesPath,
+ out var logName,
+ out _,
+ out _,
+ out var mdfFilename,
+ out var ldfFilename);
// cannot use parameters on CREATE DATABASE
// ie "CREATE DATABASE @0 ..." does not work
@@ -802,13 +821,19 @@ public class LocalDb
/// The LDF logical name.
/// The MDF filename.
/// The LDF filename.
- private void GetFilenames(SqlCommand cmd, string databaseName,
- out string? mdfName, out string? ldfName,
- out string? mdfFilename, out string? ldfFilename)
+ private void GetFilenames(
+ SqlCommand cmd,
+ string databaseName,
+ out string? mdfName,
+ out string? ldfName,
+ out string? mdfFilename,
+ out string? ldfFilename)
{
mdfName = ldfName = mdfFilename = ldfFilename = null;
- SetCommand(cmd, @"
+ SetCommand(
+ cmd,
+ @"
SELECT DB_NAME(database_id), type_desc, name, physical_name
FROM master.sys.master_files
WHERE database_id=DB_ID(@0)",
@@ -854,21 +879,32 @@ public class LocalDb
/// .
/// Extensions are used eg to copy MyDatabase.mdf to MyDatabase.mdf.temp.
///
- public void CopyDatabaseFiles(string databaseName, string filesPath,
- string? targetDatabaseName = null, string? targetFilesPath = null,
- string? sourceExtension = null, string? targetExtension = null,
- bool overwrite = false, bool delete = false)
+ public void CopyDatabaseFiles(
+ string databaseName,
+ string filesPath,
+ string? targetDatabaseName = null,
+ string? targetFilesPath = null,
+ string? sourceExtension = null,
+ string? targetExtension = null,
+ bool overwrite = false,
+ bool delete = false)
{
var nop = (targetFilesPath == null || targetFilesPath == filesPath)
&& (targetDatabaseName == null || targetDatabaseName == databaseName)
- && (sourceExtension == null && targetExtension == null || sourceExtension == targetExtension);
+ && ((sourceExtension == null && targetExtension == null) || sourceExtension == targetExtension);
if (nop && delete == false)
{
return;
}
- GetDatabaseFiles(databaseName, filesPath,
- out _, out _, out _, out var mdfFilename, out var ldfFilename);
+ GetDatabaseFiles(
+ databaseName,
+ filesPath,
+ out _,
+ out _,
+ out _,
+ out var mdfFilename,
+ out var ldfFilename);
if (sourceExtension != null)
{
@@ -892,8 +928,14 @@ public class LocalDb
else
{
// copy or copy+delete ie move
- GetDatabaseFiles(targetDatabaseName ?? databaseName, targetFilesPath ?? filesPath,
- out _, out _, out _, out var targetMdfFilename, out var targetLdfFilename);
+ GetDatabaseFiles(
+ targetDatabaseName ?? databaseName,
+ targetFilesPath ?? filesPath,
+ out _,
+ out _,
+ out _,
+ out var targetMdfFilename,
+ out var targetLdfFilename);
if (targetExtension != null)
{
@@ -936,8 +978,14 @@ public class LocalDb
///
public bool DatabaseFilesExist(string databaseName, string filesPath, string? extension = null)
{
- GetDatabaseFiles(databaseName, filesPath,
- out _, out _, out _, out var mdfFilename, out var ldfFilename);
+ GetDatabaseFiles(
+ databaseName,
+ filesPath,
+ out _,
+ out _,
+ out _,
+ out var mdfFilename,
+ out var ldfFilename);
if (extension != null)
{
@@ -958,10 +1006,14 @@ public class LocalDb
/// The base log filename (the LDF filename without the .ldf extension).
/// The MDF filename.
/// The LDF filename.
- private static void GetDatabaseFiles(string databaseName, string filesPath,
+ private static void GetDatabaseFiles(
+ string databaseName,
+ string filesPath,
out string logName,
- out string baseFilename, out string baseLogFilename,
- out string mdfFilename, out string ldfFilename)
+ out string baseFilename,
+ out string baseLogFilename,
+ out string mdfFilename,
+ out string ldfFilename)
{
logName = databaseName + "_log";
baseFilename = Path.Combine(filesPath, databaseName);
diff --git a/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj b/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj
index 9aef183cf6..1061c89526 100644
--- a/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj
+++ b/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj
@@ -3,7 +3,12 @@
Umbraco CMS - Persistence - SQL Server
Adds support for SQL Server to Umbraco CMS.
-
+
+
+ SA1405,SA1121,SA1117,SA1116,IDE1006,CS0618,IDE0270,IDE0057,IDE0054,CSO618,IDE0048,CS1574
+
diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj
index f9755aad61..0c39c66d64 100644
--- a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj
+++ b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj
@@ -3,7 +3,10 @@
Umbraco CMS - Persistence - SQLite
Adds support for SQLite to Umbraco CMS.
-
+
+
+ CS0114
+
diff --git a/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj b/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
index e186d9789d..a67dafbac5 100644
--- a/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
+++ b/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
@@ -6,6 +6,11 @@
/
+
+
+ NU5123
+
+
@@ -71,4 +76,4 @@
-
+
\ No newline at end of file
diff --git a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj
index a9a7604e7c..0ed86b3564 100644
--- a/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj
+++ b/src/Umbraco.Cms.Targets/Umbraco.Cms.Targets.csproj
@@ -5,7 +5,11 @@
false
false
-
+
+
+ IDE0270,CS0108,CS1998
+
diff --git a/src/Umbraco.Cms/Umbraco.Cms.csproj b/src/Umbraco.Cms/Umbraco.Cms.csproj
index 39a3b03c56..3bc60ebd12 100644
--- a/src/Umbraco.Cms/Umbraco.Cms.csproj
+++ b/src/Umbraco.Cms/Umbraco.Cms.csproj
@@ -5,7 +5,6 @@
false
false
-
diff --git a/src/Umbraco.Core/Constants-HealthChecks.cs b/src/Umbraco.Core/Constants-HealthChecks.cs
index bb18145401..d4b35f4e04 100644
--- a/src/Umbraco.Core/Constants-HealthChecks.cs
+++ b/src/Umbraco.Core/Constants-HealthChecks.cs
@@ -52,6 +52,7 @@ public static partial class Constants
[Obsolete("This link is not used anymore in the XSS protected check.")]
public const string XssProtectionCheck = "https://umbra.co/healthchecks-xss-protection";
public const string ExcessiveHeadersCheck = "https://umbra.co/healthchecks-excessive-headers";
+ public const string CspHeaderCheck = "https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP";
public static class HttpsCheck
{
diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml
index 893ab7c242..c05ea72cfc 100644
--- a/src/Umbraco.Core/EmbeddedResources/Lang/en.xml
+++ b/src/Umbraco.Core/EmbeddedResources/Lang/en.xml
@@ -467,6 +467,12 @@
You can read about this on the Mozilla website ]]>
X-XSS-Protection was not found.]]>
+
+ Content-Security-Policy (CSP) was found. ]]>
+
+
+ Content-Security-Policy (CSP) used to prevent cross-site scripting (XSS) attacks and other code injection vulnerabilities was not found.]]>
+
%0%.]]>
No headers revealing information about the website technology were found.
diff --git a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
index 69558f72da..dec3809f8d 100644
--- a/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
+++ b/src/Umbraco.Core/EmbeddedResources/Lang/en_us.xml
@@ -455,6 +455,12 @@
You can read about this on the Mozilla website ]]>
X-XSS-Protection was not found.]]>
+
+ Content-Security-Policy (CSP) was found. ]]>
+
+
+ Content-Security-Policy (CSP) used to prevent cross-site scripting (XSS) attacks and other code injection vulnerabilities was not found.]]>
+
%0%.]]>
No headers revealing information about the website technology were found.
diff --git a/src/Umbraco.Core/HealthChecks/Checks/Security/CspCheck.cs b/src/Umbraco.Core/HealthChecks/Checks/Security/CspCheck.cs
new file mode 100644
index 0000000000..1ac8cf56f4
--- /dev/null
+++ b/src/Umbraco.Core/HealthChecks/Checks/Security/CspCheck.cs
@@ -0,0 +1,31 @@
+// Copyright (c) Umbraco.
+// See LICENSE for more details.
+
+using Umbraco.Cms.Core.Hosting;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Core.HealthChecks.Checks.Security;
+
+///
+/// Health check for the recommended production setup regarding the content-security-policy header.
+///
+[HealthCheck(
+ "10BEBF47-C128-4C5E-9680-5059BEAFBBDF",
+ "Content Security Policy (CSP)",
+ Description = "Checks whether the site contains a Content-Security-Policy (CSP) header.",
+ Group = "Security")]
+public class CspCheck : BaseHttpHeaderCheck
+{
+ private const string LocalizationPrefix = "contentSecurityPolicy";
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CspCheck(IHostingEnvironment hostingEnvironment, ILocalizedTextService textService)
+ : base(hostingEnvironment, textService, "Content-Security-Policy", LocalizationPrefix, false, false)
+ {
+ }
+
+ ///
+ protected override string ReadMoreLink => Constants.HealthChecks.DocumentationLinks.Security.CspHeaderCheck;
+}
diff --git a/src/Umbraco.Core/Logging/DisposableTimer.cs b/src/Umbraco.Core/Logging/DisposableTimer.cs
index 087ae7adb6..7db20a0068 100644
--- a/src/Umbraco.Core/Logging/DisposableTimer.cs
+++ b/src/Umbraco.Core/Logging/DisposableTimer.cs
@@ -44,7 +44,7 @@ public class DisposableTimer : DisposableObjectSlim
_endMessageArgs = endMessageArgs;
_failMessageArgs = failMessageArgs;
_thresholdMilliseconds = thresholdMilliseconds < 0 ? 0 : thresholdMilliseconds;
- _timingId = Guid.NewGuid().ToString("N").Substring(0, 7); // keep it short-ish
+ _timingId = Guid.NewGuid().ToString("N")[..7]; // keep it short-ish
if (thresholdMilliseconds == 0)
{
@@ -63,7 +63,7 @@ public class DisposableTimer : DisposableObjectSlim
var args = new object[startMessageArgs.Length + 1];
startMessageArgs.CopyTo(args, 0);
args[^1] = _timingId;
-
+
if (_logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug))
{
logger.LogDebug(startMessage + " [Timing {TimingId}]", args);
diff --git a/src/Umbraco.Core/Models/Membership/UserGroup.cs b/src/Umbraco.Core/Models/Membership/UserGroup.cs
index c512702d54..95f8dee7b8 100644
--- a/src/Umbraco.Core/Models/Membership/UserGroup.cs
+++ b/src/Umbraco.Core/Models/Membership/UserGroup.cs
@@ -58,8 +58,6 @@ public class UserGroup : EntityBase, IUserGroup, IReadOnlyUserGroup
///
///
///
- ///
- ///
///
///
public UserGroup(
diff --git a/src/Umbraco.Core/Persistence/Repositories/ITrackedReferencesRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ITrackedReferencesRepository.cs
index fda745c2f6..4442e5ecf2 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ITrackedReferencesRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ITrackedReferencesRepository.cs
@@ -54,7 +54,7 @@ public interface ITrackedReferencesRepository
/// Gets a page of items which are in relation with the current item.
/// Basically, shows the items which depend on the current item.
///
- /// The identifier of the entity to retrieve relations for.
+ /// The identifier of the entity to retrieve relations for.
/// The amount of items to skip.
/// The amount of items to take.
///
@@ -81,7 +81,7 @@ public interface ITrackedReferencesRepository
///
/// Gets a page of items used in any kind of relation from selected integer ids.
///
- /// The identifiers of the entities to check for relations.
+ /// The identifiers of the entities to check for relations.
/// The amount of items to skip.
/// The amount of items to take.
///
diff --git a/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs b/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs
index a6f3b5739b..e4a7492c5d 100644
--- a/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs
+++ b/src/Umbraco.Core/PropertyEditors/JsonPropertyIndexValueFactoryBase.cs
@@ -2,7 +2,6 @@ using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Serialization;
-using Umbraco.Cms.Core.Serialization;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.PropertyEditors;
diff --git a/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs b/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs
index 39fc468cee..200a7d7143 100644
--- a/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs
+++ b/src/Umbraco.Core/Routing/ContentFinderByUrlAndTemplate.cs
@@ -77,8 +77,8 @@ public class ContentFinderByUrlAndTemplate : ContentFinderByUrl
// look for template in last position
var pos = path.LastIndexOf('/');
- var templateAlias = path.Substring(pos + 1);
- path = pos == 0 ? "/" : path.Substring(0, pos);;
+ var templateAlias = path[(pos + 1)..];
+ path = pos == 0 ? "/" : path[..pos];
ITemplate? template = _fileService.GetTemplate(templateAlias);
diff --git a/src/Umbraco.Core/Routing/DefaultUrlProvider.cs b/src/Umbraco.Core/Routing/DefaultUrlProvider.cs
index c30d5453aa..4a5d5d2826 100644
--- a/src/Umbraco.Core/Routing/DefaultUrlProvider.cs
+++ b/src/Umbraco.Core/Routing/DefaultUrlProvider.cs
@@ -98,7 +98,7 @@ public class DefaultUrlProvider : IUrlProvider
// need to strip off the leading ID for the route if it exists (occurs if the route is for a node with a domain assigned)
var pos = route.IndexOf('/');
- var path = pos == 0 ? route : route.Substring(pos);
+ var path = pos == 0 ? route : route[pos..];
var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path));
uri = _uriUtility.UriFromUmbraco(uri, _requestSettings);
diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index dd61585203..cd005b576c 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -582,10 +582,7 @@ public class ContentService : RepositoryService, IContentService
throw new ArgumentOutOfRangeException(nameof(pageSize));
}
- if (ordering == null)
- {
- ordering = Ordering.By("sortOrder");
- }
+ ordering ??= Ordering.By("sortOrder");
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
@@ -613,10 +610,7 @@ public class ContentService : RepositoryService, IContentService
throw new ArgumentOutOfRangeException(nameof(pageSize));
}
- if (ordering == null)
- {
- ordering = Ordering.By("sortOrder");
- }
+ ordering ??= Ordering.By("sortOrder");
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
@@ -773,10 +767,7 @@ public class ContentService : RepositoryService, IContentService
throw new ArgumentOutOfRangeException(nameof(pageSize));
}
- if (ordering == null)
- {
- ordering = Ordering.By("sortOrder");
- }
+ ordering ??= Ordering.By("sortOrder");
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
@@ -790,10 +781,7 @@ public class ContentService : RepositoryService, IContentService
///
public IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalChildren, IQuery? filter = null, Ordering? ordering = null)
{
- if (ordering == null)
- {
- ordering = Ordering.By("Path");
- }
+ ordering ??= Ordering.By("Path");
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
@@ -931,10 +919,7 @@ public class ContentService : RepositoryService, IContentService
{
using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
- if (ordering == null)
- {
- ordering = Ordering.By("Path");
- }
+ ordering ??= Ordering.By("Path");
scope.ReadLock(Constants.Locks.ContentTree);
IQuery? query = Query()?
@@ -1361,6 +1346,7 @@ public class ContentService : RepositoryService, IContentService
///
///
///
+ ///
///
///
///
@@ -1831,7 +1817,7 @@ public class ContentService : RepositoryService, IContentService
// publish the culture values and validate the property values, if validation fails, log the invalid properties so the develeper has an idea of what has failed
IProperty[]? invalidProperties = null;
- var impact = _cultureImpactFactory.ImpactExplicit(culture, IsDefaultCulture(allLangs.Value, culture));
+ CultureImpact impact = _cultureImpactFactory.ImpactExplicit(culture, IsDefaultCulture(allLangs.Value, culture));
var tryPublish = d.PublishCulture(impact) &&
_propertyValidationService.Value.IsPropertyDataValid(d, out invalidProperties, impact);
if (invalidProperties != null && invalidProperties.Length > 0)
@@ -1913,7 +1899,7 @@ public class ContentService : RepositoryService, IContentService
{
return culturesToPublish.All(culture =>
{
- var impact = _cultureImpactFactory.Create(culture, IsDefaultCulture(allLangs, culture), content);
+ CultureImpact? impact = _cultureImpactFactory.Create(culture, IsDefaultCulture(allLangs, culture), content);
return content.PublishCulture(impact) &&
_propertyValidationService.Value.IsPropertyDataValid(content, out _, impact);
});
@@ -1929,10 +1915,7 @@ public class ContentService : RepositoryService, IContentService
// if published, republish
if (published)
{
- if (cultures == null)
- {
- cultures = new HashSet(); // empty means 'already published'
- }
+ cultures ??= new HashSet(); // empty means 'already published'
if (edited)
{
@@ -1948,10 +1931,7 @@ public class ContentService : RepositoryService, IContentService
return cultures; // null means 'nothing to do'
}
- if (cultures == null)
- {
- cultures = new HashSet();
- }
+ cultures ??= new HashSet();
cultures.Add(c); // means 'publish this culture'
return cultures;
@@ -2654,7 +2634,6 @@ public class ContentService : RepositoryService, IContentService
///
/// The to copy
/// Id of the Content's new Parent
- /// Key of the Content's new Parent
/// Boolean indicating whether the copy should be related to the original
/// A value indicating whether to recursively copy children.
/// Optional Id of the User copying the Content
@@ -3300,6 +3279,7 @@ public class ContentService : RepositoryService, IContentService
///
///
///
+ ///
///
private PublishResult StrategyCanUnpublish(
ICoreScope scope,
@@ -3308,7 +3288,7 @@ public class ContentService : RepositoryService, IContentService
IDictionary? notificationState)
{
// raise Unpublishing notification
- var notification = new ContentUnpublishingNotification(content, evtMsgs).WithState(notificationState);
+ ContentUnpublishingNotification notification = new ContentUnpublishingNotification(content, evtMsgs).WithState(notificationState);
var notificationResult = scope.Notifications.PublishCancelable(notification);
if (notificationResult)
diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs
index 382238d583..7797a30015 100644
--- a/src/Umbraco.Core/Services/DataTypeService.cs
+++ b/src/Umbraco.Core/Services/DataTypeService.cs
@@ -330,7 +330,7 @@ namespace Umbraco.Cms.Core.Services.Implement
return Task.FromResult(dataTypes);
}
-
+
///
public async Task> GetByEditorAliasAsync(string[] propertyEditorAlias)
{
@@ -555,7 +555,7 @@ namespace Umbraco.Cms.Core.Services.Implement
return Attempt.FailWithStatus(DataTypeOperationStatus.DuplicateKey, dataType);
}
- var result = await SaveAsync(dataType, () => DataTypeOperationStatus.Success, userKey, AuditType.New);
+ Attempt result = await SaveAsync(dataType, () => DataTypeOperationStatus.Success, userKey, AuditType.New);
scope.Complete();
diff --git a/src/Umbraco.Core/Services/IAuditService.cs b/src/Umbraco.Core/Services/IAuditService.cs
index e4c973ced0..7481a5e613 100644
--- a/src/Umbraco.Core/Services/IAuditService.cs
+++ b/src/Umbraco.Core/Services/IAuditService.cs
@@ -105,10 +105,9 @@ public interface IAuditService : IService
///
/// Returns paged items in the audit trail for a given user
///
- ///
- ///
- ///
- ///
+ ///
+ ///
+ ///
///
/// By default this will always be ordered descending (newest first)
///
@@ -117,9 +116,7 @@ public interface IAuditService : IService
/// or the custom filter
/// so we need to do that here
///
- ///
- /// Optional filter to be applied
- ///
+ ///
///
Task> GetPagedItemsByUserAsync(
Guid userKey,
diff --git a/src/Umbraco.Core/Services/IContentPublishingService.cs b/src/Umbraco.Core/Services/IContentPublishingService.cs
index 0d60da7313..701aba3166 100644
--- a/src/Umbraco.Core/Services/IContentPublishingService.cs
+++ b/src/Umbraco.Core/Services/IContentPublishingService.cs
@@ -1,4 +1,4 @@
-using Umbraco.Cms.Core.Models.ContentPublishing;
+using Umbraco.Cms.Core.Models.ContentPublishing;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Core.Services;
@@ -9,7 +9,7 @@ public interface IContentPublishingService
/// Publishes a single content item.
///
/// The key of the root content.
- /// The cultures to publish.
+ /// The cultures to publish and their publishing schedules.
/// The identifier of the user performing the operation.
/// Result of the publish operation.
Task> PublishAsync(Guid key, CultureAndScheduleModel cultureAndSchedule, Guid userKey);
diff --git a/src/Umbraco.Core/Services/IRelationService.cs b/src/Umbraco.Core/Services/IRelationService.cs
index 04e99528b5..676e7ea17c 100644
--- a/src/Umbraco.Core/Services/IRelationService.cs
+++ b/src/Umbraco.Core/Services/IRelationService.cs
@@ -177,9 +177,8 @@ public interface IRelationService : IService
/// Gets a paged result of
///
///
- ///
- ///
- ///
+ ///
+ ///
///
///
Task, RelationOperationStatus>> GetPagedByRelationTypeKeyAsync(Guid key, int skip, int take, Ordering? ordering = null);
@@ -403,6 +402,8 @@ public interface IRelationService : IService
/// Gets the Relation types in a paged manner.
/// Currently implements the paging in memory on the name attribute because the underlying repository does not support paging yet
///
+ ///
+ ///
///
///
Task> GetPagedRelationTypesAsync(int skip, int take, params int[] ids);
diff --git a/src/Umbraco.Core/Services/ITrackedReferencesService.cs b/src/Umbraco.Core/Services/ITrackedReferencesService.cs
index 2b5dcfb833..7cfcd1c117 100644
--- a/src/Umbraco.Core/Services/ITrackedReferencesService.cs
+++ b/src/Umbraco.Core/Services/ITrackedReferencesService.cs
@@ -54,7 +54,7 @@ public interface ITrackedReferencesService
/// Gets a paged result of items which are in relation with the current item.
/// Basically, shows the items which depend on the current item.
///
- /// The identifier of the entity to retrieve relations for.
+ /// The identifier of the entity to retrieve relations for.
/// The amount of items to skip
/// The amount of items to take.
///
diff --git a/src/Umbraco.Core/Services/ImportExport/ContentTypeImportService.cs b/src/Umbraco.Core/Services/ImportExport/ContentTypeImportService.cs
index ec9cc5a5ce..c1f97d8d40 100644
--- a/src/Umbraco.Core/Services/ImportExport/ContentTypeImportService.cs
+++ b/src/Umbraco.Core/Services/ImportExport/ContentTypeImportService.cs
@@ -32,7 +32,7 @@ public class ContentTypeImportService : IContentTypeImportService
/// Imports the contentType
///
///
- ///
+ ///
/// the id of the contentType to overwrite, null if a new contentType should be created
///
public async Task> Import(
diff --git a/src/Umbraco.Core/Services/LocalizationService.cs b/src/Umbraco.Core/Services/LocalizationService.cs
index e1fcfab220..989b8f8206 100644
--- a/src/Umbraco.Core/Services/LocalizationService.cs
+++ b/src/Umbraco.Core/Services/LocalizationService.cs
@@ -1,4 +1,4 @@
-using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
@@ -220,7 +220,7 @@ internal class LocalizationService : RepositoryService, ILocalizationService
/// Optional id of the user saving the dictionary item
[Obsolete("Please use IDictionaryItemService for dictionary item operations. Will be removed in V15.")]
public void Save(IDictionaryItem dictionaryItem, int userId = Constants.Security.SuperUserId)
- { ;
+ {
Guid currentUserKey = _userIdKeyResolver.GetAsync(userId).GetAwaiter().GetResult();
if (dictionaryItem.Id > 0)
{
diff --git a/src/Umbraco.Core/Services/Querying/RecycleBin/RecycleBinQueryResultType.cs b/src/Umbraco.Core/Services/Querying/RecycleBin/RecycleBinQueryResultType.cs
index e864020a15..f9f0a34a75 100644
--- a/src/Umbraco.Core/Services/Querying/RecycleBin/RecycleBinQueryResultType.cs
+++ b/src/Umbraco.Core/Services/Querying/RecycleBin/RecycleBinQueryResultType.cs
@@ -1,7 +1,7 @@
namespace Umbraco.Cms.Core.Services.Querying.RecycleBin;
///
-/// < 10 = Success
+/// <10 = Success.
///
public enum RecycleBinQueryResultType
{
diff --git a/src/Umbraco.Core/Services/RedirectUrlService.cs b/src/Umbraco.Core/Services/RedirectUrlService.cs
index 07646de3de..0944b2a6a1 100644
--- a/src/Umbraco.Core/Services/RedirectUrlService.cs
+++ b/src/Umbraco.Core/Services/RedirectUrlService.cs
@@ -1,4 +1,4 @@
-using System.Threading.Tasks;
+using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
@@ -84,7 +84,7 @@ internal class RedirectUrlService : RepositoryService, IRedirectUrlService
public async Task GetMostRecentRedirectUrlAsync(string url)
{
- using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true))
+ using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
return await _redirectUrlRepository.GetMostRecentUrlAsync(url);
}
@@ -142,9 +142,9 @@ internal class RedirectUrlService : RepositoryService, IRedirectUrlService
return await GetMostRecentRedirectUrlAsync(url);
}
- using (var scope = ScopeProvider.CreateCoreScope(autoComplete: true))
+ using (ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true))
{
return await _redirectUrlRepository.GetMostRecentUrlAsync(url, culture);
}
- }
+ }
}
diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs
index dd25791d13..0167dc6d92 100644
--- a/src/Umbraco.Core/Services/UserService.cs
+++ b/src/Umbraco.Core/Services/UserService.cs
@@ -4,14 +4,12 @@ using System.Linq.Expressions;
using Microsoft.Extensions.DependencyInjection;
using System.Security.Claims;
using System.Security.Cryptography;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Editors;
-using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Exceptions;
using Umbraco.Cms.Core.IO;
@@ -156,7 +154,7 @@ internal class UserService : RepositoryService, IUserService
if (permissions.Any(x => x.EntityId == nodeId))
{
EntityPermission found = permissions.First(x => x.EntityId == nodeId);
- var assignedPermissionsArray = found.AssignedPermissions;
+ ISet assignedPermissionsArray = found.AssignedPermissions;
// Working with permissions assigned directly to a user AND to their groups, so maybe several per node
// and we need to get the most permissive set
@@ -668,7 +666,7 @@ internal class UserService : RepositoryService, IUserService
return Attempt.FailWithStatus(UserOperationStatus.MissingUser, new UserCreationResult());
}
- var userGroups = _userGroupRepository.GetMany().Where(x=>model.UserGroupKeys.Contains(x.Key)).ToArray();
+ IUserGroup[] userGroups = _userGroupRepository.GetMany().Where(x=>model.UserGroupKeys.Contains(x.Key)).ToArray();
if (userGroups.Length != model.UserGroupKeys.Count)
{
@@ -789,7 +787,7 @@ internal class UserService : RepositoryService, IUserService
return Attempt.FailWithStatus(UserOperationStatus.MissingUser, new UserInvitationResult());
}
- var userGroups = _userGroupRepository.GetMany().Where(x=>model.UserGroupKeys.Contains(x.Key)).ToArray();
+ IUserGroup[] userGroups = _userGroupRepository.GetMany().Where(x => model.UserGroupKeys.Contains(x.Key)).ToArray();
if (userGroups.Length != model.UserGroupKeys.Count)
{
@@ -2298,7 +2296,7 @@ internal class UserService : RepositoryService, IUserService
var results = new List();
foreach (KeyValuePair node in nodes)
{
- var permissions = permissionsCollection.GetAllPermissions(node.Value);
+ ISet permissions = permissionsCollection.GetAllPermissions(node.Value);
results.Add(new NodePermissions { NodeKey = node.Key, Permissions = permissions });
}
@@ -2361,7 +2359,7 @@ internal class UserService : RepositoryService, IUserService
var results = new List();
foreach (int nodeId in idKeyMap.Keys)
{
- var permissions = permissionCollection.GetAllPermissions(nodeId);
+ ISet permissions = permissionCollection.GetAllPermissions(nodeId);
results.Add(new NodePermissions { NodeKey = idKeyMap[nodeId], Permissions = permissions });
}
diff --git a/src/Umbraco.Core/Services/WebProfilerService.cs b/src/Umbraco.Core/Services/WebProfilerService.cs
index 026c2afd38..e895bba6e7 100644
--- a/src/Umbraco.Core/Services/WebProfilerService.cs
+++ b/src/Umbraco.Core/Services/WebProfilerService.cs
@@ -46,7 +46,11 @@ internal sealed class WebProfilerService : IWebProfilerService
//FIXME when we can get current user
return Attempt.Succeed(-1);
+#pragma warning disable CS0162 // Unreachable code detected
+#pragma warning disable CS0618 // Type or member is obsolete
Attempt? userIdAttempt = _backOfficeSecurityAccessor?.BackOfficeSecurity?.GetUserId();
+#pragma warning restore CS0618 // Type or member is obsolete
+#pragma warning restore CS0162 // Unreachable code detected
return (userIdAttempt.HasValue && userIdAttempt.Value.Success)
? Attempt.Succeed(userIdAttempt.Value.Result)
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index e0d0bd79fa..e4b3a7cd04 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -5,7 +5,10 @@
Contains the core assembly needed to run Umbraco CMS.
Umbraco.Cms.Core
-
+
+
+ false
+
diff --git a/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj b/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj
index 7e28eb6971..e036605449 100644
--- a/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj
+++ b/src/Umbraco.Examine.Lucene/Umbraco.Examine.Lucene.csproj
@@ -5,7 +5,10 @@
Adds Examine searching support using Lucene to Umbraco CMS.
Umbraco.Cms.Infrastructure.Examine
-
+
+
+ CS0618
+
diff --git a/src/Umbraco.Infrastructure/BackgroundJobs/IRecurringBackgroundJob.cs b/src/Umbraco.Infrastructure/BackgroundJobs/IRecurringBackgroundJob.cs
index c6be3dcec5..db57d02665 100644
--- a/src/Umbraco.Infrastructure/BackgroundJobs/IRecurringBackgroundJob.cs
+++ b/src/Umbraco.Infrastructure/BackgroundJobs/IRecurringBackgroundJob.cs
@@ -8,15 +8,17 @@ namespace Umbraco.Cms.Infrastructure.BackgroundJobs;
public interface IRecurringBackgroundJob
{
static readonly TimeSpan DefaultDelay = System.TimeSpan.FromMinutes(3);
- static readonly ServerRole[] DefaultServerRoles = new[] { ServerRole.Single, ServerRole.SchedulingPublisher };
+ static readonly ServerRole[] DefaultServerRoles = new[] { ServerRole.Single, ServerRole.SchedulingPublisher };
- /// Timespan representing how often the task should recur.
+ ///
+ /// Timespan representing how often the task should recur.
+ ///
TimeSpan Period { get; }
- ///
- /// Timespan representing the initial delay after application start-up before the first run of the task
- /// occurs.
- ///
+ ///
+ /// Timespan representing the initial delay after application start-up before the first run of the task
+ /// occurs.
+ ///
TimeSpan Delay { get => DefaultDelay; }
ServerRole[] ServerRoles { get => DefaultServerRoles; }
diff --git a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs
index cf99583fc4..c79a1a0866 100644
--- a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs
+++ b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/HealthCheckNotifierJob.cs
@@ -47,6 +47,7 @@ public class HealthCheckNotifierJob : IRecurringBackgroundJob
/// The typed logger.
/// The profiling logger.
/// Parser of crontab expressions.
+ ///
public HealthCheckNotifierJob(
IOptionsMonitor healthChecksSettings,
HealthCheckCollection healthChecks,
diff --git a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LogScrubberJob.cs b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LogScrubberJob.cs
index 1c745661cb..3fcbe8d3d6 100644
--- a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LogScrubberJob.cs
+++ b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/LogScrubberJob.cs
@@ -30,7 +30,7 @@ public class LogScrubberJob : IRecurringBackgroundJob
private readonly IAuditService _auditService;
private readonly ILogger _logger;
private readonly IProfilingLogger _profilingLogger;
- private readonly ICoreScopeProvider _scopeProvider;
+ private readonly ICoreScopeProvider _scopeProvider;
private LoggingSettings _settings;
///
@@ -41,14 +41,14 @@ public class LogScrubberJob : IRecurringBackgroundJob
/// Provides scopes for database operations.
/// The typed logger.
/// The profiling logger.
- public LogScrubberJob(
+ public LogScrubberJob(
IAuditService auditService,
IOptionsMonitor settings,
ICoreScopeProvider scopeProvider,
ILogger logger,
IProfilingLogger profilingLogger)
{
-
+
_auditService = auditService;
_settings = settings.CurrentValue;
_scopeProvider = scopeProvider;
@@ -59,7 +59,7 @@ public class LogScrubberJob : IRecurringBackgroundJob
public Task RunJobAsync()
{
-
+
// Ensure we use an explicit scope since we are running on a background thread.
using (ICoreScope scope = _scopeProvider.CreateCoreScope())
using (_profilingLogger.DebugDuration("Log scrubbing executing", "Log scrubbing complete"))
diff --git a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ServerRegistration/InstructionProcessJob.cs b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ServerRegistration/InstructionProcessJob.cs
index cc6e35bf83..87b459d69f 100644
--- a/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ServerRegistration/InstructionProcessJob.cs
+++ b/src/Umbraco.Infrastructure/BackgroundJobs/Jobs/ServerRegistration/InstructionProcessJob.cs
@@ -55,5 +55,5 @@ public class InstructionProcessJob : IRecurringBackgroundJob
}
return Task.CompletedTask;
- }
+ }
}
diff --git a/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs b/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
index d3777d4113..92ed6ced14 100644
--- a/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
+++ b/src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
@@ -91,10 +91,7 @@ public class FilePermissionHelper : IFilePermissionHelper
continue;
}
- if (temp == null)
- {
- temp = new List();
- }
+ temp ??= new List();
temp.Add(dir.TrimStart(_basePath));
success = false;
@@ -116,10 +113,7 @@ public class FilePermissionHelper : IFilePermissionHelper
continue;
}
- if (temp == null)
- {
- temp = new List();
- }
+ temp ??= new List();
temp.Add(file.TrimStart(_basePath));
success = false;
@@ -144,10 +138,7 @@ public class FilePermissionHelper : IFilePermissionHelper
continue;
}
- if (temp == null)
- {
- temp = new List();
- }
+ temp ??= new List();
temp.Add(dir);
success = false;
diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs
index 3e4b0b7931..3bd18bc1ac 100644
--- a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs
+++ b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs
@@ -49,7 +49,5 @@ public class LogViewerConfig : ILogViewerConfig
IReadOnlyList result = GetSavedSearches()!;
scope.Complete();
return result;
- scope.Complete();
- return result;
}
}
diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs
index 23f4aa108c..c9d23acb90 100644
--- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs
+++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPremigrationPlan.cs
@@ -12,7 +12,6 @@ public class UmbracoPremigrationPlan : MigrationPlan
///
/// Initializes a new instance of the class.
///
- /// The Umbraco version.
public UmbracoPremigrationPlan()
: base(Constants.Conventions.Migrations.UmbracoUpgradePlanPremigrationsName)
=> DefinePlan();
diff --git a/src/Umbraco.Infrastructure/Persistence/Dtos/LogDto.cs b/src/Umbraco.Infrastructure/Persistence/Dtos/LogDto.cs
index 89bfeb8612..62f8232da5 100644
--- a/src/Umbraco.Infrastructure/Persistence/Dtos/LogDto.cs
+++ b/src/Umbraco.Infrastructure/Persistence/Dtos/LogDto.cs
@@ -55,6 +55,6 @@ internal class LogDto
///
[Column("parameters")]
[NullSetting(NullSetting = NullSettings.Null)]
- [Length(500)]
+ [Length(4000)]
public string? Parameters { get; set; }
}
diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs
index 332339e49c..892fa78ae4 100644
--- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs
+++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/UserRepository.cs
@@ -411,8 +411,8 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
List userIds = dtos.Count == 1 ? new List {dtos[0].Id} : dtos.Select(x => x.Id).ToList();
Dictionary? xUsers = dtos.Count == 1 ? null : dtos.ToDictionary(x => x.Id, x => x);
- List groupIds = new List();
- List groupKeys = new List();
+ var groupIds = new List();
+ var groupKeys = new List();
Sql sql;
try
{
@@ -595,9 +595,9 @@ SELECT 4 AS [Key], COUNT(id) AS [Value] FROM umbracoUser WHERE userDisabled = 0
// map languages
- foreach (var group in groups.Values)
+ foreach (UserGroupDto group in groups.Values)
{
- if (groups2languages.TryGetValue(group.Id, out var list))
+ if (groups2languages.TryGetValue(group.Id, out IGrouping? list))
{
group.UserGroup2LanguageDtos = list.ToList(); // groups2apps is distinct
}
diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs
index 449d59ba42..46f02863a9 100644
--- a/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs
+++ b/src/Umbraco.Infrastructure/PropertyEditors/ImageCropperPropertyEditor.cs
@@ -197,7 +197,6 @@ public class ImageCropperPropertyEditor : DataEditor, IMediaUrlGenerator,
/// Returns the "src" property from the json structure if the value is formatted correctly
///
///
- /// The deserialized value
/// Should the path returned be the application relative path
///
private string? GetFileSrcFromPropertyValue(object? propVal, bool relative = true)
diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs b/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs
index eeac48801d..32a554aff0 100644
--- a/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs
+++ b/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs
@@ -17,6 +17,7 @@ public class BackOfficeClaimsPrincipalFactory : UserClaimsPrincipalFactory
/// The user manager
/// The
+ ///
public BackOfficeClaimsPrincipalFactory(
UserManager userManager,
IOptions optionsAccessor,
diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs b/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs
index 4c7943c69c..4341b01b79 100644
--- a/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs
+++ b/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs
@@ -62,10 +62,7 @@ public class BackOfficeIdentityUser : UmbracoIdentityUser
get => _startContentIds;
set
{
- if (value == null)
- {
- value = new int[0];
- }
+ value ??= new int[0];
BeingDirty.SetPropertyValueAndDetectChanges(value, ref _startContentIds!, nameof(StartContentIds), _startIdsComparer);
}
@@ -79,10 +76,7 @@ public class BackOfficeIdentityUser : UmbracoIdentityUser
get => _startMediaIds;
set
{
- if (value == null)
- {
- value = new int[0];
- }
+ value ??= Array.Empty();
BeingDirty.SetPropertyValueAndDetectChanges(value, ref _startMediaIds!, nameof(StartMediaIds), _startIdsComparer);
}
@@ -123,6 +117,7 @@ public class BackOfficeIdentityUser : UmbracoIdentityUser
/// This is allowed to be null (but would need to be filled in if trying to persist this instance)
///
///
+ ///
public static BackOfficeIdentityUser CreateNew(GlobalSettings globalSettings, string? username, string email, string culture, string? name = null, Guid? id = null)
{
if (string.IsNullOrWhiteSpace(username))
diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
index a3b64b1cc5..cca5a43954 100644
--- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
+++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
@@ -5,7 +5,10 @@
Contains the infrastructure assembly needed to run Umbraco CMS.
Umbraco.Cms.Infrastructure
-
+
+
+ false
+
$(DefineConstants);TRACE_SCOPES
diff --git a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj
index 4894759e5f..04986712c8 100644
--- a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj
+++ b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj
@@ -5,7 +5,10 @@
Contains the published cache assembly needed to run Umbraco CMS.
Umbraco.Cms.Infrastructure.PublishedCache
-
+
+
+ false
+
diff --git a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs
index 20cd35d0d1..3784781413 100644
--- a/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs
+++ b/src/Umbraco.Web.Common/ModelsBuilder/DependencyInjection/UmbracoBuilderDependencyInjectionExtensions.cs
@@ -126,7 +126,7 @@ public static class UmbracoBuilderDependencyInjectionExtensions
builder.AddNotificationHandler();
builder.AddNotificationHandler();
builder.AddNotificationHandler();
-
+
builder.AddNotificationHandler();
builder.AddNotificationHandler();
}
@@ -135,7 +135,7 @@ public static class UmbracoBuilderDependencyInjectionExtensions
// Register required services for ModelsBuilderDashboardController
builder.Services.AddSingleton();
-
+
// TODO: Remove in v13 - this is only here in case someone is already using this generator directly
builder.Services.AddSingleton();
builder.Services.AddSingleton();
@@ -165,7 +165,7 @@ public static class UmbracoBuilderDependencyInjectionExtensions
// This is what the community MB would replace, all of the above services are fine to be registered
builder.Services.AddSingleton(factory => factory.CreateDefaultPublishedModelFactory());
-
+
return builder;
}
}
diff --git a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs
index f0ab7e02e2..b0b2622e16 100644
--- a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs
+++ b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs
@@ -165,7 +165,8 @@ public abstract class UmbracoSignInManager : SignInManager
public override async Task PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
{
// override to handle logging/events
- TUser? user = await UserManager.FindByNameAsync(userName);
+ string strippedUsername = userName.Trim();
+ TUser? user = await UserManager.FindByNameAsync(strippedUsername);
if (user == null)
{
return await HandleSignIn(null, userName, SignInResult.Failed);
diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
index ba92e96fc0..2da3121a5f 100644
--- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
+++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
@@ -5,7 +5,10 @@
Contains the web assembly needed to run Umbraco CMS.
Umbraco.Cms.Web.Common
-
+
+
+ false
+
diff --git a/src/Umbraco.Web.Common/UmbracoHelper.cs b/src/Umbraco.Web.Common/UmbracoHelper.cs
index ec726148ec..9b1a9c6275 100644
--- a/src/Umbraco.Web.Common/UmbracoHelper.cs
+++ b/src/Umbraco.Web.Common/UmbracoHelper.cs
@@ -4,6 +4,7 @@ using Umbraco.Cms.Core.Dictionary;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Core.Templates;
+using Umbraco.Extensions;
namespace Umbraco.Cms.Web.Common;
@@ -18,7 +19,7 @@ public class UmbracoHelper
private readonly IUmbracoComponentRenderer _componentRenderer;
private readonly ICultureDictionaryFactory _cultureDictionaryFactory;
private readonly IPublishedContentQuery _publishedContentQuery;
- private ICultureDictionary? _cultureDictionary;
+ private readonly Dictionary _cultureDictionaries = [];
private IPublishedContent? _currentPage;
@@ -103,29 +104,29 @@ public class UmbracoHelper
///
/// Returns the dictionary value for the key specified
///
- ///
- ///
- public string? GetDictionaryValue(string key) => CultureDictionary[key];
+ /// Key of dictionary item.
+ /// The dictionary value, should one exist.
+ public string? GetDictionaryValue(string key) => GetDictionaryValue(key, Thread.CurrentThread.CurrentUICulture);
///
/// Returns the dictionary value for the key specified, and if empty returns the specified default fall back value
///
- /// key of dictionary item
+ /// Key of dictionary item.
/// the specific culture on which the result well be back upon
- ///
+ /// The dictionary value, should one exist.
public string? GetDictionaryValue(string key, CultureInfo specificCulture)
{
- _cultureDictionary = _cultureDictionaryFactory.CreateDictionary(specificCulture);
- return GetDictionaryValue(key);
+ ICultureDictionary cultureDictionary = GetCultureDictionary(specificCulture);
+ return cultureDictionary[key];
}
///
/// Returns the dictionary value for the key specified, and if empty returns the specified default fall back value
///
- /// key of dictionary item
- /// fall back text if dictionary item is empty - Name altText to match Umbraco.Field
- ///
+ /// key of dictionary item.
+ /// fall back text if dictionary item is empty - Name altText to match Umbraco.Field.
+ /// Returns the dictionary value, or a default value if none exists.
public string GetDictionaryValueOrDefault(string key, string defaultValue)
{
var dictionaryValue = GetDictionaryValue(key);
@@ -140,26 +141,51 @@ public class UmbracoHelper
///
/// Returns the dictionary value for the key specified, and if empty returns the specified default fall back value
///
- /// key of dictionary item
- /// the specific culture on which the result well be back upon
- /// fall back text if dictionary item is empty - Name altText to match Umbraco.Field
- ///
+ /// Key of dictionary item.
+ /// The specific culture on which the result well be back upon.
+ /// Fall back text if dictionary item is empty - Name altText to match Umbraco.Field.
+ /// Returns the dictionary value, or a default value if none exists.
public string GetDictionaryValueOrDefault(string key, CultureInfo specificCulture, string defaultValue)
{
- _cultureDictionary = _cultureDictionaryFactory.CreateDictionary(specificCulture);
- var dictionaryValue = GetDictionaryValue(key);
+ var dictionaryValue = GetDictionaryValue(key, specificCulture);
if (string.IsNullOrWhiteSpace(dictionaryValue))
{
dictionaryValue = defaultValue;
}
+
return dictionaryValue;
}
+ ///
+ /// Gets the ICultureDictionary for the current UI Culture for access to dictionary items
+ ///
+ public ICultureDictionary CultureDictionary => GetCultureDictionary(Thread.CurrentThread.CurrentUICulture);
///
- /// Returns the ICultureDictionary for access to dictionary items
+ /// Gets the ICultureDictionary for access to dictionary items for a specific culture
///
- public ICultureDictionary CultureDictionary => _cultureDictionary ??= _cultureDictionaryFactory.CreateDictionary();
+ /// The culture of the culture dictionary you want to retrieve.
+ /// Returns the culture dictionary for the specified culture.
+ public ICultureDictionary GetCultureDictionary(CultureInfo specificCulture)
+ {
+ CreateCultureDictionary(specificCulture);
+ return _cultureDictionaries.GetValue(specificCulture)!;
+ }
+
+ ///
+ /// Creates a culture dictionary for a specific culture if it doesn't already exist
+ ///
+ /// The culture to create a culture dictionary for.
+ internal void CreateCultureDictionary(CultureInfo specificCulture)
+ {
+ if (_cultureDictionaries.ContainsKey(specificCulture))
+ {
+ return;
+ }
+
+ ICultureDictionary dictionary = _cultureDictionaryFactory.CreateDictionary(specificCulture);
+ _cultureDictionaries.Add(specificCulture, dictionary);
+ }
#endregion
diff --git a/src/Umbraco.Web.UI.Login/package-lock.json b/src/Umbraco.Web.UI.Login/package-lock.json
index 43eaac8a2b..66bfe7a528 100644
--- a/src/Umbraco.Web.UI.Login/package-lock.json
+++ b/src/Umbraco.Web.UI.Login/package-lock.json
@@ -10,7 +10,7 @@
"@umbraco-ui/uui-css": "^1.8.0",
"msw": "^2.3.0",
"typescript": "^5.4.5",
- "vite": "^5.2.11",
+ "vite": "^5.4.6",
"vite-tsconfig-paths": "^4.3.2"
},
"engines": {
@@ -525,9 +525,9 @@
"dev": true
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
- "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.3.tgz",
+ "integrity": "sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==",
"cpu": [
"arm"
],
@@ -538,9 +538,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
- "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.21.3.tgz",
+ "integrity": "sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==",
"cpu": [
"arm64"
],
@@ -551,9 +551,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
- "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.21.3.tgz",
+ "integrity": "sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==",
"cpu": [
"arm64"
],
@@ -564,9 +564,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
- "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.21.3.tgz",
+ "integrity": "sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==",
"cpu": [
"x64"
],
@@ -577,9 +577,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
- "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.21.3.tgz",
+ "integrity": "sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==",
"cpu": [
"arm"
],
@@ -590,9 +590,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
- "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.21.3.tgz",
+ "integrity": "sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==",
"cpu": [
"arm"
],
@@ -603,9 +603,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
- "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.21.3.tgz",
+ "integrity": "sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==",
"cpu": [
"arm64"
],
@@ -616,9 +616,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
- "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.21.3.tgz",
+ "integrity": "sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==",
"cpu": [
"arm64"
],
@@ -629,9 +629,9 @@
]
},
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
- "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.21.3.tgz",
+ "integrity": "sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==",
"cpu": [
"ppc64"
],
@@ -642,9 +642,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
- "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.21.3.tgz",
+ "integrity": "sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==",
"cpu": [
"riscv64"
],
@@ -655,9 +655,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
- "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.21.3.tgz",
+ "integrity": "sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==",
"cpu": [
"s390x"
],
@@ -668,9 +668,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
- "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.21.3.tgz",
+ "integrity": "sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==",
"cpu": [
"x64"
],
@@ -681,9 +681,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
- "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.21.3.tgz",
+ "integrity": "sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==",
"cpu": [
"x64"
],
@@ -694,9 +694,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
- "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.21.3.tgz",
+ "integrity": "sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==",
"cpu": [
"arm64"
],
@@ -707,9 +707,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
- "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.21.3.tgz",
+ "integrity": "sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==",
"cpu": [
"ia32"
],
@@ -720,9 +720,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
- "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.21.3.tgz",
+ "integrity": "sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==",
"cpu": [
"x64"
],
@@ -2288,15 +2288,15 @@
"dev": true
},
"node_modules/picocolors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
"dev": true
},
"node_modules/postcss": {
- "version": "8.4.38",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
- "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "version": "8.4.47",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
+ "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
"dev": true,
"funding": [
{
@@ -2314,8 +2314,8 @@
],
"dependencies": {
"nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.2.0"
+ "picocolors": "^1.1.0",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
@@ -2331,9 +2331,9 @@
}
},
"node_modules/rollup": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
- "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.3.tgz",
+ "integrity": "sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==",
"dev": true,
"dependencies": {
"@types/estree": "1.0.5"
@@ -2346,22 +2346,22 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.18.0",
- "@rollup/rollup-android-arm64": "4.18.0",
- "@rollup/rollup-darwin-arm64": "4.18.0",
- "@rollup/rollup-darwin-x64": "4.18.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
- "@rollup/rollup-linux-arm64-gnu": "4.18.0",
- "@rollup/rollup-linux-arm64-musl": "4.18.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
- "@rollup/rollup-linux-s390x-gnu": "4.18.0",
- "@rollup/rollup-linux-x64-gnu": "4.18.0",
- "@rollup/rollup-linux-x64-musl": "4.18.0",
- "@rollup/rollup-win32-arm64-msvc": "4.18.0",
- "@rollup/rollup-win32-ia32-msvc": "4.18.0",
- "@rollup/rollup-win32-x64-msvc": "4.18.0",
+ "@rollup/rollup-android-arm-eabi": "4.21.3",
+ "@rollup/rollup-android-arm64": "4.21.3",
+ "@rollup/rollup-darwin-arm64": "4.21.3",
+ "@rollup/rollup-darwin-x64": "4.21.3",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.21.3",
+ "@rollup/rollup-linux-arm-musleabihf": "4.21.3",
+ "@rollup/rollup-linux-arm64-gnu": "4.21.3",
+ "@rollup/rollup-linux-arm64-musl": "4.21.3",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.21.3",
+ "@rollup/rollup-linux-riscv64-gnu": "4.21.3",
+ "@rollup/rollup-linux-s390x-gnu": "4.21.3",
+ "@rollup/rollup-linux-x64-gnu": "4.21.3",
+ "@rollup/rollup-linux-x64-musl": "4.21.3",
+ "@rollup/rollup-win32-arm64-msvc": "4.21.3",
+ "@rollup/rollup-win32-ia32-msvc": "4.21.3",
+ "@rollup/rollup-win32-x64-msvc": "4.21.3",
"fsevents": "~2.3.2"
}
},
@@ -2388,9 +2388,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true,
"engines": {
"node": ">=0.10.0"
@@ -2536,14 +2536,14 @@
}
},
"node_modules/vite": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.1.tgz",
- "integrity": "sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==",
+ "version": "5.4.6",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.6.tgz",
+ "integrity": "sha512-IeL5f8OO5nylsgzd9tq4qD2QqI0k2CQLGrWD0rCN0EQJZpBK5vJAx0I+GDkMOXxQX/OfFHMuLIx6ddAxGX/k+Q==",
"dev": true,
"dependencies": {
"esbuild": "^0.21.3",
- "postcss": "^8.4.38",
- "rollup": "^4.13.0"
+ "postcss": "^8.4.43",
+ "rollup": "^4.20.0"
},
"bin": {
"vite": "bin/vite.js"
@@ -2562,6 +2562,7 @@
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
+ "sass-embedded": "*",
"stylus": "*",
"sugarss": "*",
"terser": "^5.4.0"
@@ -2579,6 +2580,9 @@
"sass": {
"optional": true
},
+ "sass-embedded": {
+ "optional": true
+ },
"stylus": {
"optional": true
},
diff --git a/src/Umbraco.Web.UI.Login/package.json b/src/Umbraco.Web.UI.Login/package.json
index 7b0e3455c4..38cc5bca58 100644
--- a/src/Umbraco.Web.UI.Login/package.json
+++ b/src/Umbraco.Web.UI.Login/package.json
@@ -19,7 +19,7 @@
"@umbraco-ui/uui-css": "^1.8.0",
"msw": "^2.3.0",
"typescript": "^5.4.5",
- "vite": "^5.2.11",
+ "vite": "^5.4.6",
"vite-tsconfig-paths": "^4.3.2"
},
"msw": {
diff --git a/src/Umbraco.Web.UI/Program.cs b/src/Umbraco.Web.UI/Program.cs
index 8fca919b0a..ad68d28351 100644
--- a/src/Umbraco.Web.UI/Program.cs
+++ b/src/Umbraco.Web.UI/Program.cs
@@ -13,7 +13,7 @@ WebApplication app = builder.Build();
await app.BootUmbracoAsync();
-#if (UseHttpsRedirect)
+#if UseHttpsRedirect
app.UseHttpsRedirection();
#endif
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index acd631e1ad..c22b5ae739 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -5,6 +5,10 @@
false
+
+
+ SA1119
+
diff --git a/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs b/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs
index f182bda7b6..400b288786 100644
--- a/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs
+++ b/src/Umbraco.Web.Website/DependencyInjection/UmbracoBuilderExtensions.cs
@@ -57,8 +57,7 @@ public static partial class UmbracoBuilderExtensions
x.GetRequiredService(),
x.GetRequiredService(),
x.GetRequiredService(),
- x.GetRequiredService>()
- ));
+ x.GetRequiredService>()));
builder.Services.AddSingleton();
builder.Services.TryAddEnumerable(Singleton());
builder.Services.AddSingleton();
diff --git a/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs b/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs
index b7c751d28c..801e4af08f 100644
--- a/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs
+++ b/src/Umbraco.Web.Website/Routing/PublicAccessRequestHandler.cs
@@ -148,9 +148,10 @@ public class PublicAccessRequestHandler : IPublicAccessRequestHandler
_logger.LogDebug("EnsurePublishedContentAccess: Page is not protected");
}
}
+ }
- // loop until we have access or reached max loops
- } while (publicAccessStatus != PublicAccessStatus.AccessAccepted && i++ < maxLoop);
+ // loop until we have access or reached max loops
+ while (publicAccessStatus != PublicAccessStatus.AccessAccepted && i++ < maxLoop);
if (i == maxLoop)
{
diff --git a/src/Umbraco.Web.Website/Routing/UmbracoRouteValuesFactory.cs b/src/Umbraco.Web.Website/Routing/UmbracoRouteValuesFactory.cs
index d8fbca45d4..714024a1bc 100644
--- a/src/Umbraco.Web.Website/Routing/UmbracoRouteValuesFactory.cs
+++ b/src/Umbraco.Web.Website/Routing/UmbracoRouteValuesFactory.cs
@@ -45,13 +45,8 @@ public class UmbracoRouteValuesFactory : IUmbracoRouteValuesFactory
ControllerActionDescriptor? descriptor = _controllerActionSearcher.Find(
new DefaultHttpContext(), // this actually makes no difference for this method
DefaultControllerName,
- UmbracoRouteValues.DefaultActionName);
-
- if (descriptor == null)
- {
- throw new InvalidOperationException(
+ UmbracoRouteValues.DefaultActionName) ?? throw new InvalidOperationException(
$"No controller/action found by name {DefaultControllerName}.{UmbracoRouteValues.DefaultActionName}");
- }
return descriptor;
});
@@ -128,11 +123,12 @@ public class UmbracoRouteValuesFactory : IUmbracoRouteValuesFactory
IPublishedRequest request = def.PublishedRequest;
// Here we need to check if there is no hijacked route and no template assigned but there is a content item.
- // If this is the case we want to return a blank page.
+ // If this is the case we want to return a blank page, the only exception being if the content item has a redirect field present.
// We also check if templates have been disabled since if they are then we're allowed to render even though there's no template,
// for example for json rendering in headless.
if (request.HasPublishedContent()
&& !request.HasTemplate()
+ && !request.IsRedirect()
&& !_umbracoFeatures.Disabled.DisableTemplates
&& !hasHijackedRoute)
{
@@ -150,8 +146,8 @@ public class UmbracoRouteValuesFactory : IUmbracoRouteValuesFactory
$"The call to {nameof(IPublishedRouter.UpdateRequestAsync)} cannot return null");
}
- string? customActionName = GetTemplateName(request);
-
+ string? customActionName = GetTemplateName(request);
+
def = new UmbracoRouteValues(
request,
def.ControllerActionDescriptor,
@@ -166,7 +162,7 @@ public class UmbracoRouteValuesFactory : IUmbracoRouteValuesFactory
return def;
}
-
+
private string? GetTemplateName(IPublishedRequest request)
{
// check that a template is defined), if it doesn't and there is a hijacked route it will just route
diff --git a/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj b/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj
index 31c057e7b9..0e8d475725 100644
--- a/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj
+++ b/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj
@@ -5,7 +5,13 @@
Contains the website assembly needed to run the frontend of Umbraco CMS.
Umbraco.Cms.Web.Website
-
+
+
+ ASP0019,CS0618,SA1401,SA1649,IDE0270,IDE1006
+
diff --git a/src/Umbraco.Web.Website/ViewEngines/ProfilingViewEngine.cs b/src/Umbraco.Web.Website/ViewEngines/ProfilingViewEngine.cs
index 5862f90d64..33ec4acb33 100644
--- a/src/Umbraco.Web.Website/ViewEngines/ProfilingViewEngine.cs
+++ b/src/Umbraco.Web.Website/ViewEngines/ProfilingViewEngine.cs
@@ -8,6 +8,8 @@ public class ProfilingViewEngine : IViewEngine
{
private readonly string _name;
private readonly IProfiler _profiler;
+
+ //TODO: can this be made private and with underscore?
internal readonly IViewEngine Inner;
public ProfilingViewEngine(IViewEngine inner, IProfiler profiler)
diff --git a/tests/Umbraco.TestData/Umbraco.TestData.csproj b/tests/Umbraco.TestData/Umbraco.TestData.csproj
index 7e19740a31..2b8fc3fca8 100644
--- a/tests/Umbraco.TestData/Umbraco.TestData.csproj
+++ b/tests/Umbraco.TestData/Umbraco.TestData.csproj
@@ -1,4 +1,9 @@
+
+
+ CS0618,IDE1006,IDE0057
+
diff --git a/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/.gitignore b/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/.gitignore
new file mode 100644
index 0000000000..ff99115ae5
--- /dev/null
+++ b/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/.gitignore
@@ -0,0 +1,2 @@
+# Ignore Visual Studio's generated launchSettings file.
+Properties/launchSettings.json
diff --git a/tests/Umbraco.Tests.Benchmarks/EnumeratorBenchmarks.cs b/tests/Umbraco.Tests.Benchmarks/EnumeratorBenchmarks.cs
index 05db4034dd..460e819f18 100644
--- a/tests/Umbraco.Tests.Benchmarks/EnumeratorBenchmarks.cs
+++ b/tests/Umbraco.Tests.Benchmarks/EnumeratorBenchmarks.cs
@@ -11,7 +11,7 @@ public class EnumeratorBenchmarks
{
foreach (var t in EnumerateOneWithArray(1))
{
- ;
+
}
}
@@ -20,7 +20,7 @@ public class EnumeratorBenchmarks
{
foreach (var t in EnumerateOneWithYield(1))
{
- ;
+
}
}
diff --git a/tests/Umbraco.Tests.Benchmarks/HashFromStreams.cs b/tests/Umbraco.Tests.Benchmarks/HashFromStreams.cs
index cc8ad90877..7b291b88b8 100644
--- a/tests/Umbraco.Tests.Benchmarks/HashFromStreams.cs
+++ b/tests/Umbraco.Tests.Benchmarks/HashFromStreams.cs
@@ -18,7 +18,7 @@ public class HashFromStreams
// the SHA1CryptoServiceProvider is faster, but that is not reflected in these benchmarks.
/*
-
+
BenchmarkDotNet=v0.13.0, OS=Windows 10.0.19042.1052 (20H2/October2020Update)
Intel Core i7-7700HQ CPU 2.80GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
.NET SDK=5.0.300-preview.21258.4
diff --git a/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
index 189d69ac31..5b8f2b3b56 100644
--- a/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
+++ b/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
@@ -5,7 +5,10 @@
false
false
-
+
+
+ false
+
diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj
index bf0dc9ddc1..24e0dce808 100644
--- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj
+++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj
@@ -7,7 +7,10 @@
true
$(BaseEnablePackageValidation)
-
+
+
+ false
+
diff --git a/tests/Umbraco.Tests.Integration/Implementations/TestHelper.cs b/tests/Umbraco.Tests.Integration/Implementations/TestHelper.cs
index 1a4ccacdd1..47d095c02a 100644
--- a/tests/Umbraco.Tests.Integration/Implementations/TestHelper.cs
+++ b/tests/Umbraco.Tests.Integration/Implementations/TestHelper.cs
@@ -174,16 +174,13 @@ public class TestHelper : TestHelperBase
private static void AssertListsAreEqual(PropertyInfo property, IEnumerable expected, IEnumerable actual, Func sorter = null, int dateDeltaMilliseconds = 0)
{
- if (sorter == null)
+ // this is pretty hackerific but saves us some code to write
+ sorter ??= enumerable =>
{
- // this is pretty hackerific but saves us some code to write
- sorter = enumerable =>
- {
- // semi-generic way of ensuring any collection of IEntity are sorted by Ids for comparison
- var entities = enumerable.OfType().ToList();
- return entities.Count > 0 ? entities.OrderBy(x => x.Id) : entities;
- };
- }
+ // semi-generic way of ensuring any collection of IEntity are sorted by Ids for comparison
+ var entities = enumerable.OfType().ToList();
+ return entities.Count > 0 ? entities.OrderBy(x => x.Id) : entities;
+ };
var expectedListEx = sorter(expected).Cast