From 2ad4ffceebb0dc233cb246db7d14b0fbde22e37a Mon Sep 17 00:00:00 2001 From: Tom Clarkson Date: Tue, 29 Aug 2017 13:29:33 +1000 Subject: [PATCH] add a reauthenticate method to expose refresh token use --- .../fullstack/oauth/OAuthManagerModule.java | 15 +++++ ios/OAuthManager/OAuthManager.m | 62 +++++++++++++++++++ react-native-oauth.js | 7 +++ 3 files changed, 84 insertions(+) diff --git a/android/src/main/java/io/fullstack/oauth/OAuthManagerModule.java b/android/src/main/java/io/fullstack/oauth/OAuthManagerModule.java index 35777a4..eda6d7f 100644 --- a/android/src/main/java/io/fullstack/oauth/OAuthManagerModule.java +++ b/android/src/main/java/io/fullstack/oauth/OAuthManagerModule.java @@ -162,6 +162,21 @@ public void onOAuth2AccessToken(final OAuth2AccessToken accessToken) { } } + @ReactMethod + public void reauthenticate( + final String providerName, + @Nullable final ReadableMap params, + final Callback callback) + { + Log.e(TAG, "Reauthenticate is not implemented for android"); + WritableMap err = Arguments.createMap(); + err.putString("status", "error"); + err.putString("msg", "Reauthenticate is not implemented for android"); + callback.invoke(err); + return; + } + + @ReactMethod public void makeRequest( final String providerName, diff --git a/ios/OAuthManager/OAuthManager.m b/ios/OAuthManager/OAuthManager.m index a9451bc..f9b9d99 100644 --- a/ios/OAuthManager/OAuthManager.m +++ b/ios/OAuthManager/OAuthManager.m @@ -383,6 +383,61 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name }]; } +RCT_EXPORT_METHOD(reauthenticate:(NSString *) providerName + opts:(NSDictionary *) opts + callback:(RCTResponseSenderBlock) callback) +{ + OAuthManager *manager = [OAuthManager sharedManager]; + DCTAuthAccountStore *store = [manager accountStore]; + NSMutableDictionary *cfg = [[manager getConfigForProvider:providerName] mutableCopy]; + + NSString *newToken = [opts valueForKey:@"accessToken"]; + + DCTAuthAccount *existingAccount = [manager accountForProvider:providerName]; + if (existingAccount == nil) { + NSDictionary *resp = @{ + @"status": @"error", + @"msg": [NSString stringWithFormat:@"No account found for %@", providerName] + }; + callback(@[resp]); + } else if (newToken != nil) { + DCTOAuth2Credential *existingCredential = existingAccount.credential; + existingAccount.credential = [[DCTOAuth2Credential alloc] initWithClientID:existingCredential.clientID + clientSecret:existingCredential.clientSecret + password:existingCredential.password + accessToken:newToken + refreshToken: existingCredential.refreshToken + type:existingCredential.type]; + + [store saveAccount:existingAccount]; + NSDictionary *accountResponse = [manager getAccountResponse:existingAccount cfg:cfg]; + callback(@[[NSNull null], @{ + @"status": @"ok", + @"provider": providerName, + @"response": accountResponse + }]); + } else { + [existingAccount reauthenticateWithHandler:^(DCTAuthResponse *response, NSError *error) { + if (error != nil) { + NSDictionary *resp = @{ + @"status": @"error", + @"msg": [error localizedDescription] + }; + callback(@[resp]); + } + else { + [store saveAccount:existingAccount]; + NSDictionary *accountResponse = [manager getAccountResponse:existingAccount cfg:cfg]; + callback(@[[NSNull null], @{ + @"status": @"ok", + @"provider": providerName, + @"response": accountResponse + }]); + } + }]; + } +} + RCT_EXPORT_METHOD(makeRequest:(NSString *)providerName urlOrPath:(NSString *) urlOrPath opts:(NSDictionary *) opts @@ -403,6 +458,8 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name NSDictionary *creds = [self credentialForAccount:providerName cfg:cfg]; + id existingCredential = [existingAccount credential]; + // If we have the http in the string, use it as the URL, otherwise create one // with the configuration NSURL *apiUrl; @@ -474,6 +531,11 @@ - (NSDictionary *) getConfigForProvider:(NSString *)name NSInteger statusCode = response.statusCode; NSData *rawData = response.data; + // if account.credential has changed through use of a refresh token, save the updated token + if ([existingAccount credential] != existingCredential) { + [[manager accountStore] saveAccount:existingAccount]; + } + NSError *err; NSArray *data; diff --git a/react-native-oauth.js b/react-native-oauth.js index 3008cf0..105da37 100644 --- a/react-native-oauth.js +++ b/react-native-oauth.js @@ -44,6 +44,13 @@ export default class OAuthManager { return promisify('authorize')(provider, options); } + reauthenticate(provider, opts={}) { + const options = Object.assign({}, this._options, opts, { + app_name: this.appName + }) + return promisify('reauthenticate')(provider, options); + } + savedAccounts(opts={}) { // const options = Object.assign({}, this._options, opts, { // app_name: this.appName