Skip to main content

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.

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 (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 matches SF_CALLBACK_URI in your .env.

Required OAuth Scopes

Your Connected App must grant the following OAuth scopes:
api
refresh_token
offline_access
These map to the environment variable:
SF_OAUTH_SCOPE="api refresh_token offline_access"
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.
If offline_access is missing, Salesforce will not include a refresh_token in the authorization response. This means iLeben cannot renew the access token automatically, and the integration will disconnect after the initial token expires.
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 recurring invalid_grant errors. A restrictive inactivity timeout is the most common cause of token expiry in production. Also set:
SF_OAUTH_PROMPT="consent"
Setting 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

1

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.
2

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)
Save the Connected App. Allow a few minutes for Salesforce to propagate the changes.
3

Set the Callback URI

Set the Callback URL in your Connected App to the value of SF_CALLBACK_URI in your environment:
SF_CALLBACK_URI=https://your-app.example.com/salesforce/callback
4

Copy Consumer Key and Secret to .env

From the Connected App detail page, copy Consumer Key and Consumer Secret into your .env:
SF_AUTH_METHOD=WebServer
SF_CONSUMER_KEY=3MVG9xxxxxxxxxxxxxxxxxxxxxxx
SF_CONSUMER_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
SF_CALLBACK_URI=https://your-app.example.com/salesforce/callback
SF_LOGIN_URL=https://login.salesforce.com
SF_API_VERSION=57.0
SF_INSTANCE_URL=https://your-domain.my.salesforce.com
SF_OAUTH_SCOPE="api refresh_token offline_access"
SF_OAUTH_PROMPT="consent"
5

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.
6

Verify the Connection

Run the test command to confirm authentication is working:
php artisan salesforce:test-auth
A successful run outputs:
✓ Token obtenido exitosamente
✓ Consulta exitosa
Conexión con Salesforce funcionando correctamente

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:
  1. After every successful OAuth callback, SalesforceOAuthController::callback() persists encrypted blobs of forrest_token and forrest_refresh_token into SiteSetting.extra_settings.salesforce_oauth under the keys token_cache_backup and refresh_token_cache_backup.
  2. When a background job (CreateSalesforceCaseJob) finds no token in the cache (e.g., after cache:clear or Redis restart), it calls SalesforceService::tryAutoReconnect().
  3. tryAutoReconnect() restores both encrypted blobs from the database to the Laravel cache, then calls Forrest::refresh() to obtain a new access token from Salesforce — with no user interaction.
  4. After each successful refresh, SalesforceService::updateTokenBackup() writes the new access token (and any rotated refresh token) back to the database, keeping the backup current.
  5. The scheduled command salesforce:refresh-token runs 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.
Post-deploy requirement: After the initial deployment, you must connect once from /admin/site-settingsConectar con Salesforce to generate the first token_cache_backup in the database. Without this step, the auto-reconnect mechanism has no backup to restore from and jobs will fail silently until a manual reconnect is performed.

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:
1

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.
2

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.
3

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).
SF_OAUTH_SCOPE="api refresh_token offline_access"
SF_OAUTH_PROMPT="consent"
4

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.
5

Test Authentication

Run the auth test command to verify the new token is working:
php artisan salesforce:test-auth
6

Validate End-to-End Lead Creation

Submit a test contact form on the public site and confirm a new Lead appears in Salesforce.
7

Monitor Logs

Watch the application log for the next 30 minutes to confirm invalid_grant does not reappear:
tail -f storage/logs/laravel.log | grep -i "salesforce\|invalid_grant"

Scheduler: Proactive Token Refresh

The salesforce:refresh-token command is scheduled to run every 20 hours via a cron expression in routes/console.php:
Schedule::command('salesforce:refresh-token')->cron('0 */20 * * *')->withoutOverlapping();
Its behavior depends on the current cache state:
  • 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.
You can run php artisan salesforce:refresh-token manually at any time to force a backup sync or trigger auto-reconnect outside the scheduled window.

Build docs developers (and LLMs) love