From a0e056fac04772e17d45a450b6ccb3e9869be8f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Thu, 8 Jan 2026 18:15:41 +0100 Subject: [PATCH] Replace Polyfill by Meziantou.Polyfill and bring back internal OperatingSystem polyfills --- Directory.Build.props | 7 +- Directory.Build.targets | 34 +- Directory.Packages.props | 585 +++++++++--------- .../OpenIddictHelpers.cs | 135 +++- .../OpenIddictPolyfills.cs | 306 +++++++++ .../OpenIddict.Abstractions.csproj | 5 + ...OpenIddict.Client.SystemIntegration.csproj | 2 +- ...ictClientSystemIntegrationConfiguration.cs | 9 +- ...IddictClientSystemIntegrationExtensions.cs | 9 +- ...penIddictClientSystemIntegrationHelpers.cs | 4 +- .../OpenIddict.Client.SystemNetHttp.csproj | 1 - ...OpenIddict.Validation.SystemNetHttp.csproj | 1 - 12 files changed, 735 insertions(+), 363 deletions(-) create mode 100644 shared/OpenIddict.Extensions/OpenIddictPolyfills.cs diff --git a/Directory.Build.props b/Directory.Build.props index 93cac457..eb93f374 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -22,8 +22,6 @@ true false true - true - true @@ -36,6 +34,11 @@ 35a561290d20de2f + + $(MeziantouPolyfill_ExcludedPolyfills);M:System.OperatingSystem. + $(MeziantouPolyfill_ExcludedPolyfills);T:System.Net.Http. + + $([System.IO.Path]::GetDirectoryName($(DOTNET_HOST_PATH))) $(ProgramFiles)\dotnet diff --git a/Directory.Build.targets b/Directory.Build.targets index dc320ece..6db20806 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -59,12 +59,15 @@ $(DefineConstants);SUPPORTS_AUTHORIZATION_MIDDLEWARE $(DefineConstants);SUPPORTS_BCL_ASYNC_ENUMERABLE $(DefineConstants);SUPPORTS_BULK_DBSET_OPERATIONS + $(DefineConstants);SUPPORTS_CHUNK_LINQ_EXTENSION $(DefineConstants);SUPPORTS_DBSET_VALUETASK_FINDASYNC $(DefineConstants);SUPPORTS_ENDPOINT_ROUTING $(DefineConstants);SUPPORTS_ENVIRONMENT_PROCESS_PATH + $(DefineConstants);SUPPORTS_HEXADECIMAL_STRING_CONVERSION $(DefineConstants);SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION $(DefineConstants);SUPPORTS_HTTP_CLIENT_DEFAULT_REQUEST_VERSION_POLICY $(DefineConstants);SUPPORTS_HTTP_CLIENT_RESILIENCE + $(DefineConstants);SUPPORTS_INT32_RANDOM_NUMBER_GENERATOR_METHODS $(DefineConstants);SUPPORTS_MULTIPLE_VALUES_IN_QUERYHELPERS $(DefineConstants);SUPPORTS_NAMED_PIPE_STATIC_FACTORY_WITH_ACL $(DefineConstants);SUPPORTS_ONE_SHOT_HASHING_METHODS @@ -73,6 +76,7 @@ $(DefineConstants);SUPPORTS_PEM_ENCODED_KEY_IMPORT $(DefineConstants);SUPPORTS_REDIRECTION_ON_SIGN_IN $(DefineConstants);SUPPORTS_TEXT_ELEMENT_ENUMERATOR + $(DefineConstants);SUPPORTS_VALUETASK_COMPLETED_TASK $(DefineConstants);SUPPORTS_WINFORMS_TASK_DIALOG $(DefineConstants);SUPPORTS_ZLIB_COMPRESSION @@ -155,19 +159,6 @@ $(DefineConstants);SUPPORTS_WINDOWS_RUNTIME - - - - $(DefineConstants);FeatureRuntimeInformation - - - - - - - - - diff --git a/Directory.Packages.props b/Directory.Packages.props index 45eb5471..b38e6fba 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -20,39 +20,40 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - + + + + + + + + - + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - + + + + + + - + - - - - - - + + + + + + - + - - - - - + + + + + - - - - - - - - - - + + + + + + + + + + - + - - - - + + + + - + - + - + diff --git a/shared/OpenIddict.Extensions/OpenIddictHelpers.cs b/shared/OpenIddict.Extensions/OpenIddictHelpers.cs index 7389ab07..3a7328c6 100644 --- a/shared/OpenIddict.Extensions/OpenIddictHelpers.cs +++ b/shared/OpenIddict.Extensions/OpenIddictHelpers.cs @@ -527,14 +527,33 @@ internal static class OpenIddictHelpers /// public static byte[] ComputeSha256Hash(byte[] data) { - using var algorithm = GetAlgorithmFromConfig() switch + var algorithm = GetAlgorithmFromConfig() switch { SHA256 result => result, null => null, var result => throw new CryptographicException(SR.FormatID0351(result.GetType().FullName)) }; - return algorithm is not null ? algorithm.ComputeHash(data) : SHA256.HashData(data); + // If no custom algorithm was registered, use either the static/one-shot HashData() API + // on platforms that support it or create a default instance provided by the BCL. + if (algorithm is null) + { +#if SUPPORTS_ONE_SHOT_HASHING_METHODS + return SHA256.HashData(data); +#else + algorithm = SHA256.Create(); +#endif + } + + try + { + return algorithm.ComputeHash(data); + } + + finally + { + algorithm.Dispose(); + } [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The default implementation is always used when no custom algorithm was registered.")] @@ -551,14 +570,33 @@ internal static class OpenIddictHelpers /// public static byte[] ComputeSha384Hash(byte[] data) { - using var algorithm = GetAlgorithmFromConfig() switch + var algorithm = GetAlgorithmFromConfig() switch { SHA384 result => result, null => null, var result => throw new CryptographicException(SR.FormatID0351(result.GetType().FullName)) }; - return algorithm is not null ? algorithm.ComputeHash(data) : SHA384.HashData(data); + // If no custom algorithm was registered, use either the static/one-shot HashData() API + // on platforms that support it or create a default instance provided by the BCL. + if (algorithm is null) + { +#if SUPPORTS_ONE_SHOT_HASHING_METHODS + return SHA384.HashData(data); +#else + algorithm = SHA384.Create(); +#endif + } + + try + { + return algorithm.ComputeHash(data); + } + + finally + { + algorithm.Dispose(); + } [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The default implementation is always used when no custom algorithm was registered.")] @@ -575,14 +613,33 @@ internal static class OpenIddictHelpers /// public static byte[] ComputeSha512Hash(byte[] data) { - using var algorithm = GetAlgorithmFromConfig() switch + var algorithm = GetAlgorithmFromConfig() switch { SHA512 result => result, null => null, var result => throw new CryptographicException(SR.FormatID0351(result.GetType().FullName)) }; - return algorithm is not null ? algorithm.ComputeHash(data) : SHA512.HashData(data); + // If no custom algorithm was registered, use either the static/one-shot HashData() API + // on platforms that support it or create a default instance provided by the BCL. + if (algorithm is null) + { +#if SUPPORTS_ONE_SHOT_HASHING_METHODS + return SHA512.HashData(data); +#else + algorithm = SHA512.Create(); +#endif + } + + try + { + return algorithm.ComputeHash(data); + } + + finally + { + algorithm.Dispose(); + } [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The default implementation is always used when no custom algorithm was registered.")] @@ -599,22 +656,46 @@ internal static class OpenIddictHelpers /// public static byte[] CreateRandomArray(int size) { - using var algorithm = GetAlgorithmFromConfig() switch + var algorithm = GetAlgorithmFromConfig() switch { RandomNumberGenerator result => result, null => null, var result => throw new CryptographicException(SR.FormatID0351(result.GetType().FullName)) }; - if (algorithm is not null) + // If no custom random number generator was registered, use either the static GetBytes() or + // Fill() APIs on platforms that support them or create a default instance provided by the BCL. +#if SUPPORTS_ONE_SHOT_RANDOM_NUMBER_GENERATOR_METHODS + if (algorithm is null) { var array = new byte[size / 8]; algorithm.GetBytes(array); return array; } +#endif + var array = new byte[size / 8]; + +#if SUPPORTS_STATIC_RANDOM_NUMBER_GENERATOR_METHODS + if (algorithm is null) + { + RandomNumberGenerator.Fill(array); + return array; + } +#else + algorithm ??= RandomNumberGenerator.Create(); +#endif + try + { + algorithm.GetBytes(array); + } - return RandomNumberGenerator.GetBytes(size / 8); + finally + { + algorithm.Dispose(); + } + + return array; [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The default implementation is always used when no custom algorithm was registered.")] @@ -633,30 +714,40 @@ internal static class OpenIddictHelpers /// public static string CreateRandomString(ReadOnlySpan charset, int count) { - using var algorithm = GetAlgorithmFromConfig() switch + var algorithm = GetAlgorithmFromConfig() switch { RandomNumberGenerator result => result, null => null, var result => throw new CryptographicException(SR.FormatID0351(result.GetType().FullName)) }; - var builder = new StringBuilder(); - - for (var index = 0; index < count; index++) + try { - // Pick a character in the specified charset by generating a random index. - builder.Append(charset[index: algorithm switch + var builder = new StringBuilder(); + + for (var index = 0; index < count; index++) { - // If no custom random number generator was registered, use the static GetInt32() API. - null => RandomNumberGenerator.GetInt32(0, charset.Length), + // Pick a character in the specified charset by generating a random index. + builder.Append(charset[index: algorithm switch + { +#if SUPPORTS_INT32_RANDOM_NUMBER_GENERATOR_METHODS + // If no custom random number generator was registered, use + // the static GetInt32() API on platforms that support it. + null => RandomNumberGenerator.GetInt32(0, charset.Length), +#endif + // Otherwise, create a default implementation if necessary + // and use the local function that achieves the same result. + _ => GetInt32(algorithm ??= RandomNumberGenerator.Create(), 0..charset.Length) + }]); + } - // Otherwise, create a default implementation if necessary - // and use the local function that achieves the same result. - _ => GetInt32(algorithm, 0..charset.Length) - }]); + return builder.ToString(); } - return builder.ToString(); + finally + { + algorithm?.Dispose(); + } static int GetInt32(RandomNumberGenerator algorithm, Range range) { diff --git a/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs b/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs new file mode 100644 index 00000000..07f12b29 --- /dev/null +++ b/shared/OpenIddict.Extensions/OpenIddictPolyfills.cs @@ -0,0 +1,306 @@ +/* + * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) + * See https://github.com/openiddict/openiddict-core for more information concerning + * the license and the contributors participating to this project. + */ + +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; + +namespace OpenIddict.Extensions; + +/// +/// Exposes common polyfills used by the OpenIddict assemblies. +/// +internal static class OpenIddictPolyfills +{ + extension(ArgumentOutOfRangeException) + { + /// Throws an if is negative. + /// The argument to validate as non-negative. + /// The name of the parameter with which corresponds. + public static void ThrowIfNegative(T value, [CallerArgumentExpression(nameof(value))] string? paramName = null) + where T : struct, IComparable + { + switch (value) + { + case byte or ushort or uint or ulong or char: + return; + case sbyte n: + if (n < 0) + ThrowArgumentOutOfRangeException(paramName, value); + return; + case short n: + if (n < 0) + ThrowArgumentOutOfRangeException(paramName, value); + return; + case int n: + if (n < 0) + ThrowArgumentOutOfRangeException(paramName, value); + return; + case long n: + if (n < 0L) + ThrowArgumentOutOfRangeException(paramName, value); + return; + + case float n: + if (n < 0F) + ThrowArgumentOutOfRangeException(paramName, value); + return; + case double n: + if (n < 0D) + ThrowArgumentOutOfRangeException(paramName, value); + return; + case decimal n: + if (n < 0M) + ThrowArgumentOutOfRangeException(paramName, value); + return; + default: + throw new InvalidOperationException($"Invalid type '{typeof(T).AssemblyQualifiedName}' for {paramName}."); + } + + static void ThrowArgumentOutOfRangeException(string? paramName, object value) + { + throw new ArgumentOutOfRangeException(paramName, value, $"{paramName} ('{value}') must not be negative."); + } + } + } + + extension(Convert) + { +#if !SUPPORTS_HEXADECIMAL_STRING_CONVERSION + + /// Converts the specified string, which encodes binary data as hex characters, to an equivalent 8-bit unsigned integer array. + /// The string to convert. + /// An array of 8-bit unsigned integers that is equivalent to . + /// is null. + /// The length of , is not zero or a multiple of 2. + /// The format of is invalid. contains a non-hex character. + public static byte[] FromHexString(string s) + { + if ((uint) s.Length % 2 is not 0) + { + throw new FormatException(SR.GetResourceString(SR.ID0413)); + } + + var array = new byte[s.Length / 2]; + + for (var index = 0; index < s.Length; index += 2) + { + array[index / 2] = Convert.ToByte(s.Substring(index, 2), 16); + } + + return array; + } +#endif + } + + extension(IEnumerable source) + { +#if !SUPPORTS_CHUNK_LINQ_EXTENSION + /// + /// Split the elements of a sequence into chunks of size at most . + /// + /// + /// Every chunk except the last will be of size . + /// The last chunk will contain the remaining elements and may be of a smaller size. + /// + /// Maximum size of each chunk. + /// + /// An that contains the elements of the input + /// sequence split into chunks of size . + /// + public IEnumerable Chunk(int size) + { + // Note: this polyfill was directly copied from .NET's source code: + // https://github.com/dotnet/runtime/blob/main/src/libraries/System.Linq/src/System/Linq/Chunk.cs. + + using IEnumerator enumerator = source.GetEnumerator(); + + if (enumerator.MoveNext()) + { + var count = Math.Min(size, 4); + int index; + + do + { + var array = new TSource[count]; + + array[0] = enumerator.Current; + index = 1; + + if (size != array.Length) + { + for (; index < size && enumerator.MoveNext(); index++) + { + if (index >= array.Length) + { + count = (int) Math.Min((uint) size, 2 * (uint) array.Length); + Array.Resize(ref array, count); + } + + array[index] = enumerator.Current; + } + } + + else + { + var local = array; + Debug.Assert(local.Length == size); + for (; (uint) index < (uint) local.Length && enumerator.MoveNext(); index++) + { + local[index] = enumerator.Current; + } + } + + if (index != array.Length) + { + Array.Resize(ref array, index); + } + + yield return array; + } + + while (index >= size && enumerator.MoveNext()); + } + } +#endif + } + + extension(OperatingSystem) + { +#if !SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON + /// + /// Indicates whether the current application is running on Android. + /// + public static bool IsAndroid() => RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID")); + + /// + /// Check for the Android API level (returned by 'ro.build.version.sdk') with a >= + /// version comparison. Used to guard APIs that were added in the given Android release. + /// + public static bool IsAndroidVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) + => IsAndroid() && IsOSVersionAtLeast(major, minor, build, revision); + + /// + /// Indicates whether the current application is running on iOS or MacCatalyst. + /// + [SupportedOSPlatformGuard("maccatalyst")] + public static bool IsIOS() => RuntimeInformation.IsOSPlatform(OSPlatform.Create("IOS")); + + /// + /// Check for the iOS/MacCatalyst version (returned by 'libobjc.get_operatingSystemVersion') + /// with a >= version comparison. Used to guard APIs that were added in the given iOS release. + /// + [SupportedOSPlatformGuard("maccatalyst")] + public static bool IsIOSVersionAtLeast(int major, int minor = 0, int build = 0) + => IsIOS() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on Linux. + /// + public static bool IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux); + + /// + /// Indicates whether the current application is running on Mac Catalyst. + /// + public static bool IsMacCatalyst() => RuntimeInformation.IsOSPlatform(OSPlatform.Create("MACCATALYST")); + + /// + /// Check for the Mac Catalyst version (iOS version as presented in Apple documentation) with a >= + /// version comparison. Used to guard APIs that were added in the given Mac Catalyst release. + /// + public static bool IsMacCatalystVersionAtLeast(int major, int minor = 0, int build = 0) + => IsMacCatalyst() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on macOS. + /// + public static bool IsMacOS() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + + /// + /// Check for the macOS version (returned by 'libobjc.get_operatingSystemVersion') with a >= + /// version comparison. Used to guard APIs that were added in the given macOS release. + /// + public static bool IsMacOSVersionAtLeast(int major, int minor = 0, int build = 0) + => IsMacOS() && IsOSVersionAtLeast(major, minor, build, 0); + + /// + /// Indicates whether the current application is running on Windows. + /// + public static bool IsWindows() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); + + /// + /// Check for the Windows version (returned by 'RtlGetVersion') with a >= version + /// comparison. Used to guard APIs that were added in the given Windows release. + /// + public static bool IsWindowsVersionAtLeast(int major, int minor = 0, int build = 0, int revision = 0) + { + if (Environment.OSVersion.Platform is PlatformID.Win32NT && + Environment.OSVersion.Version >= new Version(major, minor, build, revision)) + { + return true; + } + + // Note: on older versions of .NET, Environment.OSVersion.Version is known to be affected by + // the compatibility shims used by Windows 10+ when the application doesn't have a manifest + // that explicitly indicates it's compatible with Windows 10 and higher. To avoid that, a + // second pass using RuntimeInformation.OSDescription (that calls NtDll.RtlGetVersion() under + // the hood) is made. Note: no version is returned on UWP due to the missing Win32 API. + return RuntimeInformation.OSDescription.StartsWith("Microsoft Windows ", StringComparison.OrdinalIgnoreCase) && + RuntimeInformation.OSDescription["Microsoft Windows ".Length..] is string value && + Version.TryParse(value, out Version? version) && version >= new Version(major, minor, build, revision); + } +#endif + } + + extension(ValueTask) + { +#if !SUPPORTS_VALUETASK_COMPLETED_TASK + /// + /// Gets a task that has already completed successfully. + /// + public static ValueTask CompletedTask => default; +#endif + } + + extension(ValueTask) + { +#if !SUPPORTS_VALUETASK_COMPLETED_TASK + /// + /// Gets a task that has already completed successfully. + /// + public static ValueTask CompletedTask => default; +#endif + } + +#if !SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON + static bool IsOSVersionAtLeast(int major, int minor, int build, int revision) + { + Version current = Environment.OSVersion.Version; + + if (current.Major != major) + { + return current.Major > major; + } + if (current.Minor != minor) + { + return current.Minor > minor; + } + + int currentBuild = current.Build < 0 ? 0 : current.Build; + build = build < 0 ? 0 : build; + if (currentBuild != build) + { + return currentBuild > build; + } + + int currentRevision = current.Revision < 0 ? 0 : current.Revision; + revision = revision < 0 ? 0 : revision; + + return currentRevision >= revision; + } +#endif +} diff --git a/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj b/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj index a3cc3048..05fc3fd6 100644 --- a/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj +++ b/src/OpenIddict.Abstractions/OpenIddict.Abstractions.csproj @@ -38,6 +38,11 @@ + + + + diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj b/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj index 7c8cc5ca..1aa3a77d 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj @@ -30,7 +30,7 @@ allow loading dependencies that are not strong-named), the warning can be safely disabled. --> $(NoWarn);CS8002 - $(DefineConstants);FeatureRuntimeInformation;FeatureValueTuple + $(DefineConstants);FeatureValueTuple diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs index ed274d2d..83c6fd8a 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs @@ -62,12 +62,9 @@ public sealed class OpenIddictClientSystemIntegrationConfiguration : IConfigureO ArgumentNullException.ThrowIfNull(options); // Ensure the operating system version is supported. - if ((OperatingSystem.IsAndroid() && !OperatingSystem.IsAndroidVersionAtLeast(21)) || - (OperatingSystem.IsIOS() && !OperatingSystem.IsIOSVersionAtLeast(12)) || - OperatingSystem.IsLinux() || - (OperatingSystem.IsMacCatalyst() && !OperatingSystem.IsMacCatalystVersionAtLeast(13, 1)) || - (OperatingSystem.IsMacOS() && !OperatingSystem.IsMacOSVersionAtLeast(10, 15)) || - (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(7))) + if (!OperatingSystem.IsAndroidVersionAtLeast(21) && !OperatingSystem.IsIOSVersionAtLeast(12) && + !OperatingSystem.IsLinux() && !OperatingSystem.IsMacCatalystVersionAtLeast(13, 1) && + !OperatingSystem.IsMacOSVersionAtLeast(10, 15) && !OperatingSystem.IsWindowsVersionAtLeast(7)) { throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389)); } diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs index 31f6d5c1..02a364bc 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs @@ -28,12 +28,9 @@ public static class OpenIddictClientSystemIntegrationExtensions ArgumentNullException.ThrowIfNull(builder); // Ensure the operating system version is supported. - if ((OperatingSystem.IsAndroid() && !OperatingSystem.IsAndroidVersionAtLeast(21)) || - (OperatingSystem.IsIOS() && !OperatingSystem.IsIOSVersionAtLeast(12)) || - OperatingSystem.IsLinux() || - (OperatingSystem.IsMacCatalyst() && !OperatingSystem.IsMacCatalystVersionAtLeast(13, 1)) || - (OperatingSystem.IsMacOS() && !OperatingSystem.IsMacOSVersionAtLeast(10, 15)) || - (OperatingSystem.IsWindows() && !OperatingSystem.IsWindowsVersionAtLeast(7))) + if (!OperatingSystem.IsAndroidVersionAtLeast(21) && !OperatingSystem.IsIOSVersionAtLeast(12) && + !OperatingSystem.IsLinux() && !OperatingSystem.IsMacCatalystVersionAtLeast(13, 1) && + !OperatingSystem.IsMacOSVersionAtLeast(10, 15) && !OperatingSystem.IsWindowsVersionAtLeast(7)) { throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389)); } diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs index 9ff291fe..079c8ee1 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs @@ -77,7 +77,7 @@ public static class OpenIddictClientSystemIntegrationHelpers [SupportedOSPlatformGuard("maccatalyst13.1")] [SupportedOSPlatformGuard("macos10.15")] internal static bool IsASWebAuthenticationSessionSupported() -#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON +#if SUPPORTS_AUTHENTICATION_SERVICES => OperatingSystem.IsIOSVersionAtLeast(12) || OperatingSystem.IsMacCatalystVersionAtLeast(13) || OperatingSystem.IsMacOSVersionAtLeast(10, 15); @@ -92,7 +92,7 @@ public static class OpenIddictClientSystemIntegrationHelpers [MethodImpl(MethodImplOptions.AggressiveInlining)] [SupportedOSPlatformGuard("android21.0")] internal static bool IsCustomTabsIntentSupported() -#if SUPPORTS_ANDROIDX_BROWSER && SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON +#if SUPPORTS_ANDROIDX_BROWSER => OperatingSystem.IsAndroidVersionAtLeast(21); #else => false; diff --git a/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj b/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj index ea267002..968b12e7 100644 --- a/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj +++ b/src/OpenIddict.Client.SystemNetHttp/OpenIddict.Client.SystemNetHttp.csproj @@ -6,7 +6,6 @@ $(NetCoreTargetFrameworks); $(NetStandardTargetFrameworks) - $(DefineConstants);FeatureRuntimeInformation diff --git a/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj b/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj index 5ed8891f..3b2fcfcb 100644 --- a/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj +++ b/src/OpenIddict.Validation.SystemNetHttp/OpenIddict.Validation.SystemNetHttp.csproj @@ -6,7 +6,6 @@ $(NetCoreTargetFrameworks); $(NetStandardTargetFrameworks) - $(DefineConstants);FeatureRuntimeInformation