Skip to content

Commit 10493ca

Browse files
author
Axel Eirola
committed
Expose OAuth error codes
1 parent 0918935 commit 10493ca

File tree

4 files changed

+100
-19
lines changed

4 files changed

+100
-19
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ try {
395395
396396
## Error messages
397397
398+
Values are in the `code` field of the rejected Error object.
399+
400+
- OAuth Authorization [error codes](https://tools.ietf.org/html/rfc6749#section-4.1.2.1)
401+
- OAuth Access Token [error codes](https://tools.ietf.org/html/rfc6749#section-5.2)
402+
- OpendID Connect Registration [error codes](https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError)
398403
- `service_configuration_fetch_error` - could not fetch the service configuration
399404
- `authentication_failed` - user authentication failed
400405
- `token_refresh_failed` - could not exchange the refresh token for a new JWT

android/src/main/java/com/rnappauth/RNAppAuthModule.java

+7-16
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ public void onFetchConfigurationCompleted(
183183
@Nullable AuthorizationServiceConfiguration fetchedConfiguration,
184184
@Nullable AuthorizationException ex) {
185185
if (ex != null) {
186-
promise.reject("service_configuration_fetch_error", getErrorMessage(ex));
186+
promise.reject("service_configuration_fetch_error", ex.getLocalizedMessage(), ex);
187187
return;
188188
}
189189

@@ -260,7 +260,7 @@ public void onFetchConfigurationCompleted(
260260
@Nullable AuthorizationServiceConfiguration fetchedConfiguration,
261261
@Nullable AuthorizationException ex) {
262262
if (ex != null) {
263-
promise.reject("service_configuration_fetch_error", getErrorMessage(ex));
263+
promise.reject("service_configuration_fetch_error", ex.getLocalizedMessage(), ex);
264264
return;
265265
}
266266

@@ -344,7 +344,7 @@ public void onFetchConfigurationCompleted(
344344
@Nullable AuthorizationServiceConfiguration fetchedConfiguration,
345345
@Nullable AuthorizationException ex) {
346346
if (ex != null) {
347-
promise.reject("service_configuration_fetch_error", getErrorMessage(ex));
347+
promise.reject("service_configuration_fetch_error", ex.getLocalizedMessage(), ex);
348348
return;
349349
}
350350

@@ -386,7 +386,7 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode,
386386
AuthorizationException exception = AuthorizationException.fromIntent(data);
387387
if (exception != null) {
388388
if (promise != null) {
389-
promise.reject("authentication_error", getErrorMessage(exception));
389+
promise.reject(exception.error != null ? exception.error: "authentication_error", exception.getLocalizedMessage(), exception);
390390
}
391391
return;
392392
}
@@ -412,7 +412,7 @@ public void onTokenRequestCompleted(
412412
}
413413
} else {
414414
if (promise != null) {
415-
promise.reject("token_exchange_failed", getErrorMessage(ex));
415+
promise.reject(ex.error != null ? ex.error: "token_exchange_failed", ex.getLocalizedMessage(), ex);
416416
}
417417
}
418418
}
@@ -479,7 +479,7 @@ public void onRegistrationRequestCompleted(@Nullable RegistrationResponse respon
479479
WritableMap map = RegistrationResponseFactory.registrationResponseToMap(response);
480480
promise.resolve(map);
481481
} else {
482-
promise.reject("registration_failed", getErrorMessage(ex));
482+
promise.reject(ex.error != null ? ex.error: "registration_failed", ex.getLocalizedMessage(), ex);
483483
}
484484
}
485485
};
@@ -610,7 +610,7 @@ public void onTokenRequestCompleted(@Nullable TokenResponse response, @Nullable
610610
WritableMap map = TokenResponseFactory.tokenResponseToMap(response);
611611
promise.resolve(map);
612612
} else {
613-
promise.reject("token_refresh_failed", getErrorMessage(ex));
613+
promise.reject(ex.error != null ? ex.error: "token_refresh_failed", ex.getLocalizedMessage(), ex);
614614
}
615615
}
616616
};
@@ -649,15 +649,6 @@ private ClientAuthentication getClientAuthentication(String clientSecret, String
649649
return new ClientSecretBasic(clientSecret);
650650
}
651651

652-
/*
653-
* Return error information if it is available
654-
*/
655-
private String getErrorMessage(AuthorizationException ex){
656-
if(ex.errorDescription == null && ex.error != null)
657-
return ex.error;
658-
return ex.errorDescription;
659-
}
660-
661652
/*
662653
* Create a space-delimited string from an array
663654
*/

index.d.ts

+35
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,38 @@ export function revoke(
119119
config: BaseAuthConfiguration,
120120
revokeConfig: RevokeConfiguration
121121
): Promise<void>;
122+
123+
// https://tools.ietf.org/html/rfc6749#section-4.1.2.1
124+
type OAuthAuthorizationErrorCode =
125+
| 'unauthorized_client'
126+
| 'access_denied'
127+
| 'unsupported_response_type'
128+
| 'invalid_scope'
129+
| 'server_error'
130+
| 'temporarily_unavailable';
131+
// https://tools.ietf.org/html/rfc6749#section-5.2
132+
type OAuthTokenErrorCode =
133+
| 'invalid_request'
134+
| 'invalid_client'
135+
| 'invalid_grant'
136+
| 'unauthorized_client'
137+
| 'unsupported_grant_type'
138+
| 'invalid_scope';
139+
// https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError
140+
type OICRegistrationErrorCode = 'invalid_redirect_uri' | 'invalid_client_metadata';
141+
type AppAuthErrorCode =
142+
| 'service_configuration_fetch_error'
143+
| 'authentication_failed'
144+
| 'token_refresh_failed'
145+
| 'registration_failed'
146+
| 'browser_not_found';
147+
148+
type ErrorCode =
149+
| OAuthAuthorizationErrorCode
150+
| OAuthTokenErrorCode
151+
| OICRegistrationErrorCode
152+
| AppAuthErrorCode;
153+
154+
export interface AppAuthError extends Error {
155+
code: ErrorCode;
156+
}

ios/RNAppAuth.m

+53-3
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,8 @@ - (void)registerWithConfiguration: (OIDServiceConfiguration *) configuration
243243
if (response) {
244244
resolve([self formatRegistrationResponse:response]);
245245
} else {
246-
reject(@"registration_failed", [error localizedDescription], error);
246+
reject([self getErrorCode: error defaultCode:@"registration_failed"],
247+
[error localizedDescription], error);
247248
}
248249
}];
249250
}
@@ -308,7 +309,8 @@ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
308309
resolve([self formatResponse:authState.lastTokenResponse
309310
withAuthResponse:authState.lastAuthorizationResponse]);
310311
} else {
311-
reject(@"authentication_failed", [error localizedDescription], error);
312+
reject([self getErrorCode: error defaultCode:@"authentication_failed"],
313+
[error localizedDescription], error);
312314
}
313315
}]; // end [OIDAuthState authStateByPresentingAuthorizationRequest:request
314316
}
@@ -345,7 +347,8 @@ - (void)refreshWithConfiguration: (OIDServiceConfiguration *)configuration
345347
if (response) {
346348
resolve([self formatResponse:response]);
347349
} else {
348-
reject(@"token_refresh_failed", [error localizedDescription], error);
350+
reject([self getErrorCode: error defaultCode:@"token_refresh_failed"],
351+
[error localizedDescription], error);
349352
}
350353
}];
351354
}
@@ -407,4 +410,51 @@ - (NSDictionary*)formatRegistrationResponse: (OIDRegistrationResponse*) response
407410
};
408411
}
409412

413+
- (NSString*)getErrorCode: (NSError*) error defaultCode: (NSString *) defaultCode {
414+
if ([[error domain] isEqualToString:OIDOAuthAuthorizationErrorDomain]) {
415+
switch ([error code]) {
416+
case OIDErrorCodeOAuthAuthorizationInvalidRequest:
417+
return @"invalid_request";
418+
case OIDErrorCodeOAuthAuthorizationUnauthorizedClient:
419+
return @"unauthorized_client";
420+
case OIDErrorCodeOAuthAuthorizationAccessDenied:
421+
return @"access_denied";
422+
case OIDErrorCodeOAuthAuthorizationUnsupportedResponseType:
423+
return @"unsupported_response_type";
424+
case OIDErrorCodeOAuthAuthorizationAuthorizationInvalidScope:
425+
return @"invalid_scope";
426+
case OIDErrorCodeOAuthAuthorizationServerError:
427+
return @"server_error";
428+
case OIDErrorCodeOAuthAuthorizationTemporarilyUnavailable:
429+
return @"temporarily_unavailable";
430+
}
431+
} else if ([[error domain] isEqualToString:OIDOAuthTokenErrorDomain]) {
432+
switch ([error code]) {
433+
case OIDErrorCodeOAuthTokenInvalidRequest:
434+
return @"invalid_request";
435+
case OIDErrorCodeOAuthTokenInvalidClient:
436+
return @"invalid_client";
437+
case OIDErrorCodeOAuthTokenInvalidGrant:
438+
return @"invalid_grant";
439+
case OIDErrorCodeOAuthTokenUnauthorizedClient:
440+
return @"unauthorized_client";
441+
case OIDErrorCodeOAuthTokenUnsupportedGrantType:
442+
return @"unsupported_grant_type";
443+
case OIDErrorCodeOAuthTokenInvalidScope:
444+
return @"invalid_scope";
445+
}
446+
} else if ([[error domain] isEqualToString:OIDOAuthRegistrationErrorDomain]) {
447+
switch ([error code]) {
448+
case OIDErrorCodeOAuthRegistrationInvalidRequest:
449+
return @"invalid_request";
450+
case OIDErrorCodeOAuthRegistrationInvalidRedirectURI:
451+
return @"invalid_redirect_uri";
452+
case OIDErrorCodeOAuthRegistrationInvalidClientMetadata:
453+
return @"invalid_client_metadata";
454+
}
455+
}
456+
457+
return defaultCode;
458+
}
459+
410460
@end

0 commit comments

Comments
 (0)