@thinkingcat/auth-utils 1.0.4

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.
@@ -0,0 +1,384 @@
1
+ import { JWT } from "next-auth/jwt";
2
+ import { NextResponse, NextRequest } from 'next/server';
3
+ export interface ResponseLike {
4
+ cookies: {
5
+ delete(name: string): void;
6
+ set(name: string, value: string, options?: {
7
+ httpOnly?: boolean;
8
+ secure?: boolean;
9
+ sameSite?: 'strict' | 'lax' | 'none';
10
+ maxAge?: number;
11
+ path?: string;
12
+ domain?: string;
13
+ }): void;
14
+ };
15
+ }
16
+ export interface ServiceInfo {
17
+ serviceId: string;
18
+ role: string;
19
+ joinedAt: string;
20
+ lastAccessAt?: string;
21
+ expiredAt?: string;
22
+ status: string;
23
+ }
24
+ export interface SSOUpsertResponse {
25
+ success: boolean;
26
+ message?: string;
27
+ user?: {
28
+ id: string;
29
+ email: string;
30
+ name: string;
31
+ };
32
+ }
33
+ export interface SSOErrorResponse {
34
+ error: string;
35
+ message?: string;
36
+ }
37
+ export interface SSORefreshTokenResponse {
38
+ success: boolean;
39
+ accessToken?: string;
40
+ refreshToken?: string;
41
+ user?: {
42
+ id: string;
43
+ email: string;
44
+ name: string;
45
+ };
46
+ error?: string;
47
+ }
48
+ export interface SSOGetRefreshTokenResponse {
49
+ success: boolean;
50
+ refreshToken?: string;
51
+ error?: string;
52
+ }
53
+ export interface SSORegisterResponse {
54
+ success: boolean;
55
+ message?: string;
56
+ user?: {
57
+ id: string;
58
+ email: string;
59
+ name: string;
60
+ };
61
+ }
62
+ export interface JWTPayload {
63
+ sub?: string;
64
+ id?: string;
65
+ email: string;
66
+ name: string;
67
+ role?: string;
68
+ iat?: number;
69
+ exp?: number;
70
+ services?: ServiceInfo[];
71
+ academies?: Array<{
72
+ id: string;
73
+ name: string;
74
+ role: string;
75
+ }>;
76
+ phoneVerified?: boolean;
77
+ emailVerified?: boolean;
78
+ smsVerified?: boolean;
79
+ phone?: string;
80
+ academyId?: string;
81
+ academyName?: string;
82
+ isPasswordReset?: boolean;
83
+ decryptedEmail?: string;
84
+ decryptedPhone?: string;
85
+ emailHash?: string;
86
+ maskedEmail?: string;
87
+ phoneHash?: string;
88
+ maskedPhone?: string;
89
+ refreshToken?: string;
90
+ accessToken?: string;
91
+ accessTokenExpires?: number;
92
+ serviceId?: string;
93
+ [key: string]: unknown;
94
+ }
95
+ /**
96
+ * 토큰 검증 및 디코딩
97
+ * @param accessToken JWT access token
98
+ * @param secret JWT 서명에 사용할 secret key
99
+ * @returns 검증된 payload 또는 null
100
+ */
101
+ export declare function verifyToken(accessToken: string, secret: string): Promise<{
102
+ payload: JWTPayload;
103
+ } | null>;
104
+ /**
105
+ * payload에서 역할 추출 (서비스별)
106
+ * @param payload JWT payload
107
+ * @param serviceId 서비스 ID (기본값: 'checkon')
108
+ * @param defaultRole 기본 역할 (기본값: 'ADMIN')
109
+ * @returns 추출된 역할
110
+ */
111
+ export declare function extractRoleFromPayload(payload: JWTPayload, serviceId?: string, defaultRole?: string): string;
112
+ /**
113
+ * payload에서 NextAuth JWT 객체 생성
114
+ * @param payload JWT payload
115
+ * @param includeAcademies academies 정보 포함 여부
116
+ * @returns NextAuth JWT 객체
117
+ */
118
+ export declare function createNextAuthJWT(payload: JWTPayload, includeAcademies?: boolean): JWT;
119
+ /**
120
+ * NextAuth JWT를 인코딩된 세션 토큰으로 변환
121
+ * @param jwt NextAuth JWT 객체
122
+ * @param secret JWT 서명에 사용할 secret key
123
+ * @param maxAge 토큰 유효 기간 (초, 기본값: 30일)
124
+ * @returns 인코딩된 세션 토큰
125
+ */
126
+ export declare function encodeNextAuthToken(jwt: JWT, secret: string, maxAge?: number): Promise<string>;
127
+ /**
128
+ * 자체 토큰만 설정 (access token, refresh token)
129
+ * @param response NextResponse 객체
130
+ * @param accessToken access token
131
+ * @param refreshToken refresh token (선택)
132
+ * @param options 쿠키 설정 옵션
133
+ * @param options.cookiePrefix 쿠키 이름 접두사 (기본값: 'checkon')
134
+ * @param options.isProduction 프로덕션 환경 여부 (기본값: false)
135
+ */
136
+ export declare function setCustomTokens(response: ResponseLike, accessToken: string, refreshToken: string, options?: {
137
+ cookiePrefix?: string;
138
+ isProduction?: boolean;
139
+ }): void;
140
+ export declare function setCustomTokens(response: ResponseLike, accessToken: string, options?: {
141
+ refreshToken?: string;
142
+ cookiePrefix?: string;
143
+ isProduction?: boolean;
144
+ }): void;
145
+ /**
146
+ * NextAuth 세션 토큰만 설정
147
+ * @param response NextResponse 객체
148
+ * @param sessionToken NextAuth session token
149
+ * @param options 쿠키 설정 옵션
150
+ * @param options.isProduction 프로덕션 환경 여부 (기본값: false)
151
+ * @param options.cookieDomain 쿠키 도메인 (선택)
152
+ */
153
+ export declare function setNextAuthToken(response: ResponseLike, sessionToken: string, options?: {
154
+ isProduction?: boolean;
155
+ cookieDomain?: string;
156
+ }): void;
157
+ /**
158
+ * 리다이렉트용 HTML 생성
159
+ * @param redirectPath 리다이렉트할 경로
160
+ * @param text 표시할 텍스트 (기본값: 'checkon')
161
+ * @returns HTML 문자열
162
+ */
163
+ export declare function createRedirectHTML(redirectPath: string, text?: string): string;
164
+ /**
165
+ * access token과 refresh token을 사용하여 완전한 인증 세션 생성
166
+ * @param accessToken access token
167
+ * @param secret JWT 서명에 사용할 secret key
168
+ * @param options 추가 옵션
169
+ * @param options.refreshToken refresh token (선택)
170
+ * @param options.redirectPath 리다이렉트할 경로 (기본값: 페이지 리로드)
171
+ * @param options.text 리다이렉트 HTML에 표시할 텍스트 (기본값: 'checkon')
172
+ * @param options.cookiePrefix 쿠키 이름 접두사 (기본값: 'checkon')
173
+ * @param options.isProduction 프로덕션 환경 여부 (기본값: false)
174
+ * @param options.cookieDomain 쿠키 도메인 (선택)
175
+ * @returns NextResponse 객체
176
+ */
177
+ export declare function createAuthResponse(accessToken: string, secret: string, options?: {
178
+ refreshToken?: string;
179
+ redirectPath?: string;
180
+ text?: string;
181
+ cookiePrefix?: string;
182
+ isProduction?: boolean;
183
+ cookieDomain?: string;
184
+ }): Promise<NextResponse>;
185
+ /**
186
+ * 서비스 구독 유효성 확인 함수
187
+ * @param services 서비스 정보 배열
188
+ * @param serviceId 확인할 서비스 ID
189
+ * @returns 구독 유효성 결과
190
+ */
191
+ export declare function validateServiceSubscription(services: ServiceInfo[], serviceId: string): {
192
+ isValid: boolean;
193
+ redirectUrl?: string;
194
+ service?: ServiceInfo;
195
+ };
196
+ /**
197
+ * SSO 서버에서 refresh token을 사용하여 새로운 access token을 발급받는 함수
198
+ * @param refreshToken refresh token
199
+ * @param options 옵션
200
+ * @param options.ssoBaseURL SSO 서버 기본 URL (기본값: 환경 변수 또는 기본값)
201
+ * @param options.authServiceKey 인증 서비스 키 (기본값: 환경 변수)
202
+ * @returns SSO refresh token 응답
203
+ */
204
+ export declare function refreshSSOToken(refreshToken: string, options?: {
205
+ ssoBaseURL?: string;
206
+ authServiceKey?: string;
207
+ }): Promise<SSORefreshTokenResponse>;
208
+ /**
209
+ * SSO 서버에서 사용자의 refresh token을 가져오는 함수
210
+ * @param userId 사용자 ID
211
+ * @param accessToken access token
212
+ * @param options 옵션
213
+ * @param options.ssoBaseURL SSO 서버 기본 URL (기본값: 환경 변수 또는 기본값)
214
+ * @param options.authServiceKey 인증 서비스 키 (기본값: 환경 변수)
215
+ * @returns refresh token 또는 null
216
+ */
217
+ export declare function getRefreshTokenFromSSO(userId: string, accessToken: string, options?: {
218
+ ssoBaseURL?: string;
219
+ authServiceKey?: string;
220
+ }): Promise<string | null>;
221
+ /**
222
+ * 토큰 검증 및 리프레시 처리 공통 함수
223
+ *
224
+ * @param req - NextRequest 객체
225
+ * @param secret - JWT 서명에 사용할 secret key
226
+ * @param options - 옵션
227
+ * @param options.cookiePrefix - 쿠키 이름 접두사 (기본값: 'checkon')
228
+ * @param options.isProduction - 프로덕션 환경 여부 (기본값: false)
229
+ * @param options.cookieDomain - 쿠키 도메인 (선택)
230
+ * @param options.text - 리다이렉트 HTML에 표시할 텍스트 (기본값: 'checkon')
231
+ * @param options.ssoBaseURL - SSO 서버 기본 URL (기본값: 환경 변수 또는 기본값)
232
+ * @param options.authServiceKey - 인증 서비스 키 (기본값: 환경 변수)
233
+ * @returns 검증 결과 및 필요시 리프레시된 응답
234
+ */
235
+ export declare function verifyAndRefreshToken(req: NextRequest, secret: string, options?: {
236
+ cookiePrefix?: string;
237
+ isProduction?: boolean;
238
+ cookieDomain?: string;
239
+ text?: string;
240
+ ssoBaseURL?: string;
241
+ authServiceKey?: string;
242
+ }): Promise<{
243
+ isValid: boolean;
244
+ response?: NextResponse;
245
+ payload?: JWTPayload;
246
+ error?: string;
247
+ }>;
248
+ /**
249
+ * 에러 페이지로 리다이렉트하는 헬퍼 함수
250
+ * @param req NextRequest 객체
251
+ * @param code 에러 코드
252
+ * @param message 에러 메시지
253
+ * @param errorPath 에러 페이지 경로 (기본값: '/error')
254
+ * @returns NextResponse 리다이렉트 응답
255
+ */
256
+ export declare function redirectToError(req: NextRequest, code: string, message: string, errorPath?: string): NextResponse;
257
+ /**
258
+ * 인증 쿠키를 삭제하는 헬퍼 함수
259
+ * @param response NextResponse 객체
260
+ * @param cookiePrefix 쿠키 이름 접두사 (기본값: 'checkon')
261
+ * @returns NextResponse 객체
262
+ */
263
+ export declare function clearAuthCookies(response: NextResponse, cookiePrefix?: string): NextResponse;
264
+ /**
265
+ * JWT에서 서비스별 역할을 추출하는 헬퍼 함수
266
+ * @param token NextAuth JWT 객체 또는 null
267
+ * @param serviceId 서비스 ID (기본값: 'checkon')
268
+ * @returns 추출된 역할 또는 undefined
269
+ */
270
+ export declare function getEffectiveRole(token: JWT | null, serviceId?: string): string | undefined;
271
+ /**
272
+ * 구독이 필요한 경로인지 확인하는 헬퍼 함수
273
+ * @param pathname 경로명
274
+ * @param role 사용자 역할
275
+ * @param subscriptionRequiredPaths 구독이 필요한 경로 배열
276
+ * @param systemAdminRole 시스템 관리자 역할 (기본값: 'SYSTEM_ADMIN')
277
+ * @returns 구독이 필요한지 여부
278
+ */
279
+ export declare function requiresSubscription(pathname: string, role: string, subscriptionRequiredPaths: string[], systemAdminRole?: string): boolean;
280
+ /**
281
+ * 역할 기반 접근 제어 헬퍼 함수
282
+ * @param pathname 경로명
283
+ * @param role 사용자 역할
284
+ * @param roleConfig 역할별 경로 설정 객체
285
+ * @returns 접근 허용 여부 및 메시지
286
+ */
287
+ export interface RoleAccessConfig {
288
+ [role: string]: {
289
+ paths: string[];
290
+ message: string;
291
+ allowedRoles?: string[];
292
+ };
293
+ }
294
+ export declare function checkRoleAccess(pathname: string, role: string, roleConfig: RoleAccessConfig): {
295
+ allowed: boolean;
296
+ message?: string;
297
+ };
298
+ /**
299
+ * SSO 로그인 페이지로 리다이렉트하는 헬퍼 함수
300
+ * @param req NextRequest 객체
301
+ * @param serviceId 서비스 ID
302
+ * @param ssoBaseURL SSO 서버 기본 URL (기본값: 환경 변수 또는 기본값)
303
+ * @returns NextResponse 리다이렉트 응답
304
+ */
305
+ export declare function redirectToSSOLogin(req: NextRequest, serviceId: string, ssoBaseURL?: string): NextResponse;
306
+ /**
307
+ * 역할별 대시보드 경로로 리다이렉트하는 헬퍼 함수
308
+ * @param req NextRequest 객체
309
+ * @param role 사용자 역할
310
+ * @param rolePaths 역할별 경로 설정 객체
311
+ * @param defaultPath 기본 경로 (기본값: '/admin')
312
+ * @returns NextResponse 리다이렉트 응답
313
+ */
314
+ export declare function redirectToRoleDashboard(req: NextRequest, role: string, rolePaths: Record<string, string>, defaultPath?: string): NextResponse;
315
+ /**
316
+ * 토큰이 만료되었는지 확인하는 함수
317
+ * @param token NextAuth JWT 객체
318
+ * @returns 만료 여부
319
+ */
320
+ export declare function isTokenExpired(token: JWT | null): boolean;
321
+ /**
322
+ * 토큰이 유효한지 확인하는 함수 (만료 및 필수 필드 체크)
323
+ * @param token NextAuth JWT 객체
324
+ * @returns 유효성 여부
325
+ */
326
+ export declare function isValidToken(token: JWT | null): boolean;
327
+ /**
328
+ * 특정 역할을 가지고 있는지 확인하는 함수
329
+ * @param token NextAuth JWT 객체
330
+ * @param role 확인할 역할
331
+ * @param serviceId 서비스 ID (기본값: 'checkon')
332
+ * @returns 역할 보유 여부
333
+ */
334
+ export declare function hasRole(token: JWT | null, role: string, serviceId?: string): boolean;
335
+ /**
336
+ * 여러 역할 중 하나라도 가지고 있는지 확인하는 함수
337
+ * @param token NextAuth JWT 객체
338
+ * @param roles 확인할 역할 배열
339
+ * @param serviceId 서비스 ID (기본값: 'checkon')
340
+ * @returns 역할 보유 여부
341
+ */
342
+ export declare function hasAnyRole(token: JWT | null, roles: string[], serviceId?: string): boolean;
343
+ /**
344
+ * 공개 경로인지 확인하는 함수
345
+ * @param pathname 경로명
346
+ * @param publicPaths 공개 경로 배열
347
+ * @returns 공개 경로 여부
348
+ */
349
+ export declare function isPublicPath(pathname: string, publicPaths: string[]): boolean;
350
+ /**
351
+ * API 경로인지 확인하는 함수
352
+ * @param pathname 경로명
353
+ * @returns API 경로 여부
354
+ */
355
+ export declare function isApiPath(pathname: string): boolean;
356
+ /**
357
+ * 보호된 API 경로인지 확인하는 함수
358
+ * @param pathname 경로명
359
+ * @param exemptPaths 제외할 경로 배열
360
+ * @returns 보호된 API 경로 여부
361
+ */
362
+ export declare function isProtectedApiPath(pathname: string, exemptPaths?: string[]): boolean;
363
+ /**
364
+ * NextAuth 토큰과 자체 토큰을 모두 확인하는 통합 인증 체크 함수
365
+ * @param req NextRequest 객체
366
+ * @param secret JWT 서명에 사용할 secret key
367
+ * @param options 옵션
368
+ * @returns 인증 결과
369
+ */
370
+ export declare function checkAuthentication(req: NextRequest, secret: string, options?: {
371
+ cookiePrefix?: string;
372
+ isProduction?: boolean;
373
+ cookieDomain?: string;
374
+ text?: string;
375
+ ssoBaseURL?: string;
376
+ authServiceKey?: string;
377
+ getNextAuthToken?: (req: NextRequest) => Promise<JWT | null>;
378
+ }): Promise<{
379
+ isAuthenticated: boolean;
380
+ token?: JWT | null;
381
+ payload?: JWTPayload;
382
+ response?: NextResponse;
383
+ error?: string;
384
+ }>;