@capgo/capacitor-social-login 0.0.68-alpha.2 → 0.0.68-alpha.5
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 +28 -20
- package/android/src/main/java/ee/forgr/capacitor/social/login/GoogleProvider.java +346 -291
- package/android/src/main/java/ee/forgr/capacitor/social/login/SocialLoginPlugin.java +14 -1
- package/dist/docs.json +38 -14
- package/dist/esm/definitions.d.ts +13 -6
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +1 -0
- package/dist/esm/web.js +128 -89
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +128 -89
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +128 -89
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/SocialLoginPlugin/GoogleProvider.swift +36 -7
- package/ios/Sources/SocialLoginPlugin/SocialLoginPlugin.swift +54 -23
- package/package.json +2 -2
|
@@ -80,10 +80,16 @@ public class GoogleProvider implements SocialProvider {
|
|
|
80
80
|
private String clientId;
|
|
81
81
|
private String[] scopes;
|
|
82
82
|
private List<
|
|
83
|
-
CallbackToFutureAdapter.Completer<
|
|
83
|
+
CallbackToFutureAdapter.Completer<AuthorizationResult>
|
|
84
84
|
> futuresList = new ArrayList<>(FUTURE_LIST_LENGTH);
|
|
85
85
|
|
|
86
86
|
private String savedAccessToken = null;
|
|
87
|
+
private GoogleProviderLoginType mode = GoogleProviderLoginType.ONLINE;
|
|
88
|
+
|
|
89
|
+
public enum GoogleProviderLoginType {
|
|
90
|
+
ONLINE,
|
|
91
|
+
OFFLINE,
|
|
92
|
+
}
|
|
87
93
|
|
|
88
94
|
public GoogleProvider(Activity activity, Context context) {
|
|
89
95
|
this.activity = activity;
|
|
@@ -94,9 +100,10 @@ public class GoogleProvider implements SocialProvider {
|
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
102
|
|
|
97
|
-
public void initialize(String clientId) {
|
|
103
|
+
public void initialize(String clientId, GoogleProviderLoginType mode) {
|
|
98
104
|
this.credentialManager = CredentialManager.create(activity);
|
|
99
105
|
this.clientId = clientId;
|
|
106
|
+
this.mode = mode;
|
|
100
107
|
|
|
101
108
|
String data = context
|
|
102
109
|
.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE)
|
|
@@ -216,90 +223,240 @@ public class GoogleProvider implements SocialProvider {
|
|
|
216
223
|
) {
|
|
217
224
|
GoogleIdTokenCredential googleIdTokenCredential =
|
|
218
225
|
GoogleIdTokenCredential.createFrom(credential.getData());
|
|
219
|
-
String idToken = googleIdTokenCredential.getIdToken();
|
|
226
|
+
// String idToken = googleIdTokenCredential.getIdToken();
|
|
220
227
|
// resultObj.put("idToken", idToken);
|
|
221
228
|
|
|
222
229
|
// Use ExecutorService to retrieve the access token
|
|
223
230
|
ExecutorService executor = Executors.newSingleThreadExecutor();
|
|
224
|
-
|
|
231
|
+
JSONObject options = call.getObject("options", new JSObject());
|
|
232
|
+
Boolean forceRefreshToken =
|
|
233
|
+
options != null &&
|
|
234
|
+
options.has("forceRefreshToken") &&
|
|
235
|
+
options.getBoolean("forceRefreshToken");
|
|
236
|
+
ListenableFuture<AuthorizationResult> future = getAuthorizationResult(
|
|
237
|
+
forceRefreshToken
|
|
238
|
+
);
|
|
225
239
|
|
|
226
240
|
executor.execute(
|
|
227
241
|
new Runnable() {
|
|
228
242
|
@Override
|
|
229
243
|
public void run() {
|
|
230
244
|
try {
|
|
231
|
-
AccessToken accessToken = future.get();
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
)
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
245
|
+
// AccessToken accessToken = future.get();
|
|
246
|
+
AuthorizationResult result = future.get();
|
|
247
|
+
if (
|
|
248
|
+
GoogleProvider.this.mode == GoogleProviderLoginType.ONLINE
|
|
249
|
+
) {
|
|
250
|
+
AccessToken accessToken = new AccessToken();
|
|
251
|
+
accessToken.token = result.getAccessToken();
|
|
252
|
+
|
|
253
|
+
OkHttpClient client = new OkHttpClient();
|
|
254
|
+
Request request = new Request.Builder()
|
|
255
|
+
.url(USERINFO_URL)
|
|
256
|
+
.get()
|
|
257
|
+
.addHeader("Authorization", "Bearer " + accessToken.token)
|
|
258
|
+
.build();
|
|
259
|
+
|
|
260
|
+
ListenableFuture<Date> tokenExpiresIn =
|
|
261
|
+
CallbackToFutureAdapter.getFuture(completer -> {
|
|
262
|
+
Request tokenRequest = new Request.Builder()
|
|
263
|
+
.url(
|
|
264
|
+
TOKEN_REQUEST_URL +
|
|
265
|
+
"?" +
|
|
266
|
+
"access_token=" +
|
|
267
|
+
accessToken.token
|
|
268
|
+
)
|
|
269
|
+
.get()
|
|
270
|
+
.build();
|
|
271
|
+
|
|
272
|
+
client
|
|
273
|
+
.newCall(tokenRequest)
|
|
274
|
+
.enqueue(
|
|
275
|
+
new Callback() {
|
|
276
|
+
@Override
|
|
277
|
+
public void onFailure(
|
|
278
|
+
@NonNull Call call,
|
|
279
|
+
@NonNull IOException e
|
|
280
|
+
) {}
|
|
281
|
+
|
|
282
|
+
@Override
|
|
283
|
+
public void onResponse(
|
|
284
|
+
@NonNull Call httpCall,
|
|
285
|
+
@NonNull Response httpResponse
|
|
286
|
+
) throws IOException {
|
|
287
|
+
if (!httpResponse.isSuccessful()) {
|
|
288
|
+
completer.setException(
|
|
289
|
+
new RuntimeException(
|
|
290
|
+
String.format(
|
|
291
|
+
"Invalid response from %s. Response not successful. Status code: %s",
|
|
292
|
+
TOKEN_REQUEST_URL,
|
|
293
|
+
httpResponse.code()
|
|
294
|
+
)
|
|
295
|
+
)
|
|
296
|
+
);
|
|
297
|
+
Log.e(
|
|
298
|
+
LOG_TAG,
|
|
270
299
|
String.format(
|
|
271
300
|
"Invalid response from %s. Response not successful. Status code: %s",
|
|
272
301
|
TOKEN_REQUEST_URL,
|
|
273
302
|
httpResponse.code()
|
|
274
303
|
)
|
|
304
|
+
);
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
ResponseBody responseBody = httpResponse.body();
|
|
309
|
+
if (responseBody == null) {
|
|
310
|
+
completer.setException(
|
|
311
|
+
new RuntimeException(
|
|
312
|
+
String.format(
|
|
313
|
+
"Invalid response from %s. Response body is null",
|
|
314
|
+
TOKEN_REQUEST_URL
|
|
315
|
+
)
|
|
316
|
+
)
|
|
317
|
+
);
|
|
318
|
+
Log.e(
|
|
319
|
+
LOG_TAG,
|
|
320
|
+
String.format(
|
|
321
|
+
"Invalid response from %s. Response body is null",
|
|
322
|
+
TOKEN_REQUEST_URL
|
|
323
|
+
)
|
|
324
|
+
);
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
String responseString = responseBody.string();
|
|
329
|
+
JSONObject jsonObject;
|
|
330
|
+
try {
|
|
331
|
+
jsonObject = (JSONObject) new JSONTokener(
|
|
332
|
+
responseString
|
|
333
|
+
).nextValue();
|
|
334
|
+
} catch (JSONException e) {
|
|
335
|
+
completer.setException(
|
|
336
|
+
new RuntimeException(
|
|
337
|
+
String.format(
|
|
338
|
+
"Invalid response from %s. Response body is not a valid JSON. Error: %s",
|
|
339
|
+
TOKEN_REQUEST_URL,
|
|
340
|
+
e
|
|
341
|
+
)
|
|
342
|
+
)
|
|
343
|
+
);
|
|
344
|
+
Log.e(
|
|
345
|
+
LOG_TAG,
|
|
346
|
+
String.format(
|
|
347
|
+
"Invalid response from %s. Response body is not a valid JSON. Error: %s",
|
|
348
|
+
TOKEN_REQUEST_URL,
|
|
349
|
+
e
|
|
350
|
+
)
|
|
351
|
+
);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
String expiresIn;
|
|
356
|
+
try {
|
|
357
|
+
expiresIn = jsonObject.getString(
|
|
358
|
+
"expires_in"
|
|
359
|
+
);
|
|
360
|
+
} catch (JSONException e) {
|
|
361
|
+
completer.setException(
|
|
362
|
+
new RuntimeException(
|
|
363
|
+
String.format(
|
|
364
|
+
"Invalid response from %s. Response JSON does not include expires_in. Error: %s",
|
|
365
|
+
TOKEN_REQUEST_URL,
|
|
366
|
+
e
|
|
367
|
+
)
|
|
368
|
+
)
|
|
369
|
+
);
|
|
370
|
+
Log.e(
|
|
371
|
+
LOG_TAG,
|
|
372
|
+
String.format(
|
|
373
|
+
"Invalid response from %s. Response JSON does not include expires_in. Error: %s",
|
|
374
|
+
TOKEN_REQUEST_URL,
|
|
375
|
+
e
|
|
376
|
+
)
|
|
377
|
+
);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
int expressInInt;
|
|
382
|
+
try {
|
|
383
|
+
expressInInt = Integer.parseInt(expiresIn);
|
|
384
|
+
} catch (Exception e) {
|
|
385
|
+
completer.setException(
|
|
386
|
+
new RuntimeException(
|
|
387
|
+
String.format(
|
|
388
|
+
"Invalid response from %s. expires_in: %s is not a valid int. Error: %s",
|
|
389
|
+
TOKEN_REQUEST_URL,
|
|
390
|
+
expiresIn,
|
|
391
|
+
e
|
|
392
|
+
)
|
|
393
|
+
)
|
|
394
|
+
);
|
|
395
|
+
Log.e(
|
|
396
|
+
LOG_TAG,
|
|
397
|
+
String.format(
|
|
398
|
+
"Invalid response from %s. expires_in: %s is not a valid int. Error: %s",
|
|
399
|
+
TOKEN_REQUEST_URL,
|
|
400
|
+
expiresIn,
|
|
401
|
+
e
|
|
402
|
+
)
|
|
403
|
+
);
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
Date instant = new Date();
|
|
408
|
+
Calendar calendar = Calendar.getInstance();
|
|
409
|
+
calendar.setTime(instant);
|
|
410
|
+
calendar.add(Calendar.SECOND, expressInInt);
|
|
411
|
+
completer.set(calendar.getTime());
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
);
|
|
415
|
+
|
|
416
|
+
return "TokenExpiresInOperationTag";
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
client
|
|
420
|
+
.newCall(request)
|
|
421
|
+
.enqueue(
|
|
422
|
+
new Callback() {
|
|
423
|
+
@Override
|
|
424
|
+
public void onResponse(
|
|
425
|
+
@NonNull Call httpCall,
|
|
426
|
+
@NonNull Response httpResponse
|
|
427
|
+
) throws IOException {
|
|
428
|
+
try {
|
|
429
|
+
if (!httpResponse.isSuccessful()) {
|
|
430
|
+
call.reject(
|
|
431
|
+
String.format(
|
|
432
|
+
"Invalid response from %s. Response not successful. Status code: %s",
|
|
433
|
+
USERINFO_URL,
|
|
434
|
+
httpResponse.code()
|
|
275
435
|
)
|
|
276
436
|
);
|
|
277
437
|
Log.e(
|
|
278
438
|
LOG_TAG,
|
|
279
439
|
String.format(
|
|
280
440
|
"Invalid response from %s. Response not successful. Status code: %s",
|
|
281
|
-
|
|
441
|
+
USERINFO_URL,
|
|
282
442
|
httpResponse.code()
|
|
283
443
|
)
|
|
284
444
|
);
|
|
285
445
|
return;
|
|
286
446
|
}
|
|
287
|
-
|
|
288
447
|
ResponseBody responseBody = httpResponse.body();
|
|
289
448
|
if (responseBody == null) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
TOKEN_REQUEST_URL
|
|
295
|
-
)
|
|
449
|
+
call.reject(
|
|
450
|
+
String.format(
|
|
451
|
+
"Invalid response from %s. Response body is null",
|
|
452
|
+
USERINFO_URL
|
|
296
453
|
)
|
|
297
454
|
);
|
|
298
455
|
Log.e(
|
|
299
456
|
LOG_TAG,
|
|
300
457
|
String.format(
|
|
301
458
|
"Invalid response from %s. Response body is null",
|
|
302
|
-
|
|
459
|
+
USERINFO_URL
|
|
303
460
|
)
|
|
304
461
|
);
|
|
305
462
|
return;
|
|
@@ -312,258 +469,133 @@ public class GoogleProvider implements SocialProvider {
|
|
|
312
469
|
responseString
|
|
313
470
|
).nextValue();
|
|
314
471
|
} catch (JSONException e) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
e
|
|
321
|
-
)
|
|
472
|
+
call.reject(
|
|
473
|
+
String.format(
|
|
474
|
+
"Invalid response from %s. Response body is not a valid JSON. Error: %s",
|
|
475
|
+
USERINFO_URL,
|
|
476
|
+
e
|
|
322
477
|
)
|
|
323
478
|
);
|
|
324
479
|
Log.e(
|
|
325
480
|
LOG_TAG,
|
|
326
481
|
String.format(
|
|
327
482
|
"Invalid response from %s. Response body is not a valid JSON. Error: %s",
|
|
328
|
-
|
|
483
|
+
USERINFO_URL,
|
|
329
484
|
e
|
|
330
485
|
)
|
|
331
486
|
);
|
|
332
487
|
return;
|
|
333
488
|
}
|
|
334
489
|
|
|
335
|
-
String expiresIn;
|
|
336
490
|
try {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
new RuntimeException(
|
|
341
|
-
String.format(
|
|
342
|
-
"Invalid response from %s. Response JSON does not include expires_in. Error: %s",
|
|
343
|
-
TOKEN_REQUEST_URL,
|
|
344
|
-
e
|
|
345
|
-
)
|
|
346
|
-
)
|
|
491
|
+
String name = jsonObject.getString("name");
|
|
492
|
+
String givenName = jsonObject.getString(
|
|
493
|
+
"given_name"
|
|
347
494
|
);
|
|
348
|
-
|
|
349
|
-
|
|
495
|
+
String familyName = jsonObject.getString(
|
|
496
|
+
"family_name"
|
|
497
|
+
);
|
|
498
|
+
String picture = jsonObject.getString(
|
|
499
|
+
"picture"
|
|
500
|
+
);
|
|
501
|
+
String email = jsonObject.getString("email");
|
|
502
|
+
String sub = jsonObject.getString("sub");
|
|
503
|
+
|
|
504
|
+
// now, let's try to get the expiry
|
|
505
|
+
try {
|
|
506
|
+
Date expiryDate = tokenExpiresIn.get(
|
|
507
|
+
5,
|
|
508
|
+
TimeUnit.SECONDS
|
|
509
|
+
);
|
|
510
|
+
long seconds =
|
|
511
|
+
(expiryDate.getTime() -
|
|
512
|
+
(new Date()).getTime()) /
|
|
513
|
+
1000;
|
|
514
|
+
accessToken.expires = String.valueOf(seconds);
|
|
515
|
+
} catch (
|
|
516
|
+
ExecutionException
|
|
517
|
+
| InterruptedException
|
|
518
|
+
| TimeoutException e
|
|
519
|
+
) {
|
|
520
|
+
Log.e(LOG_TAG, "Cannot get expiry date", e);
|
|
521
|
+
// it's a non-fatal error
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
profile.put("email", email);
|
|
525
|
+
profile.put("familyName", familyName);
|
|
526
|
+
profile.put("givenName", givenName);
|
|
527
|
+
profile.put("id", sub);
|
|
528
|
+
profile.put("name", name);
|
|
529
|
+
profile.put("imageUrl", picture);
|
|
530
|
+
|
|
531
|
+
JSObject accessTokenObj = new JSObject();
|
|
532
|
+
accessTokenObj.put("token", accessToken.token);
|
|
533
|
+
if (accessToken.expires != null) {
|
|
534
|
+
accessTokenObj.put(
|
|
535
|
+
"expires",
|
|
536
|
+
accessToken.expires
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
resultObj.put("accessToken", accessTokenObj);
|
|
541
|
+
resultObj.put("profile", profile);
|
|
542
|
+
response.put("result", resultObj);
|
|
543
|
+
resultObj.put("responseType", "online");
|
|
544
|
+
persistState(accessToken.token);
|
|
545
|
+
call.resolve(response);
|
|
546
|
+
} catch (JSONException e) {
|
|
547
|
+
call.reject(
|
|
350
548
|
String.format(
|
|
351
|
-
"Invalid response from %s.
|
|
352
|
-
|
|
549
|
+
"Invalid response from %s. Could not get some value from JSON. Error: %s",
|
|
550
|
+
USERINFO_URL,
|
|
353
551
|
e
|
|
354
552
|
)
|
|
355
553
|
);
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
int expressInInt;
|
|
360
|
-
try {
|
|
361
|
-
expressInInt = Integer.parseInt(expiresIn);
|
|
362
|
-
} catch (Exception e) {
|
|
363
|
-
completer.setException(
|
|
364
|
-
new RuntimeException(
|
|
365
|
-
String.format(
|
|
366
|
-
"Invalid response from %s. expires_in: %s is not a valid int. Error: %s",
|
|
367
|
-
TOKEN_REQUEST_URL,
|
|
368
|
-
expiresIn,
|
|
369
|
-
e
|
|
370
|
-
)
|
|
371
|
-
)
|
|
372
|
-
);
|
|
373
554
|
Log.e(
|
|
374
555
|
LOG_TAG,
|
|
375
556
|
String.format(
|
|
376
|
-
"Invalid response from %s.
|
|
377
|
-
|
|
378
|
-
expiresIn,
|
|
557
|
+
"Invalid response from %s. Could not get some value from JSON. Error: %s",
|
|
558
|
+
USERINFO_URL,
|
|
379
559
|
e
|
|
380
560
|
)
|
|
381
561
|
);
|
|
382
562
|
return;
|
|
383
563
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
Calendar calendar = Calendar.getInstance();
|
|
387
|
-
calendar.setTime(instant);
|
|
388
|
-
calendar.add(Calendar.SECOND, expressInInt);
|
|
389
|
-
completer.set(calendar.getTime());
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
);
|
|
393
|
-
|
|
394
|
-
return "TokenExpiresInOperationTag";
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
client
|
|
398
|
-
.newCall(request)
|
|
399
|
-
.enqueue(
|
|
400
|
-
new Callback() {
|
|
401
|
-
@Override
|
|
402
|
-
public void onResponse(
|
|
403
|
-
@NonNull Call httpCall,
|
|
404
|
-
@NonNull Response httpResponse
|
|
405
|
-
) throws IOException {
|
|
406
|
-
try {
|
|
407
|
-
if (!httpResponse.isSuccessful()) {
|
|
408
|
-
call.reject(
|
|
409
|
-
String.format(
|
|
410
|
-
"Invalid response from %s. Response not successful. Status code: %s",
|
|
411
|
-
USERINFO_URL,
|
|
412
|
-
httpResponse.code()
|
|
413
|
-
)
|
|
414
|
-
);
|
|
415
|
-
Log.e(
|
|
416
|
-
LOG_TAG,
|
|
417
|
-
String.format(
|
|
418
|
-
"Invalid response from %s. Response not successful. Status code: %s",
|
|
419
|
-
USERINFO_URL,
|
|
420
|
-
httpResponse.code()
|
|
421
|
-
)
|
|
422
|
-
);
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
ResponseBody responseBody = httpResponse.body();
|
|
426
|
-
if (responseBody == null) {
|
|
427
|
-
call.reject(
|
|
428
|
-
String.format(
|
|
429
|
-
"Invalid response from %s. Response body is null",
|
|
430
|
-
USERINFO_URL
|
|
431
|
-
)
|
|
432
|
-
);
|
|
433
|
-
Log.e(
|
|
434
|
-
LOG_TAG,
|
|
435
|
-
String.format(
|
|
436
|
-
"Invalid response from %s. Response body is null",
|
|
437
|
-
USERINFO_URL
|
|
438
|
-
)
|
|
439
|
-
);
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
String responseString = responseBody.string();
|
|
444
|
-
JSONObject jsonObject;
|
|
445
|
-
try {
|
|
446
|
-
jsonObject = (JSONObject) new JSONTokener(
|
|
447
|
-
responseString
|
|
448
|
-
).nextValue();
|
|
449
|
-
} catch (JSONException e) {
|
|
450
|
-
call.reject(
|
|
451
|
-
String.format(
|
|
452
|
-
"Invalid response from %s. Response body is not a valid JSON. Error: %s",
|
|
453
|
-
USERINFO_URL,
|
|
454
|
-
e
|
|
455
|
-
)
|
|
456
|
-
);
|
|
457
|
-
Log.e(
|
|
458
|
-
LOG_TAG,
|
|
459
|
-
String.format(
|
|
460
|
-
"Invalid response from %s. Response body is not a valid JSON. Error: %s",
|
|
461
|
-
USERINFO_URL,
|
|
462
|
-
e
|
|
463
|
-
)
|
|
464
|
-
);
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
try {
|
|
469
|
-
String name = jsonObject.getString("name");
|
|
470
|
-
String givenName = jsonObject.getString(
|
|
471
|
-
"given_name"
|
|
472
|
-
);
|
|
473
|
-
String familyName = jsonObject.getString(
|
|
474
|
-
"family_name"
|
|
475
|
-
);
|
|
476
|
-
String picture = jsonObject.getString("picture");
|
|
477
|
-
String email = jsonObject.getString("email");
|
|
478
|
-
String sub = jsonObject.getString("sub");
|
|
479
|
-
|
|
480
|
-
// now, let's try to get the expiry
|
|
481
|
-
try {
|
|
482
|
-
Date expiryDate = tokenExpiresIn.get(
|
|
483
|
-
5,
|
|
484
|
-
TimeUnit.SECONDS
|
|
485
|
-
);
|
|
486
|
-
long seconds =
|
|
487
|
-
(expiryDate.getTime() -
|
|
488
|
-
(new Date()).getTime()) /
|
|
489
|
-
1000;
|
|
490
|
-
accessToken.expires = String.valueOf(seconds);
|
|
491
|
-
} catch (
|
|
492
|
-
ExecutionException
|
|
493
|
-
| InterruptedException
|
|
494
|
-
| TimeoutException e
|
|
495
|
-
) {
|
|
496
|
-
Log.e(LOG_TAG, "Cannot get expiry date", e);
|
|
497
|
-
// it's a non-fatal error
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
profile.put("email", email);
|
|
501
|
-
profile.put("familyName", familyName);
|
|
502
|
-
profile.put("givenName", givenName);
|
|
503
|
-
profile.put("id", sub);
|
|
504
|
-
profile.put("name", name);
|
|
505
|
-
profile.put("imageUrl", picture);
|
|
506
|
-
|
|
507
|
-
JSObject accessTokenObj = new JSObject();
|
|
508
|
-
accessTokenObj.put("token", accessToken.token);
|
|
509
|
-
if (accessToken.expires != null) {
|
|
510
|
-
accessTokenObj.put(
|
|
511
|
-
"expires",
|
|
512
|
-
accessToken.expires
|
|
513
|
-
);
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
resultObj.put("accessToken", accessTokenObj);
|
|
517
|
-
resultObj.put("profile", profile);
|
|
518
|
-
response.put("result", resultObj);
|
|
519
|
-
persistState(accessToken.token);
|
|
520
|
-
call.resolve(response);
|
|
521
|
-
} catch (JSONException e) {
|
|
522
|
-
call.reject(
|
|
523
|
-
String.format(
|
|
524
|
-
"Invalid response from %s. Could not get some value from JSON. Error: %s",
|
|
525
|
-
USERINFO_URL,
|
|
526
|
-
e
|
|
527
|
-
)
|
|
528
|
-
);
|
|
529
|
-
Log.e(
|
|
530
|
-
LOG_TAG,
|
|
531
|
-
String.format(
|
|
532
|
-
"Invalid response from %s. Could not get some value from JSON. Error: %s",
|
|
533
|
-
USERINFO_URL,
|
|
534
|
-
e
|
|
535
|
-
)
|
|
536
|
-
);
|
|
537
|
-
return;
|
|
564
|
+
} finally {
|
|
565
|
+
httpResponse.close();
|
|
538
566
|
}
|
|
539
|
-
} finally {
|
|
540
|
-
httpResponse.close();
|
|
541
567
|
}
|
|
542
|
-
}
|
|
543
568
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
569
|
+
@Override
|
|
570
|
+
public void onFailure(
|
|
571
|
+
@NonNull Call httpCall,
|
|
572
|
+
@NonNull IOException e
|
|
573
|
+
) {
|
|
574
|
+
call.reject(
|
|
575
|
+
String.format(
|
|
576
|
+
"Invalid response from %s. Error: %s",
|
|
577
|
+
USERINFO_URL,
|
|
578
|
+
e
|
|
579
|
+
)
|
|
580
|
+
);
|
|
581
|
+
Log.e(
|
|
582
|
+
LOG_TAG,
|
|
583
|
+
String.format(
|
|
584
|
+
"Invalid response from %s",
|
|
585
|
+
USERINFO_URL
|
|
586
|
+
),
|
|
553
587
|
e
|
|
554
|
-
)
|
|
555
|
-
|
|
556
|
-
Log.e(
|
|
557
|
-
LOG_TAG,
|
|
558
|
-
String.format(
|
|
559
|
-
"Invalid response from %s",
|
|
560
|
-
USERINFO_URL
|
|
561
|
-
),
|
|
562
|
-
e
|
|
563
|
-
);
|
|
588
|
+
);
|
|
589
|
+
}
|
|
564
590
|
}
|
|
565
|
-
|
|
566
|
-
|
|
591
|
+
);
|
|
592
|
+
} else {
|
|
593
|
+
String serverAuthCode = result.getServerAuthCode();
|
|
594
|
+
resultObj.put("serverAuthCode", serverAuthCode);
|
|
595
|
+
resultObj.put("responseType", "offline");
|
|
596
|
+
response.put("result", resultObj);
|
|
597
|
+
call.resolve(response);
|
|
598
|
+
}
|
|
567
599
|
} catch (Exception e) {
|
|
568
600
|
call.reject(
|
|
569
601
|
"Error retrieving access token: " + e.getMessage()
|
|
@@ -586,7 +618,9 @@ public class GoogleProvider implements SocialProvider {
|
|
|
586
618
|
}
|
|
587
619
|
}
|
|
588
620
|
|
|
589
|
-
private ListenableFuture<
|
|
621
|
+
private ListenableFuture<AuthorizationResult> getAuthorizationResult(
|
|
622
|
+
Boolean forceRefreshToken
|
|
623
|
+
) {
|
|
590
624
|
// Account account = new Account(credential.getId(), "com.google");
|
|
591
625
|
// String scopesString = "oauth2:" + TextUtils.join(" ", this.scopes);
|
|
592
626
|
// String token = GoogleAuthUtil.getToken(
|
|
@@ -602,18 +636,27 @@ public class GoogleProvider implements SocialProvider {
|
|
|
602
636
|
//
|
|
603
637
|
// return accessToken;
|
|
604
638
|
|
|
605
|
-
ListenableFuture<
|
|
606
|
-
completer -> {
|
|
639
|
+
ListenableFuture<AuthorizationResult> future =
|
|
640
|
+
CallbackToFutureAdapter.getFuture(completer -> {
|
|
607
641
|
List<Scope> scopes = Arrays.asList(
|
|
608
642
|
new Scope(Scopes.EMAIL),
|
|
609
643
|
new Scope(Scopes.PROFILE),
|
|
610
644
|
new Scope(Scopes.OPEN_ID)
|
|
611
645
|
);
|
|
646
|
+
AuthorizationRequest.Builder authorizationRequestBuilder =
|
|
647
|
+
AuthorizationRequest.builder().setRequestedScopes(scopes);
|
|
648
|
+
// .requestOfflineAccess(this.clientId)
|
|
649
|
+
|
|
650
|
+
if (GoogleProvider.this.mode == GoogleProviderLoginType.OFFLINE) {
|
|
651
|
+
authorizationRequestBuilder =
|
|
652
|
+
authorizationRequestBuilder.requestOfflineAccess(
|
|
653
|
+
this.clientId,
|
|
654
|
+
forceRefreshToken
|
|
655
|
+
);
|
|
656
|
+
}
|
|
657
|
+
|
|
612
658
|
AuthorizationRequest authorizationRequest =
|
|
613
|
-
|
|
614
|
-
.setRequestedScopes(scopes)
|
|
615
|
-
// .requestOfflineAccess(this.clientId)
|
|
616
|
-
.build();
|
|
659
|
+
authorizationRequestBuilder.build();
|
|
617
660
|
|
|
618
661
|
Identity.getAuthorizationClient(context)
|
|
619
662
|
.authorize(authorizationRequest)
|
|
@@ -677,9 +720,9 @@ public class GoogleProvider implements SocialProvider {
|
|
|
677
720
|
// if (authorizationResult.getServerAuthCode() != null)
|
|
678
721
|
// Log.i("TAG", authorizationResult.getServerAuthCode());
|
|
679
722
|
|
|
680
|
-
AccessToken accessToken = new AccessToken();
|
|
681
|
-
accessToken.token = authorizationResult.getAccessToken();
|
|
682
|
-
completer.set(
|
|
723
|
+
// AccessToken accessToken = new AccessToken();
|
|
724
|
+
// accessToken.token = authorizationResult.getAccessToken();
|
|
725
|
+
completer.set(authorizationResult);
|
|
683
726
|
}
|
|
684
727
|
})
|
|
685
728
|
.addOnFailureListener(e -> {
|
|
@@ -688,8 +731,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
688
731
|
});
|
|
689
732
|
|
|
690
733
|
return "GetAccessTokenOperationTag";
|
|
691
|
-
}
|
|
692
|
-
);
|
|
734
|
+
});
|
|
693
735
|
|
|
694
736
|
return future;
|
|
695
737
|
}
|
|
@@ -710,17 +752,16 @@ public class GoogleProvider implements SocialProvider {
|
|
|
710
752
|
return;
|
|
711
753
|
}
|
|
712
754
|
|
|
713
|
-
CallbackToFutureAdapter.Completer<
|
|
714
|
-
futureIndex
|
|
715
|
-
);
|
|
755
|
+
CallbackToFutureAdapter.Completer<AuthorizationResult> future =
|
|
756
|
+
futuresList.get(futureIndex);
|
|
716
757
|
|
|
717
758
|
try {
|
|
718
759
|
AuthorizationResult authorizationResult = Identity.getAuthorizationClient(
|
|
719
760
|
this.activity
|
|
720
761
|
).getAuthorizationResultFromIntent(data);
|
|
721
|
-
AccessToken accessToken = new AccessToken();
|
|
722
|
-
accessToken.token = authorizationResult.getAccessToken();
|
|
723
|
-
future.set(
|
|
762
|
+
// AccessToken accessToken = new AccessToken();
|
|
763
|
+
// accessToken.token = authorizationResult.getAccessToken();
|
|
764
|
+
future.set(authorizationResult);
|
|
724
765
|
} catch (ApiException e) {
|
|
725
766
|
Log.e(LOG_TAG, "Cannot get getAuthorizationResultFromIntent", e);
|
|
726
767
|
future.setException(
|
|
@@ -772,6 +813,10 @@ public class GoogleProvider implements SocialProvider {
|
|
|
772
813
|
|
|
773
814
|
@Override
|
|
774
815
|
public void logout(PluginCall call) {
|
|
816
|
+
if (this.mode == GoogleProviderLoginType.OFFLINE) {
|
|
817
|
+
call.reject("logout is not implemented when using offline mode");
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
775
820
|
rawLogout(
|
|
776
821
|
new CredentialManagerCallback<Void, Exception>() {
|
|
777
822
|
@Override
|
|
@@ -926,6 +971,12 @@ public class GoogleProvider implements SocialProvider {
|
|
|
926
971
|
|
|
927
972
|
@Override
|
|
928
973
|
public void getAuthorizationCode(PluginCall call) {
|
|
974
|
+
if (this.mode == GoogleProviderLoginType.OFFLINE) {
|
|
975
|
+
call.reject(
|
|
976
|
+
"getAuthorizationCode is not implemented when using offline mode"
|
|
977
|
+
);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
929
980
|
if (GoogleProvider.this.savedAccessToken == null) {
|
|
930
981
|
call.reject("User is not logged in");
|
|
931
982
|
return;
|
|
@@ -969,6 +1020,10 @@ public class GoogleProvider implements SocialProvider {
|
|
|
969
1020
|
|
|
970
1021
|
@Override
|
|
971
1022
|
public void isLoggedIn(PluginCall call) {
|
|
1023
|
+
if (this.mode == GoogleProviderLoginType.OFFLINE) {
|
|
1024
|
+
call.reject("isLoggedIn is not implemented when using offline mode");
|
|
1025
|
+
return;
|
|
1026
|
+
}
|
|
972
1027
|
if (GoogleProvider.this.savedAccessToken == null) {
|
|
973
1028
|
call.resolve(new JSObject().put("isLoggedIn", false));
|
|
974
1029
|
return;
|