@capgo/capacitor-social-login 7.2.2 → 7.4.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 CHANGED
@@ -426,13 +426,13 @@ Refresh the access token
426
426
 
427
427
  #### GoogleLoginOptions
428
428
 
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
- | **`disableOneTap`** | <code>boolean</code> | Disable one-tap login (web only) | <code>false</code> |
435
- | **`forcePrompt`** | <code>boolean</code> | Force account selection prompt (iOS) | <code>false</code> |
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
- Integer expressInInt;
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 (int i = 0; i < array.length; i++) {
267
- if (array[i].equals(search)) {
268
- return array[i];
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
- // Extract scopes from the config
289
- JSONArray scopesArray = config.optJSONArray("scopes");
290
-
291
- // Remove duplicates from scopes array
292
- if (scopesArray != null) {
293
- Set<String> uniqueScopes = new HashSet<>();
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
- scopesArray = new JSONArray(uniqueScopes);
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
- this.scopes[i] = scopesArray.optString(i);
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
- if (arrayFind(this.scopes, "https://www.googleapis.com/auth/userinfo.email") == null) {
311
- String[] newScopes = new String[this.scopes.length + 1];
312
- System.arraycopy(this.scopes, 0, newScopes, 0, this.scopes.length);
313
- newScopes[this.scopes.length] = "https://www.googleapis.com/auth/userinfo.email";
314
- this.scopes = newScopes;
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
- if (arrayFind(this.scopes, "https://www.googleapis.com/auth/userinfo.profile") == null) {
317
- String[] newScopes = new String[this.scopes.length + 1];
318
- System.arraycopy(this.scopes, 0, newScopes, 0, this.scopes.length);
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 (arrayFind(this.scopes, "openid") == null) {
323
- String[] newScopes = new String[this.scopes.length + 1];
324
- System.arraycopy(this.scopes, 0, newScopes, 0, this.scopes.length);
325
- newScopes[this.scopes.length] = "openid";
326
- this.scopes = newScopes;
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
- GetSignInWithGoogleOption.Builder googleIdOptionBuilder = new GetSignInWithGoogleOption.Builder(this.clientId);
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
- if (nonce != null && !nonce.isEmpty()) {
340
- googleIdOptionBuilder.setNonce(nonce);
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
- if (this.hostedDomain != null && !this.hostedDomain.isEmpty()) {
344
- googleIdOptionBuilder.setHostedDomainFilter(this.hostedDomain);
360
+ requestBuilder.addCredentialOption(googleIdOptionBuilder.build());
345
361
  }
346
362
 
347
- GetSignInWithGoogleOption googleIdOptionFiltered = googleIdOptionBuilder.build();
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 (int i = 0; i < this.scopes.length; i++) {
404
- scopes.add(new Scope(this.scopes[i]));
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
- options != null && options.has("forceRefreshToken") && options.getBoolean("forceRefreshToken");
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
- if (e instanceof NoCredentialException) {
589
- call.reject("No Google accounts available. Please add a Google account to your device and try again.");
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": "disableOneTap",
481
+ "name": "forcePrompt",
482
482
  "tags": [
483
483
  {
484
- "text": "disable one-tap login",
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": "Disable one-tap login (web only)",
492
+ "docs": "Force account selection prompt (iOS)",
493
493
  "complexTypes": [],
494
494
  "type": "boolean | undefined"
495
495
  },
496
496
  {
497
- "name": "forcePrompt",
497
+ "name": "style",
498
498
  "tags": [
499
499
  {
500
- "text": "forces the account selection prompt to appear on iOS",
500
+ "text": "style",
501
501
  "name": "description"
502
502
  },
503
503
  {
504
- "text": "false",
504
+ "text": "'standard'",
505
505
  "name": "default"
506
506
  }
507
507
  ],
508
- "docs": "Force account selection prompt (iOS)",
508
+ "docs": "Style",
509
509
  "complexTypes": [],
510
- "type": "boolean | undefined"
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
+ }
@@ -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 * Disable one-tap login (web only)\n * @description disable one-tap login\n * @default false\n */\n disableOneTap?: 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\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"]}
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
+ }