Skip to content

Commit 82ab731

Browse files
author
Kadi Kraman
authored
Merge pull request FormidableLabs#482 from aeirola/oauth-error-codes
Expose OAuth error codes
2 parents 798f433 + 10493ca commit 82ab731

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
@@ -428,6 +428,11 @@ try {
428428
429429
## Error messages
430430
431+
Values are in the `code` field of the rejected Error object.
432+
433+
- OAuth Authorization [error codes](https://tools.ietf.org/html/rfc6749#section-4.1.2.1)
434+
- OAuth Access Token [error codes](https://tools.ietf.org/html/rfc6749#section-5.2)
435+
- OpendID Connect Registration [error codes](https://openid.net/specs/openid-connect-registration-1_0.html#RegistrationError)
431436
- `service_configuration_fetch_error` - could not fetch the service configuration
432437
- `authentication_failed` - user authentication failed
433438
- `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
@@ -185,7 +185,7 @@ public void onFetchConfigurationCompleted(
185185
@Nullable AuthorizationServiceConfiguration fetchedConfiguration,
186186
@Nullable AuthorizationException ex) {
187187
if (ex != null) {
188-
promise.reject("service_configuration_fetch_error", getErrorMessage(ex));
188+
promise.reject("service_configuration_fetch_error", ex.getLocalizedMessage(), ex);
189189
return;
190190
}
191191

@@ -264,7 +264,7 @@ public void onFetchConfigurationCompleted(
264264
@Nullable AuthorizationServiceConfiguration fetchedConfiguration,
265265
@Nullable AuthorizationException ex) {
266266
if (ex != null) {
267-
promise.reject("service_configuration_fetch_error", getErrorMessage(ex));
267+
promise.reject("service_configuration_fetch_error", ex.getLocalizedMessage(), ex);
268268
return;
269269
}
270270

@@ -348,7 +348,7 @@ public void onFetchConfigurationCompleted(
348348
@Nullable AuthorizationServiceConfiguration fetchedConfiguration,
349349
@Nullable AuthorizationException ex) {
350350
if (ex != null) {
351-
promise.reject("service_configuration_fetch_error", getErrorMessage(ex));
351+
promise.reject("service_configuration_fetch_error", ex.getLocalizedMessage(), ex);
352352
return;
353353
}
354354

@@ -390,7 +390,7 @@ public void onActivityResult(Activity activity, int requestCode, int resultCode,
390390
AuthorizationException exception = AuthorizationException.fromIntent(data);
391391
if (exception != null) {
392392
if (promise != null) {
393-
promise.reject("authentication_error", getErrorMessage(exception));
393+
promise.reject(exception.error != null ? exception.error: "authentication_error", exception.getLocalizedMessage(), exception);
394394
}
395395
return;
396396
}
@@ -423,7 +423,7 @@ public void onTokenRequestCompleted(
423423
}
424424
} else {
425425
if (promise != null) {
426-
promise.reject("token_exchange_failed", getErrorMessage(ex));
426+
promise.reject(ex.error != null ? ex.error: "token_exchange_failed", ex.getLocalizedMessage(), ex);
427427
}
428428
}
429429
}
@@ -490,7 +490,7 @@ public void onRegistrationRequestCompleted(@Nullable RegistrationResponse respon
490490
WritableMap map = RegistrationResponseFactory.registrationResponseToMap(response);
491491
promise.resolve(map);
492492
} else {
493-
promise.reject("registration_failed", getErrorMessage(ex));
493+
promise.reject(ex.error != null ? ex.error: "registration_failed", ex.getLocalizedMessage(), ex);
494494
}
495495
}
496496
};
@@ -621,7 +621,7 @@ public void onTokenRequestCompleted(@Nullable TokenResponse response, @Nullable
621621
WritableMap map = TokenResponseFactory.tokenResponseToMap(response);
622622
promise.resolve(map);
623623
} else {
624-
promise.reject("token_refresh_failed", getErrorMessage(ex));
624+
promise.reject(ex.error != null ? ex.error: "token_refresh_failed", ex.getLocalizedMessage(), ex);
625625
}
626626
}
627627
};
@@ -660,15 +660,6 @@ private ClientAuthentication getClientAuthentication(String clientSecret, String
660660
return new ClientSecretBasic(clientSecret);
661661
}
662662

663-
/*
664-
* Return error information if it is available
665-
*/
666-
private String getErrorMessage(AuthorizationException ex){
667-
if(ex.errorDescription == null && ex.error != null)
668-
return ex.error;
669-
return ex.errorDescription;
670-
}
671-
672663
/*
673664
* Create a space-delimited string from an array
674665
*/

index.d.ts

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

ios/RNAppAuth.m

+53-3
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,8 @@ - (void)registerWithConfiguration: (OIDServiceConfiguration *) configuration
246246
if (response) {
247247
resolve([self formatRegistrationResponse:response]);
248248
} else {
249-
reject(@"registration_failed", [error localizedDescription], error);
249+
reject([self getErrorCode: error defaultCode:@"registration_failed"],
250+
[error localizedDescription], error);
250251
}
251252
}];
252253
}
@@ -311,7 +312,8 @@ - (void)authorizeWithConfiguration: (OIDServiceConfiguration *) configuration
311312
if (authorizationResponse) {
312313
resolve([self formatAuthorizationResponse:authorizationResponse]);
313314
} else {
314-
reject(@"authentication_failed", [error localizedDescription], error);
315+
reject([self getErrorCode: error defaultCode:@"authentication_failed"],
316+
[error localizedDescription], error);
315317
}
316318
}]; // end [OIDAuthState presentAuthorizationRequest:request
317319
} else {
@@ -364,7 +366,8 @@ - (void)refreshWithConfiguration: (OIDServiceConfiguration *)configuration
364366
if (response) {
365367
resolve([self formatResponse:response]);
366368
} else {
367-
reject(@"token_refresh_failed", [error localizedDescription], error);
369+
reject([self getErrorCode: error defaultCode:@"token_refresh_failed"],
370+
[error localizedDescription], error);
368371
}
369372
}];
370373
}
@@ -447,4 +450,51 @@ - (NSDictionary*)formatRegistrationResponse: (OIDRegistrationResponse*) response
447450
};
448451
}
449452

453+
- (NSString*)getErrorCode: (NSError*) error defaultCode: (NSString *) defaultCode {
454+
if ([[error domain] isEqualToString:OIDOAuthAuthorizationErrorDomain]) {
455+
switch ([error code]) {
456+
case OIDErrorCodeOAuthAuthorizationInvalidRequest:
457+
return @"invalid_request";
458+
case OIDErrorCodeOAuthAuthorizationUnauthorizedClient:
459+
return @"unauthorized_client";
460+
case OIDErrorCodeOAuthAuthorizationAccessDenied:
461+
return @"access_denied";
462+
case OIDErrorCodeOAuthAuthorizationUnsupportedResponseType:
463+
return @"unsupported_response_type";
464+
case OIDErrorCodeOAuthAuthorizationAuthorizationInvalidScope:
465+
return @"invalid_scope";
466+
case OIDErrorCodeOAuthAuthorizationServerError:
467+
return @"server_error";
468+
case OIDErrorCodeOAuthAuthorizationTemporarilyUnavailable:
469+
return @"temporarily_unavailable";
470+
}
471+
} else if ([[error domain] isEqualToString:OIDOAuthTokenErrorDomain]) {
472+
switch ([error code]) {
473+
case OIDErrorCodeOAuthTokenInvalidRequest:
474+
return @"invalid_request";
475+
case OIDErrorCodeOAuthTokenInvalidClient:
476+
return @"invalid_client";
477+
case OIDErrorCodeOAuthTokenInvalidGrant:
478+
return @"invalid_grant";
479+
case OIDErrorCodeOAuthTokenUnauthorizedClient:
480+
return @"unauthorized_client";
481+
case OIDErrorCodeOAuthTokenUnsupportedGrantType:
482+
return @"unsupported_grant_type";
483+
case OIDErrorCodeOAuthTokenInvalidScope:
484+
return @"invalid_scope";
485+
}
486+
} else if ([[error domain] isEqualToString:OIDOAuthRegistrationErrorDomain]) {
487+
switch ([error code]) {
488+
case OIDErrorCodeOAuthRegistrationInvalidRequest:
489+
return @"invalid_request";
490+
case OIDErrorCodeOAuthRegistrationInvalidRedirectURI:
491+
return @"invalid_redirect_uri";
492+
case OIDErrorCodeOAuthRegistrationInvalidClientMetadata:
493+
return @"invalid_client_metadata";
494+
}
495+
}
496+
497+
return defaultCode;
498+
}
499+
450500
@end

0 commit comments

Comments
 (0)