mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 06:52:47 +00:00
⏳ feat: Make OpenID Token Reuse Window Configurable (#13546)
* feat: make OpenID token reuse window configurable via OPENID_REUSE_MAX_SESSION_AGE_MS
The OpenID session-token reuse window in AuthController was a hardcoded 15-minute
constant, forcing /api/auth/refresh to perform a real refreshTokenGrant against the
IdP every 15 minutes even when the current access token is still valid. IdPs that
rotate and revoke the previous access token on refresh then invalidate a token that
is still in use by downstream consumers of the reused OpenID token (e.g. MCP servers
that receive {{LIBRECHAT_OPENID_TOKEN}} and introspect the bearer), producing
~15-minute 401 cycles regardless of the access token's actual lifetime.
Read the window from process.env.OPENID_REUSE_MAX_SESSION_AGE_MS via the existing
math() helper, so it accepts an arithmetic expression like SESSION_EXPIRY (e.g.
60 * 60 * 24 * 1000), defaulting to the existing 15 minutes so behavior is unchanged
unless explicitly configured. The existing 30s-before-expiry guard still forces a
refresh before genuine expiry, so a larger window remains safe.
* fix: extend OpenID reuse session lifetime
---------
Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
07af6ee288
commit
98822341ed
5 changed files with 183 additions and 5 deletions
|
|
@ -3,6 +3,7 @@ const jwt = require('jsonwebtoken');
|
|||
const openIdClient = require('openid-client');
|
||||
const { logger } = require('@librechat/data-schemas');
|
||||
const {
|
||||
math,
|
||||
isEnabled,
|
||||
findOpenIDUser,
|
||||
getOpenIdIssuer,
|
||||
|
|
@ -28,8 +29,18 @@ const { getOpenIdConfig, getOpenIdEmail } = require('~/strategies');
|
|||
|
||||
const AUTH_REFRESH_USER_PROJECTION = '-password -__v -totpSecret -backupCodes -federatedTokens';
|
||||
const OPENID_REUSE_EXPIRY_BUFFER_SECONDS = 30;
|
||||
/** Mirrors the default SESSION_EXPIRY to bound IdP revocation lag for session-token reuse. */
|
||||
const OPENID_REUSE_MAX_SESSION_AGE_MS = 15 * 60 * 1000;
|
||||
/**
|
||||
* Max age (ms) LibreChat reuses a cached OpenID session token before forcing an IdP refresh.
|
||||
* Env-overridable (accepts an arithmetic expression, e.g. `60 * 60 * 24 * 1000`, like
|
||||
* `SESSION_EXPIRY`): deployments whose IdP revokes the previous access token on refresh can
|
||||
* widen this to the access-token lifetime so a still-valid token is not rotated/revoked out
|
||||
* from under downstream consumers (e.g. MCP servers that introspect the bearer). Defaults to
|
||||
* 15 minutes.
|
||||
*/
|
||||
const OPENID_REUSE_MAX_SESSION_AGE_MS = math(
|
||||
process.env.OPENID_REUSE_MAX_SESSION_AGE_MS,
|
||||
15 * 60 * 1000,
|
||||
);
|
||||
|
||||
const registrationController = async (req, res) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ jest.mock('~/models', () => ({
|
|||
findUser: jest.fn(),
|
||||
}));
|
||||
jest.mock('@librechat/api', () => ({
|
||||
math: jest.fn((value, fallback) => fallback),
|
||||
isEnabled: jest.fn(),
|
||||
findOpenIDUser: jest.fn(),
|
||||
getOpenIdIssuer: jest.fn(() => 'https://issuer.example.com'),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue