@capgo/capacitor-social-login 0.0.16 → 0.0.28
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 +2 -2
- package/Package.swift +2 -1
- package/README.md +17 -12
- package/android/build.gradle +2 -1
- package/android/src/main/java/ee/forgr/capacitor/social/login/AppleProvider.java +205 -199
- package/android/src/main/java/ee/forgr/capacitor/social/login/GoogleProvider.java +25 -9
- package/android/src/main/java/ee/forgr/capacitor/social/login/SocialLoginPlugin.java +20 -2
- package/dist/docs.json +15 -15
- package/dist/esm/definitions.d.ts +24 -11
- package/dist/esm/definitions.js.map +1 -1
- package/ios/Sources/SocialLoginPlugin/AppleProvider.swift +4 -9
- package/ios/Sources/SocialLoginPlugin/FacebookProvider.swift +5 -0
- package/ios/Sources/SocialLoginPlugin/GoogleProvider.swift +5 -4
- package/ios/Sources/SocialLoginPlugin/SocialLoginPlugin.swift +14 -5
- package/package.json +1 -1
|
@@ -13,8 +13,8 @@ Pod::Spec.new do |s|
|
|
|
13
13
|
s.source_files = 'ios/Sources/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
14
|
s.ios.deployment_target = '13.0'
|
|
15
15
|
s.dependency 'Capacitor'
|
|
16
|
-
s.dependency 'FBSDKCoreKit', '17.
|
|
17
|
-
s.dependency 'FBSDKLoginKit', '17.
|
|
16
|
+
s.dependency 'FBSDKCoreKit', '17.3.0'
|
|
17
|
+
s.dependency 'FBSDKLoginKit', '17.3.0'
|
|
18
18
|
s.dependency 'GoogleSignIn', '~> 8.0.0'
|
|
19
19
|
s.dependency 'Alamofire'
|
|
20
20
|
s.swift_version = '5.1'
|
package/Package.swift
CHANGED
|
@@ -12,7 +12,7 @@ let package = Package(
|
|
|
12
12
|
dependencies: [
|
|
13
13
|
.package(url: "https://github.com/ionic-team/capacitor-swift-pm.git", branch: "main"),
|
|
14
14
|
// FBSDKCoreKit and FBSDKLoginKit
|
|
15
|
-
.package(url: "https://github.com/facebook/facebook-ios-sdk.git", .upToNextMajor(from: "17.
|
|
15
|
+
.package(url: "https://github.com/facebook/facebook-ios-sdk.git", .upToNextMajor(from: "17.3.0")),
|
|
16
16
|
// Add Google Sign-In dependency
|
|
17
17
|
.package(url: "https://github.com/google/GoogleSignIn-iOS.git", .upToNextMajor(from: "8.0.0")),
|
|
18
18
|
// Alamofire
|
|
@@ -24,6 +24,7 @@ let package = Package(
|
|
|
24
24
|
dependencies: [
|
|
25
25
|
.product(name: "Capacitor", package: "capacitor-swift-pm"),
|
|
26
26
|
.product(name: "Cordova", package: "capacitor-swift-pm"),
|
|
27
|
+
.product(name: "FacebookCore", package: "facebook-ios-sdk"),
|
|
27
28
|
.product(name: "FacebookLogin", package: "facebook-ios-sdk"),
|
|
28
29
|
.product(name: "GoogleSignIn", package: "GoogleSignIn-iOS"),
|
|
29
30
|
.product(name: "Alamofire", package: "Alamofire")
|
package/README.md
CHANGED
|
@@ -24,6 +24,9 @@ npx cap sync
|
|
|
24
24
|
|
|
25
25
|
## Apple
|
|
26
26
|
|
|
27
|
+
[How to get the credentials](https://github.com/Cap-go/capacitor-social-login/blob/main/docs/setup_apple.md)
|
|
28
|
+
[How to setup redirect url](https://github.com/Cap-go/capacitor-social-login/blob/main/docs/apple_redirect_url.png)
|
|
29
|
+
|
|
27
30
|
### Android configuration
|
|
28
31
|
|
|
29
32
|
For android you need a server to get the callback from the apple login. As we use the web SDK .
|
|
@@ -195,6 +198,8 @@ const res = await SocialLogin.login({
|
|
|
195
198
|
|
|
196
199
|
## Google
|
|
197
200
|
|
|
201
|
+
[How to get the credentials](https://github.com/Cap-go/capacitor-social-login/blob/main/docs/setup_google.md)
|
|
202
|
+
|
|
198
203
|
### Android configuration
|
|
199
204
|
|
|
200
205
|
Directly call the `initialize` method with the `google` provider
|
|
@@ -349,11 +354,11 @@ Refresh the access token
|
|
|
349
354
|
|
|
350
355
|
#### InitializeOptions
|
|
351
356
|
|
|
352
|
-
| Prop | Type
|
|
353
|
-
| -------------- |
|
|
354
|
-
| **`facebook`** | <code>{ appId: string; }</code>
|
|
355
|
-
| **`google`** | <code>{
|
|
356
|
-
| **`apple`** | <code>{ clientId
|
|
357
|
+
| Prop | Type |
|
|
358
|
+
| -------------- | ---------------------------------------------------------------------------------------- |
|
|
359
|
+
| **`facebook`** | <code>{ appId: string; }</code> |
|
|
360
|
+
| **`google`** | <code>{ iOSClientId?: string; iOSServerClientId?: string; webclientId?: string; }</code> |
|
|
361
|
+
| **`apple`** | <code>{ clientId?: string; redirectUrl?: string; }</code> |
|
|
357
362
|
|
|
358
363
|
|
|
359
364
|
#### LoginResult
|
|
@@ -404,7 +409,7 @@ Refresh the access token
|
|
|
404
409
|
| **`givenName`** | <code>string \| null</code> |
|
|
405
410
|
| **`familyName`** | <code>string \| null</code> |
|
|
406
411
|
| **`identityToken`** | <code>string \| null</code> |
|
|
407
|
-
| **`authorizationCode`** | <code>string</code>
|
|
412
|
+
| **`authorizationCode`** | <code>string \| null</code> |
|
|
408
413
|
|
|
409
414
|
|
|
410
415
|
#### LoginOptions
|
|
@@ -427,17 +432,17 @@ Refresh the access token
|
|
|
427
432
|
| Prop | Type | Description | Default | Since |
|
|
428
433
|
| ------------------------ | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
|
|
429
434
|
| **`scopes`** | <code>string[]</code> | Specifies the scopes required for accessing Google APIs The default is defined in the configuration. | | |
|
|
435
|
+
| **`nonce`** | <code>string</code> | Nonce | | |
|
|
430
436
|
| **`grantOfflineAccess`** | <code>boolean</code> | Set if your application needs to refresh access tokens when the user is not present at the browser. In response use `serverAuthCode` key | <code>false</code> | 3.1.0 |
|
|
431
437
|
|
|
432
438
|
|
|
433
439
|
#### AppleProviderOptions
|
|
434
440
|
|
|
435
|
-
| Prop
|
|
436
|
-
|
|
|
437
|
-
| **`scopes`**
|
|
438
|
-
| **`
|
|
439
|
-
| **`
|
|
440
|
-
| **`state`** | <code>string</code> | State |
|
|
441
|
+
| Prop | Type | Description |
|
|
442
|
+
| ------------ | --------------------- | ----------- |
|
|
443
|
+
| **`scopes`** | <code>string[]</code> | Scopes |
|
|
444
|
+
| **`nonce`** | <code>string</code> | Nonce |
|
|
445
|
+
| **`state`** | <code>string</code> | State |
|
|
441
446
|
|
|
442
447
|
|
|
443
448
|
#### isLoggedInOptions
|
package/android/build.gradle
CHANGED
|
@@ -56,8 +56,9 @@ dependencies {
|
|
|
56
56
|
implementation 'com.squareup.okhttp3:okhttp:4.9.1'
|
|
57
57
|
implementation 'com.auth0.android:jwtdecode:2.0.2'
|
|
58
58
|
implementation "androidx.credentials:credentials:1.2.2"
|
|
59
|
-
implementation "androidx.credentials:credentials-play-services-auth:1.
|
|
59
|
+
implementation "androidx.credentials:credentials-play-services-auth:1.3.0"
|
|
60
60
|
implementation "com.google.android.libraries.identity.googleid:googleid:1.1.1"
|
|
61
|
+
implementation 'com.google.androidbrowserhelper:androidbrowserhelper:2.4.0'
|
|
61
62
|
testImplementation "junit:junit:$junitVersion"
|
|
62
63
|
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
63
64
|
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
@@ -3,7 +3,9 @@ package ee.forgr.capacitor.social.login;
|
|
|
3
3
|
import android.annotation.SuppressLint;
|
|
4
4
|
import android.app.Activity;
|
|
5
5
|
import android.app.Dialog;
|
|
6
|
+
import android.content.ComponentName;
|
|
6
7
|
import android.content.Context;
|
|
8
|
+
import android.content.Intent;
|
|
7
9
|
import android.graphics.Bitmap;
|
|
8
10
|
import android.graphics.Color;
|
|
9
11
|
import android.graphics.Rect;
|
|
@@ -12,6 +14,7 @@ import android.net.Uri;
|
|
|
12
14
|
import android.util.Log;
|
|
13
15
|
import android.view.Gravity;
|
|
14
16
|
import android.view.View;
|
|
17
|
+
import android.view.ViewGroup;
|
|
15
18
|
import android.view.Window;
|
|
16
19
|
import android.view.WindowManager;
|
|
17
20
|
import android.webkit.WebResourceRequest;
|
|
@@ -20,9 +23,16 @@ import android.webkit.WebViewClient;
|
|
|
20
23
|
import android.widget.ImageButton;
|
|
21
24
|
import android.widget.ProgressBar;
|
|
22
25
|
import androidx.annotation.NonNull;
|
|
26
|
+
import androidx.browser.customtabs.CustomTabsCallback;
|
|
27
|
+
import androidx.browser.customtabs.CustomTabsClient;
|
|
28
|
+
import androidx.browser.customtabs.CustomTabsIntent;
|
|
29
|
+
import androidx.browser.customtabs.CustomTabsServiceConnection;
|
|
30
|
+
import androidx.browser.customtabs.CustomTabsSession;
|
|
31
|
+
import androidx.browser.trusted.TrustedWebActivityIntentBuilder;
|
|
23
32
|
import com.auth0.android.jwt.JWT;
|
|
24
33
|
import com.getcapacitor.JSObject;
|
|
25
34
|
import com.getcapacitor.PluginCall;
|
|
35
|
+
import com.google.androidbrowserhelper.trusted.TwaLauncher;
|
|
26
36
|
import ee.forgr.capacitor.social.login.helpers.SocialProvider;
|
|
27
37
|
import java.io.IOException;
|
|
28
38
|
import java.util.Objects;
|
|
@@ -45,9 +55,11 @@ public class AppleProvider implements SocialProvider {
|
|
|
45
55
|
private static final String TOKENURL = "https://appleid.apple.com/auth/token";
|
|
46
56
|
private static final String SHARED_PREFERENCE_NAME =
|
|
47
57
|
"APPLE_LOGIN_Q16ob0k_SHARED_PERF";
|
|
58
|
+
private static final String APPLE_DATA_PREFERENCE =
|
|
59
|
+
"APPLE_LOGIN_APPLE_DATA_83b2d6db-17fe-49c9-8c33-e3f5d02f9f84";
|
|
48
60
|
|
|
61
|
+
private PluginCall lastcall;
|
|
49
62
|
private String appleAuthURLFull;
|
|
50
|
-
private Dialog appledialog;
|
|
51
63
|
|
|
52
64
|
private String idToken;
|
|
53
65
|
private String refreshToken;
|
|
@@ -58,6 +70,22 @@ public class AppleProvider implements SocialProvider {
|
|
|
58
70
|
private final Activity activity;
|
|
59
71
|
private final Context context;
|
|
60
72
|
|
|
73
|
+
private CustomTabsClient customTabsClient;
|
|
74
|
+
private CustomTabsSession currentSession;
|
|
75
|
+
CustomTabsServiceConnection connection = new CustomTabsServiceConnection() {
|
|
76
|
+
@Override
|
|
77
|
+
public void onCustomTabsServiceConnected(
|
|
78
|
+
@NonNull ComponentName name,
|
|
79
|
+
CustomTabsClient client
|
|
80
|
+
) {
|
|
81
|
+
customTabsClient = client;
|
|
82
|
+
client.warmup(0);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Override
|
|
86
|
+
public void onServiceDisconnected(ComponentName name) {}
|
|
87
|
+
};
|
|
88
|
+
|
|
61
89
|
public AppleProvider(
|
|
62
90
|
String redirectUrl,
|
|
63
91
|
String clientId,
|
|
@@ -70,18 +98,71 @@ public class AppleProvider implements SocialProvider {
|
|
|
70
98
|
this.context = context;
|
|
71
99
|
}
|
|
72
100
|
|
|
73
|
-
public void initialize(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
101
|
+
public void initialize() {
|
|
102
|
+
String data = context
|
|
103
|
+
.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE)
|
|
104
|
+
.getString(APPLE_DATA_PREFERENCE, null);
|
|
105
|
+
|
|
106
|
+
if (data == null || data.isEmpty()) {
|
|
107
|
+
Log.i(SocialLoginPlugin.LOG_TAG, "No data to restore for apple login");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
JSONObject object = new JSONObject(data);
|
|
112
|
+
String idToken = object.optString("idToken", null);
|
|
113
|
+
String refreshToken = object.optString("refreshToken", null);
|
|
114
|
+
String accessToken = object.optString("accessToken", null);
|
|
115
|
+
AppleProvider.this.idToken = idToken;
|
|
116
|
+
AppleProvider.this.refreshToken = refreshToken;
|
|
117
|
+
AppleProvider.this.accessToken = accessToken;
|
|
118
|
+
Log.i(
|
|
119
|
+
SocialLoginPlugin.LOG_TAG,
|
|
120
|
+
String.format("Apple restoreState: %s", object)
|
|
121
|
+
);
|
|
122
|
+
} catch (JSONException e) {
|
|
123
|
+
Log.e(
|
|
124
|
+
SocialLoginPlugin.LOG_TAG,
|
|
125
|
+
"Apple restoreState: Failed to parse JSON",
|
|
126
|
+
e
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
public void handleIntent(Intent intent) {
|
|
132
|
+
// Extract information from the URI
|
|
133
|
+
Uri data = intent.getData();
|
|
134
|
+
|
|
135
|
+
// Data should never be null
|
|
136
|
+
assert data != null;
|
|
137
|
+
|
|
138
|
+
String scheme = data.getScheme(); // "capgo-demo-app"
|
|
139
|
+
String host = data.getHost(); // "path"
|
|
140
|
+
String path = data.getPath(); // Additional path segments
|
|
141
|
+
String query = data.getQuery(); // Query parameters
|
|
142
|
+
|
|
77
143
|
Log.i(
|
|
78
144
|
SocialLoginPlugin.LOG_TAG,
|
|
79
|
-
String.format(
|
|
145
|
+
String.format(
|
|
146
|
+
"Recieved apple login intent: %s, %s, %s, %s",
|
|
147
|
+
scheme,
|
|
148
|
+
host,
|
|
149
|
+
path,
|
|
150
|
+
query
|
|
151
|
+
)
|
|
80
152
|
);
|
|
153
|
+
|
|
154
|
+
handleUrl(data.toString());
|
|
155
|
+
// if (data.toString().contains("success=")) {
|
|
156
|
+
// this.currentSession.
|
|
157
|
+
// }
|
|
81
158
|
}
|
|
82
159
|
|
|
83
160
|
@Override
|
|
84
161
|
public void login(PluginCall call, JSONObject config) {
|
|
162
|
+
if (this.lastcall != null) {
|
|
163
|
+
call.reject("Last call is not null");
|
|
164
|
+
}
|
|
165
|
+
|
|
85
166
|
String state = UUID.randomUUID().toString();
|
|
86
167
|
this.appleAuthURLFull = AUTHURL +
|
|
87
168
|
"?client_id=" +
|
|
@@ -98,6 +179,7 @@ public class AppleProvider implements SocialProvider {
|
|
|
98
179
|
return;
|
|
99
180
|
}
|
|
100
181
|
|
|
182
|
+
this.lastcall = call;
|
|
101
183
|
call.setKeepAlive(true);
|
|
102
184
|
activity.runOnUiThread(() ->
|
|
103
185
|
setupWebview(context, activity, call, appleAuthURLFull)
|
|
@@ -126,7 +208,7 @@ public class AppleProvider implements SocialProvider {
|
|
|
126
208
|
@Override
|
|
127
209
|
public void getAuthorizationCode(PluginCall call) {
|
|
128
210
|
if (this.idToken != null && !this.idToken.isEmpty()) {
|
|
129
|
-
call.resolve(new JSObject().put("
|
|
211
|
+
call.resolve(new JSObject().put("jwt", this.idToken));
|
|
130
212
|
} else {
|
|
131
213
|
call.reject("Apple-login not logged in!");
|
|
132
214
|
}
|
|
@@ -157,161 +239,131 @@ public class AppleProvider implements SocialProvider {
|
|
|
157
239
|
call.reject("Not implemented");
|
|
158
240
|
}
|
|
159
241
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
public boolean shouldOverrideUrlLoading(
|
|
181
|
-
WebView view,
|
|
182
|
-
WebResourceRequest request
|
|
183
|
-
) {
|
|
184
|
-
String url = request.getUrl().toString();
|
|
185
|
-
if (url.startsWith(redirectUrl)) {
|
|
186
|
-
handleUrl(url);
|
|
187
|
-
if (url.contains("success=")) {
|
|
188
|
-
appledialog.dismiss();
|
|
189
|
-
}
|
|
190
|
-
return true;
|
|
191
|
-
}
|
|
192
|
-
return false;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
@Override
|
|
196
|
-
public void onPageFinished(WebView view, String url) {
|
|
197
|
-
super.onPageFinished(view, url);
|
|
198
|
-
Rect displayRectangle = new Rect();
|
|
199
|
-
Window window = activity.getWindow();
|
|
200
|
-
window.getDecorView().getWindowVisibleDisplayFrame(displayRectangle);
|
|
201
|
-
view.setLayoutParams(
|
|
202
|
-
new android.view.ViewGroup.LayoutParams(
|
|
203
|
-
android.view.ViewGroup.LayoutParams.MATCH_PARENT,
|
|
204
|
-
(int) (displayRectangle.height() * 0.9f)
|
|
205
|
-
)
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
private void handleUrl(String url) {
|
|
210
|
-
Uri uri = Uri.parse(url);
|
|
211
|
-
String success = uri.getQueryParameter("success");
|
|
212
|
-
if ("true".equals(success)) {
|
|
213
|
-
String accessToken = uri.getQueryParameter("access_token");
|
|
214
|
-
if (accessToken != null) {
|
|
215
|
-
String refreshToken = uri.getQueryParameter("refresh_token");
|
|
216
|
-
String idToken = uri.getQueryParameter("id_token");
|
|
217
|
-
try {
|
|
218
|
-
persistState(idToken, refreshToken, accessToken);
|
|
219
|
-
call.resolve(new JSObject().put("success", true));
|
|
220
|
-
} catch (JSONException e) {
|
|
221
|
-
Log.e(SocialLoginPlugin.LOG_TAG, "Cannot persist state", e);
|
|
222
|
-
call.reject("Cannot persist state", e);
|
|
223
|
-
}
|
|
224
|
-
} else {
|
|
225
|
-
String appleAuthCode = uri.getQueryParameter("code");
|
|
226
|
-
String appleClientSecret = uri.getQueryParameter("client_secret");
|
|
227
|
-
requestForAccessToken(appleAuthCode, appleClientSecret);
|
|
242
|
+
public void handleUrl(String url) {
|
|
243
|
+
Uri uri = Uri.parse(url);
|
|
244
|
+
String success = uri.getQueryParameter("success");
|
|
245
|
+
if ("true".equals(success)) {
|
|
246
|
+
String accessToken = uri.getQueryParameter("access_token");
|
|
247
|
+
if (accessToken != null) {
|
|
248
|
+
String refreshToken = uri.getQueryParameter("refresh_token");
|
|
249
|
+
String idToken = uri.getQueryParameter("id_token");
|
|
250
|
+
try {
|
|
251
|
+
persistState(idToken, refreshToken, accessToken);
|
|
252
|
+
this.lastcall.resolve(
|
|
253
|
+
new JSObject()
|
|
254
|
+
.put("provider", "apple")
|
|
255
|
+
.put("result", new JSObject().put("identityToken", idToken))
|
|
256
|
+
);
|
|
257
|
+
this.lastcall = null;
|
|
258
|
+
} catch (JSONException e) {
|
|
259
|
+
Log.e(SocialLoginPlugin.LOG_TAG, "Cannot persist state", e);
|
|
260
|
+
this.lastcall.reject("Cannot persist state", e);
|
|
261
|
+
this.lastcall = null;
|
|
228
262
|
}
|
|
229
263
|
} else {
|
|
230
|
-
|
|
264
|
+
String appleAuthCode = uri.getQueryParameter("code");
|
|
265
|
+
String appleClientSecret = uri.getQueryParameter("client_secret");
|
|
266
|
+
requestForAccessToken(appleAuthCode, appleClientSecret);
|
|
231
267
|
}
|
|
268
|
+
} else {
|
|
269
|
+
this.lastcall.reject("We couldn't get the Auth Code");
|
|
270
|
+
this.lastcall = null;
|
|
232
271
|
}
|
|
272
|
+
}
|
|
233
273
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
274
|
+
private void requestForAccessToken(String code, String clientSecret) {
|
|
275
|
+
OkHttpClient client = new OkHttpClient();
|
|
276
|
+
FormBody formBody = new FormBody.Builder()
|
|
277
|
+
.add("grant_type", "authorization_code")
|
|
278
|
+
.add("code", code)
|
|
279
|
+
.add("redirect_uri", redirectUrl)
|
|
280
|
+
.add("client_id", clientId)
|
|
281
|
+
.add("client_secret", clientSecret)
|
|
282
|
+
.build();
|
|
283
|
+
|
|
284
|
+
Request request = new Request.Builder()
|
|
285
|
+
.url(TOKENURL)
|
|
286
|
+
.post(formBody)
|
|
287
|
+
.build();
|
|
288
|
+
|
|
289
|
+
client
|
|
290
|
+
.newCall(request)
|
|
291
|
+
.enqueue(
|
|
292
|
+
new Callback() {
|
|
293
|
+
@Override
|
|
294
|
+
public void onFailure(@NonNull Call call, @NonNull IOException e) {
|
|
295
|
+
AppleProvider.this.lastcall.reject("Cannot get access_token", e);
|
|
296
|
+
AppleProvider.this.lastcall = null;
|
|
297
|
+
}
|
|
257
298
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
299
|
+
@Override
|
|
300
|
+
public void onResponse(
|
|
301
|
+
@NonNull Call call,
|
|
302
|
+
@NonNull Response response
|
|
303
|
+
) throws IOException {
|
|
304
|
+
try {
|
|
305
|
+
if (!response.isSuccessful()) throw new IOException(
|
|
306
|
+
"Unexpected code " + response
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
String responseData = Objects.requireNonNull(
|
|
310
|
+
response.body()
|
|
311
|
+
).string();
|
|
312
|
+
JSONObject jsonObject = (JSONObject) new JSONTokener(
|
|
313
|
+
responseData
|
|
314
|
+
).nextValue();
|
|
315
|
+
String accessToken = jsonObject.getString("access_token");
|
|
316
|
+
String refreshToken = jsonObject.getString("refresh_token");
|
|
317
|
+
String idToken = jsonObject.getString("id_token");
|
|
318
|
+
|
|
319
|
+
persistState(idToken, refreshToken, accessToken);
|
|
320
|
+
AppleProvider.this.lastcall.resolve(
|
|
321
|
+
new JSObject()
|
|
322
|
+
.put("provider", "apple")
|
|
323
|
+
.put("result", new JSObject().put("identityToken", idToken))
|
|
266
324
|
);
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
).nextValue();
|
|
274
|
-
String accessToken = jsonObject.getString("access_token");
|
|
275
|
-
String refreshToken = jsonObject.getString("refresh_token");
|
|
276
|
-
String idToken = jsonObject.getString("id_token");
|
|
277
|
-
|
|
278
|
-
persistState(idToken, refreshToken, accessToken);
|
|
279
|
-
AppleWebViewClient.this.call.resolve(
|
|
280
|
-
new JSObject().put("success", true)
|
|
281
|
-
);
|
|
282
|
-
} catch (Exception e) {
|
|
283
|
-
AppleWebViewClient.this.call.reject(
|
|
284
|
-
"Cannot get access_token",
|
|
285
|
-
e
|
|
286
|
-
);
|
|
287
|
-
} finally {
|
|
288
|
-
response.close();
|
|
289
|
-
}
|
|
325
|
+
AppleProvider.this.lastcall = null;
|
|
326
|
+
} catch (Exception e) {
|
|
327
|
+
AppleProvider.this.lastcall.reject("Cannot get access_token", e);
|
|
328
|
+
AppleProvider.this.lastcall = null;
|
|
329
|
+
} finally {
|
|
330
|
+
response.close();
|
|
290
331
|
}
|
|
291
332
|
}
|
|
292
|
-
|
|
293
|
-
|
|
333
|
+
}
|
|
334
|
+
);
|
|
335
|
+
}
|
|
294
336
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
337
|
+
private void persistState(
|
|
338
|
+
String idToken,
|
|
339
|
+
String refreshToken,
|
|
340
|
+
String accessToken
|
|
341
|
+
) throws JSONException {
|
|
342
|
+
JSONObject object = new JSONObject();
|
|
343
|
+
object.put("idToken", idToken);
|
|
344
|
+
object.put("refreshToken", refreshToken);
|
|
345
|
+
object.put("accessToken", accessToken);
|
|
346
|
+
|
|
347
|
+
AppleProvider.this.idToken = idToken;
|
|
348
|
+
AppleProvider.this.refreshToken = refreshToken;
|
|
349
|
+
AppleProvider.this.accessToken = accessToken;
|
|
350
|
+
|
|
351
|
+
activity
|
|
352
|
+
.getSharedPreferences(SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE)
|
|
353
|
+
.edit()
|
|
354
|
+
.putString(APPLE_DATA_PREFERENCE, object.toString())
|
|
355
|
+
.apply();
|
|
356
|
+
}
|
|
304
357
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
358
|
+
public CustomTabsSession getCustomTabsSession() {
|
|
359
|
+
if (customTabsClient == null) {
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
308
362
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
.edit()
|
|
312
|
-
.putString(SHARED_PREFERENCE_NAME, object.toString())
|
|
313
|
-
.apply();
|
|
363
|
+
if (currentSession == null) {
|
|
364
|
+
currentSession = customTabsClient.newSession(new CustomTabsCallback() {});
|
|
314
365
|
}
|
|
366
|
+
return currentSession;
|
|
315
367
|
}
|
|
316
368
|
|
|
317
369
|
@SuppressLint("SetJavaScriptEnabled")
|
|
@@ -321,56 +373,10 @@ public class AppleProvider implements SocialProvider {
|
|
|
321
373
|
PluginCall call,
|
|
322
374
|
String url
|
|
323
375
|
) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
window.setLayout(
|
|
328
|
-
WindowManager.LayoutParams.MATCH_PARENT,
|
|
329
|
-
WindowManager.LayoutParams.MATCH_PARENT
|
|
330
|
-
);
|
|
331
|
-
window.setGravity(Gravity.TOP);
|
|
332
|
-
window.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
|
|
333
|
-
window.setDimAmount(0.0f);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
View customView = activity
|
|
337
|
-
.getLayoutInflater()
|
|
338
|
-
.inflate(R.layout.dialog_custom_layout, null);
|
|
339
|
-
WebView webView = customView.findViewById(R.id.webview);
|
|
340
|
-
ProgressBar progressBar = customView.findViewById(R.id.progress_bar);
|
|
341
|
-
|
|
342
|
-
webView.setVerticalScrollBarEnabled(false);
|
|
343
|
-
webView.setHorizontalScrollBarEnabled(false);
|
|
344
|
-
|
|
345
|
-
AppleWebViewClient webViewClient = new AppleWebViewClient(
|
|
346
|
-
activity,
|
|
347
|
-
call,
|
|
348
|
-
this.redirectUrl,
|
|
349
|
-
this.clientId
|
|
350
|
-
) {
|
|
351
|
-
@Override
|
|
352
|
-
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
|
353
|
-
super.onPageStarted(view, url, favicon);
|
|
354
|
-
progressBar.setVisibility(View.VISIBLE);
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
@Override
|
|
358
|
-
public void onPageFinished(WebView view, String url) {
|
|
359
|
-
super.onPageFinished(view, url);
|
|
360
|
-
progressBar.setVisibility(View.GONE);
|
|
361
|
-
}
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
webView.setWebViewClient(webViewClient);
|
|
365
|
-
|
|
366
|
-
webView.getSettings().setJavaScriptEnabled(true);
|
|
367
|
-
webView.loadUrl(url);
|
|
368
|
-
|
|
369
|
-
ImageButton closeButton = customView.findViewById(R.id.close_button);
|
|
370
|
-
closeButton.setOnClickListener(v -> appledialog.dismiss());
|
|
371
|
-
|
|
372
|
-
appledialog.setContentView(customView);
|
|
376
|
+
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder(
|
|
377
|
+
getCustomTabsSession()
|
|
378
|
+
);
|
|
373
379
|
|
|
374
|
-
|
|
380
|
+
builder.build().launchUrl(context, Uri.parse(url));
|
|
375
381
|
}
|
|
376
382
|
}
|
|
@@ -51,12 +51,20 @@ public class GoogleProvider implements SocialProvider {
|
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
String nonce = call.getString("nonce");
|
|
55
|
+
|
|
54
56
|
// First attempt with setFilterByAuthorizedAccounts(true)
|
|
55
|
-
GetGoogleIdOption
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
GetGoogleIdOption.Builder googleIdOptionBuilder =
|
|
58
|
+
new GetGoogleIdOption.Builder()
|
|
59
|
+
.setFilterByAuthorizedAccounts(true)
|
|
60
|
+
.setServerClientId(this.clientId)
|
|
61
|
+
.setAutoSelectEnabled(true);
|
|
62
|
+
|
|
63
|
+
if (nonce != null && !nonce.isEmpty()) {
|
|
64
|
+
googleIdOptionBuilder.setNonce(nonce);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
GetGoogleIdOption googleIdOptionFiltered = googleIdOptionBuilder.build();
|
|
60
68
|
GetCredentialRequest filteredRequest = new GetCredentialRequest.Builder()
|
|
61
69
|
.addCredentialOption(googleIdOptionFiltered)
|
|
62
70
|
.build();
|
|
@@ -90,10 +98,18 @@ public class GoogleProvider implements SocialProvider {
|
|
|
90
98
|
}
|
|
91
99
|
|
|
92
100
|
private void retryWithoutFiltering(PluginCall call) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
.
|
|
101
|
+
String nonce = call.getString("nonce");
|
|
102
|
+
|
|
103
|
+
GetGoogleIdOption.Builder googleIdOptionBuilder =
|
|
104
|
+
new GetGoogleIdOption.Builder()
|
|
105
|
+
.setFilterByAuthorizedAccounts(false)
|
|
106
|
+
.setServerClientId(this.clientId);
|
|
107
|
+
|
|
108
|
+
if (nonce != null && !nonce.isEmpty()) {
|
|
109
|
+
googleIdOptionBuilder.setNonce(nonce);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
GetGoogleIdOption googleIdOption = googleIdOptionBuilder.build();
|
|
97
113
|
GetCredentialRequest request = new GetCredentialRequest.Builder()
|
|
98
114
|
.addCredentialOption(googleIdOption)
|
|
99
115
|
.build();
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package ee.forgr.capacitor.social.login;
|
|
2
2
|
|
|
3
|
+
import android.content.Intent;
|
|
3
4
|
import android.os.Build;
|
|
5
|
+
import android.util.Log;
|
|
4
6
|
import com.getcapacitor.JSObject;
|
|
5
7
|
import com.getcapacitor.Plugin;
|
|
6
8
|
import com.getcapacitor.PluginCall;
|
|
@@ -46,7 +48,7 @@ public class SocialLoginPlugin extends Plugin {
|
|
|
46
48
|
this.getContext()
|
|
47
49
|
);
|
|
48
50
|
|
|
49
|
-
appleProvider.initialize(
|
|
51
|
+
appleProvider.initialize();
|
|
50
52
|
this.socialProviderHashMap.put("apple", appleProvider);
|
|
51
53
|
}
|
|
52
54
|
|
|
@@ -56,7 +58,7 @@ public class SocialLoginPlugin extends Plugin {
|
|
|
56
58
|
this.getActivity(),
|
|
57
59
|
this.getContext()
|
|
58
60
|
);
|
|
59
|
-
String googleClientId = google.getString("
|
|
61
|
+
String googleClientId = google.getString("webclientId");
|
|
60
62
|
if (googleClientId == null || googleClientId.isEmpty()) {
|
|
61
63
|
call.reject("google.clientId is null or empty");
|
|
62
64
|
return;
|
|
@@ -158,4 +160,20 @@ public class SocialLoginPlugin extends Plugin {
|
|
|
158
160
|
// call.reject("Unsupported social login provider: " + provider);
|
|
159
161
|
// }
|
|
160
162
|
}
|
|
163
|
+
|
|
164
|
+
public void handleAppleLoginIntent(Intent intent) {
|
|
165
|
+
try {
|
|
166
|
+
SocialProvider provider = socialProviderHashMap.get("apple");
|
|
167
|
+
if (!(provider instanceof AppleProvider)) {
|
|
168
|
+
Log.e(
|
|
169
|
+
SocialLoginPlugin.LOG_TAG,
|
|
170
|
+
"Provider is not an apple provider (could be null)"
|
|
171
|
+
);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
((AppleProvider) provider).handleIntent(intent);
|
|
175
|
+
} catch (Throwable t) {
|
|
176
|
+
Log.e(SocialLoginPlugin.LOG_TAG, "Cannot handle apple login intent");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
161
179
|
}
|
package/dist/docs.json
CHANGED
|
@@ -166,14 +166,14 @@
|
|
|
166
166
|
"tags": [],
|
|
167
167
|
"docs": "",
|
|
168
168
|
"complexTypes": [],
|
|
169
|
-
"type": "{
|
|
169
|
+
"type": "{ iOSClientId?: string | undefined; iOSServerClientId?: string | undefined; webclientId?: string | undefined; } | undefined"
|
|
170
170
|
},
|
|
171
171
|
{
|
|
172
172
|
"name": "apple",
|
|
173
173
|
"tags": [],
|
|
174
174
|
"docs": "",
|
|
175
175
|
"complexTypes": [],
|
|
176
|
-
"type": "{ clientId
|
|
176
|
+
"type": "{ clientId?: string | undefined; redirectUrl?: string | undefined; } | undefined"
|
|
177
177
|
}
|
|
178
178
|
]
|
|
179
179
|
},
|
|
@@ -383,7 +383,7 @@
|
|
|
383
383
|
"tags": [],
|
|
384
384
|
"docs": "",
|
|
385
385
|
"complexTypes": [],
|
|
386
|
-
"type": "string"
|
|
386
|
+
"type": "string | null"
|
|
387
387
|
}
|
|
388
388
|
]
|
|
389
389
|
},
|
|
@@ -468,6 +468,18 @@
|
|
|
468
468
|
"complexTypes": [],
|
|
469
469
|
"type": "string[] | undefined"
|
|
470
470
|
},
|
|
471
|
+
{
|
|
472
|
+
"name": "nonce",
|
|
473
|
+
"tags": [
|
|
474
|
+
{
|
|
475
|
+
"text": "nonce",
|
|
476
|
+
"name": "description"
|
|
477
|
+
}
|
|
478
|
+
],
|
|
479
|
+
"docs": "Nonce",
|
|
480
|
+
"complexTypes": [],
|
|
481
|
+
"type": "string | undefined"
|
|
482
|
+
},
|
|
471
483
|
{
|
|
472
484
|
"name": "grantOfflineAccess",
|
|
473
485
|
"tags": [
|
|
@@ -505,18 +517,6 @@
|
|
|
505
517
|
"complexTypes": [],
|
|
506
518
|
"type": "string[] | undefined"
|
|
507
519
|
},
|
|
508
|
-
{
|
|
509
|
-
"name": "redirectURI",
|
|
510
|
-
"tags": [
|
|
511
|
-
{
|
|
512
|
-
"text": "redirect URI",
|
|
513
|
-
"name": "description"
|
|
514
|
-
}
|
|
515
|
-
],
|
|
516
|
-
"docs": "Redirect URI",
|
|
517
|
-
"complexTypes": [],
|
|
518
|
-
"type": "string"
|
|
519
|
-
},
|
|
520
520
|
{
|
|
521
521
|
"name": "nonce",
|
|
522
522
|
"tags": [
|
|
@@ -8,22 +8,35 @@ export interface InitializeOptions {
|
|
|
8
8
|
google?: {
|
|
9
9
|
/**
|
|
10
10
|
* The app's client ID, found and created in the Google Developers Console.
|
|
11
|
-
*
|
|
12
|
-
* The default is defined in the configuration.
|
|
11
|
+
* For iOS.
|
|
13
12
|
* @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
|
14
13
|
* @since 3.1.0
|
|
15
14
|
*/
|
|
16
|
-
|
|
15
|
+
iOSClientId?: string;
|
|
16
|
+
/**
|
|
17
|
+
* The app's server client ID, found and created in the Google Developers Console.
|
|
18
|
+
* For iOS.
|
|
19
|
+
* @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
|
20
|
+
* @since 3.1.0
|
|
21
|
+
*/
|
|
22
|
+
iOSServerClientId?: string;
|
|
23
|
+
/**
|
|
24
|
+
* The app's web client ID, found and created in the Google Developers Console.
|
|
25
|
+
* For Android (and web in the future).
|
|
26
|
+
* @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
|
27
|
+
* @since 3.1.0
|
|
28
|
+
*/
|
|
29
|
+
webclientId?: string;
|
|
17
30
|
};
|
|
18
31
|
apple?: {
|
|
19
32
|
/**
|
|
20
33
|
* Apple Client ID, provided by Apple
|
|
21
34
|
*/
|
|
22
|
-
clientId
|
|
35
|
+
clientId?: string;
|
|
23
36
|
/**
|
|
24
37
|
* Apple Redirect URL, should be your backend url that is configured in your apple app, only for android
|
|
25
38
|
*/
|
|
26
|
-
redirectUrl
|
|
39
|
+
redirectUrl?: string;
|
|
27
40
|
};
|
|
28
41
|
}
|
|
29
42
|
export interface FacebookLoginOptions {
|
|
@@ -41,6 +54,11 @@ export interface GoogleLoginOptions {
|
|
|
41
54
|
* @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes)
|
|
42
55
|
*/
|
|
43
56
|
scopes?: string[];
|
|
57
|
+
/**
|
|
58
|
+
* Nonce
|
|
59
|
+
* @description nonce
|
|
60
|
+
*/
|
|
61
|
+
nonce?: string;
|
|
44
62
|
/**
|
|
45
63
|
* Set if your application needs to refresh access tokens when the user is not present at the browser.
|
|
46
64
|
* In response use `serverAuthCode` key
|
|
@@ -68,11 +86,6 @@ export interface AppleProviderOptions {
|
|
|
68
86
|
* @description select scopes to login with
|
|
69
87
|
*/
|
|
70
88
|
scopes?: string[];
|
|
71
|
-
/**
|
|
72
|
-
* Redirect URI
|
|
73
|
-
* @description redirect URI
|
|
74
|
-
*/
|
|
75
|
-
redirectURI: string;
|
|
76
89
|
/**
|
|
77
90
|
* Nonce
|
|
78
91
|
* @description nonce
|
|
@@ -90,7 +103,7 @@ export interface AppleProviderResponse {
|
|
|
90
103
|
givenName: string | null;
|
|
91
104
|
familyName: string | null;
|
|
92
105
|
identityToken: string | null;
|
|
93
|
-
authorizationCode: string;
|
|
106
|
+
authorizationCode: string | null;
|
|
94
107
|
}
|
|
95
108
|
export interface LoginOptions {
|
|
96
109
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitializeOptions {\n facebook?: {\n /**\n * Facebook App ID, provided by Facebook for web, in mobile it's set in the native files\n */\n appId: string;\n };\n\n google?: {\n /**\n * The app's client ID, found and created in the Google Developers Console.\n *
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface InitializeOptions {\n facebook?: {\n /**\n * Facebook App ID, provided by Facebook for web, in mobile it's set in the native files\n */\n appId: string;\n };\n\n google?: {\n /**\n * The app's client ID, found and created in the Google Developers Console.\n * For iOS.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSClientId?: string;\n /**\n * The app's server client ID, found and created in the Google Developers Console.\n * For iOS.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSServerClientId?: string;\n /**\n * The app's web client ID, found and created in the Google Developers Console.\n * For Android (and web in the future).\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n webclientId?: string;\n };\n apple?: {\n /**\n * Apple Client ID, provided by Apple\n */\n clientId?: string;\n /**\n * Apple Redirect URL, should be your backend url that is configured in your apple app, only for android\n */\n redirectUrl?: string;\n };\n}\n\nexport interface FacebookLoginOptions {\n /**\n * Permissions\n * @description select permissions to login with\n */\n permissions: string[];\n}\n\nexport interface GoogleLoginOptions {\n /**\n * Specifies the scopes required for accessing Google APIs\n * The default is defined in the configuration.\n * @example [\"profile\", \"email\"]\n * @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes)\n */\n scopes?: string[];\n /**\n * Nonce\n * @description nonce\n */\n nonce?: string;\n /**\n * Set if your application needs to refresh access tokens when the user is not present at the browser.\n * In response use `serverAuthCode` key\n *\n * @default false\n * @since 3.1.0\n * */\n grantOfflineAccess?: boolean;\n}\n\nexport interface GoogleLoginResponse {\n accessToken: AccessToken | null;\n idToken: string | null;\n profile: {\n email: string | null;\n familyName: string | null;\n givenName: string | null;\n id: string | null;\n name: string | null;\n imageUrl: string | null;\n };\n}\n\nexport interface AppleProviderOptions {\n /**\n * Scopes\n * @description select scopes to login with\n */\n scopes?: string[];\n /**\n * Nonce\n * @description nonce\n */\n nonce?: string;\n /**\n * State\n * @description state\n */\n state?: string;\n}\n\nexport interface AppleProviderResponse {\n user: string | null;\n email: string | null;\n givenName: string | null;\n familyName: string | null;\n identityToken: string | null;\n authorizationCode: string | null;\n}\n\nexport interface LoginOptions {\n /**\n * Provider\n * @description select provider to login with\n */\n provider: \"facebook\" | \"google\" | \"apple\" | \"twitter\";\n /**\n * Options\n * @description payload to login with\n */\n options: FacebookLoginOptions | GoogleLoginOptions | AppleProviderOptions;\n}\n\nexport interface LoginResult {\n /**\n * Provider\n * @description select provider to login with\n */\n provider: \"facebook\" | \"google\" | \"apple\" | \"twitter\";\n /**\n * Payload\n * @description payload to login with\n */\n result: FacebookLoginResponse | GoogleLoginResponse | AppleProviderResponse;\n}\n\nexport interface AccessToken {\n applicationId?: string;\n declinedPermissions?: string[];\n expires?: string;\n isExpired?: boolean;\n lastRefresh?: string;\n permissions?: string[];\n token: string;\n userId?: string;\n}\n\nexport interface FacebookLoginResponse {\n accessToken: AccessToken | null;\n profile: {\n fields: readonly string[];\n };\n}\n\nexport interface AuthorizationCode {\n /**\n * Jwt\n * @description A JSON web token\n */\n jwt: string;\n}\n\nexport interface AuthorizationCodeOptions {\n /**\n * Provider\n * @description Provider for the authorization code\n */\n provider: \"apple\" | \"google\" | \"facebook\";\n}\n\nexport interface isLoggedInOptions {\n /**\n * Provider\n * @description Provider for the isLoggedIn\n */\n provider: \"apple\" | \"google\" | \"facebook\";\n}\n\nexport interface SocialLoginPlugin {\n /**\n * Initialize the plugin\n * @description initialize the plugin with the required options\n */\n initialize(options: InitializeOptions): Promise<void>;\n /**\n * Login with the selected provider\n * @description login with the selected provider\n */\n login(options: LoginOptions): Promise<LoginResult>;\n /**\n * Logout\n * @description logout the user\n */\n logout(options: { provider: \"apple\" | \"google\" | \"facebook\" }): Promise<void>;\n /**\n * IsLoggedIn\n * @description logout the user\n */\n isLoggedIn(options: isLoggedInOptions): Promise<{ isLoggedIn: boolean }>;\n\n /**\n * Get the current access token\n * @description get the current access token\n */\n getAuthorizationCode(\n options: AuthorizationCodeOptions,\n ): Promise<AuthorizationCode>;\n /**\n * Refresh the access token\n * @description refresh the access token\n */\n refresh(options: LoginOptions): Promise<void>;\n}\n"]}
|
|
@@ -76,7 +76,6 @@ extension AppleProviderError: LocalizedError {
|
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
class AppleProvider: NSObject, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
|
|
79
|
-
private var clientId: String?
|
|
80
79
|
private var completion: ((Result<AppleProviderResponse, Error>) -> Void)?
|
|
81
80
|
|
|
82
81
|
// Instance variables
|
|
@@ -88,9 +87,10 @@ class AppleProvider: NSObject, ASAuthorizationControllerDelegate, ASAuthorizatio
|
|
|
88
87
|
private let SHARED_PREFERENCE_NAME = "AppleProviderSharedPrefs_0eda2642"
|
|
89
88
|
private var redirectUrl = ""
|
|
90
89
|
|
|
91
|
-
func initialize(
|
|
92
|
-
|
|
93
|
-
|
|
90
|
+
func initialize(redirectUrl: String? = nil) {
|
|
91
|
+
if let redirectUrl = redirectUrl {
|
|
92
|
+
self.redirectUrl = redirectUrl
|
|
93
|
+
}
|
|
94
94
|
|
|
95
95
|
do {
|
|
96
96
|
try retrieveState()
|
|
@@ -164,11 +164,6 @@ class AppleProvider: NSObject, ASAuthorizationControllerDelegate, ASAuthorizatio
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
func login(payload: [String: Any], completion: @escaping (Result<AppleProviderResponse, Error>) -> Void) {
|
|
167
|
-
guard let clientId = clientId else {
|
|
168
|
-
completion(.failure(NSError(domain: "AppleProvider", code: 0, userInfo: [NSLocalizedDescriptionKey: "Client ID not set"])))
|
|
169
|
-
return
|
|
170
|
-
}
|
|
171
|
-
|
|
172
167
|
self.completion = completion
|
|
173
168
|
|
|
174
169
|
let appleIDProvider = ASAuthorizationAppleIDProvider()
|
|
@@ -5,12 +5,13 @@ class GoogleProvider {
|
|
|
5
5
|
var configuration: GIDConfiguration!
|
|
6
6
|
var forceAuthCode: Bool = false
|
|
7
7
|
var additionalScopes: [String]!
|
|
8
|
+
var defaultGrantedScopes = ["email", "profile", "openid"]
|
|
8
9
|
|
|
9
|
-
func initialize(clientId: String) {
|
|
10
|
-
let serverClientId = getServerClientIdValue()
|
|
10
|
+
func initialize(clientId: String, serverClientId: String? = nil) {
|
|
11
11
|
configuration = GIDConfiguration(clientID: clientId, serverClientID: serverClientId)
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
GIDSignIn.sharedInstance.configuration = configuration
|
|
14
|
+
|
|
14
15
|
additionalScopes = []
|
|
15
16
|
|
|
16
17
|
forceAuthCode = false
|
|
@@ -35,7 +36,7 @@ class GoogleProvider {
|
|
|
35
36
|
GIDSignIn.sharedInstance.signIn(
|
|
36
37
|
withPresenting: presentingVc,
|
|
37
38
|
hint: nil,
|
|
38
|
-
additionalScopes: self.
|
|
39
|
+
additionalScopes: payload["scopes"] as? [String] ?? self.defaultGrantedScopes
|
|
39
40
|
) { result, error in
|
|
40
41
|
if let error = error {
|
|
41
42
|
completion(.failure(error))
|
|
@@ -37,16 +37,25 @@ public class SocialLoginPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
if let googleSettings = call.getObject("google") {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
let iOSClientId = googleSettings["iOSClientId"] as? String
|
|
41
|
+
let iOSServerClientId = googleSettings["iOSServerClientId"] as? String
|
|
42
|
+
|
|
43
|
+
if let clientId = iOSClientId {
|
|
44
|
+
if let serverClientId = iOSServerClientId {
|
|
45
|
+
google.initialize(clientId: clientId, serverClientId: serverClientId)
|
|
46
|
+
} else {
|
|
47
|
+
google.initialize(clientId: clientId, serverClientId: nil)
|
|
48
|
+
}
|
|
42
49
|
initialized = true
|
|
43
50
|
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
if let appleSettings = call.getObject("apple") {
|
|
47
|
-
if let
|
|
48
|
-
|
|
49
|
-
|
|
54
|
+
if let redirectUrl = appleSettings["redirectUrl"] as? String {
|
|
55
|
+
apple.initialize(redirectUrl: redirectUrl)
|
|
56
|
+
initialized = true
|
|
57
|
+
} else {
|
|
58
|
+
apple.initialize()
|
|
50
59
|
initialized = true
|
|
51
60
|
}
|
|
52
61
|
}
|