Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add visionOS support #821

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,12 @@ let package = Package(
name: "AppAuth",
dependencies: ["AppAuthCore"],
path: "Source/AppAuth",
sources: ["iOS", "macOS"],
sources: ["iOS", "macOS", "visionOS"],
publicHeadersPath: "",
cSettings: [
.headerSearchPath("iOS"),
.headerSearchPath("macOS"),
.headerSearchPath("visionOS"),
.headerSearchPath("macOS/LoopbackHTTPServer"),
]
),
Expand Down
5 changes: 5 additions & 0 deletions Source/AppAuth.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
#import "OIDAuthorizationService+Mac.h"
#import "OIDExternalUserAgentMac.h"
#import "OIDRedirectHTTPHandler.h"
#elif TARGET_OS_VISION
#import "OIDAuthState+Vision.h"
#import "OIDAuthorizationService+Vision.h"
#import "OIDExternalUserAgentVision.h"
#import "OIDExternalUserAgentVisionCustomBrowser.h"
#else
#error "Platform Undefined"
#endif
Expand Down
6 changes: 3 additions & 3 deletions Source/AppAuth/iOS/OIDAuthState+IOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingViewController:(UIViewController *)presentingViewController
callback:(OIDAuthStateAuthorizationCallback)callback;
completion:(OIDAuthStateAuthorizationCallback)callback;

/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
(optionally using an emphemeral browser session that shares no cookies or data with the
Expand All @@ -68,12 +68,12 @@ NS_ASSUME_NONNULL_BEGIN
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingViewController:(UIViewController *)presentingViewController
prefersEphemeralSession:(BOOL)prefersEphemeralSession
callback:(OIDAuthStateAuthorizationCallback)callback
completion:(OIDAuthStateAuthorizationCallback)callback
API_AVAILABLE(ios(13));

+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
callback:(OIDAuthStateAuthorizationCallback)callback API_AVAILABLE(ios(11)) API_UNAVAILABLE(macCatalyst)
completion:(OIDAuthStateAuthorizationCallback)callback API_AVAILABLE(ios(11)) API_UNAVAILABLE(macCatalyst)
__deprecated_msg("This method will not work on iOS 13. Use "
"authStateByPresentingAuthorizationRequest:presentingViewController:callback:");

Expand Down
12 changes: 6 additions & 6 deletions Source/AppAuth/iOS/OIDAuthState+IOS.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ @implementation OIDAuthState (IOS)
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingViewController:(UIViewController *)presentingViewController
callback:(OIDAuthStateAuthorizationCallback)callback {
completion:(OIDAuthStateAuthorizationCallback)callback {
id<OIDExternalUserAgent> externalUserAgent;
#if TARGET_OS_MACCATALYST
externalUserAgent = [[OIDExternalUserAgentCatalyst alloc]
Expand All @@ -39,14 +39,14 @@ @implementation OIDAuthState (IOS)
#endif // TARGET_OS_MACCATALYST
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
externalUserAgent:externalUserAgent
callback:callback];
completion:callback];
}

+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingViewController:(UIViewController *)presentingViewController
prefersEphemeralSession:(BOOL)prefersEphemeralSession
callback:(OIDAuthStateAuthorizationCallback)callback {
completion:(OIDAuthStateAuthorizationCallback)callback {
id<OIDExternalUserAgent> externalUserAgent;
#if TARGET_OS_MACCATALYST
externalUserAgent = [[OIDExternalUserAgentCatalyst alloc]
Expand All @@ -59,17 +59,17 @@ @implementation OIDAuthState (IOS)
#endif // TARGET_OS_MACCATALYST
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
externalUserAgent:externalUserAgent
callback:callback];
completion:callback];
}

#if !TARGET_OS_MACCATALYST
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
callback:(OIDAuthStateAuthorizationCallback)callback {
completion:(OIDAuthStateAuthorizationCallback)callback {
OIDExternalUserAgentIOS *externalUserAgent = [[OIDExternalUserAgentIOS alloc] init];
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
externalUserAgent:externalUserAgent
callback:callback];
completion:callback];
}
#endif // !TARGET_OS_MACCATALYST

Expand Down
63 changes: 44 additions & 19 deletions Source/AppAuth/iOS/OIDExternalUserAgentIOS.m
Original file line number Diff line number Diff line change
Expand Up @@ -104,26 +104,51 @@ - (BOOL)presentExternalUserAgentRequest:(id<OIDExternalUserAgentRequest>)request
if (!UIAccessibilityIsGuidedAccessEnabled()) {
__weak OIDExternalUserAgentIOS *weakSelf = self;
NSString *redirectScheme = request.redirectScheme;
ASWebAuthenticationSession *authenticationVC =
[[ASWebAuthenticationSession alloc] initWithURL:requestURL
callbackURLScheme:redirectScheme
completionHandler:^(NSURL * _Nullable callbackURL,
NSError * _Nullable error) {
__strong OIDExternalUserAgentIOS *strongSelf = weakSelf;
if (!strongSelf) {
ASWebAuthenticationSession *authenticationVC;
if (@available(iOS 17.4, *)) {
authenticationVC =
[[ASWebAuthenticationSession alloc] initWithURL:requestURL
callback: [ASWebAuthenticationSessionCallback callbackWithCustomScheme: redirectScheme]
completionHandler:^(NSURL * _Nullable callbackURL,
NSError * _Nullable error) {
__strong OIDExternalUserAgentIOS *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
strongSelf->_webAuthenticationVC = nil;
if (callbackURL) {
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
} else {
NSError *safariError =
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
underlyingError:error
description:nil];
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
}
}];
}
strongSelf->_webAuthenticationVC = nil;
if (callbackURL) {
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
} else {
NSError *safariError =
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
underlyingError:error
description:nil];
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
}
}];

} else {
authenticationVC = [[ASWebAuthenticationSession alloc] initWithURL:requestURL
callbackURLScheme:redirectScheme
completionHandler:^(NSURL * _Nullable callbackURL,
NSError * _Nullable error) {
__strong OIDExternalUserAgentIOS *strongSelf = weakSelf;
if (!strongSelf) {
return;
}
strongSelf->_webAuthenticationVC = nil;
if (callbackURL) {
[strongSelf->_session resumeExternalUserAgentFlowWithURL:callbackURL];
} else {
NSError *safariError =
[OIDErrorUtilities errorWithCode:OIDErrorCodeUserCanceledAuthorizationFlow
underlyingError:error
description:nil];
[strongSelf->_session failExternalUserAgentFlowWithError:safariError];
}
}];
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
if (@available(iOS 13.0, *)) {
authenticationVC.presentationContextProvider = self;
Expand Down
6 changes: 3 additions & 3 deletions Source/AppAuth/macOS/OIDAuthState+Mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingWindow:(NSWindow *)presentingWindow
callback:(OIDAuthStateAuthorizationCallback)callback;
completion:(OIDAuthStateAuthorizationCallback)callback;

/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
(optionally using an emphemeral browser session that shares no cookies or data with the
Expand All @@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingWindow:(NSWindow *)presentingWindow
prefersEphemeralSession:(BOOL)prefersEphemeralSession
callback:(OIDAuthStateAuthorizationCallback)callback
completion:(OIDAuthStateAuthorizationCallback)callback
API_AVAILABLE(macos(10.15));

/*! @param authorizationRequest The authorization request to present.
Expand All @@ -81,7 +81,7 @@ NS_ASSUME_NONNULL_BEGIN
*/
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
callback:(OIDAuthStateAuthorizationCallback)callback
completion:(OIDAuthStateAuthorizationCallback)callback
__deprecated_msg("For macOS 10.15 and above please use "
"authStateByPresentingAuthorizationRequest:presentingWindow:callback:");

Expand Down
12 changes: 6 additions & 6 deletions Source/AppAuth/macOS/OIDAuthState+Mac.m
Original file line number Diff line number Diff line change
Expand Up @@ -29,32 +29,32 @@ @implementation OIDAuthState (Mac)
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingWindow:(NSWindow *)presentingWindow
callback:(OIDAuthStateAuthorizationCallback)callback {
completion:(OIDAuthStateAuthorizationCallback)callback {
OIDExternalUserAgentMac *externalUserAgent = [[OIDExternalUserAgentMac alloc] initWithPresentingWindow:presentingWindow];
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
externalUserAgent:externalUserAgent
callback:callback];
completion:callback];
}
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingWindow:(NSWindow *)presentingWindow
prefersEphemeralSession:(BOOL)prefersEphemeralSession
callback:(OIDAuthStateAuthorizationCallback)callback {
completion:(OIDAuthStateAuthorizationCallback)callback {
OIDExternalUserAgentMac *externalUserAgent =
[[OIDExternalUserAgentMac alloc] initWithPresentingWindow:presentingWindow
prefersEphemeralSession:prefersEphemeralSession];
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
externalUserAgent:externalUserAgent
callback:callback];
completion:callback];
}

+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
callback:(OIDAuthStateAuthorizationCallback)callback {
completion:(OIDAuthStateAuthorizationCallback)callback {
OIDExternalUserAgentMac *externalUserAgent = [[OIDExternalUserAgentMac alloc] init];
return [self authStateByPresentingAuthorizationRequest:authorizationRequest
externalUserAgent:externalUserAgent
callback:callback];
completion:callback];
}

@end
Expand Down
90 changes: 90 additions & 0 deletions Source/AppAuth/visionOS/OIDAuthState+Vision.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*! @file OIDAuthState+Vision.h
@brief AppAuth iOS SDK
@copyright
Copyright 2016 Google Inc. All Rights Reserved.
@copydetails
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#import <TargetConditionals.h>

#if TARGET_OS_VISION

#import <UIKit/UIKit.h>

#import "OIDAuthState.h"

NS_ASSUME_NONNULL_BEGIN

/*! @brief visionOS specific convenience methods for @c OIDAuthState.
*/
@interface OIDAuthState (Vision)

/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
and performing the authorization code exchange in the case of code flow requests. For
the hybrid flow, the caller should validate the id_token and c_hash, then perform the token
request (@c OIDAuthorizationService.performTokenRequest:callback:)
and update the OIDAuthState with the results (@c
OIDAuthState.updateWithTokenResponse:error:).
@param authorizationRequest The authorization request to present.
@param presentingWindow The window to present the authentication flow.
@param callback The method called when the request has completed or failed.
@return A @c OIDExternalUserAgentSession instance which will terminate when it
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
*/
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingWindow:(UIWindow *)presentingWindow
completion:(OIDAuthStateAuthorizationCallback)callback;

/*! @brief Convenience method to create a @c OIDAuthState by presenting an authorization request
(optionally using an emphemeral browser session that shares no cookies or data with the
normal browser session) and performing the authorization code exchange in the case of code
flow requests. For the hybrid flow, the caller should validate the id_token and c_hash, then
perform the token request (@c OIDAuthorizationService.performTokenRequest:callback:)
and update the OIDAuthState with the results using
@c OIDAuthState.updateWithTokenResponse:error:.
@param authorizationRequest The authorization request to present.
@param presentingWindow The window to present the @c ASWebAuthenticationSession UI.
@param prefersEphemeralSession Whether the caller prefers to use a private authentication
session. See @c ASWebAuthenticationSession.prefersEphemeralWebBrowserSession for more.
@param callback The method called when the request has completed or failed.
@return A @c OIDExternalUserAgentSession instance which will terminate when it
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
*/
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
presentingWindow:(UIWindow *)presentingWindow
prefersEphemeralSession:(BOOL)prefersEphemeralSession
completion:(OIDAuthStateAuthorizationCallback)callback;

/*! @param authorizationRequest The authorization request to present.
@param callback The method called when the request has completed or failed.
@return A @c OIDExternalUserAgentSession instance which will terminate when it
receives a @c OIDExternalUserAgentSession.cancel message, or after processing a
@c OIDExternalUserAgentSession.resumeExternalUserAgentFlowWithURL: message.
@discussion This method uses the default browser to present the authentication flow.
*/
+ (id<OIDExternalUserAgentSession>)
authStateByPresentingAuthorizationRequest:(OIDAuthorizationRequest *)authorizationRequest
completion:(OIDAuthStateAuthorizationCallback)callback
__deprecated_msg("For visionOS 1.0 and above please use "
"authStateByPresentingAuthorizationRequest:presentingWindow:callback:");

@end

NS_ASSUME_NONNULL_END

#endif // TARGET_OS_OSX
Loading