@capgo/capacitor-social-login 7.8.0 → 7.8.2
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/README.md
CHANGED
|
@@ -202,16 +202,38 @@ const res = await SocialLogin.login({
|
|
|
202
202
|
|
|
203
203
|
[How to get the credentials](https://github.com/Cap-go/capacitor-social-login/blob/main/docs/setup_google.md)
|
|
204
204
|
|
|
205
|
+
### Complete Configuration Example
|
|
206
|
+
|
|
207
|
+
For Google login to work properly across all platforms, you need different client IDs and must understand the requirements for each mode:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
await SocialLogin.initialize({
|
|
211
|
+
google: {
|
|
212
|
+
webClientId: 'YOUR_WEB_CLIENT_ID', // Required for Android and Web
|
|
213
|
+
iOSClientId: 'YOUR_IOS_CLIENT_ID', // Required for iOS
|
|
214
|
+
iOSServerClientId: 'YOUR_WEB_CLIENT_ID', // Required for iOS offline mode (same as webClientId)
|
|
215
|
+
mode: 'online', // 'online' or 'offline'
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
**Important Notes:**
|
|
221
|
+
- `webClientId`: Required for Android and Web platforms
|
|
222
|
+
- `iOSClientId`: Required for iOS platform
|
|
223
|
+
- `iOSServerClientId`: Required only when using `mode: 'offline'` on iOS (should be the same value as `webClientId`)
|
|
224
|
+
- `mode: 'offline'`: Returns only `serverAuthCode` for backend authentication, no user profile data
|
|
225
|
+
- `mode: 'online'`: Returns user profile data and access tokens (default)
|
|
226
|
+
|
|
205
227
|
### Android configuration
|
|
206
228
|
|
|
207
229
|
The implemention use the new library of Google who use Google account at Os level, make sure your device does have at least one google account connected
|
|
208
230
|
|
|
209
|
-
|
|
231
|
+
Call the `initialize` method with the `google` provider:
|
|
210
232
|
|
|
211
233
|
```typescript
|
|
212
234
|
await SocialLogin.initialize({
|
|
213
235
|
google: {
|
|
214
|
-
webClientId: 'your-client-id', // the web client id for Android and Web
|
|
236
|
+
webClientId: 'your-web-client-id', // Required: the web client id for Android and Web
|
|
215
237
|
},
|
|
216
238
|
});
|
|
217
239
|
const res = await SocialLogin.login({
|
|
@@ -224,13 +246,14 @@ const res = await SocialLogin.login({
|
|
|
224
246
|
|
|
225
247
|
### iOS configuration
|
|
226
248
|
|
|
227
|
-
Call the `initialize` method with the `google` provider
|
|
249
|
+
Call the `initialize` method with the `google` provider:
|
|
228
250
|
|
|
229
251
|
```typescript
|
|
230
252
|
await SocialLogin.initialize({
|
|
231
253
|
google: {
|
|
232
|
-
iOSClientId: 'your-client-id',
|
|
233
|
-
iOSServerClientId: 'your-
|
|
254
|
+
iOSClientId: 'your-ios-client-id', // Required: the iOS client id
|
|
255
|
+
iOSServerClientId: 'your-web-client-id', // Required for offline mode: same as webClientId
|
|
256
|
+
mode: 'online', // 'online' for user data, 'offline' for server auth code only
|
|
234
257
|
},
|
|
235
258
|
});
|
|
236
259
|
const res = await SocialLogin.login({
|
|
@@ -241,10 +264,76 @@ const res = await SocialLogin.login({
|
|
|
241
264
|
});
|
|
242
265
|
```
|
|
243
266
|
|
|
267
|
+
**Offline Mode Behavior:**
|
|
268
|
+
When using `mode: 'offline'`, the login response will only contain:
|
|
269
|
+
```typescript
|
|
270
|
+
{
|
|
271
|
+
provider: 'google',
|
|
272
|
+
result: {
|
|
273
|
+
serverAuthCode: 'auth_code_for_backend',
|
|
274
|
+
responseType: 'offline'
|
|
275
|
+
}
|
|
276
|
+
// Note: No user profile data is returned in offline mode
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
244
280
|
### Web
|
|
245
281
|
|
|
246
282
|
Initialize method to create a script tag with Google lib. We cannot know when it's ready so be sure to do it early in web otherwise it will fail.
|
|
247
283
|
|
|
284
|
+
## Troubleshooting
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
### Invalid Privacy Manifest (ITMS-91056)
|
|
288
|
+
If you get this error on App Store Connect:
|
|
289
|
+
|
|
290
|
+
> ITMS-91056: Invalid privacy manifest - The PrivacyInfo.xcprivacy file from the following path is invalid: ...
|
|
291
|
+
|
|
292
|
+
**How to fix:**
|
|
293
|
+
- Make sure your app's `PrivacyInfo.xcprivacy` is valid JSON, with only Apple-documented keys/values.
|
|
294
|
+
- Do not include a privacy manifest in the plugin, only in your app.
|
|
295
|
+
|
|
296
|
+
### Google Play Console AD_ID Permission Error
|
|
297
|
+
|
|
298
|
+
**Problem**: After submitting your app to Google Play, you receive this error:
|
|
299
|
+
```
|
|
300
|
+
Google Api Error: Invalid request - This release includes the com.google.android.gms.permission.AD_ID permission
|
|
301
|
+
but your declaration on Play Console says your app doesn't use advertising ID. You must update your advertising
|
|
302
|
+
ID declaration.
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Root Cause**: The Facebook SDK automatically includes the `com.google.android.gms.permission.AD_ID` permission, even when you're only using Google and Apple sign-in.
|
|
306
|
+
|
|
307
|
+
**Solutions**:
|
|
308
|
+
|
|
309
|
+
#### Solution 1: Remove AD_ID Permission (Recommended)
|
|
310
|
+
If you're not using Facebook login, add this to your app's `android/app/src/main/AndroidManifest.xml`:
|
|
311
|
+
```xml
|
|
312
|
+
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove" />
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Make sure you have the tools namespace declared:
|
|
316
|
+
```xml
|
|
317
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
318
|
+
xmlns:tools="http://schemas.android.com/tools">
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
#### Solution 2: Update Google Play Console Declaration
|
|
322
|
+
In Google Play Console → App content → Data safety:
|
|
323
|
+
1. Select "Yes, my app collects or shares user data"
|
|
324
|
+
2. Under "Data types" → "Device or other IDs" → Select "Advertising ID"
|
|
325
|
+
3. Specify usage purpose (usually "App functionality" and/or "Analytics")
|
|
326
|
+
|
|
327
|
+
#### Solution 3: Conditional Facebook Dependencies (Advanced)
|
|
328
|
+
For advanced users who want to completely exclude Facebook from builds, you can use Gradle's conditional dependencies, but this requires custom build configuration.
|
|
329
|
+
|
|
330
|
+
**Verification**: After implementing Solution 1, run:
|
|
331
|
+
```bash
|
|
332
|
+
./gradlew :app:dependencies --configuration debugRuntimeClasspath | grep facebook
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
The Facebook dependencies should still be present (for compatibility), but the AD_ID permission should be removed from your final APK.
|
|
336
|
+
|
|
248
337
|
## API
|
|
249
338
|
|
|
250
339
|
<docgen-index>
|
|
@@ -565,10 +654,6 @@ Construct a type with a set of properties K of type T
|
|
|
565
654
|
|
|
566
655
|
</docgen-api>
|
|
567
656
|
|
|
568
|
-
### Credits
|
|
569
|
-
|
|
570
|
-
This plugin implementation of google is based on [CapacitorGoogleAuth](https://github.com/CodetrixStudio/CapacitorGoogleAuth) with a lot of rework, the current maintainer is unreachable, we are thankful for his work and are now going forward on our own!
|
|
571
|
-
Thanks to [reslear](https://github.com/reslear) for helping to tranfer users to this plugin from the old one and all the work.
|
|
572
657
|
|
|
573
658
|
## Privacy Manifest for App Developers
|
|
574
659
|
|
|
@@ -636,13 +721,7 @@ Add this file in your app at: `ios/App/PrivacyInfo.xcprivacy`
|
|
|
636
721
|
}
|
|
637
722
|
```
|
|
638
723
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
### Invalid Privacy Manifest (ITMS-91056)
|
|
642
|
-
If you get this error on App Store Connect:
|
|
643
|
-
|
|
644
|
-
> ITMS-91056: Invalid privacy manifest - The PrivacyInfo.xcprivacy file from the following path is invalid: ...
|
|
724
|
+
### Credits
|
|
645
725
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
- Do not include a privacy manifest in the plugin, only in your app.
|
|
726
|
+
This plugin implementation of google is based on [CapacitorGoogleAuth](https://github.com/CodetrixStudio/CapacitorGoogleAuth) with a lot of rework, the current maintainer is unreachable, we are thankful for his work and are now going forward on our own!
|
|
727
|
+
Thanks to [reslear](https://github.com/reslear) for helping to tranfer users to this plugin from the old one and all the work.
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
|
|
4
4
|
<uses-permission android:name="android.permission.INTERNET"/>
|
|
5
5
|
|
|
6
|
+
<!-- Remove AD_ID permission if you're not using Facebook login to avoid Google Play Console errors -->
|
|
7
|
+
<!-- Uncomment the line below if you're only using Google/Apple login and getting AD_ID permission errors -->
|
|
8
|
+
<!-- <uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove" /> -->
|
|
9
|
+
|
|
6
10
|
<application>
|
|
7
11
|
<provider
|
|
8
12
|
android:name="com.facebook.internal.FacebookInitProvider"
|
|
@@ -12,27 +12,31 @@ export interface InitializeOptions {
|
|
|
12
12
|
google?: {
|
|
13
13
|
/**
|
|
14
14
|
* The app's client ID, found and created in the Google Developers Console.
|
|
15
|
-
*
|
|
15
|
+
* Required for iOS platform.
|
|
16
16
|
* @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
|
17
17
|
* @since 3.1.0
|
|
18
18
|
*/
|
|
19
19
|
iOSClientId?: string;
|
|
20
20
|
/**
|
|
21
|
-
* The app's server client ID, required for offline mode
|
|
22
|
-
*
|
|
21
|
+
* The app's server client ID, required for offline mode on iOS.
|
|
22
|
+
* Should be the same value as webClientId.
|
|
23
|
+
* Found and created in the Google Developers Console.
|
|
23
24
|
* @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
|
24
25
|
* @since 3.1.0
|
|
25
26
|
*/
|
|
26
27
|
iOSServerClientId?: string;
|
|
27
28
|
/**
|
|
28
29
|
* The app's web client ID, found and created in the Google Developers Console.
|
|
29
|
-
*
|
|
30
|
+
* Required for Android and Web platforms.
|
|
30
31
|
* @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
|
31
32
|
* @since 3.1.0
|
|
32
33
|
*/
|
|
33
34
|
webClientId?: string;
|
|
34
35
|
/**
|
|
35
|
-
* The login mode, can be online or offline.
|
|
36
|
+
* The login mode, can be online or offline.
|
|
37
|
+
* - online: Returns user profile data and access tokens (default)
|
|
38
|
+
* - offline: Returns only serverAuthCode for backend authentication, no user profile data
|
|
39
|
+
* Note: offline mode requires iOSServerClientId to be set on iOS
|
|
36
40
|
* @example offline
|
|
37
41
|
* @since 3.1.0
|
|
38
42
|
*/
|
|
@@ -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 * Facebook Client Token, provided by Facebook for web, in mobile it's set in the native files\n */\n clientToken?: 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 * Facebook Client Token, provided by Facebook for web, in mobile it's set in the native files\n */\n clientToken?: string;\n };\n\n google?: {\n /**\n * The app's client ID, found and created in the Google Developers Console.\n * Required for iOS platform.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n iOSClientId?: string;\n /**\n * The app's server client ID, required for offline mode on iOS.\n * Should be the same value as webClientId.\n * Found and created in the Google Developers Console.\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 * Required for Android and Web platforms.\n * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com\n * @since 3.1.0\n */\n webClientId?: string;\n /**\n * The login mode, can be online or offline.\n * - online: Returns user profile data and access tokens (default)\n * - offline: Returns only serverAuthCode for backend authentication, no user profile data\n * Note: offline mode requires iOSServerClientId to be set on iOS\n * @example offline\n * @since 3.1.0\n */\n mode?: 'online' | 'offline';\n /**\n * Filter visible accounts by hosted domain\n * @description filter visible accounts by hosted domain\n */\n hostedDomain?: string;\n /**\n * Google Redirect URL, should be your backend url that is configured in your google app\n */\n redirectUrl?: string;\n };\n apple?: {\n /**\n * Apple Client ID, provided by Apple for web and Android\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 * Is Limited Login\n * @description use limited login for Facebook IOS\n * @default false\n */\n limitedLogin?: boolean;\n /**\n * Nonce\n * @description A custom nonce to use for the login request\n */\n nonce?: 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 * Force refresh token (only for Android)\n * @description force refresh token\n * @default false\n */\n forceRefreshToken?: boolean;\n /**\n * Force account selection prompt (iOS)\n * @description forces the account selection prompt to appear on iOS\n * @default false\n */\n forcePrompt?: boolean;\n /**\n * Style\n * @description style\n * @default 'standard'\n */\n style?: 'bottom' | 'standard';\n}\n\nexport interface GoogleLoginResponseOnline {\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 responseType: 'online';\n}\n\nexport interface GoogleLoginResponseOffline {\n serverAuthCode: string;\n responseType: 'offline';\n}\n\nexport type GoogleLoginResponse = GoogleLoginResponseOnline | GoogleLoginResponseOffline;\n\nexport interface AppleProviderOptions {\n /**\n * Scopes\n * @description An array of scopes to request during login\n * @example [\"name\", \"email\"]\n * default: [\"name\", \"email\"]\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 accessToken: AccessToken | null;\n idToken: string | null;\n profile: {\n user: string;\n email: string | null;\n givenName: string | null;\n familyName: string | null;\n };\n}\n\nexport type LoginOptions =\n | {\n provider: 'facebook';\n options: FacebookLoginOptions;\n }\n | {\n provider: 'google';\n options: GoogleLoginOptions;\n }\n | {\n provider: 'apple';\n options: AppleProviderOptions;\n };\n\nexport type LoginResult =\n | {\n provider: 'facebook';\n result: FacebookLoginResponse;\n }\n | {\n provider: 'google';\n result: GoogleLoginResponse;\n }\n | {\n provider: 'apple';\n result: 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 refreshToken?: string;\n userId?: string;\n}\n\nexport interface FacebookLoginResponse {\n accessToken: AccessToken | null;\n idToken: string | null;\n profile: {\n userID: string;\n email: string | null;\n friendIDs: string[];\n birthday: string | null;\n ageRange: { min?: number; max?: number } | null;\n gender: string | null;\n location: { id: string; name: string } | null;\n hometown: { id: string; name: string } | null;\n profileURL: string | null;\n name: string | null;\n imageURL: string | null;\n };\n}\n\nexport interface AuthorizationCode {\n /**\n * Jwt\n * @description A JSON web token\n */\n jwt?: string;\n /**\n * Access Token\n * @description An access token\n */\n accessToken?: 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\n// Define the provider-specific call types\nexport type ProviderSpecificCall = 'facebook#getProfile' | 'facebook#requestTracking';\n\n// Define the options and response types for each specific call\nexport interface FacebookGetProfileOptions {\n /**\n * Fields to retrieve from Facebook profile\n * @example [\"id\", \"name\", \"email\", \"picture\"]\n */\n fields?: string[];\n}\n\nexport interface FacebookGetProfileResponse {\n /**\n * Facebook profile data\n */\n profile: {\n id: string | null;\n name: string | null;\n email: string | null;\n first_name: string | null;\n last_name: string | null;\n picture?: {\n data: {\n height: number | null;\n is_silhouette: boolean | null;\n url: string | null;\n width: number | null;\n };\n } | null;\n [key: string]: any; // For additional fields that might be requested\n };\n}\n\nexport type FacebookRequestTrackingOptions = Record<string, never>;\n\nexport interface FacebookRequestTrackingResponse {\n /**\n * App tracking authorization status\n */\n status: 'authorized' | 'denied' | 'notDetermined' | 'restricted';\n}\n\n// Map call strings to their options and response types\nexport type ProviderSpecificCallOptionsMap = {\n 'facebook#getProfile': FacebookGetProfileOptions;\n 'facebook#requestTracking': FacebookRequestTrackingOptions;\n};\n\nexport type ProviderSpecificCallResponseMap = {\n 'facebook#getProfile': FacebookGetProfileResponse;\n 'facebook#requestTracking': FacebookRequestTrackingResponse;\n};\n\n// Add a helper type to map providers to their response types\nexport type ProviderResponseMap = {\n facebook: FacebookLoginResponse;\n google: GoogleLoginResponse;\n apple: AppleProviderResponse;\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<T extends LoginOptions['provider']>(\n options: Extract<LoginOptions, { provider: T }>,\n ): Promise<{ provider: T; result: ProviderResponseMap[T] }>;\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(options: AuthorizationCodeOptions): Promise<AuthorizationCode>;\n /**\n * Refresh the access token\n * @description refresh the access token\n */\n refresh(options: LoginOptions): Promise<void>;\n\n /**\n * Execute provider-specific calls\n * @description Execute a provider-specific functionality\n */\n providerSpecificCall<T extends ProviderSpecificCall>(options: {\n call: T;\n options: ProviderSpecificCallOptionsMap[T];\n }): Promise<ProviderSpecificCallResponseMap[T]>;\n}\n"]}
|