diff --git a/controlplane/src/core/auth-utils.ts b/controlplane/src/core/auth-utils.ts index 1b895f88ae..63a49a838a 100644 --- a/controlplane/src/core/auth-utils.ts +++ b/controlplane/src/core/auth-utils.ts @@ -317,8 +317,16 @@ export default class AuthUtils { throw new AuthenticationError(EnumStatusCode.ERROR_NOT_AUTHENTICATED, 'Refresh token expired'); } - const sessionExpiresIn = DEFAULT_SESSION_MAX_AGE_SEC; - const sessionExpiresDate = new Date(Date.now() + 1000 * sessionExpiresIn); + // The session expiration is relative to the creation time + const baseMs = userSession.createdAt.getTime(); + const expiresAtMs = baseMs + DEFAULT_SESSION_MAX_AGE_SEC * 1000; + const sessionExpiresDate = new Date(expiresAtMs); + const remainingSeconds = Math.max(0, Math.floor((expiresAtMs - Date.now()) / 1000)); + + if (remainingSeconds <= 0) { + // Absolute session lifetime has elapsed; do not renew. + throw new AuthenticationError(EnumStatusCode.ERROR_NOT_AUTHENTICATED, 'Session expired'); + } // Refresh the access token with the refresh token // The method will throw an error if the request fails @@ -345,7 +353,7 @@ export default class AuthUtils { const newUserSession = updatedSessions[0]; const jwt = await encrypt({ - maxAgeInSeconds: sessionExpiresIn, + maxAgeInSeconds: remainingSeconds, token: { iss: userSession.userId, sessionId: newUserSession.id,