@capgo/capacitor-social-login 7.2.3 → 7.4.6
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 +7 -7
- package/android/src/main/java/ee/forgr/capacitor/social/login/GoogleProvider.java +103 -64
- package/dist/docs.json +8 -8
- package/dist/esm/apple-provider.d.ts +17 -0
- package/dist/esm/apple-provider.js +83 -0
- package/dist/esm/apple-provider.js.map +1 -0
- package/dist/esm/base.d.ts +7 -0
- package/dist/esm/base.js +31 -0
- package/dist/esm/base.js.map +1 -0
- package/dist/esm/definitions.d.ts +6 -6
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/facebook-provider.d.ts +15 -0
- package/dist/esm/facebook-provider.js +94 -0
- package/dist/esm/facebook-provider.js.map +1 -0
- package/dist/esm/google-provider.d.ts +28 -0
- package/dist/esm/google-provider.js +350 -0
- package/dist/esm/google-provider.js.map +1 -0
- package/dist/esm/web.d.ts +4 -26
- package/dist/esm/web.js +28 -578
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +433 -432
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +433 -432
- package/dist/plugin.js.map +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -426,13 +426,13 @@ Refresh the access token
|
|
|
426
426
|
|
|
427
427
|
#### GoogleLoginOptions
|
|
428
428
|
|
|
429
|
-
| Prop | Type
|
|
430
|
-
| ----------------------- |
|
|
431
|
-
| **`scopes`** | <code>string[]</code>
|
|
432
|
-
| **`nonce`** | <code>string</code>
|
|
433
|
-
| **`forceRefreshToken`** | <code>boolean</code>
|
|
434
|
-
| **`
|
|
435
|
-
| **`
|
|
429
|
+
| Prop | Type | Description | Default |
|
|
430
|
+
| ----------------------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
431
|
+
| **`scopes`** | <code>string[]</code> | Specifies the scopes required for accessing Google APIs The default is defined in the configuration. | |
|
|
432
|
+
| **`nonce`** | <code>string</code> | Nonce | |
|
|
433
|
+
| **`forceRefreshToken`** | <code>boolean</code> | Force refresh token (only for Android) | <code>false</code> |
|
|
434
|
+
| **`forcePrompt`** | <code>boolean</code> | Force account selection prompt (iOS) | <code>false</code> |
|
|
435
|
+
| **`style`** | <code>'bottom' \| 'standard'</code> | Style | <code>'standard'</code> |
|
|
436
436
|
|
|
437
437
|
|
|
438
438
|
#### AppleProviderOptions
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
package ee.forgr.capacitor.social.login;
|
|
2
2
|
|
|
3
|
-
import android.accounts.Account;
|
|
4
3
|
import android.app.Activity;
|
|
5
4
|
import android.app.PendingIntent;
|
|
6
5
|
import android.content.Context;
|
|
7
6
|
import android.content.Intent;
|
|
8
7
|
import android.content.IntentSender;
|
|
9
|
-
import android.text.TextUtils;
|
|
10
8
|
import android.util.Log;
|
|
11
9
|
import androidx.annotation.NonNull;
|
|
12
10
|
import androidx.concurrent.futures.CallbackToFutureAdapter;
|
|
@@ -22,13 +20,12 @@ import androidx.credentials.exceptions.GetCredentialException;
|
|
|
22
20
|
import androidx.credentials.exceptions.NoCredentialException;
|
|
23
21
|
import com.getcapacitor.JSObject;
|
|
24
22
|
import com.getcapacitor.PluginCall;
|
|
25
|
-
import com.google.android.gms.auth.GoogleAuthException;
|
|
26
|
-
import com.google.android.gms.auth.GoogleAuthUtil;
|
|
27
23
|
import com.google.android.gms.auth.api.identity.AuthorizationRequest;
|
|
28
24
|
import com.google.android.gms.auth.api.identity.AuthorizationResult;
|
|
29
25
|
import com.google.android.gms.auth.api.identity.Identity;
|
|
30
26
|
import com.google.android.gms.common.api.ApiException;
|
|
31
27
|
import com.google.android.gms.common.api.Scope;
|
|
28
|
+
import com.google.android.libraries.identity.googleid.GetGoogleIdOption;
|
|
32
29
|
import com.google.android.libraries.identity.googleid.GetSignInWithGoogleOption;
|
|
33
30
|
import com.google.android.libraries.identity.googleid.GoogleIdTokenCredential;
|
|
34
31
|
import com.google.common.util.concurrent.ListenableFuture;
|
|
@@ -37,12 +34,11 @@ import java.io.IOException;
|
|
|
37
34
|
import java.util.ArrayList;
|
|
38
35
|
import java.util.HashSet;
|
|
39
36
|
import java.util.List;
|
|
37
|
+
import java.util.Objects;
|
|
40
38
|
import java.util.Set;
|
|
41
|
-
import java.util.concurrent.Callable;
|
|
42
39
|
import java.util.concurrent.Executor;
|
|
43
40
|
import java.util.concurrent.ExecutorService;
|
|
44
41
|
import java.util.concurrent.Executors;
|
|
45
|
-
import java.util.concurrent.Future;
|
|
46
42
|
import java.util.concurrent.TimeUnit;
|
|
47
43
|
import okhttp3.Call;
|
|
48
44
|
import okhttp3.Callback;
|
|
@@ -71,7 +67,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
71
67
|
private CredentialManager credentialManager;
|
|
72
68
|
private String clientId;
|
|
73
69
|
private String[] scopes;
|
|
74
|
-
private List<CallbackToFutureAdapter.Completer<AuthorizationResult>> futuresList = new ArrayList<>(FUTURE_LIST_LENGTH);
|
|
70
|
+
private final List<CallbackToFutureAdapter.Completer<AuthorizationResult>> futuresList = new ArrayList<>(FUTURE_LIST_LENGTH);
|
|
75
71
|
|
|
76
72
|
private String idToken = null;
|
|
77
73
|
private String accessToken = null;
|
|
@@ -202,7 +198,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
202
198
|
return;
|
|
203
199
|
}
|
|
204
200
|
|
|
205
|
-
|
|
201
|
+
int expressInInt;
|
|
206
202
|
try {
|
|
207
203
|
expressInInt = Integer.parseInt(expiresIn);
|
|
208
204
|
} catch (Exception e) {
|
|
@@ -263,9 +259,9 @@ public class GoogleProvider implements SocialProvider {
|
|
|
263
259
|
}
|
|
264
260
|
|
|
265
261
|
public String arrayFind(String[] array, String search) {
|
|
266
|
-
for (
|
|
267
|
-
if (
|
|
268
|
-
return
|
|
262
|
+
for (String s : array) {
|
|
263
|
+
if (s.equals(search)) {
|
|
264
|
+
return s;
|
|
269
265
|
}
|
|
270
266
|
}
|
|
271
267
|
return null;
|
|
@@ -284,69 +280,89 @@ public class GoogleProvider implements SocialProvider {
|
|
|
284
280
|
}
|
|
285
281
|
|
|
286
282
|
String nonce = config.optString("nonce");
|
|
283
|
+
JSONObject options = call.getObject("options", new JSObject());
|
|
284
|
+
boolean bottomUi = false;
|
|
285
|
+
boolean forcePrompt = false;
|
|
286
|
+
boolean filterByAuthorizedAccounts = false;
|
|
287
|
+
boolean autoSelectEnabled = false;
|
|
287
288
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
for (int i = 0; i < scopesArray.length(); i++) {
|
|
295
|
-
uniqueScopes.add(scopesArray.optString(i));
|
|
289
|
+
try {
|
|
290
|
+
if (options != null) {
|
|
291
|
+
bottomUi = options.has("style") && Objects.equals(options.getString("style"), "bottom");
|
|
292
|
+
filterByAuthorizedAccounts = options.has("filterByAuthorizedAccounts") && options.getBoolean("filterByAuthorizedAccounts");
|
|
293
|
+
autoSelectEnabled = options.has("autoSelectEnabled") && options.getBoolean("autoSelectEnabled");
|
|
294
|
+
forcePrompt = options.has("forcePrompt") && options.getBoolean("forcePrompt");
|
|
296
295
|
}
|
|
297
|
-
|
|
296
|
+
} catch (JSONException e) {
|
|
297
|
+
Log.e(LOG_TAG, "Error parsing options", e);
|
|
298
|
+
call.reject("Error parsing options: " + e.getMessage());
|
|
299
|
+
return;
|
|
298
300
|
}
|
|
301
|
+
|
|
302
|
+
// Handle scopes
|
|
303
|
+
JSONArray scopesArray = config.optJSONArray("scopes");
|
|
304
|
+
Set<String> uniqueScopes = new HashSet<>();
|
|
305
|
+
|
|
306
|
+
// Add default scopes
|
|
307
|
+
uniqueScopes.add("https://www.googleapis.com/auth/userinfo.email");
|
|
308
|
+
uniqueScopes.add("https://www.googleapis.com/auth/userinfo.profile");
|
|
309
|
+
uniqueScopes.add("openid");
|
|
310
|
+
|
|
311
|
+
// Add custom scopes if provided
|
|
299
312
|
if (scopesArray != null) {
|
|
300
313
|
if (!(this.activity instanceof ModifiedMainActivityForSocialLoginPlugin)) {
|
|
301
314
|
call.reject("You CANNOT use scopes without modifying the main activity. Please follow the docs!");
|
|
302
315
|
return;
|
|
303
316
|
}
|
|
304
|
-
|
|
305
|
-
this.scopes = new String[scopesArray.length()];
|
|
306
317
|
for (int i = 0; i < scopesArray.length(); i++) {
|
|
307
|
-
|
|
318
|
+
uniqueScopes.add(scopesArray.optString(i));
|
|
308
319
|
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
this.scopes = uniqueScopes.toArray(new String[0]);
|
|
323
|
+
|
|
324
|
+
// Build credential request
|
|
325
|
+
GetCredentialRequest.Builder requestBuilder = new GetCredentialRequest.Builder();
|
|
309
326
|
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
327
|
+
if (bottomUi) {
|
|
328
|
+
Log.e(LOG_TAG, "use bottomUi");
|
|
329
|
+
GetGoogleIdOption.Builder googleIdOptionBuilder = new GetGoogleIdOption.Builder().setServerClientId(this.clientId);
|
|
330
|
+
// Handle bottom UI specific options
|
|
331
|
+
if (forcePrompt) {
|
|
332
|
+
filterByAuthorizedAccounts = false;
|
|
333
|
+
autoSelectEnabled = false;
|
|
315
334
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
newScopes[this.scopes.length] = "https://www.googleapis.com/auth/userinfo.profile";
|
|
320
|
-
this.scopes = newScopes;
|
|
335
|
+
|
|
336
|
+
if (!nonce.isEmpty()) {
|
|
337
|
+
googleIdOptionBuilder.setNonce(nonce);
|
|
321
338
|
}
|
|
322
|
-
if (
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
339
|
+
if (filterByAuthorizedAccounts) {
|
|
340
|
+
googleIdOptionBuilder.setFilterByAuthorizedAccounts(true);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
if (autoSelectEnabled) {
|
|
344
|
+
googleIdOptionBuilder.setAutoSelectEnabled(true);
|
|
327
345
|
}
|
|
328
|
-
} else {
|
|
329
|
-
// Default scopes if not provided
|
|
330
|
-
this.scopes = new String[] {
|
|
331
|
-
"https://www.googleapis.com/auth/userinfo.profile",
|
|
332
|
-
"https://www.googleapis.com/auth/userinfo.email",
|
|
333
|
-
"openid"
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
346
|
|
|
337
|
-
|
|
347
|
+
GetGoogleIdOption googleIdOptionFiltered = googleIdOptionBuilder.build();
|
|
348
|
+
requestBuilder.addCredentialOption(googleIdOptionFiltered);
|
|
349
|
+
} else {
|
|
350
|
+
// For standard UI, we don't use these options
|
|
351
|
+
GetSignInWithGoogleOption.Builder googleIdOptionBuilder = new GetSignInWithGoogleOption.Builder(this.clientId);
|
|
338
352
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
353
|
+
if (!nonce.isEmpty()) {
|
|
354
|
+
googleIdOptionBuilder.setNonce(nonce);
|
|
355
|
+
}
|
|
356
|
+
if (this.hostedDomain != null && !this.hostedDomain.isEmpty()) {
|
|
357
|
+
googleIdOptionBuilder.setHostedDomainFilter(this.hostedDomain);
|
|
358
|
+
}
|
|
342
359
|
|
|
343
|
-
|
|
344
|
-
googleIdOptionBuilder.setHostedDomainFilter(this.hostedDomain);
|
|
360
|
+
requestBuilder.addCredentialOption(googleIdOptionBuilder.build());
|
|
345
361
|
}
|
|
346
362
|
|
|
347
|
-
|
|
348
|
-
GetCredentialRequest filteredRequest = new GetCredentialRequest.Builder().addCredentialOption(googleIdOptionFiltered).build();
|
|
363
|
+
GetCredentialRequest filteredRequest = requestBuilder.build();
|
|
349
364
|
|
|
365
|
+
// Execute credential request
|
|
350
366
|
Executor executor = Executors.newSingleThreadExecutor();
|
|
351
367
|
credentialManager.getCredentialAsync(
|
|
352
368
|
context,
|
|
@@ -360,8 +376,8 @@ public class GoogleProvider implements SocialProvider {
|
|
|
360
376
|
}
|
|
361
377
|
|
|
362
378
|
@Override
|
|
363
|
-
public void onError(GetCredentialException e) {
|
|
364
|
-
handleSignInError(e, call);
|
|
379
|
+
public void onError(@NonNull GetCredentialException e) {
|
|
380
|
+
handleSignInError(e, call, config);
|
|
365
381
|
}
|
|
366
382
|
}
|
|
367
383
|
);
|
|
@@ -400,8 +416,8 @@ public class GoogleProvider implements SocialProvider {
|
|
|
400
416
|
|
|
401
417
|
ListenableFuture<AuthorizationResult> future = CallbackToFutureAdapter.getFuture(completer -> {
|
|
402
418
|
List<Scope> scopes = new ArrayList<>(this.scopes.length);
|
|
403
|
-
for (
|
|
404
|
-
scopes.add(new Scope(
|
|
419
|
+
for (String scope : this.scopes) {
|
|
420
|
+
scopes.add(new Scope(scope));
|
|
405
421
|
}
|
|
406
422
|
AuthorizationRequest.Builder authorizationRequestBuilder = AuthorizationRequest.builder().setRequestedScopes(scopes);
|
|
407
423
|
// .requestOfflineAccess(this.clientId)
|
|
@@ -495,8 +511,12 @@ public class GoogleProvider implements SocialProvider {
|
|
|
495
511
|
JSObject resultObj = new JSObject();
|
|
496
512
|
|
|
497
513
|
JSONObject options = call.getObject("options", new JSObject());
|
|
498
|
-
Boolean forceRefreshToken =
|
|
499
|
-
|
|
514
|
+
Boolean forceRefreshToken = false;
|
|
515
|
+
try {
|
|
516
|
+
forceRefreshToken = options != null && options.has("forceRefreshToken") && options.getBoolean("forceRefreshToken");
|
|
517
|
+
} catch (JSONException e) {
|
|
518
|
+
Log.e(LOG_TAG, "Error parsing forceRefreshToken option", e);
|
|
519
|
+
}
|
|
500
520
|
|
|
501
521
|
GoogleIdTokenCredential googleIdTokenCredential = GoogleIdTokenCredential.createFrom(credential.getData());
|
|
502
522
|
ListenableFuture<AuthorizationResult> future = getAuthorizationResult(forceRefreshToken);
|
|
@@ -583,10 +603,29 @@ public class GoogleProvider implements SocialProvider {
|
|
|
583
603
|
}
|
|
584
604
|
}
|
|
585
605
|
|
|
586
|
-
private void handleSignInError(GetCredentialException e, PluginCall call) {
|
|
606
|
+
private void handleSignInError(GetCredentialException e, PluginCall call, JSONObject config) {
|
|
587
607
|
Log.e(LOG_TAG, "Google Sign-In failed", e);
|
|
588
|
-
|
|
589
|
-
|
|
608
|
+
boolean isBottomUi = false;
|
|
609
|
+
JSONObject options = call.getObject("options", new JSObject());
|
|
610
|
+
if (options.has("style")) {
|
|
611
|
+
try {
|
|
612
|
+
isBottomUi = options.getString("style").equals("bottom");
|
|
613
|
+
} catch (JSONException ex) {
|
|
614
|
+
// do nothing
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
if (e instanceof NoCredentialException && isBottomUi) {
|
|
618
|
+
Log.e(LOG_TAG, "No Google accounts available or miss configuration using bottomUi, auto switch to standard UI");
|
|
619
|
+
// During the get credential flow, this is returned when no viable credential is available for the the user. This can be caused by various scenarios such as that the user doesn't have any credential or the user doesn't grant consent to using any available credential. Upon this exception, your app should navigate to use the regular app sign-up or sign-in screen.
|
|
620
|
+
// https://developer.android.com/reference/androidx/credentials/exceptions/NoCredentialException
|
|
621
|
+
try {
|
|
622
|
+
options.put("style", "standard");
|
|
623
|
+
call.getData().put("options", options);
|
|
624
|
+
} catch (JSONException ex) {
|
|
625
|
+
call.reject("Google Sign-In failed: " + ex.getMessage());
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
login(call, config);
|
|
590
629
|
} else {
|
|
591
630
|
call.reject("Google Sign-In failed: " + e.getMessage());
|
|
592
631
|
}
|
|
@@ -656,7 +695,7 @@ public class GoogleProvider implements SocialProvider {
|
|
|
656
695
|
}
|
|
657
696
|
|
|
658
697
|
@Override
|
|
659
|
-
public void onError(ClearCredentialException e) {
|
|
698
|
+
public void onError(@NonNull ClearCredentialException e) {
|
|
660
699
|
Log.e(LOG_TAG, "Failed to clear credential state", e);
|
|
661
700
|
handler.onError(e);
|
|
662
701
|
}
|
package/dist/docs.json
CHANGED
|
@@ -478,10 +478,10 @@
|
|
|
478
478
|
"type": "boolean | undefined"
|
|
479
479
|
},
|
|
480
480
|
{
|
|
481
|
-
"name": "
|
|
481
|
+
"name": "forcePrompt",
|
|
482
482
|
"tags": [
|
|
483
483
|
{
|
|
484
|
-
"text": "
|
|
484
|
+
"text": "forces the account selection prompt to appear on iOS",
|
|
485
485
|
"name": "description"
|
|
486
486
|
},
|
|
487
487
|
{
|
|
@@ -489,25 +489,25 @@
|
|
|
489
489
|
"name": "default"
|
|
490
490
|
}
|
|
491
491
|
],
|
|
492
|
-
"docs": "
|
|
492
|
+
"docs": "Force account selection prompt (iOS)",
|
|
493
493
|
"complexTypes": [],
|
|
494
494
|
"type": "boolean | undefined"
|
|
495
495
|
},
|
|
496
496
|
{
|
|
497
|
-
"name": "
|
|
497
|
+
"name": "style",
|
|
498
498
|
"tags": [
|
|
499
499
|
{
|
|
500
|
-
"text": "
|
|
500
|
+
"text": "style",
|
|
501
501
|
"name": "description"
|
|
502
502
|
},
|
|
503
503
|
{
|
|
504
|
-
"text": "
|
|
504
|
+
"text": "'standard'",
|
|
505
505
|
"name": "default"
|
|
506
506
|
}
|
|
507
507
|
],
|
|
508
|
-
"docs": "
|
|
508
|
+
"docs": "Style",
|
|
509
509
|
"complexTypes": [],
|
|
510
|
-
"type": "
|
|
510
|
+
"type": "'bottom' | 'standard' | undefined"
|
|
511
511
|
}
|
|
512
512
|
]
|
|
513
513
|
},
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseSocialLogin } from './base';
|
|
2
|
+
import type { AppleProviderOptions, AuthorizationCode, LoginResult } from './definitions';
|
|
3
|
+
export declare class AppleSocialLogin extends BaseSocialLogin {
|
|
4
|
+
private clientId;
|
|
5
|
+
private redirectUrl;
|
|
6
|
+
private scriptLoaded;
|
|
7
|
+
private scriptUrl;
|
|
8
|
+
initialize(clientId: string | null, redirectUrl: string | null | undefined): Promise<void>;
|
|
9
|
+
login(options: AppleProviderOptions): Promise<LoginResult>;
|
|
10
|
+
logout(): Promise<void>;
|
|
11
|
+
isLoggedIn(): Promise<{
|
|
12
|
+
isLoggedIn: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
getAuthorizationCode(): Promise<AuthorizationCode>;
|
|
15
|
+
refresh(): Promise<void>;
|
|
16
|
+
private loadAppleScript;
|
|
17
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { BaseSocialLogin } from './base';
|
|
2
|
+
export class AppleSocialLogin extends BaseSocialLogin {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
this.clientId = null;
|
|
6
|
+
this.redirectUrl = null;
|
|
7
|
+
this.scriptLoaded = false;
|
|
8
|
+
this.scriptUrl = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
|
|
9
|
+
}
|
|
10
|
+
async initialize(clientId, redirectUrl) {
|
|
11
|
+
this.clientId = clientId;
|
|
12
|
+
this.redirectUrl = redirectUrl || null;
|
|
13
|
+
if (clientId) {
|
|
14
|
+
await this.loadAppleScript();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async login(options) {
|
|
18
|
+
if (!this.clientId) {
|
|
19
|
+
throw new Error('Apple Client ID not set. Call initialize() first.');
|
|
20
|
+
}
|
|
21
|
+
if (!this.scriptLoaded) {
|
|
22
|
+
throw new Error('Apple Sign-In script not loaded.');
|
|
23
|
+
}
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
var _a;
|
|
26
|
+
AppleID.auth.init({
|
|
27
|
+
clientId: this.clientId,
|
|
28
|
+
scope: ((_a = options.scopes) === null || _a === void 0 ? void 0 : _a.join(' ')) || 'name email',
|
|
29
|
+
redirectURI: this.redirectUrl || window.location.href,
|
|
30
|
+
state: options.state,
|
|
31
|
+
nonce: options.nonce,
|
|
32
|
+
usePopup: true,
|
|
33
|
+
});
|
|
34
|
+
AppleID.auth
|
|
35
|
+
.signIn()
|
|
36
|
+
.then((res) => {
|
|
37
|
+
var _a, _b, _c, _d, _e;
|
|
38
|
+
const result = {
|
|
39
|
+
profile: {
|
|
40
|
+
user: res.user || '',
|
|
41
|
+
email: ((_a = res.user) === null || _a === void 0 ? void 0 : _a.email) || null,
|
|
42
|
+
givenName: ((_c = (_b = res.user) === null || _b === void 0 ? void 0 : _b.name) === null || _c === void 0 ? void 0 : _c.firstName) || null,
|
|
43
|
+
familyName: ((_e = (_d = res.user) === null || _d === void 0 ? void 0 : _d.name) === null || _e === void 0 ? void 0 : _e.lastName) || null,
|
|
44
|
+
},
|
|
45
|
+
accessToken: {
|
|
46
|
+
token: res.authorization.id_token || '',
|
|
47
|
+
},
|
|
48
|
+
idToken: res.authorization.code || null,
|
|
49
|
+
};
|
|
50
|
+
resolve({ provider: 'apple', result });
|
|
51
|
+
})
|
|
52
|
+
.catch((error) => {
|
|
53
|
+
reject(error);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
async logout() {
|
|
58
|
+
// Apple doesn't provide a logout method for web
|
|
59
|
+
console.log('Apple logout: Session should be managed on the client side');
|
|
60
|
+
}
|
|
61
|
+
async isLoggedIn() {
|
|
62
|
+
// Apple doesn't provide a method to check login status on web
|
|
63
|
+
console.log('Apple login status should be managed on the client side');
|
|
64
|
+
return { isLoggedIn: false };
|
|
65
|
+
}
|
|
66
|
+
async getAuthorizationCode() {
|
|
67
|
+
// Apple authorization code should be obtained during login
|
|
68
|
+
console.log('Apple authorization code should be stored during login');
|
|
69
|
+
throw new Error('Apple authorization code not available');
|
|
70
|
+
}
|
|
71
|
+
async refresh() {
|
|
72
|
+
// Apple doesn't provide a refresh method for web
|
|
73
|
+
console.log('Apple refresh not available on web');
|
|
74
|
+
}
|
|
75
|
+
async loadAppleScript() {
|
|
76
|
+
if (this.scriptLoaded)
|
|
77
|
+
return;
|
|
78
|
+
return this.loadScript(this.scriptUrl).then(() => {
|
|
79
|
+
this.scriptLoaded = true;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=apple-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apple-provider.js","sourceRoot":"","sources":["../../src/apple-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { BaseSocialLogin } from './base';\nimport type { AppleProviderOptions, AppleProviderResponse, AuthorizationCode, LoginResult } from './definitions';\n\ndeclare const AppleID: any;\n\nexport class AppleSocialLogin extends BaseSocialLogin {\n private clientId: string | null = null;\n private redirectUrl: string | null = null;\n private scriptLoaded = false;\n private scriptUrl = 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';\n\n async initialize(clientId: string | null, redirectUrl: string | null | undefined): Promise<void> {\n this.clientId = clientId;\n this.redirectUrl = redirectUrl || null;\n\n if (clientId) {\n await this.loadAppleScript();\n }\n }\n\n async login(options: AppleProviderOptions): Promise<LoginResult> {\n if (!this.clientId) {\n throw new Error('Apple Client ID not set. Call initialize() first.');\n }\n\n if (!this.scriptLoaded) {\n throw new Error('Apple Sign-In script not loaded.');\n }\n\n return new Promise((resolve, reject) => {\n AppleID.auth.init({\n clientId: this.clientId!,\n scope: options.scopes?.join(' ') || 'name email',\n redirectURI: this.redirectUrl || window.location.href,\n state: options.state,\n nonce: options.nonce,\n usePopup: true,\n });\n\n AppleID.auth\n .signIn()\n .then((res: any) => {\n const result: AppleProviderResponse = {\n profile: {\n user: res.user || '',\n email: res.user?.email || null,\n givenName: res.user?.name?.firstName || null,\n familyName: res.user?.name?.lastName || null,\n },\n accessToken: {\n token: res.authorization.id_token || '',\n },\n idToken: res.authorization.code || null,\n };\n resolve({ provider: 'apple', result });\n })\n .catch((error: any) => {\n reject(error);\n });\n });\n }\n\n async logout(): Promise<void> {\n // Apple doesn't provide a logout method for web\n console.log('Apple logout: Session should be managed on the client side');\n }\n\n async isLoggedIn(): Promise<{ isLoggedIn: boolean }> {\n // Apple doesn't provide a method to check login status on web\n console.log('Apple login status should be managed on the client side');\n return { isLoggedIn: false };\n }\n\n async getAuthorizationCode(): Promise<AuthorizationCode> {\n // Apple authorization code should be obtained during login\n console.log('Apple authorization code should be stored during login');\n throw new Error('Apple authorization code not available');\n }\n\n async refresh(): Promise<void> {\n // Apple doesn't provide a refresh method for web\n console.log('Apple refresh not available on web');\n }\n\n private async loadAppleScript(): Promise<void> {\n if (this.scriptLoaded) return;\n\n return this.loadScript(this.scriptUrl).then(() => {\n this.scriptLoaded = true;\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
export declare class BaseSocialLogin extends WebPlugin {
|
|
3
|
+
protected static readonly OAUTH_STATE_KEY = "social_login_oauth_pending";
|
|
4
|
+
constructor();
|
|
5
|
+
protected parseJwt(token: string): any;
|
|
6
|
+
protected loadScript(src: string): Promise<void>;
|
|
7
|
+
}
|
package/dist/esm/base.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
export class BaseSocialLogin extends WebPlugin {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
}
|
|
6
|
+
parseJwt(token) {
|
|
7
|
+
const base64Url = token.split('.')[1];
|
|
8
|
+
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
|
9
|
+
const jsonPayload = decodeURIComponent(atob(base64)
|
|
10
|
+
.split('')
|
|
11
|
+
.map((c) => {
|
|
12
|
+
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
|
13
|
+
})
|
|
14
|
+
.join(''));
|
|
15
|
+
return JSON.parse(jsonPayload);
|
|
16
|
+
}
|
|
17
|
+
async loadScript(src) {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
const script = document.createElement('script');
|
|
20
|
+
script.src = src;
|
|
21
|
+
script.async = true;
|
|
22
|
+
script.onload = () => {
|
|
23
|
+
resolve();
|
|
24
|
+
};
|
|
25
|
+
script.onerror = reject;
|
|
26
|
+
document.body.appendChild(script);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
BaseSocialLogin.OAUTH_STATE_KEY = 'social_login_oauth_pending';
|
|
31
|
+
//# sourceMappingURL=base.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,eAAgB,SAAQ,SAAS;IAG5C;QACE,KAAK,EAAE,CAAC;IACV,CAAC;IAES,QAAQ,CAAC,KAAa;QAC9B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,WAAW,GAAG,kBAAkB,CACpC,IAAI,CAAC,MAAM,CAAC;aACT,KAAK,CAAC,EAAE,CAAC;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACT,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC,CAAC;aACD,IAAI,CAAC,EAAE,CAAC,CACZ,CAAC;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACjC,CAAC;IAES,KAAK,CAAC,UAAU,CAAC,GAAW;QACpC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC;YACjB,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC;YACpB,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE;gBACnB,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC;YACF,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC;YACxB,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;;AA/ByB,+BAAe,GAAG,4BAA4B,CAAC","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nexport class BaseSocialLogin extends WebPlugin {\n protected static readonly OAUTH_STATE_KEY = 'social_login_oauth_pending';\n\n constructor() {\n super();\n }\n\n protected parseJwt(token: string): any {\n const base64Url = token.split('.')[1];\n const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');\n const jsonPayload = decodeURIComponent(\n atob(base64)\n .split('')\n .map((c) => {\n return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n })\n .join(''),\n );\n return JSON.parse(jsonPayload);\n }\n\n protected async loadScript(src: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src = src;\n script.async = true;\n script.onload = () => {\n resolve();\n };\n script.onerror = reject;\n document.body.appendChild(script);\n });\n }\n}\n"]}
|
|
@@ -91,18 +91,18 @@ export interface GoogleLoginOptions {
|
|
|
91
91
|
* @default false
|
|
92
92
|
*/
|
|
93
93
|
forceRefreshToken?: boolean;
|
|
94
|
-
/**
|
|
95
|
-
* Disable one-tap login (web only)
|
|
96
|
-
* @description disable one-tap login
|
|
97
|
-
* @default false
|
|
98
|
-
*/
|
|
99
|
-
disableOneTap?: boolean;
|
|
100
94
|
/**
|
|
101
95
|
* Force account selection prompt (iOS)
|
|
102
96
|
* @description forces the account selection prompt to appear on iOS
|
|
103
97
|
* @default false
|
|
104
98
|
*/
|
|
105
99
|
forcePrompt?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Style
|
|
102
|
+
* @description style
|
|
103
|
+
* @default 'standard'
|
|
104
|
+
*/
|
|
105
|
+
style?: 'bottom' | 'standard';
|
|
106
106
|
}
|
|
107
107
|
export interface GoogleLoginResponseOnline {
|
|
108
108
|
accessToken: AccessToken | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitializeOptions {\n facebook?: {\n /**\n * Facebook App ID, provided by Facebook for web, in mobile it's set in the native files\n */\n appId: string;\n /**\n * Facebook Client Token, provided by Facebook for web, in mobile it's set in the native files\n */\n clientToken: string;\n };\n\n google?: {\n /**\n * The app's client ID, found and created in the Google Developers Console.\n * For iOS.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSClientId?: string;\n /**\n * The app's server client ID, required for offline mode, found and created in the Google Developers Console.\n * For iOS.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSServerClientId?: string;\n /**\n * The app's web client ID, found and created in the Google Developers Console.\n * For Android (and web in the future).\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n webClientId?: string;\n /**\n * The login mode, can be online or offline. In offline mode, the user will be able to login without an internet connection. It requires iOSServerClientId to be set.\n * @example offline\n * @since 3.1.0\n */\n mode?: 'online' | 'offline';\n /**\n * Filter visible accounts by hosted domain\n * @description filter visible accounts by hosted domain\n */\n hostedDomain?: string;\n };\n apple?: {\n /**\n * Apple Client ID, provided by Apple for web and Android\n */\n clientId?: string;\n /**\n * Apple Redirect URL, should be your backend url that is configured in your apple app, only for android\n */\n redirectUrl?: string;\n };\n}\n\nexport interface FacebookLoginOptions {\n /**\n * Permissions\n * @description select permissions to login with\n */\n permissions: string[];\n /**\n * Is Limited Login\n * @description use limited login for Facebook IOS\n * @default false\n */\n limitedLogin?: boolean;\n /**\n * Nonce\n * @description A custom nonce to use for the login request\n */\n nonce?: string;\n}\n\nexport interface GoogleLoginOptions {\n /**\n * Specifies the scopes required for accessing Google APIs\n * The default is defined in the configuration.\n * @example [\"profile\", \"email\"]\n * @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes)\n */\n scopes?: string[];\n /**\n * Nonce\n * @description nonce\n */\n nonce?: string;\n /**\n * Force refresh token (only for Android)\n * @description force refresh token\n * @default false\n */\n forceRefreshToken?: boolean;\n /**\n *
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitializeOptions {\n facebook?: {\n /**\n * Facebook App ID, provided by Facebook for web, in mobile it's set in the native files\n */\n appId: string;\n /**\n * Facebook Client Token, provided by Facebook for web, in mobile it's set in the native files\n */\n clientToken: string;\n };\n\n google?: {\n /**\n * The app's client ID, found and created in the Google Developers Console.\n * For iOS.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSClientId?: string;\n /**\n * The app's server client ID, required for offline mode, found and created in the Google Developers Console.\n * For iOS.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSServerClientId?: string;\n /**\n * The app's web client ID, found and created in the Google Developers Console.\n * For Android (and web in the future).\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n webClientId?: string;\n /**\n * The login mode, can be online or offline. In offline mode, the user will be able to login without an internet connection. It requires iOSServerClientId to be set.\n * @example offline\n * @since 3.1.0\n */\n mode?: 'online' | 'offline';\n /**\n * Filter visible accounts by hosted domain\n * @description filter visible accounts by hosted domain\n */\n hostedDomain?: string;\n };\n apple?: {\n /**\n * Apple Client ID, provided by Apple for web and Android\n */\n clientId?: string;\n /**\n * Apple Redirect URL, should be your backend url that is configured in your apple app, only for android\n */\n redirectUrl?: string;\n };\n}\n\nexport interface FacebookLoginOptions {\n /**\n * Permissions\n * @description select permissions to login with\n */\n permissions: string[];\n /**\n * Is Limited Login\n * @description use limited login for Facebook IOS\n * @default false\n */\n limitedLogin?: boolean;\n /**\n * Nonce\n * @description A custom nonce to use for the login request\n */\n nonce?: string;\n}\n\nexport interface GoogleLoginOptions {\n /**\n * Specifies the scopes required for accessing Google APIs\n * The default is defined in the configuration.\n * @example [\"profile\", \"email\"]\n * @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes)\n */\n scopes?: string[];\n /**\n * Nonce\n * @description nonce\n */\n nonce?: string;\n /**\n * Force refresh token (only for Android)\n * @description force refresh token\n * @default false\n */\n forceRefreshToken?: boolean;\n /**\n * Force account selection prompt (iOS)\n * @description forces the account selection prompt to appear on iOS\n * @default false\n */\n forcePrompt?: boolean;\n /**\n * Style\n * @description style\n * @default 'standard'\n */\n style?: 'bottom' | 'standard';\n}\n\nexport interface GoogleLoginResponseOnline {\n accessToken: AccessToken | null;\n idToken: string | null;\n profile: {\n email: string | null;\n familyName: string | null;\n givenName: string | null;\n id: string | null;\n name: string | null;\n imageUrl: string | null;\n };\n responseType: 'online';\n}\n\nexport interface GoogleLoginResponseOffline {\n serverAuthCode: string;\n responseType: 'offline';\n}\n\nexport type GoogleLoginResponse = GoogleLoginResponseOnline | GoogleLoginResponseOffline;\n\nexport interface AppleProviderOptions {\n /**\n * Scopes\n * @description An array of scopes to request during login\n * @example [\"name\", \"email\"]\n * default: [\"name\", \"email\"]\n */\n scopes?: string[];\n /**\n * Nonce\n * @description nonce\n */\n nonce?: string;\n /**\n * State\n * @description state\n */\n state?: string;\n}\n\nexport interface AppleProviderResponse {\n accessToken: AccessToken | null;\n idToken: string | null;\n profile: {\n user: string;\n email: string | null;\n givenName: string | null;\n familyName: string | null;\n };\n}\n\nexport type LoginOptions =\n | {\n provider: 'facebook';\n options: FacebookLoginOptions;\n }\n | {\n provider: 'google';\n options: GoogleLoginOptions;\n }\n | {\n provider: 'apple';\n options: AppleProviderOptions;\n };\n\nexport type LoginResult =\n | {\n provider: 'facebook';\n result: FacebookLoginResponse;\n }\n | {\n provider: 'google';\n result: GoogleLoginResponse;\n }\n | {\n provider: 'apple';\n result: AppleProviderResponse;\n };\n\nexport interface AccessToken {\n applicationId?: string;\n declinedPermissions?: string[];\n expires?: string;\n isExpired?: boolean;\n lastRefresh?: string;\n permissions?: string[];\n token: string;\n refreshToken?: string;\n userId?: string;\n}\n\nexport interface FacebookLoginResponse {\n accessToken: AccessToken | null;\n idToken: string | null;\n profile: {\n userID: string;\n email: string | null;\n friendIDs: string[];\n birthday: string | null;\n ageRange: { min?: number; max?: number } | null;\n gender: string | null;\n location: { id: string; name: string } | null;\n hometown: { id: string; name: string } | null;\n profileURL: string | null;\n name: string | null;\n imageURL: string | null;\n };\n}\n\nexport interface AuthorizationCode {\n /**\n * Jwt\n * @description A JSON web token\n */\n jwt?: string;\n /**\n * Access Token\n * @description An access token\n */\n accessToken?: string;\n}\n\nexport interface AuthorizationCodeOptions {\n /**\n * Provider\n * @description Provider for the authorization code\n */\n provider: 'apple' | 'google' | 'facebook';\n}\n\nexport interface isLoggedInOptions {\n /**\n * Provider\n * @description Provider for the isLoggedIn\n */\n provider: 'apple' | 'google' | 'facebook';\n}\n\n// Add a helper type to map providers to their response types\nexport type ProviderResponseMap = {\n facebook: FacebookLoginResponse;\n google: GoogleLoginResponse;\n apple: AppleProviderResponse;\n};\n\nexport interface SocialLoginPlugin {\n /**\n * Initialize the plugin\n * @description initialize the plugin with the required options\n */\n initialize(options: InitializeOptions): Promise<void>;\n /**\n * Login with the selected provider\n * @description login with the selected provider\n */\n login<T extends LoginOptions['provider']>(\n options: Extract<LoginOptions, { provider: T }>,\n ): Promise<{ provider: T; result: ProviderResponseMap[T] }>;\n /**\n * Logout\n * @description logout the user\n */\n logout(options: { provider: 'apple' | 'google' | 'facebook' }): Promise<void>;\n /**\n * IsLoggedIn\n * @description logout the user\n */\n isLoggedIn(options: isLoggedInOptions): Promise<{ isLoggedIn: boolean }>;\n\n /**\n * Get the current access token\n * @description get the current access token\n */\n getAuthorizationCode(options: AuthorizationCodeOptions): Promise<AuthorizationCode>;\n /**\n * Refresh the access token\n * @description refresh the access token\n */\n refresh(options: LoginOptions): Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BaseSocialLogin } from './base';
|
|
2
|
+
import type { FacebookLoginOptions, AuthorizationCode, LoginResult } from './definitions';
|
|
3
|
+
export declare class FacebookSocialLogin extends BaseSocialLogin {
|
|
4
|
+
private appId;
|
|
5
|
+
private scriptLoaded;
|
|
6
|
+
initialize(appId: string | null): Promise<void>;
|
|
7
|
+
login(options: FacebookLoginOptions): Promise<LoginResult>;
|
|
8
|
+
logout(): Promise<void>;
|
|
9
|
+
isLoggedIn(): Promise<{
|
|
10
|
+
isLoggedIn: boolean;
|
|
11
|
+
}>;
|
|
12
|
+
getAuthorizationCode(): Promise<AuthorizationCode>;
|
|
13
|
+
refresh(options: FacebookLoginOptions): Promise<void>;
|
|
14
|
+
private loadFacebookScript;
|
|
15
|
+
}
|