@korioinc/next-core 1.0.0

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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -0
  3. package/dist/ads/components/AdContainer.d.ts +12 -0
  4. package/dist/ads/components/AdContainer.d.ts.map +1 -0
  5. package/dist/ads/components/AdContainer.js +287 -0
  6. package/dist/ads/components/GoogleAdSense.d.ts +6 -0
  7. package/dist/ads/components/GoogleAdSense.d.ts.map +1 -0
  8. package/dist/ads/components/GoogleAdSense.js +6 -0
  9. package/dist/ads/components/MockAdDisplay.d.ts +8 -0
  10. package/dist/ads/components/MockAdDisplay.d.ts.map +1 -0
  11. package/dist/ads/components/MockAdDisplay.js +13 -0
  12. package/dist/ads/config.d.ts +3 -0
  13. package/dist/ads/config.d.ts.map +1 -0
  14. package/dist/ads/config.js +134 -0
  15. package/dist/ads/index.d.ts +6 -0
  16. package/dist/ads/index.d.ts.map +1 -0
  17. package/dist/ads/index.js +7 -0
  18. package/dist/ads/types.d.ts +15 -0
  19. package/dist/ads/types.d.ts.map +1 -0
  20. package/dist/ads/types.js +1 -0
  21. package/dist/api-client/index.d.ts +31 -0
  22. package/dist/api-client/index.d.ts.map +1 -0
  23. package/dist/api-client/index.js +90 -0
  24. package/dist/auth/auth-manager.d.ts +45 -0
  25. package/dist/auth/auth-manager.d.ts.map +1 -0
  26. package/dist/auth/auth-manager.js +75 -0
  27. package/dist/auth/index.client.d.ts +7 -0
  28. package/dist/auth/index.client.d.ts.map +1 -0
  29. package/dist/auth/index.client.js +5 -0
  30. package/dist/auth/index.d.ts +8 -0
  31. package/dist/auth/index.d.ts.map +1 -0
  32. package/dist/auth/index.js +11 -0
  33. package/dist/auth/index.server.d.ts +7 -0
  34. package/dist/auth/index.server.d.ts.map +1 -0
  35. package/dist/auth/index.server.js +5 -0
  36. package/dist/auth/providers/auth-context-provider.d.ts +21 -0
  37. package/dist/auth/providers/auth-context-provider.d.ts.map +1 -0
  38. package/dist/auth/providers/auth-context-provider.js +74 -0
  39. package/dist/auth/routing.d.ts +3 -0
  40. package/dist/auth/routing.d.ts.map +1 -0
  41. package/dist/auth/routing.js +40 -0
  42. package/dist/auth/types/auth.d.ts +23 -0
  43. package/dist/auth/types/auth.d.ts.map +1 -0
  44. package/dist/auth/types/auth.js +1 -0
  45. package/dist/auth/types/user.d.ts +6 -0
  46. package/dist/auth/types/user.d.ts.map +1 -0
  47. package/dist/auth/types/user.js +1 -0
  48. package/dist/auth/utils/auth.d.ts +32 -0
  49. package/dist/auth/utils/auth.d.ts.map +1 -0
  50. package/dist/auth/utils/auth.js +116 -0
  51. package/dist/auth/utils/permission.d.ts +29 -0
  52. package/dist/auth/utils/permission.d.ts.map +1 -0
  53. package/dist/auth/utils/permission.js +44 -0
  54. package/dist/components/head-manifest/index.d.ts +6 -0
  55. package/dist/components/head-manifest/index.d.ts.map +1 -0
  56. package/dist/components/head-manifest/index.js +4 -0
  57. package/dist/components/index.d.ts +6 -0
  58. package/dist/components/index.d.ts.map +1 -0
  59. package/dist/components/index.js +7 -0
  60. package/dist/components/json-ld/index.d.ts +7 -0
  61. package/dist/components/json-ld/index.d.ts.map +1 -0
  62. package/dist/components/json-ld/index.js +6 -0
  63. package/dist/components/locale-switcher/_components/china-flag.d.ts +2 -0
  64. package/dist/components/locale-switcher/_components/china-flag.d.ts.map +1 -0
  65. package/dist/components/locale-switcher/_components/china-flag.js +4 -0
  66. package/dist/components/locale-switcher/_components/japan-flag.d.ts +2 -0
  67. package/dist/components/locale-switcher/_components/japan-flag.d.ts.map +1 -0
  68. package/dist/components/locale-switcher/_components/japan-flag.js +4 -0
  69. package/dist/components/locale-switcher/_components/korea-flag.d.ts +4 -0
  70. package/dist/components/locale-switcher/_components/korea-flag.d.ts.map +1 -0
  71. package/dist/components/locale-switcher/_components/korea-flag.js +4 -0
  72. package/dist/components/locale-switcher/_components/taiwan-flag.d.ts +2 -0
  73. package/dist/components/locale-switcher/_components/taiwan-flag.d.ts.map +1 -0
  74. package/dist/components/locale-switcher/_components/taiwan-flag.js +4 -0
  75. package/dist/components/locale-switcher/_components/usa-flag.d.ts +4 -0
  76. package/dist/components/locale-switcher/_components/usa-flag.d.ts.map +1 -0
  77. package/dist/components/locale-switcher/_components/usa-flag.js +4 -0
  78. package/dist/components/locale-switcher/index.d.ts +11 -0
  79. package/dist/components/locale-switcher/index.d.ts.map +1 -0
  80. package/dist/components/locale-switcher/index.js +69 -0
  81. package/dist/components/theme-switcher/index.d.ts +3 -0
  82. package/dist/components/theme-switcher/index.d.ts.map +1 -0
  83. package/dist/components/theme-switcher/index.js +20 -0
  84. package/dist/components/tooltip/index.d.ts +8 -0
  85. package/dist/components/tooltip/index.d.ts.map +1 -0
  86. package/dist/components/tooltip/index.js +40 -0
  87. package/dist/i18n/init-lingui.d.ts +7 -0
  88. package/dist/i18n/init-lingui.d.ts.map +1 -0
  89. package/dist/i18n/init-lingui.js +7 -0
  90. package/dist/i18n/lingui.setup.d.ts +15 -0
  91. package/dist/i18n/lingui.setup.d.ts.map +1 -0
  92. package/dist/i18n/lingui.setup.js +29 -0
  93. package/dist/i18n/providers/lingui-client-provider.d.ts +9 -0
  94. package/dist/i18n/providers/lingui-client-provider.d.ts.map +1 -0
  95. package/dist/i18n/providers/lingui-client-provider.js +14 -0
  96. package/dist/i18n/routing.d.ts +25 -0
  97. package/dist/i18n/routing.d.ts.map +1 -0
  98. package/dist/i18n/routing.js +252 -0
  99. package/dist/local-storage/index.d.ts +4 -0
  100. package/dist/local-storage/index.d.ts.map +1 -0
  101. package/dist/local-storage/index.js +4 -0
  102. package/dist/local-storage/local-storage-manager.d.ts +41 -0
  103. package/dist/local-storage/local-storage-manager.d.ts.map +1 -0
  104. package/dist/local-storage/local-storage-manager.js +200 -0
  105. package/dist/local-storage/valtio-persist.d.ts +31 -0
  106. package/dist/local-storage/valtio-persist.d.ts.map +1 -0
  107. package/dist/local-storage/valtio-persist.js +84 -0
  108. package/dist/navigation/index.d.ts +4 -0
  109. package/dist/navigation/index.d.ts.map +1 -0
  110. package/dist/navigation/index.js +4 -0
  111. package/dist/navigation/permissions.d.ts +25 -0
  112. package/dist/navigation/permissions.d.ts.map +1 -0
  113. package/dist/navigation/permissions.js +97 -0
  114. package/dist/navigation/types.d.ts +57 -0
  115. package/dist/navigation/types.d.ts.map +1 -0
  116. package/dist/navigation/types.js +1 -0
  117. package/dist/navigation/utils.d.ts +42 -0
  118. package/dist/navigation/utils.d.ts.map +1 -0
  119. package/dist/navigation/utils.js +107 -0
  120. package/dist/utils/cookie.d.ts +3 -0
  121. package/dist/utils/cookie.d.ts.map +1 -0
  122. package/dist/utils/cookie.js +22 -0
  123. package/dist/utils/helpers.d.ts +5 -0
  124. package/dist/utils/helpers.d.ts.map +1 -0
  125. package/dist/utils/helpers.js +18 -0
  126. package/dist/utils/index.d.ts +3 -0
  127. package/dist/utils/index.d.ts.map +1 -0
  128. package/dist/utils/index.js +2 -0
  129. package/dist/utils/sitemap.d.ts +13 -0
  130. package/dist/utils/sitemap.d.ts.map +1 -0
  131. package/dist/utils/sitemap.js +19 -0
  132. package/package.json +126 -0
@@ -0,0 +1,31 @@
1
+ type RequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
2
+ type NextFetchOptions = {
3
+ revalidate?: number | false;
4
+ tags?: string[];
5
+ };
6
+ interface RequestOptions extends Omit<RequestInit, 'method' | 'headers' | 'body' | 'cache' | 'credentials'> {
7
+ method?: RequestMethod;
8
+ headers?: Record<string, string>;
9
+ body?: unknown;
10
+ cache?: RequestCache;
11
+ credentials?: RequestCredentials;
12
+ next?: NextFetchOptions;
13
+ }
14
+ /**
15
+ * Generic API response type
16
+ */
17
+ export interface ApiResponse<T> {
18
+ data: T;
19
+ success: boolean;
20
+ message?: string;
21
+ error?: unknown;
22
+ }
23
+ /**
24
+ * Reusable API request function
25
+ * @param endpoint - API endpoint path (without base URL)
26
+ * @param options - Request options
27
+ * @returns Promise with the response data
28
+ */
29
+ export declare function requestApi<T = unknown>(endpoint: string, options?: RequestOptions): Promise<T>;
30
+ export {};
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api-client/index.ts"],"names":[],"mappings":"AAMA,KAAK,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEjE,KAAK,gBAAgB,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEzE,UAAU,cAAe,SAAQ,IAAI,CAAC,WAAW,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,aAAa,CAAC;IACzG,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CAgGxG"}
@@ -0,0 +1,90 @@
1
+ import { cookies } from 'next/headers';
2
+ import { getConfig } from '@korioinc/next-conf';
3
+ import { deleteCookie, getCookie, setCookie } from 'cookies-next/server';
4
+ /**
5
+ * Reusable API request function
6
+ * @param endpoint - API endpoint path (without base URL)
7
+ * @param options - Request options
8
+ * @returns Promise with the response data
9
+ */
10
+ export async function requestApi(endpoint, options = {}) {
11
+ const { method = 'GET', headers = {}, body, cache, credentials, next } = options;
12
+ // Get configuration
13
+ const cfg = getConfig();
14
+ const apiConfig = cfg.api;
15
+ // Prepare URL
16
+ const url = `${apiConfig.baseUrl}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`;
17
+ // Get access token from cookie
18
+ const cookieCfg = cfg.cookie;
19
+ const accessTokenName = cookieCfg.accessTokenName;
20
+ const accessToken = await getCookie(accessTokenName, { cookies });
21
+ // Prepare headers with defaults
22
+ const requestHeaders = {
23
+ Accept: 'application/json',
24
+ ...headers,
25
+ };
26
+ // Add Authorization header if token exists
27
+ if (accessToken) {
28
+ requestHeaders['Authorization'] = `Bearer ${accessToken}`;
29
+ }
30
+ // Add Content-Type for requests with body
31
+ if (body && !requestHeaders['Content-Type'] && !(body instanceof FormData)) {
32
+ requestHeaders['Content-Type'] = 'application/json';
33
+ }
34
+ // Prepare request options
35
+ const requestOptions = {
36
+ method,
37
+ headers: requestHeaders,
38
+ credentials: credentials || 'same-origin',
39
+ };
40
+ // Add cache and revalidation options
41
+ if (cache) {
42
+ requestOptions.cache = cache;
43
+ }
44
+ if (next) {
45
+ requestOptions.next = next;
46
+ }
47
+ // Add body for non-GET requests if provided
48
+ if (method !== 'GET' && body) {
49
+ requestOptions.body = body instanceof FormData ? body : JSON.stringify(body);
50
+ }
51
+ try {
52
+ const response = await fetch(url, requestOptions);
53
+ const refreshedToken = response.headers.get('x-refreshed-token');
54
+ if (refreshedToken) {
55
+ // Update the access token cookie
56
+ await setCookie(accessTokenName, refreshedToken, {
57
+ cookies,
58
+ path: '/',
59
+ domain: cookieCfg.domain,
60
+ maxAge: cookieCfg.maxAge,
61
+ sameSite: 'lax',
62
+ });
63
+ }
64
+ // Handle non-OK responses
65
+ if (!response.ok) {
66
+ const errorData = await response.json().catch(() => ({
67
+ message: `API error: ${response.status} ${response.statusText}`,
68
+ }));
69
+ // Delete cookie on 401 Unauthorized
70
+ if (response.status === 401) {
71
+ deleteCookie(accessTokenName, {
72
+ cookies,
73
+ path: '/',
74
+ domain: cookieCfg.domain,
75
+ });
76
+ }
77
+ throw new Error(errorData.message || `API error: ${response.status}`);
78
+ }
79
+ if (response.status === 204) {
80
+ return undefined;
81
+ }
82
+ // Parse JSON response
83
+ const jsonResponse = await response.json();
84
+ return jsonResponse;
85
+ }
86
+ catch (error) {
87
+ console.error(`Failed API request to ${endpoint}:`, error);
88
+ throw error;
89
+ }
90
+ }
@@ -0,0 +1,45 @@
1
+ import { AuthData } from '../auth/types/auth';
2
+ import { Permission, Role, UserData } from '../auth/types/user';
3
+ /**
4
+ * 서버 컴포넌트/액션에서 현재 사용자 정보를 가져옴
5
+ */
6
+ export declare function getCurrentUser(): Promise<UserData | null>;
7
+ /**
8
+ * 서버 컴포넌트/액션에서 로그인 여부 확인
9
+ */
10
+ export declare function isAuthenticated(): Promise<boolean>;
11
+ /**
12
+ * 내부 구현 - 실제 인증 데이터를 가져오는 함수
13
+ */
14
+ declare function _getAuthDataImpl(): Promise<AuthData>;
15
+ /**
16
+ * 전체 인증 데이터 가져오기 (User, Permissions, Roles)
17
+ * React cache를 사용하여 요청 단위로 캐싱됨
18
+ */
19
+ export declare const getAuthData: typeof _getAuthDataImpl;
20
+ /**
21
+ * 특정 역할 확인 (서버용)
22
+ */
23
+ export declare function hasRole(role: Role): Promise<boolean>;
24
+ /**
25
+ * 특정 권한 확인 (서버용)
26
+ */
27
+ export declare function hasPermission(permission: Permission): Promise<boolean>;
28
+ /**
29
+ * 여러 권한 중 하나라도 있는지 확인 (서버용)
30
+ */
31
+ export declare function hasAnyPermission(requiredPermissions: Permission[]): Promise<boolean>;
32
+ /**
33
+ * 모든 권한을 가지고 있는지 확인 (서버용)
34
+ */
35
+ export declare function hasAllPermissions(requiredPermissions: Permission[]): Promise<boolean>;
36
+ /**
37
+ * 특정 역할 또는 권한을 가지고 있는지 확인 (서버용)
38
+ */
39
+ export declare function hasRoleOrPermission(roleOrPermission: Role | Permission): Promise<boolean>;
40
+ /**
41
+ * 여러 역할 또는 권한 중 하나라도 있는지 확인 (서버용)
42
+ */
43
+ export declare function hasAnyRoleOrPermission(rolesOrPermissions: Array<Role | Permission>): Promise<boolean>;
44
+ export {};
45
+ //# sourceMappingURL=auth-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-manager.d.ts","sourceRoot":"","sources":["../../src/auth/auth-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAYnE;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAI/D;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC,CAIxD;AAED;;GAEG;AACH,iBAAe,gBAAgB,IAAI,OAAO,CAAC,QAAQ,CAAC,CAMnD;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,yBAA0B,CAAC;AAEnD;;GAEG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAI1D;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAI5E;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,mBAAmB,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAI1F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,mBAAmB,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3F;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,gBAAgB,EAAE,IAAI,GAAG,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAI/F;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,kBAAkB,EAAE,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAI3G"}
@@ -0,0 +1,75 @@
1
+ import { cache } from 'react';
2
+ import { cookies } from 'next/headers';
3
+ import { createAuthDataFromTokenServer } from '../auth/utils/auth';
4
+ import { checkHasAllPermissions, checkHasAnyPermission, checkHasAnyRoleOrPermission, checkHasPermission, checkHasRole, checkHasRoleOrPermission, } from '../auth/utils/permission';
5
+ import { getConfig } from '@korioinc/next-conf';
6
+ /**
7
+ * 서버 컴포넌트/액션에서 현재 사용자 정보를 가져옴
8
+ */
9
+ export async function getCurrentUser() {
10
+ const { user } = await getAuthData();
11
+ return user;
12
+ }
13
+ /**
14
+ * 서버 컴포넌트/액션에서 로그인 여부 확인
15
+ */
16
+ export async function isAuthenticated() {
17
+ const { user } = await getAuthData();
18
+ return !!user;
19
+ }
20
+ /**
21
+ * 내부 구현 - 실제 인증 데이터를 가져오는 함수
22
+ */
23
+ async function _getAuthDataImpl() {
24
+ const config = getConfig();
25
+ const cookieStore = await cookies();
26
+ const token = cookieStore.get(config.cookie?.accessTokenName || '_at');
27
+ return createAuthDataFromTokenServer(token?.value || null);
28
+ }
29
+ /**
30
+ * 전체 인증 데이터 가져오기 (User, Permissions, Roles)
31
+ * React cache를 사용하여 요청 단위로 캐싱됨
32
+ */
33
+ export const getAuthData = cache(_getAuthDataImpl);
34
+ /**
35
+ * 특정 역할 확인 (서버용)
36
+ */
37
+ export async function hasRole(role) {
38
+ const authData = await getAuthData();
39
+ return checkHasRole(authData, role);
40
+ }
41
+ /**
42
+ * 특정 권한 확인 (서버용)
43
+ */
44
+ export async function hasPermission(permission) {
45
+ const authData = await getAuthData();
46
+ return checkHasPermission(authData, permission);
47
+ }
48
+ /**
49
+ * 여러 권한 중 하나라도 있는지 확인 (서버용)
50
+ */
51
+ export async function hasAnyPermission(requiredPermissions) {
52
+ const authData = await getAuthData();
53
+ return checkHasAnyPermission(authData, requiredPermissions);
54
+ }
55
+ /**
56
+ * 모든 권한을 가지고 있는지 확인 (서버용)
57
+ */
58
+ export async function hasAllPermissions(requiredPermissions) {
59
+ const authData = await getAuthData();
60
+ return checkHasAllPermissions(authData, requiredPermissions);
61
+ }
62
+ /**
63
+ * 특정 역할 또는 권한을 가지고 있는지 확인 (서버용)
64
+ */
65
+ export async function hasRoleOrPermission(roleOrPermission) {
66
+ const authData = await getAuthData();
67
+ return checkHasRoleOrPermission(authData, roleOrPermission);
68
+ }
69
+ /**
70
+ * 여러 역할 또는 권한 중 하나라도 있는지 확인 (서버용)
71
+ */
72
+ export async function hasAnyRoleOrPermission(rolesOrPermissions) {
73
+ const authData = await getAuthData();
74
+ return checkHasAnyRoleOrPermission(authData, rolesOrPermissions);
75
+ }
@@ -0,0 +1,7 @@
1
+ export { default as AuthContextProvider } from './providers/auth-context-provider';
2
+ export { useAuthContext } from './providers/auth-context-provider';
3
+ export { createAuthDataFromTokenClient } from './utils/auth';
4
+ export { checkHasRole, checkHasPermission, checkHasAllPermissions, checkHasAnyPermission, checkHasRoleOrPermission, checkHasAnyRoleOrPermission, } from './utils/permission';
5
+ export type { AuthData, JWTPayload } from './types/auth';
6
+ export type { Permission, Role, UserData } from './types/user';
7
+ //# sourceMappingURL=index.client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.client.d.ts","sourceRoot":"","sources":["../../src/auth/index.client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ // Client-side auth exports
2
+ export { default as AuthContextProvider } from './providers/auth-context-provider';
3
+ export { useAuthContext } from './providers/auth-context-provider';
4
+ export { createAuthDataFromTokenClient } from './utils/auth';
5
+ export { checkHasRole, checkHasPermission, checkHasAllPermissions, checkHasAnyPermission, checkHasRoleOrPermission, checkHasAnyRoleOrPermission, } from './utils/permission';
@@ -0,0 +1,8 @@
1
+ export type { AuthData, JWTPayload, UserDataWithAuth } from './types/auth';
2
+ export type { UserData, Role, Permission } from './types/user';
3
+ export { getCurrentUser, isAuthenticated, getAuthData, hasRole, hasPermission, hasAnyPermission, hasAllPermissions, hasRoleOrPermission, hasAnyRoleOrPermission, } from './auth-manager';
4
+ export { handleAuthRouting } from './routing';
5
+ export { decodeJWT, createAuthDataFromTokenClient, isTokenExpired, createUserFromPayload, extractPermissions, } from './utils/auth';
6
+ export { checkHasRole, checkHasPermission, checkHasAnyPermission, checkHasAllPermissions, checkHasRoleOrPermission, checkHasAnyRoleOrPermission, } from './utils/permission';
7
+ export { default as AuthContextProvider, useAuthContext } from './providers/auth-context-provider';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAGA,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC3E,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/D,OAAO,EACL,cAAc,EACd,eAAe,EACf,WAAW,EACX,OAAO,EACP,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAG9C,OAAO,EACL,SAAS,EACT,6BAA6B,EAC7B,cAAc,EACd,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC"}
@@ -0,0 +1,11 @@
1
+ // Main Auth Module Exports
2
+ // Server-side auth functions (with cache)
3
+ export { getCurrentUser, isAuthenticated, getAuthData, hasRole, hasPermission, hasAnyPermission, hasAllPermissions, hasRoleOrPermission, hasAnyRoleOrPermission, } from './auth-manager';
4
+ // Routing utilities
5
+ export { handleAuthRouting } from './routing';
6
+ // Client utilities
7
+ export { decodeJWT, createAuthDataFromTokenClient, isTokenExpired, createUserFromPayload, extractPermissions, } from './utils/auth';
8
+ // Permission utilities (pure functions)
9
+ export { checkHasRole, checkHasPermission, checkHasAnyPermission, checkHasAllPermissions, checkHasRoleOrPermission, checkHasAnyRoleOrPermission, } from './utils/permission';
10
+ // React Context Provider
11
+ export { default as AuthContextProvider, useAuthContext } from './providers/auth-context-provider';
@@ -0,0 +1,7 @@
1
+ export { getAuthData, getCurrentUser, isAuthenticated, hasRole, hasPermission, hasAllPermissions, hasAnyPermission, hasRoleOrPermission, hasAnyRoleOrPermission, } from './auth-manager';
2
+ export { handleAuthRouting } from './routing';
3
+ export { createAuthDataFromTokenServer } from './utils/auth';
4
+ export { checkHasRole, checkHasPermission, checkHasAllPermissions, checkHasAnyPermission, checkHasRoleOrPermission, checkHasAnyRoleOrPermission, } from './utils/permission';
5
+ export type { AuthData, JWTPayload } from './types/auth';
6
+ export type { Permission, Role, UserData } from './types/user';
7
+ //# sourceMappingURL=index.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.server.d.ts","sourceRoot":"","sources":["../../src/auth/index.server.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,OAAO,EACP,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,6BAA6B,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,2BAA2B,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AACzD,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ // Server-side auth exports
2
+ export { getAuthData, getCurrentUser, isAuthenticated, hasRole, hasPermission, hasAllPermissions, hasAnyPermission, hasRoleOrPermission, hasAnyRoleOrPermission, } from './auth-manager';
3
+ export { handleAuthRouting } from './routing';
4
+ export { createAuthDataFromTokenServer } from './utils/auth';
5
+ export { checkHasRole, checkHasPermission, checkHasAllPermissions, checkHasAnyPermission, checkHasRoleOrPermission, checkHasAnyRoleOrPermission, } from './utils/permission';
@@ -0,0 +1,21 @@
1
+ import { AuthData } from '../../auth/types/auth';
2
+ import { Permission, Role, UserData } from '../../auth/types/user';
3
+ interface AuthContextType {
4
+ user: UserData | null;
5
+ isLogin: boolean;
6
+ hasPermission: (permission: Permission) => boolean;
7
+ hasRole: (role: Role) => boolean;
8
+ hasAnyPermission: (permissions: Permission[]) => boolean;
9
+ hasAllPermissions: (permissions: Permission[]) => boolean;
10
+ hasRoleOrPermission: (roleOrPermission: Role | Permission) => boolean;
11
+ hasAnyRoleOrPermission: (rolesOrPermissions: Array<Role | Permission>) => boolean;
12
+ logout: () => Promise<void>;
13
+ }
14
+ export declare function useAuthContext(): AuthContextType;
15
+ interface AuthContextProviderProps {
16
+ children: React.ReactNode;
17
+ initialAuthData: AuthData;
18
+ }
19
+ export default function AuthContextProvider({ children, initialAuthData }: AuthContextProviderProps): import("react/jsx-runtime").JSX.Element;
20
+ export {};
21
+ //# sourceMappingURL=auth-context-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-context-provider.d.ts","sourceRoot":"","sources":["../../../src/auth/providers/auth-context-provider.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAcnE,UAAU,eAAe;IACvB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,OAAO,CAAC;IACnD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IACjC,gBAAgB,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC;IACzD,iBAAiB,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,OAAO,CAAC;IAC1D,mBAAmB,EAAE,CAAC,gBAAgB,EAAE,IAAI,GAAG,UAAU,KAAK,OAAO,CAAC;IACtE,sBAAsB,EAAE,CAAC,kBAAkB,EAAE,KAAK,CAAC,IAAI,GAAG,UAAU,CAAC,KAAK,OAAO,CAAC;IAClF,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAID,wBAAgB,cAAc,oBAO7B;AAED,UAAU,wBAAwB;IAChC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,eAAe,EAAE,QAAQ,CAAC;CAC3B;AAED,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,EAAE,wBAAwB,2CAsElG"}
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useEffect, useState } from 'react';
4
+ import { createAuthDataFromTokenClient } from '../../auth/utils/auth';
5
+ import { checkHasAllPermissions, checkHasAnyPermission, checkHasAnyRoleOrPermission, checkHasPermission, checkHasRole, checkHasRoleOrPermission, } from '../../auth/utils/permission';
6
+ import { getConfig } from '@korioinc/next-conf';
7
+ import { deleteCookie, getCookie } from 'cookies-next/client';
8
+ const AuthContext = createContext(undefined);
9
+ export function useAuthContext() {
10
+ const context = useContext(AuthContext);
11
+ if (context === undefined) {
12
+ throw new Error('useAuthContext must be used within an AuthContextProvider');
13
+ }
14
+ return context;
15
+ }
16
+ export default function AuthContextProvider({ children, initialAuthData }) {
17
+ const [authData, setAuthData] = useState(initialAuthData);
18
+ const config = getConfig();
19
+ const cookieName = config.cookie?.accessTokenName || '_at';
20
+ const cookieDomain = config.cookie?.domain;
21
+ useEffect(() => {
22
+ if (authData.token && authData.user === null) {
23
+ deleteCookie(cookieName, {
24
+ path: '/',
25
+ domain: cookieDomain,
26
+ });
27
+ }
28
+ }, [authData.token, authData.user, cookieName, cookieDomain]);
29
+ // jwt 토큰 쿠키가 변경된 경우
30
+ useEffect(() => {
31
+ const token = getCookie(cookieName);
32
+ if (token && authData.token !== token) {
33
+ setAuthData(createAuthDataFromTokenClient(token));
34
+ }
35
+ }, [cookieName, authData.token]);
36
+ // 권한 확인 헬퍼 함수들 (순수 함수 사용)
37
+ const hasPermission = (permission) => {
38
+ return checkHasPermission(authData, permission);
39
+ };
40
+ const hasRole = (role) => {
41
+ return checkHasRole(authData, role);
42
+ };
43
+ const hasAnyPermission = (requiredPermissions) => {
44
+ return checkHasAnyPermission(authData, requiredPermissions);
45
+ };
46
+ const hasAllPermissions = (requiredPermissions) => {
47
+ return checkHasAllPermissions(authData, requiredPermissions);
48
+ };
49
+ const hasRoleOrPermission = (roleOrPermission) => {
50
+ return checkHasRoleOrPermission(authData, roleOrPermission);
51
+ };
52
+ const hasAnyRoleOrPermission = (rolesOrPermissions) => {
53
+ return checkHasAnyRoleOrPermission(authData, rolesOrPermissions);
54
+ };
55
+ const logout = async () => {
56
+ deleteCookie(config.cookie?.accessTokenName || '_at', {
57
+ path: '/',
58
+ domain: config.cookie?.domain,
59
+ });
60
+ window.location.replace(config.auth?.homeUrl || '/');
61
+ };
62
+ const contextValue = {
63
+ user: authData.user,
64
+ isLogin: !!authData.user,
65
+ hasPermission,
66
+ hasRole,
67
+ hasAnyPermission,
68
+ hasAllPermissions,
69
+ hasRoleOrPermission,
70
+ hasAnyRoleOrPermission,
71
+ logout,
72
+ };
73
+ return _jsx(AuthContext.Provider, { value: contextValue, children: children });
74
+ }
@@ -0,0 +1,3 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ export declare function handleAuthRouting(request: NextRequest): Promise<NextResponse | null>;
3
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/auth/routing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgCxD,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAmB1F"}
@@ -0,0 +1,40 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { getAuthData } from '../auth/auth-manager';
3
+ import { getConfig } from '@korioinc/next-conf';
4
+ import linguiConfig from 'lingui.config';
5
+ const { locales } = linguiConfig;
6
+ // 경로가 패턴에 매칭되는지 확인하는 공통 함수
7
+ function isPathMatching(path, patterns) {
8
+ return patterns.some((pattern) => {
9
+ if (typeof pattern === 'string') {
10
+ return path === pattern;
11
+ }
12
+ return pattern.test(path);
13
+ });
14
+ }
15
+ // 경로에서 locale 접두사를 제거하는 함수
16
+ function removeLocalePrefix(pathname) {
17
+ // Check if pathname starts with any locale
18
+ for (const locale of locales) {
19
+ if (pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`) {
20
+ return pathname.slice(`/${locale}`.length) || '/';
21
+ }
22
+ }
23
+ return pathname;
24
+ }
25
+ export async function handleAuthRouting(request) {
26
+ const config = getConfig();
27
+ const authData = await getAuthData();
28
+ const fullPath = request.nextUrl.pathname;
29
+ // Remove locale prefix from the path for auth checking
30
+ const path = removeLocalePrefix(fullPath);
31
+ // 로그인한 사용자가 인증 관련 페이지 접근 시 홈으로 리다이렉트
32
+ if (authData.user && isPathMatching(path, config.auth?.restrictedPaths || [])) {
33
+ return NextResponse.redirect(new URL(config.auth?.homeUrl || '/', request.url));
34
+ }
35
+ // 로그인하지 않은 사용자가 보호된 페이지 접근 시 로그인 페이지로 리다이렉트
36
+ if (!authData.user && isPathMatching(path, config.auth?.requiredPaths || [])) {
37
+ return NextResponse.redirect(new URL(config.auth?.loginUrl || '/accounts/login', request.url));
38
+ }
39
+ return null;
40
+ }
@@ -0,0 +1,23 @@
1
+ import { Permission, Role, UserData } from '../../auth/types/user';
2
+ export interface UserDataWithAuth extends UserData {
3
+ roles?: Role[];
4
+ permissions?: Permission[];
5
+ }
6
+ export interface JWTPayload {
7
+ jti?: string;
8
+ iat: number;
9
+ exp: number;
10
+ sub?: string;
11
+ iss?: string;
12
+ aud?: string;
13
+ amr?: string[];
14
+ nbf?: number;
15
+ props?: UserDataWithAuth;
16
+ }
17
+ export interface AuthData {
18
+ user: UserData | null;
19
+ roles: Role[];
20
+ permissions: Permission[];
21
+ token: string | null;
22
+ }
23
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/auth/types/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEnE,MAAM,WAAW,gBAAiB,SAAQ,QAAQ;IAChD,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;CAC5B;AAGD,MAAM,WAAW,UAAU;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAGD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ export type Role = 'admin' | 'user' | 'moderator' | 'guest';
2
+ export type Permission = 'read' | 'write' | 'delete' | 'create' | 'update' | 'tester' | 'manage_users' | 'manage_posts';
3
+ export interface UserData {
4
+ nickname: string;
5
+ }
6
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../../src/auth/types/user.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,WAAW,GAAG,OAAO,CAAC;AAG5D,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,cAAc,GAAG,cAAc,CAAC;AAGxH,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { AuthData, JWTPayload } from '../../auth/types/auth';
2
+ import { Permission, UserData } from '../../auth/types/user';
3
+ export declare const getJWTSecret: () => Uint8Array<ArrayBuffer>;
4
+ /**
5
+ * JWT 토큰 검증 및 페이로드 추출
6
+ */
7
+ export declare function verifyJWT(token: string): Promise<JWTPayload | null>;
8
+ /**
9
+ * JWT 페이로드에서 UserDto 객체 생성 (역할/권한 제외)
10
+ */
11
+ export declare function createUserFromPayload(payload: JWTPayload): UserData | null;
12
+ /**
13
+ * 권한 목록 추출
14
+ */
15
+ export declare function extractPermissions(payload: JWTPayload): Permission[];
16
+ /**
17
+ * 토큰 만료 확인
18
+ */
19
+ export declare function isTokenExpired(payload: JWTPayload): boolean;
20
+ /**
21
+ * 클라이언트에서 JWT 디코드 (검증 없이)
22
+ */
23
+ export declare function decodeJWT(token: string): JWTPayload | null;
24
+ /**
25
+ * 클라이언트에서 토큰으로부터 인증 데이터를 생성하는 함수 (디코드만)
26
+ */
27
+ export declare function createAuthDataFromTokenClient(token: string | null): AuthData;
28
+ /**
29
+ * 서버에서 토큰으로부터 인증 데이터를 생성하는 함수 (검증 포함)
30
+ */
31
+ export declare function createAuthDataFromTokenServer(token: string | null): Promise<AuthData>;
32
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/auth/utils/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAK7D,eAAO,MAAM,YAAY,+BAOxB,CAAC;AAEF;;GAEG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAiBzE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,IAAI,CAS1E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,EAAE,CAOpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAE3D;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAwB1D;AAqBD;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,CAQ5E;AAED;;GAEG;AACH,wBAAsB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAQ3F"}