@capgo/capacitor-social-login 8.1.1 → 8.2.0
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 +215 -35
- package/android/src/main/AndroidManifest.xml +4 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/OAuth2LoginActivity.java +110 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/OAuth2Provider.java +848 -0
- package/android/src/main/java/ee/forgr/capacitor/social/login/SocialLoginPlugin.java +27 -1
- package/dist/docs.json +352 -22
- package/dist/esm/definitions.d.ts +167 -3
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/oauth2-provider.d.ts +41 -0
- package/dist/esm/oauth2-provider.js +444 -0
- package/dist/esm/oauth2-provider.js.map +1 -0
- package/dist/esm/web.d.ts +3 -1
- package/dist/esm/web.js +32 -0
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +474 -0
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +474 -0
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/SocialLoginPlugin/OAuth2Provider.swift +575 -0
- package/ios/Sources/SocialLoginPlugin/SocialLoginPlugin.swift +111 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,14 +14,14 @@ If you're currently using `@codetrix-studio/capacitor-google-auth`, we recommend
|
|
|
14
14
|
## About
|
|
15
15
|
All social logins in one plugin
|
|
16
16
|
|
|
17
|
-
This plugin
|
|
17
|
+
This plugin implements social auth for:
|
|
18
18
|
- Google (with credential manager)
|
|
19
|
-
- Apple (with
|
|
20
|
-
- Facebook (
|
|
19
|
+
- Apple (with OAuth on android)
|
|
20
|
+
- Facebook (with latest SDK)
|
|
21
|
+
- Twitter/X (OAuth 2.0)
|
|
22
|
+
- Generic OAuth2 (supports multiple providers: GitHub, Azure AD, Auth0, Okta, and any OAuth2-compliant server)
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
This plugin is the only one who implement all 3 majors social login on WEB, IOS and Android
|
|
24
|
+
This plugin is the all-in-one solution for social authentication on Web, iOS, and Android.
|
|
25
25
|
|
|
26
26
|
## Documentation
|
|
27
27
|
|
|
@@ -343,6 +343,137 @@ When using `mode: 'offline'`, the login response will only contain:
|
|
|
343
343
|
|
|
344
344
|
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.
|
|
345
345
|
|
|
346
|
+
## OAuth2 (Generic)
|
|
347
|
+
|
|
348
|
+
The plugin supports generic OAuth2 authentication, allowing you to integrate with any OAuth2-compliant provider (GitHub, Azure AD, Auth0, Okta, custom servers, etc.). You can configure multiple OAuth2 providers simultaneously.
|
|
349
|
+
|
|
350
|
+
### Multi-Provider Configuration
|
|
351
|
+
|
|
352
|
+
```typescript
|
|
353
|
+
await SocialLogin.initialize({
|
|
354
|
+
oauth2: {
|
|
355
|
+
// GitHub OAuth2
|
|
356
|
+
github: {
|
|
357
|
+
appId: 'your-github-client-id',
|
|
358
|
+
authorizationBaseUrl: 'https://github.com/login/oauth/authorize',
|
|
359
|
+
accessTokenEndpoint: 'https://github.com/login/oauth/access_token',
|
|
360
|
+
redirectUrl: 'myapp://oauth/github',
|
|
361
|
+
scope: 'read:user user:email',
|
|
362
|
+
pkceEnabled: true,
|
|
363
|
+
},
|
|
364
|
+
// Azure AD OAuth2
|
|
365
|
+
azure: {
|
|
366
|
+
appId: 'your-azure-client-id',
|
|
367
|
+
authorizationBaseUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
|
|
368
|
+
accessTokenEndpoint: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
|
|
369
|
+
redirectUrl: 'myapp://oauth/azure',
|
|
370
|
+
scope: 'openid profile email',
|
|
371
|
+
pkceEnabled: true,
|
|
372
|
+
resourceUrl: 'https://graph.microsoft.com/v1.0/me',
|
|
373
|
+
},
|
|
374
|
+
// Auth0 OAuth2
|
|
375
|
+
auth0: {
|
|
376
|
+
appId: 'your-auth0-client-id',
|
|
377
|
+
authorizationBaseUrl: 'https://your-tenant.auth0.com/authorize',
|
|
378
|
+
accessTokenEndpoint: 'https://your-tenant.auth0.com/oauth/token',
|
|
379
|
+
redirectUrl: 'myapp://oauth/auth0',
|
|
380
|
+
scope: 'openid profile email offline_access',
|
|
381
|
+
pkceEnabled: true,
|
|
382
|
+
additionalParameters: {
|
|
383
|
+
audience: 'https://your-api.example.com',
|
|
384
|
+
},
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Login with a Specific Provider
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
// Login with GitHub
|
|
394
|
+
const githubResult = await SocialLogin.login({
|
|
395
|
+
provider: 'oauth2',
|
|
396
|
+
options: {
|
|
397
|
+
providerId: 'github', // Required: must match key from initialize()
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
// Login with Azure AD
|
|
402
|
+
const azureResult = await SocialLogin.login({
|
|
403
|
+
provider: 'oauth2',
|
|
404
|
+
options: {
|
|
405
|
+
providerId: 'azure',
|
|
406
|
+
scope: 'openid profile email', // Optional: override default scopes
|
|
407
|
+
},
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
console.log('Access Token:', azureResult.result.accessToken?.token);
|
|
411
|
+
console.log('ID Token:', azureResult.result.idToken);
|
|
412
|
+
console.log('User Data:', azureResult.result.resourceData);
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Check Login Status
|
|
416
|
+
|
|
417
|
+
```typescript
|
|
418
|
+
const status = await SocialLogin.isLoggedIn({
|
|
419
|
+
provider: 'oauth2',
|
|
420
|
+
providerId: 'github', // Required for OAuth2
|
|
421
|
+
});
|
|
422
|
+
console.log('Is logged in:', status.isLoggedIn);
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### Logout
|
|
426
|
+
|
|
427
|
+
```typescript
|
|
428
|
+
await SocialLogin.logout({
|
|
429
|
+
provider: 'oauth2',
|
|
430
|
+
providerId: 'github', // Required for OAuth2
|
|
431
|
+
});
|
|
432
|
+
```
|
|
433
|
+
|
|
434
|
+
### Refresh Token
|
|
435
|
+
|
|
436
|
+
```typescript
|
|
437
|
+
await SocialLogin.refresh({
|
|
438
|
+
provider: 'oauth2',
|
|
439
|
+
options: {
|
|
440
|
+
providerId: 'github', // Required for OAuth2
|
|
441
|
+
},
|
|
442
|
+
});
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
### OAuth2 Configuration Options
|
|
446
|
+
|
|
447
|
+
| Option | Type | Required | Description |
|
|
448
|
+
|--------|------|----------|-------------|
|
|
449
|
+
| `appId` | string | Yes | OAuth2 Client ID |
|
|
450
|
+
| `authorizationBaseUrl` | string | Yes | Authorization endpoint URL |
|
|
451
|
+
| `accessTokenEndpoint` | string | No* | Token endpoint URL (*Required for code flow) |
|
|
452
|
+
| `redirectUrl` | string | Yes | Callback URL for OAuth redirect |
|
|
453
|
+
| `responseType` | 'code' \| 'token' | No | OAuth flow type (default: 'code') |
|
|
454
|
+
| `pkceEnabled` | boolean | No | Enable PKCE (default: true) |
|
|
455
|
+
| `scope` | string | No | Default scopes to request |
|
|
456
|
+
| `resourceUrl` | string | No | URL to fetch user profile after auth |
|
|
457
|
+
| `additionalParameters` | Record<string, string> | No | Extra params for authorization URL |
|
|
458
|
+
| `additionalResourceHeaders` | Record<string, string> | No | Extra headers for resource request |
|
|
459
|
+
| `logoutUrl` | string | No | URL to open on logout |
|
|
460
|
+
| `logsEnabled` | boolean | No | Enable debug logging (default: false) |
|
|
461
|
+
|
|
462
|
+
### Platform-Specific Notes
|
|
463
|
+
|
|
464
|
+
**iOS**: Uses `ASWebAuthenticationSession` for secure authentication.
|
|
465
|
+
|
|
466
|
+
**Android**: Uses a WebView-based authentication flow.
|
|
467
|
+
|
|
468
|
+
**Web**: Opens a popup window for OAuth flow.
|
|
469
|
+
|
|
470
|
+
### Security Recommendations
|
|
471
|
+
|
|
472
|
+
1. **Always use PKCE** (`pkceEnabled: true`) for public clients
|
|
473
|
+
2. **Use authorization code flow** (`responseType: 'code'`) instead of implicit flow
|
|
474
|
+
3. **Store tokens securely** using [@capgo/capacitor-persistent-account](https://github.com/Cap-go/capacitor-persistent-account)
|
|
475
|
+
4. **Use HTTPS** for all endpoints and redirect URLs in production
|
|
476
|
+
|
|
346
477
|
## Troubleshooting
|
|
347
478
|
|
|
348
479
|
|
|
@@ -464,14 +595,14 @@ Initialize the plugin
|
|
|
464
595
|
### login(...)
|
|
465
596
|
|
|
466
597
|
```typescript
|
|
467
|
-
login<T extends "apple" | "google" | "facebook" | "twitter">(options: Extract<LoginOptions, { provider: T; }>) => Promise<{ provider: T; result: ProviderResponseMap[T]; }>
|
|
598
|
+
login<T extends "apple" | "google" | "facebook" | "twitter" | "oauth2">(options: Extract<LoginOptions, { provider: T; }>) => Promise<{ provider: T; result: ProviderResponseMap[T]; }>
|
|
468
599
|
```
|
|
469
600
|
|
|
470
601
|
Login with the selected provider
|
|
471
602
|
|
|
472
|
-
| Param | Type
|
|
473
|
-
| ------------- |
|
|
474
|
-
| **`options`** | <code><a href="#extract">Extract</a><{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'twitter'; options: <a href="#twitterloginoptions">TwitterLoginOptions</a>; }, { provider: T; }></code> |
|
|
603
|
+
| Param | Type |
|
|
604
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
605
|
+
| **`options`** | <code><a href="#extract">Extract</a><{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'twitter'; options: <a href="#twitterloginoptions">TwitterLoginOptions</a>; }, { provider: T; }> \| <a href="#extract">Extract</a><{ provider: 'oauth2'; options: <a href="#oauth2loginoptions">OAuth2LoginOptions</a>; }, { provider: T; }></code> |
|
|
475
606
|
|
|
476
607
|
**Returns:** <code>Promise<{ provider: T; result: ProviderResponseMap[T]; }></code>
|
|
477
608
|
|
|
@@ -481,14 +612,14 @@ Login with the selected provider
|
|
|
481
612
|
### logout(...)
|
|
482
613
|
|
|
483
614
|
```typescript
|
|
484
|
-
logout(options: { provider: 'apple' | 'google' | 'facebook' | 'twitter'; }) => Promise<void>
|
|
615
|
+
logout(options: { provider: 'apple' | 'google' | 'facebook' | 'twitter' | 'oauth2'; providerId?: string; }) => Promise<void>
|
|
485
616
|
```
|
|
486
617
|
|
|
487
618
|
Logout
|
|
488
619
|
|
|
489
|
-
| Param | Type
|
|
490
|
-
| ------------- |
|
|
491
|
-
| **`options`** | <code>{ provider: 'apple' \| 'google' \| 'facebook' \| 'twitter'; }</code> |
|
|
620
|
+
| Param | Type |
|
|
621
|
+
| ------------- | ----------------------------------------------------------------------------------------------------------- |
|
|
622
|
+
| **`options`** | <code>{ provider: 'apple' \| 'google' \| 'facebook' \| 'twitter' \| 'oauth2'; providerId?: string; }</code> |
|
|
492
623
|
|
|
493
624
|
--------------------
|
|
494
625
|
|
|
@@ -577,12 +708,33 @@ Get the native Capacitor plugin version
|
|
|
577
708
|
|
|
578
709
|
#### InitializeOptions
|
|
579
710
|
|
|
580
|
-
| Prop | Type |
|
|
581
|
-
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
582
|
-
| **`
|
|
583
|
-
| **`
|
|
584
|
-
| **`
|
|
585
|
-
| **`
|
|
711
|
+
| Prop | Type | Description |
|
|
712
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
|
713
|
+
| **`oauth2`** | <code><a href="#record">Record</a><string, <a href="#oauth2providerconfig">OAuth2ProviderConfig</a>></code> | OAuth2 provider configurations. Supports multiple providers by using a <a href="#record">Record</a> with provider IDs as keys. |
|
|
714
|
+
| **`twitter`** | <code>{ clientId: string; redirectUrl: string; defaultScopes?: string[]; forceLogin?: boolean; audience?: string; }</code> | |
|
|
715
|
+
| **`facebook`** | <code>{ appId: string; clientToken?: string; locale?: string; }</code> | |
|
|
716
|
+
| **`google`** | <code>{ iOSClientId?: string; iOSServerClientId?: string; webClientId?: string; mode?: 'online' \| 'offline'; hostedDomain?: string; redirectUrl?: string; }</code> | |
|
|
717
|
+
| **`apple`** | <code>{ clientId?: string; redirectUrl?: string; useProperTokenExchange?: boolean; useBroadcastChannel?: boolean; }</code> | |
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
#### OAuth2ProviderConfig
|
|
721
|
+
|
|
722
|
+
Configuration for a single OAuth2 provider instance
|
|
723
|
+
|
|
724
|
+
| Prop | Type | Description | Default |
|
|
725
|
+
| ------------------------------- | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
|
|
726
|
+
| **`appId`** | <code>string</code> | The OAuth 2.0 client identifier (App ID / Client ID) | |
|
|
727
|
+
| **`authorizationBaseUrl`** | <code>string</code> | The base URL of the authorization endpoint | |
|
|
728
|
+
| **`accessTokenEndpoint`** | <code>string</code> | The URL to exchange the authorization code for tokens Required for authorization code flow | |
|
|
729
|
+
| **`redirectUrl`** | <code>string</code> | Redirect URL that receives the OAuth callback | |
|
|
730
|
+
| **`resourceUrl`** | <code>string</code> | Optional URL to fetch user profile/resource data after authentication The access token will be sent as Bearer token in the Authorization header | |
|
|
731
|
+
| **`responseType`** | <code>'code' \| 'token'</code> | The OAuth response type - 'code': Authorization Code flow (recommended, requires accessTokenEndpoint) - 'token': Implicit flow (less secure, tokens returned directly) | <code>'code'</code> |
|
|
732
|
+
| **`pkceEnabled`** | <code>boolean</code> | Enable PKCE (Proof Key for Code Exchange) Strongly recommended for public clients (mobile/web apps) | <code>true</code> |
|
|
733
|
+
| **`scope`** | <code>string</code> | Default scopes to request during authorization | |
|
|
734
|
+
| **`additionalParameters`** | <code><a href="#record">Record</a><string, string></code> | Additional parameters to include in the authorization request | |
|
|
735
|
+
| **`additionalResourceHeaders`** | <code><a href="#record">Record</a><string, string></code> | Additional headers to include when fetching the resource URL | |
|
|
736
|
+
| **`logoutUrl`** | <code>string</code> | Custom logout URL for ending the session | |
|
|
737
|
+
| **`logsEnabled`** | <code>boolean</code> | Enable debug logging | <code>false</code> |
|
|
586
738
|
|
|
587
739
|
|
|
588
740
|
#### FacebookLoginResponse
|
|
@@ -662,6 +814,20 @@ Get the native Capacitor plugin version
|
|
|
662
814
|
| **`email`** | <code>string \| null</code> |
|
|
663
815
|
|
|
664
816
|
|
|
817
|
+
#### OAuth2LoginResponse
|
|
818
|
+
|
|
819
|
+
| Prop | Type | Description |
|
|
820
|
+
| ------------------ | ------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
|
821
|
+
| **`providerId`** | <code>string</code> | The provider ID that was used for this login |
|
|
822
|
+
| **`accessToken`** | <code><a href="#accesstoken">AccessToken</a> \| null</code> | The access token received from the OAuth provider |
|
|
823
|
+
| **`idToken`** | <code>string \| null</code> | The ID token (JWT) if provided by the OAuth server (e.g., OpenID Connect) |
|
|
824
|
+
| **`refreshToken`** | <code>string \| null</code> | The refresh token if provided (requires appropriate scope like offline_access) |
|
|
825
|
+
| **`resourceData`** | <code><a href="#record">Record</a><string, unknown> \| null</code> | Resource data fetched from resourceUrl if configured Contains the raw JSON response from the resource endpoint |
|
|
826
|
+
| **`scope`** | <code>string[]</code> | The scopes that were granted |
|
|
827
|
+
| **`tokenType`** | <code>string</code> | Token type (usually 'bearer') |
|
|
828
|
+
| **`expiresIn`** | <code>number \| null</code> | Token expiration time in seconds |
|
|
829
|
+
|
|
830
|
+
|
|
665
831
|
#### FacebookLoginOptions
|
|
666
832
|
|
|
667
833
|
| Prop | Type | Description | Default |
|
|
@@ -706,11 +872,24 @@ Get the native Capacitor plugin version
|
|
|
706
872
|
| **`forceLogin`** | <code>boolean</code> | Force the consent screen on every attempt, maps to `force_login=true`. |
|
|
707
873
|
|
|
708
874
|
|
|
875
|
+
#### OAuth2LoginOptions
|
|
876
|
+
|
|
877
|
+
| Prop | Type | Description |
|
|
878
|
+
| -------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
|
|
879
|
+
| **`providerId`** | <code>string</code> | The provider ID as configured in initialize() This is required to identify which OAuth2 provider to use |
|
|
880
|
+
| **`scope`** | <code>string</code> | Override the scopes for this login request If not provided, uses the scopes from initialization |
|
|
881
|
+
| **`state`** | <code>string</code> | Custom state parameter for CSRF protection If not provided, a random value is generated |
|
|
882
|
+
| **`codeVerifier`** | <code>string</code> | Override PKCE code verifier (for testing purposes) If not provided, a secure random verifier is generated |
|
|
883
|
+
| **`redirectUrl`** | <code>string</code> | Override redirect URL for this login request |
|
|
884
|
+
| **`additionalParameters`** | <code><a href="#record">Record</a><string, string></code> | Additional parameters to add to the authorization URL |
|
|
885
|
+
|
|
886
|
+
|
|
709
887
|
#### isLoggedInOptions
|
|
710
888
|
|
|
711
|
-
| Prop
|
|
712
|
-
|
|
|
713
|
-
| **`provider`**
|
|
889
|
+
| Prop | Type | Description |
|
|
890
|
+
| ---------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
891
|
+
| **`provider`** | <code>'apple' \| 'google' \| 'facebook' \| 'twitter' \| 'oauth2'</code> | Provider |
|
|
892
|
+
| **`providerId`** | <code>string</code> | Provider ID for OAuth2 providers (required when provider is 'oauth2') |
|
|
714
893
|
|
|
715
894
|
|
|
716
895
|
#### AuthorizationCode
|
|
@@ -723,9 +902,10 @@ Get the native Capacitor plugin version
|
|
|
723
902
|
|
|
724
903
|
#### AuthorizationCodeOptions
|
|
725
904
|
|
|
726
|
-
| Prop
|
|
727
|
-
|
|
|
728
|
-
| **`provider`**
|
|
905
|
+
| Prop | Type | Description |
|
|
906
|
+
| ---------------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------- |
|
|
907
|
+
| **`provider`** | <code>'apple' \| 'google' \| 'facebook' \| 'twitter' \| 'oauth2'</code> | Provider |
|
|
908
|
+
| **`providerId`** | <code>string</code> | Provider ID for OAuth2 providers (required when provider is 'oauth2') |
|
|
729
909
|
|
|
730
910
|
|
|
731
911
|
#### FacebookGetProfileResponse
|
|
@@ -752,9 +932,16 @@ Get the native Capacitor plugin version
|
|
|
752
932
|
### Type Aliases
|
|
753
933
|
|
|
754
934
|
|
|
935
|
+
#### Record
|
|
936
|
+
|
|
937
|
+
Construct a type with a set of properties K of type T
|
|
938
|
+
|
|
939
|
+
<code>{
|
|
755
940
|
[P in K]: T;
|
|
756
941
|
}</code>
|
|
942
|
+
|
|
943
|
+
|
|
757
944
|
#### ProviderResponseMap
|
|
758
945
|
|
|
759
|
-
<code>{ facebook: <a href="#facebookloginresponse">FacebookLoginResponse</a>; google: <a href="#googleloginresponse">GoogleLoginResponse</a>; apple: <a href="#appleproviderresponse">AppleProviderResponse</a>; twitter: <a href="#twitterloginresponse">TwitterLoginResponse</a>; }</code>
|
|
946
|
+
<code>{ facebook: <a href="#facebookloginresponse">FacebookLoginResponse</a>; google: <a href="#googleloginresponse">GoogleLoginResponse</a>; apple: <a href="#appleproviderresponse">AppleProviderResponse</a>; twitter: <a href="#twitterloginresponse">TwitterLoginResponse</a>; oauth2: <a href="#oauth2loginresponse">OAuth2LoginResponse</a>; }</code>
|
|
760
947
|
|
|
761
948
|
|
|
762
949
|
#### GoogleLoginResponse
|
|
@@ -764,7 +951,7 @@ Get the native Capacitor plugin version
|
|
|
764
951
|
|
|
765
952
|
#### LoginOptions
|
|
766
953
|
|
|
767
|
-
<code>{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; } | { provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; } | { provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; } | { provider: 'twitter'; options: <a href="#twitterloginoptions">TwitterLoginOptions</a>; }</code>
|
|
954
|
+
<code>{ provider: 'facebook'; options: <a href="#facebookloginoptions">FacebookLoginOptions</a>; } | { provider: 'google'; options: <a href="#googleloginoptions">GoogleLoginOptions</a>; } | { provider: 'apple'; options: <a href="#appleprovideroptions">AppleProviderOptions</a>; } | { provider: 'twitter'; options: <a href="#twitterloginoptions">TwitterLoginOptions</a>; } | { provider: 'oauth2'; options: <a href="#oauth2loginoptions">OAuth2LoginOptions</a>; }</code>
|
|
768
955
|
|
|
769
956
|
|
|
770
957
|
#### Extract
|
|
@@ -793,13 +980,6 @@ Get the native Capacitor plugin version
|
|
|
793
980
|
|
|
794
981
|
<code><a href="#record">Record</a><string, never></code>
|
|
795
982
|
|
|
796
|
-
|
|
797
|
-
#### Record
|
|
798
|
-
|
|
799
|
-
Construct a type with a set of properties K of type T
|
|
800
|
-
|
|
801
|
-
<code>{
|
|
802
983
|
[P in K]: T;
|
|
803
984
|
}</code>
|
|
804
|
-
|
|
805
985
|
</docgen-api>
|
|
806
986
|
|
|
807
987
|
|
|
@@ -13,5 +13,9 @@
|
|
|
13
13
|
android:name="ee.forgr.capacitor.social.login.TwitterLoginActivity"
|
|
14
14
|
android:exported="false"
|
|
15
15
|
android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar" />
|
|
16
|
+
<activity
|
|
17
|
+
android:name="ee.forgr.capacitor.social.login.OAuth2LoginActivity"
|
|
18
|
+
android:exported="false"
|
|
19
|
+
android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar" />
|
|
16
20
|
</application>
|
|
17
21
|
</manifest>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
package ee.forgr.capacitor.social.login;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import android.content.Intent;
|
|
5
|
+
import android.graphics.Bitmap;
|
|
6
|
+
import android.net.Uri;
|
|
7
|
+
import android.os.Bundle;
|
|
8
|
+
import android.view.ViewGroup;
|
|
9
|
+
import android.webkit.WebResourceRequest;
|
|
10
|
+
import android.webkit.WebSettings;
|
|
11
|
+
import android.webkit.WebView;
|
|
12
|
+
import android.webkit.WebViewClient;
|
|
13
|
+
import androidx.annotation.Nullable;
|
|
14
|
+
import androidx.annotation.RequiresApi;
|
|
15
|
+
|
|
16
|
+
public class OAuth2LoginActivity extends Activity {
|
|
17
|
+
|
|
18
|
+
public static final String EXTRA_AUTH_URL = "authUrl";
|
|
19
|
+
public static final String EXTRA_REDIRECT_URL = "redirectUrl";
|
|
20
|
+
|
|
21
|
+
private String redirectUrl;
|
|
22
|
+
|
|
23
|
+
@Override
|
|
24
|
+
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
25
|
+
super.onCreate(savedInstanceState);
|
|
26
|
+
WebView webView = new WebView(this);
|
|
27
|
+
webView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
|
|
28
|
+
WebSettings settings = webView.getSettings();
|
|
29
|
+
settings.setJavaScriptEnabled(true);
|
|
30
|
+
settings.setDomStorageEnabled(true);
|
|
31
|
+
settings.setLoadWithOverviewMode(true);
|
|
32
|
+
settings.setUseWideViewPort(true);
|
|
33
|
+
|
|
34
|
+
redirectUrl = getIntent().getStringExtra(EXTRA_REDIRECT_URL);
|
|
35
|
+
final String authUrl = getIntent().getStringExtra(EXTRA_AUTH_URL);
|
|
36
|
+
|
|
37
|
+
webView.setWebViewClient(
|
|
38
|
+
new WebViewClient() {
|
|
39
|
+
@Override
|
|
40
|
+
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
41
|
+
return handleUrl(url);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@RequiresApi(21)
|
|
45
|
+
@Override
|
|
46
|
+
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
|
47
|
+
return handleUrl(request.getUrl().toString());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@Override
|
|
51
|
+
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
|
52
|
+
handleUrl(url);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
setContentView(webView);
|
|
58
|
+
|
|
59
|
+
if (authUrl == null) {
|
|
60
|
+
finishWithError("Missing authorization URL");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
webView.loadUrl(authUrl);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private boolean handleUrl(String url) {
|
|
68
|
+
if (redirectUrl != null && url.startsWith(redirectUrl)) {
|
|
69
|
+
Uri uri = Uri.parse(url);
|
|
70
|
+
Intent data = new Intent();
|
|
71
|
+
|
|
72
|
+
// Handle authorization code flow (query parameters)
|
|
73
|
+
data.putExtra("code", uri.getQueryParameter("code"));
|
|
74
|
+
data.putExtra("state", uri.getQueryParameter("state"));
|
|
75
|
+
data.putExtra("error", uri.getQueryParameter("error"));
|
|
76
|
+
data.putExtra("error_description", uri.getQueryParameter("error_description"));
|
|
77
|
+
|
|
78
|
+
// Handle implicit flow (fragment parameters)
|
|
79
|
+
String fragment = uri.getFragment();
|
|
80
|
+
if (fragment != null && !fragment.isEmpty()) {
|
|
81
|
+
String[] pairs = fragment.split("&");
|
|
82
|
+
for (String pair : pairs) {
|
|
83
|
+
String[] keyValue = pair.split("=");
|
|
84
|
+
if (keyValue.length == 2) {
|
|
85
|
+
String key = keyValue[0];
|
|
86
|
+
String value = Uri.decode(keyValue[1]);
|
|
87
|
+
data.putExtra(key, value);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
setResult(Activity.RESULT_OK, data);
|
|
93
|
+
finish();
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private void finishWithError(String message) {
|
|
100
|
+
Intent data = new Intent();
|
|
101
|
+
data.putExtra("error", message);
|
|
102
|
+
setResult(Activity.RESULT_CANCELED, data);
|
|
103
|
+
finish();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@Override
|
|
107
|
+
public void onBackPressed() {
|
|
108
|
+
finishWithError("User cancelled");
|
|
109
|
+
}
|
|
110
|
+
}
|