Control exposes password, mobile OTP, and OAuth/social login. Which ones show up in the app is a LoginConfig setting on the client.
LoginConfig flags
LoginConfig(
enablePasswordLogin: true,
enableMobileLogin: true,
enableOAuth: true,
enableSocialLogin: true,
autoDiscoverSocialProviders: true,
socialProviders: [
SocialProviderConfig(id: 'google', label: 'Google'),
],
oauthClientId: config.AppConstants.oauthClientId,
oauthClientSecret: config.AppConstants.oauthClientSecret,
)
enableOAuth turns on the generic OAuth/SSO button. enableSocialLogin turns on provider-direct buttons (Google, Microsoft, and so on) that skip the extra provider-selection click. autoDiscoverSocialProviders pulls the provider list from the server instead of the static socialProviders fallback.
Password and OTP
No special server setup beyond having Control installed. The SDK calls mobile_auth.login for username/password and mobile_auth.send_login_otp / mobile_auth.verify_login_otp for mobile OTP.
OAuth and social login
Authorization code flow with PKCE.
Server side:
- Create an OAuth Client in Frappe.
- Set its redirect URI to exactly
frappemobilesdk://oauth/callback. - Configure providers via Social Login Key for social/SSO.
Client side, Android: add to the manifest inside your main activity.
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="frappemobilesdk"
android:host="oauth"
android:pathPrefix="/callback" />
</intent-filter>
Android 11+ also needs a queries entry so the browser is visible to the app:
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
</queries>
Client side, iOS: add to Info.plist.
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>frappemobilesdk</string>
</array>
</dict>
</array>
The client_id sent to the authorize URL is the Frappe OAuth Client ID, not a provider-side ID.
Session health
New in 2.0.0-beta.2. SessionHealth is healthy, degraded, or expired, exposed as sdk.sessionHealth.
expiredmeans the stored credential was definitively rejected and cleared. Prompt for re-login.degradedclears itself once a refresh succeeds. No action needed.
The SDK never wipes anything on the strength of this value by itself. It only tells the host what happened, so the host can decide what to show.