Comparing sensitive data, confidential files or internal emails?

Most legal and privacy policies prohibit uploading sensitive data online. Diffchecker Desktop ensures your confidential information never leaves your computer. Work offline and compare documents securely.

RNAppAuth.m (react-native-app-auth@7.1.3)

Created Diff never expires
28 removals
413 lines
26 additions
411 lines
#import "RNAppAuth.h"
#import "RNAppAuth.h"
#if __has_include(<AppAuth/AppAuth.h>)
#if __has_include(<AppAuth/AppAuth.h>)
#import <AppAuth/AppAuth.h>
#import <AppAuth/AppAuth.h>
#else
#else
#import "AppAuth.h"
#import "AppAuth.h"
#endif
#endif
#import <React/RCTLog.h>
#import <React/RCTLog.h>
#import <React/RCTConvert.h>
#import <React/RCTConvert.h>
#import "RNAppAuthAuthorizationFlowManager.h"
#import "RNAppAuthAuthorizationFlowManager.h"


@interface RNAppAuth()<RNAppAuthAuthorizationFlowManagerDelegate> {
@interface RNAppAuth()<RNAppAuthAuthorizationFlowManagerDelegate> {
id<OIDExternalUserAgentSession> _currentSession;
id<OIDExternalUserAgentSession> _currentSession;
}
}
@property (nonatomic, copy) RCTPromiseRejectBlock authorizeRejectBlock;
@end
@end


@implementation RNAppAuth
@implementation RNAppAuth


-(BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)url {
-(BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)url {
return [_currentSession resumeExternalUserAgentFlowWithURL:url];
return [_currentSession resumeExternalUserAgentFlowWithURL:url];
}
}


- (dispatch_queue_t)methodQueue
- (dispatch_queue_t)methodQueue
{
{
return dispatch_get_main_queue();
return dispatch_get_main_queue();
}
}


UIBackgroundTaskIdentifier rnAppAuthTaskId;
UIBackgroundTaskIdentifier rnAppAuthTaskId;


/*! @brief Number of random bytes generated for the @ state.
/*! @brief Number of random bytes generated for the @ state.
*/
*/
static NSUInteger const kStateSizeBytes = 32;
static NSUInteger const kStateSizeBytes = 32;


/*! @brief Number of random bytes generated for the @ codeVerifier.
/*! @brief Number of random bytes generated for the @ codeVerifier.
*/
*/
static NSUInteger const kCodeVerifierBytes = 32;
static NSUInteger const kCodeVerifierBytes = 32;






RCT_EXPORT_MODULE()
RCT_EXPORT_MODULE()


RCT_REMAP_METHOD(cancelAuthorizationFlow,
cancelAuthorizationFlowWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
if (self->_currentSession) {
id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate;
UIViewController *presentingViewController = appDelegate.window.rootViewController.view.window ? appDelegate.window.rootViewController : appDelegate.window.rootViewController.presentedViewController;
[presentingViewController dismissViewControllerAnimated:YES completion:^{
resolve(@"Authorization flow cancelled");
self->_currentSession = nil;
NSError *error = [NSError errorWithDomain:@"RNAppAuth" code:0 userInfo:@{NSLocalizedDescriptionKey: @"Authorization flow cancelled"}];
if(self.authorizeRejectBlock != nil) {
self.authorizeRejectBlock([self getErrorCode: error defaultCode:@"browser_force_closed"], @"Authorization flow cancelled", error);
}
self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks.
}];
} else {
NSError *error = [NSError errorWithDomain:@"RNAppAuth" code:500 userInfo:@{NSLocalizedDescriptionKey: @"No current session available to cancel"}];
reject(@"no_current_session", @"No current session available to cancel", error);
}
}

RCT_REMAP_METHOD(register,
RCT_REMAP_METHOD(register,
issuer: (NSString *) issuer
issuer: (NSString *) issuer
redirectUrls: (NSArray *) redirectUrls
redirectUrls: (NSArray *) redirectUrls
responseTypes: (NSArray *) responseTypes
responseTypes: (NSArray *) responseTypes
grantTypes: (NSArray *) grantTypes
grantTypes: (NSArray *) grantTypes
subjectType: (NSString *) subjectType
subjectType: (NSString *) subjectType
tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod
tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod
additionalParameters: (NSDictionary *_Nullable) additionalParameters
additionalParameters: (NSDictionary *_Nullable) additionalParameters
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
connectionTimeoutSeconds: (double) connectionTimeoutSeconds
connectionTimeoutSeconds: (double) connectionTimeoutSeconds
additionalHeaders: (NSDictionary *_Nullable) additionalHeaders
additionalHeaders: (NSDictionary *_Nullable) additionalHeaders
resolve: (RCTPromiseResolveBlock) resolve
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject)
reject: (RCTPromiseRejectBlock) reject)
{
{
[self configureUrlSession:additionalHeaders sessionTimeout:connectionTimeoutSeconds];
[self configureUrlSession:additionalHeaders sessionTimeout:connectionTimeoutSeconds];


// if we have manually provided configuration, we can use it and skip the OIDC well-known discovery endpoint call
// if we have manually provided configuration, we can use it and skip the OIDC well-known discovery endpoint call
if (serviceConfiguration) {
if (serviceConfiguration) {
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
[self registerWithConfiguration: configuration
[self registerWithConfiguration: configuration
redirectUrls: redirectUrls
redirectUrls: redirectUrls
responseTypes: responseTypes
responseTypes: responseTypes
grantTypes: grantTypes
grantTypes: grantTypes
subjectType: subjectType
subjectType: subjectType
tokenEndpointAuthMethod: tokenEndpointAuthMethod
tokenEndpointAuthMethod: tokenEndpointAuthMethod
additionalParameters: additionalParameters
additionalParameters: additionalParameters
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
} else {
} else {
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
if (!configuration) {
if (!configuration) {
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
return;
return;
}
}
[self registerWithConfiguration: configuration
[self registerWithConfiguration: configuration
redirectUrls: redirectUrls
redirectUrls: redirectUrls
responseTypes: responseTypes
responseTypes: responseTypes
grantTypes: grantTypes
grantTypes: grantTypes
subjectType: subjectType
subjectType: subjectType
tokenEndpointAuthMethod: tokenEndpointAuthMethod
tokenEndpointAuthMethod: tokenEndpointAuthMethod
additionalParameters: additionalParameters
additionalParameters: additionalParameters
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
}];
}];
}
}
} // end RCT_REMAP_METHOD(register,
} // end RCT_REMAP_METHOD(register,


RCT_REMAP_METHOD(authorize,
RCT_REMAP_METHOD(authorize,
issuer: (NSString *) issuer
issuer: (NSString *) issuer
redirectUrl: (NSString *) redirectUrl
redirectUrl: (NSString *) redirectUrl
clientId: (NSString *) clientId
clientId: (NSString *) clientId
clientSecret: (NSString *) clientSecret
clientSecret: (NSString *) clientSecret
scopes: (NSArray *) scopes
scopes: (NSArray *) scopes
additionalParameters: (NSDictionary *_Nullable) additionalParameters
additionalParameters: (NSDictionary *_Nullable) additionalParameters
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
skipCodeExchange: (BOOL) skipCodeExchange
skipCodeExchange: (BOOL) skipCodeExchange
connectionTimeoutSeconds: (double) connectionTimeoutSeconds
connectionTimeoutSeconds: (double) connectionTimeoutSeconds
additionalHeaders: (NSDictionary *_Nullable) additionalHeaders
additionalHeaders: (NSDictionary *_Nullable) additionalHeaders
useNonce: (BOOL *) useNonce
useNonce: (BOOL *) useNonce
usePKCE: (BOOL *) usePKCE
usePKCE: (BOOL *) usePKCE
iosCustomBrowser: (NSString *) iosCustomBrowser
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve: (RCTPromiseResolveBlock) resolve
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject)
reject: (RCTPromiseRejectBlock) reject)
{
{
self.authorizeRejectBlock = reject;
[self configureUrlSession:additionalHeaders sessionTimeout:connectionTimeoutSeconds];
[self configureUrlSession:additionalHeaders sessionTimeout:connectionTimeoutSeconds];


// if we have manually provided configuration, we can use it and skip the OIDC well-known discovery endpoint call
// if we have manually provided configuration, we can use it and skip the OIDC well-known discovery endpoint call
if (serviceConfiguration) {
if (serviceConfiguration) {
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
[self authorizeWithConfiguration: configuration
[self authorizeWithConfiguration: configuration
redirectUrl: redirectUrl
redirectUrl: redirectUrl
clientId: clientId
clientId: clientId
clientSecret: clientSecret
clientSecret: clientSecret
scopes: scopes
scopes: scopes
useNonce: useNonce
useNonce: useNonce
usePKCE: usePKCE
usePKCE: usePKCE
additionalParameters: additionalParameters
additionalParameters: additionalParameters
skipCodeExchange: skipCodeExchange
skipCodeExchange: skipCodeExchange
iosCustomBrowser: iosCustomBrowser
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
} else {
} else {
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
if (!configuration) {
if (!configuration) {
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks.
return;
return;
}
}
[self authorizeWithConfiguration: configuration
[self authorizeWithConfiguration: configuration
redirectUrl: redirectUrl
redirectUrl: redirectUrl
clientId: clientId
clientId: clientId
clientSecret: clientSecret
clientSecret: clientSecret
scopes: scopes
scopes: scopes
useNonce: useNonce
useNonce: useNonce
usePKCE: usePKCE
usePKCE: usePKCE
additionalParameters: additionalParameters
additionalParameters: additionalParameters
skipCodeExchange: skipCodeExchange
skipCodeExchange: skipCodeExchange
iosCustomBrowser: iosCustomBrowser
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
}];
}];
}
}
} // end RCT_REMAP_METHOD(authorize,
} // end RCT_REMAP_METHOD(authorize,


RCT_REMAP_METHOD(refresh,
RCT_REMAP_METHOD(refresh,
issuer: (NSString *) issuer
issuer: (NSString *) issuer
redirectUrl: (NSString *) redirectUrl
redirectUrl: (NSString *) redirectUrl
clientId: (NSString *) clientId
clientId: (NSString *) clientId
clientSecret: (NSString *) clientSecret
clientSecret: (NSString *) clientSecret
refreshToken: (NSString *) refreshToken
refreshToken: (NSString *) refreshToken
scopes: (NSArray *) scopes
scopes: (NSArray *) scopes
additionalParameters: (NSDictionary *_Nullable) additionalParameters
additionalParameters: (NSDictionary *_Nullable) additionalParameters
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
connectionTimeoutSeconds: (double) connectionTimeoutSeconds
connectionTimeoutSeconds: (double) connectionTimeoutSeconds
additionalHeaders: (NSDictionary *_Nullable) additionalHeaders
additionalHeaders: (NSDictionary *_Nullable) additionalHeaders
iosCustomBrowser: (NSString *) iosCustomBrowser
iosCustomBrowser: (NSString *) iosCustomBrowser
resolve:(RCTPromiseResolveBlock) resolve
resolve:(RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject)
reject: (RCTPromiseRejectBlock) reject)
{
{
[self configureUrlSession:additionalHeaders sessionTimeout:connectionTimeoutSeconds];
[self configureUrlSession:additionalHeaders sessionTimeout:connectionTimeoutSeconds];


// if we have manually provided configuration, we can use it and skip the OIDC well-known discovery endpoint call
// if we have manually provided configuration, we can use it and skip the OIDC well-known discovery endpoint call
if (serviceConfiguration) {
if (serviceConfiguration) {
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
[self refreshWithConfiguration: configuration
[self refreshWithConfiguration: configuration
redirectUrl: redirectUrl
redirectUrl: redirectUrl
clientId: clientId
clientId: clientId
clientSecret: clientSecret
clientSecret: clientSecret
refreshToken: refreshToken
refreshToken: refreshToken
scopes: scopes
scopes: scopes
additionalParameters: additionalParameters
additionalParameters: additionalParameters
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
} else {
} else {
// otherwise hit up the discovery endpoint
// otherwise hit up the discovery endpoint
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
if (!configuration) {
if (!configuration) {
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
return;
return;
}
}
[self refreshWithConfiguration: configuration
[self refreshWithConfiguration: configuration
redirectUrl: redirectUrl
redirectUrl: redirectUrl
clientId: clientId
clientId: clientId
clientSecret: clientSecret
clientSecret: clientSecret
refreshToken: refreshToken
refreshToken: refreshToken
scopes: scopes
scopes: scopes
additionalParameters: additionalParameters
additionalParameters: additionalParameters
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
}];
}];
}
}
} // end RCT_REMAP_METHOD(refresh,
} // end RCT_REMAP_METHOD(refresh,


RCT_REMAP_METHOD(logout,
RCT_REMAP_METHOD(logout,
issuer: (NSString *) issuer
issuer: (NSString *) issuer
idTokenHint: (NSString *) idTokenHint
idTokenHint: (NSString *) idTokenHint
postLogoutRedirectURL: (NSString *) postLogoutRedirectURL
postLogoutRedirectURL: (NSString *) postLogoutRedirectURL
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration
additionalParameters: (NSDictionary *_Nullable) additionalParameters
additionalParameters: (NSDictionary *_Nullable) additionalParameters
iosCustomBrowser: (NSString *) iosCustomBrowser
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve:(RCTPromiseResolveBlock) resolve
resolve:(RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject)
reject: (RCTPromiseRejectBlock) reject)
{
{
if (serviceConfiguration) {
if (serviceConfiguration) {
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration];
[self endSessionWithConfiguration: configuration
[self endSessionWithConfiguration: configuration
idTokenHint: idTokenHint
idTokenHint: idTokenHint
postLogoutRedirectURL: postLogoutRedirectURL
postLogoutRedirectURL: postLogoutRedirectURL
additionalParameters: additionalParameters
additionalParameters: additionalParameters
iosCustomBrowser: iosCustomBrowser
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];


} else {
} else {
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
[OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer]
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) {
if (!configuration) {
if (!configuration) {
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
reject(@"service_configuration_fetch_error", [error localizedDescription], error);
return;
return;
}
}
[self endSessionWithConfiguration: configuration
[self endSessionWithConfiguration: configuration
idTokenHint: idTokenHint
idTokenHint: idTokenHint
postLogoutRedirectURL: postLogoutRedirectURL
postLogoutRedirectURL: postLogoutRedirectURL
additionalParameters: additionalParameters
additionalParameters: additionalParameters
iosCustomBrowser: iosCustomBrowser
iosCustomBrowser: iosCustomBrowser
prefersEphemeralSession: prefersEphemeralSession
prefersEphemeralSession: prefersEphemeralSession
resolve: resolve
resolve: resolve
reject: reject];
reject: reject];
}];
}];
}
}
} // end RCT_REMAP_METHOD(logout,
} // end RCT_REMAP_METHOD(logout,


/*
/*
* Create a OIDServiceConfiguration from passed serviceConfiguration dictionary
* Create a OIDServiceConfiguration from passed serviceConfiguration dictionary
*/
*/
- (OIDServiceConfiguration *) createServiceConfiguration: (NSDictionary *) serviceConfiguration {
- (OIDServiceConfiguration *) createServiceConfiguration: (NSDictionary *) serviceConfiguration {
NSURL *authorizationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"authorizationEndpoint"]];
NSURL *authorizationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"authorizationEndpoint"]];
NSURL *tokenEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"tokenEndpoint"]];
NSURL *tokenEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"tokenEndpoint"]];
NSURL *registrationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"registrationEndpoint"]];
NSURL *registrationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"registrationEndpoint"]];
NSURL *endSessionEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"endSessionEndpoint"]];
NSURL *endSessionEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"endSessionEndpoint"]];


OIDServiceConfiguration *configuration =
OIDServiceConfiguration *configuration =
[[OIDServiceConfiguration alloc]
[[OIDServiceConfiguration alloc]
initWithAuthorizationEndpoint:authorizationEndpoint
initWithAuthorizationEndpoint:authorizationEndpoint
tokenEndpoint:tokenEndpoint
tokenEndpoint:tokenEndpoint
issuer:nil
issuer:nil
registrationEndpoint:registrationEndpoint
registrationEndpoint:registrationEndpoint
endSessionEndpoint:endSessionEndpoint];
endSessionEndpoint:endSessionEndpoint];


return configuration;
return configuration;
}
}


+ (nullable NSString *)generateCodeVerifier {
+ (nullable NSString *)generateCodeVerifier {
return [OIDTokenUtilities randomURLSafeStringWithSize:kCodeVerifierBytes];
return [OIDTokenUtilities randomURLSafeStringWithSize:kCodeVerifierBytes];
}
}


+ (nullable NSString *)generateState {
+ (nullable NSString *)generateState {
return [OIDTokenUtilities randomURLSafeStringWithSize:kStateSizeBytes];
return [OIDTokenUtilities randomURLSafeStringWithSize:kStateSizeBytes];
}
}


+ (nullable NSString *)codeChallengeS256ForVerifier:(NSString *)codeVerifier {
+ (nullable NSString *)codeChallengeS256ForVerifier:(NSString *)codeVerifier {
if (!codeVerifier) {
if (!codeVerifier) {
return nil;
return nil;
}
}
// generates the code_challenge per spec https://tools.ietf.org/html/rfc7636#section-4.2
// generates the code_challenge per spec https://tools.ietf.org/html/rfc7636#section-4.2
// code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
// code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
// NB. the ASCII conversion on the code_verifier entropy was done at time of generation.
// NB. the ASCII conversion on the code_verifier entropy was done at time of generation.
NSData *sha256Verifier = [OIDTokenUtilities sha256:codeVerifier];
NSData *sha256Verifier = [OIDTokenUtilities sha256:codeVerifier];
return [OIDTokenUtilities encodeBase64urlNoPadding:sha256Verifier];
return [OIDTokenUtilities encodeBase64urlNoPadding:sha256Verifier];
}
}




/*
/*
* Perform dynamic client registration with provided OIDServiceConfiguration
* Perform dynamic client registration with provided OIDServiceConfiguration
*/
*/
- (void)registerWithConfiguration: (OIDServiceConfiguration *) configuration
- (void)registerWithConfiguration: (OIDServiceConfiguration *) configuration
redirectUrls: (NSArray *) redirectUrlStrings
redirectUrls: (NSArray *) redirectUrlStrings
responseTypes: (NSArray *) responseTypes
responseTypes: (NSArray *) responseTypes
grantTypes: (NSArray *) grantTypes
grantTypes: (NSArray *) grantTypes
subjectType: (NSString *) subjectType
subjectType: (NSString *) subjectType
tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod
tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod
additionalParameters: (NSDictionary *_Nullable) additionalParameters
additionalParameters: (NSDictionary *_Nullable) additionalParameters
resolve: (RCTPromiseResolveBlock) resolve
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject
reject: (RCTPromiseRejectBlock) reject
{
{
NSMutableArray<NSURL *> *redirectUrls = [NSMutableArray arrayWithCapacity:[redirectUrlStrings count]];
NSMutableArray<NSURL *> *redirectUrls = [NSMutableArray arrayWithCapacity:[redirectUrlStrings count]];
for (NSString *urlString in redirectUrlStrings) {
for (NSString *urlString in redirectUrlStrings) {
[redirectUrls addObject:[NSURL URLWithString:urlString]];
[redirectUrls addObject:[NSURL URLWithString:urlString]];
}
}


OIDRegistrationRequest *request =
OIDRegistrationRequest *request =
[[OIDRegistrationRequest alloc] initWithConfiguration:configuration
[[OIDRegistrationRequest alloc] initWithConfiguration:configuration
redirectURIs:redirectUrls
redirectURIs:redirectUrls
responseTypes:responseTypes
responseTypes:responseTypes
grantTypes:grantTypes
grantTypes:grantTypes
subjectType:subjectType
subjectType:subjectType
tokenEndpointAuthMethod:tokenEndpointAuthMethod
tokenEndpointAuthMethod:tokenEndpointAuthMethod
additionalParameters:additionalParameters];
additionalParameters:additionalParameters];


[OIDAuthorizationService performRegistrationRequest:request
[OIDAuthorizationService performRegistrationRequest:request
completion:^(OIDRegistrationResponse *_Nullable response,
completion:^(OIDRegistrationResponse *_Nullable response,
NSError *_Nullable error) {
NSError *_Nullable error) {
if (response) {
if (response) {
resolve([self formatRegistrationResponse:response]);
resolve([self formatRegistrationResponse:response]);
} else {
} else {
reject([self getErrorCode: error defaultCode:@"registration_failed"],
reject([self getErrorCode: error defaultCode:@"registration_failed"],
[self getErrorMessage: error], error);
[self getErrorMessage: error], error);
}
}
}];
}];
}
}


/*
/*
* Authorize a user in exchange for a token with provided OIDServiceConfiguration
* Authorize a user in exchange for a token with provided OIDServiceConfiguration
*/
*/
- (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
- (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
redirectUrl: (NSString *) redirectUrl
redirectUrl: (NSString *) redirectUrl
clientId: (NSString *) clientId
clientId: (NSString *) clientId
clientSecret: (NSString *) clientSecret
clientSecret: (NSString *) clientSecret
scopes: (NSArray *) scopes
scopes: (NSArray *) scopes
useNonce: (BOOL *) useNonce
useNonce: (BOOL *) useNonce
usePKCE: (BOOL *) usePKCE
usePKCE: (BOOL *) usePKCE
additionalParameters: (NSDictionary *_Nullable) additionalParameters
additionalParameters: (NSDictionary *_Nullable) additionalParameters
skipCodeExchange: (BOOL) skipCodeExchange
skipCodeExchange: (BOOL) skipCodeExchange
iosCustomBrowser: (NSString *) iosCustomBrowser
iosCustomBrowser: (NSString *) iosCustomBrowser
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
prefersEphemeralSession: (BOOL *) prefersEphemeralSession
resolve: (RCTPromiseResolveBlock) resolve
resolve: (RCTPromiseResolveBlock) resolve
reject: (RCTPromiseRejectBlock) reject
reject: (RCTPromiseRejectBlock) reject
{
{


NSString *codeVerifier = usePKCE ? [[self class] generateCodeVerifier] : nil;
NSString *codeVerifier = usePKCE ? [[self class] generateCodeVerifier] : nil;
NSString *codeChallenge = usePKCE ? [[self class] codeChallengeS256ForVerifier:codeVerifier] : nil;
NSString *codeChallenge = usePKCE ? [[self class] codeChallengeS256ForVerifier:codeVerifier] : nil;
NSString *nonce = useNonce ? additionalParameters[@"nonce"]? additionalParameters[@"nonce"]: [[self class] generateState] : nil ;
NSString *nonce = useNonce ? additionalParameters[@"nonce"]? additionalParameters[@"nonce"]: [[self class] generateState] : nil ;


// builds authentication request
// builds authentication request
OIDAuthorizationRequest *request =
OIDAuthorizationRequest *request =
[[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
[[OIDAuthorizationRequest alloc] initWithConfiguration:configuration
clientId:clientId
clientId:clientId
clientSecret:clientSecret
clientSecret:clientSecret
scope:[OIDScopeUtilities scopesWithArray:scopes]
scope:[OIDScopeUtilities scopesWithArray:scopes]
redirectURL:[NSURL URLWithString:redirectUrl]
redirectURL:[NSURL URLWithString:redirectUrl]
responseType:OIDResponseTypeCode
responseType:OIDResponseTypeCode
state: additionalParameters[@"state"] ? additionalParameters[@"state"] : [[self class] generateState]
state: additionalParameters[@"state"] ? additionalParameters[@"state"] : [[self class] generateState]
nonce:nonce
nonce:nonce
codeVerifier:codeVerifier
codeVerifier:codeVerifier
codeChallenge:codeChallenge
codeChallenge:codeChallenge
codeChallengeMethod: usePKCE ? OIDOAuthorizationRequestCodeChallengeMethodS256 : nil
codeChallengeMethod: usePKCE ? OIDOAuthorizationRequestCodeChallengeMethodS256 : nil
additionalParameters:additionalParameters];
additionalParameters:additionalParameters];


// performs authentication request
// performs authentication request
id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate;
id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate;
if (![[appDelegate class] conformsToProtocol:@protocol(RNAppAuthAuthorizationFlowManager)]) {
if (![[appDelegate class] conformsToProtocol:@protocol(RNAppAuthAuthorizationFlowManager)]) {
[NSException raise:@"RNAppAuth Missing protocol conformance"
[NSException raise:@"RNAppAuth Missing protocol conformance"
format:@"%@ does not conform to RNAppAuthAuthorizationFlowManager", appDelegate];
format:@"%@ does not conform to RNAppAuthAuthorizationFlowManager", appDelegate];
}
}
appDelegate.authorizationFlowManagerDelegate = self;
appDelegate.authorizationFlowManagerDelegate = self;
__weak typeof(self) weakSelf = self;
__weak typeof(self) weakSelf = self;


rnAppAuthTaskId = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{
rnAppAuthTaskId = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{
[UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId];
[UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId];
rnAppAuthTaskId = UIBackgroundTaskInvalid;
rnAppAuthTaskId = UIBackgroundTaskInvalid;
}];
}];


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


#if TARGET_OS_MACCATALYST
#if TARGET_OS_MACCATALYST
id<OIDExternalUserAgent> externalUserAgent = nil;
id<OIDExternalUserAgent> externalUserAgent = nil;
#elif TARGET_OS_IOS
#elif TARGET_OS_IOS
id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : nil;
id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : nil;
#endif
#endif
OIDAuthorizationCallback callback = ^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) {
OIDAuthorizationCallback callback = ^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) {
typeof(self) strongSelf = weakSelf;
typeof(self) strongSelf = weakSelf;
strongSelf->_currentSession = nil;
strongSelf->_currentSession = nil;
[UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId];
[UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId];
rnAppAuthTaskId = UIBackgroundTaskInvalid;
rnAppAuthTaskId = UIBackgroundTaskInvalid;
if (authorizationResponse) {
if (authorizationResponse) {
resolve([self formatAuthorizationResponse:authorizationResponse withCodeVerifier:codeVerifier]);
resolve([
} else {
reject([self getErrorCode: error defaultCode:@"authentication_failed"],
[self getErrorMessage: error], error);
}
};

if (skipCodeExchange) {
if(externalUserAgent != nil) {
_currentSession = [OIDAuthorizationService presentAuthorizationRequest:request
externalUserAgent:externalUserAgent
callback:callback];
} else {
if (@available(iOS 13, *)) {
_currentSession = [OIDAuthorizationService presentAuthorizationRequest:request
presentingViewController:presentingViewController
prefersEphemeralSession:prefersEphemeralSession
callback:callback];
} else {
_currentSession = [OIDAuthorizationService presentAuthorizationRequest:request
presentingViewController:presentingViewController
callback:callback];
}
}
} else {
OIDAuthStateAuthorizationCallback callback = ^(
OI