@casfa/client 0.0.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.
- package/README.md +201 -0
- package/README.zh-CN.md +201 -0
- package/dist/api/index.d.ts +3 -0
- package/dist/api/index.js +421 -0
- package/dist/api/index.js.map +1 -0
- package/dist/index-cPO-6GxE.d.ts +338 -0
- package/dist/index.d.ts +298 -0
- package/dist/index.js +994 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +144 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +55 -0
package/README.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# @casfa/client
|
|
2
|
+
|
|
3
|
+
CASFA client library with unified authorization strategies.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @casfa/client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
A stateful client that manages the three-tier token hierarchy:
|
|
14
|
+
|
|
15
|
+
1. **User JWT** - OAuth login token, highest authority
|
|
16
|
+
2. **Delegate Token** - Re-delegation token, can issue child tokens
|
|
17
|
+
3. **Access Token** - Data access token, used for CAS operations
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createClient } from '@casfa/client';
|
|
23
|
+
|
|
24
|
+
const client = createClient({
|
|
25
|
+
baseUrl: 'https://api.casfa.example.com',
|
|
26
|
+
onAuthRequired: async () => {
|
|
27
|
+
// Handle authentication (e.g., redirect to login)
|
|
28
|
+
},
|
|
29
|
+
onTokenChange: (state) => {
|
|
30
|
+
// Persist token state
|
|
31
|
+
localStorage.setItem('casfa-tokens', JSON.stringify(state));
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// Initialize with stored tokens
|
|
36
|
+
const stored = localStorage.getItem('casfa-tokens');
|
|
37
|
+
if (stored) {
|
|
38
|
+
client.tokens.restore(JSON.parse(stored));
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
### OAuth Authentication
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// Start OAuth flow
|
|
48
|
+
const { authUrl, state, codeVerifier } = await client.oauth.startAuth({
|
|
49
|
+
redirectUri: 'https://myapp.com/callback',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Handle callback
|
|
53
|
+
const tokens = await client.oauth.handleCallback({
|
|
54
|
+
code: authCode,
|
|
55
|
+
codeVerifier,
|
|
56
|
+
redirectUri: 'https://myapp.com/callback',
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Token Management
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// Check token status
|
|
64
|
+
const hasValidTokens = client.tokens.hasValidTokens();
|
|
65
|
+
const userToken = client.tokens.getUserToken();
|
|
66
|
+
const delegateToken = client.tokens.getDelegateToken();
|
|
67
|
+
const accessToken = client.tokens.getAccessToken();
|
|
68
|
+
|
|
69
|
+
// Refresh tokens
|
|
70
|
+
await client.tokens.refresh();
|
|
71
|
+
|
|
72
|
+
// Clear all tokens (logout)
|
|
73
|
+
client.tokens.clear();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Depot Operations
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// List depots
|
|
80
|
+
const depots = await client.depots.list();
|
|
81
|
+
|
|
82
|
+
// Create depot
|
|
83
|
+
const depot = await client.depots.create({
|
|
84
|
+
name: 'my-depot',
|
|
85
|
+
description: 'My storage depot',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Get depot info
|
|
89
|
+
const info = await client.depots.get(depotId);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Ticket Operations
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// Create access ticket
|
|
96
|
+
const ticket = await client.tickets.create({
|
|
97
|
+
depotId: 'depot:...',
|
|
98
|
+
permissions: ['read', 'write'],
|
|
99
|
+
expiresIn: 3600,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// List tickets
|
|
103
|
+
const tickets = await client.tickets.list({ depotId: 'depot:...' });
|
|
104
|
+
|
|
105
|
+
// Revoke ticket
|
|
106
|
+
await client.tickets.revoke(ticketId);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Node Operations (CAS)
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Read node data
|
|
113
|
+
const data = await client.nodes.get('node:abc123...');
|
|
114
|
+
|
|
115
|
+
// Put node data
|
|
116
|
+
const key = await client.nodes.put(data);
|
|
117
|
+
|
|
118
|
+
// Check if node exists
|
|
119
|
+
const exists = await client.nodes.has('node:abc123...');
|
|
120
|
+
|
|
121
|
+
// Prepare upload (for large files)
|
|
122
|
+
const { uploadUrl } = await client.nodes.prepare({
|
|
123
|
+
size: fileSize,
|
|
124
|
+
hash: computedHash,
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Configuration
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
interface ClientConfig {
|
|
132
|
+
// Required
|
|
133
|
+
baseUrl: string;
|
|
134
|
+
|
|
135
|
+
// Callbacks
|
|
136
|
+
onAuthRequired?: () => void | Promise<void>;
|
|
137
|
+
onTokenChange?: (state: TokenState) => void;
|
|
138
|
+
|
|
139
|
+
// Optional storage provider (for CAS operations)
|
|
140
|
+
storage?: StorageProvider;
|
|
141
|
+
|
|
142
|
+
// Timeouts and retries
|
|
143
|
+
timeout?: number;
|
|
144
|
+
retries?: number;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Token Store
|
|
149
|
+
|
|
150
|
+
The client includes a sophisticated token store that handles:
|
|
151
|
+
|
|
152
|
+
- Automatic token refresh before expiry
|
|
153
|
+
- Token hierarchy validation
|
|
154
|
+
- Issuer chain tracking
|
|
155
|
+
- Concurrent refresh protection
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import {
|
|
159
|
+
createTokenStore,
|
|
160
|
+
createRefreshManager,
|
|
161
|
+
isTokenValid,
|
|
162
|
+
isTokenExpiringSoon,
|
|
163
|
+
} from '@casfa/client';
|
|
164
|
+
|
|
165
|
+
// Create standalone token store
|
|
166
|
+
const store = createTokenStore();
|
|
167
|
+
|
|
168
|
+
// Create refresh manager
|
|
169
|
+
const refreshManager = createRefreshManager(store, {
|
|
170
|
+
refreshThreshold: 5 * 60 * 1000, // 5 minutes before expiry
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## API Module
|
|
175
|
+
|
|
176
|
+
For advanced usage, access the raw API functions:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { api } from '@casfa/client';
|
|
180
|
+
|
|
181
|
+
// Direct API calls
|
|
182
|
+
const result = await api.createTicket(baseUrl, token, params);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Types
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import type {
|
|
189
|
+
CasfaClient,
|
|
190
|
+
ClientConfig,
|
|
191
|
+
ClientError,
|
|
192
|
+
TokenState,
|
|
193
|
+
StoredUserToken,
|
|
194
|
+
StoredDelegateToken,
|
|
195
|
+
StoredAccessToken,
|
|
196
|
+
} from '@casfa/client';
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## License
|
|
200
|
+
|
|
201
|
+
MIT
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# @casfa/client
|
|
2
|
+
|
|
3
|
+
CASFA 客户端库,提供统一的授权策略。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun add @casfa/client
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 概述
|
|
12
|
+
|
|
13
|
+
一个有状态的客户端,管理三层令牌体系:
|
|
14
|
+
|
|
15
|
+
1. **用户 JWT** - OAuth 登录令牌,最高权限
|
|
16
|
+
2. **委托令牌(Delegate Token)** - 可再委托的令牌,能够签发子令牌
|
|
17
|
+
3. **访问令牌(Access Token)** - 数据访问令牌,用于 CAS 操作
|
|
18
|
+
|
|
19
|
+
## 快速开始
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { createClient } from '@casfa/client';
|
|
23
|
+
|
|
24
|
+
const client = createClient({
|
|
25
|
+
baseUrl: 'https://api.casfa.example.com',
|
|
26
|
+
onAuthRequired: async () => {
|
|
27
|
+
// 处理认证(例如跳转到登录页面)
|
|
28
|
+
},
|
|
29
|
+
onTokenChange: (state) => {
|
|
30
|
+
// 持久化令牌状态
|
|
31
|
+
localStorage.setItem('casfa-tokens', JSON.stringify(state));
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// 使用已保存的令牌初始化
|
|
36
|
+
const stored = localStorage.getItem('casfa-tokens');
|
|
37
|
+
if (stored) {
|
|
38
|
+
client.tokens.restore(JSON.parse(stored));
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 功能特性
|
|
43
|
+
|
|
44
|
+
### OAuth 认证
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
// 发起 OAuth 流程
|
|
48
|
+
const { authUrl, state, codeVerifier } = await client.oauth.startAuth({
|
|
49
|
+
redirectUri: 'https://myapp.com/callback',
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// 处理回调
|
|
53
|
+
const tokens = await client.oauth.handleCallback({
|
|
54
|
+
code: authCode,
|
|
55
|
+
codeVerifier,
|
|
56
|
+
redirectUri: 'https://myapp.com/callback',
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 令牌管理
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
// 检查令牌状态
|
|
64
|
+
const hasValidTokens = client.tokens.hasValidTokens();
|
|
65
|
+
const userToken = client.tokens.getUserToken();
|
|
66
|
+
const delegateToken = client.tokens.getDelegateToken();
|
|
67
|
+
const accessToken = client.tokens.getAccessToken();
|
|
68
|
+
|
|
69
|
+
// 刷新令牌
|
|
70
|
+
await client.tokens.refresh();
|
|
71
|
+
|
|
72
|
+
// 清除所有令牌(登出)
|
|
73
|
+
client.tokens.clear();
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Depot 操作
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
// 列出 depot
|
|
80
|
+
const depots = await client.depots.list();
|
|
81
|
+
|
|
82
|
+
// 创建 depot
|
|
83
|
+
const depot = await client.depots.create({
|
|
84
|
+
name: 'my-depot',
|
|
85
|
+
description: 'My storage depot',
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// 获取 depot 信息
|
|
89
|
+
const info = await client.depots.get(depotId);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Ticket 操作
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// 创建访问 ticket
|
|
96
|
+
const ticket = await client.tickets.create({
|
|
97
|
+
depotId: 'depot:...',
|
|
98
|
+
permissions: ['read', 'write'],
|
|
99
|
+
expiresIn: 3600,
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// 列出 ticket
|
|
103
|
+
const tickets = await client.tickets.list({ depotId: 'depot:...' });
|
|
104
|
+
|
|
105
|
+
// 撤销 ticket
|
|
106
|
+
await client.tickets.revoke(ticketId);
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 节点操作(CAS)
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// 读取节点数据
|
|
113
|
+
const data = await client.nodes.get('node:abc123...');
|
|
114
|
+
|
|
115
|
+
// 写入节点数据
|
|
116
|
+
const key = await client.nodes.put(data);
|
|
117
|
+
|
|
118
|
+
// 检查节点是否存在
|
|
119
|
+
const exists = await client.nodes.has('node:abc123...');
|
|
120
|
+
|
|
121
|
+
// 准备上传(用于大文件)
|
|
122
|
+
const { uploadUrl } = await client.nodes.prepare({
|
|
123
|
+
size: fileSize,
|
|
124
|
+
hash: computedHash,
|
|
125
|
+
});
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## 配置
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
interface ClientConfig {
|
|
132
|
+
// 必需
|
|
133
|
+
baseUrl: string;
|
|
134
|
+
|
|
135
|
+
// 回调函数
|
|
136
|
+
onAuthRequired?: () => void | Promise<void>;
|
|
137
|
+
onTokenChange?: (state: TokenState) => void;
|
|
138
|
+
|
|
139
|
+
// 可选的存储提供者(用于 CAS 操作)
|
|
140
|
+
storage?: StorageProvider;
|
|
141
|
+
|
|
142
|
+
// 超时和重试
|
|
143
|
+
timeout?: number;
|
|
144
|
+
retries?: number;
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 令牌存储
|
|
149
|
+
|
|
150
|
+
客户端包含一个完善的令牌存储,支持:
|
|
151
|
+
|
|
152
|
+
- 过期前自动刷新令牌
|
|
153
|
+
- 令牌层级校验
|
|
154
|
+
- 签发链追踪
|
|
155
|
+
- 并发刷新保护
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
import {
|
|
159
|
+
createTokenStore,
|
|
160
|
+
createRefreshManager,
|
|
161
|
+
isTokenValid,
|
|
162
|
+
isTokenExpiringSoon,
|
|
163
|
+
} from '@casfa/client';
|
|
164
|
+
|
|
165
|
+
// 创建独立的令牌存储
|
|
166
|
+
const store = createTokenStore();
|
|
167
|
+
|
|
168
|
+
// 创建刷新管理器
|
|
169
|
+
const refreshManager = createRefreshManager(store, {
|
|
170
|
+
refreshThreshold: 5 * 60 * 1000, // 过期前 5 分钟刷新
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## API 模块
|
|
175
|
+
|
|
176
|
+
如需高级用法,可直接访问底层 API 函数:
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { api } from '@casfa/client';
|
|
180
|
+
|
|
181
|
+
// 直接调用 API
|
|
182
|
+
const result = await api.createTicket(baseUrl, token, params);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## 类型
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import type {
|
|
189
|
+
CasfaClient,
|
|
190
|
+
ClientConfig,
|
|
191
|
+
ClientError,
|
|
192
|
+
TokenState,
|
|
193
|
+
StoredUserToken,
|
|
194
|
+
StoredDelegateToken,
|
|
195
|
+
StoredAccessToken,
|
|
196
|
+
} from '@casfa/client';
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## 许可证
|
|
200
|
+
|
|
201
|
+
MIT
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { a as CognitoConfig, C as CommitDepotResponse, D as DelegateTokenParams, L as ListDepotsResponse, b as ListTicketsResponse, c as ListTokensParams, d as ListTokensResponse, N as NodeUploadResult, S as SubmitTicketResponse, T as TokenResponse, U as UserInfo, e as approveAuthRequest, f as commitDepot, g as createAuthRequest, h as createDepot, j as createTicket, k as createToken, l as delegateToken, m as deleteDepot, n as exchangeCode, o as fetchServiceInfo, p as getAuthRequest, q as getDepot, r as getMe, s as getNode, t as getNodeMetadata, u as getOAuthConfig, v as getTicket, w as getToken, x as healthCheck, y as listDepots, z as listTickets, A as listTokens, B as login, E as pollAuthRequest, F as prepareNodes, G as putNode, H as refresh, I as rejectAuthRequest, J as revokeToken, K as submitTicket, M as tokenResponseToStoredUserToken, O as updateDepot } from '../index-cPO-6GxE.js';
|
|
2
|
+
import '@casfa/protocol';
|
|
3
|
+
import '../types/index.js';
|