/** * Configuration for a single OAuth2 provider instance */ export interface OAuth2ProviderConfig { /** * The OAuth 2.0 client identifier (App ID / Client ID). * * Note: this configuration object is only used by the plugin's built-in `oauth2` provider * (i.e. `SocialLogin.initialize({ oauth2: { ... } })`). It does not affect Google/Apple/Facebook/Twitter. * @example 'your-client-id' */ appId?: string; /** * Alias for `appId` to match common OAuth/OIDC naming (`clientId`). * If both are provided, `appId` takes precedence. * @example 'your-client-id' */ clientId?: string; /** * OpenID Connect issuer URL (enables discovery via `/.well-known/openid-configuration`). * When set, you may omit explicit endpoints like `authorizationBaseUrl` and `accessTokenEndpoint`. * * Notes: * - Explicit endpoints (authorization/token/logout) take precedence over discovered values. * - Discovery is supported for `oauth2` on Web, iOS, and Android. * * @example 'https://accounts.example.com' */ issuerUrl?: string; /** * The base URL of the authorization endpoint * @example 'https://accounts.example.com/oauth2/authorize' */ authorizationBaseUrl?: string; /** * Alias for `authorizationBaseUrl` (to match common OAuth/OIDC naming). * @example 'https://accounts.example.com/oauth2/authorize' */ authorizationEndpoint?: string; /** * OAuth 2.0 client secret for token requests (e.g., when exchanging the code). * When provided, this value is sent using `clientSecretParamName` (default `client_secret`). */ clientSecret?: string; /** * Override the client identifier parameter name used for authorization and token requests. * Some providers (e.g. TikTok) expect `client_key` instead of the default `client_id`. * @default 'client_id' */ clientIdParamName?: string; /** * Override the client secret parameter name used for token requests. * Useful for providers that expect a different parameter name. * @default 'client_secret' */ clientSecretParamName?: string; /** * The URL to exchange the authorization code for tokens * Required for authorization code flow * @example 'https://accounts.example.com/oauth2/token' */ accessTokenEndpoint?: string; /** * Alias for `accessTokenEndpoint` (to match common OAuth/OIDC naming). * @example 'https://accounts.example.com/oauth2/token' */ tokenEndpoint?: string; /** * Redirect URL that receives the OAuth callback * @example 'myapp://oauth/callback' */ redirectUrl: string; /** * Optional URL to fetch user profile/resource data after authentication * The access token will be sent as Bearer token in the Authorization header * @example 'https://api.example.com/userinfo' */ resourceUrl?: string; /** * The OAuth response type * - 'code': Authorization Code flow (recommended, requires accessTokenEndpoint) * - 'token': Implicit flow (less secure, tokens returned directly) * @default 'code' */ responseType?: 'code' | 'token'; /** * Enable PKCE (Proof Key for Code Exchange) * Strongly recommended for public clients (mobile/web apps) * @default true */ pkceEnabled?: boolean; /** * Default scopes to request during authorization * @example 'openid profile email' * @example ['openid','profile','email'] */ scope?: string | string[]; /** * Alias for `scope` using common naming (`scopes`). * If both are provided, `scope` takes precedence. */ scopes?: string[]; /** * Additional parameters to include in the authorization request * @example { prompt: 'consent', login_hint: 'user@example.com' } */ additionalParameters?: Record; /** * Convenience option for OIDC `login_hint`. * Equivalent to passing `additionalParameters.login_hint`. */ loginHint?: string; /** * Convenience option for OAuth/OIDC `prompt`. * Equivalent to passing `additionalParameters.prompt`. */ prompt?: string; /** * Additional parameters to include in token requests (code exchange / refresh). * Useful for providers that require non-standard parameters. */ additionalTokenParameters?: Record; /** * Additional headers to include when fetching the resource URL * @example { 'X-Custom-Header': 'value' } */ additionalResourceHeaders?: Record; /** * Custom logout URL for ending the session * @example 'https://accounts.example.com/logout' */ logoutUrl?: string; /** * Alias for `logoutUrl` to match OIDC naming (`endSessionEndpoint`). * @example 'https://accounts.example.com/logout' */ endSessionEndpoint?: string; /** * OIDC post logout redirect URL (sent as `post_logout_redirect_uri` when building the end-session URL). * @example 'myapp://logout/callback' */ postLogoutRedirectUrl?: string; /** * Additional parameters to include in logout / end-session URL. */ additionalLogoutParameters?: Record; /** * iOS-only: Whether to prefer an ephemeral browser session for ASWebAuthenticationSession. * Defaults to true to match existing behavior in this plugin. */ iosPrefersEphemeralWebBrowserSession?: boolean; /** * Alias for `iosPrefersEphemeralWebBrowserSession` (to match Capawesome OAuth naming). */ iosPrefersEphemeralSession?: boolean; /** * Android-only: Use Chrome Custom Tabs (system browser) instead of an embedded WebView * for the authorization request. * * Custom Tabs follow RFC 8252 (OAuth 2.0 for Native Apps) and fix issues with brokered * IdPs (Microsoft Entra Conditional Access / Authenticator, passkeys/WebAuthn, Google * `disallowed_useragent`, SSO cookie sharing, password managers). * * Requires a custom-scheme or App Link `redirectUrl` with a matching intent filter in * your app's `AndroidManifest.xml` (same setup as `openSecureWindow()` / Apple on Android). * * Defaults to `false` to preserve the historical WebView flow. * * @default false * @example true */ androidUseCustomTabs?: boolean; /** * Enable debug logging * @default false */ logsEnabled?: boolean; } /** * LinkedIn provider configuration (convenience wrapper around the generic OAuth2 provider). * * Uses the OAuth2 engine with LinkedIn defaults: * - Authorization URL: https://www.linkedin.com/oauth/v2/authorization * - Token URL: https://www.linkedin.com/oauth/v2/accessToken * - Resource URL: https://api.linkedin.com/v2/userinfo * - Default scopes: `openid profile email` */ export interface LinkedInProviderConfig extends OAuth2ProviderConfig { /** * LinkedIn Client ID from the LinkedIn Developer Portal. */ clientId: string; /** * Redirect URL that receives the OAuth callback. * Must match a redirect URL configured in the LinkedIn Developer Portal. * @example 'https://your-app.example/auth/linkedin' */ redirectUrl: string; /** * LinkedIn Client Secret. * * Prefer exchanging the authorization code on a backend when possible. * Needed for confidential clients that do not use PKCE-only token exchange. */ clientSecret?: string; } /** * TikTok Login Kit configuration (convenience wrapper around the generic OAuth2 provider). * * Uses TikTok OAuth 2.0 endpoints and `client_key` instead of `client_id`. * @see https://developers.tiktok.com/doc/login-kit-web */ export interface TikTokProviderConfig { /** * TikTok client key (also known as app key). * @example 'aw3y*****' */ clientKey: string; /** * Redirect URL registered in your TikTok developer app. * @example 'myapp://auth/tiktok' */ redirectUrl: string; /** * TikTok client secret. Optional. * When set, the plugin includes it on token and refresh requests. * On web this value is stored with the OAuth2 config. * Login always exchanges the authorization code in the plugin; the raw code is not returned to the app. */ clientSecret?: string; /** * Scopes to request during login. Arrays are sent as a comma-separated string (TikTok Login Kit). * @default ['user.info.basic'] * @example ['user.info.basic','video.list'] */ scopes?: string[]; /** * Alias for `scopes`. */ scope?: string | string[]; /** * Toggle PKCE usage during the authorization code flow. * @default true */ pkceEnabled?: boolean; /** * Enable verbose debug logging for the TikTok OAuth2 flow. * @default false */ logsEnabled?: boolean; } /** * Options for `refreshToken()`. * `providerId` is required for generic `oauth2` and ignored for LinkedIn and TikTok. */ export type RefreshTokenOptions = { provider: 'oauth2'; providerId: string; refreshToken?: string; additionalParameters?: Record; } | { provider: 'linkedin'; providerId?: string; refreshToken?: string; additionalParameters?: Record; } | { provider: 'tiktok'; providerId?: string; refreshToken?: string; additionalParameters?: Record; }; export interface InitializeOptions { /** * OAuth2 provider configurations. * Supports multiple providers by using a Record with provider IDs as keys. * @example * { * github: { appId: '...', authorizationBaseUrl: 'https://github.com/login/oauth/authorize', ... }, * azure: { appId: '...', authorizationBaseUrl: 'https://login.microsoftonline.com/.../oauth2/v2.0/authorize', ... } * } */ oauth2?: Record; /** * Telegram Login Widget configuration. * Uses Telegram's OAuth widget (`oauth.telegram.org`), not standard OAuth2. */ telegram?: { /** * Telegram bot ID (numeric, not the bot token). * @example '123456789' */ botId: string; /** * Default redirect URL that will receive Telegram auth data. * For mobile apps, prefer a custom scheme (e.g. `myapp://telegram-auth`). * On iOS/Android this must be set here or per login; native login rejects if it is missing. */ redirectUrl?: string; /** * Origin/domain registered for the Telegram login widget. * Required when `redirectUrl` is not `http`/`https` (for example a custom scheme like `myapp://telegram-auth`). * Defaults to the origin of `redirectUrl` only when that URL is already http(s). * @example 'https://example.com' */ origin?: string; /** * Requested access level. * @default 'write' */ requestAccess?: 'read' | 'write'; /** * Optional language code passed to Telegram (e.g. 'en', 'fr'). */ languageCode?: string; }; /** * LinkedIn configuration. * Convenience wrapper that maps to the OAuth2 provider using LinkedIn defaults. */ linkedin?: LinkedInProviderConfig; /** * TikTok Login Kit configuration. * Convenience wrapper that maps to the OAuth2 provider using TikTok defaults (`client_key`). */ tiktok?: TikTokProviderConfig; twitter?: { /** * The OAuth 2.0 client identifier issued by X (Twitter) Developer Portal * @example 'Y2xpZW50SWQ' */ clientId: string; /** * Redirect URL that is registered inside the X Developer Portal. * The plugin uses this URL on every platform to receive the authorization code. * @example 'myapp://auth/x' */ redirectUrl: string; /** * Default scopes appended to every login request when no custom scopes are provided. * @description Defaults to the minimum required scopes for Log in with X. * @default ['tweet.read','users.read'] */ defaultScopes?: string[]; /** * Force the consent screen to show on every login attempt. * Mirrors X's `force_login=true` flag. * @default false */ forceLogin?: boolean; /** * Optional audience value when your application has been approved for multi-tenant access. */ audience?: string; }; facebook?: { /** * Facebook App ID, provided by Facebook for web, in mobile it's set in the native files * @description For business integrations, use your Business App ID from Facebook Developer Console. * Business apps can access additional permissions like Instagram API, Pages API, and business management features. * @see docs/facebook_business_login.md for business app setup guide */ appId: string; /** * Facebook Client Token, provided by Facebook for web, in mobile it's set in the native files */ clientToken?: string; /** * Locale * @description The locale to use for the Facebook SDK (e.g., 'en_US', 'fr_FR', 'es_ES') * @default 'en_US' * @example 'fr_FR' */ locale?: string; }; google?: { /** * The app's client ID, found and created in the Google Developers Console. * Required for iOS platform. * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com * @since 3.1.0 */ iOSClientId?: string; /** * The app's server client ID, required for offline mode on iOS. * Should be the same value as webClientId. * Found and created in the Google Developers Console. * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com * @since 3.1.0 */ iOSServerClientId?: string; /** * The app's web client ID, found and created in the Google Developers Console. * Required for Android and Web platforms. * @example xxxxxx-xxxxxxxxxxxxxxxxxx.apps.googleusercontent.com * @since 3.1.0 */ webClientId?: string; /** * The login mode, can be online or offline. * * **Online mode (default):** * - Returns user profile data and access tokens * - Supports all methods: login, logout, isLoggedIn, getAuthorizationCode * * **Offline mode:** * - Returns only serverAuthCode for backend authentication * - No user profile data available * - **Limitations:** The following methods are NOT supported in offline mode: * - `logout()` - Will reject with "not implemented when using offline mode" * - `isLoggedIn()` - Will reject with "not implemented when using offline mode" * - `getAuthorizationCode()` - Will reject with "not implemented when using offline mode" * - `refresh()` - Will reject because offline mode only returns `serverAuthCode`; token refresh must happen on your backend * - Only `login()` method works in offline mode, returning serverAuthCode only * - `serverAuthCode` must be exchanged on your backend for access/refresh tokens * - Requires `iOSServerClientId` to be set on iOS * * @example 'offline' * @default 'online' * @since 3.1.0 */ mode?: 'online' | 'offline'; /** * Filter visible accounts by hosted domain * @description filter visible accounts by hosted domain */ hostedDomain?: string; /** * Google Redirect URL, should be your backend url that is configured in your google app */ redirectUrl?: string; }; apple?: { /** * Apple Client ID, provided by Apple for web and Android */ clientId?: string; /** * Apple Redirect URL, should be your backend url that is configured in your apple app * * **Note**: Use empty string `''` for iOS to prevent redirect. * **Note**: Not required when using Broadcast Channel mode on Android. */ redirectUrl?: string; /** * Use proper token exchange for Apple Sign-In * @description Controls how Apple Sign-In tokens are handled and what gets returned: * * **When `true` (Recommended for new implementations):** * - Exchanges authorization code for proper access tokens via Apple's token endpoint * - `idToken`: JWT containing user identity information (email, name, user ID) * - `accessToken.token`: Proper access token from Apple (short-lived, ~1 hour) * - `authorizationCode`: Raw authorization code for backend token exchange * * **When `false` (Default - Legacy mode):** * - Uses authorization code directly as access token for backward compatibility * - `idToken`: JWT containing user identity information (email, name, user ID) * - `accessToken.token`: The authorization code itself (not a real access token) * - `authorizationCode`: undefined * * @default false * @example * // Enable proper token exchange (recommended) * useProperTokenExchange: true * // Result: idToken=JWT, accessToken=real_token, authorizationCode=present * * // Legacy mode (backward compatibility) * useProperTokenExchange: false * // Result: idToken=JWT, accessToken=auth_code, authorizationCode=undefined */ useProperTokenExchange?: boolean; /** * Use Broadcast Channel for Android Apple Sign-In (Recommended) * @description When enabled, Android uses Broadcast Channel API instead of URL redirects. * This eliminates the need for redirect URL configuration and server-side setup. * * **Benefits:** * - No redirect URL configuration required * - No backend server needed for Android * - Simpler setup and more reliable communication * - Direct client-server communication via Broadcast Channel * * **When `true`:** * - Uses Broadcast Channel for authentication flow * - `redirectUrl` is ignored * - Requires Broadcast Channel compatible backend or direct token handling * * **When `false` (Default - Legacy mode):** * - Uses traditional URL redirect flow * - Requires `redirectUrl` configuration * - Requires backend server for token exchange * * @default false * @since 7.10.0 * @example * // Enable Broadcast Channel mode (recommended for new Android implementations) * useBroadcastChannel: true * // Result: Simplified setup, no redirect URL needed * * // Legacy mode (backward compatibility) * useBroadcastChannel: false * // Result: Traditional URL redirect flow with server-side setup */ useBroadcastChannel?: boolean; }; } export interface FacebookLoginOptions { /** * Permissions * @description Select permissions to login with. Supports both consumer and business permissions. * * **Consumer Permissions:** * - `email` - User's email address * - `public_profile` - User's public profile info * - `user_friends` - List of friends who also use your app * * **Business Permissions** (require business app configuration and may need App Review): * - `instagram_basic` - Instagram Basic Display API access * - `instagram_manage_insights` - Instagram Insights data * - `instagram_manage_comments` - Manage Instagram comments * - `instagram_content_publish` - Publish to Instagram * - `pages_show_list` - List of Pages managed by user * - `pages_read_engagement` - Read Page engagement metrics * - `pages_manage_posts` - Manage Page posts * - `pages_messaging` - Page messaging features * - `business_management` - Manage business assets * - `catalog_management` - Manage product catalogs * - `ads_management` - Manage advertising accounts * * @example ['email', 'public_profile'] // Consumer permissions * @example ['email', 'instagram_basic', 'pages_show_list'] // Business permissions * @see https://developers.facebook.com/docs/permissions/reference * @see docs/facebook_business_login.md for complete business integration guide */ permissions: string[]; /** * Is Limited Login * @description use limited login for Facebook iOS only. Important: This is iOS-only and doesn't affect Android. * Even if set to false, Facebook will automatically force it to true if App Tracking Transparency (ATT) permission is not granted. * Developers should always be prepared to handle both limited and full login scenarios. * @default false */ limitedLogin?: boolean; /** * Nonce * @description A custom nonce to use for the login request */ nonce?: string; } export interface TwitterLoginOptions { /** * Additional scopes to request during login. * If omitted the plugin falls back to the default scopes configured during initialization. * @example ['tweet.read','users.read','offline.access'] */ scopes?: string[]; /** * Provide a custom OAuth state value. * When not provided the plugin generates a cryptographically random value. */ state?: string; /** * Provide a pre-computed PKCE code verifier (mostly used for testing). * When omitted the plugin generates a secure verifier automatically. */ codeVerifier?: string; /** * Override the redirect URI for a single login call. * Useful when the same app supports multiple callback URLs per platform. */ redirectUrl?: string; /** * Force the consent screen on every attempt, maps to `force_login=true`. */ forceLogin?: boolean; } export interface TelegramLoginOptions { /** * Override the redirect URL for this login attempt. * Defaults to the redirect configured during initialize(). * Required on iOS/Android when initialize() did not set `redirectUrl`. */ redirectUrl?: string; /** * Optional state parameter for CSRF protection. * If omitted, a secure random value is generated automatically. */ state?: string; /** * Override requested access level for this login. * Defaults to the value configured during initialize(). * @default 'write' */ requestAccess?: 'read' | 'write'; } export interface OAuth2LoginOptions { /** * The provider ID as configured in initialize() * This is required to identify which OAuth2 provider to use * @example 'github', 'azure', 'keycloak' */ providerId: string; /** * Override the scopes for this login request * If not provided, uses the scopes from initialization */ scope?: string | string[]; /** * Alias for `scope` using common naming (`scopes`). * If both are provided, `scope` takes precedence. */ scopes?: string[]; /** * Custom state parameter for CSRF protection * If not provided, a random value is generated */ state?: string; /** * Override PKCE code verifier (for testing purposes) * If not provided, a secure random verifier is generated */ codeVerifier?: string; /** * Override redirect URL for this login request */ redirectUrl?: string; /** * Additional parameters to add to the authorization URL */ additionalParameters?: Record; /** * Convenience option for OIDC `login_hint`. * Equivalent to passing `additionalParameters.login_hint`. */ loginHint?: string; /** * Convenience option for OAuth/OIDC `prompt`. * Equivalent to passing `additionalParameters.prompt`. */ prompt?: string; /** * Web-only (`oauth2` provider only): Use a full-page redirect instead of a popup window. * * When using `redirect`, the promise returned by `login()` will not resolve because the page navigates away. * After the redirect lands back in your app, call `SocialLogin.handleRedirectCallback()` on that page to * parse the result. * * @default 'popup' */ flow?: 'popup' | 'redirect'; } /** * LinkedIn login options (maps to the OAuth2 provider internally). * `providerId` is set to `linkedin` automatically. */ export type LinkedInLoginOptions = Omit; export interface TikTokLoginOptions { /** * Optional scopes to override the initialization scopes. * @example ['user.info.basic'] */ scopes?: string[]; /** * Alias for `scopes`. */ scope?: string | string[]; /** * Custom state parameter for CSRF protection. */ state?: string; /** * Custom PKCE code verifier (mostly for testing). */ codeVerifier?: string; /** * Override redirect URL for this login request. */ redirectUrl?: string; } export interface OAuth2LoginResponse { /** * The provider ID that was used for this login */ providerId: string; /** * The access token received from the OAuth provider */ accessToken: AccessToken | null; /** * The ID token (JWT) if provided by the OAuth server (e.g., OpenID Connect) */ idToken: string | null; /** * The refresh token if provided (requires appropriate scope like offline_access) */ refreshToken: string | null; /** * Resource data fetched from resourceUrl if configured * Contains the raw JSON response from the resource endpoint */ resourceData: Record | null; /** * The scopes that were granted */ scope: string[]; /** * Token type (usually 'bearer') */ tokenType: string; /** * Token expiration time in seconds */ expiresIn: number | null; } /** * LinkedIn login response (returned when using the LinkedIn convenience API). */ export type LinkedInLoginResponse = OAuth2LoginResponse; /** * TikTok login response (same shape as generic OAuth2). */ export type TikTokLoginResponse = OAuth2LoginResponse; export interface GoogleLoginOptions { /** * Specifies the scopes required for accessing Google APIs * The default is defined in the configuration. * @example ["profile", "email"] * @see [Google OAuth2 Scopes](https://developers.google.com/identity/protocols/oauth2/scopes) */ scopes?: string[]; /** * Nonce * @description nonce */ nonce?: string; /** * Force refresh token (only for Android) * @description force refresh token * @default false * @note On Android, the OS caches access tokens, and if a token is invalid (e.g., user revoked app access), the plugin might return an invalid accessToken. Using getAuthorizationCode() is recommended to ensure the token is valid. */ forceRefreshToken?: boolean; /** * Force account selection prompt (iOS) * @description forces the account selection prompt to appear on iOS * @default false */ forcePrompt?: boolean; /** * Style * @description style * @default 'standard' */ style?: 'bottom' | 'standard'; /** * Filter by authorized accounts (Android only) * @description Only show accounts that have previously been used to sign in to the app. * This option is only available for the 'bottom' style. * Note: For Family Link supervised accounts, this should be set to false. * @default false */ filterByAuthorizedAccounts?: boolean; /** * Auto select enabled (Android only) * @description Automatically select the account if only one Google account is available. * This option is only available for the 'bottom' style. * @default false */ autoSelectEnabled?: boolean; /** * Prompt parameter for Google OAuth (Web only) * @description A space-delimited, case-sensitive list of prompts to present the user. * If you don't specify this parameter, the user will be prompted only the first time your project requests access. * * **Possible values:** * - `none`: Don't display any authentication or consent screens. Must not be specified with other values. * - `consent`: Prompt the user for consent. * - `select_account`: Prompt the user to select an account. * * **Examples:** * - `prompt: 'consent'` - Always show consent screen * - `prompt: 'select_account'` - Always show account selection * - `prompt: 'consent select_account'` - Show both consent and account selection * * **Note:** This parameter only affects web platform behavior. Mobile platforms use their own native prompts. * * @example 'consent' * @example 'select_account' * @example 'consent select_account' * @see [Google OAuth2 Prompt Parameter](https://developers.google.com/identity/protocols/oauth2/openid-connect#prompt) * @since 7.12.0 */ prompt?: 'none' | 'consent' | 'select_account' | 'consent select_account' | 'select_account consent'; } export interface GoogleLoginResponseOnline { /** * OAuth access token for Google APIs. * * May be `null` on Android when Credential Manager authentication succeeds but * AuthorizationClient does not return an access token (authentication-only / * ID-token login with default OIDC scopes). Use `idToken` for user authentication; * request additional Google API scopes when an access token is required. */ accessToken: AccessToken | null; /** * OpenID Connect ID token (JWT). * * Includes an `email_verified` claim when the `email` scope is granted. Use * `SocialLogin.decodeIdToken({ idToken })` to read claims on the client, but * always verify the token signature, `iss`, `aud`, and `exp` on your backend * before trusting `email_verified` for account linking. * * @see https://developers.google.com/identity/gsi/web/guides/verify-google-id-token */ idToken: string | null; profile: { /** * Email from the ID token payload. Does not include a separate verification flag; * check `idToken` claims (`email_verified`) for whether Google attests the address. */ email: string | null; familyName: string | null; givenName: string | null; id: string | null; name: string | null; imageUrl: string | null; }; responseType: 'online'; } export interface GoogleLoginResponseOffline { serverAuthCode: string; responseType: 'offline'; } export type GoogleLoginResponse = GoogleLoginResponseOnline | GoogleLoginResponseOffline; export interface AppleProviderOptions { /** * Scopes * @description An array of scopes to request during login * @example ["name", "email"] * default: ["name", "email"] */ scopes?: string[]; /** * Nonce * @description nonce */ nonce?: string; /** * State * @description state */ state?: string; /** * Use Broadcast Channel for authentication flow * @description When enabled, uses Broadcast Channel API for communication instead of URL redirects. * Only applicable on platforms that support Broadcast Channel (Android). * @default false */ useBroadcastChannel?: boolean; } export interface AppleProviderResponse { /** * Access token from Apple * @description Content depends on `useProperTokenExchange` setting: * - When `useProperTokenExchange: true`: Real access token from Apple (~1 hour validity) * - When `useProperTokenExchange: false`: Contains authorization code as token (legacy mode) * Use `idToken` for user authentication, `accessToken` for API calls when properly exchanged. */ accessToken: AccessToken | null; /** * Identity token (JWT) from Apple. * * Includes standard OIDC claims such as `sub`, `email` (when granted), and * `email_verified` (boolean). Apple sets `email_verified` to `true` when it * attests the user controls the email (including Hide My Email relay addresses). * * Use `SocialLogin.decodeIdToken({ idToken })` to read claims on the client, but * verify the token signature, `iss`, `aud`, and `exp` on your backend before * trusting `email_verified` for account linking. * * @see https://developer.apple.com/documentation/signinwithapple/authenticating-users-with-sign-in-with-apple */ idToken: string | null; /** * User profile information * @description Basic user profile data extracted from the identity token and Apple response: * - `user`: Apple's user identifier (sub claim from idToken) * - `email`: User's email address (if permission granted) * - `givenName`: User's first name (if permission granted) * - `familyName`: User's last name (if permission granted) */ profile: { user: string; email: string | null; givenName: string | null; familyName: string | null; }; /** * Authorization code for proper token exchange (when useProperTokenExchange is enabled) * @description Only present when `useProperTokenExchange` is `true`. This code should be exchanged * for proper access tokens on your backend using Apple's token endpoint. Use this for secure * server-side token validation and to obtain refresh tokens. * @see https://developer.apple.com/documentation/sign_in_with_apple/tokenresponse */ authorizationCode?: string; } export type LoginOptions = { provider: 'facebook'; options: FacebookLoginOptions; } | { provider: 'google'; options: GoogleLoginOptions; } | { provider: 'apple'; options: AppleProviderOptions; } | { provider: 'twitter'; options: TwitterLoginOptions; } | { provider: 'telegram'; options: TelegramLoginOptions; } | { provider: 'linkedin'; options: LinkedInLoginOptions; } | { provider: 'tiktok'; options: TikTokLoginOptions; } | { provider: 'oauth2'; options: OAuth2LoginOptions; }; export type LoginResult = { provider: 'facebook'; result: FacebookLoginResponse; } | { provider: 'google'; result: GoogleLoginResponse; } | { provider: 'apple'; result: AppleProviderResponse; } | { provider: 'twitter'; result: TwitterLoginResponse; } | { provider: 'telegram'; result: TelegramLoginResponse; } | { provider: 'linkedin'; result: LinkedInLoginResponse; } | { provider: 'tiktok'; result: TikTokLoginResponse; } | { provider: 'oauth2'; result: OAuth2LoginResponse; }; export interface AccessToken { applicationId?: string; declinedPermissions?: string[]; expires?: string; isExpired?: boolean; lastRefresh?: string; permissions?: string[]; token: string; tokenType?: string; refreshToken?: string; userId?: string; } export interface FacebookLoginResponse { accessToken: AccessToken | null; /** * Whether Facebook Limited Login was used for this session. * When `true`, `accessToken` is not valid for Graph API calls (Facebook error 190). * Validate `idToken` on your backend instead, or call `facebook#requestTracking` and log in again after ATT is granted. * @since 8.4.0 */ isLimitedLogin?: boolean; /** * OpenID Connect ID token (JWT) from Meta Limited Login (iOS native, when available). * * **Not equivalent to Google/Apple `email_verified`:** Meta's OIDC token may include * an `email` claim (when the `email` permission is granted) but does **not** publish an * `email_verified` claim like Google or Apple. Meta documents the value as the user's * primary account email, not as an OIDC-verified email assertion. * * On Android and Web this is usually `null` (Graph API access token flow instead). * Validate signature, `iss` (`https://www.facebook.com` or `https://limited.facebook.com`), * `aud`, `exp`, and nonce on your backend. Do not infer `email_verified: true` from the * presence of `email` alone when linking accounts across providers. * * @see https://developers.facebook.com/docs/facebook-login/limited-login/token/validating/ */ idToken: string | null; profile: { userID: string; /** * Primary email from the Meta profile / Graph API (`/me?fields=email`). * * **Not equivalent to Google/Apple `email_verified`:** this field has no verification * flag. Meta returns the account's primary email when the `email` permission is * granted; it does not expose an `email_verified` boolean comparable to Google or * Apple ID tokens. Treat this as an identifier hint only—verify ownership yourself * (e.g. magic link) before linking Meta sign-in to Google/Apple accounts by email. */ email: string | null; friendIDs: string[]; birthday: string | null; ageRange: { min?: number; max?: number; } | null; gender: string | null; location: { id: string; name: string; } | null; hometown: { id: string; name: string; } | null; profileURL: string | null; name: string | null; imageURL: string | null; }; } export interface TwitterProfile { id: string; username: string; name: string | null; profileImageUrl: string | null; verified: boolean; email?: string | null; } export interface TwitterLoginResponse { accessToken: AccessToken | null; refreshToken?: string | null; scope: string[]; tokenType: 'bearer'; expiresIn?: number | null; profile: TwitterProfile; } export interface TelegramProfile { id: string; firstName: string; lastName?: string | null; username?: string | null; photoUrl?: string | null; } export interface TelegramLoginResponse { profile: TelegramProfile; /** * Unix timestamp (seconds) when the user authorized the login. */ authDate: number; /** * Telegram-provided hash for server-side verification. */ hash: string; /** * Requested access level that was used for this login. */ requestAccess: 'read' | 'write'; } export interface AuthorizationCode { /** * Jwt * @description A JSON web token */ jwt?: string; /** * Access Token * @description An access token */ accessToken?: string; } export interface AuthorizationCodeOptions { /** * Provider * @description Provider for the authorization code */ provider: 'apple' | 'google' | 'facebook' | 'twitter' | 'linkedin' | 'tiktok' | 'oauth2'; /** * Provider ID for OAuth2 providers (required when provider is 'oauth2') * @description The ID used when configuring the OAuth2 provider in initialize() */ providerId?: string; } export interface isLoggedInOptions { /** * Provider * @description Provider for the isLoggedIn */ provider: 'apple' | 'google' | 'facebook' | 'twitter' | 'telegram' | 'linkedin' | 'tiktok' | 'oauth2'; /** * Provider ID for OAuth2 providers (required when provider is 'oauth2') * @description The ID used when configuring the OAuth2 provider in initialize() */ providerId?: string; } /** * Options for `providerSpecificCall` with `google#createRestoreCredential`. * * Android-only. Creates a Restore Credential (restore key) via Credential Manager after the user * signs in. Your backend must supply WebAuthn PublicKeyCredentialCreationOptionsJSON (the same * FIDO2/passkey registration flow used for passkeys). * * @see https://developer.android.com/identity/sign-in/restore-credentials * @since 8.5.0 */ export interface GoogleCreateRestoreCredentialOptions { /** * Credential creation options from your server in WebAuthn PublicKeyCredentialCreationOptionsJSON format. */ requestJson: string; /** * When `true` (default), the restore key is backed up to the cloud when the user has backup and * end-to-end encryption (e.g. screen lock) enabled. If cloud backup creation fails with * `E2eeUnavailableException` on Android, the plugin automatically retries with local-only storage. * @default true */ isCloudBackupEnabled?: boolean; } /** * Response from `google#createRestoreCredential`. * * Send `responseJson` to your server to complete restore key registration (same as passkey creation). */ export interface GoogleCreateRestoreCredentialResponse { /** Public key credential registration response JSON from Credential Manager. */ responseJson: string; } /** * Options for `providerSpecificCall` with `google#getRestoreCredential`. * * Android-only. Retrieves a Restore Credential silently (e.g. on first launch on a new device or from * BackupAgent `onRestoreFinished`). Your backend must supply WebAuthn authentication request JSON. */ export interface GoogleGetRestoreCredentialOptions { /** * Credential request options from your server (WebAuthn authentication request JSON). */ requestJson: string; } /** * Response from `google#getRestoreCredential`. * * Send `responseJson` to your server to sign the user in (same server path as passkey authentication). */ export interface GoogleGetRestoreCredentialResponse { /** Restore credential authentication response JSON from Credential Manager. */ responseJson: string; } /** Options for `google#clearRestoreCredential` (no fields). */ export type GoogleClearRestoreCredentialOptions = Record; /** Response from `google#clearRestoreCredential`. */ export interface GoogleClearRestoreCredentialResponse { /** Whether the restore credential clear request completed successfully. */ cleared: boolean; } export type ProviderSpecificCall = 'facebook#getProfile' | 'facebook#requestTracking' | 'google#createRestoreCredential' | 'google#getRestoreCredential' | 'google#clearRestoreCredential'; export interface FacebookGetProfileOptions { /** * Fields to retrieve from Facebook profile. * @default ['id', 'name', 'email', 'picture'] * @example ["id", "name", "email", "picture"] */ fields?: string[]; } export interface FacebookGetProfileResponse { /** * Facebook profile data */ profile: { id: string | null; name: string | null; email: string | null; first_name: string | null; last_name: string | null; picture?: { data: { height: number | null; is_silhouette: boolean | null; url: string | null; width: number | null; }; } | null; [key: string]: any; }; } export interface OpenSecureWindowOptions { /** * The endpoint to open */ authEndpoint: string; /** * The redirect URI to use for the openSecureWindow call. * This will be checked to make sure it matches the redirect URI after the window finishes the redirection. */ redirectUri: string; /** * The name of the broadcast channel to listen to, relevant only for web */ broadcastChannelName?: string; } export interface OpenSecureWindowResponse { /** * The result of the openSecureWindow call */ redirectedUri: string; } export type FacebookRequestTrackingOptions = Record; export interface FacebookRequestTrackingResponse { /** * App tracking authorization status */ status: 'authorized' | 'denied' | 'notDetermined' | 'restricted'; } export type ProviderSpecificCallOptionsMap = { 'facebook#getProfile': FacebookGetProfileOptions; 'facebook#requestTracking': FacebookRequestTrackingOptions; 'google#createRestoreCredential': GoogleCreateRestoreCredentialOptions; 'google#getRestoreCredential': GoogleGetRestoreCredentialOptions; 'google#clearRestoreCredential': GoogleClearRestoreCredentialOptions; }; export type ProviderSpecificCallResponseMap = { 'facebook#getProfile': FacebookGetProfileResponse; 'facebook#requestTracking': FacebookRequestTrackingResponse; 'google#createRestoreCredential': GoogleCreateRestoreCredentialResponse; 'google#getRestoreCredential': GoogleGetRestoreCredentialResponse; 'google#clearRestoreCredential': GoogleClearRestoreCredentialResponse; }; export type ProviderResponseMap = { facebook: FacebookLoginResponse; google: GoogleLoginResponse; apple: AppleProviderResponse; twitter: TwitterLoginResponse; telegram: TelegramLoginResponse; linkedin: LinkedInLoginResponse; tiktok: TikTokLoginResponse; oauth2: OAuth2LoginResponse; }; /** * Error codes returned by the plugin. * @since 8.3.x */ export type SocialLoginErrorCode = 'USER_CANCELLED'; /** * Errors thrown by SocialLogin methods. * * When a user dismisses or cancels the provider UI (popup closed, system dialog cancelled, access denied, etc.), * the plugin rejects with `code === 'USER_CANCELLED'` so the caller can distinguish user intent from real failures. * Other errors may omit the code or use provider-specific values. */ export interface SocialLoginError extends Error { code?: SocialLoginErrorCode | string; } export interface SocialLoginPlugin { /** * Initialize the plugin * @description initialize the plugin with the required options */ initialize(options: InitializeOptions): Promise; /** * Login with the selected provider * @description login with the selected provider * * On user dismissal/cancellation, the Promise is rejected with `code === 'USER_CANCELLED'` (see `SocialLoginError`). */ login(options: Extract): Promise<{ provider: T; result: ProviderResponseMap[T]; }>; /** * Logout * @description Logout the user from the specified provider * * **Google Offline Mode Limitation:** * This method is NOT supported when Google is initialized with `mode: 'offline'`. * It will reject with error: "logout is not implemented when using offline mode" * * **Google Restore Credentials (Android):** * When logging out from Google, the plugin also clears any stored Restore Credential * (`google#clearRestoreCredential`) in addition to Credential Manager sign-in state. * * @throws Error if Google provider is in offline mode */ logout(options: { provider: 'apple' | 'google' | 'facebook' | 'twitter' | 'telegram' | 'linkedin' | 'tiktok' | 'oauth2'; providerId?: string; }): Promise; /** * IsLoggedIn * @description Check if the user is currently logged in with the specified provider * * **Google Offline Mode Limitation:** * This method is NOT supported when Google is initialized with `mode: 'offline'`. * It will reject with error: "isLoggedIn is not implemented when using offline mode" * * @throws Error if Google provider is in offline mode */ isLoggedIn(options: isLoggedInOptions): Promise<{ isLoggedIn: boolean; }>; /** * Get the current authorization code * @description Get the authorization code for server-side authentication * * **Google Offline Mode Limitation:** * This method is NOT supported when Google is initialized with `mode: 'offline'`. * It will reject with error: "getAuthorizationCode is not implemented when using offline mode" * * In offline mode, the authorization code (serverAuthCode) is already returned by the `login()` method. * * Telegram login does not produce an authorization code; use the `hash` from `login()` and verify it on your backend. * * @throws Error if Google provider is in offline mode */ getAuthorizationCode(options: AuthorizationCodeOptions): Promise; /** * Refresh the access token * @description refresh the access token * * **Google Offline Mode Limitation:** * This method is NOT supported when Google is initialized with `mode: 'offline'`. * Offline mode only returns `serverAuthCode` for backend token exchange, so token refresh must happen on your backend. * The plugin logs and rejects with a message explaining that you should send `serverAuthCode` to your backend, * refresh the Google tokens there, or switch to `mode: 'online'` for client-side refresh. * * **Google Web Limitation:** * On Web, Google `refresh()` is not implemented, even when using `mode: 'online'`. * Call `login()` again on Web to obtain a fresh token instead. * * @throws Error if Google provider is in offline mode, or on Web where Google `refresh()` is not implemented */ refresh(options: LoginOptions): Promise; /** * OAuth2 refresh-token helper (feature parity with Capawesome OAuth). * * Scope: * - Applies to the built-in `oauth2` provider and the LinkedIn and TikTok convenience wrappers. * - Requires a token endpoint (either `accessTokenEndpoint`/`tokenEndpoint` or `issuerUrl` discovery). * * Security note: * - This does not validate JWT signatures. It only exchanges/refreshes tokens. * * If `refreshToken` is omitted, the plugin will attempt to use the stored refresh token (if available). */ refreshToken(options: RefreshTokenOptions): Promise; /** * Web-only: handle the OAuth redirect callback and return the parsed result. * * Notes: * - This is only meaningful on Web. iOS/Android implementations will reject. * - Intended for redirect-based flows (e.g. `oauth2` with `flow: 'redirect'`) where the page navigates away. * - LinkedIn convenience logins (`provider: 'linkedin'`, `flow: 'redirect'`) return `provider: 'linkedin'`. * The same app used as `oauth2` with `providerId: 'linkedin'` keeps `provider: 'oauth2'`. */ handleRedirectCallback(): Promise; /** * Decode a JWT (typically an OIDC ID token) into its claims. * * Notes: * - Accepts both `idToken` and `token` to match common naming (Capawesome uses `token`). * - This does not validate the signature or issuer/audience. It only base64url-decodes the payload. * * **`email_verified` semantics by provider (for account linking):** * - **Google** — ID token includes `email_verified` (boolean). When `true`, Google attests * the user controls that email. Verify the JWT on your backend before trusting it. * - **Apple** — ID token includes `email_verified` (boolean). When `true`, Apple attests * the user controls that email (including private relay). Verify the JWT on your backend. * - **Meta (Facebook)** — Limited Login OIDC tokens may include `email` but **do not** * include `email_verified`. The presence of `email` is not the same guarantee as * `email_verified: true` from Google or Apple. Do not link accounts by email across * providers using Meta claims alone; perform your own email verification if needed. */ decodeIdToken(options: { idToken?: string; token?: string; }): Promise<{ claims: Record; }>; /** * Convert an access token expiration timestamp (milliseconds since epoch) to an ISO date string. * * This is a pure helper (feature parity with Capawesome OAuth) and does not depend on provider state. */ getAccessTokenExpirationDate(options: { /** * Access token expiration date in milliseconds since epoch. * Typically: `Date.now() + expiresInSeconds * 1000`. */ accessTokenExpirationDate: number; }): Promise<{ date: string; }>; /** * Check if an access token is available (non-empty). * * This is a pure helper (feature parity with Capawesome OAuth) and does not depend on provider state. */ isAccessTokenAvailable(options: { accessToken: string | null; }): Promise<{ isAvailable: boolean; }>; /** * Check if an access token is expired. * * This is a pure helper (feature parity with Capawesome OAuth) and does not depend on provider state. */ isAccessTokenExpired(options: { accessTokenExpirationDate: number; }): Promise<{ isExpired: boolean; }>; /** * Check if a refresh token is available (non-empty). * * This is a pure helper (feature parity with Capawesome OAuth) and does not depend on provider state. */ isRefreshTokenAvailable(options: { refreshToken: string | null; }): Promise<{ isAvailable: boolean; }>; /** * Execute provider-specific calls * @description Execute a provider-specific functionality */ providerSpecificCall(options: { call: T; options: ProviderSpecificCallOptionsMap[T]; }): Promise; /** * Get the native Capacitor plugin version * * @returns {Promise<{ id: string }>} an Promise with version for this device * @throws An error if the something went wrong */ getPluginVersion(): Promise<{ version: string; }>; /** * Opens a secured window for OAuth2 authentication. * For web, you should have the code in the redirected page to use a broadcast channel to send the redirected url to the app * Something like: * ```html * * * * * * * ``` * For mobile, you should have a redirect uri that opens the app, something like: `myapp://oauth_callback/` * And make sure to register it in the app's info.plist: * ```xml * CFBundleURLTypes * * * CFBundleURLSchemes * * myapp * * * * ``` * And in the AndroidManifest.xml file: * ```xml * * * * * * * * * ``` * @param options - the options for the openSecureWindow call */ openSecureWindow(options: OpenSecureWindowOptions): Promise; }