@capgo/capacitor-social-login 0.0.57 → 0.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -8
- package/android/src/main/java/ee/forgr/capacitor/social/login/AppleProvider.java +69 -15
- package/android/src/main/java/ee/forgr/capacitor/social/login/FacebookProvider.java +145 -117
- package/android/src/main/java/ee/forgr/capacitor/social/login/GoogleProvider.java +42 -73
- package/android/src/main/java/ee/forgr/capacitor/social/login/SocialLoginPlugin.java +24 -11
- package/android/src/main/java/ee/forgr/capacitor/social/login/helpers/SocialProvider.java +0 -1
- package/dist/docs.json +13 -21
- package/dist/esm/definitions.d.ts +11 -6
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +1 -0
- package/dist/esm/web.js +64 -17
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +64 -17
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +64 -17
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/SocialLoginPlugin/AppleProvider.swift +47 -51
- package/ios/Sources/SocialLoginPlugin/FacebookProvider.swift +1 -24
- package/ios/Sources/SocialLoginPlugin/GoogleProvider.swift +0 -8
- package/ios/Sources/SocialLoginPlugin/SocialLoginPlugin.swift +19 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -390,14 +390,12 @@ Refresh the access token
|
|
|
390
390
|
|
|
391
391
|
#### AppleProviderResponse
|
|
392
392
|
|
|
393
|
-
| Prop | Type
|
|
394
|
-
| ----------------------- |
|
|
395
|
-
| **`
|
|
396
|
-
| **`
|
|
397
|
-
| **`
|
|
398
|
-
| **`
|
|
399
|
-
| **`identityToken`** | <code>string \| null</code> |
|
|
400
|
-
| **`authorizationCode`** | <code>string \| null</code> |
|
|
393
|
+
| Prop | Type |
|
|
394
|
+
| ----------------------- | ------------------------------------------------------------------------------------------------------------ |
|
|
395
|
+
| **`accessToken`** | <code><a href="#accesstoken">AccessToken</a> \| null</code> |
|
|
396
|
+
| **`profile`** | <code>{ user: string; email: string \| null; givenName: string \| null; familyName: string \| null; }</code> |
|
|
397
|
+
| **`idToken`** | <code>string \| null</code> |
|
|
398
|
+
| **`authorizationCode`** | <code>string \| null</code> |
|
|
401
399
|
|
|
402
400
|
|
|
403
401
|
#### LoginOptions
|
|
@@ -43,13 +43,15 @@ import okhttp3.FormBody;
|
|
|
43
43
|
import okhttp3.OkHttpClient;
|
|
44
44
|
import okhttp3.Request;
|
|
45
45
|
import okhttp3.Response;
|
|
46
|
+
import org.json.JSONArray;
|
|
46
47
|
import org.json.JSONException;
|
|
47
48
|
import org.json.JSONObject;
|
|
48
49
|
import org.json.JSONTokener;
|
|
49
50
|
|
|
50
51
|
public class AppleProvider implements SocialProvider {
|
|
51
52
|
|
|
52
|
-
private static final String
|
|
53
|
+
private static final String LOG_TAG = "AppleProvider";
|
|
54
|
+
private static final String DEFAULT_SCOPE = "name%20email";
|
|
53
55
|
private static final String AUTHURL =
|
|
54
56
|
"https://appleid.apple.com/auth/authorize";
|
|
55
57
|
private static final String TOKENURL = "https://appleid.apple.com/auth/token";
|
|
@@ -164,13 +166,27 @@ public class AppleProvider implements SocialProvider {
|
|
|
164
166
|
}
|
|
165
167
|
|
|
166
168
|
String state = UUID.randomUUID().toString();
|
|
169
|
+
|
|
170
|
+
// Extract scopes from config
|
|
171
|
+
String scopes = DEFAULT_SCOPE;
|
|
172
|
+
if (config.has("scopes")) {
|
|
173
|
+
try {
|
|
174
|
+
JSONArray scopesArray = config.getJSONArray("scopes");
|
|
175
|
+
if (scopesArray.length() > 0) {
|
|
176
|
+
scopes = String.join("%20", toStringArray(scopesArray));
|
|
177
|
+
}
|
|
178
|
+
} catch (JSONException e) {
|
|
179
|
+
Log.e(SocialLoginPlugin.LOG_TAG, "Error parsing scopes", e);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
167
183
|
this.appleAuthURLFull = AUTHURL +
|
|
168
184
|
"?client_id=" +
|
|
169
185
|
this.clientId +
|
|
170
186
|
"&redirect_uri=" +
|
|
171
187
|
this.redirectUrl +
|
|
172
188
|
"&response_type=code&scope=" +
|
|
173
|
-
|
|
189
|
+
scopes +
|
|
174
190
|
"&response_mode=form_post&state=" +
|
|
175
191
|
state;
|
|
176
192
|
|
|
@@ -229,11 +245,6 @@ public class AppleProvider implements SocialProvider {
|
|
|
229
245
|
}
|
|
230
246
|
}
|
|
231
247
|
|
|
232
|
-
@Override
|
|
233
|
-
public void getCurrentUser(PluginCall call) {
|
|
234
|
-
call.reject("Not implemented");
|
|
235
|
-
}
|
|
236
|
-
|
|
237
248
|
@Override
|
|
238
249
|
public void refresh(PluginCall call) {
|
|
239
250
|
call.reject("Not implemented");
|
|
@@ -249,16 +260,20 @@ public class AppleProvider implements SocialProvider {
|
|
|
249
260
|
String idToken = uri.getQueryParameter("id_token");
|
|
250
261
|
try {
|
|
251
262
|
persistState(idToken, refreshToken, accessToken);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
263
|
+
JSObject result = new JSObject();
|
|
264
|
+
result.put("accessToken", createAccessTokenObject(accessToken));
|
|
265
|
+
result.put("profile", createProfileObject(idToken));
|
|
266
|
+
result.put("idToken", idToken);
|
|
267
|
+
result.put("authorizationCode", ""); // Apple doesn't provide this in the response
|
|
268
|
+
|
|
269
|
+
JSObject response = new JSObject();
|
|
270
|
+
response.put("provider", "apple");
|
|
271
|
+
response.put("result", result);
|
|
272
|
+
|
|
273
|
+
this.lastcall.resolve(response);
|
|
258
274
|
} catch (JSONException e) {
|
|
259
275
|
Log.e(SocialLoginPlugin.LOG_TAG, "Cannot persist state", e);
|
|
260
276
|
this.lastcall.reject("Cannot persist state", e);
|
|
261
|
-
this.lastcall = null;
|
|
262
277
|
}
|
|
263
278
|
} else {
|
|
264
279
|
String appleAuthCode = uri.getQueryParameter("code");
|
|
@@ -267,8 +282,8 @@ public class AppleProvider implements SocialProvider {
|
|
|
267
282
|
}
|
|
268
283
|
} else {
|
|
269
284
|
this.lastcall.reject("We couldn't get the Auth Code");
|
|
270
|
-
this.lastcall = null;
|
|
271
285
|
}
|
|
286
|
+
this.lastcall = null;
|
|
272
287
|
}
|
|
273
288
|
|
|
274
289
|
private void requestForAccessToken(String code, String clientSecret) {
|
|
@@ -379,4 +394,43 @@ public class AppleProvider implements SocialProvider {
|
|
|
379
394
|
|
|
380
395
|
builder.build().launchUrl(context, Uri.parse(url));
|
|
381
396
|
}
|
|
397
|
+
|
|
398
|
+
private JSObject createAccessTokenObject(String accessToken) {
|
|
399
|
+
JSObject tokenObject = new JSObject();
|
|
400
|
+
tokenObject.put("token", accessToken);
|
|
401
|
+
// Add other fields if available
|
|
402
|
+
return tokenObject;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
private JSObject createProfileObject(String idToken) {
|
|
406
|
+
JSObject profileObject = new JSObject();
|
|
407
|
+
// Parse the ID token to extract user information
|
|
408
|
+
// This is a simplified example. In practice, you should properly decode and verify the JWT.
|
|
409
|
+
String[] parts = idToken.split("\\.");
|
|
410
|
+
if (parts.length == 3) {
|
|
411
|
+
try {
|
|
412
|
+
String payload = new String(
|
|
413
|
+
android.util.Base64.decode(parts[1], android.util.Base64.URL_SAFE)
|
|
414
|
+
);
|
|
415
|
+
JSONObject claims = new JSONObject(payload);
|
|
416
|
+
profileObject.put("user", claims.optString("sub"));
|
|
417
|
+
profileObject.put("email", claims.optString("email"));
|
|
418
|
+
// Apple doesn't provide given name and family name in the ID token
|
|
419
|
+
profileObject.put("givenName", JSONObject.NULL);
|
|
420
|
+
profileObject.put("familyName", JSONObject.NULL);
|
|
421
|
+
} catch (JSONException e) {
|
|
422
|
+
Log.e(LOG_TAG, "Error parsing ID token", e);
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return profileObject;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Helper method to convert JSONArray to String array
|
|
429
|
+
private String[] toStringArray(JSONArray array) throws JSONException {
|
|
430
|
+
String[] stringArray = new String[array.length()];
|
|
431
|
+
for (int i = 0; i < array.length(); i++) {
|
|
432
|
+
stringArray[i] = array.getString(i);
|
|
433
|
+
}
|
|
434
|
+
return stringArray;
|
|
435
|
+
}
|
|
382
436
|
}
|
|
@@ -4,6 +4,7 @@ import android.app.Activity;
|
|
|
4
4
|
import android.content.Intent;
|
|
5
5
|
import android.os.Bundle;
|
|
6
6
|
import android.util.Log;
|
|
7
|
+
import androidx.activity.result.ActivityResultRegistryOwner;
|
|
7
8
|
import com.facebook.AccessToken;
|
|
8
9
|
import com.facebook.CallbackManager;
|
|
9
10
|
import com.facebook.FacebookCallback;
|
|
@@ -17,7 +18,6 @@ import com.facebook.login.LoginResult;
|
|
|
17
18
|
import com.getcapacitor.JSArray;
|
|
18
19
|
import com.getcapacitor.JSObject;
|
|
19
20
|
import com.getcapacitor.PluginCall;
|
|
20
|
-
import androidx.activity.result.ActivityResultRegistryOwner;
|
|
21
21
|
import ee.forgr.capacitor.social.login.helpers.JsonHelper;
|
|
22
22
|
import ee.forgr.capacitor.social.login.helpers.SocialProvider;
|
|
23
23
|
import java.util.Collection;
|
|
@@ -37,90 +37,117 @@ public class FacebookProvider implements SocialProvider {
|
|
|
37
37
|
|
|
38
38
|
public void initialize(JSONObject config) {
|
|
39
39
|
try {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
40
|
+
// Set Facebook App ID
|
|
41
|
+
String facebookAppId = config.getString("appId");
|
|
42
|
+
FacebookSdk.setApplicationId(facebookAppId);
|
|
43
|
+
|
|
44
|
+
// Set Facebook Client Token
|
|
45
|
+
String facebookClientToken = config.getString("clientToken");
|
|
46
|
+
FacebookSdk.setClientToken(facebookClientToken);
|
|
47
|
+
|
|
48
|
+
// Initialize Facebook SDK
|
|
49
|
+
FacebookSdk.sdkInitialize(activity.getApplicationContext());
|
|
50
|
+
|
|
51
|
+
this.callbackManager = CallbackManager.Factory.create();
|
|
52
|
+
|
|
53
|
+
LoginManager.getInstance()
|
|
54
|
+
.registerCallback(
|
|
55
|
+
callbackManager,
|
|
56
|
+
new FacebookCallback<LoginResult>() {
|
|
57
|
+
@Override
|
|
58
|
+
public void onSuccess(LoginResult loginResult) {
|
|
59
|
+
Log.d(LOG_TAG, "LoginManager.onSuccess");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@Override
|
|
63
|
+
public void onCancel() {
|
|
64
|
+
Log.d(LOG_TAG, "LoginManager.onCancel");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@Override
|
|
68
|
+
public void onError(FacebookException exception) {
|
|
69
|
+
Log.e(LOG_TAG, "LoginManager.onError", exception);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
);
|
|
70
73
|
} catch (JSONException e) {
|
|
71
|
-
|
|
72
|
-
|
|
74
|
+
Log.e(LOG_TAG, "Error initializing Facebook SDK", e);
|
|
75
|
+
throw new RuntimeException(
|
|
76
|
+
"Failed to initialize Facebook SDK: " + e.getMessage()
|
|
77
|
+
);
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
|
|
76
81
|
@Override
|
|
77
82
|
public void login(PluginCall call, JSONObject config) {
|
|
78
83
|
try {
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
Collection<String> permissions = JsonHelper.jsonArrayToList(
|
|
85
|
+
config.getJSONArray("permissions")
|
|
86
|
+
);
|
|
87
|
+
boolean limitedLogin = config.optBoolean("limitedLogin", false);
|
|
88
|
+
String nonce = config.optString("nonce", "");
|
|
89
|
+
|
|
90
|
+
LoginManager.getInstance()
|
|
91
|
+
.registerCallback(
|
|
92
|
+
callbackManager,
|
|
93
|
+
new FacebookCallback<LoginResult>() {
|
|
94
|
+
@Override
|
|
95
|
+
public void onSuccess(LoginResult loginResult) {
|
|
96
|
+
Log.d(LOG_TAG, "LoginManager.onSuccess");
|
|
97
|
+
AccessToken accessToken = loginResult.getAccessToken();
|
|
98
|
+
JSObject result = new JSObject();
|
|
99
|
+
result.put("accessToken", createAccessTokenObject(accessToken));
|
|
100
|
+
result.put("profile", createProfileObject(accessToken));
|
|
101
|
+
result.put(
|
|
102
|
+
"authenticationToken",
|
|
103
|
+
loginResult.getAuthenticationToken() != null
|
|
104
|
+
? loginResult.getAuthenticationToken().getToken()
|
|
105
|
+
: null
|
|
106
|
+
);
|
|
107
|
+
|
|
108
|
+
JSObject response = new JSObject();
|
|
109
|
+
response.put("provider", "facebook");
|
|
110
|
+
response.put("result", result);
|
|
111
|
+
|
|
112
|
+
call.resolve(response);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@Override
|
|
116
|
+
public void onCancel() {
|
|
117
|
+
Log.d(LOG_TAG, "LoginManager.onCancel");
|
|
118
|
+
call.reject("Login cancelled");
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@Override
|
|
122
|
+
public void onError(FacebookException exception) {
|
|
123
|
+
Log.e(LOG_TAG, "LoginManager.onError", exception);
|
|
124
|
+
call.reject(exception.getMessage());
|
|
125
|
+
}
|
|
126
|
+
}
|
|
81
127
|
);
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@Override
|
|
105
|
-
public void onError(FacebookException exception) {
|
|
106
|
-
Log.e(LOG_TAG, "LoginManager.onError", exception);
|
|
107
|
-
call.reject(exception.getMessage());
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
LoginManager loginManager = LoginManager.getInstance();
|
|
112
|
-
if (limitedLogin) {
|
|
113
|
-
Log.w(LOG_TAG, "Limited login is not available for Android");
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
loginManager.setLoginBehavior(LoginBehavior.NATIVE_WITH_FALLBACK);
|
|
117
|
-
if (!nonce.isEmpty()) {
|
|
118
|
-
loginManager.logIn((ActivityResultRegistryOwner) activity, callbackManager, permissions, nonce);
|
|
119
|
-
} else {
|
|
120
|
-
loginManager.logIn((ActivityResultRegistryOwner) activity, callbackManager, permissions);
|
|
121
|
-
}
|
|
128
|
+
|
|
129
|
+
LoginManager loginManager = LoginManager.getInstance();
|
|
130
|
+
if (limitedLogin) {
|
|
131
|
+
Log.w(LOG_TAG, "Limited login is not available for Android");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
loginManager.setLoginBehavior(LoginBehavior.NATIVE_WITH_FALLBACK);
|
|
135
|
+
if (!nonce.isEmpty()) {
|
|
136
|
+
loginManager.logIn(
|
|
137
|
+
(ActivityResultRegistryOwner) activity,
|
|
138
|
+
callbackManager,
|
|
139
|
+
permissions,
|
|
140
|
+
nonce
|
|
141
|
+
);
|
|
142
|
+
} else {
|
|
143
|
+
loginManager.logIn(
|
|
144
|
+
(ActivityResultRegistryOwner) activity,
|
|
145
|
+
callbackManager,
|
|
146
|
+
permissions
|
|
147
|
+
);
|
|
148
|
+
}
|
|
122
149
|
} catch (JSONException e) {
|
|
123
|
-
|
|
150
|
+
call.reject("Invalid login options format");
|
|
124
151
|
}
|
|
125
152
|
}
|
|
126
153
|
|
|
@@ -149,45 +176,6 @@ public class FacebookProvider implements SocialProvider {
|
|
|
149
176
|
);
|
|
150
177
|
}
|
|
151
178
|
|
|
152
|
-
@Override
|
|
153
|
-
public void getCurrentUser(PluginCall call) {
|
|
154
|
-
AccessToken accessToken = AccessToken.getCurrentAccessToken();
|
|
155
|
-
if (accessToken == null) {
|
|
156
|
-
call.reject(
|
|
157
|
-
"You're not logged in. Call FacebookLogin.login() first to obtain an access token."
|
|
158
|
-
);
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (accessToken.isExpired()) {
|
|
163
|
-
call.reject("AccessToken is expired.");
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
GraphRequest graphRequest = GraphRequest.newMeRequest(
|
|
168
|
-
accessToken,
|
|
169
|
-
new GraphRequest.GraphJSONObjectCallback() {
|
|
170
|
-
@Override
|
|
171
|
-
public void onCompleted(JSONObject object, GraphResponse response) {
|
|
172
|
-
if (response.getError() != null) {
|
|
173
|
-
call.reject(response.getError().getErrorMessage());
|
|
174
|
-
} else {
|
|
175
|
-
try {
|
|
176
|
-
call.resolve(JSObject.fromJSONObject(object));
|
|
177
|
-
} catch (JSONException e) {
|
|
178
|
-
call.reject("Error parsing user data: " + e.getMessage());
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
Bundle parameters = new Bundle();
|
|
186
|
-
parameters.putString("fields", "id,name,email");
|
|
187
|
-
graphRequest.setParameters(parameters);
|
|
188
|
-
graphRequest.executeAsync();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
179
|
@Override
|
|
192
180
|
public void refresh(PluginCall call) {
|
|
193
181
|
// Not implemented for Facebook
|
|
@@ -201,7 +189,7 @@ public class FacebookProvider implements SocialProvider {
|
|
|
201
189
|
) {
|
|
202
190
|
Log.d(LOG_TAG, "FacebookProvider.handleOnActivityResult called");
|
|
203
191
|
if (callbackManager != null) {
|
|
204
|
-
|
|
192
|
+
return callbackManager.onActivityResult(requestCode, resultCode, data);
|
|
205
193
|
}
|
|
206
194
|
return false;
|
|
207
195
|
}
|
|
@@ -209,7 +197,10 @@ public class FacebookProvider implements SocialProvider {
|
|
|
209
197
|
private JSObject createAccessTokenObject(AccessToken accessToken) {
|
|
210
198
|
JSObject tokenObject = new JSObject();
|
|
211
199
|
tokenObject.put("applicationId", accessToken.getApplicationId());
|
|
212
|
-
tokenObject.put(
|
|
200
|
+
tokenObject.put(
|
|
201
|
+
"declinedPermissions",
|
|
202
|
+
new JSArray(accessToken.getDeclinedPermissions())
|
|
203
|
+
);
|
|
213
204
|
tokenObject.put("expires", accessToken.getExpires().getTime());
|
|
214
205
|
tokenObject.put("isExpired", accessToken.isExpired());
|
|
215
206
|
tokenObject.put("lastRefresh", accessToken.getLastRefresh().getTime());
|
|
@@ -218,4 +209,41 @@ public class FacebookProvider implements SocialProvider {
|
|
|
218
209
|
tokenObject.put("userId", accessToken.getUserId());
|
|
219
210
|
return tokenObject;
|
|
220
211
|
}
|
|
212
|
+
|
|
213
|
+
private JSObject createProfileObject(AccessToken accessToken) {
|
|
214
|
+
JSObject profileObject = new JSObject();
|
|
215
|
+
GraphRequest request = GraphRequest.newMeRequest(
|
|
216
|
+
accessToken,
|
|
217
|
+
new GraphRequest.GraphJSONObjectCallback() {
|
|
218
|
+
@Override
|
|
219
|
+
public void onCompleted(JSONObject object, GraphResponse response) {
|
|
220
|
+
if (response.getError() != null) {
|
|
221
|
+
Log.e(
|
|
222
|
+
LOG_TAG,
|
|
223
|
+
"Error fetching profile",
|
|
224
|
+
response.getError().getException()
|
|
225
|
+
);
|
|
226
|
+
} else {
|
|
227
|
+
profileObject.put("userID", object.optString("id", ""));
|
|
228
|
+
profileObject.put("email", object.optString("email", ""));
|
|
229
|
+
profileObject.put("name", object.optString("name", ""));
|
|
230
|
+
|
|
231
|
+
JSONObject pictureObject = object.optJSONObject("picture");
|
|
232
|
+
if (pictureObject != null) {
|
|
233
|
+
JSONObject dataObject = pictureObject.optJSONObject("data");
|
|
234
|
+
if (dataObject != null) {
|
|
235
|
+
profileObject.put("imageURL", dataObject.optString("url", ""));
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Add other fields as needed
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
);
|
|
243
|
+
Bundle parameters = new Bundle();
|
|
244
|
+
parameters.putString("fields", "id,name,email,picture.type(large)");
|
|
245
|
+
request.setParameters(parameters);
|
|
246
|
+
request.executeAndWait();
|
|
247
|
+
return profileObject;
|
|
248
|
+
}
|
|
221
249
|
}
|
|
@@ -3,8 +3,8 @@ package ee.forgr.capacitor.social.login;
|
|
|
3
3
|
import android.accounts.Account;
|
|
4
4
|
import android.app.Activity;
|
|
5
5
|
import android.content.Context;
|
|
6
|
-
import android.util.Log;
|
|
7
6
|
import android.text.TextUtils;
|
|
7
|
+
import android.util.Log;
|
|
8
8
|
import androidx.credentials.ClearCredentialStateRequest;
|
|
9
9
|
import androidx.credentials.Credential;
|
|
10
10
|
import androidx.credentials.CredentialManager;
|
|
@@ -19,19 +19,18 @@ import com.getcapacitor.JSObject;
|
|
|
19
19
|
import com.getcapacitor.PluginCall;
|
|
20
20
|
import com.google.android.gms.auth.GoogleAuthException;
|
|
21
21
|
import com.google.android.gms.auth.GoogleAuthUtil;
|
|
22
|
-
import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
|
|
23
22
|
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption;
|
|
24
23
|
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;
|
|
25
24
|
import ee.forgr.capacitor.social.login.helpers.SocialProvider;
|
|
26
25
|
import java.io.IOException;
|
|
26
|
+
import java.util.concurrent.Callable;
|
|
27
27
|
import java.util.concurrent.Executor;
|
|
28
|
+
import java.util.concurrent.ExecutorService;
|
|
28
29
|
import java.util.concurrent.Executors;
|
|
30
|
+
import java.util.concurrent.Future;
|
|
29
31
|
import org.json.JSONArray;
|
|
30
32
|
import org.json.JSONException;
|
|
31
33
|
import org.json.JSONObject;
|
|
32
|
-
import java.util.concurrent.ExecutorService;
|
|
33
|
-
import java.util.concurrent.Callable;
|
|
34
|
-
import java.util.concurrent.Future;
|
|
35
34
|
|
|
36
35
|
public class GoogleProvider implements SocialProvider {
|
|
37
36
|
|
|
@@ -91,7 +90,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
String nonce = call.getString("nonce");
|
|
94
|
-
|
|
93
|
+
|
|
95
94
|
// Extract scopes from the config
|
|
96
95
|
JSONArray scopesArray = config.optJSONArray("scopes");
|
|
97
96
|
if (scopesArray != null) {
|
|
@@ -101,7 +100,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
101
100
|
}
|
|
102
101
|
} else {
|
|
103
102
|
// Default scopes if not provided
|
|
104
|
-
this.scopes = new String[]{"profile", "email"};
|
|
103
|
+
this.scopes = new String[] { "profile", "email" };
|
|
105
104
|
}
|
|
106
105
|
|
|
107
106
|
GetSignInWithGoogleOption.Builder googleIdOptionBuilder =
|
|
@@ -111,7 +110,8 @@ public class GoogleProvider implements SocialProvider {
|
|
|
111
110
|
googleIdOptionBuilder.setNonce(nonce);
|
|
112
111
|
}
|
|
113
112
|
|
|
114
|
-
GetSignInWithGoogleOption googleIdOptionFiltered =
|
|
113
|
+
GetSignInWithGoogleOption googleIdOptionFiltered =
|
|
114
|
+
googleIdOptionBuilder.build();
|
|
115
115
|
GetCredentialRequest filteredRequest = new GetCredentialRequest.Builder()
|
|
116
116
|
.addCredentialOption(googleIdOptionFiltered)
|
|
117
117
|
.build();
|
|
@@ -178,37 +178,43 @@ public class GoogleProvider implements SocialProvider {
|
|
|
178
178
|
|
|
179
179
|
// Use ExecutorService to retrieve the access token
|
|
180
180
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
181
|
-
Future<AccessToken> future = executor.submit(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
Future<AccessToken> future = executor.submit(
|
|
182
|
+
new Callable<AccessToken>() {
|
|
183
|
+
@Override
|
|
184
|
+
public AccessToken call() throws Exception {
|
|
185
|
+
return getAccessToken(googleIdTokenCredential);
|
|
186
|
+
}
|
|
185
187
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
executor.execute(
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
executor.execute(
|
|
191
|
+
new Runnable() {
|
|
192
|
+
@Override
|
|
193
|
+
public void run() {
|
|
194
|
+
try {
|
|
195
|
+
AccessToken accessToken = future.get();
|
|
196
|
+
if (accessToken != null) {
|
|
197
|
+
JSObject accessTokenObj = new JSObject();
|
|
198
|
+
accessTokenObj.put("token", accessToken.token);
|
|
199
|
+
accessTokenObj.put("userId", accessToken.userId);
|
|
200
|
+
|
|
201
|
+
resultObj.put("accessToken", accessTokenObj);
|
|
202
|
+
resultObj.put("profile", user);
|
|
203
|
+
response.put("result", resultObj);
|
|
204
|
+
call.resolve(response);
|
|
205
|
+
} else {
|
|
206
|
+
call.reject("Failed to get access token");
|
|
207
|
+
}
|
|
208
|
+
} catch (Exception e) {
|
|
209
|
+
call.reject(
|
|
210
|
+
"Error retrieving access token: " + e.getMessage()
|
|
211
|
+
);
|
|
212
|
+
} finally {
|
|
213
|
+
executor.shutdown();
|
|
204
214
|
}
|
|
205
|
-
} catch (Exception e) {
|
|
206
|
-
call.reject("Error retrieving access token: " + e.getMessage());
|
|
207
|
-
} finally {
|
|
208
|
-
executor.shutdown();
|
|
209
215
|
}
|
|
210
216
|
}
|
|
211
|
-
|
|
217
|
+
);
|
|
212
218
|
|
|
213
219
|
return; // The call will be resolved in the Runnable
|
|
214
220
|
}
|
|
@@ -329,44 +335,6 @@ public class GoogleProvider implements SocialProvider {
|
|
|
329
335
|
);
|
|
330
336
|
}
|
|
331
337
|
|
|
332
|
-
@Override
|
|
333
|
-
public void getCurrentUser(PluginCall call) {
|
|
334
|
-
GetGoogleIdOption googleIdOption = new GetGoogleIdOption.Builder()
|
|
335
|
-
.setFilterByAuthorizedAccounts(true)
|
|
336
|
-
.setServerClientId(this.clientId)
|
|
337
|
-
.build();
|
|
338
|
-
GetCredentialRequest request = new GetCredentialRequest.Builder()
|
|
339
|
-
.addCredentialOption(googleIdOption)
|
|
340
|
-
.build();
|
|
341
|
-
|
|
342
|
-
Executor executor = Executors.newSingleThreadExecutor();
|
|
343
|
-
credentialManager.getCredentialAsync(
|
|
344
|
-
context,
|
|
345
|
-
request,
|
|
346
|
-
null,
|
|
347
|
-
executor,
|
|
348
|
-
new CredentialManagerCallback<
|
|
349
|
-
GetCredentialResponse,
|
|
350
|
-
GetCredentialException
|
|
351
|
-
>() {
|
|
352
|
-
@Override
|
|
353
|
-
public void onResult(GetCredentialResponse result) {
|
|
354
|
-
try {
|
|
355
|
-
JSObject user = handleSignInResult(result);
|
|
356
|
-
call.resolve(user);
|
|
357
|
-
} catch (JSONException e) {
|
|
358
|
-
call.reject("Error creating user object: " + e.getMessage());
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
@Override
|
|
363
|
-
public void onError(GetCredentialException e) {
|
|
364
|
-
call.reject("No current user: " + e.getMessage());
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
338
|
@Override
|
|
371
339
|
public void refresh(PluginCall call) {
|
|
372
340
|
// Implement refresh logic here
|
|
@@ -374,6 +342,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
374
342
|
}
|
|
375
343
|
|
|
376
344
|
private static class AccessToken {
|
|
345
|
+
|
|
377
346
|
String token;
|
|
378
347
|
String userId;
|
|
379
348
|
// Add other fields as needed (expires, isExpired, etc.)
|