Skip to content

Commit

Permalink
feat(authentication): support OAuth 2.0 scopes (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
nkalupahana authored May 21, 2022
1 parent e159f92 commit e4a4787
Show file tree
Hide file tree
Showing 14 changed files with 159 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-falcons-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@capacitor-firebase/authentication": minor
---

Added ability to request scopes when authenticating.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Pod::Spec.new do |s|

s.subspec 'Google' do |google|
google.xcconfig = { 'OTHER_SWIFT_FLAGS' => '$(inherited) -DRGCFA_INCLUDE_GOOGLE' }
google.dependency 'GoogleSignIn', '6.0.0'
google.dependency 'GoogleSignIn', '6.2.1'
end

s.subspec 'Facebook' do |facebook|
Expand Down
1 change: 1 addition & 0 deletions packages/authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -798,6 +798,7 @@ Remove all listeners for this plugin.
| Prop | Type | Description |
| ---------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------- |
| **`customParameters`** | <code>SignInCustomParameter[]</code> | Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow. |
| **`scopes`** | <code>string[]</code> | Scopes to request from provider. |


#### SignInCustomParameter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,5 +121,15 @@ private void applySignInConfig(PluginCall call, OAuthProvider.Builder provider)
Log.e(FirebaseAuthenticationPlugin.TAG, "applySignInConfig failed.", exception);
}
}

JSArray scopes = call.getArray("scopes");
if (scopes != null) {
try {
List<String> scopeList = scopes.toList();
provider.setScopes(scopeList);
} catch (JSONException exception) {
Log.e(FirebaseAuthenticationPlugin.TAG, "applySignInConfig failed.", exception);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
import com.facebook.login.LoginManager;
import com.facebook.login.LoginResult;
import com.facebook.login.widget.LoginButton;
import com.getcapacitor.JSArray;
import com.getcapacitor.Plugin;
import com.getcapacitor.PluginCall;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.FacebookAuthProvider;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin;
import java.util.List;
import org.json.JSONException;

public class FacebookAuthProviderHandler {

Expand All @@ -29,6 +33,7 @@ public FacebookAuthProviderHandler(FirebaseAuthentication pluginImplementation)
try {
mCallbackManager = CallbackManager.Factory.create();
loginButton = new LoginButton(pluginImplementation.getPlugin().getContext());

loginButton.setPermissions("email", "public_profile");
loginButton.registerCallback(
mCallbackManager,
Expand All @@ -54,8 +59,23 @@ public void onError(FacebookException exception) {
}
}

private void applySignInConfig(LoginButton button) {
JSArray scopes = this.savedCall.getArray("scopes");
if (scopes != null) {
try {
List<String> scopeList = scopes.toList();
scopeList.add("email");
scopeList.add("public_profile");
button.setPermissions(scopeList);
} catch (JSONException exception) {
Log.e(FirebaseAuthenticationPlugin.TAG, "applySignInConfig failed.", exception);
}
}
}

public void signIn(PluginCall call) {
savedCall = call;
this.savedCall = call;
this.applySignInConfig(this.loginButton);
this.loginButton.performClick();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
package dev.robingenz.capacitorjs.plugins.firebase.authentication.handlers;

import android.content.Intent;
import android.util.Log;
import androidx.activity.result.ActivityResult;
import androidx.annotation.Nullable;
import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.PluginCall;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.GoogleAuthProvider;
import com.google.firebase.auth.OAuthCredential;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.R;
import java.util.List;
import org.json.JSONException;

public class GoogleAuthProviderHandler {

Expand All @@ -23,14 +30,11 @@ public class GoogleAuthProviderHandler {

public GoogleAuthProviderHandler(FirebaseAuthentication pluginImplementation) {
this.pluginImplementation = pluginImplementation;
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id))
.requestEmail()
.build();
mGoogleSignInClient = GoogleSignIn.getClient(pluginImplementation.getPlugin().getActivity(), gso);
this.buildGoogleSignInClient(null);
}

public void signIn(PluginCall call) {
this.buildGoogleSignInClient(call);
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
pluginImplementation.startActivityForResult(call, signInIntent, "handleGoogleAuthProviderActivityResult");
}
Expand All @@ -51,4 +55,26 @@ public void handleOnActivityResult(PluginCall call, ActivityResult result) {
pluginImplementation.handleFailedSignIn(call, null, exception);
}
}

private void buildGoogleSignInClient(@Nullable PluginCall call) {
GoogleSignInOptions.Builder gsob = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id))
.requestEmail();

if (call != null) {
JSArray scopes = call.getArray("scopes");
if (scopes != null) {
try {
List<String> scopeList = scopes.toList();
for (String scope : scopeList) {
gsob = gsob.requestScopes(new Scope(scope));
}
} catch (JSONException exception) {
Log.e(FirebaseAuthenticationPlugin.TAG, "buildGoogleSignInClient failed.", exception);
}
}
}

mGoogleSignInClient = GoogleSignIn.getClient(pluginImplementation.getPlugin().getActivity(), gsob.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,5 +76,15 @@ private void applySignInConfig(PluginCall call, OAuthProvider.Builder provider)
Log.e(FirebaseAuthenticationPlugin.TAG, "applySignInConfig failed.", exception);
}
}

JSArray scopes = call.getArray("scopes");
if (scopes != null) {
try {
List<String> scopeList = scopes.toList();
provider.setScopes(scopeList);
} catch (JSONException exception) {
Log.e(FirebaseAuthenticationPlugin.TAG, "applySignInConfig failed.", exception);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
package dev.robingenz.capacitorjs.plugins.firebase.authentication.handlers;

import android.content.Intent;
import android.util.Log;
import androidx.activity.result.ActivityResult;
import androidx.annotation.Nullable;
import com.getcapacitor.JSArray;
import com.getcapacitor.PluginCall;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.PlayGamesAuthProvider;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.FirebaseAuthentication;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.FirebaseAuthenticationPlugin;
import dev.robingenz.capacitorjs.plugins.firebase.authentication.R;
import java.util.List;
import org.json.JSONException;

public class PlayGamesAuthProviderHandler {

Expand All @@ -21,13 +28,33 @@ public class PlayGamesAuthProviderHandler {

public PlayGamesAuthProviderHandler(FirebaseAuthentication pluginImplementation) {
this.pluginImplementation = pluginImplementation;
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN)
.requestServerAuthCode(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id))
.build();
mGoogleSignInClient = GoogleSignIn.getClient(pluginImplementation.getPlugin().getActivity(), gso);
this.buildGoogleSignInClient(null);
}

private void buildGoogleSignInClient(@Nullable PluginCall call) {
GoogleSignInOptions.Builder gsob = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(pluginImplementation.getPlugin().getContext().getString(R.string.default_web_client_id))
.requestEmail();

if (call != null) {
JSArray scopes = call.getArray("scopes");
if (scopes != null) {
try {
List<String> scopeList = scopes.toList();
for (String scope : scopeList) {
gsob = gsob.requestScopes(new Scope(scope));
}
} catch (JSONException exception) {
Log.e(FirebaseAuthenticationPlugin.TAG, "buildGoogleSignInClient failed.", exception);
}
}
}

mGoogleSignInClient = GoogleSignIn.getClient(pluginImplementation.getPlugin().getActivity(), gsob.build());
}

public void signIn(PluginCall call) {
this.buildGoogleSignInClient(call);
Intent signInIntent = mGoogleSignInClient.getSignInIntent();
pluginImplementation.startActivityForResult(call, signInIntent, "handlePlayGamesAuthProviderActivityResult");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ class FacebookAuthProviderHandler: NSObject {

func signIn(call: CAPPluginCall) {
#if RGCFA_INCLUDE_FACEBOOK
let scopes = call.getArray("scopes", String.self) ?? []
DispatchQueue.main.async {
self.loginManager.logIn(permissions: ["email", "public_profile"], from: self.pluginImplementation.getPlugin().bridge?.viewController) { result, error in
self.loginManager.logIn(permissions: ["email", "public_profile"] + scopes, from: self.pluginImplementation.getPlugin().bridge?.viewController) { result, error in
if let error = error {
self.pluginImplementation.handleFailedSignIn(message: nil, error: error)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ class GoogleAuthProviderHandler: NSObject {
guard let clientId = FirebaseApp.app()?.options.clientID else { return }
let config = GIDConfiguration(clientID: clientId)
guard let controller = self.pluginImplementation.getPlugin().bridge?.viewController else { return }
let scopes = call.getArray("scopes", String.self) ?? []

DispatchQueue.main.async {
GIDSignIn.sharedInstance.signIn(with: config, presenting: controller) { user, error in
GIDSignIn.sharedInstance.signIn(with: config, presenting: controller, hint: nil, additionalScopes: scopes, callback: { user, error in
if let error = error {
self.pluginImplementation.handleFailedSignIn(message: nil, error: error)
return
Expand All @@ -33,7 +34,7 @@ class GoogleAuthProviderHandler: NSObject {

let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: authentication.accessToken)
self.pluginImplementation.handleSuccessfulSignIn(credential: credential, idToken: idToken, nonce: nil, accessToken: accessToken)
}
})
}
#endif
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class OAuthProviderHandler: NSObject {
}
provider.customParameters?[key] = value
}

let scopes = call.getArray("scopes", String.self) ?? []
provider.scopes = scopes
}

private func startSignInFlow() {
Expand Down
2 changes: 1 addition & 1 deletion packages/authentication/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ end
target 'Plugin' do
capacitor_pods
pod 'Firebase/Auth', '8.13.0'
pod 'GoogleSignIn', '6.0.0'
pod 'GoogleSignIn', '6.2.1'
pod 'FBSDKCoreKit', '11.1.0'
pod 'FBSDKLoginKit', '11.1.0'
end
Expand Down
4 changes: 4 additions & 0 deletions packages/authentication/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ export interface SignInOptions {
* Configures custom parameters to be passed to the identity provider during the OAuth sign-in flow.
*/
customParameters?: SignInCustomParameter[];
/**
* Scopes to request from provider.
*/
scopes?: string[];
}

export interface SignInCustomParameter {
Expand Down
Loading

0 comments on commit e4a4787

Please sign in to comment.