@capgo/capacitor-social-login 7.19.0 → 7.20.0-beta.1

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.
@@ -1,11 +1,15 @@
1
1
  import Foundation
2
+
3
+ #if canImport(GoogleSignIn)
2
4
  import GoogleSignIn
5
+ #endif
3
6
 
4
7
  enum GoogleProviderLoginType {
5
8
  case OFFLINE
6
9
  case ONLINE
7
10
  }
8
11
 
12
+ #if canImport(GoogleSignIn)
9
13
  class GoogleProvider {
10
14
  var configuration: GIDConfiguration!
11
15
  var forceAuthCode: Bool = false
@@ -218,6 +222,34 @@ class GoogleProvider {
218
222
  ), email: nil, familyName: nil, givenName: nil, id: nil, name: nil, imageUrl: nil, serverAuthCode: serverAuthCode)
219
223
  }
220
224
  }
225
+ #else
226
+ // Stub class when GoogleSignIn is not available
227
+ class GoogleProvider {
228
+ func initialize(clientId: String, mode: GoogleProviderLoginType, serverClientId: String? = nil, hostedDomain: String? = nil) {
229
+ fatalError("Google Sign-In is not available. Include GoogleSignIn dependency in your Podfile.")
230
+ }
231
+
232
+ func login(payload: [String: Any], completion: @escaping (Result<GoogleLoginResponse, Error>) -> Void) {
233
+ completion(.failure(NSError(domain: "GoogleProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Google Sign-In is not available"])))
234
+ }
235
+
236
+ func logout(completion: @escaping (Result<Void, Error>) -> Void) {
237
+ completion(.failure(NSError(domain: "GoogleProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Google Sign-In is not available"])))
238
+ }
239
+
240
+ func isLoggedIn(completion: @escaping (Result<Bool, Error>) -> Void) {
241
+ completion(.failure(NSError(domain: "GoogleProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Google Sign-In is not available"])))
242
+ }
243
+
244
+ func getAuthorizationCode(completion: @escaping (Result<GoogleLoginResponse.Authentication, Error>) -> Void) {
245
+ completion(.failure(NSError(domain: "GoogleProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Google Sign-In is not available"])))
246
+ }
247
+
248
+ func refresh(completion: @escaping (Result<Void, Error>) -> Void) {
249
+ completion(.failure(NSError(domain: "GoogleProvider", code: -1, userInfo: [NSLocalizedDescriptionKey: "Google Sign-In is not available"])))
250
+ }
251
+ }
252
+ #endif
221
253
 
222
254
  struct GoogleLoginResponse {
223
255
  let authentication: Authentication
@@ -1,13 +1,21 @@
1
1
  import Foundation
2
2
  import Capacitor
3
3
 
4
+ #if canImport(FBSDKLoginKit)
5
+ import FBSDKLoginKit
6
+ #endif
7
+
8
+ #if canImport(GoogleSignIn)
9
+ import GoogleSignIn
10
+ #endif
11
+
4
12
  /**
5
13
  * Please read the Capacitor iOS Plugin Development Guide
6
14
  * here: https://capacitorjs.com/docs/plugins/ios
7
15
  */
8
16
  @objc(SocialLoginPlugin)
9
17
  public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
10
- private let pluginVersion: String = "7.19.0"
18
+ private let pluginVersion: String = "7.20.0"
11
19
  public let identifier = "SocialLoginPlugin"
12
20
  public let jsName = "SocialLogin"
13
21
  public let pluginMethods: [CAPPluginMethod] = [
@@ -21,11 +29,115 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
21
29
  CAPPluginMethod(name: "providerSpecificCall", returnType: CAPPluginReturnPromise),
22
30
  CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise)
23
31
  ]
32
+
33
+ // Providers - conditionally initialized based on available dependencies
34
+ #if canImport(Alamofire)
24
35
  private let apple = AppleProvider()
36
+ #else
37
+ private let apple: AppleProvider? = nil
38
+ #endif
39
+
40
+ #if canImport(FBSDKLoginKit)
25
41
  private let facebook = FacebookProvider()
42
+ #else
43
+ private let facebook: FacebookProvider? = nil
44
+ #endif
45
+
46
+ #if canImport(GoogleSignIn)
26
47
  private let google = GoogleProvider()
48
+ #else
49
+ private let google: GoogleProvider? = nil
50
+ #endif
51
+
27
52
  private let twitter = TwitterProvider()
28
53
 
54
+ // Helper to get Facebook provider (returns nil if unavailable)
55
+ private var facebookProvider: FacebookProvider? {
56
+ #if canImport(FBSDKLoginKit)
57
+ return facebook
58
+ #else
59
+ return nil
60
+ #endif
61
+ }
62
+
63
+ // Helper to get Google provider (returns nil if unavailable)
64
+ private var googleProvider: GoogleProvider? {
65
+ #if canImport(GoogleSignIn)
66
+ return google
67
+ #else
68
+ return nil
69
+ #endif
70
+ }
71
+
72
+ // Helper to get Apple provider (returns nil if unavailable)
73
+ private var appleProvider: AppleProvider? {
74
+ #if canImport(Alamofire)
75
+ return apple
76
+ #else
77
+ return nil
78
+ #endif
79
+ }
80
+
81
+ /**
82
+ * Check if a provider is enabled in Capacitor config.
83
+ * Returns true if not set (default enabled).
84
+ */
85
+ private func isProviderEnabledInConfig(_ providerName: String) -> Bool {
86
+ let config = self.getConfig().getConfigJSON()
87
+
88
+ guard let providers = config["providers"] as? [String: Any] else {
89
+ return true
90
+ }
91
+
92
+ // Check if provider is explicitly set to false
93
+ if let value = providers[providerName] {
94
+ if let boolValue = value as? Bool {
95
+ return boolValue
96
+ }
97
+ // If it's a string "false", treat as disabled
98
+ if let stringValue = value as? String, stringValue.lowercased() == "false" {
99
+ return false
100
+ }
101
+ }
102
+
103
+ return true // Default to enabled
104
+ }
105
+
106
+ /**
107
+ * Check if a provider is available (dependencies are included or enabled via config)
108
+ */
109
+ private func isProviderAvailable(_ provider: String) -> Bool {
110
+ switch provider.lowercased() {
111
+ case "apple":
112
+ // Check config first (for "fake disable"), then check Alamofire dependency
113
+ if !isProviderEnabledInConfig("apple") {
114
+ return false
115
+ }
116
+ #if canImport(Alamofire)
117
+ return true
118
+ #else
119
+ return false
120
+ #endif
121
+ case "facebook":
122
+ #if canImport(FBSDKLoginKit)
123
+ return true
124
+ #else
125
+ return false
126
+ #endif
127
+ case "google":
128
+ #if canImport(GoogleSignIn)
129
+ return true
130
+ #else
131
+ return false
132
+ #endif
133
+ case "twitter":
134
+ // Check config first (for "fake disable")
135
+ return isProviderEnabledInConfig("twitter")
136
+ default:
137
+ return false
138
+ }
139
+ }
140
+
29
141
  @objc func getPluginVersion(_ call: CAPPluginCall) {
30
142
  call.resolve(["version": self.pluginVersion])
31
143
  }
@@ -35,7 +147,12 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
35
147
 
36
148
  if let facebookSettings = call.getObject("facebook") {
37
149
  if facebookSettings["appId"] is String {
38
- facebook.initialize()
150
+ // Check if Facebook dependencies are available
151
+ guard let fbProvider = facebookProvider else {
152
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
153
+ return
154
+ }
155
+ fbProvider.initialize()
39
156
  initialized = true
40
157
  }
41
158
  }
@@ -60,15 +177,24 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
60
177
  }
61
178
 
62
179
  if let clientId = iOSClientId {
63
- google.initialize(clientId: clientId, mode: mode, serverClientId: iOSServerClientId, hostedDomain: hostedDomain)
180
+ // Check if Google dependencies are available
181
+ guard let gProvider = googleProvider else {
182
+ call.reject("Google Sign-In provider is disabled. Dependencies are not available. Ensure Google Sign-In dependencies are included in your Podfile")
183
+ return
184
+ }
185
+ gProvider.initialize(clientId: clientId, mode: mode, serverClientId: iOSServerClientId, hostedDomain: hostedDomain)
64
186
  initialized = true
65
187
  }
66
188
  }
67
189
 
68
190
  if let appleSettings = call.getObject("apple") {
191
+ guard let apProvider = appleProvider else {
192
+ call.reject("Apple Sign-In provider is disabled. Dependencies are not available. Ensure Alamofire dependency is included in your Podfile")
193
+ return
194
+ }
69
195
  let redirectUrl = appleSettings["redirectUrl"] as? String
70
196
  let useProperTokenExchange = appleSettings["useProperTokenExchange"] as? Bool ?? false
71
- apple.initialize(redirectUrl: redirectUrl, useProperTokenExchange: useProperTokenExchange)
197
+ apProvider.initialize(redirectUrl: redirectUrl, useProperTokenExchange: useProperTokenExchange)
72
198
  initialized = true
73
199
  }
74
200
 
@@ -103,7 +229,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
103
229
 
104
230
  switch provider {
105
231
  case "apple": do {
106
- if let idToken = apple.idToken {
232
+ guard let apProvider = appleProvider else {
233
+ call.reject("Apple Sign-In provider is disabled. Dependencies are not available. Ensure Alamofire dependency is included in your Podfile")
234
+ return
235
+ }
236
+ if let idToken = apProvider.idToken {
107
237
  if !idToken.isEmpty {
108
238
  call.resolve([ "jwt": idToken ])
109
239
  } else {
@@ -114,7 +244,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
114
244
  }
115
245
  }
116
246
  case "google": do {
117
- self.google.getAuthorizationCode { res in
247
+ guard let gProvider = googleProvider else {
248
+ call.reject("Google Sign-In provider is disabled. Dependencies are not available. Ensure Google Sign-In dependencies are included in your Podfile")
249
+ return
250
+ }
251
+ gProvider.getAuthorizationCode { res in
118
252
  do {
119
253
  let authorizationCode = try res.get()
120
254
  call.resolve([ "jwt": authorizationCode.idToken ?? "", "accessToken": authorizationCode.accessToken ])
@@ -124,7 +258,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
124
258
  }
125
259
  }
126
260
  case "facebook": do {
127
- self.facebook.getAuthorizationCode { res in
261
+ guard let fbProvider = facebookProvider else {
262
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
263
+ return
264
+ }
265
+ fbProvider.getAuthorizationCode { res in
128
266
  do {
129
267
  let result = try res.get()
130
268
  var response: [String: String] = [:]
@@ -173,7 +311,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
173
311
 
174
312
  switch provider {
175
313
  case "apple": do {
176
- if let idToken = apple.idToken {
314
+ guard let apProvider = appleProvider else {
315
+ call.reject("Apple Sign-In provider is disabled. Dependencies are not available. Ensure Alamofire dependency is included in your Podfile")
316
+ return
317
+ }
318
+ if let idToken = apProvider.idToken {
177
319
  if !idToken.isEmpty {
178
320
  call.resolve([ "isLoggedIn": true ])
179
321
  } else {
@@ -184,7 +326,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
184
326
  }
185
327
  }
186
328
  case "google": do {
187
- self.google.isLoggedIn { res in
329
+ guard let gProvider = googleProvider else {
330
+ call.reject("Google Sign-In provider is disabled. Dependencies are not available. Ensure Google Sign-In dependencies are included in your Podfile")
331
+ return
332
+ }
333
+ gProvider.isLoggedIn { res in
188
334
  do {
189
335
  let isLogged = try res.get()
190
336
  call.resolve([ "isLoggedIn": isLogged ])
@@ -194,8 +340,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
194
340
  }
195
341
  }
196
342
  case "facebook": do {
197
- call.resolve([ "isLoggedIn": self.facebook.isLoggedIn() ])
198
-
343
+ guard let fbProvider = facebookProvider else {
344
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
345
+ return
346
+ }
347
+ call.resolve([ "isLoggedIn": fbProvider.isLoggedIn() ])
199
348
  }
200
349
  case "twitter": do {
201
350
  self.twitter.isLoggedIn { res in
@@ -221,15 +370,27 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
221
370
 
222
371
  switch provider {
223
372
  case "facebook":
224
- facebook.login(payload: payload) { (result: Result<FacebookLoginResponse, Error>) in
373
+ guard let fbProvider = facebookProvider else {
374
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
375
+ return
376
+ }
377
+ fbProvider.login(payload: payload) { (result: Result<FacebookLoginResponse, Error>) in
225
378
  self.handleLoginResult(result, call: call)
226
379
  }
227
380
  case "google":
228
- google.login(payload: payload) { (result: Result<GoogleLoginResponse, Error>) in
381
+ guard let gProvider = googleProvider else {
382
+ call.reject("Google Sign-In provider is disabled. Dependencies are not available. Ensure Google Sign-In dependencies are included in your Podfile")
383
+ return
384
+ }
385
+ gProvider.login(payload: payload) { (result: Result<GoogleLoginResponse, Error>) in
229
386
  self.handleLoginResult(result, call: call)
230
387
  }
231
388
  case "apple":
232
- apple.login(payload: payload) { (result: Result<AppleProviderResponse, Error>) in
389
+ guard let apProvider = appleProvider else {
390
+ call.reject("Apple Sign-In provider is disabled. Dependencies are not available. Ensure Alamofire dependency is included in your Podfile")
391
+ return
392
+ }
393
+ apProvider.login(payload: payload) { (result: Result<AppleProviderResponse, Error>) in
233
394
  self.handleLoginResult(result, call: call)
234
395
  }
235
396
  case "twitter":
@@ -248,6 +409,10 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
248
409
  }
249
410
  switch customCall {
250
411
  case "facebook#getProfile":
412
+ guard let fbProvider = facebookProvider else {
413
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
414
+ return
415
+ }
251
416
  guard let options = call.getObject("options") else {
252
417
  call.reject("options are required")
253
418
  return
@@ -257,7 +422,7 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
257
422
  return
258
423
  }
259
424
 
260
- facebook.getProfile(fields: fields, completion: { res in
425
+ fbProvider.getProfile(fields: fields, completion: { res in
261
426
  switch res {
262
427
  case .success(let profile):
263
428
  call.resolve(["profile": profile as Any])
@@ -266,7 +431,11 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
266
431
  }
267
432
  })
268
433
  case "facebook#requestTracking":
269
- facebook.requestTracking(completion: { res in
434
+ guard let fbProvider = facebookProvider else {
435
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
436
+ return
437
+ }
438
+ fbProvider.requestTracking(completion: { res in
270
439
  switch res {
271
440
  case .success(let status):
272
441
  call.resolve(["status": status])
@@ -287,15 +456,27 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
287
456
 
288
457
  switch provider {
289
458
  case "facebook":
290
- facebook.logout { result in
459
+ guard let fbProvider = facebookProvider else {
460
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
461
+ return
462
+ }
463
+ fbProvider.logout { result in
291
464
  self.handleLogoutResult(result, call: call)
292
465
  }
293
466
  case "google":
294
- google.logout { result in
467
+ guard let gProvider = googleProvider else {
468
+ call.reject("Google Sign-In provider is disabled. Dependencies are not available. Ensure Google Sign-In dependencies are included in your Podfile")
469
+ return
470
+ }
471
+ gProvider.logout { result in
295
472
  self.handleLogoutResult(result, call: call)
296
473
  }
297
474
  case "apple":
298
- apple.logout { result in
475
+ guard let apProvider = appleProvider else {
476
+ call.reject("Apple Sign-In provider is disabled. Dependencies are not available. Ensure Alamofire dependency is included in your Podfile")
477
+ return
478
+ }
479
+ apProvider.logout { result in
299
480
  self.handleLogoutResult(result, call: call)
300
481
  }
301
482
  case "twitter":
@@ -315,15 +496,27 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
315
496
 
316
497
  switch provider {
317
498
  case "facebook":
318
- facebook.refresh(viewController: self.bridge?.viewController) { result in
499
+ guard let fbProvider = facebookProvider else {
500
+ call.reject("Facebook provider is disabled. Dependencies are not available. Ensure Facebook Login dependencies are included in your Podfile")
501
+ return
502
+ }
503
+ fbProvider.refresh(viewController: self.bridge?.viewController) { result in
319
504
  self.handleRefreshResult(result, call: call)
320
505
  }
321
506
  case "google":
322
- google.refresh { result in
507
+ guard let gProvider = googleProvider else {
508
+ call.reject("Google Sign-In provider is disabled. Dependencies are not available. Ensure Google Sign-In dependencies are included in your Podfile")
509
+ return
510
+ }
511
+ gProvider.refresh { result in
323
512
  self.handleRefreshResult(result, call: call)
324
513
  }
325
514
  case "apple":
326
- apple.refresh { result in
515
+ guard let apProvider = appleProvider else {
516
+ call.reject("Apple Sign-In provider is disabled. Dependencies are not available. Ensure Alamofire dependency is included in your Podfile")
517
+ return
518
+ }
519
+ apProvider.refresh { result in
327
520
  self.handleRefreshResult(result, call: call)
328
521
  }
329
522
  case "twitter":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-social-login",
3
- "version": "7.19.0",
3
+ "version": "7.20.0-beta.1",
4
4
  "description": "All social logins in one plugin",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -13,10 +13,11 @@
13
13
  "ios/Sources",
14
14
  "ios/Tests",
15
15
  "Package.swift",
16
- "CapgoCapacitorSocialLogin.podspec"
16
+ "CapgoCapacitorSocialLogin.podspec",
17
+ "scripts/configure-dependencies.js"
17
18
  ],
18
19
  "author": "Martin Donadieu <martin@capgo.app>",
19
- "license": "MIT",
20
+ "license": "MPL-2.0",
20
21
  "repository": {
21
22
  "type": "git",
22
23
  "url": "git+https://github.com/Cap-go/capacitor-social-login.git"
@@ -39,17 +40,19 @@
39
40
  "oauth2"
40
41
  ],
41
42
  "scripts": {
43
+ "capacitor:sync:before": "node scripts/configure-dependencies.js",
42
44
  "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
43
45
  "verify:ios": "xcodebuild -scheme CapgoCapacitorSocialLogin -destination generic/platform=iOS",
44
46
  "verify:android": "cd android && ./gradlew clean build test && cd ..",
45
47
  "verify:web": "npm run build",
46
48
  "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
47
49
  "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
48
- "eslint": "eslint . --ext .ts",
50
+ "eslint": "eslint . --ext .ts --ignore-path .eslintignore",
49
51
  "prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
50
52
  "swiftlint": "node-swiftlint",
51
53
  "docgen": "docgen --api SocialLoginPlugin --output-readme README.md --output-json dist/docs.json",
52
- "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
54
+ "build": "npm run clean && npm run docgen && npm run build:scripts && tsc && rollup -c rollup.config.mjs",
55
+ "build:scripts": "tsc -p scripts/tsconfig.json",
53
56
  "clean": "rimraf ./dist",
54
57
  "watch": "tsc --watch",
55
58
  "prepublishOnly": "npm run build"