@thinkingcat/auth-utils 1.0.20 → 1.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +75 -60
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -886,75 +886,90 @@ async function handleJWTCallback(token, user, account, options) {
886
886
  debugLog('handleJWTCallback', 'Initial login, creating token from user data');
887
887
  return createInitialJWTToken(token, user, account);
888
888
  }
889
- // 2. 이미 토큰에 정보가 있는 경우 - 만료 체크 갱신
890
- if (token.id) {
891
- const now = Date.now();
892
- const expires = token.accessTokenExpires;
893
- // 2-1. 토큰이 만료되지 않았으면 그대로 사용
894
- if (expires && expires > now) {
895
- debugLog('handleJWTCallback', 'Token is still valid, using existing token');
896
- return token;
889
+ // 2. 커스텀 토큰 쿠키 우선 체크 (middleware에서 refresh한 토큰이 있을 수 있음)
890
+ if (secret && licenseKey && serviceId) {
891
+ const cookieNameToUse = cookieName || `${serviceId}_access_token`;
892
+ debugLog('handleJWTCallback', 'Checking custom token cookie first:', cookieNameToUse);
893
+ const customJwt = await getJWTFromCustomTokenCookie(cookieNameToUse, secret, serviceId, licenseKey);
894
+ if (customJwt) {
895
+ debugLog('handleJWTCallback', 'Found valid custom token cookie, using it');
896
+ // refreshToken이 있으면 유지
897
+ if (token.refreshToken) {
898
+ customJwt.refreshToken = token.refreshToken;
899
+ }
900
+ return customJwt;
897
901
  }
898
- // 2-2. 토큰이 만료되었으면 refresh token으로 갱신 시도
899
- debugLog('handleJWTCallback', 'Token expired or no expiry, attempting refresh');
900
- const refreshToken = token.refreshToken;
901
- if (refreshToken && ssoBaseURL && authServiceKey) {
902
- try {
903
- debugLog('handleJWTCallback', 'Calling SSO refresh endpoint');
904
- const response = await fetch(`${ssoBaseURL}/api/sso/refresh`, {
905
- method: 'POST',
906
- headers: {
907
- 'Content-Type': 'application/json',
908
- 'x-auth-service-key': authServiceKey,
909
- },
910
- body: JSON.stringify({ refreshToken }),
911
- });
912
- if (response.ok) {
913
- const result = await response.json();
914
- if (result.success && result.accessToken) {
915
- debugLog('handleJWTCallback', 'Successfully refreshed token');
916
- // 새 액세스 토큰 검증 및 페이로드 추출
917
- if (secret) {
918
- const tokenResult = await verifyToken(result.accessToken, secret);
919
- if (tokenResult) {
920
- const newJWT = createNextAuthJWT(tokenResult.payload, serviceId || '');
921
- return {
922
- ...newJWT,
923
- refreshToken, // 기존 refresh token 유지
924
- accessTokenExpires: Date.now() + (15 * 60 * 1000), // 15분
925
- };
926
- }
927
- }
902
+ debugLog('handleJWTCallback', 'No valid custom token cookie found');
903
+ }
904
+ // 3. 토큰 유효성 체크
905
+ const now = Date.now();
906
+ const expires = token.accessTokenExpires;
907
+ const hasValidToken = token.id && expires && expires > now;
908
+ const refreshToken = token.refreshToken;
909
+ debugLog('handleJWTCallback', 'Token status:', {
910
+ hasId: !!token.id,
911
+ hasExpires: !!expires,
912
+ expiresIn: expires ? Math.round((expires - now) / 1000) + 's' : 'N/A',
913
+ hasValidToken,
914
+ hasRefreshToken: !!refreshToken,
915
+ });
916
+ // 3-1. nextauth token이 있고 만료되지 않았으면 그대로 사용
917
+ if (hasValidToken) {
918
+ debugLog('handleJWTCallback', 'Token is still valid, using existing token');
919
+ return token;
920
+ }
921
+ // 3-2. nextauth token이 없거나 만료됨 → refresh token으로 갱신 시도
922
+ // (refreshToken이 있고 SSO 설정이 있을 때만)
923
+ if (refreshToken && ssoBaseURL && authServiceKey && secret) {
924
+ debugLog('handleJWTCallback', 'Token invalid or expired, attempting SSO refresh');
925
+ try {
926
+ debugLog('handleJWTCallback', 'Calling SSO refresh endpoint:', `${ssoBaseURL}/api/sso/refresh`);
927
+ const response = await fetch(`${ssoBaseURL}/api/sso/refresh`, {
928
+ method: 'POST',
929
+ headers: {
930
+ 'Content-Type': 'application/json',
931
+ 'x-auth-service-key': authServiceKey,
932
+ },
933
+ body: JSON.stringify({ refreshToken }),
934
+ });
935
+ debugLog('handleJWTCallback', 'SSO refresh response status:', response.status);
936
+ if (response.ok) {
937
+ const result = await response.json();
938
+ if (result.success && result.accessToken) {
939
+ debugLog('handleJWTCallback', 'Successfully refreshed token from SSO');
940
+ // 새 액세스 토큰 검증 및 페이로드 추출
941
+ const tokenResult = await verifyToken(result.accessToken, secret);
942
+ if (tokenResult) {
943
+ const newJWT = createNextAuthJWT(tokenResult.payload, serviceId || '');
944
+ return {
945
+ ...newJWT,
946
+ refreshToken, // 기존 refresh token 유지
947
+ accessTokenExpires: Date.now() + (15 * 60 * 1000), // 15분
948
+ };
928
949
  }
929
950
  }
930
- debugLog('handleJWTCallback', 'Failed to refresh token, SSO response not ok');
931
- }
932
- catch (error) {
933
- console.error('[handleJWTCallback] Error refreshing token:', error);
934
951
  }
952
+ debugLog('handleJWTCallback', 'Failed to refresh token from SSO');
935
953
  }
936
- else {
937
- debugLog('handleJWTCallback', 'Missing refresh token or SSO config, cannot refresh');
938
- }
939
- // 갱신 실패 시 기존 토큰 반환 (만료되었지만)
940
- debugLog('handleJWTCallback', 'Returning existing token (possibly expired)');
941
- return token;
942
- }
943
- // 3. 토큰에 id가 없는 경우 - 커스텀 토큰 쿠키에서 정보 읽기
944
- debugLog('handleJWTCallback', 'Token has no id, checking custom token cookie');
945
- if (secret && licenseKey && serviceId) {
946
- const cookieNameToUse = cookieName || `${serviceId}_access_token`;
947
- const jwt = await getJWTFromCustomTokenCookie(cookieNameToUse, secret, serviceId, licenseKey);
948
- if (jwt) {
949
- debugLog('handleJWTCallback', 'Successfully created JWT from custom token cookie');
950
- return jwt;
954
+ catch (error) {
955
+ console.error('[handleJWTCallback] Error refreshing token:', error);
951
956
  }
952
- debugLog('handleJWTCallback', 'Failed to create JWT from custom token cookie');
953
957
  }
954
958
  else {
955
- debugLog('handleJWTCallback', 'Missing required parameters for custom token reading');
959
+ debugLog('handleJWTCallback', 'Cannot refresh - missing requirements:', {
960
+ hasRefreshToken: !!refreshToken,
961
+ hasSSO: !!ssoBaseURL,
962
+ hasAuthKey: !!authServiceKey,
963
+ hasSecret: !!secret,
964
+ });
965
+ }
966
+ // 4. refresh 실패 시 - 기존 토큰이 있으면 반환
967
+ if (token.id) {
968
+ debugLog('handleJWTCallback', 'Refresh failed, returning existing token (possibly expired)');
969
+ return token;
956
970
  }
957
- debugLog('handleJWTCallback', 'Returning original token');
971
+ // 5. 모든 시도 실패 - 빈 토큰 반환
972
+ debugLog('handleJWTCallback', 'All attempts failed, returning empty token');
958
973
  return token;
959
974
  }
960
975
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkingcat/auth-utils",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "Authentication utilities for ThinkingCat SSO services with conditional logging",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",