chaimi-keep-mcp 3.3.0-beta.2 → 3.3.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/oauth.js +48 -22
  2. package/package.json +1 -1
  3. package/server.js +34 -4
package/oauth.js CHANGED
@@ -428,28 +428,54 @@ class FileTokenStorage extends TokenStorage {
428
428
  }
429
429
 
430
430
  async save(token) {
431
- const dir = this.path.dirname(this.filePath);
432
- await this.fs.mkdir(dir, { recursive: true });
433
-
434
- console.error('🔍 [DEBUG] 开始保存 Token');
435
- console.error('🔍 [DEBUG] 加密密钥 (前8位):', this.key.substring(0, 8));
436
- console.error('🔍 [DEBUG] Token 过期时间:', token.expiresAt);
437
-
438
- // 加密 Token 后保存
439
- const encrypted = encryptToken(token, this.key);
440
- const data = {
441
- version: '2.0',
442
- encrypted: encrypted,
443
- algorithm: 'aes-256-cbc',
444
- updatedAt: new Date().toISOString()
445
- };
446
-
447
- await this.fs.writeFile(
448
- this.filePath,
449
- JSON.stringify(data, null, 2),
450
- { mode: 0o600 }
451
- );
452
- console.error('🔍 [DEBUG] Token 保存成功:', this.filePath);
431
+ try {
432
+ const dir = this.path.dirname(this.filePath);
433
+ await this.fs.mkdir(dir, { recursive: true });
434
+
435
+ console.error('🔍 [DEBUG] 开始保存 Token');
436
+ console.error('🔍 [DEBUG] 加密密钥 (前8位):', this.key.substring(0, 8));
437
+ console.error('🔍 [DEBUG] Token 过期时间:', token.expiresAt);
438
+
439
+ // 加密 Token 后保存
440
+ const encrypted = encryptToken(token, this.key);
441
+ const data = {
442
+ version: '2.0',
443
+ encrypted: encrypted,
444
+ algorithm: 'aes-256-cbc',
445
+ updatedAt: new Date().toISOString()
446
+ };
447
+
448
+ const content = JSON.stringify(data, null, 2);
449
+ console.error('🔍 [DEBUG] 准备写入内容长度:', content.length, '字节');
450
+
451
+ await this.fs.writeFile(
452
+ this.filePath,
453
+ content,
454
+ { mode: 0o600 }
455
+ );
456
+
457
+ // 验证写入是否成功
458
+ const stats = await this.fs.stat(this.filePath);
459
+ console.error('🔍 [DEBUG] Token 文件写入成功');
460
+ console.error('🔍 [DEBUG] 文件路径:', this.filePath);
461
+ console.error('🔍 [DEBUG] 文件大小:', stats.size, '字节');
462
+
463
+ if (stats.size === 0) {
464
+ throw new Error('Token 文件写入后大小为 0,写入失败');
465
+ }
466
+
467
+ // 立即读取验证
468
+ const readBack = await this.fs.readFile(this.filePath, 'utf8');
469
+ if (readBack.length === 0) {
470
+ throw new Error('Token 文件读取验证失败,内容为空');
471
+ }
472
+ console.error('🔍 [DEBUG] Token 文件验证成功,内容长度:', readBack.length, '字节');
473
+
474
+ } catch (error) {
475
+ console.error('❌ Token 保存失败:', error.message);
476
+ console.error('❌ 错误详情:', error);
477
+ throw error;
478
+ }
453
479
  }
454
480
 
455
481
  async load() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chaimi-keep-mcp",
3
- "version": "3.3.0-beta.2",
3
+ "version": "3.3.0-beta.4",
4
4
  "description": "柴米记账 MCP Server - 支持 Claude、Cursor、OpenClaw、WorkBuddy 等 AI 工具直接记账",
5
5
  "main": "server.js",
6
6
  "bin": {
package/server.js CHANGED
@@ -475,10 +475,27 @@ async function getToken() {
475
475
 
476
476
  // 【优化2】尝试从文件加载 token(优先级高于授权状态检查)
477
477
  try {
478
+ console.error('🔍 [DEBUG] 尝试从文件加载 Token...');
478
479
  const existingToken = await oauthManager.tokenStorage.load();
480
+ console.error('🔍 [DEBUG] Token 加载结果:', existingToken ? '成功' : '为空');
481
+ if (existingToken) {
482
+ console.error('🔍 [DEBUG] Token 字段检查:', {
483
+ hasAccessToken: !!existingToken.accessToken,
484
+ hasExpiresAt: !!existingToken.expiresAt,
485
+ expiresAt: existingToken.expiresAt
486
+ });
487
+ }
479
488
  if (existingToken && existingToken.accessToken && existingToken.expiresAt) {
480
489
  const expiresAt = new Date(existingToken.expiresAt).getTime();
481
- if (expiresAt > Date.now() + 5 * 60 * 1000) {
490
+ const now = Date.now();
491
+ const threshold = now + 5 * 60 * 1000;
492
+ console.error('🔍 [DEBUG] 过期时间检查:', {
493
+ expiresAt,
494
+ now,
495
+ threshold,
496
+ isValid: expiresAt > threshold
497
+ });
498
+ if (expiresAt > threshold) {
482
499
  // Token 有效,直接使用
483
500
  cachedToken = existingToken.accessToken;
484
501
  tokenExpireTime = expiresAt;
@@ -492,6 +509,7 @@ async function getToken() {
492
509
  }
493
510
  } catch (err) {
494
511
  console.error('⚠️ 加载保存的 Token 失败:', err.message);
512
+ console.error('⚠️ 错误堆栈:', err.stack);
495
513
  }
496
514
 
497
515
  // 【优化3】Token 不存在或已过期,检查是否需要授权
@@ -2183,11 +2201,23 @@ async function pollForAuthInBackground(deviceCode, interval) {
2183
2201
  authState.isWaiting = false;
2184
2202
 
2185
2203
  // 保存token到文件
2186
- await oauthManager.tokenStorage.save(token);
2204
+ try {
2205
+ await oauthManager.tokenStorage.save(token);
2206
+ console.error('🔍 [DEBUG] Token 保存完成');
2207
+ } catch (error) {
2208
+ console.error('❌ Token 保存失败:', error.message);
2209
+ throw error;
2210
+ }
2187
2211
 
2188
2212
  // 【新增】保存默认 Agent 名称和 deviceCode(首次记账时会获取真实名称)
2189
- await oauthManager.tokenStorage.saveAgentName('柴米AI助手');
2190
- await oauthManager.tokenStorage.saveDeviceCode(authState.deviceCode);
2213
+ try {
2214
+ await oauthManager.tokenStorage.saveAgentName('柴米AI助手');
2215
+ await oauthManager.tokenStorage.saveDeviceCode(authState.deviceCode);
2216
+ console.error('🔍 [DEBUG] Agent 名称和 deviceCode 保存完成');
2217
+ } catch (error) {
2218
+ console.error('❌ Agent 信息保存失败:', error.message);
2219
+ // 这个失败不影响授权,只记录日志
2220
+ }
2191
2221
 
2192
2222
  // 清除授权状态
2193
2223
  await oauthManager.clearAuthState();