@capgo/capacitor-social-login 0.0.10
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/CapgoCapacitorSocialLogin.podspec +21 -0
- package/Package.swift +37 -0
- package/README.md +457 -0
- package/android/build.gradle +64 -0
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/AppleProvider.java +376 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/FacebookProvider.java +175 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/GoogleProvider.java +305 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/SocialLoginPlugin.java +161 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/helpers/JsonHelper.java +18 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/helpers/SocialProvider.java +13 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
- package/android/src/main/res/layout/dialog_custom_layout.xml +43 -0
- package/android/src/main/res/values/styles.xml +14 -0
- package/dist/docs.json +613 -0
- package/dist/esm/definitions.d.ts +191 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +17 -0
- package/dist/esm/web.js +29 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +43 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +46 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/SocialLoginPlugin/AppleProvider.swift +516 -0
- package/ios/Sources/SocialLoginPlugin/FacebookProvider.swift +108 -0
- package/ios/Sources/SocialLoginPlugin/GoogleProvider.swift +165 -0
- package/ios/Sources/SocialLoginPlugin/SocialLoginPlugin.swift +322 -0
- package/ios/Tests/SocialLoginPluginTests/SocialLoginPluginTests.swift +15 -0
- package/package.json +87 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import GoogleSignIn
|
|
3
|
+
|
|
4
|
+
class GoogleProvider {
|
|
5
|
+
var configuration: GIDConfiguration!
|
|
6
|
+
var forceAuthCode: Bool = false
|
|
7
|
+
var additionalScopes: [String]!
|
|
8
|
+
|
|
9
|
+
func initialize(clientId: String) {
|
|
10
|
+
let serverClientId = getServerClientIdValue()
|
|
11
|
+
configuration = GIDConfiguration(clientID: clientId, serverClientID: serverClientId)
|
|
12
|
+
|
|
13
|
+
let defaultGrantedScopes = ["email", "profile", "openid"]
|
|
14
|
+
additionalScopes = []
|
|
15
|
+
|
|
16
|
+
forceAuthCode = false
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
func login(payload: [String: Any], completion: @escaping (Result<GoogleLoginResponse, Error>) -> Void) {
|
|
20
|
+
DispatchQueue.main.async {
|
|
21
|
+
if GIDSignIn.sharedInstance.hasPreviousSignIn() && !self.forceAuthCode {
|
|
22
|
+
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
|
|
23
|
+
if let error = error {
|
|
24
|
+
completion(.failure(error))
|
|
25
|
+
return
|
|
26
|
+
}
|
|
27
|
+
completion(.success(self.createLoginResponse(user: user!)))
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
guard let presentingVc = UIApplication.shared.windows.first?.rootViewController else {
|
|
31
|
+
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "No presenting view controller found"])))
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
GIDSignIn.sharedInstance.signIn(
|
|
36
|
+
withPresenting: presentingVc,
|
|
37
|
+
hint: nil,
|
|
38
|
+
additionalScopes: self.additionalScopes
|
|
39
|
+
) { result, error in
|
|
40
|
+
if let error = error {
|
|
41
|
+
completion(.failure(error))
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
guard let result = result else {
|
|
45
|
+
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "No result returned"])))
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
completion(.success(self.createLoginResponse(user: result.user)))
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func logout(completion: @escaping (Result<Void, Error>) -> Void) {
|
|
55
|
+
DispatchQueue.main.async {
|
|
56
|
+
GIDSignIn.sharedInstance.signOut()
|
|
57
|
+
completion(.success(()))
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
func isLoggedIn(completion: @escaping (Result<Bool, Error>) -> Void) {
|
|
62
|
+
DispatchQueue.main.async {
|
|
63
|
+
if GIDSignIn.sharedInstance.currentUser != nil {
|
|
64
|
+
completion(.success(true))
|
|
65
|
+
return
|
|
66
|
+
}
|
|
67
|
+
if GIDSignIn.sharedInstance.hasPreviousSignIn() {
|
|
68
|
+
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
|
|
69
|
+
if let error = error {
|
|
70
|
+
completion(.failure(error))
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
completion(.success(user != nil))
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
completion(.success(false))
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
func getAuthorizationCode(completion: @escaping (Result<String, Error>) -> Void) {
|
|
82
|
+
DispatchQueue.main.async {
|
|
83
|
+
if let currentUser = GIDSignIn.sharedInstance.currentUser, let idToken = currentUser.idToken?.tokenString {
|
|
84
|
+
completion(.success(idToken))
|
|
85
|
+
return
|
|
86
|
+
}
|
|
87
|
+
if GIDSignIn.sharedInstance.hasPreviousSignIn() {
|
|
88
|
+
GIDSignIn.sharedInstance.restorePreviousSignIn { user, error in
|
|
89
|
+
if let error = error {
|
|
90
|
+
completion(.failure(error))
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
if let user = user, let idToken = user.idToken?.tokenString {
|
|
94
|
+
completion(.success(idToken))
|
|
95
|
+
return
|
|
96
|
+
}
|
|
97
|
+
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "AuthorizationCode not found for google login"])))
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "AuthorizationCode not found for google login"])))
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
func getCurrentUser(completion: @escaping (Result<GoogleLoginResponse?, Error>) -> Void) {
|
|
106
|
+
if let user = GIDSignIn.sharedInstance.currentUser {
|
|
107
|
+
completion(.success(createLoginResponse(user: user)))
|
|
108
|
+
} else {
|
|
109
|
+
completion(.success(nil))
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
func refresh(completion: @escaping (Result<Void, Error>) -> Void) {
|
|
114
|
+
DispatchQueue.main.async {
|
|
115
|
+
guard let currentUser = GIDSignIn.sharedInstance.currentUser else {
|
|
116
|
+
completion(.failure(NSError(domain: "GoogleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "User not logged in"])))
|
|
117
|
+
return
|
|
118
|
+
}
|
|
119
|
+
currentUser.refreshTokensIfNeeded { _, error in
|
|
120
|
+
if let error = error {
|
|
121
|
+
completion(.failure(error))
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
completion(.success(()))
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
private func getServerClientIdValue() -> String? {
|
|
130
|
+
// Implement your logic to retrieve the server client ID
|
|
131
|
+
return nil
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private func createLoginResponse(user: GIDGoogleUser) -> GoogleLoginResponse {
|
|
135
|
+
return GoogleLoginResponse(
|
|
136
|
+
authentication: GoogleLoginResponse.Authentication(
|
|
137
|
+
accessToken: user.accessToken.tokenString,
|
|
138
|
+
idToken: user.idToken?.tokenString,
|
|
139
|
+
refreshToken: user.refreshToken.tokenString
|
|
140
|
+
),
|
|
141
|
+
email: user.profile?.email,
|
|
142
|
+
familyName: user.profile?.familyName,
|
|
143
|
+
givenName: user.profile?.givenName,
|
|
144
|
+
id: user.userID,
|
|
145
|
+
name: user.profile?.name,
|
|
146
|
+
imageUrl: user.profile?.imageURL(withDimension: 100)?.absoluteString
|
|
147
|
+
)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
struct GoogleLoginResponse {
|
|
152
|
+
let authentication: Authentication
|
|
153
|
+
let email: String?
|
|
154
|
+
let familyName: String?
|
|
155
|
+
let givenName: String?
|
|
156
|
+
let id: String?
|
|
157
|
+
let name: String?
|
|
158
|
+
let imageUrl: String?
|
|
159
|
+
|
|
160
|
+
struct Authentication {
|
|
161
|
+
let accessToken: String
|
|
162
|
+
let idToken: String?
|
|
163
|
+
let refreshToken: String?
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Please read the Capacitor iOS Plugin Development Guide
|
|
6
|
+
* here: https://capacitorjs.com/docs/plugins/ios
|
|
7
|
+
*/
|
|
8
|
+
@objc(SocialLoginPlugin)
|
|
9
|
+
public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
10
|
+
public let identifier = "SocialLoginPlugin"
|
|
11
|
+
public let jsName = "SocialLogin"
|
|
12
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
13
|
+
CAPPluginMethod(name: "login", returnType: CAPPluginReturnPromise),
|
|
14
|
+
CAPPluginMethod(name: "logout", returnType: CAPPluginReturnPromise),
|
|
15
|
+
CAPPluginMethod(name: "isLoggedIn", returnType: CAPPluginReturnPromise),
|
|
16
|
+
CAPPluginMethod(name: "getAuthorizationCode", returnType: CAPPluginReturnPromise),
|
|
17
|
+
CAPPluginMethod(name: "getUserInfo", returnType: CAPPluginReturnPromise),
|
|
18
|
+
CAPPluginMethod(name: "initialize", returnType: CAPPluginReturnPromise)
|
|
19
|
+
]
|
|
20
|
+
private let apple = AppleProvider()
|
|
21
|
+
private let facebook = FacebookProvider()
|
|
22
|
+
private let google = GoogleProvider()
|
|
23
|
+
|
|
24
|
+
@objc func initialize(_ call: CAPPluginCall) {
|
|
25
|
+
guard let options = call.options else {
|
|
26
|
+
call.reject("Missing options")
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var initialized = false
|
|
31
|
+
|
|
32
|
+
if let facebookSettings = call.getObject("facebook") {
|
|
33
|
+
if let facebookAppId = facebookSettings["appId"] as? String {
|
|
34
|
+
facebook.initialize()
|
|
35
|
+
initialized = true
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if let googleSettings = call.getObject("google") {
|
|
40
|
+
if let googleClientId = googleSettings["clientId"] as? String {
|
|
41
|
+
google.initialize(clientId: googleClientId)
|
|
42
|
+
initialized = true
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if let appleSettings = call.getObject("apple") {
|
|
47
|
+
if let appleClientId = appleSettings["clientId"] as? String,
|
|
48
|
+
let redirectUrl = appleSettings["redirectUrl"] as? String {
|
|
49
|
+
apple.initialize(clientId: appleClientId, redirectUrl: redirectUrl)
|
|
50
|
+
initialized = true
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if initialized {
|
|
55
|
+
call.resolve()
|
|
56
|
+
} else {
|
|
57
|
+
call.reject("No provider was initialized")
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@objc func getAuthorizationCode(_ call: CAPPluginCall) {
|
|
62
|
+
guard let provider = call.getString("provider") else {
|
|
63
|
+
call.reject("Missing provider or options")
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
switch provider {
|
|
68
|
+
case "apple": do {
|
|
69
|
+
if let idToken = apple.idToken {
|
|
70
|
+
if !idToken.isEmpty {
|
|
71
|
+
call.resolve([ "jwt": idToken ])
|
|
72
|
+
} else {
|
|
73
|
+
call.reject("IdToken is empty")
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
call.reject("IdToken is nil")
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
case "google": do {
|
|
80
|
+
self.google.getAuthorizationCode { res in
|
|
81
|
+
do {
|
|
82
|
+
let authorizationCode = try res.get()
|
|
83
|
+
call.resolve([ "jwt": authorizationCode ])
|
|
84
|
+
} catch {
|
|
85
|
+
call.reject(error.localizedDescription)
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
default:
|
|
90
|
+
call.reject("Invalid provider")
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@objc func isLoggedIn(_ call: CAPPluginCall) {
|
|
95
|
+
guard let provider = call.getString("provider") else {
|
|
96
|
+
call.reject("Missing provider or options")
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
switch provider {
|
|
101
|
+
case "apple": do {
|
|
102
|
+
if let idToken = apple.idToken {
|
|
103
|
+
if !idToken.isEmpty {
|
|
104
|
+
call.resolve([ "isLoggedIn": true ])
|
|
105
|
+
} else {
|
|
106
|
+
call.resolve([ "isLoggedIn": false ])
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
call.resolve([ "isLoggedIn": false ])
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
case "google": do {
|
|
113
|
+
self.google.isLoggedIn { res in
|
|
114
|
+
do {
|
|
115
|
+
let isLogged = try res.get()
|
|
116
|
+
call.resolve([ "isLoggedIn": isLogged ])
|
|
117
|
+
} catch {
|
|
118
|
+
call.reject(error.localizedDescription)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
default:
|
|
123
|
+
call.reject("Invalid provider")
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@objc func login(_ call: CAPPluginCall) {
|
|
128
|
+
guard let provider = call.getString("provider"),
|
|
129
|
+
let payload = call.getObject("options") else {
|
|
130
|
+
call.reject("Missing provider or options")
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
switch provider {
|
|
135
|
+
case "facebook":
|
|
136
|
+
facebook.login(payload: payload) { (result: Result<FacebookLoginResponse, Error>) in
|
|
137
|
+
self.handleLoginResult(result, call: call)
|
|
138
|
+
}
|
|
139
|
+
case "google":
|
|
140
|
+
google.login(payload: payload) { (result: Result<GoogleLoginResponse, Error>) in
|
|
141
|
+
self.handleLoginResult(result, call: call)
|
|
142
|
+
}
|
|
143
|
+
case "apple":
|
|
144
|
+
apple.login(payload: payload) { (result: Result<AppleProviderResponse, Error>) in
|
|
145
|
+
self.handleLoginResult(result, call: call)
|
|
146
|
+
}
|
|
147
|
+
default:
|
|
148
|
+
call.reject("Invalid provider")
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@objc func logout(_ call: CAPPluginCall) {
|
|
153
|
+
guard let provider = call.getString("provider") else {
|
|
154
|
+
call.reject("Missing provider")
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
switch provider {
|
|
159
|
+
case "facebook":
|
|
160
|
+
facebook.logout { result in
|
|
161
|
+
self.handleLogoutResult(result, call: call)
|
|
162
|
+
}
|
|
163
|
+
case "google":
|
|
164
|
+
google.logout { result in
|
|
165
|
+
self.handleLogoutResult(result, call: call)
|
|
166
|
+
}
|
|
167
|
+
case "apple":
|
|
168
|
+
apple.logout { result in
|
|
169
|
+
self.handleLogoutResult(result, call: call)
|
|
170
|
+
}
|
|
171
|
+
default:
|
|
172
|
+
call.reject("Invalid provider")
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@objc func getCurrentUser(_ call: CAPPluginCall) {
|
|
177
|
+
guard let provider = call.getString("provider") else {
|
|
178
|
+
call.reject("Missing provider")
|
|
179
|
+
return
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
switch provider {
|
|
183
|
+
case "facebook":
|
|
184
|
+
facebook.getCurrentUser { result in
|
|
185
|
+
self.handleCurrentUserResult(result, call: call)
|
|
186
|
+
}
|
|
187
|
+
case "google":
|
|
188
|
+
google.getCurrentUser { result in
|
|
189
|
+
self.handleCurrentUserResult(result, call: call)
|
|
190
|
+
}
|
|
191
|
+
case "apple":
|
|
192
|
+
apple.getCurrentUser { result in
|
|
193
|
+
self.handleCurrentUserResult(result, call: call)
|
|
194
|
+
}
|
|
195
|
+
default:
|
|
196
|
+
call.reject("Invalid provider")
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@objc func refresh(_ call: CAPPluginCall) {
|
|
201
|
+
guard let provider = call.getString("provider") else {
|
|
202
|
+
call.reject("Missing provider")
|
|
203
|
+
return
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
switch provider {
|
|
207
|
+
case "facebook":
|
|
208
|
+
facebook.refresh(viewController: self.bridge?.viewController) { result in
|
|
209
|
+
self.handleRefreshResult(result, call: call)
|
|
210
|
+
}
|
|
211
|
+
case "google":
|
|
212
|
+
google.refresh { result in
|
|
213
|
+
self.handleRefreshResult(result, call: call)
|
|
214
|
+
}
|
|
215
|
+
case "apple":
|
|
216
|
+
apple.refresh { result in
|
|
217
|
+
self.handleRefreshResult(result, call: call)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
default:
|
|
221
|
+
call.reject("Invalid provider")
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private func handleLogoutResult<T>(_ result: Result<T, Error>, call: CAPPluginCall) {
|
|
226
|
+
switch result {
|
|
227
|
+
case .success:
|
|
228
|
+
call.resolve()
|
|
229
|
+
case .failure(let error):
|
|
230
|
+
call.reject(error.localizedDescription)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
private func handleRefreshResult<T>(_ result: Result<T, Error>, call: CAPPluginCall) {
|
|
235
|
+
switch result {
|
|
236
|
+
case .success(let response):
|
|
237
|
+
if let user = response as? SocialLoginUser {
|
|
238
|
+
call.resolve([
|
|
239
|
+
"accessToken": user.accessToken,
|
|
240
|
+
"idToken": user.idToken,
|
|
241
|
+
"refreshToken": user.refreshToken,
|
|
242
|
+
"expiresIn": user.expiresIn
|
|
243
|
+
])
|
|
244
|
+
} else {
|
|
245
|
+
call.reject("Invalid refresh response")
|
|
246
|
+
}
|
|
247
|
+
case .failure(let error):
|
|
248
|
+
call.reject(error.localizedDescription)
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private func handleCurrentUserResult<T>(_ result: Result<T?, Error>, call: CAPPluginCall) {
|
|
253
|
+
switch result {
|
|
254
|
+
case .success(let response):
|
|
255
|
+
if let user = response as? SocialLoginUser {
|
|
256
|
+
call.resolve([
|
|
257
|
+
"accessToken": user.accessToken,
|
|
258
|
+
"idToken": user.idToken ?? "",
|
|
259
|
+
"refreshToken": user.refreshToken ?? "",
|
|
260
|
+
"expiresIn": user.expiresIn ?? 0
|
|
261
|
+
])
|
|
262
|
+
} else {
|
|
263
|
+
call.reject("User not logged in")
|
|
264
|
+
}
|
|
265
|
+
case .failure(let error):
|
|
266
|
+
call.reject(error.localizedDescription)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private func handleLoginResult<T>(_ result: Result<T, Error>, call: CAPPluginCall) {
|
|
271
|
+
switch result {
|
|
272
|
+
case .success(let response):
|
|
273
|
+
if let appleResponse = response as? AppleProviderResponse {
|
|
274
|
+
call.resolve([
|
|
275
|
+
"provider": "apple",
|
|
276
|
+
"result": [
|
|
277
|
+
"identityToken": appleResponse.identityToken
|
|
278
|
+
]
|
|
279
|
+
])
|
|
280
|
+
} else if let googleResponse = response as? GoogleLoginResponse {
|
|
281
|
+
call.resolve([
|
|
282
|
+
"provider": "google",
|
|
283
|
+
"result": [
|
|
284
|
+
"accessToken": [
|
|
285
|
+
"token": googleResponse.authentication.accessToken,
|
|
286
|
+
"userId": googleResponse.id ?? ""
|
|
287
|
+
],
|
|
288
|
+
"idToken": googleResponse.authentication.idToken ?? "",
|
|
289
|
+
// ""
|
|
290
|
+
"profile": [
|
|
291
|
+
"email": googleResponse.email ?? "",
|
|
292
|
+
"familyName": googleResponse.familyName ?? "",
|
|
293
|
+
"givenName": googleResponse.givenName ?? "",
|
|
294
|
+
"id": googleResponse.id ?? "",
|
|
295
|
+
"name": googleResponse.name ?? "",
|
|
296
|
+
"imageUrl": googleResponse.imageUrl ?? ""
|
|
297
|
+
]
|
|
298
|
+
]
|
|
299
|
+
])
|
|
300
|
+
} else if let facebookResponse = response as? FacebookLoginResponse {
|
|
301
|
+
call.resolve([
|
|
302
|
+
"provider": "facebook",
|
|
303
|
+
"result": [
|
|
304
|
+
"accessToken": facebookResponse.accessToken,
|
|
305
|
+
"profile": facebookResponse.profile
|
|
306
|
+
]
|
|
307
|
+
])
|
|
308
|
+
} else {
|
|
309
|
+
call.reject("Unsupported provider response")
|
|
310
|
+
}
|
|
311
|
+
case .failure(let error):
|
|
312
|
+
call.reject(error.localizedDescription)
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
struct SocialLoginUser {
|
|
318
|
+
let accessToken: String
|
|
319
|
+
let idToken: String?
|
|
320
|
+
let refreshToken: String?
|
|
321
|
+
let expiresIn: Int?
|
|
322
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
@testable import SocialLoginPlugin
|
|
3
|
+
|
|
4
|
+
class SocialLoginTests: XCTestCase {
|
|
5
|
+
func testEcho() {
|
|
6
|
+
// This is an example of a functional test case for a plugin.
|
|
7
|
+
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
|
8
|
+
|
|
9
|
+
let implementation = SocialLogin()
|
|
10
|
+
let value = "Hello, World!"
|
|
11
|
+
let result = implementation.echo(value)
|
|
12
|
+
|
|
13
|
+
XCTAssertEqual(value, result)
|
|
14
|
+
}
|
|
15
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capgo/capacitor-social-login",
|
|
3
|
+
"version": "0.0.10",
|
|
4
|
+
"description": "All social logins in one plugin",
|
|
5
|
+
"main": "dist/plugin.cjs.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"unpkg": "dist/plugin.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"android/src/main/",
|
|
11
|
+
"android/build.gradle",
|
|
12
|
+
"dist/",
|
|
13
|
+
"ios/Sources",
|
|
14
|
+
"ios/Tests",
|
|
15
|
+
"Package.swift",
|
|
16
|
+
"CapgoCapacitorSocialLogin.podspec"
|
|
17
|
+
],
|
|
18
|
+
"author": "Martin Donadieu <martin@capgo.app>",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/Cap-go/capacitor-social-login.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/Cap-go/capacitor-social-login/issues"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"capacitor",
|
|
29
|
+
"plugin",
|
|
30
|
+
"native",
|
|
31
|
+
"social",
|
|
32
|
+
"login"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
36
|
+
"verify:ios": "xcodebuild -scheme CapgoCapacitorSocialLogin -destination generic/platform=iOS",
|
|
37
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
38
|
+
"verify:web": "npm run build",
|
|
39
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
40
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --autocorrect --format",
|
|
41
|
+
"eslint": "eslint . --ext .ts",
|
|
42
|
+
"prettier": "prettier --config .prettierrc.js \"**/*.{css,html,ts,js,java}\"",
|
|
43
|
+
"swiftlint": "node-swiftlint",
|
|
44
|
+
"docgen": "docgen --api SocialLoginPlugin --output-readme README.md --output-json dist/docs.json",
|
|
45
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
46
|
+
"clean": "rimraf ./dist",
|
|
47
|
+
"watch": "tsc --watch",
|
|
48
|
+
"prepublishOnly": "npm run build"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@capacitor/android": "^6.0.0",
|
|
52
|
+
"@capacitor/cli": "^6.0.0",
|
|
53
|
+
"@capacitor/core": "^6.0.0",
|
|
54
|
+
"@capacitor/docgen": "^0.2.2",
|
|
55
|
+
"@capacitor/ios": "^6.0.0",
|
|
56
|
+
"@ionic/eslint-config": "^0.4.0",
|
|
57
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
58
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
59
|
+
"@types/node": "^20.12.12",
|
|
60
|
+
"@typescript-eslint/eslint-plugin": "^8.7.0",
|
|
61
|
+
"@typescript-eslint/parser": "^8.7.0",
|
|
62
|
+
"eslint": "^8.57.1",
|
|
63
|
+
"eslint-plugin-import": "^2.30.0",
|
|
64
|
+
"prettier": "^3.3.3",
|
|
65
|
+
"prettier-plugin-java": "^2.6.4",
|
|
66
|
+
"rimraf": "^6.0.1",
|
|
67
|
+
"rollup": "^4.22.4",
|
|
68
|
+
"swiftlint": "^2.0.0",
|
|
69
|
+
"typescript": "^5.4.5"
|
|
70
|
+
},
|
|
71
|
+
"peerDependencies": {
|
|
72
|
+
"@capacitor/core": "^6.0.0"
|
|
73
|
+
},
|
|
74
|
+
"prettier": "@ionic/prettier-config",
|
|
75
|
+
"eslintConfig": {
|
|
76
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
77
|
+
},
|
|
78
|
+
"capacitor": {
|
|
79
|
+
"ios": {
|
|
80
|
+
"src": "ios"
|
|
81
|
+
},
|
|
82
|
+
"android": {
|
|
83
|
+
"src": "android"
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"packageManager": "pnpm@9.9.0+sha512.60c18acd138bff695d339be6ad13f7e936eea6745660d4cc4a776d5247c540d0edee1a563695c183a66eb917ef88f2b4feb1fc25f32a7adcadc7aaf3438e99c1"
|
|
87
|
+
}
|