Diff
checker
テキスト
テキスト
画像
ドキュメント
Excel
フォルダ
Legal
Enterprise
デスクトップ
料金
ログイン
Diffchecker デスクトップのダウンロード
テキスト比較
2 つのテキスト ファイルの違いを見つける
ツール
履歴
ライブエディター
未変更行を折りたたむ
折り返しなし
レイアウト
分割
統合
比較精度
スマート
単語
文字
シンタックスハイライト
構文を選択
無視
テキスト変換
最初の差分へ移動
入力を編集
Diffchecker Desktop
Diffcheckerを実行する最も安全な方法。Diffchecker Desktopアプリを入手:あなたの差分はコンピューターから出ることはありません!
Desktopを入手
RNAppAuth.m (react-native-app-auth@7.1.3)
作成日
2 年前
差分は期限切れになりません
クリア
エクスポート
共有
説明
28 削除
行
合計
削除
文字
合計
削除
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
413 行
すべてコピー
25 追加
行
合計
追加
文字
合計
追加
この機能を引き続き使用するには、アップグレードしてください
Diff
checker
Pro
価格を見る
411 行
すべてコピー
#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
保存された差分
原文
ファイルを開く
#import "RNAppAuth.h" #if __has_include(<AppAuth/AppAuth.h>) #import <AppAuth/AppAuth.h> #else #import "AppAuth.h" #endif #import <React/RCTLog.h> #import <React/RCTConvert.h> #import "RNAppAuthAuthorizationFlowManager.h" @interface RNAppAuth()<RNAppAuthAuthorizationFlowManagerDelegate> { id<OIDExternalUserAgentSession> _currentSession; } @end @implementation RNAppAuth -(BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)url { return [_currentSession resumeExternalUserAgentFlowWithURL:url]; } - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } UIBackgroundTaskIdentifier rnAppAuthTaskId; /*! @brief Number of random bytes generated for the @ state. */ static NSUInteger const kStateSizeBytes = 32; /*! @brief Number of random bytes generated for the @ codeVerifier. */ static NSUInteger const kCodeVerifierBytes = 32; RCT_EXPORT_MODULE() RCT_REMAP_METHOD(register, issuer: (NSString *) issuer redirectUrls: (NSArray *) redirectUrls responseTypes: (NSArray *) responseTypes grantTypes: (NSArray *) grantTypes subjectType: (NSString *) subjectType tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod additionalParameters: (NSDictionary *_Nullable) additionalParameters serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration connectionTimeoutSeconds: (double) connectionTimeoutSeconds additionalHeaders: (NSDictionary *_Nullable) additionalHeaders resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { [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 (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self registerWithConfiguration: configuration redirectUrls: redirectUrls responseTypes: responseTypes grantTypes: grantTypes subjectType: subjectType tokenEndpointAuthMethod: tokenEndpointAuthMethod additionalParameters: additionalParameters resolve: resolve reject: reject]; } else { [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self registerWithConfiguration: configuration redirectUrls: redirectUrls responseTypes: responseTypes grantTypes: grantTypes subjectType: subjectType tokenEndpointAuthMethod: tokenEndpointAuthMethod additionalParameters: additionalParameters resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(register, RCT_REMAP_METHOD(authorize, issuer: (NSString *) issuer redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret scopes: (NSArray *) scopes additionalParameters: (NSDictionary *_Nullable) additionalParameters serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration skipCodeExchange: (BOOL) skipCodeExchange connectionTimeoutSeconds: (double) connectionTimeoutSeconds additionalHeaders: (NSDictionary *_Nullable) additionalHeaders useNonce: (BOOL *) useNonce usePKCE: (BOOL *) usePKCE iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { [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 (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self authorizeWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret scopes: scopes useNonce: useNonce usePKCE: usePKCE additionalParameters: additionalParameters skipCodeExchange: skipCodeExchange iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; } else { [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self authorizeWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret scopes: scopes useNonce: useNonce usePKCE: usePKCE additionalParameters: additionalParameters skipCodeExchange: skipCodeExchange iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(authorize, RCT_REMAP_METHOD(refresh, issuer: (NSString *) issuer redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret refreshToken: (NSString *) refreshToken scopes: (NSArray *) scopes additionalParameters: (NSDictionary *_Nullable) additionalParameters serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration connectionTimeoutSeconds: (double) connectionTimeoutSeconds additionalHeaders: (NSDictionary *_Nullable) additionalHeaders iosCustomBrowser: (NSString *) iosCustomBrowser resolve:(RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { [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 (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self refreshWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret refreshToken: refreshToken scopes: scopes additionalParameters: additionalParameters resolve: resolve reject: reject]; } else { // otherwise hit up the discovery endpoint [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self refreshWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret refreshToken: refreshToken scopes: scopes additionalParameters: additionalParameters resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(refresh, RCT_REMAP_METHOD(logout, issuer: (NSString *) issuer idTokenHint: (NSString *) idTokenHint postLogoutRedirectURL: (NSString *) postLogoutRedirectURL serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration additionalParameters: (NSDictionary *_Nullable) additionalParameters iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve:(RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { if (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self endSessionWithConfiguration: configuration idTokenHint: idTokenHint postLogoutRedirectURL: postLogoutRedirectURL additionalParameters: additionalParameters iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; } else { [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self endSessionWithConfiguration: configuration idTokenHint: idTokenHint postLogoutRedirectURL: postLogoutRedirectURL additionalParameters: additionalParameters iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(logout, /* * Create a OIDServiceConfiguration from passed serviceConfiguration dictionary */ - (OIDServiceConfiguration *) createServiceConfiguration: (NSDictionary *) serviceConfiguration { NSURL *authorizationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"authorizationEndpoint"]]; NSURL *tokenEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"tokenEndpoint"]]; NSURL *registrationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"registrationEndpoint"]]; NSURL *endSessionEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"endSessionEndpoint"]]; OIDServiceConfiguration *configuration = [[OIDServiceConfiguration alloc] initWithAuthorizationEndpoint:authorizationEndpoint tokenEndpoint:tokenEndpoint issuer:nil registrationEndpoint:registrationEndpoint endSessionEndpoint:endSessionEndpoint]; return configuration; } + (nullable NSString *)generateCodeVerifier { return [OIDTokenUtilities randomURLSafeStringWithSize:kCodeVerifierBytes]; } + (nullable NSString *)generateState { return [OIDTokenUtilities randomURLSafeStringWithSize:kStateSizeBytes]; } + (nullable NSString *)codeChallengeS256ForVerifier:(NSString *)codeVerifier { if (!codeVerifier) { return nil; } // generates the code_challenge per spec https://tools.ietf.org/html/rfc7636#section-4.2 // code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) // NB. the ASCII conversion on the code_verifier entropy was done at time of generation. NSData *sha256Verifier = [OIDTokenUtilities sha256:codeVerifier]; return [OIDTokenUtilities encodeBase64urlNoPadding:sha256Verifier]; } /* * Perform dynamic client registration with provided OIDServiceConfiguration */ - (void)registerWithConfiguration: (OIDServiceConfiguration *) configuration redirectUrls: (NSArray *) redirectUrlStrings responseTypes: (NSArray *) responseTypes grantTypes: (NSArray *) grantTypes subjectType: (NSString *) subjectType tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod additionalParameters: (NSDictionary *_Nullable) additionalParameters resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { NSMutableArray<NSURL *> *redirectUrls = [NSMutableArray arrayWithCapacity:[redirectUrlStrings count]]; for (NSString *urlString in redirectUrlStrings) { [redirectUrls addObject:[NSURL URLWithString:urlString]]; } OIDRegistrationRequest *request = [[OIDRegistrationRequest alloc] initWithConfiguration:configuration redirectURIs:redirectUrls responseTypes:responseTypes grantTypes:grantTypes subjectType:subjectType tokenEndpointAuthMethod:tokenEndpointAuthMethod additionalParameters:additionalParameters]; [OIDAuthorizationService performRegistrationRequest:request completion:^(OIDRegistrationResponse *_Nullable response, NSError *_Nullable error) { if (response) { resolve([self formatRegistrationResponse:response]); } else { reject([self getErrorCode: error defaultCode:@"registration_failed"], [self getErrorMessage: error], error); } }]; } /* * Authorize a user in exchange for a token with provided OIDServiceConfiguration */ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret scopes: (NSArray *) scopes useNonce: (BOOL *) useNonce usePKCE: (BOOL *) usePKCE additionalParameters: (NSDictionary *_Nullable) additionalParameters skipCodeExchange: (BOOL) skipCodeExchange iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { NSString *codeVerifier = usePKCE ? [[self class] generateCodeVerifier] : nil; NSString *codeChallenge = usePKCE ? [[self class] codeChallengeS256ForVerifier:codeVerifier] : nil; NSString *nonce = useNonce ? additionalParameters[@"nonce"]? additionalParameters[@"nonce"]: [[self class] generateState] : nil ; // builds authentication request OIDAuthorizationRequest *request = [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration clientId:clientId clientSecret:clientSecret scope:[OIDScopeUtilities scopesWithArray:scopes] redirectURL:[NSURL URLWithString:redirectUrl] responseType:OIDResponseTypeCode state: additionalParameters[@"state"] ? additionalParameters[@"state"] : [[self class] generateState] nonce:nonce codeVerifier:codeVerifier codeChallenge:codeChallenge codeChallengeMethod: usePKCE ? OIDOAuthorizationRequestCodeChallengeMethodS256 : nil additionalParameters:additionalParameters]; // performs authentication request id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate; if (![[appDelegate class] conformsToProtocol:@protocol(RNAppAuthAuthorizationFlowManager)]) { [NSException raise:@"RNAppAuth Missing protocol conformance" format:@"%@ does not conform to RNAppAuthAuthorizationFlowManager", appDelegate]; } appDelegate.authorizationFlowManagerDelegate = self; __weak typeof(self) weakSelf = self; rnAppAuthTaskId = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{ [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; }]; UIViewController *presentingViewController = appDelegate.window.rootViewController.view.window ? appDelegate.window.rootViewController : appDelegate.window.rootViewController.presentedViewController; #if TARGET_OS_MACCATALYST id<OIDExternalUserAgent> externalUserAgent = nil; #elif TARGET_OS_IOS id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : nil; #endif OIDAuthorizationCallback callback = ^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) { typeof(self) strongSelf = weakSelf; strongSelf->_currentSession = nil; [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; if (authorizationResponse) { resolve([self formatAuthorizationResponse:authorizationResponse withCodeVerifier:codeVerifier]); } 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 = ^( OIDAuthState *_Nullable authState, NSError *_Nullable error ) { typeof(self) strongSelf = weakSelf; strongSelf->_currentSession = nil; [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; if (authState) { resolve([self formatResponse:authState.lastTokenResponse withAuthResponse:authState.lastAuthorizationResponse]); } else { reject([self getErrorCode: error defaultCode:@"authentication_failed"], [self getErrorMessage: error], error); } }; if(externalUserAgent != nil) { _currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request externalUserAgent:externalUserAgent callback:callback]; } else { if (@available(iOS 13, *)) { _currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request presentingViewController:presentingViewController prefersEphemeralSession:prefersEphemeralSession callback:callback]; } else { _currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request presentingViewController:presentingViewController callback:callback]; } } } } /* * Refresh a token with provided OIDServiceConfiguration */ - (void)refreshWithConfiguration: (OIDServiceConfiguration *)configuration redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret refreshToken: (NSString *) refreshToken scopes: (NSArray *) scopes additionalParameters: (NSDictionary *_Nullable) additionalParameters resolve:(RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { OIDTokenRequest *tokenRefreshRequest = [[OIDTokenRequest alloc] initWithConfiguration:configuration grantType:@"refresh_token" authorizationCode:nil redirectURL:[NSURL URLWithString:redirectUrl] clientID:clientId clientSecret:clientSecret scopes:scopes refreshToken:refreshToken codeVerifier:nil additionalParameters:additionalParameters]; [OIDAuthorizationService performTokenRequest:tokenRefreshRequest callback:^(OIDTokenResponse *_Nullable response, NSError *_Nullable error) { if (response) { resolve([self formatResponse:response]); } else { reject([self getErrorCode: error defaultCode:@"token_refresh_failed"], [self getErrorMessage: error], error); } }]; } - (void)endSessionWithConfiguration: (OIDServiceConfiguration *) configuration idTokenHint: (NSString *) idTokenHint postLogoutRedirectURL: (NSString *) postLogoutRedirectURL additionalParameters: (NSDictionary *_Nullable) additionalParameters iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { OIDEndSessionRequest *endSessionRequest = [[OIDEndSessionRequest alloc] initWithConfiguration: configuration idTokenHint: idTokenHint postLogoutRedirectURL: [NSURL URLWithString:postLogoutRedirectURL] additionalParameters: additionalParameters]; id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate; if (![[appDelegate class] conformsToProtocol:@protocol(RNAppAuthAuthorizationFlowManager)]) { [NSException raise:@"RNAppAuth Missing protocol conformance" format:@"%@ does not conform to RNAppAuthAuthorizationFlowManager", appDelegate]; } appDelegate.authorizationFlowManagerDelegate = self; __weak typeof(self) weakSelf = self; rnAppAuthTaskId = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{ [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; }]; UIViewController *presentingViewController = appDelegate.window.rootViewController.view.window ? appDelegate.window.rootViewController : appDelegate.window.rootViewController.presentedViewController; #if TARGET_OS_MACCATALYST id<OIDExternalUserAgent> externalUserAgent = nil; #elif TARGET_OS_IOS id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : [self getExternalUserAgentWithPresentingViewController:presentingViewController prefersEphemeralSession:prefersEphemeralSession]; #endif _currentSession = [OIDAuthorizationService presentEndSessionRequest: endSessionRequest externalUserAgent: externalUserAgent callback: ^(OIDEndSessionResponse *_Nullable response, NSError *_Nullable error) { typeof(self) strongSelf = weakSelf; strongSelf->_currentSession = nil; [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; if (response) { resolve([self formatEndSessionResponse:response]); } else { reject([self getErrorCode: error defaultCode:@"end_session_failed"], [self getErrorMessage: error], error); } }]; } - (void)configureUrlSession: (NSDictionary*) headers sessionTimeout: (double) sessionTimeout{ NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; if (headers != nil) { configuration.HTTPAdditionalHeaders = headers; } configuration.timeoutIntervalForRequest = sessionTimeout; NSURLSession* session = [NSURLSession sessionWithConfiguration:configuration]; [OIDURLSessionProvider setSession:session]; } /* * Take raw OIDAuthorizationResponse and turn it to response format to pass to JavaScript caller */ - (NSDictionary *)formatAuthorizationResponse: (OIDAuthorizationResponse *) response withCodeVerifier: (NSString *) codeVerifier { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; if (codeVerifier == nil) { return @{@"authorizationCode": response.authorizationCode ? response.authorizationCode : @"", @"state": response.state ? response.state : @"", @"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"tokenType": response.tokenType ? response.tokenType : @"", @"idToken": response.idToken ? response.idToken : @"", @"scopes": response.scope ? [response.scope componentsSeparatedByString:@" "] : [NSArray new], @"additionalParameters": response.additionalParameters, }; } else { return @{@"authorizationCode": response.authorizationCode ? response.authorizationCode : @"", @"state": response.state ? response.state : @"", @"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"tokenType": response.tokenType ? response.tokenType : @"", @"idToken": response.idToken ? response.idToken : @"", @"scopes": response.scope ? [response.scope componentsSeparatedByString:@" "] : [NSArray new], @"additionalParameters": response.additionalParameters, @"codeVerifier": codeVerifier }; } } /* * Take raw OIDTokenResponse and turn it to a token response format to pass to JavaScript caller */ - (NSDictionary*)formatResponse: (OIDTokenResponse*) response { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; return @{@"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"additionalParameters": response.additionalParameters, @"idToken": response.idToken ? response.idToken : @"", @"refreshToken": response.refreshToken ? response.refreshToken : @"", @"tokenType": response.tokenType ? response.tokenType : @"", }; } /* * Take raw OIDTokenResponse and additional paramaeters from an OIDAuthorizationResponse * and turn them into an extended token response format to pass to JavaScript caller */ - (NSDictionary*)formatResponse: (OIDTokenResponse*) response withAuthResponse:(OIDAuthorizationResponse*) authResponse { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; return @{@"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"authorizeAdditionalParameters": authResponse.additionalParameters, @"tokenAdditionalParameters": response.additionalParameters, @"idToken": response.idToken ? response.idToken : @"", @"refreshToken": response.refreshToken ? response.refreshToken : @"", @"tokenType": response.tokenType ? response.tokenType : @"", @"scopes": authResponse.scope ? [authResponse.scope componentsSeparatedByString:@" "] : [NSArray new], }; } - (NSDictionary*)formatRegistrationResponse: (OIDRegistrationResponse*) response { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; return @{@"clientId": response.clientID, @"additionalParameters": response.additionalParameters, @"clientIdIssuedAt": response.clientIDIssuedAt ? [dateFormat stringFromDate:response.clientIDIssuedAt] : @"", @"clientSecret": response.clientSecret ? response.clientSecret : @"", @"clientSecretExpiresAt": response.clientSecretExpiresAt ? [dateFormat stringFromDate:response.clientSecretExpiresAt] : @"", @"registrationAccessToken": response.registrationAccessToken ? response.registrationAccessToken : @"", @"registrationClientUri": response.registrationClientURI ? response.registrationClientURI : @"", @"tokenEndpointAuthMethod": response.tokenEndpointAuthenticationMethod ? response.tokenEndpointAuthenticationMethod : @"", }; } - (NSDictionary*)formatEndSessionResponse: (OIDEndSessionResponse*)response { return @{@"state": response.state ? response.state : @"", @"idTokenHint": response.request.idTokenHint, @"postLogoutRedirectUri": response.request.postLogoutRedirectURL.absoluteString }; } - (NSString*)getErrorCode: (NSError*) error defaultCode: (NSString *) defaultCode { if ([[error domain] isEqualToString:OIDOAuthAuthorizationErrorDomain]) { switch ([error code]) { case OIDErrorCodeOAuthAuthorizationInvalidRequest: return @"invalid_request"; case OIDErrorCodeOAuthAuthorizationUnauthorizedClient: return @"unauthorized_client"; case OIDErrorCodeOAuthAuthorizationAccessDenied: return @"access_denied"; case OIDErrorCodeOAuthAuthorizationUnsupportedResponseType: return @"unsupported_response_type"; case OIDErrorCodeOAuthAuthorizationAuthorizationInvalidScope: return @"invalid_scope"; case OIDErrorCodeOAuthAuthorizationServerError: return @"server_error"; case OIDErrorCodeOAuthAuthorizationTemporarilyUnavailable: return @"temporarily_unavailable"; } } else if ([[error domain] isEqualToString:OIDOAuthTokenErrorDomain]) { switch ([error code]) { case OIDErrorCodeOAuthTokenInvalidRequest: return @"invalid_request"; case OIDErrorCodeOAuthTokenInvalidClient: return @"invalid_client"; case OIDErrorCodeOAuthTokenInvalidGrant: return @"invalid_grant"; case OIDErrorCodeOAuthTokenUnauthorizedClient: return @"unauthorized_client"; case OIDErrorCodeOAuthTokenUnsupportedGrantType: return @"unsupported_grant_type"; case OIDErrorCodeOAuthTokenInvalidScope: return @"invalid_scope"; } } else if ([[error domain] isEqualToString:OIDOAuthRegistrationErrorDomain]) { switch ([error code]) { case OIDErrorCodeOAuthRegistrationInvalidRequest: return @"invalid_request"; case OIDErrorCodeOAuthRegistrationInvalidRedirectURI: return @"invalid_redirect_uri"; case OIDErrorCodeOAuthRegistrationInvalidClientMetadata: return @"invalid_client_metadata"; } } return defaultCode; } #if !TARGET_OS_MACCATALYST - (id<OIDExternalUserAgent>)getCustomBrowser: (NSString *) browserType { typedef id<OIDExternalUserAgent> (^BrowserBlock)(void); NSDictionary *browsers = @{ @"safari": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserSafari]; }, @"chrome": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserChrome]; }, @"opera": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserOpera]; }, @"firefox": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserFirefox]; } }; BrowserBlock browser = browsers[browserType]; return browser(); } #endif - (NSString*)getErrorMessage: (NSError*) error { NSDictionary * userInfo = [error userInfo]; if (userInfo && userInfo[OIDOAuthErrorResponseErrorKey] && userInfo[OIDOAuthErrorResponseErrorKey][OIDOAuthErrorFieldErrorDescription]) { return userInfo[OIDOAuthErrorResponseErrorKey][OIDOAuthErrorFieldErrorDescription]; } else { return [error localizedDescription]; } } - (id<OIDExternalUserAgent>)getExternalUserAgentWithPresentingViewController: (UIViewController *)presentingViewController prefersEphemeralSession: (BOOL *) prefersEphemeralSession { id<OIDExternalUserAgent> externalUserAgent; #if TARGET_OS_MACCATALYST externalUserAgent = [[OIDExternalUserAgentCatalyst alloc] initWithPresentingViewController:presentingViewController]; #elif TARGET_OS_IOS 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 return externalUserAgent; } @end
変更されたテキスト
ファイルを開く
#import "RNAppAuth.h" #if __has_include(<AppAuth/AppAuth.h>) #import <AppAuth/AppAuth.h> #else #import "AppAuth.h" #endif #import <React/RCTLog.h> #import <React/RCTConvert.h> #import "RNAppAuthAuthorizationFlowManager.h" @interface RNAppAuth()<RNAppAuthAuthorizationFlowManagerDelegate> { id<OIDExternalUserAgentSession> _currentSession; } @property (nonatomic, copy) RCTPromiseRejectBlock authorizeRejectBlock; @end @implementation RNAppAuth -(BOOL)resumeExternalUserAgentFlowWithURL:(NSURL *)url { return [_currentSession resumeExternalUserAgentFlowWithURL:url]; } - (dispatch_queue_t)methodQueue { return dispatch_get_main_queue(); } UIBackgroundTaskIdentifier rnAppAuthTaskId; /*! @brief Number of random bytes generated for the @ state. */ static NSUInteger const kStateSizeBytes = 32; /*! @brief Number of random bytes generated for the @ codeVerifier. */ static NSUInteger const kCodeVerifierBytes = 32; 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, issuer: (NSString *) issuer redirectUrls: (NSArray *) redirectUrls responseTypes: (NSArray *) responseTypes grantTypes: (NSArray *) grantTypes subjectType: (NSString *) subjectType tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod additionalParameters: (NSDictionary *_Nullable) additionalParameters serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration connectionTimeoutSeconds: (double) connectionTimeoutSeconds additionalHeaders: (NSDictionary *_Nullable) additionalHeaders resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { [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 (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self registerWithConfiguration: configuration redirectUrls: redirectUrls responseTypes: responseTypes grantTypes: grantTypes subjectType: subjectType tokenEndpointAuthMethod: tokenEndpointAuthMethod additionalParameters: additionalParameters resolve: resolve reject: reject]; } else { [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self registerWithConfiguration: configuration redirectUrls: redirectUrls responseTypes: responseTypes grantTypes: grantTypes subjectType: subjectType tokenEndpointAuthMethod: tokenEndpointAuthMethod additionalParameters: additionalParameters resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(register, RCT_REMAP_METHOD(authorize, issuer: (NSString *) issuer redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret scopes: (NSArray *) scopes additionalParameters: (NSDictionary *_Nullable) additionalParameters serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration skipCodeExchange: (BOOL) skipCodeExchange connectionTimeoutSeconds: (double) connectionTimeoutSeconds additionalHeaders: (NSDictionary *_Nullable) additionalHeaders useNonce: (BOOL *) useNonce usePKCE: (BOOL *) usePKCE iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { self.authorizeRejectBlock = reject; [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 (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self authorizeWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret scopes: scopes useNonce: useNonce usePKCE: usePKCE additionalParameters: additionalParameters skipCodeExchange: skipCodeExchange iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; } else { [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks. return; } [self authorizeWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret scopes: scopes useNonce: useNonce usePKCE: usePKCE additionalParameters: additionalParameters skipCodeExchange: skipCodeExchange iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(authorize, RCT_REMAP_METHOD(refresh, issuer: (NSString *) issuer redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret refreshToken: (NSString *) refreshToken scopes: (NSArray *) scopes additionalParameters: (NSDictionary *_Nullable) additionalParameters serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration connectionTimeoutSeconds: (double) connectionTimeoutSeconds additionalHeaders: (NSDictionary *_Nullable) additionalHeaders iosCustomBrowser: (NSString *) iosCustomBrowser resolve:(RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { [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 (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self refreshWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret refreshToken: refreshToken scopes: scopes additionalParameters: additionalParameters resolve: resolve reject: reject]; } else { // otherwise hit up the discovery endpoint [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self refreshWithConfiguration: configuration redirectUrl: redirectUrl clientId: clientId clientSecret: clientSecret refreshToken: refreshToken scopes: scopes additionalParameters: additionalParameters resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(refresh, RCT_REMAP_METHOD(logout, issuer: (NSString *) issuer idTokenHint: (NSString *) idTokenHint postLogoutRedirectURL: (NSString *) postLogoutRedirectURL serviceConfiguration: (NSDictionary *_Nullable) serviceConfiguration additionalParameters: (NSDictionary *_Nullable) additionalParameters iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve:(RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject) { if (serviceConfiguration) { OIDServiceConfiguration *configuration = [self createServiceConfiguration:serviceConfiguration]; [self endSessionWithConfiguration: configuration idTokenHint: idTokenHint postLogoutRedirectURL: postLogoutRedirectURL additionalParameters: additionalParameters iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; } else { [OIDAuthorizationService discoverServiceConfigurationForIssuer:[NSURL URLWithString:issuer] completion:^(OIDServiceConfiguration *_Nullable configuration, NSError *_Nullable error) { if (!configuration) { reject(@"service_configuration_fetch_error", [error localizedDescription], error); return; } [self endSessionWithConfiguration: configuration idTokenHint: idTokenHint postLogoutRedirectURL: postLogoutRedirectURL additionalParameters: additionalParameters iosCustomBrowser: iosCustomBrowser prefersEphemeralSession: prefersEphemeralSession resolve: resolve reject: reject]; }]; } } // end RCT_REMAP_METHOD(logout, /* * Create a OIDServiceConfiguration from passed serviceConfiguration dictionary */ - (OIDServiceConfiguration *) createServiceConfiguration: (NSDictionary *) serviceConfiguration { NSURL *authorizationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"authorizationEndpoint"]]; NSURL *tokenEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"tokenEndpoint"]]; NSURL *registrationEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"registrationEndpoint"]]; NSURL *endSessionEndpoint = [NSURL URLWithString: [serviceConfiguration objectForKey:@"endSessionEndpoint"]]; OIDServiceConfiguration *configuration = [[OIDServiceConfiguration alloc] initWithAuthorizationEndpoint:authorizationEndpoint tokenEndpoint:tokenEndpoint issuer:nil registrationEndpoint:registrationEndpoint endSessionEndpoint:endSessionEndpoint]; return configuration; } + (nullable NSString *)generateCodeVerifier { return [OIDTokenUtilities randomURLSafeStringWithSize:kCodeVerifierBytes]; } + (nullable NSString *)generateState { return [OIDTokenUtilities randomURLSafeStringWithSize:kStateSizeBytes]; } + (nullable NSString *)codeChallengeS256ForVerifier:(NSString *)codeVerifier { if (!codeVerifier) { return nil; } // generates the code_challenge per spec https://tools.ietf.org/html/rfc7636#section-4.2 // code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) // NB. the ASCII conversion on the code_verifier entropy was done at time of generation. NSData *sha256Verifier = [OIDTokenUtilities sha256:codeVerifier]; return [OIDTokenUtilities encodeBase64urlNoPadding:sha256Verifier]; } /* * Perform dynamic client registration with provided OIDServiceConfiguration */ - (void)registerWithConfiguration: (OIDServiceConfiguration *) configuration redirectUrls: (NSArray *) redirectUrlStrings responseTypes: (NSArray *) responseTypes grantTypes: (NSArray *) grantTypes subjectType: (NSString *) subjectType tokenEndpointAuthMethod: (NSString *) tokenEndpointAuthMethod additionalParameters: (NSDictionary *_Nullable) additionalParameters resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { NSMutableArray<NSURL *> *redirectUrls = [NSMutableArray arrayWithCapacity:[redirectUrlStrings count]]; for (NSString *urlString in redirectUrlStrings) { [redirectUrls addObject:[NSURL URLWithString:urlString]]; } OIDRegistrationRequest *request = [[OIDRegistrationRequest alloc] initWithConfiguration:configuration redirectURIs:redirectUrls responseTypes:responseTypes grantTypes:grantTypes subjectType:subjectType tokenEndpointAuthMethod:tokenEndpointAuthMethod additionalParameters:additionalParameters]; [OIDAuthorizationService performRegistrationRequest:request completion:^(OIDRegistrationResponse *_Nullable response, NSError *_Nullable error) { if (response) { resolve([self formatRegistrationResponse:response]); } else { reject([self getErrorCode: error defaultCode:@"registration_failed"], [self getErrorMessage: error], error); } }]; } /* * Authorize a user in exchange for a token with provided OIDServiceConfiguration */ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret scopes: (NSArray *) scopes useNonce: (BOOL *) useNonce usePKCE: (BOOL *) usePKCE additionalParameters: (NSDictionary *_Nullable) additionalParameters skipCodeExchange: (BOOL) skipCodeExchange iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { NSString *codeVerifier = usePKCE ? [[self class] generateCodeVerifier] : nil; NSString *codeChallenge = usePKCE ? [[self class] codeChallengeS256ForVerifier:codeVerifier] : nil; NSString *nonce = useNonce ? additionalParameters[@"nonce"]? additionalParameters[@"nonce"]: [[self class] generateState] : nil ; // builds authentication request OIDAuthorizationRequest *request = [[OIDAuthorizationRequest alloc] initWithConfiguration:configuration clientId:clientId clientSecret:clientSecret scope:[OIDScopeUtilities scopesWithArray:scopes] redirectURL:[NSURL URLWithString:redirectUrl] responseType:OIDResponseTypeCode state: additionalParameters[@"state"] ? additionalParameters[@"state"] : [[self class] generateState] nonce:nonce codeVerifier:codeVerifier codeChallenge:codeChallenge codeChallengeMethod: usePKCE ? OIDOAuthorizationRequestCodeChallengeMethodS256 : nil additionalParameters:additionalParameters]; // performs authentication request id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate; if (![[appDelegate class] conformsToProtocol:@protocol(RNAppAuthAuthorizationFlowManager)]) { [NSException raise:@"RNAppAuth Missing protocol conformance" format:@"%@ does not conform to RNAppAuthAuthorizationFlowManager", appDelegate]; } appDelegate.authorizationFlowManagerDelegate = self; __weak typeof(self) weakSelf = self; rnAppAuthTaskId = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{ [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; }]; UIViewController *presentingViewController = appDelegate.window.rootViewController.view.window ? appDelegate.window.rootViewController : appDelegate.window.rootViewController.presentedViewController; #if TARGET_OS_MACCATALYST id<OIDExternalUserAgent> externalUserAgent = nil; #elif TARGET_OS_IOS id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : nil; #endif OIDAuthorizationCallback callback = ^(OIDAuthorizationResponse *_Nullable authorizationResponse, NSError *_Nullable error) { typeof(self) strongSelf = weakSelf; strongSelf->_currentSession = nil; [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; if (authorizationResponse) { resolve([self formatAuthorizationResponse:authorizationResponse withCodeVerifier:codeVerifier]); self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks. } else { reject([self getErrorCode: error defaultCode:@"authentication_failed"], [self getErrorMessage: error], error); self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks. } }; 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 = ^( OIDAuthState *_Nullable authState, NSError *_Nullable error ) { typeof(self) strongSelf = weakSelf; strongSelf->_currentSession = nil; [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; if (authState) { resolve([self formatResponse:authState.lastTokenResponse withAuthResponse:authState.lastAuthorizationResponse]); self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks. } else { reject([self getErrorCode: error defaultCode:@"authentication_failed"], [self getErrorMessage: error], error); self.authorizeRejectBlock = nil; // Clear the block to avoid memory leaks. } }; if(externalUserAgent != nil) { _currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request externalUserAgent:externalUserAgent callback:callback]; } else { if (@available(iOS 13, *)) { _currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request presentingViewController:presentingViewController prefersEphemeralSession:prefersEphemeralSession callback:callback]; } else { _currentSession = [OIDAuthState authStateByPresentingAuthorizationRequest:request presentingViewController:presentingViewController callback:callback]; } } } } /* * Refresh a token with provided OIDServiceConfiguration */ - (void)refreshWithConfiguration: (OIDServiceConfiguration *)configuration redirectUrl: (NSString *) redirectUrl clientId: (NSString *) clientId clientSecret: (NSString *) clientSecret refreshToken: (NSString *) refreshToken scopes: (NSArray *) scopes additionalParameters: (NSDictionary *_Nullable) additionalParameters resolve:(RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { OIDTokenRequest *tokenRefreshRequest = [[OIDTokenRequest alloc] initWithConfiguration:configuration grantType:@"refresh_token" authorizationCode:nil redirectURL:[NSURL URLWithString:redirectUrl] clientID:clientId clientSecret:clientSecret scopes:scopes refreshToken:refreshToken codeVerifier:nil additionalParameters:additionalParameters]; [OIDAuthorizationService performTokenRequest:tokenRefreshRequest callback:^(OIDTokenResponse *_Nullable response, NSError *_Nullable error) { if (response) { resolve([self formatResponse:response]); } else { reject([self getErrorCode: error defaultCode:@"token_refresh_failed"], [self getErrorMessage: error], error); } }]; } - (void)endSessionWithConfiguration: (OIDServiceConfiguration *) configuration idTokenHint: (NSString *) idTokenHint postLogoutRedirectURL: (NSString *) postLogoutRedirectURL additionalParameters: (NSDictionary *_Nullable) additionalParameters iosCustomBrowser: (NSString *) iosCustomBrowser prefersEphemeralSession: (BOOL *) prefersEphemeralSession resolve: (RCTPromiseResolveBlock) resolve reject: (RCTPromiseRejectBlock) reject { OIDEndSessionRequest *endSessionRequest = [[OIDEndSessionRequest alloc] initWithConfiguration: configuration idTokenHint: idTokenHint postLogoutRedirectURL: [NSURL URLWithString:postLogoutRedirectURL] additionalParameters: additionalParameters]; id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager> appDelegate = (id<UIApplicationDelegate, RNAppAuthAuthorizationFlowManager>)[UIApplication sharedApplication].delegate; if (![[appDelegate class] conformsToProtocol:@protocol(RNAppAuthAuthorizationFlowManager)]) { [NSException raise:@"RNAppAuth Missing protocol conformance" format:@"%@ does not conform to RNAppAuthAuthorizationFlowManager", appDelegate]; } appDelegate.authorizationFlowManagerDelegate = self; __weak typeof(self) weakSelf = self; rnAppAuthTaskId = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{ [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; }]; UIViewController *presentingViewController = appDelegate.window.rootViewController.view.window ? appDelegate.window.rootViewController : appDelegate.window.rootViewController.presentedViewController; #if TARGET_OS_MACCATALYST id<OIDExternalUserAgent> externalUserAgent = nil; #elif TARGET_OS_IOS id<OIDExternalUserAgent> externalUserAgent = iosCustomBrowser != nil ? [self getCustomBrowser: iosCustomBrowser] : [self getExternalUserAgentWithPresentingViewController:presentingViewController prefersEphemeralSession:prefersEphemeralSession]; #endif _currentSession = [OIDAuthorizationService presentEndSessionRequest: endSessionRequest externalUserAgent: externalUserAgent callback: ^(OIDEndSessionResponse *_Nullable response, NSError *_Nullable error) { typeof(self) strongSelf = weakSelf; strongSelf->_currentSession = nil; [UIApplication.sharedApplication endBackgroundTask:rnAppAuthTaskId]; rnAppAuthTaskId = UIBackgroundTaskInvalid; if (response) { resolve([self formatEndSessionResponse:response]); } else { reject([self getErrorCode: error defaultCode:@"end_session_failed"], [self getErrorMessage: error], error); } }]; } - (void)configureUrlSession: (NSDictionary*) headers sessionTimeout: (double) sessionTimeout{ NSURLSessionConfiguration* configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; if (headers != nil) { configuration.HTTPAdditionalHeaders = headers; } configuration.timeoutIntervalForRequest = sessionTimeout; NSURLSession* session = [NSURLSession sessionWithConfiguration:configuration]; [OIDURLSessionProvider setSession:session]; } /* * Take raw OIDAuthorizationResponse and turn it to response format to pass to JavaScript caller */ - (NSDictionary *)formatAuthorizationResponse: (OIDAuthorizationResponse *) response withCodeVerifier: (NSString *) codeVerifier { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; if (codeVerifier == nil) { return @{@"authorizationCode": response.authorizationCode ? response.authorizationCode : @"", @"state": response.state ? response.state : @"", @"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"tokenType": response.tokenType ? response.tokenType : @"", @"idToken": response.idToken ? response.idToken : @"", @"scopes": response.scope ? [response.scope componentsSeparatedByString:@" "] : [NSArray new], @"additionalParameters": response.additionalParameters, }; } else { return @{@"authorizationCode": response.authorizationCode ? response.authorizationCode : @"", @"state": response.state ? response.state : @"", @"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"tokenType": response.tokenType ? response.tokenType : @"", @"idToken": response.idToken ? response.idToken : @"", @"scopes": response.scope ? [response.scope componentsSeparatedByString:@" "] : [NSArray new], @"additionalParameters": response.additionalParameters, @"codeVerifier": codeVerifier }; } } /* * Take raw OIDTokenResponse and turn it to a token response format to pass to JavaScript caller */ - (NSDictionary*)formatResponse: (OIDTokenResponse*) response { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; return @{@"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"additionalParameters": response.additionalParameters, @"idToken": response.idToken ? response.idToken : @"", @"refreshToken": response.refreshToken ? response.refreshToken : @"", @"tokenType": response.tokenType ? response.tokenType : @"", }; } /* * Take raw OIDTokenResponse and additional paramaeters from an OIDAuthorizationResponse * and turn them into an extended token response format to pass to JavaScript caller */ - (NSDictionary*)formatResponse: (OIDTokenResponse*) response withAuthResponse:(OIDAuthorizationResponse*) authResponse { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; return @{@"accessToken": response.accessToken ? response.accessToken : @"", @"accessTokenExpirationDate": response.accessTokenExpirationDate ? [dateFormat stringFromDate:response.accessTokenExpirationDate] : @"", @"authorizeAdditionalParameters": authResponse.additionalParameters, @"tokenAdditionalParameters": response.additionalParameters, @"idToken": response.idToken ? response.idToken : @"", @"refreshToken": response.refreshToken ? response.refreshToken : @"", @"tokenType": response.tokenType ? response.tokenType : @"", @"scopes": authResponse.scope ? [authResponse.scope componentsSeparatedByString:@" "] : [NSArray new], }; } - (NSDictionary*)formatRegistrationResponse: (OIDRegistrationResponse*) response { NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; dateFormat.timeZone = [NSTimeZone timeZoneWithAbbreviation: @"UTC"]; [dateFormat setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]]; [dateFormat setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"]; return @{@"clientId": response.clientID, @"additionalParameters": response.additionalParameters, @"clientIdIssuedAt": response.clientIDIssuedAt ? [dateFormat stringFromDate:response.clientIDIssuedAt] : @"", @"clientSecret": response.clientSecret ? response.clientSecret : @"", @"clientSecretExpiresAt": response.clientSecretExpiresAt ? [dateFormat stringFromDate:response.clientSecretExpiresAt] : @"", @"registrationAccessToken": response.registrationAccessToken ? response.registrationAccessToken : @"", @"registrationClientUri": response.registrationClientURI ? response.registrationClientURI : @"", @"tokenEndpointAuthMethod": response.tokenEndpointAuthenticationMethod ? response.tokenEndpointAuthenticationMethod : @"", }; } - (NSDictionary*)formatEndSessionResponse: (OIDEndSessionResponse*)response { return @{@"state": response.state ? response.state : @"", @"idTokenHint": response.request.idTokenHint, @"postLogoutRedirectUri": response.request.postLogoutRedirectURL.absoluteString }; } - (NSString*)getErrorCode: (NSError*) error defaultCode: (NSString *) defaultCode { if ([[error domain] isEqualToString:OIDOAuthAuthorizationErrorDomain]) { switch ([error code]) { case OIDErrorCodeOAuthAuthorizationInvalidRequest: return @"invalid_request"; case OIDErrorCodeOAuthAuthorizationUnauthorizedClient: return @"unauthorized_client"; case OIDErrorCodeOAuthAuthorizationAccessDenied: return @"access_denied"; case OIDErrorCodeOAuthAuthorizationUnsupportedResponseType: return @"unsupported_response_type"; case OIDErrorCodeOAuthAuthorizationAuthorizationInvalidScope: return @"invalid_scope"; case OIDErrorCodeOAuthAuthorizationServerError: return @"server_error"; case OIDErrorCodeOAuthAuthorizationTemporarilyUnavailable: return @"temporarily_unavailable"; } } else if ([[error domain] isEqualToString:OIDOAuthTokenErrorDomain]) { switch ([error code]) { case OIDErrorCodeOAuthTokenInvalidRequest: return @"invalid_request"; case OIDErrorCodeOAuthTokenInvalidClient: return @"invalid_client"; case OIDErrorCodeOAuthTokenInvalidGrant: return @"invalid_grant"; case OIDErrorCodeOAuthTokenUnauthorizedClient: return @"unauthorized_client"; case OIDErrorCodeOAuthTokenUnsupportedGrantType: return @"unsupported_grant_type"; case OIDErrorCodeOAuthTokenInvalidScope: return @"invalid_scope"; } } else if ([[error domain] isEqualToString:OIDOAuthRegistrationErrorDomain]) { switch ([error code]) { case OIDErrorCodeOAuthRegistrationInvalidRequest: return @"invalid_request"; case OIDErrorCodeOAuthRegistrationInvalidRedirectURI: return @"invalid_redirect_uri"; case OIDErrorCodeOAuthRegistrationInvalidClientMetadata: return @"invalid_client_metadata"; } } return defaultCode; } #if !TARGET_OS_MACCATALYST - (id<OIDExternalUserAgent>)getCustomBrowser: (NSString *) browserType { typedef id<OIDExternalUserAgent> (^BrowserBlock)(void); NSDictionary *browsers = @{ @"safari": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserSafari]; }, @"chrome": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserChrome]; }, @"opera": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserOpera]; }, @"firefox": ^{ return [OIDExternalUserAgentIOSCustomBrowser CustomBrowserFirefox]; } }; BrowserBlock browser = browsers[browserType]; return browser(); } #endif - (NSString*)getErrorMessage: (NSError*) error { NSDictionary * userInfo = [error userInfo]; if (userInfo && userInfo[OIDOAuthErrorResponseErrorKey] && userInfo[OIDOAuthErrorResponseErrorKey][OIDOAuthErrorFieldErrorDescription]) { return userInfo[OIDOAuthErrorResponseErrorKey][OIDOAuthErrorFieldErrorDescription]; } else { return [error localizedDescription]; } } - (id<OIDExternalUserAgent>)getExternalUserAgentWithPresentingViewController: (UIViewController *)presentingViewController prefersEphemeralSession: (BOOL *) prefersEphemeralSession { id<OIDExternalUserAgent> externalUserAgent; #if TARGET_OS_MACCATALYST externalUserAgent = [[OIDExternalUserAgentCatalyst alloc] initWithPresentingViewController:presentingViewController]; #elif TARGET_OS_IOS 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 return externalUserAgent; } @end
違いを見つける