Skip to content

Commit

Permalink
Added iOS SF/ASWeb AuthenticationSession support (auth0#187)
Browse files Browse the repository at this point in the history
* Added support for iOS *AuthenticationSession
* iOS 11 SFAuthenticationSession
* iOS 12 ASWebAuthenticationSession
  • Loading branch information
cocojoe authored Jan 17, 2019
1 parent 359bc9b commit 14efe5f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 19 deletions.
82 changes: 67 additions & 15 deletions ios/A0Auth0.m
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
#import "A0Auth0.h"

#import <SafariServices/SafariServices.h>
#if __has_include("AuthenticationServices/AuthenticationServices.h")
#import <AuthenticationServices/AuthenticationServices.h>
#endif
#import <CommonCrypto/CommonCrypto.h>

#if __has_include("RCTUtils.h")
Expand All @@ -10,8 +13,12 @@
#import <React/RCTUtils.h>
#endif

#define ERROR_CANCELLED @{@"error": @"a0.session.user_cancelled",@"error_description": @"User cancelled the Auth"}
#define ERROR_FAILED_TO_LOAD @{@"error": @"a0.session.failed_load",@"error_description": @"Failed to load url"}

@interface A0Auth0 () <SFSafariViewControllerDelegate>
@property (weak, nonatomic) SFSafariViewController *last;
@property (strong, nonatomic) NSObject *authenticationSession;
@property (copy, nonatomic) RCTResponseSenderBlock sessionCallback;
@property (assign, nonatomic) BOOL closeOnLoad;
@end
Expand All @@ -30,9 +37,15 @@ - (dispatch_queue_t)methodQueue
}

RCT_EXPORT_METHOD(showUrl:(NSString *)urlString closeOnLoad:(BOOL)closeOnLoad callback:(RCTResponseSenderBlock)callback) {
[self presentSafariWithURL:[NSURL URLWithString:urlString]];
self.closeOnLoad = closeOnLoad;
self.sessionCallback = callback;
if (@available(iOS 11.0, *)) {
self.sessionCallback = callback;
self.closeOnLoad = closeOnLoad;
[self presentAuthenticationSession:[NSURL URLWithString:urlString]];
} else {
[self presentSafariWithURL:[NSURL URLWithString:urlString]];
self.sessionCallback = callback;
self.closeOnLoad = closeOnLoad;
}
}

RCT_EXPORT_METHOD(oauthParameters:(RCTResponseSenderBlock)callback) {
Expand All @@ -58,17 +71,64 @@ - (void)presentSafariWithURL:(NSURL *)url {
self.last = controller;
}

- (void)presentAuthenticationSession:(NSURL *)url {

NSURLComponents *urlComponents = [NSURLComponents componentsWithURL:url
resolvingAgainstBaseURL:NO];
NSArray *queryItems = urlComponents.queryItems;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name=%@", @"redirect_uri"];
NSURLQueryItem *queryItem = [[queryItems
filteredArrayUsingPredicate:predicate]
firstObject];
NSString *callbackURLScheme = queryItem.value;
RCTResponseSenderBlock callback = self.sessionCallback ? self.sessionCallback : ^void(NSArray *_unused) {};

if (@available(iOS 12.0, *)) {
self.authenticationSession = [[ASWebAuthenticationSession alloc]
initWithURL:url callbackURLScheme:callbackURLScheme
completionHandler:^(NSURL * _Nullable callbackURL,
NSError * _Nullable error) {
if ([[error domain] isEqualToString:ASWebAuthenticationSessionErrorDomain] &&
[error code] == ASWebAuthenticationSessionErrorCodeCanceledLogin) {
callback(@[ERROR_CANCELLED, [NSNull null]]);
} else if(error) {
callback(@[error, [NSNull null]]);
} else if(callbackURL) {
callback(@[[NSNull null], callbackURL.absoluteString]);
}
self.authenticationSession = nil;
}];
[(ASWebAuthenticationSession*) self.authenticationSession start];
} else if (@available(iOS 11.0, *)) {
self.authenticationSession = [[SFAuthenticationSession alloc]
initWithURL:url callbackURLScheme:callbackURLScheme
completionHandler:^(NSURL * _Nullable callbackURL,
NSError * _Nullable error) {
if ([[error domain] isEqualToString:SFAuthenticationErrorDomain] &&
[error code] == SFAuthenticationErrorCanceledLogin) {
callback(@[ERROR_CANCELLED, [NSNull null]]);
} else if(error) {
callback(@[error, [NSNull null]]);
} else if(callbackURL) {
callback(@[[NSNull null], callbackURL.absoluteString]);
}
self.authenticationSession = nil;
}];
[(SFAuthenticationSession*) self.authenticationSession start];
}
}

- (void)terminateWithError:(id)error dismissing:(BOOL)dismissing animated:(BOOL)animated {
RCTResponseSenderBlock callback = self.sessionCallback ? self.sessionCallback : ^void(NSArray *_unused) {};
if (dismissing) {
[self.last.presentingViewController dismissViewControllerAnimated:animated
completion:^{
if (error) {
callback(@[error]);
callback(@[error, [NSNull null]]);
}
}];
} else if (error) {
callback(@[error]);
callback(@[error, [NSNull null]]);
}
self.sessionCallback = nil;
self.last = nil;
Expand Down Expand Up @@ -122,22 +182,14 @@ - (NSDictionary *)generateOAuthParameters {
#pragma mark - SFSafariViewControllerDelegate

- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller {
NSDictionary *error = @{
@"error": @"a0.session.user_cancelled",
@"error_description": @"User cancelled the Auth"
};
[self terminateWithError:error dismissing:NO animated:NO];
[self terminateWithError:ERROR_CANCELLED dismissing:NO animated:NO];
}

- (void)safariViewController:(SFSafariViewController *)controller didCompleteInitialLoad:(BOOL)didLoadSuccessfully {
if (self.closeOnLoad && didLoadSuccessfully) {
[self terminateWithError:[NSNull null] dismissing:YES animated:YES];
} else if (!didLoadSuccessfully) {
NSDictionary *error = @{
@"error": @"a0.session.failed_load",
@"error_description": @"Failed to load url"
};
[self terminateWithError:error dismissing:YES animated:YES];
[self terminateWithError:ERROR_FAILED_TO_LOAD dismissing:YES animated:YES];
}
}

Expand Down
10 changes: 6 additions & 4 deletions webauth/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ export default class Agent {
resolve(event.url);
};
Linking.addEventListener('url', urlHandler);
NativeModules.A0Auth0.showUrl(url, closeOnLoad, err => {
NativeModules.A0Auth0.showUrl(url, closeOnLoad, (error, redirectURL) => {
Linking.removeEventListener('url', urlHandler);
if (err) {
reject(err);
} else if (closeOnLoad) {
if (error) {
reject(error);
} else if(redirectURL) {
resolve(redirectURL);
} else if(closeOnLoad) {
resolve();
}
});
Expand Down

0 comments on commit 14efe5f

Please sign in to comment.