iLeben uses the WebServer OAuth flow to authenticate with Salesforce. Unlike the username-password flow, WebServer OAuth requires a one-time interactive login that yields a long-lived refresh token. Once the initial authorization is complete, the system automatically renews the access token in the background — no recurring human intervention required. The refresh token is persisted encrypted in the database (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/scooller/Leben-site/llms.txt
Use this file to discover all available pages before exploring further.
SiteSetting.extra_settings) so it survives cache:clear events, Redis restarts, and deployments without triggering a re-login.
Prerequisites
Before starting, you need a Salesforce Connected App in your org with OAuth enabled. The Connected App must be configured with the callback URI that matchesSF_CALLBACK_URI in your .env.
Required OAuth Scopes
Your Connected App must grant the following OAuth scopes:SF_OAUTH_SCOPE and SF_OAUTH_PROMPT (see below) are not included in the default .env.example. You must add them manually to your .env file after copying from .env.example.Recommended OAuth Policies
In your Connected App’s OAuth Policies section, configure the refresh token validity to allow continuous operation. Prefer a policy that keeps the refresh token valid until explicitly revoked — as long as your organization’s security policy permits — to avoid recurringinvalid_grant errors. A restrictive inactivity timeout is the most common cause of token expiry in production.
Also set:
prompt=consent forces Salesforce to always present the consent screen during the OAuth flow, which guarantees a fresh refresh_token is returned even when reconnecting. Without this, Salesforce may silently reuse a prior session and omit the refresh_token.
Setup Steps
Create a Connected App in Salesforce
In Salesforce Setup, navigate to App Manager → New Connected App. Enable OAuth settings and note the Callback URL field — this must match
SF_CALLBACK_URI.Set OAuth Scopes
In the Connected App’s Selected OAuth Scopes, add:
Access and manage your data (api)Perform requests at any time (refresh_token, offline_access)
Set the Callback URI
Set the Callback URL in your Connected App to the value of
SF_CALLBACK_URI in your environment:Copy Consumer Key and Secret to .env
From the Connected App detail page, copy Consumer Key and Consumer Secret into your
.env:Connect from the Admin Panel
Open the Filament admin panel and navigate to Site Settings (
/admin/site-settings). In the Salesforce tab, click Conectar con Salesforce. You will be redirected to Salesforce for login and consent. After authorizing, you are redirected back to the panel.On successful callback, iLeben stores the encrypted forrest_token and forrest_refresh_token blobs into SiteSetting.extra_settings.salesforce_oauth as token_cache_backup and refresh_token_cache_backup.Auto-Reconnect Mechanism
After the initial OAuth login, iLeben never requires a manual re-login unless the refresh token is explicitly revoked or expires. The auto-reconnect flow works as follows:-
After every successful OAuth callback,
SalesforceOAuthController::callback()persists encrypted blobs offorrest_tokenandforrest_refresh_tokenintoSiteSetting.extra_settings.salesforce_oauthunder the keystoken_cache_backupandrefresh_token_cache_backup. -
When a background job (
CreateSalesforceCaseJob) finds no token in the cache (e.g., aftercache:clearor Redis restart), it callsSalesforceService::tryAutoReconnect(). -
tryAutoReconnect()restores both encrypted blobs from the database to the Laravel cache, then callsForrest::refresh()to obtain a new access token from Salesforce — with no user interaction. -
After each successful refresh,
SalesforceService::updateTokenBackup()writes the new access token (and any rotated refresh token) back to the database, keeping the backup current. -
The scheduled command
salesforce:refresh-tokenruns every 20 hours (see Sync Commands) and proactively synchronizes the backup if a token is already in cache, or attempts auto-reconnect if no token is present.
Handling invalid_grant Errors
The invalid_grant error means Salesforce has invalidated the refresh token — typically because it expired, was revoked, or the Connected App’s OAuth policy rejected a reuse attempt. Follow this procedure to recover:
Verify Connected App OAuth Scopes
In Salesforce Setup, open your Connected App and confirm that OAuth Scopes include
api, refresh_token, and offline_access. Missing scopes are the most common root cause.Review OAuth Policies
Check the Connected App’s OAuth Policies and ensure the refresh token validity setting is compatible with continuous operation. If the policy forces expiry after a short inactivity period, the token will expire whenever the scheduler is paused or the server is idle.
Verify Environment Variables
Confirm that both
SF_OAUTH_SCOPE and SF_OAUTH_PROMPT are defined in your .env and that the running application has picked them up (run php artisan config:clear if in doubt).Reconnect from the Admin Panel
Navigate to
/admin/site-settings and click Conectar con Salesforce to start a fresh OAuth flow. Authorize the Connected App when prompted by Salesforce.Validate End-to-End Lead Creation
Submit a test contact form on the public site and confirm a new Lead appears in Salesforce.
Scheduler: Proactive Token Refresh
Thesalesforce:refresh-token command is scheduled to run every 20 hours via a cron expression in routes/console.php:
- Token present in cache: Calls
updateTokenBackup()to synchronize the DB backup without triggering a full refresh. This avoids consuming the refresh token unnecessarily when Salesforce has refresh token rotation enabled. - No token in cache: Calls
tryAutoReconnect()to restore the backup from the database and obtain a new access token from Salesforce.