atm-droid 1.0.1 → 1.0.2

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/api.js +49 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "atm-droid",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "ATM Token Manager CLI - 跨平台 Factory Token 管理工具",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/api.js CHANGED
@@ -28,6 +28,27 @@ function generateSignature(data, timestamp, deviceId) {
28
28
  return hmac.digest('hex');
29
29
  }
30
30
 
31
+ // 解密服务器返回的数据
32
+ function decryptPayload(encryptedData, ivHex, tagHex) {
33
+ try {
34
+ const key = getEncryptionKey();
35
+ const iv = Buffer.from(ivHex, 'hex');
36
+ const tag = Buffer.from(tagHex, 'hex');
37
+ const encrypted = Buffer.from(encryptedData, 'hex');
38
+
39
+ const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
40
+ decipher.setAuthTag(tag);
41
+
42
+ let decrypted = decipher.update(encrypted, null, 'utf8');
43
+ decrypted += decipher.final('utf8');
44
+
45
+ return JSON.parse(decrypted);
46
+ } catch (e) {
47
+ console.error('解密失败:', e.message);
48
+ return null;
49
+ }
50
+ }
51
+
31
52
  // 激活码登录
32
53
  async function activate(code) {
33
54
  const deviceId = getDeviceId();
@@ -51,19 +72,27 @@ async function getTokens() {
51
72
  throw new Error('未登录');
52
73
  }
53
74
 
75
+ const timestamp = Math.floor(Date.now() / 1000);
76
+ const signature = generateSignature(sessionToken, timestamp, deviceId);
77
+
54
78
  const response = await fetch(`${getServerUrl()}/api/v1/tokens`, {
55
79
  headers: {
56
80
  'Authorization': `Bearer ${sessionToken}`,
57
- 'X-Device-ID': deviceId
81
+ 'X-Device-ID': deviceId,
82
+ 'X-Timestamp': timestamp.toString(),
83
+ 'X-Signature': signature
58
84
  }
59
85
  });
60
86
 
61
87
  const result = await response.json();
62
88
 
63
89
  // 如果返回加密数据,需要解密
64
- if (result.success && result.data && result.iv) {
65
- // 简化版:假设服务器返回明文(或添加解密逻辑)
66
- return result;
90
+ if (result.success && result.data && result.iv && result.tag) {
91
+ const decrypted = decryptPayload(result.data, result.iv, result.tag);
92
+ if (decrypted) {
93
+ return { success: true, data: decrypted };
94
+ }
95
+ return { success: false, error: '解密失败' };
67
96
  }
68
97
 
69
98
  return result;
@@ -73,13 +102,17 @@ async function getTokens() {
73
102
  async function activateToken(tokenId) {
74
103
  const sessionToken = config.get('sessionToken');
75
104
  const deviceId = getDeviceId();
105
+ const timestamp = Math.floor(Date.now() / 1000);
106
+ const signature = generateSignature(sessionToken, timestamp, deviceId);
76
107
 
77
108
  const response = await fetch(`${getServerUrl()}/api/v1/tokens/activate`, {
78
109
  method: 'POST',
79
110
  headers: {
80
111
  'Content-Type': 'application/json',
81
112
  'Authorization': `Bearer ${sessionToken}`,
82
- 'X-Device-ID': deviceId
113
+ 'X-Device-ID': deviceId,
114
+ 'X-Timestamp': timestamp.toString(),
115
+ 'X-Signature': signature
83
116
  },
84
117
  body: JSON.stringify({ token_id: tokenId })
85
118
  });
@@ -94,12 +127,17 @@ async function heartbeat() {
94
127
 
95
128
  if (!sessionToken) return { valid: false };
96
129
 
130
+ const timestamp = Math.floor(Date.now() / 1000);
131
+ const signature = generateSignature(sessionToken, timestamp, deviceId);
132
+
97
133
  const response = await fetch(`${getServerUrl()}/api/v1/auth/heartbeat`, {
98
134
  method: 'POST',
99
135
  headers: {
100
136
  'Content-Type': 'application/json',
101
137
  'Authorization': `Bearer ${sessionToken}`,
102
- 'X-Device-ID': deviceId
138
+ 'X-Device-ID': deviceId,
139
+ 'X-Timestamp': timestamp.toString(),
140
+ 'X-Signature': signature
103
141
  }
104
142
  });
105
143
 
@@ -110,13 +148,17 @@ async function heartbeat() {
110
148
  async function unbind() {
111
149
  const sessionToken = config.get('sessionToken');
112
150
  const deviceId = getDeviceId();
151
+ const timestamp = Math.floor(Date.now() / 1000);
152
+ const signature = generateSignature(sessionToken, timestamp, deviceId);
113
153
 
114
154
  const response = await fetch(`${getServerUrl()}/api/v1/auth/unbind`, {
115
155
  method: 'POST',
116
156
  headers: {
117
157
  'Content-Type': 'application/json',
118
158
  'Authorization': `Bearer ${sessionToken}`,
119
- 'X-Device-ID': deviceId
159
+ 'X-Device-ID': deviceId,
160
+ 'X-Timestamp': timestamp.toString(),
161
+ 'X-Signature': signature
120
162
  }
121
163
  });
122
164