@withwiz/toolkit 0.4.1 → 0.5.1

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 (50) hide show
  1. package/dist/auth/adapters/prisma/index.d.ts +20 -4
  2. package/dist/auth/adapters/prisma/index.js +51 -61
  3. package/dist/auth/core/jwt/cookie.d.ts +1 -0
  4. package/dist/auth/core/jwt/cookie.js +1 -1
  5. package/dist/auth/core/jwt/index.d.ts +1 -1
  6. package/dist/auth/core/jwt/index.js +1 -1
  7. package/dist/auth/core/jwt/types.js +5 -7
  8. package/dist/auth/core/oauth/index.d.ts +17 -27
  9. package/dist/auth/core/oauth/index.js +18 -5
  10. package/dist/auth/core/oauth/providers/github.d.ts +12 -0
  11. package/dist/auth/core/oauth/providers/github.js +8 -0
  12. package/dist/auth/core/oauth/providers/google.d.ts +12 -0
  13. package/dist/auth/core/oauth/providers/google.js +8 -0
  14. package/dist/auth/core/oauth/providers/index.d.ts +3 -0
  15. package/dist/auth/core/oauth/providers/index.js +17 -0
  16. package/dist/auth/core/oauth/providers/kakao.d.ts +12 -0
  17. package/dist/auth/core/oauth/providers/kakao.js +8 -0
  18. package/dist/auth/core/password/client-helper.js +1 -1
  19. package/dist/auth/core/password/index.js +1 -1
  20. package/dist/auth/index.d.ts +2 -3
  21. package/dist/auth/index.js +35 -24
  22. package/dist/auth/types/index.d.ts +31 -31
  23. package/dist/auth/types/index.js +5 -7
  24. package/dist/chunk-2QQNL4ND.js +62 -0
  25. package/dist/chunk-6PGZTY4N.js +30 -0
  26. package/dist/chunk-GBLNXNEH.js +64 -0
  27. package/dist/chunk-HZLJYEOO.js +92 -0
  28. package/dist/{chunk-N4D6OPPP.js → chunk-LLVIA4JX.js} +4 -2
  29. package/dist/{chunk-5WP57PJK.js → chunk-O3UR234Y.js} +4 -4
  30. package/dist/{chunk-6D3HHYER.js → chunk-QKC73SWB.js} +6 -12
  31. package/dist/chunk-RVL5ROWQ.js +62 -0
  32. package/dist/chunk-T4MDCVUQ.js +0 -0
  33. package/dist/{chunk-J5AISIJS.js → chunk-ZBXSEQ6W.js} +18 -14
  34. package/dist/config/registry.d.ts +42 -0
  35. package/dist/config/registry.js +12 -0
  36. package/dist/constants/index.js +6 -6
  37. package/dist/initialize.d.ts +2 -0
  38. package/dist/initialize.js +18 -10
  39. package/dist/middleware/auth.d.ts +1 -0
  40. package/dist/middleware/auth.js +4 -2
  41. package/dist/middleware/index.d.ts +1 -1
  42. package/dist/middleware/index.js +8 -6
  43. package/dist/middleware/rate-limit.d.ts +3 -7
  44. package/dist/middleware/types.d.ts +1 -1
  45. package/dist/middleware/wrappers.js +4 -4
  46. package/dist/types/geoip.d.ts +4 -4
  47. package/dist/types/qr-code.d.ts +20 -20
  48. package/dist/types/qr-code.js +4 -4
  49. package/package.json +6 -1
  50. package/dist/chunk-V5K5FYU7.js +0 -200
@@ -10,15 +10,11 @@ export interface Logger {
10
10
  warn(message: string, meta?: any): void;
11
11
  error(message: string, meta?: any): void;
12
12
  }
13
- export declare enum UserRole {
14
- USER = "USER",
15
- ADMIN = "ADMIN"
16
- }
17
13
  export interface JWTPayload {
18
14
  id: string;
19
15
  userId: string;
20
16
  email: string;
21
- role: UserRole;
17
+ role: string;
22
18
  emailVerified?: Date | null;
23
19
  tokenType?: 'access' | 'refresh';
24
20
  iat?: number;
@@ -34,10 +30,12 @@ export interface JWTConfig {
34
30
  refreshTokenExpiry: string;
35
31
  algorithm: 'HS256' | 'HS384' | 'HS512';
36
32
  }
37
- export declare enum OAuthProvider {
38
- GOOGLE = "google",
39
- GITHUB = "github"
40
- }
33
+ export declare const OAUTH_PROVIDERS: {
34
+ readonly GOOGLE: "google";
35
+ readonly GITHUB: "github";
36
+ readonly KAKAO: "kakao";
37
+ };
38
+ export type OAuthProviderName = typeof OAUTH_PROVIDERS[keyof typeof OAUTH_PROVIDERS];
41
39
  export interface OAuthUserInfo {
42
40
  id: string;
43
41
  email: string;
@@ -52,17 +50,19 @@ export interface OAuthTokenResponse {
52
50
  refresh_token?: string;
53
51
  scope?: string;
54
52
  }
53
+ export interface OAuthProviderConfig {
54
+ clientId: string;
55
+ clientSecret: string;
56
+ redirectUri: string;
57
+ }
55
58
  export interface OAuthConfig {
56
- google?: {
57
- clientId: string;
58
- clientSecret: string;
59
- redirectUri: string;
60
- };
61
- github?: {
62
- clientId: string;
63
- clientSecret: string;
64
- redirectUri: string;
65
- };
59
+ providers: Record<string, OAuthProviderConfig>;
60
+ }
61
+ export interface IOAuthProviderAdapter {
62
+ readonly name: string;
63
+ getLoginUrl(config: OAuthProviderConfig, state?: string): string;
64
+ exchangeCodeForToken(config: OAuthProviderConfig, code: string): Promise<OAuthTokenResponse>;
65
+ getUserInfo(accessToken: string): Promise<OAuthUserInfo>;
66
66
  }
67
67
  export declare enum PasswordStrength {
68
68
  VERY_WEAK = "VERY_WEAK",
@@ -93,13 +93,13 @@ export declare enum TokenType {
93
93
  export interface BaseUser {
94
94
  id: string;
95
95
  email: string;
96
- name: string | null;
97
- role: UserRole;
98
- emailVerified: Date | null;
99
- isActive: boolean;
100
- image: string | null;
101
- createdAt: Date;
102
- updatedAt: Date;
96
+ name?: string | null;
97
+ role?: string;
98
+ emailVerified?: Date | null;
99
+ isActive?: boolean;
100
+ image?: string | null;
101
+ createdAt?: Date;
102
+ updatedAt?: Date;
103
103
  }
104
104
  export interface UserRepository {
105
105
  findById(id: string): Promise<BaseUser | null>;
@@ -114,7 +114,7 @@ export interface CreateUserData {
114
114
  email: string;
115
115
  password?: string | null;
116
116
  name?: string | null;
117
- role?: UserRole;
117
+ role?: string;
118
118
  emailVerified?: Date | null;
119
119
  image?: string | null;
120
120
  }
@@ -122,7 +122,7 @@ export interface UpdateUserData {
122
122
  email?: string;
123
123
  password?: string;
124
124
  name?: string | null;
125
- role?: UserRole;
125
+ role?: string;
126
126
  emailVerified?: Date | null;
127
127
  isActive?: boolean;
128
128
  image?: string | null;
@@ -130,7 +130,7 @@ export interface UpdateUserData {
130
130
  export interface OAuthAccount {
131
131
  id: string;
132
132
  userId: string;
133
- provider: OAuthProvider;
133
+ provider: string;
134
134
  providerAccountId: string;
135
135
  accessToken: string | null;
136
136
  refreshToken: string | null;
@@ -141,7 +141,7 @@ export interface OAuthAccount {
141
141
  updatedAt: Date;
142
142
  }
143
143
  export interface OAuthAccountRepository {
144
- findByProvider(provider: OAuthProvider, providerAccountId: string): Promise<OAuthAccount | null>;
144
+ findByProvider(provider: string, providerAccountId: string): Promise<OAuthAccount | null>;
145
145
  findByUserId(userId: string): Promise<OAuthAccount[]>;
146
146
  create(data: CreateOAuthAccountData): Promise<OAuthAccount>;
147
147
  update(id: string, data: UpdateOAuthAccountData): Promise<OAuthAccount>;
@@ -149,7 +149,7 @@ export interface OAuthAccountRepository {
149
149
  }
150
150
  export interface CreateOAuthAccountData {
151
151
  userId: string;
152
- provider: OAuthProvider;
152
+ provider: string;
153
153
  providerAccountId: string;
154
154
  accessToken?: string | null;
155
155
  refreshToken?: string | null;
@@ -1,13 +1,11 @@
1
1
  import {
2
- OAuthProvider,
2
+ OAUTH_PROVIDERS,
3
3
  PasswordStrength,
4
- TokenType,
5
- UserRole
6
- } from "../../chunk-6D3HHYER.js";
4
+ TokenType
5
+ } from "../../chunk-QKC73SWB.js";
7
6
  import "../../chunk-ORMEWXMH.js";
8
7
  export {
9
- OAuthProvider,
8
+ OAUTH_PROVIDERS,
10
9
  PasswordStrength,
11
- TokenType,
12
- UserRole
10
+ TokenType
13
11
  };
@@ -0,0 +1,62 @@
1
+ import {
2
+ OAuthError
3
+ } from "./chunk-AIH3F7JV.js";
4
+
5
+ // src/auth/core/oauth/providers/kakao.ts
6
+ var KakaoOAuthProvider = class {
7
+ constructor() {
8
+ this.name = "kakao";
9
+ }
10
+ getLoginUrl(config, state) {
11
+ const params = new URLSearchParams({
12
+ client_id: config.clientId,
13
+ redirect_uri: config.redirectUri,
14
+ response_type: "code",
15
+ scope: "profile_nickname profile_image account_email"
16
+ });
17
+ if (state) {
18
+ params.set("state", state);
19
+ }
20
+ return `https://kauth.kakao.com/oauth/authorize?${params.toString()}`;
21
+ }
22
+ async exchangeCodeForToken(config, code) {
23
+ const response = await fetch("https://kauth.kakao.com/oauth/token", {
24
+ method: "POST",
25
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
26
+ body: new URLSearchParams({
27
+ client_id: config.clientId,
28
+ client_secret: config.clientSecret,
29
+ code,
30
+ grant_type: "authorization_code",
31
+ redirect_uri: config.redirectUri
32
+ })
33
+ });
34
+ if (!response.ok) {
35
+ const errorData = await response.text();
36
+ throw new OAuthError(`Kakao token exchange failed: ${errorData}`, "TOKEN_EXCHANGE_FAILED");
37
+ }
38
+ return response.json();
39
+ }
40
+ async getUserInfo(accessToken) {
41
+ const response = await fetch("https://kapi.kakao.com/v2/user/me", {
42
+ headers: { Authorization: `Bearer ${accessToken}` }
43
+ });
44
+ if (!response.ok) {
45
+ throw new OAuthError("Failed to get Kakao user info", "USER_INFO_FAILED");
46
+ }
47
+ const data = await response.json();
48
+ const account = data.kakao_account || {};
49
+ const profile = account.profile || {};
50
+ return {
51
+ id: data.id.toString(),
52
+ email: account.email,
53
+ name: profile.nickname || null,
54
+ image: profile.profile_image_url || null,
55
+ emailVerified: account.is_email_verified || false
56
+ };
57
+ }
58
+ };
59
+
60
+ export {
61
+ KakaoOAuthProvider
62
+ };
@@ -0,0 +1,30 @@
1
+ import {
2
+ ConfigurationError
3
+ } from "./chunk-2QH66EVQ.js";
4
+
5
+ // src/config/registry.ts
6
+ function initConfig(entries) {
7
+ if (globalThis.__withwiz_config) return;
8
+ globalThis.__withwiz_config = Object.freeze(entries);
9
+ }
10
+ var config = new Proxy({}, {
11
+ get(_target, prop, _receiver) {
12
+ const store = globalThis.__withwiz_config;
13
+ if (!store) {
14
+ throw new ConfigurationError("Config", "Not initialized. Call initConfig() first.");
15
+ }
16
+ return store[prop];
17
+ },
18
+ set() {
19
+ throw new TypeError("config is read-only");
20
+ }
21
+ });
22
+ function resetConfig() {
23
+ globalThis.__withwiz_config = void 0;
24
+ }
25
+
26
+ export {
27
+ initConfig,
28
+ config,
29
+ resetConfig
30
+ };
@@ -0,0 +1,64 @@
1
+ import {
2
+ OAuthError
3
+ } from "./chunk-AIH3F7JV.js";
4
+
5
+ // src/auth/core/oauth/providers/github.ts
6
+ var GitHubOAuthProvider = class {
7
+ constructor() {
8
+ this.name = "github";
9
+ }
10
+ getLoginUrl(config, state) {
11
+ const params = new URLSearchParams({
12
+ client_id: config.clientId,
13
+ redirect_uri: config.redirectUri,
14
+ scope: "read:user user:email"
15
+ });
16
+ if (state) {
17
+ params.set("state", state);
18
+ }
19
+ return `https://github.com/login/oauth/authorize?${params.toString()}`;
20
+ }
21
+ async exchangeCodeForToken(config, code) {
22
+ const response = await fetch("https://github.com/login/oauth/access_token", {
23
+ method: "POST",
24
+ headers: {
25
+ "Content-Type": "application/json",
26
+ Accept: "application/json"
27
+ },
28
+ body: JSON.stringify({
29
+ client_id: config.clientId,
30
+ client_secret: config.clientSecret,
31
+ code,
32
+ redirect_uri: config.redirectUri
33
+ })
34
+ });
35
+ if (!response.ok) {
36
+ const errorData = await response.text();
37
+ throw new OAuthError(`GitHub token exchange failed: ${errorData}`, "TOKEN_EXCHANGE_FAILED");
38
+ }
39
+ return response.json();
40
+ }
41
+ async getUserInfo(accessToken) {
42
+ const response = await fetch("https://api.github.com/user", {
43
+ headers: {
44
+ Authorization: `Bearer ${accessToken}`,
45
+ "User-Agent": "Auth-Module"
46
+ }
47
+ });
48
+ if (!response.ok) {
49
+ throw new OAuthError("Failed to get GitHub user info", "USER_INFO_FAILED");
50
+ }
51
+ const data = await response.json();
52
+ return {
53
+ id: data.id.toString(),
54
+ email: data.email,
55
+ name: data.name || null,
56
+ image: data.avatar_url || null,
57
+ emailVerified: !!data.email
58
+ };
59
+ }
60
+ };
61
+
62
+ export {
63
+ GitHubOAuthProvider
64
+ };
@@ -0,0 +1,92 @@
1
+ import {
2
+ KakaoOAuthProvider
3
+ } from "./chunk-2QQNL4ND.js";
4
+ import {
5
+ GitHubOAuthProvider
6
+ } from "./chunk-GBLNXNEH.js";
7
+ import {
8
+ GoogleOAuthProvider
9
+ } from "./chunk-RVL5ROWQ.js";
10
+ import {
11
+ OAuthError
12
+ } from "./chunk-AIH3F7JV.js";
13
+
14
+ // src/auth/core/oauth/index.ts
15
+ var OAuthManager = class {
16
+ constructor(config, logger) {
17
+ this.providers = /* @__PURE__ */ new Map();
18
+ this.config = config;
19
+ this.logger = logger;
20
+ this.registerProvider(new GoogleOAuthProvider());
21
+ this.registerProvider(new GitHubOAuthProvider());
22
+ this.registerProvider(new KakaoOAuthProvider());
23
+ }
24
+ /**
25
+ * 프로바이더 어댑터 등록
26
+ */
27
+ registerProvider(provider) {
28
+ this.providers.set(provider.name, provider);
29
+ this.logger.debug(`OAuth provider registered: ${provider.name}`);
30
+ }
31
+ /**
32
+ * OAuth 로그인 URL 생성
33
+ */
34
+ getLoginUrl(providerName, state) {
35
+ const provider = this.getProvider(providerName);
36
+ const config = this.getProviderConfig(providerName);
37
+ return provider.getLoginUrl(config, state);
38
+ }
39
+ /**
40
+ * 인증 코드를 액세스 토큰으로 교환
41
+ */
42
+ async exchangeCodeForToken(providerName, code) {
43
+ const provider = this.getProvider(providerName);
44
+ const config = this.getProviderConfig(providerName);
45
+ try {
46
+ const tokenResponse = await provider.exchangeCodeForToken(config, code);
47
+ this.logger.debug(`${providerName} token exchange successful`);
48
+ return tokenResponse.access_token;
49
+ } catch (error) {
50
+ this.logger.error(`${providerName} token exchange error`, { error: error.message });
51
+ throw error instanceof OAuthError ? error : new OAuthError(`${providerName} token exchange failed`, "TOKEN_EXCHANGE_FAILED");
52
+ }
53
+ }
54
+ /**
55
+ * 사용자 정보 가져오기
56
+ */
57
+ async getUserInfo(providerName, accessToken) {
58
+ const provider = this.getProvider(providerName);
59
+ try {
60
+ const userInfo = await provider.getUserInfo(accessToken);
61
+ this.logger.debug(`${providerName} user info retrieved`, { userId: userInfo.id, email: userInfo.email });
62
+ return userInfo;
63
+ } catch (error) {
64
+ this.logger.error(`${providerName} user info error`, { error: error.message });
65
+ throw error instanceof OAuthError ? error : new OAuthError(`Failed to retrieve ${providerName} user info`, "USER_INFO_FAILED");
66
+ }
67
+ }
68
+ /**
69
+ * 프로바이더 어댑터 조회
70
+ */
71
+ getProvider(name) {
72
+ const provider = this.providers.get(name);
73
+ if (!provider) {
74
+ throw new OAuthError(`Unsupported OAuth provider: ${name}`, "UNSUPPORTED_PROVIDER");
75
+ }
76
+ return provider;
77
+ }
78
+ /**
79
+ * 프로바이더 설정 조회
80
+ */
81
+ getProviderConfig(providerName) {
82
+ const config = this.config.providers[providerName];
83
+ if (!config) {
84
+ throw new OAuthError(`${providerName} OAuth not configured`, `${providerName.toUpperCase()}_NOT_CONFIGURED`);
85
+ }
86
+ return config;
87
+ }
88
+ };
89
+
90
+ export {
91
+ OAuthManager
92
+ };
@@ -18,6 +18,7 @@ function getDefaultOptions() {
18
18
  };
19
19
  }
20
20
  function setTokenCookies(response, tokenPair, options = {}) {
21
+ var _a;
21
22
  const opts = __spreadValues(__spreadValues({}, getDefaultOptions()), options);
22
23
  response.cookies.set("access_token", tokenPair.accessToken, {
23
24
  httpOnly: true,
@@ -30,12 +31,13 @@ function setTokenCookies(response, tokenPair, options = {}) {
30
31
  httpOnly: true,
31
32
  secure: opts.secure,
32
33
  sameSite: opts.sameSite,
33
- path: "/api/auth",
34
+ path: (_a = opts.refreshTokenPath) != null ? _a : "/api/auth",
34
35
  maxAge: 7 * 24 * 60 * 60
35
36
  });
36
37
  return response;
37
38
  }
38
39
  function clearTokenCookies(response, options = {}) {
40
+ var _a;
39
41
  const opts = __spreadValues(__spreadValues({}, getDefaultOptions()), options);
40
42
  response.cookies.set("access_token", "", {
41
43
  httpOnly: true,
@@ -48,7 +50,7 @@ function clearTokenCookies(response, options = {}) {
48
50
  httpOnly: true,
49
51
  secure: opts.secure,
50
52
  sameSite: opts.sameSite,
51
- path: "/api/auth",
53
+ path: (_a = opts.refreshTokenPath) != null ? _a : "/api/auth",
52
54
  maxAge: 0
53
55
  });
54
56
  return response;
@@ -1,3 +1,6 @@
1
+ import {
2
+ initRequestMiddleware
3
+ } from "./chunk-62Q7DN5G.js";
1
4
  import {
2
5
  MiddlewareChain
3
6
  } from "./chunk-FPESPW6P.js";
@@ -14,16 +17,13 @@ import {
14
17
  adminMiddleware,
15
18
  authMiddleware,
16
19
  optionalAuthMiddleware
17
- } from "./chunk-J5AISIJS.js";
20
+ } from "./chunk-ZBXSEQ6W.js";
18
21
  import {
19
22
  corsMiddleware
20
23
  } from "./chunk-KGHWGLED.js";
21
24
  import {
22
25
  errorHandlerMiddleware
23
26
  } from "./chunk-3YUKCYHI.js";
24
- import {
25
- initRequestMiddleware
26
- } from "./chunk-62Q7DN5G.js";
27
27
 
28
28
  // src/middleware/wrappers.ts
29
29
  function withPublicApi(handler) {
@@ -1,14 +1,9 @@
1
1
  // src/auth/types/index.ts
2
- var UserRole = /* @__PURE__ */ ((UserRole2) => {
3
- UserRole2["USER"] = "USER";
4
- UserRole2["ADMIN"] = "ADMIN";
5
- return UserRole2;
6
- })(UserRole || {});
7
- var OAuthProvider = /* @__PURE__ */ ((OAuthProvider2) => {
8
- OAuthProvider2["GOOGLE"] = "google";
9
- OAuthProvider2["GITHUB"] = "github";
10
- return OAuthProvider2;
11
- })(OAuthProvider || {});
2
+ var OAUTH_PROVIDERS = {
3
+ GOOGLE: "google",
4
+ GITHUB: "github",
5
+ KAKAO: "kakao"
6
+ };
12
7
  var PasswordStrength = /* @__PURE__ */ ((PasswordStrength2) => {
13
8
  PasswordStrength2["VERY_WEAK"] = "VERY_WEAK";
14
9
  PasswordStrength2["WEAK"] = "WEAK";
@@ -25,8 +20,7 @@ var TokenType = /* @__PURE__ */ ((TokenType2) => {
25
20
  })(TokenType || {});
26
21
 
27
22
  export {
28
- UserRole,
29
- OAuthProvider,
23
+ OAUTH_PROVIDERS,
30
24
  PasswordStrength,
31
25
  TokenType
32
26
  };
@@ -0,0 +1,62 @@
1
+ import {
2
+ OAuthError
3
+ } from "./chunk-AIH3F7JV.js";
4
+
5
+ // src/auth/core/oauth/providers/google.ts
6
+ var GoogleOAuthProvider = class {
7
+ constructor() {
8
+ this.name = "google";
9
+ }
10
+ getLoginUrl(config, state) {
11
+ const params = new URLSearchParams({
12
+ client_id: config.clientId,
13
+ redirect_uri: config.redirectUri,
14
+ response_type: "code",
15
+ scope: "openid email profile",
16
+ access_type: "offline",
17
+ prompt: "select_account consent"
18
+ });
19
+ if (state) {
20
+ params.set("state", state);
21
+ }
22
+ return `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
23
+ }
24
+ async exchangeCodeForToken(config, code) {
25
+ const response = await fetch("https://oauth2.googleapis.com/token", {
26
+ method: "POST",
27
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
28
+ body: new URLSearchParams({
29
+ client_id: config.clientId,
30
+ client_secret: config.clientSecret,
31
+ code,
32
+ grant_type: "authorization_code",
33
+ redirect_uri: config.redirectUri
34
+ })
35
+ });
36
+ if (!response.ok) {
37
+ const errorData = await response.text();
38
+ throw new OAuthError(`Google token exchange failed: ${errorData}`, "TOKEN_EXCHANGE_FAILED");
39
+ }
40
+ return response.json();
41
+ }
42
+ async getUserInfo(accessToken) {
43
+ const response = await fetch("https://www.googleapis.com/oauth2/v2/userinfo", {
44
+ headers: { Authorization: `Bearer ${accessToken}` }
45
+ });
46
+ if (!response.ok) {
47
+ throw new OAuthError("Failed to get Google user info", "USER_INFO_FAILED");
48
+ }
49
+ const data = await response.json();
50
+ return {
51
+ id: data.id,
52
+ email: data.email,
53
+ name: data.name || null,
54
+ image: data.picture || null,
55
+ emailVerified: data.verified_email || false
56
+ };
57
+ }
58
+ };
59
+
60
+ export {
61
+ GoogleOAuthProvider
62
+ };
File without changes
@@ -72,7 +72,7 @@ function initializeAuthMiddleware() {
72
72
  return jwtManager !== null;
73
73
  }
74
74
  var authMiddleware = async (context, next) => {
75
- var _a, _b, _c, _d;
75
+ var _a, _b, _c, _d, _e;
76
76
  try {
77
77
  const jwtManager = getJWTManager();
78
78
  if (!jwtManager) {
@@ -111,13 +111,13 @@ var authMiddleware = async (context, next) => {
111
111
  email: (_c = payload.email) != null ? _c : "",
112
112
  name: void 0,
113
113
  // 필요시 DB에서 조회
114
- role: payload.role === "ADMIN" ? "ADMIN" : "USER"
114
+ role: (_d = payload.role) != null ? _d : "USER"
115
115
  };
116
116
  } catch (error) {
117
117
  if (error instanceof AppError) {
118
118
  throw error;
119
119
  }
120
- if (error.code === "TOKEN_EXPIRED" || ((_d = error.message) == null ? void 0 : _d.includes("expired"))) {
120
+ if (error.code === "TOKEN_EXPIRED" || ((_e = error.message) == null ? void 0 : _e.includes("expired"))) {
121
121
  throw new AppError(ERROR_CODES.TOKEN_EXPIRED.code, error.message);
122
122
  }
123
123
  throw new AppError(
@@ -128,7 +128,7 @@ var authMiddleware = async (context, next) => {
128
128
  return await next();
129
129
  };
130
130
  var optionalAuthMiddleware = async (context, next) => {
131
- var _a, _b, _c;
131
+ var _a, _b, _c, _d;
132
132
  try {
133
133
  const jwtManager = getJWTManager();
134
134
  if (jwtManager) {
@@ -149,7 +149,7 @@ var optionalAuthMiddleware = async (context, next) => {
149
149
  id: payload.userId,
150
150
  email: (_c = payload.email) != null ? _c : "",
151
151
  name: void 0,
152
- role: payload.role === "ADMIN" ? "ADMIN" : "USER"
152
+ role: (_d = payload.role) != null ? _d : "USER"
153
153
  };
154
154
  }
155
155
  }
@@ -158,20 +158,24 @@ var optionalAuthMiddleware = async (context, next) => {
158
158
  }
159
159
  return await next();
160
160
  };
161
- var adminMiddleware = async (context, next) => {
162
- if (!context.user) {
163
- throw new AppError(ERROR_CODES.UNAUTHORIZED.code);
164
- }
165
- if (context.user.role !== "ADMIN") {
166
- throw new AppError(ERROR_CODES.FORBIDDEN.code);
167
- }
168
- return await next();
169
- };
161
+ function createRoleMiddleware(...allowedRoles) {
162
+ return async (context, next) => {
163
+ if (!context.user) {
164
+ throw new AppError(ERROR_CODES.UNAUTHORIZED.code);
165
+ }
166
+ if (!allowedRoles.includes(context.user.role)) {
167
+ throw new AppError(ERROR_CODES.FORBIDDEN.code);
168
+ }
169
+ return await next();
170
+ };
171
+ }
172
+ var adminMiddleware = createRoleMiddleware("ADMIN");
170
173
 
171
174
  export {
172
175
  setAccessTokenBlacklistChecker,
173
176
  initializeAuthMiddleware,
174
177
  authMiddleware,
175
178
  optionalAuthMiddleware,
179
+ createRoleMiddleware,
176
180
  adminMiddleware
177
181
  };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Unified Config Registry
3
+ *
4
+ * Single entry point for all withwiz configuration.
5
+ * Stores resolved configs in globalThis.__withwiz_config and exposes
6
+ * them via a read-only Proxy (`config`).
7
+ */
8
+ import type { ResolvedCommonConfig } from './common';
9
+ import type { ResolvedAuthConfig } from '../auth/config';
10
+ import type { ResolvedLoggerConfig } from '../logger/config';
11
+ import type { ResolvedCacheConfig } from '../cache/config';
12
+ import type { ResolvedStorageConfig } from '../storage/config';
13
+ import type { ResolvedGeolocationConfig } from '../geolocation/config';
14
+ import type { ResolvedCorsConfig } from '../middleware/cors-config';
15
+ export interface ConfigRegistry {
16
+ common: ResolvedCommonConfig;
17
+ auth: ResolvedAuthConfig;
18
+ logger: ResolvedLoggerConfig;
19
+ cache?: ResolvedCacheConfig;
20
+ storage?: ResolvedStorageConfig;
21
+ geolocation?: ResolvedGeolocationConfig;
22
+ cors?: ResolvedCorsConfig;
23
+ }
24
+ declare global {
25
+ var __withwiz_config: ConfigRegistry | undefined;
26
+ }
27
+ /**
28
+ * Initialise the unified config registry.
29
+ * Idempotent — a second call is silently ignored.
30
+ * The stored object is frozen to prevent mutation.
31
+ */
32
+ export declare function initConfig(entries: ConfigRegistry): void;
33
+ /**
34
+ * Read-only Proxy that delegates to `globalThis.__withwiz_config`.
35
+ * Throws `ConfigurationError` if accessed before `initConfig()`.
36
+ * Throws `TypeError` on any setter attempt.
37
+ */
38
+ export declare const config: ConfigRegistry;
39
+ /**
40
+ * Reset the registry to uninitialised state. For test cleanup only.
41
+ */
42
+ export declare function resetConfig(): void;
@@ -0,0 +1,12 @@
1
+ import {
2
+ config,
3
+ initConfig,
4
+ resetConfig
5
+ } from "../chunk-6PGZTY4N.js";
6
+ import "../chunk-2QH66EVQ.js";
7
+ import "../chunk-ORMEWXMH.js";
8
+ export {
9
+ config,
10
+ initConfig,
11
+ resetConfig
12
+ };