From 52d4aee104caa1df94704564f4be108a9ac18f1e Mon Sep 17 00:00:00 2001 From: Ran <16112591+chen-ran@users.noreply.github.com> Date: Tue, 24 Feb 2026 04:21:18 +0800 Subject: [PATCH] feat(auth): implement JWT token refresh mechanism --- agent/src/index.ts | 3 ++- internal/auth/jwt_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/agent/src/index.ts b/agent/src/index.ts index d89fc2be..9b48767b 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -27,8 +27,9 @@ function parseJwtExp(token: string): number | null { } } +let refreshPromise: Promise | null = null + export const createAuthFetcher = (auth: AgentAuthContext): AuthFetcher => { - let refreshPromise: Promise | null = null return async (url: string, options?: RequestInit) => { if (auth.bearer) { const exp = parseJwtExp(auth.bearer) diff --git a/internal/auth/jwt_test.go b/internal/auth/jwt_test.go index 2b48f6eb..63705f86 100644 --- a/internal/auth/jwt_test.go +++ b/internal/auth/jwt_test.go @@ -45,6 +45,7 @@ func TestRefreshTokenFromContext(t *testing.T) { originalClaims, ok := token.Claims.(jwt.MapClaims) assert.True(t, ok) origIat := int64(originalClaims["iat"].(float64)) + origExp := int64(originalClaims["exp"].(float64)) // Parse the new token newToken, err := jwt.Parse(newTokenStr, func(token *jwt.Token) (interface{}, error) { @@ -67,10 +68,9 @@ func TestRefreshTokenFromContext(t *testing.T) { // 1. Ensure time has advanced assert.Greater(t, newIat, origIat) - // 2. Ensure the refreshed token has a positive lifetime and does not exceed the configured default duration - lifetimeSeconds := newExp - newIat - assert.Greater(t, lifetimeSeconds, int64(0)) - assert.LessOrEqual(t, lifetimeSeconds, int64(defaultDuration.Seconds())) + // 2. Ensure it calculated the original duration and used it (5 mins), NOT the default 1 hour + assert.Equal(t, newExp-newIat, origExp-origIat) + assert.Equal(t, int64(5*60), newExp-newIat) // 3. Ensure the return value matches the claim assert.Equal(t, newExpiresAt.Unix(), newExp)