@capgo/capacitor-social-login 7.16.0 → 7.17.0

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
@@ -226,7 +226,7 @@ await SocialLogin.initialize({
226
226
 
227
227
  ### Android configuration
228
228
 
229
- The implemention use the new library of Google who use Google account at Os level, make sure your device does have at least one google account connected
229
+ The implementation use the new library of Google who use Google account at Os level, make sure your device does have at least one google account connected
230
230
 
231
231
  Call the `initialize` method with the `google` provider:
232
232
 
@@ -406,14 +406,14 @@ Initialize the plugin
406
406
  ### login(...)
407
407
 
408
408
  ```typescript
409
- login<T extends "apple" | "google" | "facebook">(options: Extract<LoginOptions, { provider: T; }>) => Promise<{ provider: T; result: ProviderResponseMap[T]; }>
409
+ login<T extends "apple" | "google" | "facebook" | "twitter">(options: Extract<LoginOptions, { provider: T; }>) => Promise<{ provider: T; result: ProviderResponseMap[T]; }>
410
410
  ```
411
411
 
412
412
  Login with the selected provider
413
413
 
414
- | Param | Type |
415
- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
416
- | **`options`** | <code><a href="#extract">Extract</a>&lt;{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; }, { provider: T; }&gt; \| <a href="#extract">Extract</a>&lt;{ provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; }, { provider: T; }&gt; \| <a href="#extract">Extract</a>&lt;{ provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; }, { provider: T; }&gt;</code> |
414
+ | Param | Type |
415
+ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
416
+ | **`options`** | <code><a href="#extract">Extract</a>&lt;{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; }, { provider: T; }&gt; \| <a href="#extract">Extract</a>&lt;{ provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; }, { provider: T; }&gt; \| <a href="#extract">Extract</a>&lt;{ provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; }, { provider: T; }&gt; \| <a href="#extract">Extract</a>&lt;{ provider: 'twitter'; options: <a href="#twitterloginoptions">TwitterLoginOptions</a>; }, { provider: T; }&gt;</code> |
417
417
 
418
418
  **Returns:** <code>Promise&lt;{ provider: T; result: ProviderResponseMap[T]; }&gt;</code>
419
419
 
@@ -423,14 +423,14 @@ Login with the selected provider
423
423
  ### logout(...)
424
424
 
425
425
  ```typescript
426
- logout(options: { provider: 'apple' | 'google' | 'facebook'; }) => Promise<void>
426
+ logout(options: { provider: 'apple' | 'google' | 'facebook' | 'twitter'; }) => Promise<void>
427
427
  ```
428
428
 
429
429
  Logout
430
430
 
431
- | Param | Type |
432
- | ------------- | ------------------------------------------------------------- |
433
- | **`options`** | <code>{ provider: 'apple' \| 'google' \| 'facebook'; }</code> |
431
+ | Param | Type |
432
+ | ------------- | -------------------------------------------------------------------------- |
433
+ | **`options`** | <code>{ provider: 'apple' \| 'google' \| 'facebook' \| 'twitter'; }</code> |
434
434
 
435
435
  --------------------
436
436
 
@@ -521,6 +521,7 @@ Get the native Capacitor plugin version
521
521
 
522
522
  | Prop | Type |
523
523
  | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
524
+ | **`twitter`** | <code>{ clientId: string; redirectUrl: string; defaultScopes?: string[]; forceLogin?: boolean; audience?: string; }</code> |
524
525
  | **`facebook`** | <code>{ appId: string; clientToken?: string; locale?: string; }</code> |
525
526
  | **`google`** | <code>{ iOSClientId?: string; iOSServerClientId?: string; webClientId?: string; mode?: 'online' \| 'offline'; hostedDomain?: string; redirectUrl?: string; }</code> |
526
527
  | **`apple`** | <code>{ clientId?: string; redirectUrl?: string; useProperTokenExchange?: boolean; useBroadcastChannel?: boolean; }</code> |
@@ -546,6 +547,7 @@ Get the native Capacitor plugin version
546
547
  | **`lastRefresh`** | <code>string</code> |
547
548
  | **`permissions`** | <code>string[]</code> |
548
549
  | **`token`** | <code>string</code> |
550
+ | **`tokenType`** | <code>string</code> |
549
551
  | **`refreshToken`** | <code>string</code> |
550
552
  | **`userId`** | <code>string</code> |
551
553
 
@@ -578,6 +580,30 @@ Get the native Capacitor plugin version
578
580
  | **`authorizationCode`** | <code>string</code> | Authorization code for proper token exchange (when useProperTokenExchange is enabled) |
579
581
 
580
582
 
583
+ #### TwitterLoginResponse
584
+
585
+ | Prop | Type |
586
+ | ------------------ | ----------------------------------------------------------- |
587
+ | **`accessToken`** | <code><a href="#accesstoken">AccessToken</a> \| null</code> |
588
+ | **`refreshToken`** | <code>string \| null</code> |
589
+ | **`scope`** | <code>string[]</code> |
590
+ | **`tokenType`** | <code>'bearer'</code> |
591
+ | **`expiresIn`** | <code>number \| null</code> |
592
+ | **`profile`** | <code><a href="#twitterprofile">TwitterProfile</a></code> |
593
+
594
+
595
+ #### TwitterProfile
596
+
597
+ | Prop | Type |
598
+ | --------------------- | --------------------------- |
599
+ | **`id`** | <code>string</code> |
600
+ | **`username`** | <code>string</code> |
601
+ | **`name`** | <code>string \| null</code> |
602
+ | **`profileImageUrl`** | <code>string \| null</code> |
603
+ | **`verified`** | <code>boolean</code> |
604
+ | **`email`** | <code>string \| null</code> |
605
+
606
+
581
607
  #### FacebookLoginOptions
582
608
 
583
609
  | Prop | Type | Description | Default |
@@ -611,11 +637,22 @@ Get the native Capacitor plugin version
611
637
  | **`useBroadcastChannel`** | <code>boolean</code> | Use Broadcast Channel for authentication flow | <code>false</code> |
612
638
 
613
639
 
640
+ #### TwitterLoginOptions
641
+
642
+ | Prop | Type | Description |
643
+ | ------------------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
644
+ | **`scopes`** | <code>string[]</code> | Additional scopes to request during login. If omitted the plugin falls back to the default scopes configured during initialization. |
645
+ | **`state`** | <code>string</code> | Provide a custom OAuth state value. When not provided the plugin generates a cryptographically random value. |
646
+ | **`codeVerifier`** | <code>string</code> | Provide a pre-computed PKCE code verifier (mostly used for testing). When omitted the plugin generates a secure verifier automatically. |
647
+ | **`redirectUrl`** | <code>string</code> | Override the redirect URI for a single login call. Useful when the same app supports multiple callback URLs per platform. |
648
+ | **`forceLogin`** | <code>boolean</code> | Force the consent screen on every attempt, maps to `force_login=true`. |
649
+
650
+
614
651
  #### isLoggedInOptions
615
652
 
616
- | Prop | Type | Description |
617
- | -------------- | ---------------------------------------------- | ----------- |
618
- | **`provider`** | <code>'apple' \| 'google' \| 'facebook'</code> | Provider |
653
+ | Prop | Type | Description |
654
+ | -------------- | ----------------------------------------------------------- | ----------- |
655
+ | **`provider`** | <code>'apple' \| 'google' \| 'facebook' \| 'twitter'</code> | Provider |
619
656
 
620
657
 
621
658
  #### AuthorizationCode
@@ -628,9 +665,9 @@ Get the native Capacitor plugin version
628
665
 
629
666
  #### AuthorizationCodeOptions
630
667
 
631
- | Prop | Type | Description |
632
- | -------------- | ---------------------------------------------- | ----------- |
633
- | **`provider`** | <code>'apple' \| 'google' \| 'facebook'</code> | Provider |
668
+ | Prop | Type | Description |
669
+ | -------------- | ----------------------------------------------------------- | ----------- |
670
+ | **`provider`** | <code>'apple' \| 'google' \| 'facebook' \| 'twitter'</code> | Provider |
634
671
 
635
672
 
636
673
  #### FacebookGetProfileResponse
@@ -659,7 +696,7 @@ Get the native Capacitor plugin version
659
696
 
660
697
  #### ProviderResponseMap
661
698
 
662
- <code>{ facebook: <a href="#facebookloginresponse">FacebookLoginResponse</a>; google: <a href="#googleloginresponse">GoogleLoginResponse</a>; apple: <a href="#appleproviderresponse">AppleProviderResponse</a>; }</code>
699
+ <code>{ facebook: <a href="#facebookloginresponse">FacebookLoginResponse</a>; google: <a href="#googleloginresponse">GoogleLoginResponse</a>; apple: <a href="#appleproviderresponse">AppleProviderResponse</a>; twitter: <a href="#twitterloginresponse">TwitterLoginResponse</a>; }</code>
663
700
 
664
701
 
665
702
  #### GoogleLoginResponse
@@ -669,7 +706,7 @@ Get the native Capacitor plugin version
669
706
 
670
707
  #### LoginOptions
671
708
 
672
- <code>{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; } | { provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; } | { provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; }</code>
709
+ <code>{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; } | { provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; } | { provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; } | { provider: 'twitter'; options: <a href="#twitterloginoptions">TwitterLoginOptions</a>; }</code>
673
710
 
674
711
 
675
712
  #### Extract
@@ -777,4 +814,4 @@ Add this file in your app at: `ios/App/PrivacyInfo.xcprivacy`
777
814
  ### Credits
778
815
 
779
816
  This plugin implementation of google is based on [CapacitorGoogleAuth](https://github.com/CodetrixStudio/CapacitorGoogleAuth) with a lot of rework, the current maintainer is unreachable, we are thankful for his work and are now going forward on our own!
780
- Thanks to [reslear](https://github.com/reslear) for helping to tranfer users to this plugin from the old one and all the work.
817
+ Thanks to [reslear](https://github.com/reslear) for helping to transfer users to this plugin from the old one and all the work.
@@ -13,5 +13,9 @@
13
13
  android:authorities="${applicationId}.FacebookInitProvider"
14
14
  android:exported="false"
15
15
  tools:node="remove" />
16
+ <activity
17
+ android:name="ee.forgr.capacitor.social.login.TwitterLoginActivity"
18
+ android:exported="false"
19
+ android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar" />
16
20
  </application>
17
21
  </manifest>
@@ -136,7 +136,7 @@ public class AppleProvider implements SocialProvider {
136
136
  String path = data.getPath(); // Additional path segments
137
137
  String query = data.getQuery(); // Query parameters
138
138
 
139
- Log.i(SocialLoginPlugin.LOG_TAG, String.format("Recieved apple login intent: %s, %s, %s, %s", scheme, host, path, query));
139
+ Log.i(SocialLoginPlugin.LOG_TAG, String.format("Received apple login intent: %s, %s, %s, %s", scheme, host, path, query));
140
140
 
141
141
  handleUrl(data.toString());
142
142
  // if (data.toString().contains("success=")) {
@@ -18,7 +18,7 @@ import org.json.JSONObject;
18
18
  @CapacitorPlugin(name = "SocialLogin")
19
19
  public class SocialLoginPlugin extends Plugin {
20
20
 
21
- private final String pluginVersion = "7.16.0";
21
+ private final String pluginVersion = "7.17.0";
22
22
 
23
23
  public static String LOG_TAG = "CapgoSocialLogin";
24
24
 
@@ -109,6 +109,28 @@ public class SocialLoginPlugin extends Plugin {
109
109
  }
110
110
  }
111
111
 
112
+ JSObject twitter = call.getObject("twitter");
113
+ if (twitter != null) {
114
+ String twitterClientId = twitter.getString("clientId");
115
+ String twitterRedirect = twitter.getString("redirectUrl");
116
+ if (twitterClientId == null || twitterClientId.isEmpty()) {
117
+ call.reject("twitter.clientId is null or empty");
118
+ return;
119
+ }
120
+ if (twitterRedirect == null || twitterRedirect.isEmpty()) {
121
+ call.reject("twitter.redirectUrl is null or empty");
122
+ return;
123
+ }
124
+ TwitterProvider twitterProvider = new TwitterProvider(this.getActivity(), this.getContext());
125
+ try {
126
+ twitterProvider.initialize(twitter);
127
+ this.socialProviderHashMap.put("twitter", twitterProvider);
128
+ } catch (JSONException e) {
129
+ call.reject("Failed to initialize Twitter provider: " + e.getMessage());
130
+ return;
131
+ }
132
+ }
133
+
112
134
  call.resolve();
113
135
  }
114
136
 
@@ -273,6 +295,15 @@ public class SocialLoginPlugin extends Plugin {
273
295
  }
274
296
  }
275
297
 
298
+ SocialProvider twitterProvider = socialProviderHashMap.get("twitter");
299
+ if (twitterProvider instanceof TwitterProvider) {
300
+ boolean handled = ((TwitterProvider) twitterProvider).handleActivityResult(requestCode, resultCode, data);
301
+ if (handled) {
302
+ Log.d(LOG_TAG, "Twitter activity result handled");
303
+ return;
304
+ }
305
+ }
306
+
276
307
  // Handle other providers' activity results if needed
277
308
  Log.d(LOG_TAG, "Activity result not handled by any provider");
278
309
  }
@@ -0,0 +1,93 @@
1
+ package ee.forgr.capacitor.social.login;
2
+
3
+ import android.app.Activity;
4
+ import android.content.Intent;
5
+ import android.graphics.Bitmap;
6
+ import android.net.Uri;
7
+ import android.os.Bundle;
8
+ import android.view.ViewGroup;
9
+ import android.webkit.WebResourceRequest;
10
+ import android.webkit.WebSettings;
11
+ import android.webkit.WebView;
12
+ import android.webkit.WebViewClient;
13
+ import androidx.annotation.Nullable;
14
+ import androidx.annotation.RequiresApi;
15
+
16
+ public class TwitterLoginActivity extends Activity {
17
+
18
+ public static final String EXTRA_AUTH_URL = "authUrl";
19
+ public static final String EXTRA_REDIRECT_URL = "redirectUrl";
20
+
21
+ private String redirectUrl;
22
+
23
+ @Override
24
+ protected void onCreate(@Nullable Bundle savedInstanceState) {
25
+ super.onCreate(savedInstanceState);
26
+ WebView webView = new WebView(this);
27
+ webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
28
+ WebSettings settings = webView.getSettings();
29
+ settings.setJavaScriptEnabled(true);
30
+ settings.setDomStorageEnabled(true);
31
+ settings.setLoadWithOverviewMode(true);
32
+ settings.setUseWideViewPort(true);
33
+
34
+ redirectUrl = getIntent().getStringExtra(EXTRA_REDIRECT_URL);
35
+ final String authUrl = getIntent().getStringExtra(EXTRA_AUTH_URL);
36
+
37
+ webView.setWebViewClient(
38
+ new WebViewClient() {
39
+ @Override
40
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
41
+ return handleUrl(url);
42
+ }
43
+
44
+ @RequiresApi(21)
45
+ @Override
46
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
47
+ return handleUrl(request.getUrl().toString());
48
+ }
49
+
50
+ @Override
51
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
52
+ handleUrl(url);
53
+ }
54
+ }
55
+ );
56
+
57
+ setContentView(webView);
58
+
59
+ if (authUrl == null) {
60
+ finishWithError("Missing authorization URL");
61
+ return;
62
+ }
63
+
64
+ webView.loadUrl(authUrl);
65
+ }
66
+
67
+ private boolean handleUrl(String url) {
68
+ if (redirectUrl != null && url.startsWith(redirectUrl)) {
69
+ Uri uri = Uri.parse(url);
70
+ Intent data = new Intent();
71
+ data.putExtra("code", uri.getQueryParameter("code"));
72
+ data.putExtra("state", uri.getQueryParameter("state"));
73
+ data.putExtra("error", uri.getQueryParameter("error"));
74
+ data.putExtra("error_description", uri.getQueryParameter("error_description"));
75
+ setResult(Activity.RESULT_OK, data);
76
+ finish();
77
+ return true;
78
+ }
79
+ return false;
80
+ }
81
+
82
+ private void finishWithError(String message) {
83
+ Intent data = new Intent();
84
+ data.putExtra("error", message);
85
+ setResult(Activity.RESULT_CANCELED, data);
86
+ finish();
87
+ }
88
+
89
+ @Override
90
+ public void onBackPressed() {
91
+ finishWithError("User cancelled");
92
+ }
93
+ }