Skip to content

Commit

Permalink
Add support for prefersEphemeralSession on iOS. Refs #771 (#787)
Browse files Browse the repository at this point in the history
  • Loading branch information
badsyntax authored Nov 23, 2022
1 parent f8c9162 commit 96afce5
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 20 deletions.
1 change: 1 addition & 0 deletions Example/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const App = () => {
const newAuthState = await authorize({
...config,
connectionTimeoutSeconds: 5,
iosPrefersEphemeralSession: true
});

setAuthState({
Expand Down
4 changes: 2 additions & 2 deletions Example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ PODS:
- React-jsi (= 0.63.2)
- React-jsinspector (0.63.2)
- react-native-app-auth (6.4.3):
- AppAuth (~> 1.4)
- AppAuth (~> 1.6)
- React-Core
- React-RCTActionSheet (0.63.2):
- React-Core/RCTActionSheetHeaders (= 0.63.2)
Expand Down Expand Up @@ -366,7 +366,7 @@ SPEC CHECKSUMS:
React-jsi: 54245e1d5f4b690dec614a73a3795964eeef13a8
React-jsiexecutor: 8ca588cc921e70590820ce72b8789b02c67cce38
React-jsinspector: b14e62ebe7a66e9231e9581279909f2fc3db6606
react-native-app-auth: e5b48009fda193a6a6808ec8f3d2cf159d9cbba4
react-native-app-auth: 0aaa426c98f354afa487f1d792bd711d83495a22
React-RCTActionSheet: 910163b6b09685a35c4ebbc52b66d1bfbbe39fc5
React-RCTAnimation: 9a883bbe1e9d2e158d4fb53765ed64c8dc2200c6
React-RCTBlob: 39cf0ece1927996c4466510e25d2105f67010e13
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ with optional overrides.
- **usePKCE** - (`boolean`) (default: true) optionally allows not sending the code_challenge parameter and skipping PKCE code verification, to support non-compliant providers.
- **skipCodeExchange** - (`boolean`) (default: false) just return the authorization response, instead of automatically exchanging the authorization code. This is useful if this exchange needs to be done manually (not client-side)
- **iosCustomBrowser** - (`string`) (default: undefined) _IOS_ override the used browser for authorization, used to open an external browser. If no value is provided, the `SFAuthenticationSession` or `SFSafariViewController` are used.
- **iosPrefersEphemeralSession** - (`boolean`) (default: `false`) _IOS_ indicates whether the session should ask the browser for a private authentication session.
- **androidAllowCustomBrowsers** - (`string[]`) (default: undefined) _ANDROID_ override the used browser for authorization. If no value is provided, all browsers are allowed.
- **connectionTimeoutSeconds** - (`number`) configure the request timeout interval in seconds. This must be a positive number. The default values are 60 seconds on iOS and 15 seconds on Android.

Expand Down
11 changes: 10 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,21 @@ export type AuthConfiguration = BaseAuthConfiguration & {
warmAndPrefetchChrome?: boolean;
skipCodeExchange?: boolean;
iosCustomBrowser?: 'safari' | 'chrome' | 'opera' | 'firefox';
androidAllowCustomBrowsers?: ('chrome' | 'chromeCustomTab' | 'firefox' | 'firefoxCustomTab' | 'samsung' | 'samsungCustomTab')[]
androidAllowCustomBrowsers?: (
| 'chrome'
| 'chromeCustomTab'
| 'firefox'
| 'firefoxCustomTab'
| 'samsung'
| 'samsungCustomTab'
)[];
iosPrefersEphemeralSession?: boolean;
};

export type EndSessionConfiguration = BaseAuthConfiguration & {
additionalParameters?: { [name: string]: string };
dangerouslyAllowInsecureHttpRequests?: boolean;
iosPrefersEphemeralSession?: boolean;
};

export interface AuthorizeResult {
Expand Down
4 changes: 4 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ export const authorize = ({
iosCustomBrowser = null,
androidAllowCustomBrowsers = null,
connectionTimeoutSeconds,
iosPrefersEphemeralSession = false,
}) => {
validateIssuerOrServiceConfigurationEndpoints(issuer, serviceConfiguration);
validateClientId(clientId);
Expand Down Expand Up @@ -245,6 +246,7 @@ export const authorize = ({
nativeMethodArguments.push(useNonce);
nativeMethodArguments.push(usePKCE);
nativeMethodArguments.push(iosCustomBrowser);
nativeMethodArguments.push(iosPrefersEphemeralSession);
}

return RNAppAuth.authorize(...nativeMethodArguments);
Expand Down Expand Up @@ -356,6 +358,7 @@ export const logout = (
additionalParameters,
dangerouslyAllowInsecureHttpRequests = false,
iosCustomBrowser = null,
iosPrefersEphemeralSession = false,
androidAllowCustomBrowsers = null,
},
{ idToken, postLogoutRedirectUrl }
Expand All @@ -379,6 +382,7 @@ export const logout = (

if (Platform.OS === 'ios') {
nativeMethodArguments.push(iosCustomBrowser);
nativeMethodArguments.push(iosPrefersEphemeralSession);
}

return RNAppAuth.logout(...nativeMethodArguments);
Expand Down
28 changes: 19 additions & 9 deletions index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ describe('AppAuth', () => {
connectionTimeoutSeconds: TIMEOUT_SEC,
skipCodeExchange: false,
iosCustomBrowser: 'safari',
iosPrefersEphemeralSession: true,
androidAllowCustomBrowsers: ['chrome'],
};

Expand Down Expand Up @@ -533,7 +534,8 @@ describe('AppAuth', () => {
config.additionalHeaders,
config.useNonce,
config.usePKCE,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});

Expand Down Expand Up @@ -562,7 +564,8 @@ describe('AppAuth', () => {
null,
true,
true,
null
null,
false
);
});

Expand All @@ -587,7 +590,8 @@ describe('AppAuth', () => {
config.additionalHeaders,
config.useNonce,
config.usePKCE,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});
});
Expand All @@ -609,7 +613,8 @@ describe('AppAuth', () => {
additionalHeaders,
config.useNonce,
config.usePKCE,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});

Expand Down Expand Up @@ -641,7 +646,8 @@ describe('AppAuth', () => {
config.additionalHeaders,
true,
true,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});

Expand All @@ -660,7 +666,8 @@ describe('AppAuth', () => {
config.additionalHeaders,
false,
true,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});
});
Expand All @@ -681,7 +688,8 @@ describe('AppAuth', () => {
config.additionalHeaders,
config.useNonce,
true,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});

Expand All @@ -700,7 +708,8 @@ describe('AppAuth', () => {
config.additionalHeaders,
config.useNonce,
false,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});
});
Expand Down Expand Up @@ -1120,7 +1129,8 @@ describe('AppAuth', () => {
'_redirect_',
config.serviceConfiguration,
config.additionalParameters,
config.iosCustomBrowser
config.iosCustomBrowser,
config.iosPrefersEphemeralSession
);
});
});
Expand Down
46 changes: 39 additions & 7 deletions ios/RNAppAuth.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ - (dispatch_queue_t)methodQueue
*/
static NSUInteger const kCodeVerifierBytes = 32;



RCT_EXPORT_MODULE()

RCT_REMAP_METHOD(register,
Expand Down Expand Up @@ -98,6 +100,7 @@ - (dispatch_queue_t)methodQueue
useNonce: (BOOL *) useNonce
usePKCE: (BOOL *) usePKCE
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject)
{
Expand All @@ -116,6 +119,7 @@ - (dispatch_queue_t)methodQueue
additionalParameters: additionalParameters
skipCodeExchange: skipCodeExchange
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
reject: reject];
} else {
Expand All @@ -136,6 +140,7 @@ - (dispatch_queue_t)methodQueue
additionalParameters: additionalParameters
skipCodeExchange: skipCodeExchange
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
reject: reject];
}];
Expand Down Expand Up @@ -199,6 +204,7 @@ - (dispatch_queue_t)methodQueue
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
additionalParameters: (NSDictionary *_Nullable) additionalParameters
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve:(RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject)
{
Expand All @@ -209,6 +215,7 @@ - (dispatch_queue_t)methodQueue
postLogoutRedirectURL: postLogoutRedirectURL
additionalParameters: additionalParameters
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
reject: reject];

Expand All @@ -224,6 +231,7 @@ - (dispatch_queue_t)methodQueue
postLogoutRedirectURL: postLogoutRedirectURL
additionalParameters: additionalParameters
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
reject: reject];
}];
Expand Down Expand Up @@ -322,6 +330,7 @@ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
additionalParameters: (NSDictionary *_Nullable) additionalParameters
skipCodeExchange: (BOOL) skipCodeExchange
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject
{
Expand Down Expand Up @@ -383,9 +392,16 @@ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
externalUserAgent:externalUserAgent
callback:callback];
} else {
_currentSession = [OIDAuthorizationService presentAuthorizationRequest:request
if (@available(iOS 13, *)) {
_currentSession = [OIDAuthorizationService presentAuthorizationRequest:request
presentingViewController:presentingViewController
prefersEphemeralSession:prefersEphemeralSession
callback:callback];
} else {
_currentSession = [OIDAuthorizationService presentAuthorizationRequest:request
presentingViewController:presentingViewController
callback:callback];
}
}
} else {

Expand All @@ -408,10 +424,16 @@ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
[self getErrorMessage: error], error);
}
};

_currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request
presentingViewController:presentingViewController
callback:callback];
if (@available(iOS 13, *)) {
_currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request
presentingViewController:presentingViewController
prefersEphemeralSession:prefersEphemeralSession
callback:callback];
} else {
_currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request
presentingViewController:presentingViewController
callback:callback];
}
}
}
}
Expand Down Expand Up @@ -458,6 +480,7 @@ - (void)endSessionWithConfiguration: (OIDServiceConfiguration *) configuration
postLogoutRedirectURL: (NSString *) postLogoutRedirectURL
additionalParameters: (NSDictionary *_Nullable) additionalParameters
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject {

Expand All @@ -482,7 +505,8 @@ - (void)endSessionWithConfiguration: (OIDServiceConfiguration *) configuration

UIViewController *presentingViewController = appDelegate.window.rootViewController.view.window ? appDelegate.window.rootViewController : appDelegate.window.rootViewController.presentedViewController;

id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : [self getExternalUserAgentWithPresentingViewController:presentingViewController];
id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : [self getExternalUserAgentWithPresentingViewController:presentingViewController
prefersEphemeralSession:prefersEphemeralSession];

_currentSession = [OIDAuthorizationService presentEndSessionRequest: endSessionRequest
externalUserAgent: externalUserAgent
Expand Down Expand Up @@ -695,12 +719,20 @@ - (NSString*)getErrorMessage: (NSError*) error {
}

- (id<OIDExternalUserAgent>)getExternalUserAgentWithPresentingViewController: (UIViewController *)presentingViewController
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
{
id<OIDExternalUserAgent> externalUserAgent;
#if TARGET_OS_MACCATALYST
externalUserAgent = [[OIDExternalUserAgentCatalyst alloc] initWithPresentingViewController:presentingViewController];
#elif TARGET_OS_IOS
externalUserAgent = [[OIDExternalUserAgentIOS alloc] initWithPresentingViewController:presentingViewController];
if (@available(iOS 13, *)) {
externalUserAgent = [[OIDExternalUserAgentIOS alloc] initWithPresentingViewController:
presentingViewController
prefersEphemeralSession:prefersEphemeralSession];
} else {
externalUserAgent = [[OIDExternalUserAgentIOS alloc] initWithPresentingViewController:
presentingViewController];
}
#elif TARGET_OS_OSX
externalUserAgent = [[OIDExternalUserAgentMac alloc] init];
#endif
Expand Down
2 changes: 1 addition & 1 deletion react-native-app-auth.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ Pod::Spec.new do |s|
s.source_files = 'ios/**/*.{h,m}'
s.requires_arc = true
s.dependency 'React-Core'
s.dependency 'AppAuth', '~> 1.4'
s.dependency 'AppAuth', '~> 1.6'
end

0 comments on commit 96afce5

Please sign in to comment.