hop-claude 1.1.0 → 2.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/CHANGELOG.md +30 -0
- package/dist/config/config-manager.d.ts +2 -4
- package/dist/config/config-manager.d.ts.map +1 -1
- package/dist/config/config-manager.js +80 -98
- package/dist/config/config-manager.js.map +1 -1
- package/dist/types/index.d.ts +1 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/migration.d.ts.map +1 -1
- package/dist/utils/migration.js +0 -20
- package/dist/utils/migration.js.map +1 -1
- package/package.json +1 -1
- package/dist/config/encryption.d.ts +0 -36
- package/dist/config/encryption.d.ts.map +0 -1
- package/dist/config/encryption.js +0 -72
- package/dist/config/encryption.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- c835b69: 移除 Legacy 加密模式支持
|
|
8
|
+
|
|
9
|
+
**破坏性变更**:
|
|
10
|
+
|
|
11
|
+
- 完全移除 legacy 加密模式(机器绑定加密)
|
|
12
|
+
- 移除 legacy 向后兼容代码
|
|
13
|
+
- 删除 encryption.ts 文件
|
|
14
|
+
|
|
15
|
+
**新默认行为**:
|
|
16
|
+
|
|
17
|
+
- 新安装自动选择最佳加密模式:
|
|
18
|
+
- 支持 Keychain 的系统默认使用 Keychain 模式
|
|
19
|
+
- 不支持 Keychain 的系统默认使用密码加密模式
|
|
20
|
+
- 更简洁的代码库和更好的安全性
|
|
21
|
+
|
|
22
|
+
**迁移说明**:
|
|
23
|
+
如果你已有配置,系统会自动检测并提示迁移到新的加密模式。
|
|
24
|
+
建议使用 Keychain 模式(macOS/Linux)或密码加密模式(Windows/其他)。
|
|
25
|
+
|
|
26
|
+
**改进**:
|
|
27
|
+
|
|
28
|
+
- 简化了加密模式选择逻辑
|
|
29
|
+
- 移除了不安全的机器绑定加密
|
|
30
|
+
- 提升了整体安全性
|
|
31
|
+
- 减少了代码复杂度
|
|
32
|
+
|
|
3
33
|
## 1.1.0
|
|
4
34
|
|
|
5
35
|
### Minor Changes
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import type { ConfigStore, ProfileConfig, DecryptedProfile, EncryptionMode } from '../types/index.js';
|
|
2
2
|
/**
|
|
3
3
|
* 配置管理核心类
|
|
4
|
-
*
|
|
5
|
-
* - legacy: 机器绑定加密(向后兼容)
|
|
4
|
+
* 支持两种加密模式:
|
|
6
5
|
* - keychain: OS 密钥链存储(推荐)
|
|
7
|
-
* - passphrase:
|
|
6
|
+
* - passphrase: 密码加密(可移植)
|
|
8
7
|
*/
|
|
9
8
|
export declare class ConfigManager {
|
|
10
9
|
private storage;
|
|
11
|
-
private legacyEncryption;
|
|
12
10
|
private passphraseEncryption;
|
|
13
11
|
private keychainManager;
|
|
14
12
|
private sessionPassphrase?;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEtG;;;;;GAKG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,eAAe,CAAkB;IAGzC,OAAO,CAAC,iBAAiB,CAAC,CAAS;;IAQnC;;OAEG;IACH,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAI9C;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAI9B;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;IAUlD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC;IA2BxC;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,WAAW,CAAC;IAavC;;;;OAIG;IACG,WAAW,CAAC,OAAO,EAAE,gBAAgB,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDhF;;;;OAIG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAuCvF;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMtD;;;OAGG;IACG,iBAAiB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAM9E;;;OAGG;IACG,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA6CjG;;OAEG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlD;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAWrC;;OAEG;IACG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB/C;;;;OAIG;IACG,oBAAoB,CACxB,OAAO,EAAE,cAAc,EACvB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAyChB;;OAEG;IACH,aAAa,IAAI,MAAM;CAGxB"}
|
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
import { ConfigStorage } from './storage.js';
|
|
2
|
-
import { Encryption } from './encryption.js';
|
|
3
2
|
import { PassphraseEncryption } from './encryption-v2.js';
|
|
4
3
|
import { KeychainManager } from './keychain.js';
|
|
5
4
|
/**
|
|
6
5
|
* 配置管理核心类
|
|
7
|
-
*
|
|
8
|
-
* - legacy: 机器绑定加密(向后兼容)
|
|
6
|
+
* 支持两种加密模式:
|
|
9
7
|
* - keychain: OS 密钥链存储(推荐)
|
|
10
|
-
* - passphrase:
|
|
8
|
+
* - passphrase: 密码加密(可移植)
|
|
11
9
|
*/
|
|
12
10
|
export class ConfigManager {
|
|
13
11
|
storage;
|
|
14
|
-
legacyEncryption;
|
|
15
12
|
passphraseEncryption;
|
|
16
13
|
keychainManager;
|
|
17
14
|
// 用于临时存储用户输入的 passphrase(仅在当前会话有效)
|
|
18
15
|
sessionPassphrase;
|
|
19
16
|
constructor() {
|
|
20
17
|
this.storage = new ConfigStorage();
|
|
21
|
-
this.legacyEncryption = new Encryption();
|
|
22
18
|
this.passphraseEncryption = new PassphraseEncryption();
|
|
23
19
|
this.keychainManager = new KeychainManager();
|
|
24
20
|
}
|
|
@@ -39,7 +35,12 @@ export class ConfigManager {
|
|
|
39
35
|
*/
|
|
40
36
|
async getEncryptionMode() {
|
|
41
37
|
const config = await this.storage.read();
|
|
42
|
-
|
|
38
|
+
if (config?.encryptionMode) {
|
|
39
|
+
return config.encryptionMode;
|
|
40
|
+
}
|
|
41
|
+
// 默认:keychain 可用则用 keychain,否则用 passphrase
|
|
42
|
+
const keychainAvailable = await KeychainManager.isAvailable();
|
|
43
|
+
return keychainAvailable ? 'keychain' : 'passphrase';
|
|
43
44
|
}
|
|
44
45
|
/**
|
|
45
46
|
* 初始化配置文件
|
|
@@ -47,18 +48,22 @@ export class ConfigManager {
|
|
|
47
48
|
async initialize() {
|
|
48
49
|
const existing = await this.storage.read();
|
|
49
50
|
if (existing) {
|
|
50
|
-
// 确保有 encryptionMode
|
|
51
|
+
// 确保有 encryptionMode 字段
|
|
51
52
|
if (!existing.encryptionMode) {
|
|
52
|
-
|
|
53
|
+
const keychainAvailable = await KeychainManager.isAvailable();
|
|
54
|
+
existing.encryptionMode = keychainAvailable ? 'keychain' : 'passphrase';
|
|
53
55
|
}
|
|
54
56
|
return existing;
|
|
55
57
|
}
|
|
58
|
+
// 检测系统支持的加密模式
|
|
59
|
+
const keychainAvailable = await KeychainManager.isAvailable();
|
|
60
|
+
const encryptionMode = keychainAvailable ? 'keychain' : 'passphrase';
|
|
56
61
|
const newConfig = {
|
|
57
62
|
version: '1.0.0',
|
|
58
63
|
currentProfile: '',
|
|
59
64
|
profiles: [],
|
|
60
|
-
encryptionSalt: this.
|
|
61
|
-
encryptionMode
|
|
65
|
+
encryptionSalt: encryptionMode === 'passphrase' ? this.passphraseEncryption.generateSalt() : undefined,
|
|
66
|
+
encryptionMode,
|
|
62
67
|
};
|
|
63
68
|
await this.storage.write(newConfig);
|
|
64
69
|
return newConfig;
|
|
@@ -70,9 +75,10 @@ export class ConfigManager {
|
|
|
70
75
|
const config = await this.storage.read();
|
|
71
76
|
if (!config)
|
|
72
77
|
return await this.initialize();
|
|
73
|
-
//
|
|
78
|
+
// 确保有 encryptionMode 字段
|
|
74
79
|
if (!config.encryptionMode) {
|
|
75
|
-
|
|
80
|
+
const keychainAvailable = await KeychainManager.isAvailable();
|
|
81
|
+
config.encryptionMode = keychainAvailable ? 'keychain' : 'passphrase';
|
|
76
82
|
}
|
|
77
83
|
return config;
|
|
78
84
|
}
|
|
@@ -83,38 +89,28 @@ export class ConfigManager {
|
|
|
83
89
|
*/
|
|
84
90
|
async saveProfile(profile, passphrase) {
|
|
85
91
|
const config = await this.getConfig();
|
|
86
|
-
const mode = config.encryptionMode
|
|
87
|
-
if (!config.encryptionSalt && mode
|
|
88
|
-
config.encryptionSalt = this.
|
|
92
|
+
const mode = config.encryptionMode;
|
|
93
|
+
if (!config.encryptionSalt && mode === 'passphrase') {
|
|
94
|
+
config.encryptionSalt = this.passphraseEncryption.generateSalt();
|
|
89
95
|
}
|
|
90
96
|
let encryptedApiKey;
|
|
91
97
|
// 根据加密模式处理 API Key
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
encryptedApiKey = this.passphraseEncryption.encrypt(profile.apiKey, pwd, config.encryptionSalt);
|
|
109
|
-
break;
|
|
110
|
-
case 'legacy':
|
|
111
|
-
default:
|
|
112
|
-
// Legacy 模式:机器绑定加密
|
|
113
|
-
if (!config.encryptionSalt) {
|
|
114
|
-
config.encryptionSalt = this.legacyEncryption.generateSalt();
|
|
115
|
-
}
|
|
116
|
-
encryptedApiKey = this.legacyEncryption.encrypt(profile.apiKey, config.encryptionSalt);
|
|
117
|
-
break;
|
|
98
|
+
if (mode === 'keychain') {
|
|
99
|
+
// Keychain 模式:存储到 OS 密钥链
|
|
100
|
+
await this.keychainManager.setAPIKey(profile.domain, profile.apiKey);
|
|
101
|
+
// config.json 中存储占位符
|
|
102
|
+
encryptedApiKey = '__KEYCHAIN__';
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
// Passphrase 模式:使用用户密码加密
|
|
106
|
+
const pwd = passphrase || this.sessionPassphrase;
|
|
107
|
+
if (!pwd && pwd !== '') {
|
|
108
|
+
throw new Error('需要密码来加密 API Key');
|
|
109
|
+
}
|
|
110
|
+
if (!config.encryptionSalt) {
|
|
111
|
+
config.encryptionSalt = this.passphraseEncryption.generateSalt();
|
|
112
|
+
}
|
|
113
|
+
encryptedApiKey = this.passphraseEncryption.encrypt(profile.apiKey, pwd, config.encryptionSalt);
|
|
118
114
|
}
|
|
119
115
|
const encryptedProfile = {
|
|
120
116
|
...profile,
|
|
@@ -141,37 +137,27 @@ export class ConfigManager {
|
|
|
141
137
|
const profile = config.profiles.find(p => p.domain === domain);
|
|
142
138
|
if (!profile)
|
|
143
139
|
return null;
|
|
144
|
-
const mode = config.encryptionMode
|
|
140
|
+
const mode = config.encryptionMode;
|
|
145
141
|
let decryptedApiKey;
|
|
146
142
|
// 根据加密模式解密 API Key
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
decryptedApiKey = this.passphraseEncryption.decrypt(profile.apiKey, pwd, config.encryptionSalt);
|
|
166
|
-
break;
|
|
167
|
-
case 'legacy':
|
|
168
|
-
default:
|
|
169
|
-
// Legacy 模式:机器绑定解密
|
|
170
|
-
if (!config.encryptionSalt) {
|
|
171
|
-
throw new Error('Encryption salt not found');
|
|
172
|
-
}
|
|
173
|
-
decryptedApiKey = this.legacyEncryption.decrypt(profile.apiKey, config.encryptionSalt);
|
|
174
|
-
break;
|
|
143
|
+
if (mode === 'keychain') {
|
|
144
|
+
// Keychain 模式:从 OS 密钥链读取
|
|
145
|
+
const keychainKey = await this.keychainManager.getAPIKey(domain);
|
|
146
|
+
if (!keychainKey) {
|
|
147
|
+
throw new Error(`密钥链中未找到配置 ${domain} 的 API key`);
|
|
148
|
+
}
|
|
149
|
+
decryptedApiKey = keychainKey;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Passphrase 模式:使用用户密码解密
|
|
153
|
+
const pwd = passphrase || this.sessionPassphrase;
|
|
154
|
+
if (!pwd && pwd !== '') {
|
|
155
|
+
throw new Error('需要密码来解密 API key');
|
|
156
|
+
}
|
|
157
|
+
if (!config.encryptionSalt) {
|
|
158
|
+
throw new Error('未找到加密 salt');
|
|
159
|
+
}
|
|
160
|
+
decryptedApiKey = this.passphraseEncryption.decrypt(profile.apiKey, pwd, config.encryptionSalt);
|
|
175
161
|
}
|
|
176
162
|
return {
|
|
177
163
|
...profile,
|
|
@@ -202,36 +188,31 @@ export class ConfigManager {
|
|
|
202
188
|
*/
|
|
203
189
|
async listProfiles(passphrase) {
|
|
204
190
|
const config = await this.getConfig();
|
|
205
|
-
const mode = config.encryptionMode
|
|
191
|
+
const mode = config.encryptionMode;
|
|
206
192
|
const results = [];
|
|
207
193
|
for (const p of config.profiles) {
|
|
208
194
|
try {
|
|
209
195
|
let decryptedKey;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
196
|
+
if (mode === 'keychain') {
|
|
197
|
+
const keychainKey = await this.keychainManager.getAPIKey(p.domain);
|
|
198
|
+
decryptedKey = keychainKey || '';
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
// Passphrase 模式
|
|
202
|
+
const pwd = passphrase || this.sessionPassphrase;
|
|
203
|
+
if (!pwd && pwd !== '') {
|
|
204
|
+
decryptedKey = '';
|
|
205
|
+
}
|
|
206
|
+
else if (!config.encryptionSalt) {
|
|
207
|
+
decryptedKey = '';
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
221
210
|
decryptedKey = this.passphraseEncryption.decrypt(p.apiKey, pwd, config.encryptionSalt);
|
|
222
|
-
|
|
223
|
-
case 'legacy':
|
|
224
|
-
default:
|
|
225
|
-
if (!config.encryptionSalt) {
|
|
226
|
-
decryptedKey = '';
|
|
227
|
-
break;
|
|
228
|
-
}
|
|
229
|
-
decryptedKey = this.legacyEncryption.decrypt(p.apiKey, config.encryptionSalt);
|
|
230
|
-
break;
|
|
211
|
+
}
|
|
231
212
|
}
|
|
232
213
|
results.push({
|
|
233
214
|
...p,
|
|
234
|
-
maskedApiKey: this.
|
|
215
|
+
maskedApiKey: this.passphraseEncryption.maskApiKey(decryptedKey),
|
|
235
216
|
});
|
|
236
217
|
}
|
|
237
218
|
catch (error) {
|
|
@@ -249,7 +230,7 @@ export class ConfigManager {
|
|
|
249
230
|
*/
|
|
250
231
|
async deleteProfile(domain) {
|
|
251
232
|
const config = await this.getConfig();
|
|
252
|
-
const mode = config.encryptionMode
|
|
233
|
+
const mode = config.encryptionMode;
|
|
253
234
|
// Keychain 模式下,同时从密钥链中删除
|
|
254
235
|
if (mode === 'keychain') {
|
|
255
236
|
await this.keychainManager.deleteAPIKey(domain);
|
|
@@ -281,9 +262,10 @@ export class ConfigManager {
|
|
|
281
262
|
if (!config.version || !Array.isArray(config.profiles)) {
|
|
282
263
|
throw new Error('Invalid configuration format');
|
|
283
264
|
}
|
|
284
|
-
//
|
|
265
|
+
// 确保有加密模式
|
|
285
266
|
if (!config.encryptionMode) {
|
|
286
|
-
|
|
267
|
+
const keychainAvailable = await KeychainManager.isAvailable();
|
|
268
|
+
config.encryptionMode = keychainAvailable ? 'keychain' : 'passphrase';
|
|
287
269
|
}
|
|
288
270
|
await this.storage.write(config);
|
|
289
271
|
}
|
|
@@ -294,7 +276,7 @@ export class ConfigManager {
|
|
|
294
276
|
*/
|
|
295
277
|
async switchEncryptionMode(newMode, passphrase) {
|
|
296
278
|
const config = await this.getConfig();
|
|
297
|
-
const oldMode = config.encryptionMode
|
|
279
|
+
const oldMode = config.encryptionMode;
|
|
298
280
|
if (oldMode === newMode) {
|
|
299
281
|
return; // 无需切换
|
|
300
282
|
}
|
|
@@ -308,7 +290,7 @@ export class ConfigManager {
|
|
|
308
290
|
}
|
|
309
291
|
// 更新加密模式
|
|
310
292
|
config.encryptionMode = newMode;
|
|
311
|
-
//
|
|
293
|
+
// 如果切换到 passphrase 模式,可能需要新的 salt
|
|
312
294
|
if (newMode === 'passphrase' && !config.encryptionSalt) {
|
|
313
295
|
config.encryptionSalt = this.passphraseEncryption.generateSalt();
|
|
314
296
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../src/config/config-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IAChB,OAAO,CAAgB;IACvB,oBAAoB,CAAuB;IAC3C,eAAe,CAAkB;IAEzC,mCAAmC;IAC3B,iBAAiB,CAAU;IAEnC;QACE,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC;QACvD,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,oBAAoB,CAAC,UAAkB;QACrC,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,sBAAsB;QACpB,IAAI,CAAC,iBAAiB,GAAG,SAAS,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,MAAM,EAAE,cAAc,EAAE,CAAC;YAC3B,OAAO,MAAM,CAAC,cAAc,CAAC;QAC/B,CAAC;QACD,2CAA2C;QAC3C,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC;QAC9D,OAAO,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,QAAQ,EAAE,CAAC;YACb,wBAAwB;YACxB,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,CAAC;gBAC7B,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC;gBAC9D,QAAQ,CAAC,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;YAC1E,CAAC;YACD,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,cAAc;QACd,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC;QAC9D,MAAM,cAAc,GAAmB,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;QAErF,MAAM,SAAS,GAAgB;YAC7B,OAAO,EAAE,OAAO;YAChB,cAAc,EAAE,EAAE;YAClB,QAAQ,EAAE,EAAE;YACZ,cAAc,EAAE,cAAc,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,SAAS;YACtG,cAAc;SACf,CAAC;QAEF,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,SAAS;QACb,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM;YAAE,OAAO,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;QAE5C,wBAAwB;QACxB,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC3B,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC;YAC9D,MAAM,CAAC,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;QACxE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,WAAW,CAAC,OAAyB,EAAE,UAAmB;QAC9D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,CAAC,cAAe,CAAC;QAEpC,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YACpD,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;QACnE,CAAC;QAED,IAAI,eAAuB,CAAC;QAE5B,mBAAmB;QACnB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,yBAAyB;YACzB,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACrE,qBAAqB;YACrB,eAAe,GAAG,cAAc,CAAC;QACnC,CAAC;aAAM,CAAC;YACN,yBAAyB;YACzB,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC;YACjD,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC3B,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;YACnE,CAAC;YACD,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CACjD,OAAO,CAAC,MAAM,EACd,GAAG,EACH,MAAM,CAAC,cAAc,CACtB,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAkB;YACtC,GAAG,OAAO;YACV,MAAM,EAAE,eAAe;YACvB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;QAEF,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1E,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,gBAAgB,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACxC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU,CAAC,MAAc,EAAE,UAAmB;QAClD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAE/D,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,IAAI,GAAG,MAAM,CAAC,cAAe,CAAC;QACpC,IAAI,eAAuB,CAAC;QAE5B,mBAAmB;QACnB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,yBAAyB;YACzB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACjE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,aAAa,MAAM,YAAY,CAAC,CAAC;YACnD,CAAC;YACD,eAAe,GAAG,WAAW,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,yBAAyB;YACzB,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC;YACjD,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;gBACvB,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;YAChC,CAAC;YACD,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CACjD,OAAO,CAAC,MAAM,EACd,GAAG,EACH,MAAM,CAAC,cAAc,CACtB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,GAAG,OAAO;YACV,MAAM,EAAE,eAAe;SACxB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,iBAAiB,CAAC,MAAc;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC;QAC/B,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,iBAAiB,CAAC,UAAmB;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,cAAc;YAAE,OAAO,IAAI,CAAC;QACxC,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IAClE,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY,CAAC,UAAmB;QACpC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,CAAC,cAAe,CAAC;QAEpC,MAAM,OAAO,GAAoD,EAAE,CAAC;QAEpE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,IAAI,YAAoB,CAAC;gBAEzB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;oBACxB,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;oBACnE,YAAY,GAAG,WAAW,IAAI,EAAE,CAAC;gBACnC,CAAC;qBAAM,CAAC;oBACN,gBAAgB;oBAChB,MAAM,GAAG,GAAG,UAAU,IAAI,IAAI,CAAC,iBAAiB,CAAC;oBACjD,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,EAAE,EAAE,CAAC;wBACvB,YAAY,GAAG,EAAE,CAAC;oBACpB,CAAC;yBAAM,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;wBAClC,YAAY,GAAG,EAAE,CAAC;oBACpB,CAAC;yBAAM,CAAC;wBACN,YAAY,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAC9C,CAAC,CAAC,MAAM,EACR,GAAG,EACH,MAAM,CAAC,cAAc,CACtB,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC;oBACX,GAAG,CAAC;oBACJ,YAAY,EAAE,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,YAAY,CAAC;iBACjE,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACxB,gBAAgB;gBAChB,OAAO,CAAC,IAAI,CAAC;oBACX,GAAG,CAAC;oBACJ,YAAY,EAAE,iBAAiB;iBAChC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,MAAM,CAAC,cAAe,CAAC;QAEpC,yBAAyB;QACzB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,eAAe,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAClD,CAAC;QAED,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;QAEnE,IAAI,MAAM,CAAC,cAAc,KAAK,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,IAAI,EAAE,CAAC;QAC3D,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QAEtC,uBAAuB;QACvB,IAAI,MAAM,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,qGAAqG,CAAC,CAAC;QACtH,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,IAAY;QAC7B,MAAM,MAAM,GAAgB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,SAAS;QACT,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,CAAC;QAED,UAAU;QACV,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YAC3B,MAAM,iBAAiB,GAAG,MAAM,eAAe,CAAC,WAAW,EAAE,CAAC;YAC9D,MAAM,CAAC,cAAc,GAAG,iBAAiB,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;QACxE,CAAC;QAED,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,oBAAoB,CACxB,OAAuB,EACvB,UAAmB;QAEnB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,MAAM,CAAC,cAAe,CAAC;QAEvC,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,OAAO;QACjB,CAAC;QAED,6BAA6B;QAC7B,MAAM,iBAAiB,GAAuB,EAAE,CAAC;QAEjD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YAChC,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC9D,IAAI,SAAS,EAAE,CAAC;gBACd,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,SAAS;QACT,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC;QAEhC,kCAAkC;QAClC,IAAI,OAAO,KAAK,YAAY,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;YACvD,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,YAAY,EAAE,CAAC;QACnE,CAAC;QAED,gBAAgB;QAChB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;QACrB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEjC,uBAAuB;QACvB,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;YACxC,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC9C,CAAC;QAED,0BAA0B;QAC1B,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;QACxC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;IACtC,CAAC;CACF"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 加密模式
|
|
3
|
-
* - legacy: 旧版机器绑定加密(已弃用,但保持向后兼容)
|
|
4
3
|
* - keychain: OS 密钥链存储(推荐,最安全)
|
|
5
4
|
* - passphrase: 密码加密(可移植)
|
|
6
5
|
*/
|
|
7
|
-
export type EncryptionMode = '
|
|
6
|
+
export type EncryptionMode = 'keychain' | 'passphrase';
|
|
8
7
|
export interface ProfileConfig {
|
|
9
8
|
domain: string;
|
|
10
9
|
apiKey: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAEvD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC;IACrE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,oBAAoB;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wCAAwC,CAAC,EAAE,MAAM,CAAC;CACnD;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAK5D;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAAgB;gBAEzB,aAAa,EAAE,aAAa;IAIxC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"migration.d.ts","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAK5D;;;GAGG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,aAAa,CAAgB;gBAEzB,aAAa,EAAE,aAAa;IAIxC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAqL9B;;OAEG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;CA6B1C"}
|
package/dist/utils/migration.js
CHANGED
|
@@ -18,11 +18,6 @@ export class EncryptionMigration {
|
|
|
18
18
|
// 获取当前加密模式
|
|
19
19
|
const currentMode = await this.configManager.getEncryptionMode();
|
|
20
20
|
displayMessage(`当前加密模式:${currentMode}`);
|
|
21
|
-
if (currentMode === 'legacy') {
|
|
22
|
-
displayWarning('\nLegacy 模式使用机器绑定加密。');
|
|
23
|
-
displayWarning('导出的配置无法在其他机器上恢复。');
|
|
24
|
-
displayMessage('\n建议:迁移到更安全和可移植的模式。\n');
|
|
25
|
-
}
|
|
26
21
|
// 检查 keychain 是否可用
|
|
27
22
|
const keychainAvailable = await KeychainManager.isAvailable();
|
|
28
23
|
// 选择新的加密模式
|
|
@@ -42,13 +37,6 @@ export class EncryptionMigration {
|
|
|
42
37
|
value: 'passphrase',
|
|
43
38
|
description: '使用密码加密 - 可跨机器移植,每次需要输入密码',
|
|
44
39
|
});
|
|
45
|
-
if (currentMode !== 'legacy') {
|
|
46
|
-
choices.push({
|
|
47
|
-
title: 'Legacy(不推荐)',
|
|
48
|
-
value: 'legacy',
|
|
49
|
-
description: '机器绑定加密 - 无法在其他机器上恢复',
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
40
|
const { newMode } = await prompts({
|
|
53
41
|
type: 'select',
|
|
54
42
|
name: 'newMode',
|
|
@@ -187,14 +175,6 @@ export class EncryptionMigration {
|
|
|
187
175
|
displayMessage('\n=== 加密模式信息 ===\n');
|
|
188
176
|
displayMessage(`当前模式:${mode}`);
|
|
189
177
|
switch (mode) {
|
|
190
|
-
case 'legacy':
|
|
191
|
-
displayMessage('\nLegacy 模式:');
|
|
192
|
-
displayMessage(' - 使用机器绑定加密(hostname + username)');
|
|
193
|
-
displayMessage(' - 密钥已加密但绑定到本机');
|
|
194
|
-
displayMessage(' - 导出的配置无法在其他机器上恢复');
|
|
195
|
-
displayWarning('\n 警告:此模式已弃用且安全性较低。');
|
|
196
|
-
displayMessage(' 建议迁移到 keychain 或 passphrase 模式。');
|
|
197
|
-
break;
|
|
198
178
|
case 'keychain':
|
|
199
179
|
displayMessage('\nKeychain 模式:');
|
|
200
180
|
displayMessage(' - 密钥存储在系统 keychain(最安全)');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGhG;;;GAGG;AACH,MAAM,OAAO,mBAAmB;IACtB,aAAa,CAAgB;IAErC,YAAY,aAA4B;QACtC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,cAAc,CAAC,oBAAoB,CAAC,CAAC;QAErC,WAAW;QACX,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,iBAAiB,EAAE,CAAC;QAEjE,cAAc,CAAC,UAAU,WAAW,EAAE,CAAC,CAAC;QAExC,
|
|
1
|
+
{"version":3,"file":"migration.js","sourceRoot":"","sources":["../../src/utils/migration.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 加密类:使用 AES-256-GCM 对称加密
|
|
3
|
-
* 密钥派生:基于机器标识(hostname + username)+ 随机盐
|
|
4
|
-
*/
|
|
5
|
-
export declare class Encryption {
|
|
6
|
-
private algorithm;
|
|
7
|
-
/**
|
|
8
|
-
* 生成加密密钥(基于机器信息 + salt)
|
|
9
|
-
*/
|
|
10
|
-
private deriveKey;
|
|
11
|
-
/**
|
|
12
|
-
* 生成随机 salt
|
|
13
|
-
*/
|
|
14
|
-
generateSalt(): string;
|
|
15
|
-
/**
|
|
16
|
-
* 加密明文
|
|
17
|
-
* @param plaintext 要加密的明文
|
|
18
|
-
* @param salt 盐值
|
|
19
|
-
* @returns 加密后的密文,格式:iv:authTag:encrypted
|
|
20
|
-
*/
|
|
21
|
-
encrypt(plaintext: string, salt: string): string;
|
|
22
|
-
/**
|
|
23
|
-
* 解密密文
|
|
24
|
-
* @param ciphertext 密文,格式:iv:authTag:encrypted
|
|
25
|
-
* @param salt 盐值
|
|
26
|
-
* @returns 解密后的明文
|
|
27
|
-
*/
|
|
28
|
-
decrypt(ciphertext: string, salt: string): string;
|
|
29
|
-
/**
|
|
30
|
-
* 部分隐藏 API Key(用于显示)
|
|
31
|
-
* @param apiKey API Key
|
|
32
|
-
* @returns 部分隐藏的 API Key,如:sk-ant-***xyz
|
|
33
|
-
*/
|
|
34
|
-
maskApiKey(apiKey: string): string;
|
|
35
|
-
}
|
|
36
|
-
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/config/encryption.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAiB;IAElC;;OAEG;IACH,OAAO,CAAC,SAAS;IAKjB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB;;;;;OAKG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAchD;;;;;OAKG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAqBjD;;;;OAIG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;CAOnC"}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import os from 'os';
|
|
3
|
-
/**
|
|
4
|
-
* 加密类:使用 AES-256-GCM 对称加密
|
|
5
|
-
* 密钥派生:基于机器标识(hostname + username)+ 随机盐
|
|
6
|
-
*/
|
|
7
|
-
export class Encryption {
|
|
8
|
-
algorithm = 'aes-256-gcm';
|
|
9
|
-
/**
|
|
10
|
-
* 生成加密密钥(基于机器信息 + salt)
|
|
11
|
-
*/
|
|
12
|
-
deriveKey(salt) {
|
|
13
|
-
const machineId = `${os.hostname()}-${os.userInfo().username}`;
|
|
14
|
-
return crypto.pbkdf2Sync(machineId, salt, 100000, 32, 'sha512');
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* 生成随机 salt
|
|
18
|
-
*/
|
|
19
|
-
generateSalt() {
|
|
20
|
-
return crypto.randomBytes(32).toString('hex');
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* 加密明文
|
|
24
|
-
* @param plaintext 要加密的明文
|
|
25
|
-
* @param salt 盐值
|
|
26
|
-
* @returns 加密后的密文,格式:iv:authTag:encrypted
|
|
27
|
-
*/
|
|
28
|
-
encrypt(plaintext, salt) {
|
|
29
|
-
const key = this.deriveKey(salt);
|
|
30
|
-
const iv = crypto.randomBytes(16);
|
|
31
|
-
const cipher = crypto.createCipheriv(this.algorithm, key, iv);
|
|
32
|
-
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
|
|
33
|
-
encrypted += cipher.final('hex');
|
|
34
|
-
const authTag = cipher.getAuthTag();
|
|
35
|
-
// 格式: iv:authTag:encrypted
|
|
36
|
-
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* 解密密文
|
|
40
|
-
* @param ciphertext 密文,格式:iv:authTag:encrypted
|
|
41
|
-
* @param salt 盐值
|
|
42
|
-
* @returns 解密后的明文
|
|
43
|
-
*/
|
|
44
|
-
decrypt(ciphertext, salt) {
|
|
45
|
-
const key = this.deriveKey(salt);
|
|
46
|
-
const parts = ciphertext.split(':');
|
|
47
|
-
if (parts.length !== 3) {
|
|
48
|
-
throw new Error('Invalid encrypted data format');
|
|
49
|
-
}
|
|
50
|
-
const [ivHex, authTagHex, encrypted] = parts;
|
|
51
|
-
const iv = Buffer.from(ivHex, 'hex');
|
|
52
|
-
const authTag = Buffer.from(authTagHex, 'hex');
|
|
53
|
-
const decipher = crypto.createDecipheriv(this.algorithm, key, iv);
|
|
54
|
-
decipher.setAuthTag(authTag);
|
|
55
|
-
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
|
|
56
|
-
decrypted += decipher.final('utf8');
|
|
57
|
-
return decrypted;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* 部分隐藏 API Key(用于显示)
|
|
61
|
-
* @param apiKey API Key
|
|
62
|
-
* @returns 部分隐藏的 API Key,如:sk-ant-***xyz
|
|
63
|
-
*/
|
|
64
|
-
maskApiKey(apiKey) {
|
|
65
|
-
if (!apiKey || apiKey.length < 8)
|
|
66
|
-
return '***';
|
|
67
|
-
const prefix = apiKey.slice(0, 6);
|
|
68
|
-
const suffix = apiKey.slice(-3);
|
|
69
|
-
return `${prefix}***${suffix}`;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
//# sourceMappingURL=encryption.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"encryption.js","sourceRoot":"","sources":["../../src/config/encryption.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB;;;GAGG;AACH,MAAM,OAAO,UAAU;IACb,SAAS,GAAG,aAAa,CAAC;IAElC;;OAEG;IACK,SAAS,CAAC,IAAY;QAC5B,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC;QAC/D,OAAO,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACH,YAAY;QACV,OAAO,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,SAAiB,EAAE,IAAY;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAqB,CAAC;QAElF,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACxD,SAAS,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAEjC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAEpC,2BAA2B;QAC3B,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,UAAkB,EAAE,IAAY;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;QAC7C,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAuB,CAAC;QACxF,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QAE7B,IAAI,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1D,SAAS,IAAI,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAEpC,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACH,UAAU,CAAC,MAAc;QACvB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAChC,OAAO,GAAG,MAAM,MAAM,MAAM,EAAE,CAAC;IACjC,CAAC;CACF"}
|