From aff2a2a7bde03c0f3176f58fbcd6a5917eb35cb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sat, 1 Aug 2026 21:08:40 +0200 Subject: [PATCH] Re-introduce the default user code display format and fix the user code generation logic to use the specified charset --- .../OpenIddictPolyfills.cs | 9 ------ .../OpenIddictServerConfiguration.cs | 31 +++++++++++++++++++ .../OpenIddictServerHandlers.Protection.cs | 4 +-- .../OpenIddictServerConfigurationTests.cs | 30 ++++++++++++++++++ 4 files changed, 63 insertions(+), 11 deletions(-) diff --git a/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs b/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs index 59ead315..63110faf 100644 --- a/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs +++ b/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs @@ -272,11 +272,6 @@ internal static class OpenIddictPolyfills UrlRetrievalTimeout = policy.UrlRetrievalTimeout, VerificationFlags = policy.VerificationFlags, VerificationTime = policy.VerificationTime, -#if NET - DisableCertificateDownloads = policy.DisableCertificateDownloads, - TrustMode = policy.TrustMode, - VerificationTimeIgnored = policy.VerificationTimeIgnored -#endif }; if (policy.ApplicationPolicy.Count is > 0) @@ -295,10 +290,6 @@ internal static class OpenIddictPolyfills } } -#if NET - clone.CustomTrustStore.AddRange(policy.CustomTrustStore); -#endif - clone.ExtraStore.AddRange(policy.ExtraStore); return clone; diff --git a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs index 843008c7..d0032047 100644 --- a/src/OpenIddict.Server/OpenIddictServerConfiguration.cs +++ b/src/OpenIddict.Server/OpenIddictServerConfiguration.cs @@ -10,6 +10,7 @@ using System.Diagnostics; using System.Globalization; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; +using System.Text; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; @@ -39,6 +40,12 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions() ?? TimeProvider.System; + // If no user code display format was explicitly set, generate a default format based on the configured length. + if (options.UserCodeLength is >= 1 && string.IsNullOrEmpty(options.UserCodeDisplayFormat)) + { + options.UserCodeDisplayFormat = ComputeDefaultUserCodeDisplayFormat(options.UserCodeLength); + } + // Explicitly disable all the features that are implicitly excluded when the degraded mode is active. if (options.EnableDegradedMode) { @@ -119,6 +126,30 @@ public sealed class OpenIddictServerConfiguration : IPostConfigureOptions 0 }; + static string ComputeDefaultUserCodeDisplayFormat(int length) + { + var builder = new StringBuilder(); + + var count = length % 5 is 0 ? 5 : + length % 4 is 0 ? 4 : + length % 3 is 0 ? 3 : + length % 2 is 0 ? 2 : 1; + + for (var index = 0; index < length; index++) + { + if (index is > 0 && index % count is 0) + { + builder.Append(Separators.Dash[0]); + } + + builder.Append('{'); + builder.Append(index); + builder.Append('}'); + } + + return builder.ToString(); + } + static string? GetKeyIdentifier(SecurityKey key) { // When no key identifier can be retrieved from the security keys, a value is automatically diff --git a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs index 73d12657..595bc070 100644 --- a/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs +++ b/src/OpenIddict.Server/OpenIddictServerHandlers.Protection.cs @@ -1866,8 +1866,8 @@ public static partial class OpenIddictServerHandlers for (var index = 0; index < count; index++) { - // Pick a character in the specified charset by generating a random index. - builder.Append(RandomNumberGenerator.GetInt32(0, charset.Length)); + // Pick a character from the specified charset by generating a random index. + builder.Append(charset[RandomNumberGenerator.GetInt32(0, charset.Length)]); } return builder.ToString(); diff --git a/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs b/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs index 76de2895..9ff3928c 100644 --- a/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs +++ b/test/OpenIddict.Server.Tests/OpenIddictServerConfigurationTests.cs @@ -131,6 +131,36 @@ public class OpenIddictServerConfigurationTests Assert.Null(options.UserCodeDisplayFormat); } + [Theory] + [InlineData(1, "{0}")] + [InlineData(2, "{0}{1}")] + [InlineData(3, "{0}{1}{2}")] + [InlineData(4, "{0}{1}{2}{3}")] + [InlineData(5, "{0}{1}{2}{3}{4}")] + [InlineData(6, "{0}{1}{2}-{3}{4}{5}")] + [InlineData(7, "{0}-{1}-{2}-{3}-{4}-{5}-{6}")] + [InlineData(8, "{0}{1}{2}{3}-{4}{5}{6}{7}")] + [InlineData(9, "{0}{1}{2}-{3}{4}{5}-{6}{7}{8}")] + [InlineData(10, "{0}{1}{2}{3}{4}-{5}{6}{7}{8}{9}")] + [InlineData(11, "{0}-{1}-{2}-{3}-{4}-{5}-{6}-{7}-{8}-{9}-{10}")] + [InlineData(12, "{0}{1}{2}{3}-{4}{5}{6}{7}-{8}{9}{10}{11}")] + public void PostConfigure_GeneratesUserCodeDisplayFormatWhenNotSet(int length, string expected) + { + // Arrange + var configuration = new OpenIddictServerConfiguration(new ServiceCollection().BuildServiceProvider()); + var options = new OpenIddictServerOptions + { + UserCodeLength = length, + UserCodeDisplayFormat = null + }; + + // Act + configuration.PostConfigure(name: null, options); + + // Assert + Assert.Equal(expected, options.UserCodeDisplayFormat); + } + [Fact] public void Validate_ThrowsAnExceptionForNullOptions() {