@withwiz/toolkit 0.9.3 → 0.11.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.
- package/dist/{chunk-XDB3K74B.js → chunk-2QO7YXTF.js} +1 -1
- package/dist/{chunk-ISP4MDKW.js → chunk-5MPMPXIR.js} +1 -1
- package/dist/{chunk-KMUYO6YD.js → chunk-6E2Q27EN.js} +1 -1
- package/dist/chunk-6NFMRZWB.js +8 -0
- package/dist/{chunk-OXKVQGRH.js → chunk-7IOAGJMK.js} +13 -13
- package/dist/{chunk-ROMGYJFX.js → chunk-AWFP2KAU.js} +1 -1
- package/dist/chunk-BTNM5YSU.js +29 -0
- package/dist/chunk-CWS5RPRX.js +0 -0
- package/dist/{chunk-VQ47YRFC.js → chunk-DISEIUYD.js} +2 -2
- package/dist/{chunk-BOABYFJ7.js → chunk-DTRXWS7G.js} +22 -13
- package/dist/{chunk-NERL6VYQ.js → chunk-HNFYO5XV.js} +10 -6
- package/dist/{chunk-ZVGEGDYF.js → chunk-JRORMRVN.js} +1 -1
- package/dist/chunk-L2A6NGW7.js +21 -0
- package/dist/{chunk-CNXK3SLK.js → chunk-MJOXTFIC.js} +2 -2
- package/dist/chunk-MXWSG6ER.js +0 -0
- package/dist/chunk-NUHSUAXG.js +35 -0
- package/dist/{chunk-3P4TZM3O.js → chunk-QBXNL6QU.js} +1 -1
- package/dist/chunk-RWENSBNW.js +162 -0
- package/dist/{chunk-6SDUWMC3.js → chunk-RWN47K7J.js} +1 -1
- package/dist/chunk-TN5ZNYR2.js +0 -0
- package/dist/{chunk-N3TCQ5BF.js → chunk-TQMQ5XXG.js} +17 -2
- package/dist/chunk-XWHT53CZ.js +38 -0
- package/dist/{chunk-7S2PCYNT.js → chunk-YBVZ5UVC.js} +1 -1
- package/dist/chunk-Z4J452HD.js +24 -0
- package/dist/chunk-ZZTBIA57.js +18 -0
- package/dist/core/api-key/api-key.service.d.ts +28 -0
- package/dist/core/api-key/api-key.service.js +9 -0
- package/dist/core/api-key/index.d.ts +6 -0
- package/dist/core/api-key/index.js +28 -0
- package/dist/core/api-key/ip-whitelist.d.ts +4 -0
- package/dist/core/api-key/ip-whitelist.js +9 -0
- package/dist/core/api-key/key-generator.d.ts +6 -0
- package/dist/core/api-key/key-generator.js +11 -0
- package/dist/core/api-key/ports.d.ts +104 -0
- package/dist/core/api-key/ports.js +1 -0
- package/dist/core/api-key/types.d.ts +88 -0
- package/dist/core/api-key/types.js +1 -0
- package/dist/core/api-key/validate.d.ts +9 -0
- package/dist/core/api-key/validate.js +7 -0
- package/dist/core/auth/config.js +2 -1
- package/dist/core/auth/cookie-names.d.ts +3 -0
- package/dist/core/auth/cookie-names.js +9 -0
- package/dist/core/auth/index.js +13 -12
- package/dist/core/auth/jwt/cookie.js +3 -2
- package/dist/core/auth/jwt/index.js +3 -2
- package/dist/core/auth/oauth/index.js +7 -7
- package/dist/core/auth/oauth/providers/index.js +6 -6
- package/dist/core/auth/services/cache-token-stores.d.ts +45 -0
- package/dist/core/auth/services/cache-token-stores.js +59 -0
- package/dist/core/auth/services/index.js +7 -6
- package/dist/core/auth/services/login.service.js +3 -2
- package/dist/core/auth/services/oauth-callback.service.js +3 -2
- package/dist/core/auth/services/token-refresh.service.js +3 -2
- package/dist/core/auth/token-delivery.js +4 -3
- package/dist/core/cache/cache-factory.js +4 -4
- package/dist/core/cache/cache-invalidation.js +5 -5
- package/dist/core/cache/cache-redis.js +1 -1
- package/dist/core/cache/cache-wrapper.js +5 -5
- package/dist/core/cache/cache.js +10 -10
- package/dist/core/cache/hybrid-cache-manager.js +1 -1
- package/dist/core/cache/index.js +10 -10
- package/dist/core/cache/redis-cache-manager.js +1 -1
- package/dist/core/geolocation/index.js +7 -7
- package/dist/core/geolocation/providers/index.js +7 -7
- package/dist/core/system/environment.js +3 -2
- package/dist/core/system/health-check.js +1 -1
- package/dist/core/system/index.js +7 -6
- package/dist/initialize.js +6 -5
- package/dist/next/auth-handlers/index.js +20 -19
- package/dist/next/auth-handlers/login.handler.js +5 -4
- package/dist/next/auth-handlers/logout.handler.js +4 -3
- package/dist/next/auth-handlers/me.handler.js +5 -4
- package/dist/next/auth-handlers/oauth-authorize.handler.js +4 -4
- package/dist/next/auth-handlers/oauth-callback.handler.js +8 -7
- package/dist/next/auth-handlers/refresh.handler.js +5 -4
- package/dist/next/auth-types/handler-types.js +4 -3
- package/dist/next/auth-types/index.js +4 -3
- package/dist/next/error/error-handler.js +1 -1
- package/dist/next/error/index.js +1 -1
- package/dist/next/middleware/auth.js +6 -5
- package/dist/next/middleware/error-handler.js +1 -1
- package/dist/next/middleware/index.js +22 -21
- package/dist/next/middleware/wrappers.js +11 -10
- package/dist/next/oapi/api-key-auth.d.ts +27 -0
- package/dist/next/oapi/api-key-auth.js +14 -0
- package/dist/next/oapi/helpers.d.ts +19 -0
- package/dist/next/oapi/helpers.js +13 -0
- package/dist/next/oapi/index.d.ts +3 -0
- package/dist/next/oapi/index.js +28 -0
- package/dist/next/oapi/openapi-spec.d.ts +18 -0
- package/dist/next/oapi/openapi-spec.js +7 -0
- package/dist/next/proxy.d.ts +38 -0
- package/dist/next/proxy.js +53 -0
- package/dist/next/utils/index.js +14 -14
- package/package.json +21 -1
- package/dist/{chunk-BICSVLN7.js → chunk-NAFMJT62.js} +6 -6
- package/dist/{chunk-V3GEYUBG.js → chunk-UQ3Z3ZAF.js} +6 -6
- package/dist/{chunk-Q5RPNLET.js → chunk-VDRLJU6C.js} +6 -6
- /package/dist/{chunk-WU3V2AKE.js → chunk-WYA763JL.js} +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IApiKeyRepository, IApiKeyCacheStore, IPlanConfigProvider, IUsageTracker, ApiKeyServiceEnv } from '@withwiz/toolkit/core/api-key/ports';
|
|
2
|
+
import type { CreateApiKeyOptions, ApiKeyResult, ApiKeyValidationResult, ApiKeyInfo, ApiKeyFilters, ApiKeyListResponse, UpdateApiKeyData } from '@withwiz/toolkit/core/api-key/types';
|
|
3
|
+
export interface ApiKeyServiceDeps {
|
|
4
|
+
repo: IApiKeyRepository;
|
|
5
|
+
cache: IApiKeyCacheStore;
|
|
6
|
+
planConfig: IPlanConfigProvider;
|
|
7
|
+
usage: IUsageTracker;
|
|
8
|
+
env: ApiKeyServiceEnv;
|
|
9
|
+
}
|
|
10
|
+
export declare class ApiKeyService {
|
|
11
|
+
private readonly deps;
|
|
12
|
+
constructor(deps: ApiKeyServiceDeps);
|
|
13
|
+
private prefix;
|
|
14
|
+
private toInfo;
|
|
15
|
+
private requireOwned;
|
|
16
|
+
generateApiKey(userId: string, options: CreateApiKeyOptions, plan: string): Promise<ApiKeyResult>;
|
|
17
|
+
validateApiKey(rawKey: string): Promise<ApiKeyValidationResult>;
|
|
18
|
+
getApiKey(id: string, userId: string, isAdmin?: boolean): Promise<ApiKeyInfo>;
|
|
19
|
+
getApiKeys(filters: ApiKeyFilters, requesterId: string, isAdmin?: boolean): Promise<ApiKeyListResponse>;
|
|
20
|
+
updateApiKey(id: string, userId: string, data: UpdateApiKeyData, isAdmin?: boolean): Promise<ApiKeyInfo>;
|
|
21
|
+
deleteApiKey(id: string, userId: string, isAdmin?: boolean): Promise<void>;
|
|
22
|
+
trackUsage(apiKeyId: string, ip?: string): Promise<void>;
|
|
23
|
+
regenerateApiKey(userId: string, apiKeyId: string, plan: string, options?: {
|
|
24
|
+
name?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
keepOldKeyActive?: boolean;
|
|
27
|
+
}): Promise<ApiKeyResult>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from '@withwiz/toolkit/core/api-key/types';
|
|
2
|
+
export * from '@withwiz/toolkit/core/api-key/ports';
|
|
3
|
+
export * from '@withwiz/toolkit/core/api-key/key-generator';
|
|
4
|
+
export * from '@withwiz/toolkit/core/api-key/ip-whitelist';
|
|
5
|
+
export * from '@withwiz/toolkit/core/api-key/validate';
|
|
6
|
+
export { ApiKeyService, type ApiKeyServiceDeps } from '@withwiz/toolkit/core/api-key/api-key.service';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "../../chunk-MXWSG6ER.js";
|
|
2
|
+
import {
|
|
3
|
+
ApiKeyService
|
|
4
|
+
} from "../../chunk-RWENSBNW.js";
|
|
5
|
+
import {
|
|
6
|
+
validateApiKeyRecord
|
|
7
|
+
} from "../../chunk-BTNM5YSU.js";
|
|
8
|
+
import {
|
|
9
|
+
isIpAllowed,
|
|
10
|
+
isIpInCidr
|
|
11
|
+
} from "../../chunk-NUHSUAXG.js";
|
|
12
|
+
import {
|
|
13
|
+
generateRawKey,
|
|
14
|
+
hashKey,
|
|
15
|
+
keyPreview
|
|
16
|
+
} from "../../chunk-ZZTBIA57.js";
|
|
17
|
+
import "../../chunk-N3ETBM74.js";
|
|
18
|
+
import "../../chunk-CWS5RPRX.js";
|
|
19
|
+
import "../../chunk-TN5ZNYR2.js";
|
|
20
|
+
export {
|
|
21
|
+
ApiKeyService,
|
|
22
|
+
generateRawKey,
|
|
23
|
+
hashKey,
|
|
24
|
+
isIpAllowed,
|
|
25
|
+
isIpInCidr,
|
|
26
|
+
keyPreview,
|
|
27
|
+
validateApiKeyRecord
|
|
28
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** IPv4 CIDR 범위 포함 여부. 잘못된 입력은 false(throw 안 함). */
|
|
2
|
+
export declare function isIpInCidr(ip: string, cidr: string): boolean;
|
|
3
|
+
/** 클라이언트 IP가 화이트리스트(단일 IP 또는 CIDR)에 포함되는지. 빈/null이면 모두 허용. */
|
|
4
|
+
export declare function isIpAllowed(clientIp: string, whitelist: string[] | null): boolean;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** prefix + 32바이트 랜덤 hex. */
|
|
2
|
+
export declare function generateRawKey(prefix: string): string;
|
|
3
|
+
/** raw key의 sha256 hex (DB 저장용). */
|
|
4
|
+
export declare function hashKey(rawKey: string): string;
|
|
5
|
+
/** 키 해시 미리보기: 처음 10 + ... + 마지막 4. 14자 미만이면 원본. */
|
|
6
|
+
export declare function keyPreview(keyHash: string): string;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { ApiKeyEnvironment, ApiKeyPermission, ApiKeyFilters, ApiKeyValidationResult } from '@withwiz/toolkit/core/api-key/types';
|
|
2
|
+
export interface ApiKeyRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
userId: string;
|
|
5
|
+
name: string;
|
|
6
|
+
description: string | null;
|
|
7
|
+
key: string;
|
|
8
|
+
permissions: ApiKeyPermission[];
|
|
9
|
+
rateLimit: number;
|
|
10
|
+
endpointLimits: Record<string, number> | null;
|
|
11
|
+
environment: ApiKeyEnvironment;
|
|
12
|
+
ipWhitelist: string[];
|
|
13
|
+
isActive: boolean;
|
|
14
|
+
usageCount: number;
|
|
15
|
+
lastUsedAt: Date | null;
|
|
16
|
+
lastUsedIp: string | null;
|
|
17
|
+
expiresAt: Date | null;
|
|
18
|
+
createdAt: Date;
|
|
19
|
+
updatedAt: Date;
|
|
20
|
+
}
|
|
21
|
+
export interface ApiKeyWithUser extends ApiKeyRecord {
|
|
22
|
+
user: {
|
|
23
|
+
id: string;
|
|
24
|
+
email: string;
|
|
25
|
+
isActive: boolean;
|
|
26
|
+
plan: string;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface ApiKeyCreateInput {
|
|
30
|
+
userId: string;
|
|
31
|
+
key: string;
|
|
32
|
+
name: string;
|
|
33
|
+
description?: string | null;
|
|
34
|
+
permissions: ApiKeyPermission[];
|
|
35
|
+
rateLimit: number;
|
|
36
|
+
endpointLimits?: Record<string, number> | null;
|
|
37
|
+
environment: ApiKeyEnvironment;
|
|
38
|
+
ipWhitelist: string[];
|
|
39
|
+
expiresAt: Date;
|
|
40
|
+
}
|
|
41
|
+
export interface ApiKeyUpdateInput {
|
|
42
|
+
name?: string;
|
|
43
|
+
description?: string | null;
|
|
44
|
+
isActive?: boolean;
|
|
45
|
+
permissions?: ApiKeyPermission[];
|
|
46
|
+
ipWhitelist?: string[];
|
|
47
|
+
rateLimit?: number;
|
|
48
|
+
endpointLimits?: Record<string, number> | null;
|
|
49
|
+
}
|
|
50
|
+
export interface IApiKeyRepository {
|
|
51
|
+
create(data: ApiKeyCreateInput): Promise<ApiKeyRecord>;
|
|
52
|
+
findByHash(keyHash: string): Promise<ApiKeyWithUser | null>;
|
|
53
|
+
findById(id: string): Promise<ApiKeyRecord | null>;
|
|
54
|
+
findMany(filters: ApiKeyFilters): Promise<{
|
|
55
|
+
items: ApiKeyRecord[];
|
|
56
|
+
total: number;
|
|
57
|
+
}>;
|
|
58
|
+
countActive(userId: string): Promise<number>;
|
|
59
|
+
update(id: string, data: ApiKeyUpdateInput): Promise<ApiKeyRecord>;
|
|
60
|
+
deactivate(id: string): Promise<void>;
|
|
61
|
+
delete(id: string): Promise<void>;
|
|
62
|
+
incrementUsage(id: string, ip?: string): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
export interface IApiKeyCacheStore {
|
|
65
|
+
getValidation(keyHash: string): Promise<ApiKeyValidationResult | null>;
|
|
66
|
+
setValidation(keyHash: string, result: ApiKeyValidationResult): Promise<void>;
|
|
67
|
+
invalidate(keyHash: string): Promise<void>;
|
|
68
|
+
invalidateUser?(userId: string): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export interface IPlanConfigProvider {
|
|
71
|
+
getApiKeyLimit(plan: string): Promise<number>;
|
|
72
|
+
getRateLimit(plan: string): Promise<number>;
|
|
73
|
+
getEndpointLimit?(plan: string, action: string): Promise<number>;
|
|
74
|
+
}
|
|
75
|
+
export interface UsageCheckResult {
|
|
76
|
+
allowed: boolean;
|
|
77
|
+
reason?: 'DAILY_LIMIT' | 'MONTHLY_LIMIT';
|
|
78
|
+
current: {
|
|
79
|
+
daily: number;
|
|
80
|
+
monthly: number;
|
|
81
|
+
};
|
|
82
|
+
limit: {
|
|
83
|
+
daily: number;
|
|
84
|
+
monthly: number;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export interface UsageLogInput {
|
|
88
|
+
apiKeyId: string;
|
|
89
|
+
userId: string;
|
|
90
|
+
endpoint: string;
|
|
91
|
+
ip?: string;
|
|
92
|
+
}
|
|
93
|
+
export interface IUsageTracker {
|
|
94
|
+
canMakeApiCall(userId: string, plan: string): Promise<UsageCheckResult>;
|
|
95
|
+
/** 코어/미들웨어는 호출하지 않음 — 소비자 라우트 계층 선택 사용(optional). */
|
|
96
|
+
logUsage?(data: UsageLogInput): Promise<void>;
|
|
97
|
+
}
|
|
98
|
+
export interface ApiKeyServiceEnv {
|
|
99
|
+
prefixProd: string;
|
|
100
|
+
prefixDev: string;
|
|
101
|
+
defaultExpiryDays: number;
|
|
102
|
+
/** API키 발급/사용 불가 플랜명 목록. 예: ['FREEMIUM'] */
|
|
103
|
+
restrictedPlans: string[];
|
|
104
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../../chunk-CWS5RPRX.js";
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
export type ApiKeyPermission = 'read' | 'write' | 'delete';
|
|
2
|
+
export type ApiKeyEnvironment = 'production' | 'development';
|
|
3
|
+
export interface CreateApiKeyOptions {
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
permissions: ApiKeyPermission[];
|
|
7
|
+
environment: ApiKeyEnvironment;
|
|
8
|
+
expiresAt?: Date;
|
|
9
|
+
ipWhitelist?: string[];
|
|
10
|
+
customRateLimit?: number;
|
|
11
|
+
endpointLimits?: Record<string, number>;
|
|
12
|
+
}
|
|
13
|
+
export interface ApiKeyResult {
|
|
14
|
+
id: string;
|
|
15
|
+
key: string;
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
permissions: ApiKeyPermission[];
|
|
19
|
+
environment: ApiKeyEnvironment;
|
|
20
|
+
rateLimit: number;
|
|
21
|
+
endpointLimits?: Record<string, number>;
|
|
22
|
+
expiresAt?: Date;
|
|
23
|
+
createdAt: Date;
|
|
24
|
+
}
|
|
25
|
+
export interface ApiKeyInfo {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
keyPreview: string;
|
|
30
|
+
permissions: ApiKeyPermission[];
|
|
31
|
+
environment: ApiKeyEnvironment;
|
|
32
|
+
rateLimit: number;
|
|
33
|
+
endpointLimits?: Record<string, number>;
|
|
34
|
+
ipWhitelist: string[];
|
|
35
|
+
lastUsedAt?: Date;
|
|
36
|
+
lastUsedIp?: string;
|
|
37
|
+
usageCount: number;
|
|
38
|
+
isActive: boolean;
|
|
39
|
+
expiresAt?: Date;
|
|
40
|
+
createdAt: Date;
|
|
41
|
+
updatedAt: Date;
|
|
42
|
+
}
|
|
43
|
+
/** validate FSM이 반환하는 검증 실패 코드. */
|
|
44
|
+
export type ApiKeyValidationError = 'INVALID_API_KEY' | 'INACTIVE_API_KEY' | 'EXPIRED_API_KEY' | 'INACTIVE_USER' | 'PLAN_RESTRICTED';
|
|
45
|
+
export interface ApiKeyValidationResult {
|
|
46
|
+
valid: boolean;
|
|
47
|
+
error?: ApiKeyValidationError;
|
|
48
|
+
message?: string;
|
|
49
|
+
apiKey?: {
|
|
50
|
+
id: string;
|
|
51
|
+
userId: string;
|
|
52
|
+
permissions: ApiKeyPermission[];
|
|
53
|
+
rateLimit: number;
|
|
54
|
+
endpointLimits?: Record<string, number>;
|
|
55
|
+
ipWhitelist: string[];
|
|
56
|
+
environment: ApiKeyEnvironment;
|
|
57
|
+
expiresAt?: Date | null;
|
|
58
|
+
};
|
|
59
|
+
user?: {
|
|
60
|
+
id: string;
|
|
61
|
+
email: string;
|
|
62
|
+
plan: string;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export interface UpdateApiKeyData {
|
|
66
|
+
name?: string;
|
|
67
|
+
description?: string;
|
|
68
|
+
isActive?: boolean;
|
|
69
|
+
permissions?: ApiKeyPermission[];
|
|
70
|
+
ipWhitelist?: string[];
|
|
71
|
+
customRateLimit?: number;
|
|
72
|
+
endpointLimits?: Record<string, number>;
|
|
73
|
+
}
|
|
74
|
+
export interface ApiKeyFilters {
|
|
75
|
+
userId?: string;
|
|
76
|
+
environment?: ApiKeyEnvironment;
|
|
77
|
+
isActive?: boolean;
|
|
78
|
+
search?: string;
|
|
79
|
+
page?: number;
|
|
80
|
+
pageSize?: number;
|
|
81
|
+
}
|
|
82
|
+
export interface ApiKeyListResponse {
|
|
83
|
+
keys: ApiKeyInfo[];
|
|
84
|
+
total: number;
|
|
85
|
+
page: number;
|
|
86
|
+
pageSize: number;
|
|
87
|
+
hasMore: boolean;
|
|
88
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import "../../chunk-TN5ZNYR2.js";
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ApiKeyWithUser } from '@withwiz/toolkit/core/api-key/ports';
|
|
2
|
+
import type { ApiKeyValidationResult } from '@withwiz/toolkit/core/api-key/types';
|
|
3
|
+
/**
|
|
4
|
+
* API 키 레코드 검증 FSM(순수). 우선순위:
|
|
5
|
+
* null → 비활성키 → 만료 → 비활성사용자 → 제한플랜 → 정상.
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateApiKeyRecord(record: ApiKeyWithUser | null, opts: {
|
|
8
|
+
freemiumPlans?: string[];
|
|
9
|
+
}): ApiKeyValidationResult;
|
package/dist/core/auth/config.js
CHANGED
|
@@ -2,8 +2,9 @@ import {
|
|
|
2
2
|
getAuthConfig,
|
|
3
3
|
initializeAuth,
|
|
4
4
|
resetAuth
|
|
5
|
-
} from "../../chunk-
|
|
5
|
+
} from "../../chunk-TQMQ5XXG.js";
|
|
6
6
|
import "../../chunk-7YWUKMZD.js";
|
|
7
|
+
import "../../chunk-OVOBSYR4.js";
|
|
7
8
|
import "../../chunk-6J2EJVND.js";
|
|
8
9
|
import "../../chunk-F3R3UYBF.js";
|
|
9
10
|
import "../../chunk-N3ETBM74.js";
|
package/dist/core/auth/index.js
CHANGED
|
@@ -36,20 +36,24 @@ import {
|
|
|
36
36
|
} from "../../chunk-ILMPKSWS.js";
|
|
37
37
|
import {
|
|
38
38
|
OAuthManager
|
|
39
|
-
} from "../../chunk-
|
|
39
|
+
} from "../../chunk-UQ3Z3ZAF.js";
|
|
40
40
|
import "../../chunk-CDALZTPN.js";
|
|
41
|
+
import {
|
|
42
|
+
KakaoOAuthProvider
|
|
43
|
+
} from "../../chunk-65HVR74O.js";
|
|
44
|
+
import "../../chunk-33RIHX7O.js";
|
|
45
|
+
import "../../chunk-GSSHHVHF.js";
|
|
41
46
|
import {
|
|
42
47
|
GitHubOAuthProvider
|
|
43
48
|
} from "../../chunk-HIZ7USIF.js";
|
|
44
49
|
import {
|
|
45
50
|
GoogleOAuthProvider
|
|
46
51
|
} from "../../chunk-GF3DKZIW.js";
|
|
47
|
-
import {
|
|
48
|
-
KakaoOAuthProvider
|
|
49
|
-
} from "../../chunk-65HVR74O.js";
|
|
50
|
-
import "../../chunk-33RIHX7O.js";
|
|
51
|
-
import "../../chunk-GSSHHVHF.js";
|
|
52
52
|
import "../../chunk-JLRMET4V.js";
|
|
53
|
+
import {
|
|
54
|
+
JWTManager,
|
|
55
|
+
JWTService
|
|
56
|
+
} from "../../chunk-LWHLB2Y6.js";
|
|
53
57
|
import {
|
|
54
58
|
TokenGenerator
|
|
55
59
|
} from "../../chunk-ZZABL54F.js";
|
|
@@ -58,10 +62,6 @@ import {
|
|
|
58
62
|
PasswordStrength,
|
|
59
63
|
TokenType
|
|
60
64
|
} from "../../chunk-GH3U4WRE.js";
|
|
61
|
-
import {
|
|
62
|
-
JWTManager,
|
|
63
|
-
JWTService
|
|
64
|
-
} from "../../chunk-LWHLB2Y6.js";
|
|
65
65
|
import {
|
|
66
66
|
AUTH_ERROR_CODES,
|
|
67
67
|
AuthError,
|
|
@@ -70,12 +70,13 @@ import {
|
|
|
70
70
|
OAuthError,
|
|
71
71
|
PasswordError
|
|
72
72
|
} from "../../chunk-5GWGARXI.js";
|
|
73
|
-
import "../../chunk-
|
|
74
|
-
import "../../chunk-
|
|
73
|
+
import "../../chunk-DTRXWS7G.js";
|
|
74
|
+
import "../../chunk-TQMQ5XXG.js";
|
|
75
75
|
import "../../chunk-7YWUKMZD.js";
|
|
76
76
|
import "../../chunk-OVOBSYR4.js";
|
|
77
77
|
import "../../chunk-6J2EJVND.js";
|
|
78
78
|
import "../../chunk-F3R3UYBF.js";
|
|
79
|
+
import "../../chunk-6NFMRZWB.js";
|
|
79
80
|
import "../../chunk-N3ETBM74.js";
|
|
80
81
|
export {
|
|
81
82
|
AUTH_ERROR_CODES,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
clearTokenCookies,
|
|
3
3
|
setTokenCookies
|
|
4
|
-
} from "../../../chunk-
|
|
5
|
-
import "../../../chunk-
|
|
4
|
+
} from "../../../chunk-DTRXWS7G.js";
|
|
5
|
+
import "../../../chunk-TQMQ5XXG.js";
|
|
6
6
|
import "../../../chunk-7YWUKMZD.js";
|
|
7
7
|
import "../../../chunk-OVOBSYR4.js";
|
|
8
8
|
import "../../../chunk-6J2EJVND.js";
|
|
9
9
|
import "../../../chunk-F3R3UYBF.js";
|
|
10
|
+
import "../../../chunk-6NFMRZWB.js";
|
|
10
11
|
import "../../../chunk-N3ETBM74.js";
|
|
11
12
|
export {
|
|
12
13
|
clearTokenCookies,
|
|
@@ -6,12 +6,13 @@ import "../../../chunk-5GWGARXI.js";
|
|
|
6
6
|
import {
|
|
7
7
|
clearTokenCookies,
|
|
8
8
|
setTokenCookies
|
|
9
|
-
} from "../../../chunk-
|
|
10
|
-
import "../../../chunk-
|
|
9
|
+
} from "../../../chunk-DTRXWS7G.js";
|
|
10
|
+
import "../../../chunk-TQMQ5XXG.js";
|
|
11
11
|
import "../../../chunk-7YWUKMZD.js";
|
|
12
12
|
import "../../../chunk-OVOBSYR4.js";
|
|
13
13
|
import "../../../chunk-6J2EJVND.js";
|
|
14
14
|
import "../../../chunk-F3R3UYBF.js";
|
|
15
|
+
import "../../../chunk-6NFMRZWB.js";
|
|
15
16
|
import "../../../chunk-N3ETBM74.js";
|
|
16
17
|
export {
|
|
17
18
|
JWTManager,
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OAuthManager
|
|
3
|
-
} from "../../../chunk-
|
|
3
|
+
} from "../../../chunk-UQ3Z3ZAF.js";
|
|
4
4
|
import "../../../chunk-CDALZTPN.js";
|
|
5
|
-
import {
|
|
6
|
-
GitHubOAuthProvider
|
|
7
|
-
} from "../../../chunk-HIZ7USIF.js";
|
|
8
|
-
import {
|
|
9
|
-
GoogleOAuthProvider
|
|
10
|
-
} from "../../../chunk-GF3DKZIW.js";
|
|
11
5
|
import {
|
|
12
6
|
KakaoOAuthProvider
|
|
13
7
|
} from "../../../chunk-65HVR74O.js";
|
|
@@ -17,6 +11,12 @@ import {
|
|
|
17
11
|
import {
|
|
18
12
|
MicrosoftOAuthProvider
|
|
19
13
|
} from "../../../chunk-GSSHHVHF.js";
|
|
14
|
+
import {
|
|
15
|
+
GitHubOAuthProvider
|
|
16
|
+
} from "../../../chunk-HIZ7USIF.js";
|
|
17
|
+
import {
|
|
18
|
+
GoogleOAuthProvider
|
|
19
|
+
} from "../../../chunk-GF3DKZIW.js";
|
|
20
20
|
import {
|
|
21
21
|
OAUTH_STATE_COOKIE,
|
|
22
22
|
clearOAuthStateCookie,
|
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import "../../../../chunk-CDALZTPN.js";
|
|
2
|
-
import {
|
|
3
|
-
GitHubOAuthProvider
|
|
4
|
-
} from "../../../../chunk-HIZ7USIF.js";
|
|
5
|
-
import {
|
|
6
|
-
GoogleOAuthProvider
|
|
7
|
-
} from "../../../../chunk-GF3DKZIW.js";
|
|
8
2
|
import {
|
|
9
3
|
KakaoOAuthProvider
|
|
10
4
|
} from "../../../../chunk-65HVR74O.js";
|
|
@@ -14,6 +8,12 @@ import {
|
|
|
14
8
|
import {
|
|
15
9
|
MicrosoftOAuthProvider
|
|
16
10
|
} from "../../../../chunk-GSSHHVHF.js";
|
|
11
|
+
import {
|
|
12
|
+
GitHubOAuthProvider
|
|
13
|
+
} from "../../../../chunk-HIZ7USIF.js";
|
|
14
|
+
import {
|
|
15
|
+
GoogleOAuthProvider
|
|
16
|
+
} from "../../../../chunk-GF3DKZIW.js";
|
|
17
17
|
import "../../../../chunk-5GWGARXI.js";
|
|
18
18
|
import "../../../../chunk-N3ETBM74.js";
|
|
19
19
|
export {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IRefreshTokenStore } from '@withwiz/toolkit/core/auth/services/refresh-token-store';
|
|
2
|
+
/**
|
|
3
|
+
* store 가 요구하는 최소 cache 형태 — IUnifiedCacheManager 의 부분집합.
|
|
4
|
+
* ttl 은 초 단위. (InMemoryCacheManager/HybridCacheManager 등이 그대로 만족)
|
|
5
|
+
*/
|
|
6
|
+
export interface TokenStoreCache {
|
|
7
|
+
set<T>(key: string, value: T, ttl?: number): Promise<void>;
|
|
8
|
+
delete(key: string): Promise<void>;
|
|
9
|
+
exists(key: string): Promise<boolean>;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* next/middleware 의 IAccessTokenBlacklistChecker 와 구조적으로 호환한다
|
|
13
|
+
* (isAccessTokenRevoked). setAccessTokenBlacklistChecker(store) 로 주입 가능.
|
|
14
|
+
*/
|
|
15
|
+
export interface CacheAccessTokenBlacklist {
|
|
16
|
+
/** 이 access 토큰이 revoke 되었는지 여부. */
|
|
17
|
+
isAccessTokenRevoked(token: string): Promise<boolean>;
|
|
18
|
+
/** access 토큰 revoke — 남은 만료까지의 TTL(초). */
|
|
19
|
+
revokeAccessToken(token: string, ttlSec: number): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export interface CacheBlacklistOptions {
|
|
22
|
+
/** 키 네임스페이스 프리픽스. 기본 'revoked:at:' */
|
|
23
|
+
prefix?: string;
|
|
24
|
+
/** 토큰 → 키 식별자 변형. 기본 sha256 hex (원문 키 저장 지양). */
|
|
25
|
+
deriveId?: (token: string) => string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* access 토큰 blacklist(revoke) 를 cache 로 구현.
|
|
29
|
+
* 키: `${prefix}${sha256(token)}` = 1, TTL = 토큰 잔여 만료.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createCacheBlacklistChecker(cache: TokenStoreCache, opts?: CacheBlacklistOptions): CacheAccessTokenBlacklist;
|
|
32
|
+
export interface CacheRefreshStoreOptions {
|
|
33
|
+
/** used jti 키 프리픽스. 기본 'rt:used:' */
|
|
34
|
+
usedPrefix?: string;
|
|
35
|
+
/** family revoke 키 프리픽스. 기본 'rt:famrevoked:' */
|
|
36
|
+
familyPrefix?: string;
|
|
37
|
+
/** meta.expiresAt 이 없을 때 사용할 기본 TTL(초). 기본 30d. */
|
|
38
|
+
defaultTtlSec?: number;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* refresh 토큰 store(회전/재사용탐지/family revoke)를 cache 로 구현.
|
|
42
|
+
* 키: used=`${usedPrefix}${jti}`, family=`${familyPrefix}${familyId}`.
|
|
43
|
+
* TTL 은 meta.expiresAt 잔여시간에 정렬(없으면 defaultTtlSec).
|
|
44
|
+
*/
|
|
45
|
+
export declare function createCacheRefreshTokenStore(cache: TokenStoreCache, opts?: CacheRefreshStoreOptions): IRefreshTokenStore;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import "../../../chunk-N3ETBM74.js";
|
|
2
|
+
|
|
3
|
+
// src/core/auth/services/cache-token-stores.ts
|
|
4
|
+
import { createHash } from "crypto";
|
|
5
|
+
var sha256Hex = (value) => createHash("sha256").update(value).digest("hex");
|
|
6
|
+
var normalizeTtl = (ttlSec, fallback) => {
|
|
7
|
+
const s = Math.floor(ttlSec);
|
|
8
|
+
return s > 0 ? s : fallback;
|
|
9
|
+
};
|
|
10
|
+
function createCacheBlacklistChecker(cache, opts = {}) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const prefix = (_a = opts.prefix) != null ? _a : "revoked:at:";
|
|
13
|
+
const deriveId = (_b = opts.deriveId) != null ? _b : sha256Hex;
|
|
14
|
+
const keyFor = (token) => `${prefix}${deriveId(token)}`;
|
|
15
|
+
return {
|
|
16
|
+
async revokeAccessToken(token, ttlSec) {
|
|
17
|
+
await cache.set(keyFor(token), 1, normalizeTtl(ttlSec, 1));
|
|
18
|
+
},
|
|
19
|
+
async isAccessTokenRevoked(token) {
|
|
20
|
+
return cache.exists(keyFor(token));
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
var THIRTY_DAYS_SEC = 30 * 86400;
|
|
25
|
+
function createCacheRefreshTokenStore(cache, opts = {}) {
|
|
26
|
+
var _a, _b, _c;
|
|
27
|
+
const usedPrefix = (_a = opts.usedPrefix) != null ? _a : "rt:used:";
|
|
28
|
+
const familyPrefix = (_b = opts.familyPrefix) != null ? _b : "rt:famrevoked:";
|
|
29
|
+
const defaultTtl = (_c = opts.defaultTtlSec) != null ? _c : THIRTY_DAYS_SEC;
|
|
30
|
+
const ttlFrom = (expiresAt) => {
|
|
31
|
+
if (!expiresAt) return defaultTtl;
|
|
32
|
+
return normalizeTtl((expiresAt.getTime() - Date.now()) / 1e3, defaultTtl);
|
|
33
|
+
};
|
|
34
|
+
return {
|
|
35
|
+
async isUsed(jti) {
|
|
36
|
+
return cache.exists(`${usedPrefix}${jti}`);
|
|
37
|
+
},
|
|
38
|
+
async markUsed(jti, meta) {
|
|
39
|
+
await cache.set(`${usedPrefix}${jti}`, 1, ttlFrom(meta == null ? void 0 : meta.expiresAt));
|
|
40
|
+
},
|
|
41
|
+
async isFamilyRevoked(familyId) {
|
|
42
|
+
return cache.exists(`${familyPrefix}${familyId}`);
|
|
43
|
+
},
|
|
44
|
+
async revokeFamily(familyId) {
|
|
45
|
+
await cache.set(`${familyPrefix}${familyId}`, 1, defaultTtl);
|
|
46
|
+
},
|
|
47
|
+
async register(record) {
|
|
48
|
+
await cache.set(
|
|
49
|
+
`${usedPrefix}issued:${record.jti}`,
|
|
50
|
+
{ familyId: record.familyId, userId: record.userId },
|
|
51
|
+
ttlFrom(record.expiresAt)
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
createCacheBlacklistChecker,
|
|
58
|
+
createCacheRefreshTokenStore
|
|
59
|
+
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LoginService
|
|
3
3
|
} from "../../../chunk-TNDEYJEL.js";
|
|
4
|
+
import {
|
|
5
|
+
EmailVerificationService
|
|
6
|
+
} from "../../../chunk-VWKZMGPJ.js";
|
|
4
7
|
import {
|
|
5
8
|
OAuthCallbackService
|
|
6
9
|
} from "../../../chunk-MTZXWVW3.js";
|
|
@@ -10,22 +13,20 @@ import {
|
|
|
10
13
|
import {
|
|
11
14
|
RegisterService
|
|
12
15
|
} from "../../../chunk-Y4ME3Q5K.js";
|
|
13
|
-
import {
|
|
14
|
-
EmailVerificationService
|
|
15
|
-
} from "../../../chunk-VWKZMGPJ.js";
|
|
16
16
|
import {
|
|
17
17
|
PasswordResetService
|
|
18
18
|
} from "../../../chunk-75UDFONR.js";
|
|
19
|
+
import "../../../chunk-LWHLB2Y6.js";
|
|
19
20
|
import "../../../chunk-ZZABL54F.js";
|
|
20
21
|
import "../../../chunk-GH3U4WRE.js";
|
|
21
|
-
import "../../../chunk-LWHLB2Y6.js";
|
|
22
22
|
import "../../../chunk-5GWGARXI.js";
|
|
23
|
-
import "../../../chunk-
|
|
24
|
-
import "../../../chunk-
|
|
23
|
+
import "../../../chunk-DTRXWS7G.js";
|
|
24
|
+
import "../../../chunk-TQMQ5XXG.js";
|
|
25
25
|
import "../../../chunk-7YWUKMZD.js";
|
|
26
26
|
import "../../../chunk-OVOBSYR4.js";
|
|
27
27
|
import "../../../chunk-6J2EJVND.js";
|
|
28
28
|
import "../../../chunk-F3R3UYBF.js";
|
|
29
|
+
import "../../../chunk-6NFMRZWB.js";
|
|
29
30
|
import "../../../chunk-N3ETBM74.js";
|
|
30
31
|
export {
|
|
31
32
|
EmailVerificationService,
|
|
@@ -3,12 +3,13 @@ import {
|
|
|
3
3
|
} from "../../../chunk-TNDEYJEL.js";
|
|
4
4
|
import "../../../chunk-LWHLB2Y6.js";
|
|
5
5
|
import "../../../chunk-5GWGARXI.js";
|
|
6
|
-
import "../../../chunk-
|
|
7
|
-
import "../../../chunk-
|
|
6
|
+
import "../../../chunk-DTRXWS7G.js";
|
|
7
|
+
import "../../../chunk-TQMQ5XXG.js";
|
|
8
8
|
import "../../../chunk-7YWUKMZD.js";
|
|
9
9
|
import "../../../chunk-OVOBSYR4.js";
|
|
10
10
|
import "../../../chunk-6J2EJVND.js";
|
|
11
11
|
import "../../../chunk-F3R3UYBF.js";
|
|
12
|
+
import "../../../chunk-6NFMRZWB.js";
|
|
12
13
|
import "../../../chunk-N3ETBM74.js";
|
|
13
14
|
export {
|
|
14
15
|
LoginService
|