@thinkingcat/auth-utils 1.0.47 → 1.0.49

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 +51 -124
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -1,77 +1,4 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.verifyToken = verifyToken;
37
- exports.extractRoleFromPayload = extractRoleFromPayload;
38
- exports.createNextAuthJWT = createNextAuthJWT;
39
- exports.encodeNextAuthToken = encodeNextAuthToken;
40
- exports.setCustomTokens = setCustomTokens;
41
- exports.setNextAuthToken = setNextAuthToken;
42
- exports.createRedirectHTML = createRedirectHTML;
43
- exports.createAuthResponse = createAuthResponse;
44
- exports.validateServiceSubscription = validateServiceSubscription;
45
- exports.refreshSSOToken = refreshSSOToken;
46
- exports.getRefreshTokenFromSSO = getRefreshTokenFromSSO;
47
- exports.verifyAndRefreshToken = verifyAndRefreshToken;
48
- exports.redirectToError = redirectToError;
49
- exports.clearAuthCookies = clearAuthCookies;
50
- exports.getEffectiveRole = getEffectiveRole;
51
- exports.requiresSubscription = requiresSubscription;
52
- exports.createNextAuthCookies = createNextAuthCookies;
53
- exports.createNextAuthBaseConfig = createNextAuthBaseConfig;
54
- exports.createInitialJWTToken = createInitialJWTToken;
55
- exports.createEmptySession = createEmptySession;
56
- exports.mapTokenToSession = mapTokenToSession;
57
- exports.handleJWTCallback = handleJWTCallback;
58
- exports.getJWTFromCustomTokenCookie = getJWTFromCustomTokenCookie;
59
- exports.checkLicenseKey = checkLicenseKey;
60
- exports.checkRoleAccess = checkRoleAccess;
61
- exports.redirectToSSOLogin = redirectToSSOLogin;
62
- exports.redirectToRoleDashboard = redirectToRoleDashboard;
63
- exports.isTokenExpired = isTokenExpired;
64
- exports.isValidToken = isValidToken;
65
- exports.hasRole = hasRole;
66
- exports.hasAnyRole = hasAnyRole;
67
- exports.isPublicPath = isPublicPath;
68
- exports.isApiPath = isApiPath;
69
- exports.isProtectedApiPath = isProtectedApiPath;
70
- exports.checkAuthentication = checkAuthentication;
71
- exports.verifyAndRefreshTokenWithNextAuth = verifyAndRefreshTokenWithNextAuth;
72
- exports.createMiddlewareConfig = createMiddlewareConfig;
73
- exports.handleMiddleware = handleMiddleware;
74
- const jose_1 = require("jose");
1
+ import { jwtVerify, EncryptJWT } from 'jose';
75
2
  // ============================================================================
76
3
  // UTILITY FUNCTIONS
77
4
  // ============================================================================
@@ -102,7 +29,7 @@ async function createHashSHA256(data) {
102
29
  * Edge Runtime 호환을 위해 next/server를 동적 import
103
30
  */
104
31
  async function getNextServer() {
105
- return await Promise.resolve().then(() => __importStar(require('next/server')));
32
+ return await import('next/server');
106
33
  }
107
34
  /**
108
35
  * NextAuth 세션 토큰 쿠키를 삭제하는 헬퍼 함수
@@ -129,10 +56,10 @@ function clearAllAuthCookies(response, cookiePrefix, isProduction) {
129
56
  * @param secret JWT 서명에 사용할 secret key
130
57
  * @returns 검증된 payload 또는 null
131
58
  */
132
- async function verifyToken(accessToken, secret) {
59
+ export async function verifyToken(accessToken, secret) {
133
60
  try {
134
61
  const secretBytes = new TextEncoder().encode(secret);
135
- const { payload } = await (0, jose_1.jwtVerify)(accessToken, secretBytes);
62
+ const { payload } = await jwtVerify(accessToken, secretBytes);
136
63
  if (payload && typeof payload === 'object' && payload.email) {
137
64
  return { payload: payload };
138
65
  }
@@ -149,7 +76,7 @@ async function verifyToken(accessToken, secret) {
149
76
  * @param defaultRole 기본 역할 (기본값: 'ADMIN')
150
77
  * @returns 추출된 역할
151
78
  */
152
- function extractRoleFromPayload(payload, serviceId, defaultRole = 'ADMIN') {
79
+ export function extractRoleFromPayload(payload, serviceId, defaultRole = 'ADMIN') {
153
80
  const services = payload.services || [];
154
81
  const service = services.find((s) => s.serviceId === serviceId);
155
82
  return service?.role || payload.role || defaultRole;
@@ -160,7 +87,7 @@ function extractRoleFromPayload(payload, serviceId, defaultRole = 'ADMIN') {
160
87
  * @param serviceId 서비스 ID (필수)
161
88
  * @returns NextAuth JWT 객체
162
89
  */
163
- function createNextAuthJWT(payload, serviceId) {
90
+ export function createNextAuthJWT(payload, serviceId) {
164
91
  const services = payload.services || [];
165
92
  const service = services.find((s) => s.serviceId === serviceId);
166
93
  const effectiveRole = service?.role || payload.role || 'ADMIN';
@@ -216,10 +143,10 @@ function createNextAuthJWT(payload, serviceId) {
216
143
  * @param maxAge 토큰 유효 기간 (초, 기본값: 30일)
217
144
  * @returns 인코딩된 세션 토큰
218
145
  */
219
- async function encodeNextAuthToken(jwt, secret, maxAge = 30 * 24 * 60 * 60) {
146
+ export async function encodeNextAuthToken(jwt, secret, maxAge = 30 * 24 * 60 * 60) {
220
147
  // NextAuth의 encode() 함수를 우선적으로 사용 (가장 호환성 좋음)
221
148
  try {
222
- const { encode } = await Promise.resolve().then(() => __importStar(require('next-auth/jwt')));
149
+ const { encode } = await import('next-auth/jwt');
223
150
  debugLog('encodeNextAuthToken', 'Using next-auth/jwt encode');
224
151
  const encoded = await encode({
225
152
  token: jwt,
@@ -244,7 +171,7 @@ async function encodeNextAuthToken(jwt, secret, maxAge = 30 * 24 * 60 * 60) {
244
171
  // EncryptJWT를 사용하여 JWE 토큰 생성
245
172
  // NextAuth는 'dir' 키 관리와 'A256GCM' 암호화를 사용
246
173
  try {
247
- const token = await new jose_1.EncryptJWT(jwt)
174
+ const token = await new EncryptJWT(jwt)
248
175
  .setProtectedHeader({
249
176
  alg: 'dir', // Direct key agreement
250
177
  enc: 'A256GCM' // AES-256-GCM encryption
@@ -262,7 +189,7 @@ async function encodeNextAuthToken(jwt, secret, maxAge = 30 * 24 * 60 * 60) {
262
189
  }
263
190
  }
264
191
  }
265
- function setCustomTokens(response, accessToken, optionsOrRefreshToken, options) {
192
+ export function setCustomTokens(response, accessToken, optionsOrRefreshToken, options) {
266
193
  // 옵션 파라미터 처리: refreshToken과 options를 분리
267
194
  let refreshTokenValue;
268
195
  let cookiePrefix;
@@ -335,7 +262,7 @@ function setCustomTokens(response, accessToken, optionsOrRefreshToken, options)
335
262
  * @param options.isProduction 프로덕션 환경 여부 (기본값: false)
336
263
  * @param options.cookieDomain 쿠키 도메인 (선택)
337
264
  */
338
- function setNextAuthToken(response, sessionToken, options = {}) {
265
+ export function setNextAuthToken(response, sessionToken, options = {}) {
339
266
  const { isProduction = false, cookieDomain, } = options;
340
267
  // createNextAuthCookies와 동일한 로직 사용
341
268
  const cookies = createNextAuthCookies({ isProduction, cookieDomain });
@@ -353,7 +280,7 @@ function setNextAuthToken(response, sessionToken, options = {}) {
353
280
  * @param text 표시할 텍스트 (필수)
354
281
  * @returns HTML 문자열
355
282
  */
356
- function createRedirectHTML(redirectPath, text) {
283
+ export function createRedirectHTML(redirectPath, text) {
357
284
  return `
358
285
  <!DOCTYPE html>
359
286
  <html>
@@ -437,7 +364,7 @@ function createRedirectHTML(redirectPath, text) {
437
364
  * @param options.licenseKey 라이센스 키 (필수)
438
365
  * @returns NextResponse 객체 (리다이렉트 또는 JSON 응답)
439
366
  */
440
- async function createAuthResponse(accessToken, secret, options) {
367
+ export async function createAuthResponse(accessToken, secret, options) {
441
368
  await checkLicenseKey(options.licenseKey);
442
369
  const { req, refreshToken, redirectPath, text, cookiePrefix, isProduction = false, cookieDomain, serviceId, } = options;
443
370
  // 1. 토큰 검증
@@ -515,7 +442,7 @@ async function createAuthResponse(accessToken, secret, options) {
515
442
  * @param ssoBaseURL SSO 서버 기본 URL (필수)
516
443
  * @returns 구독 유효성 결과
517
444
  */
518
- function validateServiceSubscription(services, serviceId, ssoBaseURL) {
445
+ export function validateServiceSubscription(services, serviceId, ssoBaseURL) {
519
446
  const filteredServices = services.filter(service => service.serviceId === serviceId);
520
447
  if (filteredServices.length === 0) {
521
448
  return {
@@ -544,7 +471,7 @@ function validateServiceSubscription(services, serviceId, ssoBaseURL) {
544
471
  * @param options.authServiceKey 인증 서비스 키 (기본값: 환경 변수)
545
472
  * @returns SSO refresh token 응답
546
473
  */
547
- async function refreshSSOToken(refreshToken, options) {
474
+ export async function refreshSSOToken(refreshToken, options) {
548
475
  const { ssoBaseURL, authServiceKey } = options;
549
476
  if (!authServiceKey) {
550
477
  throw new Error('AUTH_SERVICE_SECRET_KEY not configured');
@@ -568,7 +495,7 @@ async function refreshSSOToken(refreshToken, options) {
568
495
  * @param options.authServiceKey 인증 서비스 키 (기본값: 환경 변수)
569
496
  * @returns refresh token 또는 null
570
497
  */
571
- async function getRefreshTokenFromSSO(userId, accessToken, options) {
498
+ export async function getRefreshTokenFromSSO(userId, accessToken, options) {
572
499
  const { ssoBaseURL, authServiceKey } = options;
573
500
  if (!authServiceKey) {
574
501
  return null;
@@ -598,7 +525,7 @@ async function getRefreshTokenFromSSO(userId, accessToken, options) {
598
525
  // ============================================================================
599
526
  // TOKEN REFRESH & VERIFICATION FUNCTIONS
600
527
  // ============================================================================
601
- async function verifyAndRefreshToken(req, secret, options) {
528
+ export async function verifyAndRefreshToken(req, secret, options) {
602
529
  const { cookiePrefix, serviceId, isProduction, cookieDomain, text, ssoBaseURL, authServiceKey, forceRefresh = false, } = options;
603
530
  // 1. access_token 쿠키 확인
604
531
  // forceRefresh가 true이면 access token이 있어도 refresh를 시도
@@ -607,7 +534,7 @@ async function verifyAndRefreshToken(req, secret, options) {
607
534
  if (accessToken && !forceRefresh) {
608
535
  try {
609
536
  const secretBytes = new TextEncoder().encode(secret);
610
- const { payload } = await (0, jose_1.jwtVerify)(accessToken, secretBytes);
537
+ const { payload } = await jwtVerify(accessToken, secretBytes);
611
538
  if (payload && typeof payload === 'object' && payload.email) {
612
539
  return { isValid: true, payload: payload };
613
540
  }
@@ -644,7 +571,7 @@ async function verifyAndRefreshToken(req, secret, options) {
644
571
  let payload;
645
572
  try {
646
573
  const secretBytes = new TextEncoder().encode(secret);
647
- const { payload: tokenPayload } = await (0, jose_1.jwtVerify)(refreshResult.accessToken, secretBytes);
574
+ const { payload: tokenPayload } = await jwtVerify(refreshResult.accessToken, secretBytes);
648
575
  if (tokenPayload && typeof tokenPayload === 'object' && tokenPayload.email) {
649
576
  payload = tokenPayload;
650
577
  }
@@ -732,7 +659,7 @@ async function verifyAndRefreshToken(req, secret, options) {
732
659
  * @param errorPath 에러 페이지 경로 (기본값: '/error')
733
660
  * @returns NextResponse 리다이렉트 응답
734
661
  */
735
- async function redirectToError(req, code, message, errorPath = '/error') {
662
+ export async function redirectToError(req, code, message, errorPath = '/error') {
736
663
  const url = new URL(errorPath, req.url);
737
664
  url.searchParams.set('code', code);
738
665
  url.searchParams.set('message', message);
@@ -745,7 +672,7 @@ async function redirectToError(req, code, message, errorPath = '/error') {
745
672
  * @param cookiePrefix 쿠키 이름 접두사 (필수)
746
673
  * @returns NextResponse 객체
747
674
  */
748
- function clearAuthCookies(response, cookiePrefix) {
675
+ export function clearAuthCookies(response, cookiePrefix) {
749
676
  response.cookies.delete(`${cookiePrefix}_access_token`);
750
677
  response.cookies.delete(`${cookiePrefix}_refresh_token`);
751
678
  return response;
@@ -756,7 +683,7 @@ function clearAuthCookies(response, cookiePrefix) {
756
683
  * @param serviceId 서비스 ID (필수)
757
684
  * @returns 추출된 역할 또는 undefined
758
685
  */
759
- function getEffectiveRole(token, serviceId) {
686
+ export function getEffectiveRole(token, serviceId) {
760
687
  if (!token)
761
688
  return undefined;
762
689
  // token이 이미 JWT 객체인 경우 role을 직접 사용
@@ -776,7 +703,7 @@ function getEffectiveRole(token, serviceId) {
776
703
  * @param systemAdminRole 시스템 관리자 역할 (기본값: 'SYSTEM_ADMIN')
777
704
  * @returns 구독이 필요한지 여부
778
705
  */
779
- function requiresSubscription(pathname, role, subscriptionRequiredPaths, systemAdminRole = 'SYSTEM_ADMIN') {
706
+ export function requiresSubscription(pathname, role, subscriptionRequiredPaths, systemAdminRole = 'SYSTEM_ADMIN') {
780
707
  // 시스템 관리자는 구독 확인 제외
781
708
  if (role === systemAdminRole) {
782
709
  return false;
@@ -798,7 +725,7 @@ const VALID_LICENSE_KEY_HASHES = new Set([
798
725
  * @param options.cookieDomain 쿠키 도메인 (선택)
799
726
  * @returns NextAuth 쿠키 설정 객체
800
727
  */
801
- function createNextAuthCookies(options) {
728
+ export function createNextAuthCookies(options) {
802
729
  const { isProduction = false, cookieDomain } = options;
803
730
  const isSecure = isProduction;
804
731
  // cookieDomain이 설정되어 있으면 같은 도메인/서브도메인 간 쿠키 공유를 위해 'lax' 사용
@@ -850,7 +777,7 @@ function createNextAuthCookies(options) {
850
777
  * @param options.jwtMaxAge JWT 최대 유지 시간 (초, 기본값: 30일)
851
778
  * @returns NextAuth 기본 설정 객체
852
779
  */
853
- function createNextAuthBaseConfig(options) {
780
+ export function createNextAuthBaseConfig(options) {
854
781
  const { secret, isProduction = false, cookieDomain, signInPath = '/login', errorPath = '/login', nextAuthUrl, sessionMaxAge = 30 * 24 * 60 * 60, // 30일
855
782
  jwtMaxAge = 30 * 24 * 60 * 60, // 30일
856
783
  } = options;
@@ -879,7 +806,7 @@ function createNextAuthBaseConfig(options) {
879
806
  * @param account 계정 정보
880
807
  * @returns 업데이트된 JWT 토큰
881
808
  */
882
- function createInitialJWTToken(token, user, account) {
809
+ export function createInitialJWTToken(token, user, account) {
883
810
  return {
884
811
  ...token,
885
812
  id: user.id,
@@ -902,7 +829,7 @@ function createInitialJWTToken(token, user, account) {
902
829
  * @param session 기존 세션
903
830
  * @returns 빈 세션 객체
904
831
  */
905
- function createEmptySession(session) {
832
+ export function createEmptySession(session) {
906
833
  return {
907
834
  ...session,
908
835
  user: {
@@ -920,7 +847,7 @@ function createEmptySession(session) {
920
847
  * @param token JWT 토큰
921
848
  * @returns 업데이트된 세션
922
849
  */
923
- function mapTokenToSession(session, token) {
850
+ export function mapTokenToSession(session, token) {
924
851
  if (!session.user) {
925
852
  return session;
926
853
  }
@@ -952,7 +879,7 @@ function mapTokenToSession(session, token) {
952
879
  * @param options.debug 디버깅 로그 출력 여부 (기본값: false)
953
880
  * @returns 업데이트된 JWT 토큰
954
881
  */
955
- async function handleJWTCallback(token, user, account, options) {
882
+ export async function handleJWTCallback(token, user, account, options) {
956
883
  const { secret, licenseKey, serviceId, cookieName, debug = false, ssoBaseURL, authServiceKey, } = options || {};
957
884
  // 디버깅 로그
958
885
  if (debug) {
@@ -1063,10 +990,10 @@ async function handleJWTCallback(token, user, account, options) {
1063
990
  * @param licenseKey 라이센스 키 (필수)
1064
991
  * @returns NextAuth JWT 객체 또는 null
1065
992
  */
1066
- async function getJWTFromCustomTokenCookie(cookieName, secret, serviceId, licenseKey) {
993
+ export async function getJWTFromCustomTokenCookie(cookieName, secret, serviceId, licenseKey) {
1067
994
  debugLog('getJWTFromCustomTokenCookie', `Reading cookie: ${cookieName}`);
1068
995
  try {
1069
- const { cookies } = await Promise.resolve().then(() => __importStar(require('next/headers')));
996
+ const { cookies } = await import('next/headers');
1070
997
  const cookieStore = await cookies();
1071
998
  const accessToken = cookieStore.get(cookieName)?.value;
1072
999
  if (!accessToken) {
@@ -1103,7 +1030,7 @@ async function getJWTFromCustomTokenCookie(cookieName, secret, serviceId, licens
1103
1030
  // ============================================================================
1104
1031
  // LICENSE & AUTHORIZATION FUNCTIONS
1105
1032
  // ============================================================================
1106
- async function checkLicenseKey(licenseKey) {
1033
+ export async function checkLicenseKey(licenseKey) {
1107
1034
  if (!licenseKey || licenseKey.length < 10) {
1108
1035
  throw new Error('License key is required');
1109
1036
  }
@@ -1112,7 +1039,7 @@ async function checkLicenseKey(licenseKey) {
1112
1039
  throw new Error('Invalid license key');
1113
1040
  }
1114
1041
  }
1115
- function checkRoleAccess(pathname, role, roleConfig) {
1042
+ export function checkRoleAccess(pathname, role, roleConfig) {
1116
1043
  // 각 역할 설정을 확인
1117
1044
  for (const [configRole, config] of Object.entries(roleConfig)) {
1118
1045
  const isPathMatch = config.paths.some(path => pathname.startsWith(path));
@@ -1138,7 +1065,7 @@ function checkRoleAccess(pathname, role, roleConfig) {
1138
1065
  * @param ssoBaseURL SSO 서버 기본 URL (필수)
1139
1066
  * @returns NextResponse 리다이렉트 응답
1140
1067
  */
1141
- async function redirectToSSOLogin(req, serviceId, ssoBaseURL) {
1068
+ export async function redirectToSSOLogin(req, serviceId, ssoBaseURL) {
1142
1069
  const { NextResponse: NextResponseClass } = await getNextServer();
1143
1070
  return NextResponseClass.redirect(new URL(`${ssoBaseURL}/auth/login?serviceId=${serviceId}`, req.url));
1144
1071
  }
@@ -1150,7 +1077,7 @@ async function redirectToSSOLogin(req, serviceId, ssoBaseURL) {
1150
1077
  * @param defaultPath 기본 경로 (기본값: '/admin')
1151
1078
  * @returns NextResponse 리다이렉트 응답
1152
1079
  */
1153
- async function redirectToRoleDashboard(req, role, rolePaths, defaultPath = '/admin') {
1080
+ export async function redirectToRoleDashboard(req, role, rolePaths, defaultPath = '/admin') {
1154
1081
  const redirectPath = rolePaths[role] || defaultPath;
1155
1082
  const { NextResponse: NextResponseClass } = await getNextServer();
1156
1083
  return NextResponseClass.redirect(new URL(redirectPath, req.url));
@@ -1163,7 +1090,7 @@ async function redirectToRoleDashboard(req, role, rolePaths, defaultPath = '/adm
1163
1090
  * @param token NextAuth JWT 객체
1164
1091
  * @returns 만료 여부
1165
1092
  */
1166
- function isTokenExpired(token) {
1093
+ export function isTokenExpired(token) {
1167
1094
  if (!token)
1168
1095
  return true;
1169
1096
  if (token.exp && typeof token.exp === 'number' && token.exp < Math.floor(Date.now() / 1000)) {
@@ -1176,7 +1103,7 @@ function isTokenExpired(token) {
1176
1103
  * @param token NextAuth JWT 객체
1177
1104
  * @returns 유효성 여부
1178
1105
  */
1179
- function isValidToken(token) {
1106
+ export function isValidToken(token) {
1180
1107
  if (!token)
1181
1108
  return false;
1182
1109
  if (isTokenExpired(token))
@@ -1192,7 +1119,7 @@ function isValidToken(token) {
1192
1119
  * @param serviceId 서비스 ID (필수)
1193
1120
  * @returns 역할 보유 여부
1194
1121
  */
1195
- function hasRole(token, role, serviceId) {
1122
+ export function hasRole(token, role, serviceId) {
1196
1123
  if (!token)
1197
1124
  return false;
1198
1125
  const effectiveRole = getEffectiveRole(token, serviceId);
@@ -1205,7 +1132,7 @@ function hasRole(token, role, serviceId) {
1205
1132
  * @param serviceId 서비스 ID (필수)
1206
1133
  * @returns 역할 보유 여부
1207
1134
  */
1208
- function hasAnyRole(token, roles, serviceId) {
1135
+ export function hasAnyRole(token, roles, serviceId) {
1209
1136
  if (!token)
1210
1137
  return false;
1211
1138
  const effectiveRole = getEffectiveRole(token, serviceId);
@@ -1220,7 +1147,7 @@ function hasAnyRole(token, roles, serviceId) {
1220
1147
  * @param publicPaths 공개 경로 배열
1221
1148
  * @returns 공개 경로 여부
1222
1149
  */
1223
- function isPublicPath(pathname, publicPaths) {
1150
+ export function isPublicPath(pathname, publicPaths) {
1224
1151
  return publicPaths.some(path => pathname === path || pathname.startsWith(path));
1225
1152
  }
1226
1153
  /**
@@ -1228,7 +1155,7 @@ function isPublicPath(pathname, publicPaths) {
1228
1155
  * @param pathname 경로명
1229
1156
  * @returns API 경로 여부
1230
1157
  */
1231
- function isApiPath(pathname) {
1158
+ export function isApiPath(pathname) {
1232
1159
  return pathname.startsWith('/api/');
1233
1160
  }
1234
1161
  /**
@@ -1237,7 +1164,7 @@ function isApiPath(pathname) {
1237
1164
  * @param exemptPaths 제외할 경로 배열
1238
1165
  * @returns 보호된 API 경로 여부
1239
1166
  */
1240
- function isProtectedApiPath(pathname, exemptPaths = []) {
1167
+ export function isProtectedApiPath(pathname, exemptPaths = []) {
1241
1168
  if (!isApiPath(pathname))
1242
1169
  return false;
1243
1170
  return !exemptPaths.some(path => pathname.startsWith(path));
@@ -1252,7 +1179,7 @@ function isProtectedApiPath(pathname, exemptPaths = []) {
1252
1179
  * @param options 옵션
1253
1180
  * @returns 인증 결과
1254
1181
  */
1255
- async function checkAuthentication(req, secret, options) {
1182
+ export async function checkAuthentication(req, secret, options) {
1256
1183
  const { cookiePrefix, serviceId, getNextAuthToken, } = options;
1257
1184
  let nextAuthToken = null;
1258
1185
  if (getNextAuthToken) {
@@ -1292,7 +1219,7 @@ async function checkAuthentication(req, secret, options) {
1292
1219
  * @param options 옵션
1293
1220
  * @returns 인증 결과
1294
1221
  */
1295
- async function verifyAndRefreshTokenWithNextAuth(req, nextAuthToken, secret, options) {
1222
+ export async function verifyAndRefreshTokenWithNextAuth(req, nextAuthToken, secret, options) {
1296
1223
  const { cookiePrefix, isProduction } = options;
1297
1224
  // NextAuth 세션 토큰 쿠키 확인
1298
1225
  const nextAuthSessionTokenCookieName = isProduction
@@ -1315,7 +1242,7 @@ async function verifyAndRefreshTokenWithNextAuth(req, nextAuthToken, secret, opt
1315
1242
  if (accessToken) {
1316
1243
  try {
1317
1244
  const secretBytes = new TextEncoder().encode(secret);
1318
- const { payload } = await (0, jose_1.jwtVerify)(accessToken, secretBytes);
1245
+ const { payload } = await jwtVerify(accessToken, secretBytes);
1319
1246
  if (payload && typeof payload === 'object' && payload.email) {
1320
1247
  hasValidAccessToken = true;
1321
1248
  }
@@ -1341,7 +1268,7 @@ async function verifyAndRefreshTokenWithNextAuth(req, nextAuthToken, secret, opt
1341
1268
  if (accessToken) {
1342
1269
  try {
1343
1270
  const secretBytes = new TextEncoder().encode(secret);
1344
- const result = await (0, jose_1.jwtVerify)(accessToken, secretBytes);
1271
+ const result = await jwtVerify(accessToken, secretBytes);
1345
1272
  payload = result.payload;
1346
1273
  }
1347
1274
  catch {
@@ -1380,7 +1307,7 @@ async function verifyAndRefreshTokenWithNextAuth(req, nextAuthToken, secret, opt
1380
1307
  if (accessToken && hasValidAccessToken) {
1381
1308
  try {
1382
1309
  const secretBytes = new TextEncoder().encode(secret);
1383
- const result = await (0, jose_1.jwtVerify)(accessToken, secretBytes);
1310
+ const result = await jwtVerify(accessToken, secretBytes);
1384
1311
  payload = result.payload;
1385
1312
  }
1386
1313
  catch {
@@ -1405,7 +1332,7 @@ async function verifyAndRefreshTokenWithNextAuth(req, nextAuthToken, secret, opt
1405
1332
  * @param defaults 기본 설정값 (선택사항, 제공하지 않으면 최소 기본값 사용)
1406
1333
  * @returns 미들웨어 설정 객체
1407
1334
  */
1408
- function createMiddlewareConfig(config, defaults) {
1335
+ export function createMiddlewareConfig(config, defaults) {
1409
1336
  // 기본값 설정
1410
1337
  const defaultPublicPaths = defaults?.publicPaths || [
1411
1338
  '/robots.txt',
@@ -1471,7 +1398,7 @@ function createMiddlewareConfig(config, defaults) {
1471
1398
  * @param options 미들웨어 실행 옵션 (secret 필수)
1472
1399
  * @returns NextResponse 또는 null (다음 미들웨어로 진행)
1473
1400
  */
1474
- async function handleMiddleware(req, config, options) {
1401
+ export async function handleMiddleware(req, config, options) {
1475
1402
  // Edge Runtime 호환을 위해 next/server를 한 번만 import
1476
1403
  const { NextResponse: NextResponseClass } = await getNextServer();
1477
1404
  try {
@@ -1491,7 +1418,7 @@ async function handleMiddleware(req, config, options) {
1491
1418
  }
1492
1419
  else {
1493
1420
  try {
1494
- const { getToken } = await Promise.resolve().then(() => __importStar(require('next-auth/jwt')));
1421
+ const { getToken } = await import('next-auth/jwt');
1495
1422
  token = await getToken({ req, secret });
1496
1423
  debugLog('handleMiddleware', 'getToken result:', { hasToken: !!token });
1497
1424
  }
@@ -1664,7 +1591,7 @@ async function handleMiddleware(req, config, options) {
1664
1591
  }
1665
1592
  else {
1666
1593
  try {
1667
- const { getToken } = await Promise.resolve().then(() => __importStar(require('next-auth/jwt')));
1594
+ const { getToken } = await import('next-auth/jwt');
1668
1595
  finalToken = await getToken({ req, secret });
1669
1596
  }
1670
1597
  catch {
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@thinkingcat/auth-utils",
3
- "version": "1.0.47",
3
+ "version": "1.0.49",
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",
7
7
  "exports": {
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
+ "edge-light": "./dist/index.js",
10
11
  "default": "./dist/index.js"
11
12
  }
12
13
  },