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)