@mole-auth/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.
- package/dist/index.d.mts +556 -0
- package/dist/index.d.ts +556 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +26 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuthSaaS SDK 核心类型定义
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 用户信息
|
|
6
|
+
*/
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
name: string;
|
|
11
|
+
avatarUrl?: string | null;
|
|
12
|
+
role: string;
|
|
13
|
+
isActive: boolean;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
lastLoginAt?: string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 登录响应
|
|
19
|
+
*/
|
|
20
|
+
interface LoginResponse {
|
|
21
|
+
user: User;
|
|
22
|
+
token: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 注册参数
|
|
26
|
+
*/
|
|
27
|
+
interface RegisterParams {
|
|
28
|
+
email: string;
|
|
29
|
+
password: string;
|
|
30
|
+
name: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 登录参数
|
|
34
|
+
*/
|
|
35
|
+
interface LoginParams {
|
|
36
|
+
email: string;
|
|
37
|
+
password: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* OAuth 登录参数
|
|
41
|
+
*/
|
|
42
|
+
interface OAuthLoginParams {
|
|
43
|
+
provider: "google" | "github" | "qq" | "wechat";
|
|
44
|
+
redirectUri?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 密码重置参数
|
|
48
|
+
*/
|
|
49
|
+
interface ForgotPasswordParams {
|
|
50
|
+
email: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 重置密码参数
|
|
54
|
+
*/
|
|
55
|
+
interface ResetPasswordParams {
|
|
56
|
+
token: string;
|
|
57
|
+
newPassword: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 更新用户信息参数
|
|
61
|
+
*/
|
|
62
|
+
interface UpdateUserParams {
|
|
63
|
+
name?: string;
|
|
64
|
+
avatarUrl?: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* SDK 配置
|
|
68
|
+
*/
|
|
69
|
+
interface AuthSaaSConfig {
|
|
70
|
+
/**
|
|
71
|
+
* API 基础 URL
|
|
72
|
+
*/
|
|
73
|
+
baseURL: string;
|
|
74
|
+
/**
|
|
75
|
+
* 存储方式
|
|
76
|
+
* - 'local': localStorage
|
|
77
|
+
* - 'session': sessionStorage
|
|
78
|
+
* - 'cookie': cookie
|
|
79
|
+
* - 'memory': 内存(不持久化)
|
|
80
|
+
*/
|
|
81
|
+
storage?: "local" | "session" | "cookie" | "memory";
|
|
82
|
+
/**
|
|
83
|
+
* Token 存储的键名
|
|
84
|
+
*/
|
|
85
|
+
tokenKey?: string;
|
|
86
|
+
/**
|
|
87
|
+
* 用户信息存储的键名
|
|
88
|
+
*/
|
|
89
|
+
userKey?: string;
|
|
90
|
+
/**
|
|
91
|
+
* 是否自动刷新 token
|
|
92
|
+
*/
|
|
93
|
+
autoRefresh?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* 是否在 token 过期时自动登出
|
|
96
|
+
*/
|
|
97
|
+
autoLogout?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* 请求超时时间(毫秒)
|
|
100
|
+
*/
|
|
101
|
+
timeout?: number;
|
|
102
|
+
/**
|
|
103
|
+
* 请求拦截器
|
|
104
|
+
*/
|
|
105
|
+
requestInterceptor?: (config: RequestInit) => RequestInit;
|
|
106
|
+
/**
|
|
107
|
+
* 响应拦截器
|
|
108
|
+
*/
|
|
109
|
+
responseInterceptor?: (response: Response, config: RequestInit) => Response;
|
|
110
|
+
/**
|
|
111
|
+
* 错误拦截器
|
|
112
|
+
*/
|
|
113
|
+
errorInterceptor?: (error: Error, config: RequestInit) => void;
|
|
114
|
+
/**
|
|
115
|
+
* 认证状态变化回调
|
|
116
|
+
*/
|
|
117
|
+
onAuthChange?: (user: User | null, token: string | null) => void;
|
|
118
|
+
/**
|
|
119
|
+
* 自定义 fetch 实现
|
|
120
|
+
*/
|
|
121
|
+
fetch?: typeof fetch;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* API 错误
|
|
125
|
+
*/
|
|
126
|
+
interface AuthError extends Error {
|
|
127
|
+
code?: string;
|
|
128
|
+
statusCode?: number;
|
|
129
|
+
details?: Record<string, unknown>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 用户统计
|
|
133
|
+
*/
|
|
134
|
+
interface UserStats {
|
|
135
|
+
total: number;
|
|
136
|
+
active: number;
|
|
137
|
+
byRole: Record<string, number>;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 分页参数
|
|
141
|
+
*/
|
|
142
|
+
interface PaginationParams {
|
|
143
|
+
skip?: number;
|
|
144
|
+
limit?: number;
|
|
145
|
+
search?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 分页响应
|
|
149
|
+
*/
|
|
150
|
+
interface PaginatedResponse<T> {
|
|
151
|
+
items: T[];
|
|
152
|
+
total: number;
|
|
153
|
+
skip: number;
|
|
154
|
+
limit: number;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* OAuth2 客户端配置
|
|
158
|
+
*/
|
|
159
|
+
interface OAuth2ClientConfig {
|
|
160
|
+
/**
|
|
161
|
+
* OAuth2 客户端 ID
|
|
162
|
+
*/
|
|
163
|
+
clientId: string;
|
|
164
|
+
/**
|
|
165
|
+
* OAuth2 客户端密钥
|
|
166
|
+
*/
|
|
167
|
+
clientSecret?: string;
|
|
168
|
+
/**
|
|
169
|
+
* 授权端点 URL
|
|
170
|
+
*/
|
|
171
|
+
authorizationEndpoint: string;
|
|
172
|
+
/**
|
|
173
|
+
* 令牌端点 URL
|
|
174
|
+
*/
|
|
175
|
+
tokenEndpoint: string;
|
|
176
|
+
/**
|
|
177
|
+
* 重定向 URI
|
|
178
|
+
*/
|
|
179
|
+
redirectUri: string;
|
|
180
|
+
/**
|
|
181
|
+
* 请求的权限范围
|
|
182
|
+
*/
|
|
183
|
+
scope?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* OAuth2 令牌响应
|
|
187
|
+
*/
|
|
188
|
+
interface OAuth2TokenResponse {
|
|
189
|
+
access_token: string;
|
|
190
|
+
token_type: string;
|
|
191
|
+
expires_in: number;
|
|
192
|
+
refresh_token?: string;
|
|
193
|
+
scope?: string;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* OAuth2 授权 URL 参数
|
|
197
|
+
*/
|
|
198
|
+
interface OAuth2AuthorizationParams {
|
|
199
|
+
responseType?: "code";
|
|
200
|
+
clientId: string;
|
|
201
|
+
redirectUri: string;
|
|
202
|
+
scope?: string;
|
|
203
|
+
state?: string;
|
|
204
|
+
codeChallenge?: string;
|
|
205
|
+
codeChallengeMethod?: "plain" | "S256";
|
|
206
|
+
nonce?: string;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 令牌交换参数
|
|
210
|
+
*/
|
|
211
|
+
interface OAuth2TokenParams {
|
|
212
|
+
grantType: "authorization_code" | "refresh_token";
|
|
213
|
+
code?: string;
|
|
214
|
+
redirectUri?: string;
|
|
215
|
+
refreshToken?: string;
|
|
216
|
+
clientId: string;
|
|
217
|
+
clientSecret?: string;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* API 密钥类型
|
|
221
|
+
*/
|
|
222
|
+
type ApiKeyType = "test" | "live";
|
|
223
|
+
/**
|
|
224
|
+
* API 密钥权限范围
|
|
225
|
+
*/
|
|
226
|
+
type ApiKeyScope = "read:users" | "write:users" | "read:applications" | "write:applications" | "read:api-keys" | "write:api-keys" | "read:audit-logs" | "admin";
|
|
227
|
+
/**
|
|
228
|
+
* API 密钥
|
|
229
|
+
*/
|
|
230
|
+
interface ApiKey {
|
|
231
|
+
id: string;
|
|
232
|
+
applicationId: string;
|
|
233
|
+
name: string;
|
|
234
|
+
/** 仅显示前缀,实际密钥只在创建时返回 */
|
|
235
|
+
prefix: string;
|
|
236
|
+
type: ApiKeyType;
|
|
237
|
+
scopes: ApiKeyScope[];
|
|
238
|
+
lastUsedAt?: string | null;
|
|
239
|
+
expiresAt?: string | null;
|
|
240
|
+
isActive: boolean;
|
|
241
|
+
createdAt: string;
|
|
242
|
+
updatedAt?: string | null;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* API 密钥(创建时返回,包含完整密钥)
|
|
246
|
+
*/
|
|
247
|
+
interface ApiKeyWithPlainKey extends ApiKey {
|
|
248
|
+
/** 完整的 API 密钥,仅在创建时返回一次 */
|
|
249
|
+
key: string;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 创建 API 密钥参数
|
|
253
|
+
*/
|
|
254
|
+
interface CreateApiKeyParams {
|
|
255
|
+
/** 密钥名称 */
|
|
256
|
+
name: string;
|
|
257
|
+
/** 密钥类型:test/live */
|
|
258
|
+
type?: ApiKeyType;
|
|
259
|
+
/** 权限范围 */
|
|
260
|
+
scopes?: ApiKeyScope[];
|
|
261
|
+
/** 过期时间 */
|
|
262
|
+
expiresAt?: string;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* 更新 API 密钥参数
|
|
266
|
+
*/
|
|
267
|
+
interface UpdateApiKeyParams {
|
|
268
|
+
/** 密钥名称 */
|
|
269
|
+
name?: string;
|
|
270
|
+
/** 启用/禁用 */
|
|
271
|
+
isActive?: boolean;
|
|
272
|
+
/** 权限范围 */
|
|
273
|
+
scopes?: ApiKeyScope[];
|
|
274
|
+
/** 过期时间 */
|
|
275
|
+
expiresAt?: string;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* API 密钥列表查询参数
|
|
279
|
+
*/
|
|
280
|
+
interface ListApiKeysParams {
|
|
281
|
+
/** 状态过滤 */
|
|
282
|
+
status?: "active" | "suspended";
|
|
283
|
+
/** 类型过滤 */
|
|
284
|
+
type?: ApiKeyType;
|
|
285
|
+
/** 跳过数量 */
|
|
286
|
+
skip?: number;
|
|
287
|
+
/** 返回数量 */
|
|
288
|
+
limit?: number;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* AuthSaaS SDK - 核心 API 客户端
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
declare class AuthSaaSClient {
|
|
296
|
+
private config;
|
|
297
|
+
private storage;
|
|
298
|
+
constructor(config: AuthSaaSConfig);
|
|
299
|
+
/**
|
|
300
|
+
* 初始化认证状态
|
|
301
|
+
*/
|
|
302
|
+
private initializeAuth;
|
|
303
|
+
/**
|
|
304
|
+
* 获取请求头
|
|
305
|
+
*/
|
|
306
|
+
private getHeaders;
|
|
307
|
+
/**
|
|
308
|
+
* 执行 HTTP 请求
|
|
309
|
+
*/
|
|
310
|
+
private request;
|
|
311
|
+
/**
|
|
312
|
+
* 注册
|
|
313
|
+
*/
|
|
314
|
+
register(data: RegisterParams): Promise<LoginResponse>;
|
|
315
|
+
/**
|
|
316
|
+
* 登录
|
|
317
|
+
*/
|
|
318
|
+
login(data: LoginParams): Promise<LoginResponse>;
|
|
319
|
+
/**
|
|
320
|
+
* 登出
|
|
321
|
+
*/
|
|
322
|
+
logout(): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* 获取当前用户
|
|
325
|
+
*/
|
|
326
|
+
getCurrentUser(): Promise<User | null>;
|
|
327
|
+
/**
|
|
328
|
+
* 忘记密码
|
|
329
|
+
*/
|
|
330
|
+
forgotPassword(data: ForgotPasswordParams): Promise<{
|
|
331
|
+
message: string;
|
|
332
|
+
}>;
|
|
333
|
+
/**
|
|
334
|
+
* 重置密码
|
|
335
|
+
*/
|
|
336
|
+
resetPassword(data: ResetPasswordParams): Promise<{
|
|
337
|
+
message: string;
|
|
338
|
+
}>;
|
|
339
|
+
/**
|
|
340
|
+
* 更新用户信息
|
|
341
|
+
*/
|
|
342
|
+
updateUser(data: UpdateUserParams): Promise<User>;
|
|
343
|
+
/**
|
|
344
|
+
* 发送邮箱验证
|
|
345
|
+
*/
|
|
346
|
+
sendVerification(): Promise<{
|
|
347
|
+
message: string;
|
|
348
|
+
}>;
|
|
349
|
+
/**
|
|
350
|
+
* 验证邮箱
|
|
351
|
+
*/
|
|
352
|
+
verifyEmail(token: string): Promise<{
|
|
353
|
+
message: string;
|
|
354
|
+
}>;
|
|
355
|
+
/**
|
|
356
|
+
* OAuth 登录(对接第三方 OAuth 提供商)
|
|
357
|
+
*/
|
|
358
|
+
loginWithOAuth(provider: "google" | "github" | "qq" | "wechat"): Promise<void>;
|
|
359
|
+
/**
|
|
360
|
+
* 使用标准 OAuth2 授权码流程登录 AuthSaaS 平台
|
|
361
|
+
*
|
|
362
|
+
* 此方法用于第三方应用通过 AuthSaaS 的标准 OAuth2 接口进行登录
|
|
363
|
+
*
|
|
364
|
+
* @param config - OAuth2 客户端配置
|
|
365
|
+
*/
|
|
366
|
+
authorizeWithOAuth2(config: {
|
|
367
|
+
clientId: string;
|
|
368
|
+
redirectUri: string;
|
|
369
|
+
scope?: string;
|
|
370
|
+
state?: string;
|
|
371
|
+
codeChallenge?: string;
|
|
372
|
+
codeChallengeMethod?: "plain" | "S256";
|
|
373
|
+
}): Promise<void>;
|
|
374
|
+
/**
|
|
375
|
+
* 使用授权码换取访问令牌
|
|
376
|
+
*
|
|
377
|
+
* @param code - 授权码
|
|
378
|
+
* @param redirectUri - 重定向 URI(必须与授权请求一致)
|
|
379
|
+
* @param clientId - 客户端 ID
|
|
380
|
+
* @param clientSecret - 客户端密钥
|
|
381
|
+
*/
|
|
382
|
+
exchangeCodeForToken(params: {
|
|
383
|
+
code: string;
|
|
384
|
+
redirectUri: string;
|
|
385
|
+
clientId: string;
|
|
386
|
+
clientSecret?: string;
|
|
387
|
+
}): Promise<LoginResponse>;
|
|
388
|
+
/**
|
|
389
|
+
* 获取用户统计
|
|
390
|
+
*/
|
|
391
|
+
getUserStats(): Promise<UserStats>;
|
|
392
|
+
/**
|
|
393
|
+
* 获取应用的 API 密钥列表
|
|
394
|
+
*
|
|
395
|
+
* @param applicationId 应用 ID
|
|
396
|
+
* @param params 查询参数
|
|
397
|
+
*/
|
|
398
|
+
listApiKeys(applicationId: string, params?: ListApiKeysParams): Promise<{
|
|
399
|
+
apiKeys: ApiKey[];
|
|
400
|
+
}>;
|
|
401
|
+
/**
|
|
402
|
+
* 创建 API 密钥
|
|
403
|
+
*
|
|
404
|
+
* @param applicationId 应用 ID
|
|
405
|
+
* @param params 创建参数
|
|
406
|
+
* @returns 创建的 API 密钥(包含完整密钥,仅此一次返回)
|
|
407
|
+
*/
|
|
408
|
+
createApiKey(applicationId: string, params: CreateApiKeyParams): Promise<{
|
|
409
|
+
apiKey: ApiKeyWithPlainKey;
|
|
410
|
+
}>;
|
|
411
|
+
/**
|
|
412
|
+
* 获取单个 API 密钥详情
|
|
413
|
+
*
|
|
414
|
+
* @param applicationId 应用 ID
|
|
415
|
+
* @param keyId 密钥 ID
|
|
416
|
+
*/
|
|
417
|
+
getApiKey(applicationId: string, keyId: string): Promise<{
|
|
418
|
+
apiKey: ApiKey;
|
|
419
|
+
}>;
|
|
420
|
+
/**
|
|
421
|
+
* 更新 API 密钥
|
|
422
|
+
*
|
|
423
|
+
* @param applicationId 应用 ID
|
|
424
|
+
* @param keyId 密钥 ID
|
|
425
|
+
* @param params 更新参数
|
|
426
|
+
*/
|
|
427
|
+
updateApiKey(applicationId: string, keyId: string, params: UpdateApiKeyParams): Promise<{
|
|
428
|
+
apiKey: ApiKey;
|
|
429
|
+
}>;
|
|
430
|
+
/**
|
|
431
|
+
* 删除 API 密钥
|
|
432
|
+
*
|
|
433
|
+
* @param applicationId 应用 ID
|
|
434
|
+
* @param keyId 密钥 ID
|
|
435
|
+
*/
|
|
436
|
+
deleteApiKey(applicationId: string, keyId: string): Promise<{
|
|
437
|
+
success: boolean;
|
|
438
|
+
}>;
|
|
439
|
+
/**
|
|
440
|
+
* 验证 API 密钥
|
|
441
|
+
*
|
|
442
|
+
* @param apiKey API 密钥
|
|
443
|
+
* @returns 验证结果
|
|
444
|
+
*/
|
|
445
|
+
verifyApiKey(apiKey: string): Promise<{
|
|
446
|
+
valid: boolean;
|
|
447
|
+
apiKey?: ApiKey;
|
|
448
|
+
}>;
|
|
449
|
+
/**
|
|
450
|
+
* 存储认证信息
|
|
451
|
+
*/
|
|
452
|
+
private setAuth;
|
|
453
|
+
/**
|
|
454
|
+
* 清除认证信息
|
|
455
|
+
*/
|
|
456
|
+
private clearAuth;
|
|
457
|
+
/**
|
|
458
|
+
* 获取用户信息
|
|
459
|
+
*/
|
|
460
|
+
getUser(): Promise<User | null>;
|
|
461
|
+
/**
|
|
462
|
+
* 设置用户信息
|
|
463
|
+
*/
|
|
464
|
+
private setUser;
|
|
465
|
+
/**
|
|
466
|
+
* 获取 token
|
|
467
|
+
*/
|
|
468
|
+
getToken(): Promise<string | null>;
|
|
469
|
+
/**
|
|
470
|
+
* 检查是否已认证
|
|
471
|
+
*/
|
|
472
|
+
isAuthenticated(): Promise<boolean>;
|
|
473
|
+
/**
|
|
474
|
+
* 获取认证钩子(用于 React/Vue 等)
|
|
475
|
+
*/
|
|
476
|
+
getAuthHooks(): {
|
|
477
|
+
isAuthenticated: () => Promise<boolean>;
|
|
478
|
+
getToken: () => Promise<string | null>;
|
|
479
|
+
getUser: () => Promise<User | null>;
|
|
480
|
+
login: (data: LoginParams) => Promise<LoginResponse>;
|
|
481
|
+
logout: () => Promise<void>;
|
|
482
|
+
register: (data: RegisterParams) => Promise<LoginResponse>;
|
|
483
|
+
getCurrentUser: () => Promise<User | null>;
|
|
484
|
+
updateUser: (data: UpdateUserParams) => Promise<User>;
|
|
485
|
+
forgotPassword: (data: ForgotPasswordParams) => Promise<{
|
|
486
|
+
message: string;
|
|
487
|
+
}>;
|
|
488
|
+
resetPassword: (data: ResetPasswordParams) => Promise<{
|
|
489
|
+
message: string;
|
|
490
|
+
}>;
|
|
491
|
+
loginWithOAuth: (provider: "google" | "github" | "qq" | "wechat") => Promise<void>;
|
|
492
|
+
authorizeWithOAuth2: (config: {
|
|
493
|
+
clientId: string;
|
|
494
|
+
redirectUri: string;
|
|
495
|
+
scope?: string;
|
|
496
|
+
state?: string;
|
|
497
|
+
codeChallenge?: string;
|
|
498
|
+
codeChallengeMethod?: "plain" | "S256";
|
|
499
|
+
}) => Promise<void>;
|
|
500
|
+
exchangeCodeForToken: (params: {
|
|
501
|
+
code: string;
|
|
502
|
+
redirectUri: string;
|
|
503
|
+
clientId: string;
|
|
504
|
+
clientSecret?: string;
|
|
505
|
+
}) => Promise<LoginResponse>;
|
|
506
|
+
listApiKeys: (applicationId: string, params?: ListApiKeysParams) => Promise<{
|
|
507
|
+
apiKeys: ApiKey[];
|
|
508
|
+
}>;
|
|
509
|
+
createApiKey: (applicationId: string, params: CreateApiKeyParams) => Promise<{
|
|
510
|
+
apiKey: ApiKeyWithPlainKey;
|
|
511
|
+
}>;
|
|
512
|
+
getApiKey: (applicationId: string, keyId: string) => Promise<{
|
|
513
|
+
apiKey: ApiKey;
|
|
514
|
+
}>;
|
|
515
|
+
updateApiKey: (applicationId: string, keyId: string, params: UpdateApiKeyParams) => Promise<{
|
|
516
|
+
apiKey: ApiKey;
|
|
517
|
+
}>;
|
|
518
|
+
deleteApiKey: (applicationId: string, keyId: string) => Promise<{
|
|
519
|
+
success: boolean;
|
|
520
|
+
}>;
|
|
521
|
+
verifyApiKey: (apiKey: string) => Promise<{
|
|
522
|
+
valid: boolean;
|
|
523
|
+
apiKey?: ApiKey;
|
|
524
|
+
}>;
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* 创建 SDK 实例
|
|
529
|
+
*/
|
|
530
|
+
declare function createAuthSaaS(config: AuthSaaSConfig): AuthSaaSClient;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* 存储管理器 - 支持多种存储方式
|
|
534
|
+
*/
|
|
535
|
+
type StorageType = "local" | "session" | "cookie" | "memory";
|
|
536
|
+
/**
|
|
537
|
+
* 存储管理器
|
|
538
|
+
*/
|
|
539
|
+
declare class StorageManager {
|
|
540
|
+
private adapter;
|
|
541
|
+
constructor(type?: StorageType);
|
|
542
|
+
getItem(key: string): Promise<string | null>;
|
|
543
|
+
setItem(key: string, value: string): Promise<void>;
|
|
544
|
+
removeItem(key: string): Promise<void>;
|
|
545
|
+
clear(): Promise<void>;
|
|
546
|
+
/**
|
|
547
|
+
* 获取对象
|
|
548
|
+
*/
|
|
549
|
+
getObject<T>(key: string): Promise<T | null>;
|
|
550
|
+
/**
|
|
551
|
+
* 设置对象
|
|
552
|
+
*/
|
|
553
|
+
setObject<T>(key: string, value: T): Promise<void>;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
export { type ApiKey, type ApiKeyScope, type ApiKeyType, type ApiKeyWithPlainKey, type AuthError, AuthSaaSClient, type AuthSaaSConfig, type CreateApiKeyParams, type ForgotPasswordParams, type ListApiKeysParams, type LoginParams, type LoginResponse, type OAuth2AuthorizationParams, type OAuth2ClientConfig, type OAuth2TokenParams, type OAuth2TokenResponse, type OAuthLoginParams, type PaginatedResponse, type PaginationParams, type RegisterParams, type ResetPasswordParams, StorageManager, type UpdateApiKeyParams, type UpdateUserParams, type User, type UserStats, createAuthSaaS };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,556 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AuthSaaS SDK 核心类型定义
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 用户信息
|
|
6
|
+
*/
|
|
7
|
+
interface User {
|
|
8
|
+
id: string;
|
|
9
|
+
email: string;
|
|
10
|
+
name: string;
|
|
11
|
+
avatarUrl?: string | null;
|
|
12
|
+
role: string;
|
|
13
|
+
isActive: boolean;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
lastLoginAt?: string | null;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* 登录响应
|
|
19
|
+
*/
|
|
20
|
+
interface LoginResponse {
|
|
21
|
+
user: User;
|
|
22
|
+
token: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 注册参数
|
|
26
|
+
*/
|
|
27
|
+
interface RegisterParams {
|
|
28
|
+
email: string;
|
|
29
|
+
password: string;
|
|
30
|
+
name: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 登录参数
|
|
34
|
+
*/
|
|
35
|
+
interface LoginParams {
|
|
36
|
+
email: string;
|
|
37
|
+
password: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* OAuth 登录参数
|
|
41
|
+
*/
|
|
42
|
+
interface OAuthLoginParams {
|
|
43
|
+
provider: "google" | "github" | "qq" | "wechat";
|
|
44
|
+
redirectUri?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* 密码重置参数
|
|
48
|
+
*/
|
|
49
|
+
interface ForgotPasswordParams {
|
|
50
|
+
email: string;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 重置密码参数
|
|
54
|
+
*/
|
|
55
|
+
interface ResetPasswordParams {
|
|
56
|
+
token: string;
|
|
57
|
+
newPassword: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 更新用户信息参数
|
|
61
|
+
*/
|
|
62
|
+
interface UpdateUserParams {
|
|
63
|
+
name?: string;
|
|
64
|
+
avatarUrl?: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* SDK 配置
|
|
68
|
+
*/
|
|
69
|
+
interface AuthSaaSConfig {
|
|
70
|
+
/**
|
|
71
|
+
* API 基础 URL
|
|
72
|
+
*/
|
|
73
|
+
baseURL: string;
|
|
74
|
+
/**
|
|
75
|
+
* 存储方式
|
|
76
|
+
* - 'local': localStorage
|
|
77
|
+
* - 'session': sessionStorage
|
|
78
|
+
* - 'cookie': cookie
|
|
79
|
+
* - 'memory': 内存(不持久化)
|
|
80
|
+
*/
|
|
81
|
+
storage?: "local" | "session" | "cookie" | "memory";
|
|
82
|
+
/**
|
|
83
|
+
* Token 存储的键名
|
|
84
|
+
*/
|
|
85
|
+
tokenKey?: string;
|
|
86
|
+
/**
|
|
87
|
+
* 用户信息存储的键名
|
|
88
|
+
*/
|
|
89
|
+
userKey?: string;
|
|
90
|
+
/**
|
|
91
|
+
* 是否自动刷新 token
|
|
92
|
+
*/
|
|
93
|
+
autoRefresh?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* 是否在 token 过期时自动登出
|
|
96
|
+
*/
|
|
97
|
+
autoLogout?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* 请求超时时间(毫秒)
|
|
100
|
+
*/
|
|
101
|
+
timeout?: number;
|
|
102
|
+
/**
|
|
103
|
+
* 请求拦截器
|
|
104
|
+
*/
|
|
105
|
+
requestInterceptor?: (config: RequestInit) => RequestInit;
|
|
106
|
+
/**
|
|
107
|
+
* 响应拦截器
|
|
108
|
+
*/
|
|
109
|
+
responseInterceptor?: (response: Response, config: RequestInit) => Response;
|
|
110
|
+
/**
|
|
111
|
+
* 错误拦截器
|
|
112
|
+
*/
|
|
113
|
+
errorInterceptor?: (error: Error, config: RequestInit) => void;
|
|
114
|
+
/**
|
|
115
|
+
* 认证状态变化回调
|
|
116
|
+
*/
|
|
117
|
+
onAuthChange?: (user: User | null, token: string | null) => void;
|
|
118
|
+
/**
|
|
119
|
+
* 自定义 fetch 实现
|
|
120
|
+
*/
|
|
121
|
+
fetch?: typeof fetch;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* API 错误
|
|
125
|
+
*/
|
|
126
|
+
interface AuthError extends Error {
|
|
127
|
+
code?: string;
|
|
128
|
+
statusCode?: number;
|
|
129
|
+
details?: Record<string, unknown>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* 用户统计
|
|
133
|
+
*/
|
|
134
|
+
interface UserStats {
|
|
135
|
+
total: number;
|
|
136
|
+
active: number;
|
|
137
|
+
byRole: Record<string, number>;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* 分页参数
|
|
141
|
+
*/
|
|
142
|
+
interface PaginationParams {
|
|
143
|
+
skip?: number;
|
|
144
|
+
limit?: number;
|
|
145
|
+
search?: string;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 分页响应
|
|
149
|
+
*/
|
|
150
|
+
interface PaginatedResponse<T> {
|
|
151
|
+
items: T[];
|
|
152
|
+
total: number;
|
|
153
|
+
skip: number;
|
|
154
|
+
limit: number;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* OAuth2 客户端配置
|
|
158
|
+
*/
|
|
159
|
+
interface OAuth2ClientConfig {
|
|
160
|
+
/**
|
|
161
|
+
* OAuth2 客户端 ID
|
|
162
|
+
*/
|
|
163
|
+
clientId: string;
|
|
164
|
+
/**
|
|
165
|
+
* OAuth2 客户端密钥
|
|
166
|
+
*/
|
|
167
|
+
clientSecret?: string;
|
|
168
|
+
/**
|
|
169
|
+
* 授权端点 URL
|
|
170
|
+
*/
|
|
171
|
+
authorizationEndpoint: string;
|
|
172
|
+
/**
|
|
173
|
+
* 令牌端点 URL
|
|
174
|
+
*/
|
|
175
|
+
tokenEndpoint: string;
|
|
176
|
+
/**
|
|
177
|
+
* 重定向 URI
|
|
178
|
+
*/
|
|
179
|
+
redirectUri: string;
|
|
180
|
+
/**
|
|
181
|
+
* 请求的权限范围
|
|
182
|
+
*/
|
|
183
|
+
scope?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* OAuth2 令牌响应
|
|
187
|
+
*/
|
|
188
|
+
interface OAuth2TokenResponse {
|
|
189
|
+
access_token: string;
|
|
190
|
+
token_type: string;
|
|
191
|
+
expires_in: number;
|
|
192
|
+
refresh_token?: string;
|
|
193
|
+
scope?: string;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* OAuth2 授权 URL 参数
|
|
197
|
+
*/
|
|
198
|
+
interface OAuth2AuthorizationParams {
|
|
199
|
+
responseType?: "code";
|
|
200
|
+
clientId: string;
|
|
201
|
+
redirectUri: string;
|
|
202
|
+
scope?: string;
|
|
203
|
+
state?: string;
|
|
204
|
+
codeChallenge?: string;
|
|
205
|
+
codeChallengeMethod?: "plain" | "S256";
|
|
206
|
+
nonce?: string;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* 令牌交换参数
|
|
210
|
+
*/
|
|
211
|
+
interface OAuth2TokenParams {
|
|
212
|
+
grantType: "authorization_code" | "refresh_token";
|
|
213
|
+
code?: string;
|
|
214
|
+
redirectUri?: string;
|
|
215
|
+
refreshToken?: string;
|
|
216
|
+
clientId: string;
|
|
217
|
+
clientSecret?: string;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* API 密钥类型
|
|
221
|
+
*/
|
|
222
|
+
type ApiKeyType = "test" | "live";
|
|
223
|
+
/**
|
|
224
|
+
* API 密钥权限范围
|
|
225
|
+
*/
|
|
226
|
+
type ApiKeyScope = "read:users" | "write:users" | "read:applications" | "write:applications" | "read:api-keys" | "write:api-keys" | "read:audit-logs" | "admin";
|
|
227
|
+
/**
|
|
228
|
+
* API 密钥
|
|
229
|
+
*/
|
|
230
|
+
interface ApiKey {
|
|
231
|
+
id: string;
|
|
232
|
+
applicationId: string;
|
|
233
|
+
name: string;
|
|
234
|
+
/** 仅显示前缀,实际密钥只在创建时返回 */
|
|
235
|
+
prefix: string;
|
|
236
|
+
type: ApiKeyType;
|
|
237
|
+
scopes: ApiKeyScope[];
|
|
238
|
+
lastUsedAt?: string | null;
|
|
239
|
+
expiresAt?: string | null;
|
|
240
|
+
isActive: boolean;
|
|
241
|
+
createdAt: string;
|
|
242
|
+
updatedAt?: string | null;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* API 密钥(创建时返回,包含完整密钥)
|
|
246
|
+
*/
|
|
247
|
+
interface ApiKeyWithPlainKey extends ApiKey {
|
|
248
|
+
/** 完整的 API 密钥,仅在创建时返回一次 */
|
|
249
|
+
key: string;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* 创建 API 密钥参数
|
|
253
|
+
*/
|
|
254
|
+
interface CreateApiKeyParams {
|
|
255
|
+
/** 密钥名称 */
|
|
256
|
+
name: string;
|
|
257
|
+
/** 密钥类型:test/live */
|
|
258
|
+
type?: ApiKeyType;
|
|
259
|
+
/** 权限范围 */
|
|
260
|
+
scopes?: ApiKeyScope[];
|
|
261
|
+
/** 过期时间 */
|
|
262
|
+
expiresAt?: string;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* 更新 API 密钥参数
|
|
266
|
+
*/
|
|
267
|
+
interface UpdateApiKeyParams {
|
|
268
|
+
/** 密钥名称 */
|
|
269
|
+
name?: string;
|
|
270
|
+
/** 启用/禁用 */
|
|
271
|
+
isActive?: boolean;
|
|
272
|
+
/** 权限范围 */
|
|
273
|
+
scopes?: ApiKeyScope[];
|
|
274
|
+
/** 过期时间 */
|
|
275
|
+
expiresAt?: string;
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* API 密钥列表查询参数
|
|
279
|
+
*/
|
|
280
|
+
interface ListApiKeysParams {
|
|
281
|
+
/** 状态过滤 */
|
|
282
|
+
status?: "active" | "suspended";
|
|
283
|
+
/** 类型过滤 */
|
|
284
|
+
type?: ApiKeyType;
|
|
285
|
+
/** 跳过数量 */
|
|
286
|
+
skip?: number;
|
|
287
|
+
/** 返回数量 */
|
|
288
|
+
limit?: number;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* AuthSaaS SDK - 核心 API 客户端
|
|
293
|
+
*/
|
|
294
|
+
|
|
295
|
+
declare class AuthSaaSClient {
|
|
296
|
+
private config;
|
|
297
|
+
private storage;
|
|
298
|
+
constructor(config: AuthSaaSConfig);
|
|
299
|
+
/**
|
|
300
|
+
* 初始化认证状态
|
|
301
|
+
*/
|
|
302
|
+
private initializeAuth;
|
|
303
|
+
/**
|
|
304
|
+
* 获取请求头
|
|
305
|
+
*/
|
|
306
|
+
private getHeaders;
|
|
307
|
+
/**
|
|
308
|
+
* 执行 HTTP 请求
|
|
309
|
+
*/
|
|
310
|
+
private request;
|
|
311
|
+
/**
|
|
312
|
+
* 注册
|
|
313
|
+
*/
|
|
314
|
+
register(data: RegisterParams): Promise<LoginResponse>;
|
|
315
|
+
/**
|
|
316
|
+
* 登录
|
|
317
|
+
*/
|
|
318
|
+
login(data: LoginParams): Promise<LoginResponse>;
|
|
319
|
+
/**
|
|
320
|
+
* 登出
|
|
321
|
+
*/
|
|
322
|
+
logout(): Promise<void>;
|
|
323
|
+
/**
|
|
324
|
+
* 获取当前用户
|
|
325
|
+
*/
|
|
326
|
+
getCurrentUser(): Promise<User | null>;
|
|
327
|
+
/**
|
|
328
|
+
* 忘记密码
|
|
329
|
+
*/
|
|
330
|
+
forgotPassword(data: ForgotPasswordParams): Promise<{
|
|
331
|
+
message: string;
|
|
332
|
+
}>;
|
|
333
|
+
/**
|
|
334
|
+
* 重置密码
|
|
335
|
+
*/
|
|
336
|
+
resetPassword(data: ResetPasswordParams): Promise<{
|
|
337
|
+
message: string;
|
|
338
|
+
}>;
|
|
339
|
+
/**
|
|
340
|
+
* 更新用户信息
|
|
341
|
+
*/
|
|
342
|
+
updateUser(data: UpdateUserParams): Promise<User>;
|
|
343
|
+
/**
|
|
344
|
+
* 发送邮箱验证
|
|
345
|
+
*/
|
|
346
|
+
sendVerification(): Promise<{
|
|
347
|
+
message: string;
|
|
348
|
+
}>;
|
|
349
|
+
/**
|
|
350
|
+
* 验证邮箱
|
|
351
|
+
*/
|
|
352
|
+
verifyEmail(token: string): Promise<{
|
|
353
|
+
message: string;
|
|
354
|
+
}>;
|
|
355
|
+
/**
|
|
356
|
+
* OAuth 登录(对接第三方 OAuth 提供商)
|
|
357
|
+
*/
|
|
358
|
+
loginWithOAuth(provider: "google" | "github" | "qq" | "wechat"): Promise<void>;
|
|
359
|
+
/**
|
|
360
|
+
* 使用标准 OAuth2 授权码流程登录 AuthSaaS 平台
|
|
361
|
+
*
|
|
362
|
+
* 此方法用于第三方应用通过 AuthSaaS 的标准 OAuth2 接口进行登录
|
|
363
|
+
*
|
|
364
|
+
* @param config - OAuth2 客户端配置
|
|
365
|
+
*/
|
|
366
|
+
authorizeWithOAuth2(config: {
|
|
367
|
+
clientId: string;
|
|
368
|
+
redirectUri: string;
|
|
369
|
+
scope?: string;
|
|
370
|
+
state?: string;
|
|
371
|
+
codeChallenge?: string;
|
|
372
|
+
codeChallengeMethod?: "plain" | "S256";
|
|
373
|
+
}): Promise<void>;
|
|
374
|
+
/**
|
|
375
|
+
* 使用授权码换取访问令牌
|
|
376
|
+
*
|
|
377
|
+
* @param code - 授权码
|
|
378
|
+
* @param redirectUri - 重定向 URI(必须与授权请求一致)
|
|
379
|
+
* @param clientId - 客户端 ID
|
|
380
|
+
* @param clientSecret - 客户端密钥
|
|
381
|
+
*/
|
|
382
|
+
exchangeCodeForToken(params: {
|
|
383
|
+
code: string;
|
|
384
|
+
redirectUri: string;
|
|
385
|
+
clientId: string;
|
|
386
|
+
clientSecret?: string;
|
|
387
|
+
}): Promise<LoginResponse>;
|
|
388
|
+
/**
|
|
389
|
+
* 获取用户统计
|
|
390
|
+
*/
|
|
391
|
+
getUserStats(): Promise<UserStats>;
|
|
392
|
+
/**
|
|
393
|
+
* 获取应用的 API 密钥列表
|
|
394
|
+
*
|
|
395
|
+
* @param applicationId 应用 ID
|
|
396
|
+
* @param params 查询参数
|
|
397
|
+
*/
|
|
398
|
+
listApiKeys(applicationId: string, params?: ListApiKeysParams): Promise<{
|
|
399
|
+
apiKeys: ApiKey[];
|
|
400
|
+
}>;
|
|
401
|
+
/**
|
|
402
|
+
* 创建 API 密钥
|
|
403
|
+
*
|
|
404
|
+
* @param applicationId 应用 ID
|
|
405
|
+
* @param params 创建参数
|
|
406
|
+
* @returns 创建的 API 密钥(包含完整密钥,仅此一次返回)
|
|
407
|
+
*/
|
|
408
|
+
createApiKey(applicationId: string, params: CreateApiKeyParams): Promise<{
|
|
409
|
+
apiKey: ApiKeyWithPlainKey;
|
|
410
|
+
}>;
|
|
411
|
+
/**
|
|
412
|
+
* 获取单个 API 密钥详情
|
|
413
|
+
*
|
|
414
|
+
* @param applicationId 应用 ID
|
|
415
|
+
* @param keyId 密钥 ID
|
|
416
|
+
*/
|
|
417
|
+
getApiKey(applicationId: string, keyId: string): Promise<{
|
|
418
|
+
apiKey: ApiKey;
|
|
419
|
+
}>;
|
|
420
|
+
/**
|
|
421
|
+
* 更新 API 密钥
|
|
422
|
+
*
|
|
423
|
+
* @param applicationId 应用 ID
|
|
424
|
+
* @param keyId 密钥 ID
|
|
425
|
+
* @param params 更新参数
|
|
426
|
+
*/
|
|
427
|
+
updateApiKey(applicationId: string, keyId: string, params: UpdateApiKeyParams): Promise<{
|
|
428
|
+
apiKey: ApiKey;
|
|
429
|
+
}>;
|
|
430
|
+
/**
|
|
431
|
+
* 删除 API 密钥
|
|
432
|
+
*
|
|
433
|
+
* @param applicationId 应用 ID
|
|
434
|
+
* @param keyId 密钥 ID
|
|
435
|
+
*/
|
|
436
|
+
deleteApiKey(applicationId: string, keyId: string): Promise<{
|
|
437
|
+
success: boolean;
|
|
438
|
+
}>;
|
|
439
|
+
/**
|
|
440
|
+
* 验证 API 密钥
|
|
441
|
+
*
|
|
442
|
+
* @param apiKey API 密钥
|
|
443
|
+
* @returns 验证结果
|
|
444
|
+
*/
|
|
445
|
+
verifyApiKey(apiKey: string): Promise<{
|
|
446
|
+
valid: boolean;
|
|
447
|
+
apiKey?: ApiKey;
|
|
448
|
+
}>;
|
|
449
|
+
/**
|
|
450
|
+
* 存储认证信息
|
|
451
|
+
*/
|
|
452
|
+
private setAuth;
|
|
453
|
+
/**
|
|
454
|
+
* 清除认证信息
|
|
455
|
+
*/
|
|
456
|
+
private clearAuth;
|
|
457
|
+
/**
|
|
458
|
+
* 获取用户信息
|
|
459
|
+
*/
|
|
460
|
+
getUser(): Promise<User | null>;
|
|
461
|
+
/**
|
|
462
|
+
* 设置用户信息
|
|
463
|
+
*/
|
|
464
|
+
private setUser;
|
|
465
|
+
/**
|
|
466
|
+
* 获取 token
|
|
467
|
+
*/
|
|
468
|
+
getToken(): Promise<string | null>;
|
|
469
|
+
/**
|
|
470
|
+
* 检查是否已认证
|
|
471
|
+
*/
|
|
472
|
+
isAuthenticated(): Promise<boolean>;
|
|
473
|
+
/**
|
|
474
|
+
* 获取认证钩子(用于 React/Vue 等)
|
|
475
|
+
*/
|
|
476
|
+
getAuthHooks(): {
|
|
477
|
+
isAuthenticated: () => Promise<boolean>;
|
|
478
|
+
getToken: () => Promise<string | null>;
|
|
479
|
+
getUser: () => Promise<User | null>;
|
|
480
|
+
login: (data: LoginParams) => Promise<LoginResponse>;
|
|
481
|
+
logout: () => Promise<void>;
|
|
482
|
+
register: (data: RegisterParams) => Promise<LoginResponse>;
|
|
483
|
+
getCurrentUser: () => Promise<User | null>;
|
|
484
|
+
updateUser: (data: UpdateUserParams) => Promise<User>;
|
|
485
|
+
forgotPassword: (data: ForgotPasswordParams) => Promise<{
|
|
486
|
+
message: string;
|
|
487
|
+
}>;
|
|
488
|
+
resetPassword: (data: ResetPasswordParams) => Promise<{
|
|
489
|
+
message: string;
|
|
490
|
+
}>;
|
|
491
|
+
loginWithOAuth: (provider: "google" | "github" | "qq" | "wechat") => Promise<void>;
|
|
492
|
+
authorizeWithOAuth2: (config: {
|
|
493
|
+
clientId: string;
|
|
494
|
+
redirectUri: string;
|
|
495
|
+
scope?: string;
|
|
496
|
+
state?: string;
|
|
497
|
+
codeChallenge?: string;
|
|
498
|
+
codeChallengeMethod?: "plain" | "S256";
|
|
499
|
+
}) => Promise<void>;
|
|
500
|
+
exchangeCodeForToken: (params: {
|
|
501
|
+
code: string;
|
|
502
|
+
redirectUri: string;
|
|
503
|
+
clientId: string;
|
|
504
|
+
clientSecret?: string;
|
|
505
|
+
}) => Promise<LoginResponse>;
|
|
506
|
+
listApiKeys: (applicationId: string, params?: ListApiKeysParams) => Promise<{
|
|
507
|
+
apiKeys: ApiKey[];
|
|
508
|
+
}>;
|
|
509
|
+
createApiKey: (applicationId: string, params: CreateApiKeyParams) => Promise<{
|
|
510
|
+
apiKey: ApiKeyWithPlainKey;
|
|
511
|
+
}>;
|
|
512
|
+
getApiKey: (applicationId: string, keyId: string) => Promise<{
|
|
513
|
+
apiKey: ApiKey;
|
|
514
|
+
}>;
|
|
515
|
+
updateApiKey: (applicationId: string, keyId: string, params: UpdateApiKeyParams) => Promise<{
|
|
516
|
+
apiKey: ApiKey;
|
|
517
|
+
}>;
|
|
518
|
+
deleteApiKey: (applicationId: string, keyId: string) => Promise<{
|
|
519
|
+
success: boolean;
|
|
520
|
+
}>;
|
|
521
|
+
verifyApiKey: (apiKey: string) => Promise<{
|
|
522
|
+
valid: boolean;
|
|
523
|
+
apiKey?: ApiKey;
|
|
524
|
+
}>;
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* 创建 SDK 实例
|
|
529
|
+
*/
|
|
530
|
+
declare function createAuthSaaS(config: AuthSaaSConfig): AuthSaaSClient;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* 存储管理器 - 支持多种存储方式
|
|
534
|
+
*/
|
|
535
|
+
type StorageType = "local" | "session" | "cookie" | "memory";
|
|
536
|
+
/**
|
|
537
|
+
* 存储管理器
|
|
538
|
+
*/
|
|
539
|
+
declare class StorageManager {
|
|
540
|
+
private adapter;
|
|
541
|
+
constructor(type?: StorageType);
|
|
542
|
+
getItem(key: string): Promise<string | null>;
|
|
543
|
+
setItem(key: string, value: string): Promise<void>;
|
|
544
|
+
removeItem(key: string): Promise<void>;
|
|
545
|
+
clear(): Promise<void>;
|
|
546
|
+
/**
|
|
547
|
+
* 获取对象
|
|
548
|
+
*/
|
|
549
|
+
getObject<T>(key: string): Promise<T | null>;
|
|
550
|
+
/**
|
|
551
|
+
* 设置对象
|
|
552
|
+
*/
|
|
553
|
+
setObject<T>(key: string, value: T): Promise<void>;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
export { type ApiKey, type ApiKeyScope, type ApiKeyType, type ApiKeyWithPlainKey, type AuthError, AuthSaaSClient, type AuthSaaSConfig, type CreateApiKeyParams, type ForgotPasswordParams, type ListApiKeysParams, type LoginParams, type LoginResponse, type OAuth2AuthorizationParams, type OAuth2ClientConfig, type OAuth2TokenParams, type OAuth2TokenResponse, type OAuthLoginParams, type PaginatedResponse, type PaginationParams, type RegisterParams, type ResetPasswordParams, StorageManager, type UpdateApiKeyParams, type UpdateUserParams, type User, type UserStats, createAuthSaaS };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';var k=Object.defineProperty,I=Object.defineProperties;var K=Object.getOwnPropertyDescriptors;var S=Object.getOwnPropertySymbols;var b=Object.prototype.hasOwnProperty,T=Object.prototype.propertyIsEnumerable;var v=(o,e,t)=>e in o?k(o,e,{enumerable:true,configurable:true,writable:true,value:t}):o[e]=t,d=(o,e)=>{for(var t in e||(e={}))b.call(e,t)&&v(o,t,e[t]);if(S)for(var t of S(e))T.call(e,t)&&v(o,t,e[t]);return o},y=(o,e)=>I(o,K(e));var r=(o,e,t)=>new Promise((s,i)=>{var n=a=>{try{h(t.next(a));}catch(c){i(c);}},g=a=>{try{h(t.throw(a));}catch(c){i(c);}},h=a=>a.done?s(a.value):Promise.resolve(a.value).then(n,g);h((t=t.apply(o,e)).next());});var w=class{getItem(e){return r(this,null,function*(){if(typeof window=="undefined")return null;try{return localStorage.getItem(e)}catch(t){return null}})}setItem(e,t){return r(this,null,function*(){if(typeof window!="undefined")try{localStorage.setItem(e,t);}catch(s){console.error("LocalStorage set error:",s);}})}removeItem(e){return r(this,null,function*(){if(typeof window!="undefined")try{localStorage.removeItem(e);}catch(t){console.error("LocalStorage remove error:",t);}})}clear(){return r(this,null,function*(){if(typeof window!="undefined")try{localStorage.clear();}catch(e){console.error("LocalStorage clear error:",e);}})}},f=class{getItem(e){return r(this,null,function*(){if(typeof window=="undefined")return null;try{return sessionStorage.getItem(e)}catch(t){return null}})}setItem(e,t){return r(this,null,function*(){if(typeof window!="undefined")try{sessionStorage.setItem(e,t);}catch(s){console.error("SessionStorage set error:",s);}})}removeItem(e){return r(this,null,function*(){if(typeof window!="undefined")try{sessionStorage.removeItem(e);}catch(t){console.error("SessionStorage remove error:",t);}})}clear(){return r(this,null,function*(){if(typeof window!="undefined")try{sessionStorage.clear();}catch(e){console.error("SessionStorage clear error:",e);}})}},P=class{constructor(e,t=false,s="lax"){this.domain=e,this.secure=t,this.sameSite=s;}getItem(e){return r(this,null,function*(){if(typeof document=="undefined")return null;try{let s=document.cookie.split("; ").find(i=>i.startsWith(`${e}=`));return s?decodeURIComponent(s.split("=")[1]):null}catch(t){return null}})}setItem(e,t){return r(this,null,function*(){if(typeof document!="undefined")try{let s=`${e}=${encodeURIComponent(t)}`;this.domain&&(s+=`; domain=${this.domain}`),this.secure&&(s+="; secure"),s+=`; samesite=${this.sameSite}`,document.cookie=s;}catch(s){console.error("Cookie set error:",s);}})}removeItem(e){return r(this,null,function*(){if(typeof document!="undefined")try{let t=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;this.domain&&(t+=`; domain=${this.domain}`),document.cookie=t;}catch(t){console.error("Cookie remove error:",t);}})}clear(){return r(this,null,function*(){if(typeof document!="undefined")try{document.cookie.split("; ").forEach(t=>{let s=t.split("=")[0];this.removeItem(s);});}catch(e){console.error("Cookie clear error:",e);}})}},A=class{constructor(){this.store=new Map;}getItem(e){return r(this,null,function*(){return this.store.get(e)||null})}setItem(e,t){return r(this,null,function*(){this.store.set(e,t);})}removeItem(e){return r(this,null,function*(){this.store.delete(e);})}clear(){return r(this,null,function*(){this.store.clear();})}},p=class{constructor(e="local"){switch(e){case "session":this.adapter=new f;break;case "cookie":this.adapter=new P;break;case "memory":this.adapter=new A;break;default:this.adapter=new w;break}}getItem(e){return r(this,null,function*(){return yield this.adapter.getItem(e)})}setItem(e,t){return r(this,null,function*(){return yield this.adapter.setItem(e,t)})}removeItem(e){return r(this,null,function*(){return yield this.adapter.removeItem(e)})}clear(){return r(this,null,function*(){return yield this.adapter.clear()})}getObject(e){return r(this,null,function*(){let t=yield this.getItem(e);if(!t)return null;try{return JSON.parse(t)}catch(s){return null}})}setObject(e,t){return r(this,null,function*(){let s=JSON.stringify(t);yield this.setItem(e,s);})}};function C(o){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t=new Uint8Array(o);if(typeof crypto!="undefined"&&crypto.getRandomValues)crypto.getRandomValues(t);else for(let i=0;i<o;i++)t[i]=Math.floor(Math.random()*256);let s="";for(let i=0;i<o;i++)s+=e[t[i]%e.length];return s}var m=class{constructor(e){var t,s;this.config={baseURL:e.baseURL,storage:e.storage||"local",tokenKey:e.tokenKey||"authsaas_token",userKey:e.userKey||"authsaas_user",autoRefresh:(t=e.autoRefresh)!=null?t:true,autoLogout:(s=e.autoLogout)!=null?s:true,timeout:e.timeout||3e4,requestInterceptor:e.requestInterceptor||(i=>i),responseInterceptor:e.responseInterceptor||(i=>i),errorInterceptor:e.errorInterceptor||(()=>{}),onAuthChange:e.onAuthChange||(()=>{}),fetch:e.fetch?e.fetch.bind(globalThis):fetch.bind(globalThis)},this.storage=new p(this.config.storage),this.initializeAuth();}initializeAuth(){return r(this,null,function*(){let e=yield this.getToken(),t=yield this.getUser();e&&t&&this.config.onAuthChange(t,e);})}getHeaders(){return r(this,arguments,function*(e={}){let t=yield this.getToken(),s=d({"Content-Type":"application/json"},t&&{Authorization:`Bearer ${t}`});return new Headers(d(d({},s),e))})}request(s){return r(this,arguments,function*(e,t={}){let i=`${this.config.baseURL}${e}`,n=y(d({},t),{headers:yield this.getHeaders(t.headers)});n=this.config.requestInterceptor(n);let g=new AbortController,h=setTimeout(()=>g.abort(),this.config.timeout);try{let a=yield this.config.fetch(i,y(d({},n),{signal:g.signal}));clearTimeout(h);let c=this.config.responseInterceptor(a,n);if(!c.ok){let u=yield c.json().catch(()=>({})),l=new Error(u.error||c.statusText||"Request failed");throw l.code=u.code||"UNKNOWN",l.statusCode=c.status,l.details=u.details,l}return yield c.json()}catch(a){clearTimeout(h);let c=a;if(c.name==="AbortError"){let u=new Error("Request timeout");throw u.code="TIMEOUT",this.config.errorInterceptor(u,n),u}throw this.config.errorInterceptor(c,n),c}})}register(e){return r(this,null,function*(){let t=yield this.request("/api/auth/register",{method:"POST",body:JSON.stringify(e)});return yield this.setAuth(t.user,t.token),t})}login(e){return r(this,null,function*(){let t=yield this.request("/api/auth/login",{method:"POST",body:JSON.stringify(e)});return yield this.setAuth(t.user,t.token),t})}logout(){return r(this,null,function*(){if(yield this.getToken())try{yield this.request("/api/auth/logout",{method:"POST"});}catch(t){console.error("Logout request failed:",t);}yield this.clearAuth();})}getCurrentUser(){return r(this,null,function*(){let e=yield this.request("/api/auth/me");return "user"in e?e.user:e})}forgotPassword(e){return r(this,null,function*(){return yield this.request("/api/auth/forgot-password",{method:"POST",body:JSON.stringify(e)})})}resetPassword(e){return r(this,null,function*(){return yield this.request("/api/auth/reset-password",{method:"POST",body:JSON.stringify(e)})})}updateUser(e){return r(this,null,function*(){let t=yield this.getUser();if(!t)throw new Error("No authenticated user");let s=yield this.request(`/api/users/${t.id}`,{method:"PATCH",body:JSON.stringify(e)});return yield this.setUser(s),s})}sendVerification(){return r(this,null,function*(){var e;return yield this.request("/api/auth/send-verification",{method:"POST",body:JSON.stringify({email:(e=yield this.getUser())==null?void 0:e.email})})})}verifyEmail(e){return r(this,null,function*(){return yield this.request("/api/auth/verify-email",{method:"POST",body:JSON.stringify({token:e})})})}loginWithOAuth(e){return r(this,null,function*(){let t=window.location.href;window.location.href=`${this.config.baseURL}/api/auth/oauth/${e}?redirect_uri=${encodeURIComponent(t)}`;})}authorizeWithOAuth2(e){return r(this,null,function*(){let s=`${this.config.baseURL.replace("/api","")}/api/auth/oauth/authorize`,i=new URLSearchParams(d(d(d(d({response_type:"code",client_id:e.clientId,redirect_uri:e.redirectUri},e.scope&&{scope:e.scope}),e.state&&{state:e.state}),e.codeChallenge&&{code_challenge:e.codeChallenge}),e.codeChallengeMethod&&{code_challenge_method:e.codeChallengeMethod})),n=e.state||C(32);yield this.storage.setItem("oauth2_state",n),yield this.storage.setItem("oauth2_redirect_uri",e.redirectUri),window.location.href=`${s}?${i.toString()}`;})}exchangeCodeForToken(e){return r(this,null,function*(){let t=this.config.baseURL.replace("/api",""),s=`${t}/api/auth/oauth/token`;yield this.storage.getItem("oauth2_state");let n=yield this.storage.getItem("oauth2_redirect_uri");yield this.storage.removeItem("oauth2_state"),yield this.storage.removeItem("oauth2_redirect_uri");let g={grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri||n||"",client_id:e.clientId};e.clientSecret&&(g.client_secret=e.clientSecret);let h=yield this.config.fetch(s,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(g).toString()});if(!h.ok){let U=yield h.json().catch(()=>({}));throw new Error(U.error_description||"\u4EE4\u724C\u4EA4\u6362\u5931\u8D25")}let a=yield h.json(),c=yield this.config.fetch(`${t}/api/auth/me`,{headers:{Authorization:`Bearer ${a.access_token}`,"Content-Type":"application/json"}});if(!c.ok)throw new Error("\u83B7\u53D6\u7528\u6237\u4FE1\u606F\u5931\u8D25");let u=yield c.json(),l="user"in u?u.user:u;return yield this.setAuth(l,a.access_token),{user:l,token:a.access_token}})}getUserStats(){return r(this,null,function*(){return (yield this.request("/api/users",{method:"POST",body:JSON.stringify({action:"stats"})})).stats})}listApiKeys(s){return r(this,arguments,function*(e,t={}){let{status:i,type:n,skip:g=0,limit:h=100}=t,a=new URLSearchParams;return i&&a.set("status",i),n&&a.set("type",n),a.set("skip",g.toString()),a.set("limit",h.toString()),yield this.request(`/api/applications/${e}/api-keys?${a.toString()}`)})}createApiKey(e,t){return r(this,null,function*(){let{name:s,type:i="test",scopes:n,expiresAt:g}=t;return yield this.request(`/api/applications/${e}/api-keys`,{method:"POST",body:JSON.stringify({name:s,type:i,scopes:n,expiresAt:g})})})}getApiKey(e,t){return r(this,null,function*(){return yield this.request(`/api/applications/${e}/api-keys/${t}`)})}updateApiKey(e,t,s){return r(this,null,function*(){return yield this.request(`/api/applications/${e}/api-keys/${t}`,{method:"PATCH",body:JSON.stringify(s)})})}deleteApiKey(e,t){return r(this,null,function*(){return yield this.request(`/api/applications/${e}/api-keys/${t}`,{method:"DELETE"})})}verifyApiKey(e){return r(this,null,function*(){try{let t=yield this.config.fetch(`${this.config.baseURL}/api/auth/verify-api-key`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return t.ok?{valid:!0,apiKey:(yield t.json()).apiKey}:{valid:!1}}catch(t){return {valid:false}}})}setAuth(e,t){return r(this,null,function*(){yield this.storage.setObject(this.config.userKey,e),yield this.storage.setItem(this.config.tokenKey,t),this.config.onAuthChange(e,t);})}clearAuth(){return r(this,null,function*(){yield this.storage.removeItem(this.config.userKey),yield this.storage.removeItem(this.config.tokenKey),this.config.onAuthChange(null,null);})}getUser(){return r(this,null,function*(){return yield this.storage.getObject(this.config.userKey)})}setUser(e){return r(this,null,function*(){yield this.storage.setObject(this.config.userKey,e),this.config.onAuthChange(e,yield this.getToken());})}getToken(){return r(this,null,function*(){return yield this.storage.getItem(this.config.tokenKey)})}isAuthenticated(){return r(this,null,function*(){let e=yield this.getToken(),t=yield this.getUser();return !!(e&&t)})}getAuthHooks(){return {isAuthenticated:()=>this.isAuthenticated(),getToken:()=>this.getToken(),getUser:()=>this.getUser(),login:e=>this.login(e),logout:()=>this.logout(),register:e=>this.register(e),getCurrentUser:()=>this.getCurrentUser(),updateUser:e=>this.updateUser(e),forgotPassword:e=>this.forgotPassword(e),resetPassword:e=>this.resetPassword(e),loginWithOAuth:e=>this.loginWithOAuth(e),authorizeWithOAuth2:e=>this.authorizeWithOAuth2(e),exchangeCodeForToken:e=>this.exchangeCodeForToken(e),listApiKeys:(e,t)=>this.listApiKeys(e,t),createApiKey:(e,t)=>this.createApiKey(e,t),getApiKey:(e,t)=>this.getApiKey(e,t),updateApiKey:(e,t,s)=>this.updateApiKey(e,t,s),deleteApiKey:(e,t)=>this.deleteApiKey(e,t),verifyApiKey:e=>this.verifyApiKey(e)}}};function R(o){return new m(o)}exports.AuthSaaSClient=m;exports.StorageManager=p;exports.createAuthSaaS=R;
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var k=Object.defineProperty,I=Object.defineProperties;var K=Object.getOwnPropertyDescriptors;var S=Object.getOwnPropertySymbols;var b=Object.prototype.hasOwnProperty,T=Object.prototype.propertyIsEnumerable;var v=(o,e,t)=>e in o?k(o,e,{enumerable:true,configurable:true,writable:true,value:t}):o[e]=t,d=(o,e)=>{for(var t in e||(e={}))b.call(e,t)&&v(o,t,e[t]);if(S)for(var t of S(e))T.call(e,t)&&v(o,t,e[t]);return o},y=(o,e)=>I(o,K(e));var r=(o,e,t)=>new Promise((s,i)=>{var n=a=>{try{h(t.next(a));}catch(c){i(c);}},g=a=>{try{h(t.throw(a));}catch(c){i(c);}},h=a=>a.done?s(a.value):Promise.resolve(a.value).then(n,g);h((t=t.apply(o,e)).next());});var w=class{getItem(e){return r(this,null,function*(){if(typeof window=="undefined")return null;try{return localStorage.getItem(e)}catch(t){return null}})}setItem(e,t){return r(this,null,function*(){if(typeof window!="undefined")try{localStorage.setItem(e,t);}catch(s){console.error("LocalStorage set error:",s);}})}removeItem(e){return r(this,null,function*(){if(typeof window!="undefined")try{localStorage.removeItem(e);}catch(t){console.error("LocalStorage remove error:",t);}})}clear(){return r(this,null,function*(){if(typeof window!="undefined")try{localStorage.clear();}catch(e){console.error("LocalStorage clear error:",e);}})}},f=class{getItem(e){return r(this,null,function*(){if(typeof window=="undefined")return null;try{return sessionStorage.getItem(e)}catch(t){return null}})}setItem(e,t){return r(this,null,function*(){if(typeof window!="undefined")try{sessionStorage.setItem(e,t);}catch(s){console.error("SessionStorage set error:",s);}})}removeItem(e){return r(this,null,function*(){if(typeof window!="undefined")try{sessionStorage.removeItem(e);}catch(t){console.error("SessionStorage remove error:",t);}})}clear(){return r(this,null,function*(){if(typeof window!="undefined")try{sessionStorage.clear();}catch(e){console.error("SessionStorage clear error:",e);}})}},P=class{constructor(e,t=false,s="lax"){this.domain=e,this.secure=t,this.sameSite=s;}getItem(e){return r(this,null,function*(){if(typeof document=="undefined")return null;try{let s=document.cookie.split("; ").find(i=>i.startsWith(`${e}=`));return s?decodeURIComponent(s.split("=")[1]):null}catch(t){return null}})}setItem(e,t){return r(this,null,function*(){if(typeof document!="undefined")try{let s=`${e}=${encodeURIComponent(t)}`;this.domain&&(s+=`; domain=${this.domain}`),this.secure&&(s+="; secure"),s+=`; samesite=${this.sameSite}`,document.cookie=s;}catch(s){console.error("Cookie set error:",s);}})}removeItem(e){return r(this,null,function*(){if(typeof document!="undefined")try{let t=`${e}=; expires=Thu, 01 Jan 1970 00:00:00 GMT`;this.domain&&(t+=`; domain=${this.domain}`),document.cookie=t;}catch(t){console.error("Cookie remove error:",t);}})}clear(){return r(this,null,function*(){if(typeof document!="undefined")try{document.cookie.split("; ").forEach(t=>{let s=t.split("=")[0];this.removeItem(s);});}catch(e){console.error("Cookie clear error:",e);}})}},A=class{constructor(){this.store=new Map;}getItem(e){return r(this,null,function*(){return this.store.get(e)||null})}setItem(e,t){return r(this,null,function*(){this.store.set(e,t);})}removeItem(e){return r(this,null,function*(){this.store.delete(e);})}clear(){return r(this,null,function*(){this.store.clear();})}},p=class{constructor(e="local"){switch(e){case "session":this.adapter=new f;break;case "cookie":this.adapter=new P;break;case "memory":this.adapter=new A;break;default:this.adapter=new w;break}}getItem(e){return r(this,null,function*(){return yield this.adapter.getItem(e)})}setItem(e,t){return r(this,null,function*(){return yield this.adapter.setItem(e,t)})}removeItem(e){return r(this,null,function*(){return yield this.adapter.removeItem(e)})}clear(){return r(this,null,function*(){return yield this.adapter.clear()})}getObject(e){return r(this,null,function*(){let t=yield this.getItem(e);if(!t)return null;try{return JSON.parse(t)}catch(s){return null}})}setObject(e,t){return r(this,null,function*(){let s=JSON.stringify(t);yield this.setItem(e,s);})}};function C(o){let e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",t=new Uint8Array(o);if(typeof crypto!="undefined"&&crypto.getRandomValues)crypto.getRandomValues(t);else for(let i=0;i<o;i++)t[i]=Math.floor(Math.random()*256);let s="";for(let i=0;i<o;i++)s+=e[t[i]%e.length];return s}var m=class{constructor(e){var t,s;this.config={baseURL:e.baseURL,storage:e.storage||"local",tokenKey:e.tokenKey||"authsaas_token",userKey:e.userKey||"authsaas_user",autoRefresh:(t=e.autoRefresh)!=null?t:true,autoLogout:(s=e.autoLogout)!=null?s:true,timeout:e.timeout||3e4,requestInterceptor:e.requestInterceptor||(i=>i),responseInterceptor:e.responseInterceptor||(i=>i),errorInterceptor:e.errorInterceptor||(()=>{}),onAuthChange:e.onAuthChange||(()=>{}),fetch:e.fetch?e.fetch.bind(globalThis):fetch.bind(globalThis)},this.storage=new p(this.config.storage),this.initializeAuth();}initializeAuth(){return r(this,null,function*(){let e=yield this.getToken(),t=yield this.getUser();e&&t&&this.config.onAuthChange(t,e);})}getHeaders(){return r(this,arguments,function*(e={}){let t=yield this.getToken(),s=d({"Content-Type":"application/json"},t&&{Authorization:`Bearer ${t}`});return new Headers(d(d({},s),e))})}request(s){return r(this,arguments,function*(e,t={}){let i=`${this.config.baseURL}${e}`,n=y(d({},t),{headers:yield this.getHeaders(t.headers)});n=this.config.requestInterceptor(n);let g=new AbortController,h=setTimeout(()=>g.abort(),this.config.timeout);try{let a=yield this.config.fetch(i,y(d({},n),{signal:g.signal}));clearTimeout(h);let c=this.config.responseInterceptor(a,n);if(!c.ok){let u=yield c.json().catch(()=>({})),l=new Error(u.error||c.statusText||"Request failed");throw l.code=u.code||"UNKNOWN",l.statusCode=c.status,l.details=u.details,l}return yield c.json()}catch(a){clearTimeout(h);let c=a;if(c.name==="AbortError"){let u=new Error("Request timeout");throw u.code="TIMEOUT",this.config.errorInterceptor(u,n),u}throw this.config.errorInterceptor(c,n),c}})}register(e){return r(this,null,function*(){let t=yield this.request("/api/auth/register",{method:"POST",body:JSON.stringify(e)});return yield this.setAuth(t.user,t.token),t})}login(e){return r(this,null,function*(){let t=yield this.request("/api/auth/login",{method:"POST",body:JSON.stringify(e)});return yield this.setAuth(t.user,t.token),t})}logout(){return r(this,null,function*(){if(yield this.getToken())try{yield this.request("/api/auth/logout",{method:"POST"});}catch(t){console.error("Logout request failed:",t);}yield this.clearAuth();})}getCurrentUser(){return r(this,null,function*(){let e=yield this.request("/api/auth/me");return "user"in e?e.user:e})}forgotPassword(e){return r(this,null,function*(){return yield this.request("/api/auth/forgot-password",{method:"POST",body:JSON.stringify(e)})})}resetPassword(e){return r(this,null,function*(){return yield this.request("/api/auth/reset-password",{method:"POST",body:JSON.stringify(e)})})}updateUser(e){return r(this,null,function*(){let t=yield this.getUser();if(!t)throw new Error("No authenticated user");let s=yield this.request(`/api/users/${t.id}`,{method:"PATCH",body:JSON.stringify(e)});return yield this.setUser(s),s})}sendVerification(){return r(this,null,function*(){var e;return yield this.request("/api/auth/send-verification",{method:"POST",body:JSON.stringify({email:(e=yield this.getUser())==null?void 0:e.email})})})}verifyEmail(e){return r(this,null,function*(){return yield this.request("/api/auth/verify-email",{method:"POST",body:JSON.stringify({token:e})})})}loginWithOAuth(e){return r(this,null,function*(){let t=window.location.href;window.location.href=`${this.config.baseURL}/api/auth/oauth/${e}?redirect_uri=${encodeURIComponent(t)}`;})}authorizeWithOAuth2(e){return r(this,null,function*(){let s=`${this.config.baseURL.replace("/api","")}/api/auth/oauth/authorize`,i=new URLSearchParams(d(d(d(d({response_type:"code",client_id:e.clientId,redirect_uri:e.redirectUri},e.scope&&{scope:e.scope}),e.state&&{state:e.state}),e.codeChallenge&&{code_challenge:e.codeChallenge}),e.codeChallengeMethod&&{code_challenge_method:e.codeChallengeMethod})),n=e.state||C(32);yield this.storage.setItem("oauth2_state",n),yield this.storage.setItem("oauth2_redirect_uri",e.redirectUri),window.location.href=`${s}?${i.toString()}`;})}exchangeCodeForToken(e){return r(this,null,function*(){let t=this.config.baseURL.replace("/api",""),s=`${t}/api/auth/oauth/token`;yield this.storage.getItem("oauth2_state");let n=yield this.storage.getItem("oauth2_redirect_uri");yield this.storage.removeItem("oauth2_state"),yield this.storage.removeItem("oauth2_redirect_uri");let g={grant_type:"authorization_code",code:e.code,redirect_uri:e.redirectUri||n||"",client_id:e.clientId};e.clientSecret&&(g.client_secret=e.clientSecret);let h=yield this.config.fetch(s,{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams(g).toString()});if(!h.ok){let U=yield h.json().catch(()=>({}));throw new Error(U.error_description||"\u4EE4\u724C\u4EA4\u6362\u5931\u8D25")}let a=yield h.json(),c=yield this.config.fetch(`${t}/api/auth/me`,{headers:{Authorization:`Bearer ${a.access_token}`,"Content-Type":"application/json"}});if(!c.ok)throw new Error("\u83B7\u53D6\u7528\u6237\u4FE1\u606F\u5931\u8D25");let u=yield c.json(),l="user"in u?u.user:u;return yield this.setAuth(l,a.access_token),{user:l,token:a.access_token}})}getUserStats(){return r(this,null,function*(){return (yield this.request("/api/users",{method:"POST",body:JSON.stringify({action:"stats"})})).stats})}listApiKeys(s){return r(this,arguments,function*(e,t={}){let{status:i,type:n,skip:g=0,limit:h=100}=t,a=new URLSearchParams;return i&&a.set("status",i),n&&a.set("type",n),a.set("skip",g.toString()),a.set("limit",h.toString()),yield this.request(`/api/applications/${e}/api-keys?${a.toString()}`)})}createApiKey(e,t){return r(this,null,function*(){let{name:s,type:i="test",scopes:n,expiresAt:g}=t;return yield this.request(`/api/applications/${e}/api-keys`,{method:"POST",body:JSON.stringify({name:s,type:i,scopes:n,expiresAt:g})})})}getApiKey(e,t){return r(this,null,function*(){return yield this.request(`/api/applications/${e}/api-keys/${t}`)})}updateApiKey(e,t,s){return r(this,null,function*(){return yield this.request(`/api/applications/${e}/api-keys/${t}`,{method:"PATCH",body:JSON.stringify(s)})})}deleteApiKey(e,t){return r(this,null,function*(){return yield this.request(`/api/applications/${e}/api-keys/${t}`,{method:"DELETE"})})}verifyApiKey(e){return r(this,null,function*(){try{let t=yield this.config.fetch(`${this.config.baseURL}/api/auth/verify-api-key`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`}});return t.ok?{valid:!0,apiKey:(yield t.json()).apiKey}:{valid:!1}}catch(t){return {valid:false}}})}setAuth(e,t){return r(this,null,function*(){yield this.storage.setObject(this.config.userKey,e),yield this.storage.setItem(this.config.tokenKey,t),this.config.onAuthChange(e,t);})}clearAuth(){return r(this,null,function*(){yield this.storage.removeItem(this.config.userKey),yield this.storage.removeItem(this.config.tokenKey),this.config.onAuthChange(null,null);})}getUser(){return r(this,null,function*(){return yield this.storage.getObject(this.config.userKey)})}setUser(e){return r(this,null,function*(){yield this.storage.setObject(this.config.userKey,e),this.config.onAuthChange(e,yield this.getToken());})}getToken(){return r(this,null,function*(){return yield this.storage.getItem(this.config.tokenKey)})}isAuthenticated(){return r(this,null,function*(){let e=yield this.getToken(),t=yield this.getUser();return !!(e&&t)})}getAuthHooks(){return {isAuthenticated:()=>this.isAuthenticated(),getToken:()=>this.getToken(),getUser:()=>this.getUser(),login:e=>this.login(e),logout:()=>this.logout(),register:e=>this.register(e),getCurrentUser:()=>this.getCurrentUser(),updateUser:e=>this.updateUser(e),forgotPassword:e=>this.forgotPassword(e),resetPassword:e=>this.resetPassword(e),loginWithOAuth:e=>this.loginWithOAuth(e),authorizeWithOAuth2:e=>this.authorizeWithOAuth2(e),exchangeCodeForToken:e=>this.exchangeCodeForToken(e),listApiKeys:(e,t)=>this.listApiKeys(e,t),createApiKey:(e,t)=>this.createApiKey(e,t),getApiKey:(e,t)=>this.getApiKey(e,t),updateApiKey:(e,t,s)=>this.updateApiKey(e,t,s),deleteApiKey:(e,t)=>this.deleteApiKey(e,t),verifyApiKey:e=>this.verifyApiKey(e)}}};function R(o){return new m(o)}export{m as AuthSaaSClient,p as StorageManager,R as createAuthSaaS};
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mole-auth/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"private": false,
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist/**/*"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
14
|
+
"build": "tsup",
|
|
15
|
+
"build:watch": "tsup --watch",
|
|
16
|
+
"clean": "rimraf dist"
|
|
17
|
+
},
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [],
|
|
22
|
+
"author": "",
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"rimraf": "^6.1.2"
|
|
25
|
+
}
|
|
26
|
+
}
|