Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iOS,web): implement scopes #58

Merged
merged 3 commits into from
Nov 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,15 @@ public void initialize(String clientId, GoogleProviderLoginType mode) {
}
}

public String arrayFind(String[] array, String search) {
for (int i = 0; i < array.length; i++) {
if (array[i].equals(search)) {
return array[i];
}
}
return null;
}

@Override
public void login(PluginCall call, JSONObject config) {
if (this.clientId == null || this.clientId.isEmpty()) {
Expand All @@ -149,9 +158,46 @@ public void login(PluginCall call, JSONObject config) {
for (int i = 0; i < scopesArray.length(); i++) {
this.scopes[i] = scopesArray.optString(i);
}

if (
arrayFind(
this.scopes,
"https://www.googleapis.com/auth/userinfo.email"
) ==
null
) {
String[] newScopes = new String[this.scopes.length + 1];
System.arraycopy(this.scopes, 0, newScopes, 0, this.scopes.length);
newScopes[this.scopes.length] =
"https://www.googleapis.com/auth/userinfo.email";
this.scopes = newScopes;
}
if (
arrayFind(
this.scopes,
"https://www.googleapis.com/auth/userinfo.profile"
) ==
null
) {
String[] newScopes = new String[this.scopes.length + 1];
System.arraycopy(this.scopes, 0, newScopes, 0, this.scopes.length);
newScopes[this.scopes.length] =
"https://www.googleapis.com/auth/userinfo.profile";
this.scopes = newScopes;
}
if (arrayFind(this.scopes, "openid") == null) {
String[] newScopes = new String[this.scopes.length + 1];
System.arraycopy(this.scopes, 0, newScopes, 0, this.scopes.length);
newScopes[this.scopes.length] = "openid";
this.scopes = newScopes;
}
} else {
// Default scopes if not provided
this.scopes = new String[] { "profile", "email" };
this.scopes = new String[] {
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/userinfo.email",
"openid",
};
}

GetSignInWithGoogleOption.Builder googleIdOptionBuilder =
Expand Down Expand Up @@ -638,11 +684,10 @@ private ListenableFuture<AuthorizationResult> getAuthorizationResult(

ListenableFuture<AuthorizationResult> future =
CallbackToFutureAdapter.getFuture(completer -> {
List<Scope> scopes = Arrays.asList(
new Scope(Scopes.EMAIL),
new Scope(Scopes.PROFILE),
new Scope(Scopes.OPEN_ID)
);
List<Scope> scopes = new ArrayList<>(this.scopes.length);
for (int i = 0; i < this.scopes.length; i++) {
scopes.add(new Scope(this.scopes[i]));
}
AuthorizationRequest.Builder authorizationRequestBuilder =
AuthorizationRequest.builder().setRequestedScopes(scopes);
// .requestOfflineAccess(this.clientId)
Expand Down
30 changes: 28 additions & 2 deletions ios/Sources/SocialLoginPlugin/GoogleProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,28 @@ class GoogleProvider {
}

func login(payload: [String: Any], completion: @escaping (Result<GoogleLoginResponse, Error>) -> Void) {
var scopes = payload["scopes"] as? [String] ?? self.defaultGrantedScopes
if (!scopes.contains(where: { $0 == "https://www.googleapis.com/auth/userinfo.email" })) {
scopes.append("https://www.googleapis.com/auth/userinfo.email")
}
if (!scopes.contains(where: { $0 == "https://www.googleapis.com/auth/userinfo.profile" })) {
scopes.append("https://www.googleapis.com/auth/userinfo.profile")
}
if (!scopes.contains(where: { $0 == "openid" })) {
scopes.append("openid")
}

DispatchQueue.main.async {

func login() {
guard let presentingVc = UIApplication.shared.windows.first?.rootViewController else {
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "No presenting view controller found"])))
return
}

GIDSignIn.sharedInstance.signIn(
withPresenting: presentingVc,
hint: nil,
additionalScopes: payload["scopes"] as? [String] ?? self.defaultGrantedScopes
additionalScopes: scopes
) { result, error in
if let error = error {
completion(.failure(error))
Expand All @@ -72,6 +83,21 @@ class GoogleProvider {
login()
return
}
guard let grantedScopes = user?.grantedScopes else {
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "grantedScopes is null (?)"])))
return
}
var sharedScopes = 0;
for scope in scopes {
if (grantedScopes.contains(scope)) {
sharedScopes += 1
}
}
// scopes do not match. Perhaps the user has requested an additional scope
if (sharedScopes != scopes.count) {
login()
return
}
self.createLoginResponse(user: user!, completion: completion)
}
} else {
Expand Down
17 changes: 15 additions & 2 deletions src/web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type {
AuthorizationCodeOptions,
FacebookLoginOptions,
FacebookLoginResponse,
GoogleLoginOptions,
} from "./definitions";

declare const AppleID: any;
Expand Down Expand Up @@ -368,7 +369,9 @@ export class SocialLoginWeb extends WebPlugin implements SocialLoginPlugin {
}
}

private async loginWithGoogle(options: any): Promise<LoginResult> {
private async loginWithGoogle(
options: GoogleLoginOptions,
): Promise<LoginResult> {
if (!this.googleClientId) {
throw new Error("Google Client ID not set. Call initialize() first.");
}
Expand All @@ -377,7 +380,17 @@ export class SocialLoginWeb extends WebPlugin implements SocialLoginPlugin {

if (scopes.length > 0) {
// If scopes are provided, directly use the traditional OAuth flow
return Promise.reject("Not yet implemented");
if (!scopes.includes("https://www.googleapis.com/auth/userinfo.email")) {
scopes.push("https://www.googleapis.com/auth/userinfo.email");
}
if (
!scopes.includes("https://www.googleapis.com/auth/userinfo.profile")
) {
scopes.push("https://www.googleapis.com/auth/userinfo.profile");
}
if (!scopes.includes("openid")) {
scopes.push("openid");
}
} else {
scopes = [
"https://www.googleapis.com/auth/userinfo.email",
Expand Down