@capgo/capacitor-social-login 8.2.25 → 8.3.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.
@@ -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.2.25"
19
+ private let pluginVersion: String = "8.3.1"
20
20
  public let identifier = "SocialLoginPlugin"
21
21
  public let jsName = "SocialLogin"
22
22
  public let pluginMethods: [CAPPluginMethod] = [
@@ -27,6 +27,13 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
27
27
  CAPPluginMethod(name: "getUserInfo", returnType: CAPPluginReturnPromise),
28
28
  CAPPluginMethod(name: "initialize", returnType: CAPPluginReturnPromise),
29
29
  CAPPluginMethod(name: "refresh", returnType: CAPPluginReturnPromise),
30
+ CAPPluginMethod(name: "refreshToken", returnType: CAPPluginReturnPromise),
31
+ CAPPluginMethod(name: "handleRedirectCallback", returnType: CAPPluginReturnPromise),
32
+ CAPPluginMethod(name: "decodeIdToken", returnType: CAPPluginReturnPromise),
33
+ CAPPluginMethod(name: "getAccessTokenExpirationDate", returnType: CAPPluginReturnPromise),
34
+ CAPPluginMethod(name: "isAccessTokenAvailable", returnType: CAPPluginReturnPromise),
35
+ CAPPluginMethod(name: "isAccessTokenExpired", returnType: CAPPluginReturnPromise),
36
+ CAPPluginMethod(name: "isRefreshTokenAvailable", returnType: CAPPluginReturnPromise),
30
37
  CAPPluginMethod(name: "providerSpecificCall", returnType: CAPPluginReturnPromise),
31
38
  CAPPluginMethod(name: "getPluginVersion", returnType: CAPPluginReturnPromise),
32
39
  CAPPluginMethod(name: "openSecureWindow", returnType: CAPPluginReturnPromise)
@@ -613,6 +620,105 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
613
620
  }
614
621
  }
615
622
 
623
+ @objc func refreshToken(_ call: CAPPluginCall) {
624
+ guard let provider = call.getString("provider") else {
625
+ call.reject("Missing provider")
626
+ return
627
+ }
628
+ if provider != "oauth2" {
629
+ call.reject("refreshToken is only implemented for oauth2")
630
+ return
631
+ }
632
+ guard let providerId = call.getString("providerId") else {
633
+ call.reject("providerId is required for oauth2 refreshToken")
634
+ return
635
+ }
636
+ let refreshToken = call.getString("refreshToken")
637
+ var additionalParameters: [String: String]?
638
+ if let raw = call.getObject("additionalParameters") {
639
+ var out: [String: String] = [:]
640
+ for (k, v) in raw {
641
+ if let s = v as? String {
642
+ out[k] = s
643
+ }
644
+ }
645
+ if !out.isEmpty {
646
+ additionalParameters = out
647
+ }
648
+ }
649
+
650
+ oauth2.refreshToken(providerId: providerId, refreshToken: refreshToken, additionalParameters: additionalParameters) { result in
651
+ switch result {
652
+ case .success(let oauth2Response):
653
+ let accessToken: [String: Any] = [
654
+ "token": oauth2Response.accessToken.token,
655
+ "tokenType": oauth2Response.accessToken.tokenType,
656
+ "expires": oauth2Response.accessToken.expires ?? NSNull(),
657
+ "refreshToken": oauth2Response.accessToken.refreshToken ?? NSNull()
658
+ ]
659
+ let out: [String: Any] = [
660
+ "providerId": oauth2Response.providerId,
661
+ "accessToken": accessToken,
662
+ "idToken": oauth2Response.idToken ?? NSNull(),
663
+ "refreshToken": oauth2Response.refreshToken ?? NSNull(),
664
+ "resourceData": oauth2Response.resourceData ?? NSNull(),
665
+ "scope": oauth2Response.scope,
666
+ "tokenType": oauth2Response.tokenType,
667
+ "expiresIn": oauth2Response.expiresIn ?? NSNull()
668
+ ]
669
+ call.resolve(out)
670
+ case .failure(let err):
671
+ call.reject(err.localizedDescription)
672
+ }
673
+ }
674
+ }
675
+
676
+ @objc func handleRedirectCallback(_ call: CAPPluginCall) {
677
+ call.reject("handleRedirectCallback is only available on web")
678
+ }
679
+
680
+ @objc func decodeIdToken(_ call: CAPPluginCall) {
681
+ let idToken = call.getString("idToken") ?? call.getString("token")
682
+ guard let idToken = idToken, !idToken.isEmpty else {
683
+ call.reject("idToken (or token) is required")
684
+ return
685
+ }
686
+ do {
687
+ let claims = try self.decodeJwtClaims(idToken: idToken)
688
+ call.resolve(["claims": claims])
689
+ } catch {
690
+ call.reject(error.localizedDescription)
691
+ }
692
+ }
693
+
694
+ @objc func getAccessTokenExpirationDate(_ call: CAPPluginCall) {
695
+ guard let ms = call.getDouble("accessTokenExpirationDate") else {
696
+ call.reject("accessTokenExpirationDate is required")
697
+ return
698
+ }
699
+ let date = Date(timeIntervalSince1970: ms / 1000.0)
700
+ call.resolve(["date": ISO8601DateFormatter().string(from: date)])
701
+ }
702
+
703
+ @objc func isAccessTokenAvailable(_ call: CAPPluginCall) {
704
+ let token = call.getString("accessToken")
705
+ call.resolve(["isAvailable": (token?.isEmpty == false)])
706
+ }
707
+
708
+ @objc func isAccessTokenExpired(_ call: CAPPluginCall) {
709
+ guard let ms = call.getDouble("accessTokenExpirationDate") else {
710
+ call.reject("accessTokenExpirationDate is required")
711
+ return
712
+ }
713
+ let nowMs = Date().timeIntervalSince1970 * 1000.0
714
+ call.resolve(["isExpired": ms <= nowMs])
715
+ }
716
+
717
+ @objc func isRefreshTokenAvailable(_ call: CAPPluginCall) {
718
+ let token = call.getString("refreshToken")
719
+ call.resolve(["isAvailable": (token?.isEmpty == false)])
720
+ }
721
+
616
722
  @objc func openSecureWindow(_ call: CAPPluginCall) {
617
723
  guard let urlString = call.getString("authEndpoint") else {
618
724
  call.reject("authEndpoint is required")
@@ -666,6 +772,28 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
666
772
  }
667
773
  }
668
774
 
775
+ private func decodeJwtClaims(idToken: String) throws -> [String: Any] {
776
+ let parts = idToken.split(separator: ".")
777
+ if parts.count < 2 {
778
+ throw NSError(domain: "SocialLogin", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid JWT"])
779
+ }
780
+ let payload = String(parts[1])
781
+ guard let data = base64UrlDecode(payload) else {
782
+ throw NSError(domain: "SocialLogin", code: -2, userInfo: [NSLocalizedDescriptionKey: "Invalid JWT payload encoding"])
783
+ }
784
+ let obj = try JSONSerialization.jsonObject(with: data)
785
+ return obj as? [String: Any] ?? [:]
786
+ }
787
+
788
+ private func base64UrlDecode(_ value: String) -> Data? {
789
+ var base64 = value.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
790
+ let padding = 4 - (base64.count % 4)
791
+ if padding < 4 {
792
+ base64 += String(repeating: "=", count: padding)
793
+ }
794
+ return Data(base64Encoded: base64)
795
+ }
796
+
669
797
  private func handleLogoutResult<T>(_ result: Result<T, Error>, call: CAPPluginCall) {
670
798
  switch result {
671
799
  case .success:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capgo/capacitor-social-login",
3
- "version": "8.2.25",
3
+ "version": "8.3.1",
4
4
  "description": "All social logins in one plugin",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",
@@ -44,21 +44,21 @@
44
44
  ],
45
45
  "scripts": {
46
46
  "capacitor:sync:before": "node scripts/configure-dependencies.js",
47
- "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
47
+ "verify": "bun run verify:ios && bun run verify:android && bun run verify:web",
48
48
  "verify:ios": "xcodebuild -scheme CapgoCapacitorSocialLogin -destination generic/platform=iOS",
49
49
  "verify:android": "cd android && ./gradlew clean build test && cd ..",
50
- "verify:web": "npm run build",
51
- "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
52
- "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
50
+ "verify:web": "bun run build",
51
+ "lint": "bun run eslint && bun run prettier -- --check && bun run swiftlint -- lint",
52
+ "fmt": "bun run eslint -- --fix && bun run prettier -- --write && bun run swiftlint -- --fix --format",
53
53
  "eslint": "eslint . --ext .ts --ignore-path .eslintignore",
54
54
  "prettier": "prettier-pretty-check \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
55
55
  "swiftlint": "node-swiftlint",
56
56
  "docgen": "docgen --api SocialLoginPlugin --output-readme README.md --output-json dist/docs.json",
57
- "build": "npm run clean && npm run docgen && npm run build:scripts && tsc && rollup -c rollup.config.mjs",
57
+ "build": "bun run clean && bun run docgen && bun run build:scripts && tsc && rollup -c rollup.config.mjs",
58
58
  "build:scripts": "tsc -p scripts/tsconfig.json",
59
59
  "clean": "rimraf ./dist",
60
60
  "watch": "tsc --watch",
61
- "prepublishOnly": "npm run build",
61
+ "prepublishOnly": "bun run build",
62
62
  "check:wiring": "node scripts/check-capacitor-plugin-wiring.mjs"
63
63
  },
64
64
  "devDependencies": {