@capgo/capacitor-social-login 8.3.4 → 8.3.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.
@@ -42,6 +42,10 @@ public class OAuth2Provider implements SocialProvider {
42
42
  private static final String PREFS_NAME = "CapgoOAuth2ProviderPrefs";
43
43
  private static final String PREFS_KEY_PREFIX = "OAuth2Tokens_";
44
44
 
45
+ public interface ActivityLauncher {
46
+ void launchForResult(Intent intent, int requestCode);
47
+ }
48
+
45
49
  private final Activity activity;
46
50
  private final Context context;
47
51
  private final OkHttpClient httpClient;
@@ -51,6 +55,19 @@ public class OAuth2Provider implements SocialProvider {
51
55
 
52
56
  private PluginCall pendingCall;
53
57
  private OAuth2PendingState pendingState;
58
+ private ActivityLauncher activityLauncher;
59
+
60
+ public void setActivityLauncher(ActivityLauncher launcher) {
61
+ this.activityLauncher = launcher;
62
+ }
63
+
64
+ public PluginCall getPendingCall() {
65
+ return pendingCall;
66
+ }
67
+
68
+ public void setPendingCall(PluginCall call) {
69
+ this.pendingCall = call;
70
+ }
54
71
 
55
72
  private static class OAuth2ProviderConfig {
56
73
 
@@ -461,7 +478,19 @@ public class OAuth2Provider implements SocialProvider {
461
478
  Intent intent = new Intent(activity, OAuth2LoginActivity.class);
462
479
  intent.putExtra(OAuth2LoginActivity.EXTRA_AUTH_URL, builder.build().toString());
463
480
  intent.putExtra(OAuth2LoginActivity.EXTRA_REDIRECT_URL, finalRedirect);
464
- activity.runOnUiThread(() -> activity.startActivityForResult(intent, REQUEST_CODE));
481
+
482
+ activity.runOnUiThread(() -> {
483
+ if (activityLauncher != null) {
484
+ activityLauncher.launchForResult(intent, REQUEST_CODE);
485
+ } else {
486
+ Log.w(
487
+ LOG_TAG,
488
+ "activityLauncher is null — falling back to raw startActivityForResult. " +
489
+ "Activity result routing through Capacitor will not work."
490
+ );
491
+ activity.startActivityForResult(intent, REQUEST_CODE);
492
+ }
493
+ });
465
494
  }
466
495
 
467
496
  @Override
@@ -621,6 +650,13 @@ public class OAuth2Provider implements SocialProvider {
621
650
  return false;
622
651
  }
623
652
  if (pendingCall == null || pendingState == null) {
653
+ if (pendingCall != null) {
654
+ // pendingCall was restored (e.g. via @ActivityCallback after process death)
655
+ // but pendingState (codeVerifier, state nonce, etc.) was lost. Cannot complete.
656
+ Log.e(LOG_TAG, "pendingCall present but pendingState is null — login state lost (process death?)");
657
+ pendingCall.reject("OAuth2 login state was lost (process death). Please retry.");
658
+ cleanupPending();
659
+ }
624
660
  return true;
625
661
  }
626
662
 
@@ -4,12 +4,14 @@ import android.content.Intent;
4
4
  import android.net.Uri;
5
5
  import android.util.Base64;
6
6
  import android.util.Log;
7
+ import androidx.activity.result.ActivityResult;
7
8
  import androidx.browser.customtabs.CustomTabsIntent;
8
9
  import com.getcapacitor.JSArray;
9
10
  import com.getcapacitor.JSObject;
10
11
  import com.getcapacitor.Plugin;
11
12
  import com.getcapacitor.PluginCall;
12
13
  import com.getcapacitor.PluginMethod;
14
+ import com.getcapacitor.annotation.ActivityCallback;
13
15
  import com.getcapacitor.annotation.CapacitorPlugin;
14
16
  import ee.forgr.capacitor.social.login.helpers.DependencyAvailabilityChecker;
15
17
  import ee.forgr.capacitor.social.login.helpers.SocialProvider;
@@ -22,10 +24,9 @@ import org.json.JSONObject;
22
24
  @CapacitorPlugin(name = "SocialLogin")
23
25
  public class SocialLoginPlugin extends Plugin {
24
26
 
25
- private final String pluginVersion = "8.3.4";
27
+ private final String pluginVersion = "8.3.6";
26
28
 
27
29
  public static String LOG_TAG = "CapgoSocialLogin";
28
-
29
30
  public HashMap<String, SocialProvider> socialProviderHashMap = new HashMap<>();
30
31
 
31
32
  private PluginCall openSecureWindowSavedCall;
@@ -174,6 +175,14 @@ public class SocialLoginPlugin extends Plugin {
174
175
  return;
175
176
  }
176
177
  this.socialProviderHashMap.put("oauth2", oauth2Provider);
178
+ oauth2Provider.setActivityLauncher((intent, requestCode) -> {
179
+ PluginCall loginCall = oauth2Provider.getPendingCall();
180
+ if (loginCall != null) {
181
+ startActivityForResult(loginCall, intent, "handleOAuth2ActivityResult");
182
+ } else {
183
+ Log.e(LOG_TAG, "OAuth2 activityLauncher fired but pendingCall is null, cannot route result");
184
+ }
185
+ });
177
186
  } catch (JSONException e) {
178
187
  call.reject("Failed to initialize OAuth2 provider: " + e.getMessage());
179
188
  return;
@@ -357,6 +366,29 @@ public class SocialLoginPlugin extends Plugin {
357
366
  }
358
367
  }
359
368
 
369
+ @ActivityCallback
370
+ private void handleOAuth2ActivityResult(PluginCall call, ActivityResult result) {
371
+ if (call == null) {
372
+ Log.e(LOG_TAG, "OAuth2 activity result: saved call is null");
373
+ return;
374
+ }
375
+
376
+ SocialProvider oauth2Provider = socialProviderHashMap.get("oauth2");
377
+ if (!(oauth2Provider instanceof OAuth2Provider)) {
378
+ call.reject("OAuth2 provider not found");
379
+ return;
380
+ }
381
+
382
+ OAuth2Provider p = (OAuth2Provider) oauth2Provider;
383
+ if (p.getPendingCall() == null) {
384
+ p.setPendingCall(call);
385
+ }
386
+
387
+ Intent data = result.getData();
388
+ int resultCode = result.getResultCode();
389
+ p.handleActivityResult(OAuth2Provider.REQUEST_CODE, resultCode, data);
390
+ }
391
+
360
392
  public void handleGoogleLoginIntent(int requestCode, Intent intent) {
361
393
  try {
362
394
  SocialProvider provider = socialProviderHashMap.get("google");
@@ -387,7 +419,7 @@ public class SocialLoginPlugin extends Plugin {
387
419
  protected void handleOnActivityResult(int requestCode, int resultCode, Intent data) {
388
420
  super.handleOnActivityResult(requestCode, resultCode, data);
389
421
 
390
- Log.d(LOG_TAG, "SocialLoginPlugin.handleOnActivityResult called");
422
+ Log.d(LOG_TAG, "SocialLoginPlugin.handleOnActivityResult called (legacy fallback path)");
391
423
 
392
424
  // Handle Facebook login result
393
425
  SocialProvider facebookProvider = socialProviderHashMap.get("facebook");
@@ -113,14 +113,14 @@ class OAuth2Provider: NSObject {
113
113
  responseType: config["responseType"] as? String ?? "code",
114
114
  pkceEnabled: config["pkceEnabled"] as? Bool ?? true,
115
115
  scope: normalizeScope(config["scope"] ?? config["scopes"]),
116
- additionalParameters: config["additionalParameters"] as? [String: String],
116
+ additionalParameters: (config["additionalParameters"] as? [String: Any]).map { $0.mapValues { "\($0)" } },
117
117
  loginHint: config["loginHint"] as? String,
118
118
  prompt: config["prompt"] as? String,
119
- additionalTokenParameters: config["additionalTokenParameters"] as? [String: String],
120
- additionalResourceHeaders: config["additionalResourceHeaders"] as? [String: String],
119
+ additionalTokenParameters: (config["additionalTokenParameters"] as? [String: Any]).map { $0.mapValues { "\($0)" } },
120
+ additionalResourceHeaders: (config["additionalResourceHeaders"] as? [String: Any]).map { $0.mapValues { "\($0)" } },
121
121
  logoutUrl: (config["logoutUrl"] as? String) ?? (config["endSessionEndpoint"] as? String),
122
122
  postLogoutRedirectUrl: config["postLogoutRedirectUrl"] as? String,
123
- additionalLogoutParameters: config["additionalLogoutParameters"] as? [String: String],
123
+ additionalLogoutParameters: (config["additionalLogoutParameters"] as? [String: Any]).map { $0.mapValues { "\($0)" } },
124
124
  iosPrefersEphemeralWebBrowserSession:
125
125
  (config["iosPrefersEphemeralWebBrowserSession"] as? Bool) ??
126
126
  (config["iosPrefersEphemeralSession"] as? Bool) ??
@@ -228,7 +228,7 @@ class OAuth2Provider: NSObject {
228
228
  let state = payload["state"] as? String ?? UUID().uuidString
229
229
  let codeVerifier = payload["codeVerifier"] as? String ?? self.generateCodeVerifier()
230
230
  let redirect = payload["redirectUrl"] as? String ?? config.redirectUrl
231
- let additionalLoginParams = payload["additionalParameters"] as? [String: String]
231
+ let additionalLoginParams = (payload["additionalParameters"] as? [String: Any]).map { $0.mapValues { "\($0)" } }
232
232
 
233
233
  self.currentState = state
234
234
  self.currentCodeVerifier = codeVerifier
@@ -740,8 +740,10 @@ extension OAuth2Provider: ASWebAuthenticationPresentationContextProviding {
740
740
 
741
741
  private extension Dictionary where Key == String, Value == String {
742
742
  func percentEncoded() -> Data? {
743
- map { key, value in
744
- "\(key.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? key)=\(value.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? value)"
743
+ var formValueAllowed = CharacterSet.urlQueryAllowed
744
+ formValueAllowed.remove(charactersIn: "+&=/")
745
+ return map { key, value in
746
+ "\(key.addingPercentEncoding(withAllowedCharacters: formValueAllowed) ?? key)=\(value.addingPercentEncoding(withAllowedCharacters: formValueAllowed) ?? value)"
745
747
  }
746
748
  .joined(separator: "&")
747
749
  .data(using: .utf8)
@@ -16,7 +16,7 @@ import GoogleSignIn
16
16
  */
17
17
  @objc(SocialLoginPlugin)
18
18
  public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
19
- private let pluginVersion: String = "8.3.4"
19
+ private let pluginVersion: String = "8.3.6"
20
20
  public let identifier = "SocialLoginPlugin"
21
21
  public let jsName = "SocialLogin"
22
22
  public let pluginMethods: [CAPPluginMethod] = [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-social-login",
3
- "version": "8.3.4",
3
+ "version": "8.3.6",
4
4
  "description": "All social logins in one plugin",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",