From b6bce3e5ddca3acddcb79e65ea9b982335d1dc7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Chalet?= Date: Sun, 30 Jun 2024 10:30:37 +0200 Subject: [PATCH] Update OpenIddict.Client.SystemIntegration to target Mac Catalyst 13.1+ and macOS 10.15+ --- Directory.Build.props | 35 ++++++++ Directory.Build.targets | 54 +++++++++++- .../App.xaml.cs | 2 +- .../AppShell.xaml.cs | 2 +- .../MainPage.xaml.cs | 2 +- .../MauiHostApplicationLifetime.cs | 2 +- .../MauiHostedServiceAdapter.cs | 2 +- .../MauiProgram.cs | 2 +- .../OpenIddict.Sandbox.Maui.Client.csproj | 1 + .../Platforms/MacCatalyst/AppDelegate.cs | 11 +++ .../Platforms/MacCatalyst/Entitlements.plist | 14 ++++ .../Platforms/MacCatalyst/Info.plist | 38 +++++++++ .../Platforms/MacCatalyst/Program.cs | 11 +++ .../OpenIddict.Sandbox.Maui.Client/Program.cs | 4 +- .../OpenIddict.Sandbox.Maui.Client/Worker.cs | 2 +- ...OpenIddict.Client.SystemIntegration.csproj | 6 +- ...ientSystemIntegrationAuthenticationMode.cs | 2 + ...penIddictClientSystemIntegrationBuilder.cs | 2 + ...ictClientSystemIntegrationConfiguration.cs | 6 +- ...IddictClientSystemIntegrationExtensions.cs | 6 +- ...ctClientSystemIntegrationHandlerFilters.cs | 2 +- ...ystemIntegrationHandlers.Authentication.cs | 29 +++++-- ...ClientSystemIntegrationHandlers.Session.cs | 29 +++++-- ...enIddictClientSystemIntegrationHandlers.cs | 8 +- ...penIddictClientSystemIntegrationHelpers.cs | 84 +++++++++++-------- ...penIddictClientSystemIntegrationService.cs | 8 +- src/OpenIddict/OpenIddict.csproj | 2 + 27 files changed, 297 insertions(+), 69 deletions(-) create mode 100644 sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/AppDelegate.cs create mode 100644 sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Entitlements.plist create mode 100644 sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Info.plist create mode 100644 sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Program.cs diff --git a/Directory.Build.props b/Directory.Build.props index a5607ffa..7b38938b 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -43,6 +43,31 @@ ('$(GITHUB_ACTIONS)' == 'true' Or ('$(DotNetRoot)' != '' And Exists('$(DotNetRoot)packs\Microsoft.iOS.Ref')) Or ('$(DOTNET_HOST_PATH)' != '' And Exists('$([System.IO.Path]::GetDirectoryName($(DOTNET_HOST_PATH)))\packs\Microsoft.iOS.Ref')) Or ('$(MSBuildRuntimeType)' != 'Core' And Exists('$(ProgramFiles)\dotnet\packs\Microsoft.iOS.Ref'))) ">true + + true + + true + + true @@ -76,6 +101,16 @@ net8.0-ios13.0 + + net8.0-maccatalyst13.1 + + + + net8.0-macos10.15 + + net6.0-windows7.0; diff --git a/Directory.Build.targets b/Directory.Build.targets index 310bfb97..b572572d 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -22,6 +22,20 @@ 12.0 + + 13.1 + + + + 10.15 + + - $(DefineConstants);SUPPORTS_AUTHENTICATION_SERVICES + $([MSBuild]::VersionGreaterThanOrEquals($(TargetPlatformVersion), '12.0'))) Or + + ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '5.0')) And + '$(TargetPlatformIdentifier)' == 'MacCatalyst' And '$(TargetPlatformVersion)' != '' And + $([MSBuild]::VersionGreaterThanOrEquals($(TargetPlatformVersion), '13.1'))) "> $(DefineConstants);SUPPORTS_UIKIT + + $(DefineConstants);SUPPORTS_APPKIT + + + $([MSBuild]::VersionGreaterThanOrEquals($(TargetPlatformVersion), '12.0'))) Or + + ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '5.0')) And + '$(TargetPlatformIdentifier)' == 'MacCatalyst' And '$(TargetPlatformVersion)' != '' And + $([MSBuild]::VersionGreaterThanOrEquals($(TargetPlatformVersion), '13.1'))) Or + + ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And $([MSBuild]::VersionGreaterThanOrEquals($(TargetFrameworkVersion), '5.0')) And + '$(TargetPlatformIdentifier)' == 'macOS' And '$(TargetPlatformVersion)' != '' And + $([MSBuild]::VersionGreaterThanOrEquals($(TargetPlatformVersion), '10.15'))) "> + $(DefineConstants);SUPPORTS_AUTHENTICATION_SERVICES + $(DefineConstants);SUPPORTS_FOUNDATION + + + $(DefineConstants);SUPPORTS_PRESENTATION_CONTEXT_PROVIDER diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/App.xaml.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/App.xaml.cs index 42de8c84..a7e187fe 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/App.xaml.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/App.xaml.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS namespace OpenIddict.Sandbox.Maui.Client; public partial class App : Application diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/AppShell.xaml.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/AppShell.xaml.cs index b3c46f73..094ba586 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/AppShell.xaml.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/AppShell.xaml.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS namespace OpenIddict.Sandbox.Maui.Client; public partial class AppShell : Shell diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs index 7d50f66b..f2c07ba6 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/MainPage.xaml.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS using OpenIddict.Abstractions; using OpenIddict.Client; using static OpenIddict.Abstractions.OpenIddictConstants; diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostApplicationLifetime.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostApplicationLifetime.cs index e3d25bdb..55842427 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostApplicationLifetime.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostApplicationLifetime.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS using Microsoft.Extensions.Hosting; namespace OpenIddict.Sandbox.Maui.Client; diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostedServiceAdapter.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostedServiceAdapter.cs index 8bc1a73a..d19fa882 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostedServiceAdapter.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiHostedServiceAdapter.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS using Microsoft.Extensions.Hosting; namespace OpenIddict.Sandbox.Maui.Client; diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs index 1c5dc3db..f172493a 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/MauiProgram.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS using System.Net.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Hosting; diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/OpenIddict.Sandbox.Maui.Client.csproj b/sandbox/OpenIddict.Sandbox.Maui.Client/OpenIddict.Sandbox.Maui.Client.csproj index 7ecc789a..670ba498 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/OpenIddict.Sandbox.Maui.Client.csproj +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/OpenIddict.Sandbox.Maui.Client.csproj @@ -4,6 +4,7 @@ Exe net8.0-windows10.0.19041 $(TargetFrameworks);net8.0-ios17.2 + $(TargetFrameworks);net8.0-maccatalyst17.2 true net8.0 true diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/AppDelegate.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/AppDelegate.cs new file mode 100644 index 00000000..3ff7b465 --- /dev/null +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/AppDelegate.cs @@ -0,0 +1,11 @@ +#if MACCATALYST +using Foundation; + +namespace OpenIddict.Sandbox.Maui.Client; + +[Register("AppDelegate")] +public class AppDelegate : MauiUIApplicationDelegate +{ + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); +} +#endif diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Entitlements.plist b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Entitlements.plist new file mode 100644 index 00000000..468ec91c --- /dev/null +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Entitlements.plist @@ -0,0 +1,14 @@ + + + + + + + com.apple.security.app-sandbox + + + com.apple.security.network.client + + + + diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Info.plist b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Info.plist new file mode 100644 index 00000000..72689771 --- /dev/null +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Info.plist @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + UIDeviceFamily + + 2 + + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/appicon.appiconset + + diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Program.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Program.cs new file mode 100644 index 00000000..f6d30888 --- /dev/null +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/Platforms/MacCatalyst/Program.cs @@ -0,0 +1,11 @@ +#if MACCATALYST +using ObjCRuntime; +using UIKit; + +namespace OpenIddict.Sandbox.Maui.Client; + +public static class Program +{ + public static void Main(string[] args) => UIApplication.Main(args, null, typeof(AppDelegate)); +} +#endif diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/Program.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/Program.cs index 415e6c91..6dd27db3 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/Program.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/Program.cs @@ -1,3 +1,3 @@ -#if !IOS && !WINDOWS -Console.Error.WriteLine("This sample is only supported on iOS and Windows."); +#if !IOS && !MACCATALYST && !WINDOWS +Console.Error.WriteLine("This sample is only supported on iOS, Mac Catalyst and Windows."); #endif diff --git a/sandbox/OpenIddict.Sandbox.Maui.Client/Worker.cs b/sandbox/OpenIddict.Sandbox.Maui.Client/Worker.cs index 6cac5262..2146f842 100644 --- a/sandbox/OpenIddict.Sandbox.Maui.Client/Worker.cs +++ b/sandbox/OpenIddict.Sandbox.Maui.Client/Worker.cs @@ -1,4 +1,4 @@ -#if IOS || WINDOWS +#if IOS || MACCATALYST || WINDOWS using Microsoft.EntityFrameworkCore; namespace OpenIddict.Sandbox.Maui.Client; diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj b/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj index eef7b032..447b8512 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddict.Client.SystemIntegration.csproj @@ -5,6 +5,8 @@ $(NetFrameworkTargetFrameworks); $(NetCoreTargetFrameworks); $(NetCoreIOSTargetFrameworks); + $(NetCoreMacCatalystTargetFrameworks); + $(NetCoreMacOSTargetFrameworks); $(NetCoreWindowsTargetFrameworks); $(NetStandardTargetFrameworks); $(UniversalWindowsPlatformTargetFrameworks) @@ -14,7 +16,7 @@ Operating system integration package for the OpenIddict client. - $(PackageTags);client;ios;linux;windows + $(PackageTags);client;ios;linux;maccatalyst;macos;windows @@ -54,6 +56,8 @@ + + diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationAuthenticationMode.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationAuthenticationMode.cs index 349043e2..bc89e8d8 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationAuthenticationMode.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationAuthenticationMode.cs @@ -32,5 +32,7 @@ public enum OpenIddictClientSystemIntegrationAuthenticationMode /// AS web authentication session-based authentication and logout. /// [SupportedOSPlatform("ios12.0")] + [SupportedOSPlatform("maccatalyst13.0")] + [SupportedOSPlatform("macos10.15")] ASWebAuthenticationSession = 2 } diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationBuilder.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationBuilder.cs index 6c17092e..0a85d7dc 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationBuilder.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationBuilder.cs @@ -54,6 +54,8 @@ public sealed class OpenIddictClientSystemIntegrationBuilder /// /// The . [SupportedOSPlatform("ios12.0")] + [SupportedOSPlatform("maccatalyst13.0")] + [SupportedOSPlatform("macos10.15")] public OpenIddictClientSystemIntegrationBuilder UseASWebAuthenticationSession() { if (!OpenIddictClientSystemIntegrationHelpers.IsASWebAuthenticationSessionSupported()) diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs index a7742293..67bf70b8 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationConfiguration.cs @@ -74,8 +74,10 @@ public sealed class OpenIddictClientSystemIntegrationConfiguration : IConfigureO throw new ArgumentNullException(nameof(options)); } - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) && - !RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) && + !RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && + !RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst")) && + !RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389)); diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs index eb9f3fe7..51b02726 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationExtensions.cs @@ -31,8 +31,10 @@ public static class OpenIddictClientSystemIntegrationExtensions throw new ArgumentNullException(nameof(builder)); } - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) && - !RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) && + !RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && + !RuntimeInformation.IsOSPlatform(OSPlatform.Create("maccatalyst")) && + !RuntimeInformation.IsOSPlatform(OSPlatform.OSX) && !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { throw new PlatformNotSupportedException(SR.GetResourceString(SR.ID0389)); diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlerFilters.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlerFilters.cs index c025bdee..6636533d 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlerFilters.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlerFilters.cs @@ -30,7 +30,7 @@ public static class OpenIddictClientSystemIntegrationHandlerFilters throw new ArgumentNullException(nameof(context)); } -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION if (OpenIddictClientSystemIntegrationHelpers.IsASWebAuthenticationSessionSupported()) { return new(ContainsASWebAuthenticationSessionResult(context.Transaction)); diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs index e09693d5..923e5aa5 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Authentication.cs @@ -16,6 +16,16 @@ using OpenIddict.Extensions; using AuthenticationServices; #endif +#if SUPPORTS_FOUNDATION +using Foundation; +#endif + +#if SUPPORTS_APPKIT +using NativeWindow = AppKit.NSWindow; +#elif SUPPORTS_UIKIT +using NativeWindow = UIKit.UIWindow; +#endif + #if SUPPORTS_WINDOWS_RUNTIME using Windows.Security.Authentication.Web; using Windows.UI.Core; @@ -90,7 +100,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008)); -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION if (string.IsNullOrEmpty(context.RedirectUri)) { return; @@ -141,7 +151,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers // which the Safari web view will be attached MUST be provided (otherwise, a code 2 // error is returned by ASWebAuthenticationSession). To avoid that, a default provider // pointing to the current UI window is automatically attached on iOS 13.0 and higher. - if (OpenIddictClientSystemIntegrationHelpers.IsIOSVersionAtLeast(13)) + if (OperatingSystem.IsIOSVersionAtLeast(13)) { #pragma warning disable CA1416 session.PresentationContextProvider = new ASWebAuthenticationPresentationContext( @@ -199,10 +209,10 @@ public static partial class OpenIddictClientSystemIntegrationHandlers } #if SUPPORTS_AUTHENTICATION_SERVICES - class ASWebAuthenticationPresentationContext(UIWindow window) : NSObject, + class ASWebAuthenticationPresentationContext(NativeWindow window) : NSObject, IASWebAuthenticationPresentationContextProviding { - UIWindow IASWebAuthenticationPresentationContextProviding.GetPresentationAnchor( + NativeWindow IASWebAuthenticationPresentationContextProviding.GetPresentationAnchor( ASWebAuthenticationSession session) => window; } #endif @@ -405,9 +415,14 @@ public static partial class OpenIddictClientSystemIntegrationHandlers } } -#if SUPPORTS_UIKIT - if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) && - await OpenIddictClientSystemIntegrationHelpers.TryLaunchBrowserWithUIApplicationAsync(uri)) +#if SUPPORTS_APPKIT + if (OperatingSystem.IsMacOS() && await OpenIddictClientSystemIntegrationHelpers.TryLaunchBrowserWithNSWorkspaceAsync(uri)) + { + context.HandleRequest(); + return; + } +#elif SUPPORTS_UIKIT + if (OperatingSystem.IsIOS() && await OpenIddictClientSystemIntegrationHelpers.TryLaunchBrowserWithUIApplicationAsync(uri)) { context.HandleRequest(); return; diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs index 0adb3a16..bc66a8ba 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.Session.cs @@ -16,6 +16,16 @@ using OpenIddict.Extensions; using AuthenticationServices; #endif +#if SUPPORTS_FOUNDATION +using Foundation; +#endif + +#if SUPPORTS_APPKIT +using NativeWindow = AppKit.NSWindow; +#elif SUPPORTS_UIKIT +using NativeWindow = UIKit.UIWindow; +#endif + #if SUPPORTS_WINDOWS_RUNTIME using Windows.Security.Authentication.Web; using Windows.UI.Core; @@ -90,7 +100,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers Debug.Assert(context.Transaction.Request is not null, SR.GetResourceString(SR.ID4008)); -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION if (string.IsNullOrEmpty(context.PostLogoutRedirectUri)) { return; @@ -141,7 +151,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers // which the Safari web view will be attached MUST be provided (otherwise, a code 2 // error is returned by ASWebAuthenticationSession). To avoid that, a default provider // pointing to the current UI window is automatically attached on iOS 13.0 and higher. - if (OpenIddictClientSystemIntegrationHelpers.IsIOSVersionAtLeast(13)) + if (OperatingSystem.IsIOSVersionAtLeast(13)) { #pragma warning disable CA1416 session.PresentationContextProvider = new ASWebAuthenticationPresentationContext( @@ -198,10 +208,10 @@ public static partial class OpenIddictClientSystemIntegrationHandlers } #if SUPPORTS_AUTHENTICATION_SERVICES - class ASWebAuthenticationPresentationContext(UIWindow window) : NSObject, + class ASWebAuthenticationPresentationContext(NativeWindow window) : NSObject, IASWebAuthenticationPresentationContextProviding { - UIWindow IASWebAuthenticationPresentationContextProviding.GetPresentationAnchor( + NativeWindow IASWebAuthenticationPresentationContextProviding.GetPresentationAnchor( ASWebAuthenticationSession session) => window; } #endif @@ -404,9 +414,14 @@ public static partial class OpenIddictClientSystemIntegrationHandlers } } -#if SUPPORTS_UIKIT - if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("ios")) && - await OpenIddictClientSystemIntegrationHelpers.TryLaunchBrowserWithUIApplicationAsync(uri)) +#if SUPPORTS_APPKIT + if (OperatingSystem.IsMacOS() && await OpenIddictClientSystemIntegrationHelpers.TryLaunchBrowserWithNSWorkspaceAsync(uri)) + { + context.HandleRequest(); + return; + } +#elif SUPPORTS_UIKIT + if (OperatingSystem.IsIOS() && await OpenIddictClientSystemIntegrationHelpers.TryLaunchBrowserWithUIApplicationAsync(uri)) { context.HandleRequest(); return; diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs index 66619895..62102c69 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHandlers.cs @@ -24,6 +24,10 @@ using static OpenIddict.Client.SystemIntegration.OpenIddictClientSystemIntegrati using IHostApplicationLifetime = Microsoft.Extensions.Hosting.IApplicationLifetime; #endif +#if SUPPORTS_FOUNDATION +using Foundation; +#endif + #if SUPPORTS_WINDOWS_RUNTIME using Windows.Security.Authentication.Web; #endif @@ -231,7 +235,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers throw new ArgumentNullException(nameof(context)); } -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION (context.BaseUri, context.RequestUri) = context.Transaction.GetASWebAuthenticationCallbackUrl() switch { NSUrl url when Uri.TryCreate(url.AbsoluteString, UriKind.Absolute, out Uri? uri) => ( @@ -642,7 +646,7 @@ public static partial class OpenIddictClientSystemIntegrationHandlers throw new ArgumentNullException(nameof(context)); } -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION if (context.Transaction.GetASWebAuthenticationCallbackUrl() is not NSUrl url || !Uri.TryCreate(url.AbsoluteString, UriKind.Absolute, out Uri? uri)) { diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs index 6b687722..af62e00c 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationHelpers.cs @@ -13,6 +13,17 @@ using System.Runtime.Versioning; using System.Security.Principal; using OpenIddict.Extensions; +#if SUPPORTS_FOUNDATION +using Foundation; +#endif + +#if SUPPORTS_APPKIT +using AppKit; +using NativeWindow = AppKit.NSWindow; +#elif SUPPORTS_UIKIT +using NativeWindow = UIKit.UIWindow; +#endif + #if SUPPORTS_WINDOWS_RUNTIME using Windows.ApplicationModel.Activation; using Windows.ApplicationModel; @@ -44,13 +55,15 @@ public static class OpenIddictClientSystemIntegrationHelpers public static HttpListenerContext? GetHttpListenerContext(this OpenIddictClientTransaction transaction) => transaction.GetProperty(typeof(HttpListenerContext).FullName!); -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION /// /// Gets the AS web authentication callback URL associated with the current context. /// /// The transaction instance. /// The instance or if it couldn't be found. [SupportedOSPlatform("ios12.0")] + [SupportedOSPlatform("maccatalyst13.0")] + [SupportedOSPlatform("macos10.15")] public static NSUrl? GetASWebAuthenticationCallbackUrl(this OpenIddictClientTransaction transaction) => transaction.GetProperty(typeof(NSUrl).FullName!); #endif @@ -66,27 +79,6 @@ public static class OpenIddictClientSystemIntegrationHelpers => transaction.GetProperty(typeof(WebAuthenticationResult).FullName!); #endif - /// - /// Determines whether the current iOS version - /// is greater than or equals to the specified version. - /// - /// - /// if the current iOS version is greater than - /// or equals to the specified version, otherwise. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [SupportedOSPlatformGuard("ios")] - internal static bool IsIOSVersionAtLeast(int major, int minor = 0, int build = 0) - { -#if SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON - return OperatingSystem.IsIOSVersionAtLeast(major, minor, build); -#else - return RuntimeInformation.OSDescription.StartsWith("iOS ", StringComparison.OrdinalIgnoreCase) && - RuntimeInformation.OSDescription["iOS ".Length..] is string value && - Version.TryParse(value, out Version? version) && version >= new Version(major, minor, build); -#endif - } - /// /// Determines whether the current Windows version /// is greater than or equals to the specified version. @@ -125,7 +117,16 @@ public static class OpenIddictClientSystemIntegrationHelpers /// if the ASWebAuthenticationSession API is supported, otherwise. [MethodImpl(MethodImplOptions.AggressiveInlining)] [SupportedOSPlatformGuard("ios12.0")] - internal static bool IsASWebAuthenticationSessionSupported() => IsIOSVersionAtLeast(12); + [SupportedOSPlatformGuard("maccatalyst13.0")] + [SupportedOSPlatformGuard("macos10.15")] + internal static bool IsASWebAuthenticationSessionSupported() +#if SUPPORTS_OPERATING_SYSTEM_VERSIONS_COMPARISON + => OperatingSystem.IsIOSVersionAtLeast(12) || + OperatingSystem.IsMacCatalystVersionAtLeast(13) || + OperatingSystem.IsMacOSVersionAtLeast(10, 15); +#else + => false; +#endif /// /// Determines whether the Windows Runtime APIs are supported on this platform. @@ -250,11 +251,14 @@ public static class OpenIddictClientSystemIntegrationHelpers #if SUPPORTS_PRESENTATION_CONTEXT_PROVIDER /// - /// Gets a reference to the current . + /// Gets a reference to the current . /// - /// The or if it couldn't be resolved. - internal static UIWindow? GetCurrentUIWindow() + /// The or if it couldn't be resolved. + internal static NativeWindow? GetCurrentUIWindow() { +#if SUPPORTS_APPKIT + return NSApplication.SharedApplication.KeyWindow; +#elif SUPPORTS_UIKIT var window = GetKeyWindow(); if (window is not null && window.WindowLevel == UIWindowLevel.Normal) { @@ -269,7 +273,7 @@ public static class OpenIddictClientSystemIntegrationHelpers static UIWindow? GetKeyWindow() { - if (IsIOSVersionAtLeast(13)) + if (OperatingSystem.IsIOSVersionAtLeast(13)) { try { @@ -292,7 +296,7 @@ public static class OpenIddictClientSystemIntegrationHelpers static UIWindow[]? GetWindows() { - if (IsIOSVersionAtLeast(13)) + if (OperatingSystem.IsIOSVersionAtLeast(13)) { try { @@ -312,6 +316,7 @@ public static class OpenIddictClientSystemIntegrationHelpers return UIApplication.SharedApplication.Windows; } +#endif } #endif @@ -344,7 +349,7 @@ public static class OpenIddictClientSystemIntegrationHelpers /// The to use. /// if the browser could be started, otherwise. [MethodImpl(MethodImplOptions.NoInlining), SupportedOSPlatform("windows10.0.17763")] - internal static async Task TryLaunchBrowserWithWindowsRuntimeAsync(Uri uri) + internal static async ValueTask TryLaunchBrowserWithWindowsRuntimeAsync(Uri uri) { // Note: with the materialization of Project Centennial/Desktop Bridge in Windows 10 1607 // (also known as Anniversary Update), desktop applications that don't have a package @@ -393,7 +398,7 @@ public static class OpenIddictClientSystemIntegrationHelpers /// if the browser could be started, otherwise. [SupportedOSPlatform("linux")] [SupportedOSPlatform("windows")] - internal static async Task TryLaunchBrowserWithShellExecuteAsync(Uri uri) + internal static async ValueTask TryLaunchBrowserWithShellExecuteAsync(Uri uri) { try { @@ -417,15 +422,26 @@ public static class OpenIddictClientSystemIntegrationHelpers } } +#if SUPPORTS_APPKIT + /// + /// Starts the system browser using . + /// + /// The to use. + /// if the browser could be started, otherwise. + [SupportedOSPlatform("macos")] + internal static ValueTask TryLaunchBrowserWithNSWorkspaceAsync(Uri uri) + => new(NSWorkspace.SharedWorkspace.OpenUrl(new NSUrl(uri.AbsoluteUri))); +#endif + #if SUPPORTS_UIKIT /// - /// Starts the system browser using xdg-open. + /// Starts the system browser using . /// /// The to use. /// if the browser could be started, otherwise. [SupportedOSPlatform("ios")] - internal static Task TryLaunchBrowserWithUIApplicationAsync(Uri uri) - => UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(uri.AbsoluteUri), new UIApplicationOpenUrlOptions()); + internal static ValueTask TryLaunchBrowserWithUIApplicationAsync(Uri uri) + => new(UIApplication.SharedApplication.OpenUrlAsync(new NSUrl(uri.AbsoluteUri), new UIApplicationOpenUrlOptions())); #endif /// @@ -434,7 +450,7 @@ public static class OpenIddictClientSystemIntegrationHelpers /// The to use. /// if the browser could be started, otherwise. [SupportedOSPlatform("linux")] - internal static async Task TryLaunchBrowserWithXdgOpenAsync(Uri uri) + internal static async ValueTask TryLaunchBrowserWithXdgOpenAsync(Uri uri) { try { diff --git a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs index 7c61e055..321ecfb8 100644 --- a/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs +++ b/src/OpenIddict.Client.SystemIntegration/OpenIddictClientSystemIntegrationService.cs @@ -12,6 +12,10 @@ using System.Security.Principal; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; +#if SUPPORTS_FOUNDATION +using Foundation; +#endif + #if SUPPORTS_WINDOWS_RUNTIME using Windows.Security.Authentication.Web; #endif @@ -64,7 +68,7 @@ public sealed class OpenIddictClientSystemIntegrationService internal Task HandleHttpRequestAsync(HttpListenerContext request, CancellationToken cancellationToken = default) => HandleRequestAsync(request ?? throw new ArgumentNullException(nameof(request)), cancellationToken); -#if SUPPORTS_AUTHENTICATION_SERVICES +#if SUPPORTS_AUTHENTICATION_SERVICES && SUPPORTS_FOUNDATION /// /// Handles the specified AS web authentication session callback URL. /// @@ -73,6 +77,8 @@ public sealed class OpenIddictClientSystemIntegrationService /// A that can be used to monitor the asynchronous operation. /// is . [SupportedOSPlatform("ios12.0")] + [SupportedOSPlatform("maccatalyst13.0")] + [SupportedOSPlatform("macos10.15")] internal Task HandleASWebAuthenticationCallbackUrlAsync(NSUrl url, CancellationToken cancellationToken = default) => HandleRequestAsync(url, cancellationToken); #endif diff --git a/src/OpenIddict/OpenIddict.csproj b/src/OpenIddict/OpenIddict.csproj index 4d366996..c074a675 100644 --- a/src/OpenIddict/OpenIddict.csproj +++ b/src/OpenIddict/OpenIddict.csproj @@ -5,6 +5,8 @@ $(NetFrameworkTargetFrameworks); $(NetCoreTargetFrameworks); $(NetCoreIOSTargetFrameworks); + $(NetCoreMacCatalystTargetFrameworks); + $(NetCoreMacOSTargetFrameworks); $(NetCoreWindowsTargetFrameworks); $(NetStandardTargetFrameworks); $(UniversalWindowsPlatformTargetFrameworks)