diff --git a/config/packages/league_oauth2_server.yaml b/config/packages/league_oauth2_server.yaml index 7f2e059..6842142 100644 --- a/config/packages/league_oauth2_server.yaml +++ b/config/packages/league_oauth2_server.yaml @@ -4,7 +4,7 @@ league_oauth2_server: private_key_passphrase: null encryption_key: '%env(resolve:OAUTH_ENCRYPTION_KEY)%' require_code_challenge_for_public_clients: true - enable_client_credentials_grant: true + enable_client_credentials_grant: false enable_auth_code_grant: true enable_refresh_token_grant: true enable_password_grant: false diff --git a/config/services.yaml b/config/services.yaml index 82de8b4..652f9da 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -382,3 +382,8 @@ services: whitelisted_ips: '%env(csv:MAINTENANCE_MODE_IP_WHITELIST)%' whitelisted_routes: '%env(csv:MAINTENANCE_MODE_ROUTE_WHITELIST)%' whitelisted_paths: '%env(csv:MAINTENANCE_MODE_PATH_WHITELIST)%' + + league.oauth2_server.grant.client_credentials: + class: League\OAuth2\Server\Grant\ClientCredentialsGrant + tags: + - { name: league.oauth2_server.authorization_server.grant, accessTokenTTL: 'PT1H' } diff --git a/docs/api-consumer-guide.md b/docs/api-consumer-guide.md index 71000e6..953dbc2 100644 --- a/docs/api-consumer-guide.md +++ b/docs/api-consumer-guide.md @@ -10,7 +10,8 @@ A Symfony application exposing a read-mostly JSON API under the `/api` prefix. A - Token endpoint: `POST /token` (unauthenticated). - Enabled grants: **client_credentials**, **authorization_code** (PKCE required for public clients), **refresh_token**. Password and implicit grants are disabled. -- Access token TTL: **10 minutes** — clients must refresh/re-request frequently. +- Access token TTL depends on the grant: **1 hour** for client_credentials, **10 minutes** for authorization_code. + Do not hardcode either value — read `expires_in` from the token response, it is authoritative and may be tuned. - Available scopes: `email`, `id`, `profile`, `roles`, `api`. Default scope if none requested: `email`. - Each granted scope maps to a role `ROLE_OAUTH2_` (e.g. scope `api` → `ROLE_OAUTH2_API`). - Send the token as `Authorization: Bearer `. @@ -427,7 +428,7 @@ CRM selection attributes/segments for the authenticated user. `400 {"message": " ## Client implementation notes -1. **Token lifetime is 10 minutes** — implement refresh/re-fetch with a safety margin and retry once on 401. +1. **Token lifetime comes from `expires_in`** (currently 1 hour for client_credentials, 10 minutes for authorization_code) — cache the token for that long, refresh with a safety margin, and retry once on 401. 2. **Check for an `error` key even on 200 responses** for `/api/products` and the travel availability endpoint. 3. **Money units are inconsistent across endpoints**: contingent endpoints return decimal major units; accommodation-booking fields return integer cents. Normalize at the client boundary. 4. **Dates**: `Y-m-d` everywhere except `acceptedAt` (ISO-8601 datetime) and pickup planning (`Y-m-d H:i`). Contingent `dateFrom`/`dateTo` are inclusive night boundaries.