argus-eye 0.1.0 → 0.2.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.
@@ -0,0 +1,5 @@
1
+ /** AES-256-GCM 加密。返回 base64(iv | tag | ciphertext)。 */
2
+ export declare function encryptBuffer(plain: Buffer, token: string): string;
3
+ export declare function decryptBuffer(payloadBase64: string, token: string): Buffer;
4
+ export declare const ENC_ALGO: "aes-256-gcm";
5
+ export type EncAlgo = typeof ENC_ALGO;
package/lib/index.mjs CHANGED
@@ -160,6 +160,37 @@ var FullscreenDetector = class {
160
160
  }
161
161
  };
162
162
 
163
+ // src/crypto.ts
164
+ import {
165
+ createCipheriv,
166
+ createDecipheriv,
167
+ randomBytes,
168
+ scryptSync
169
+ } from "node:crypto";
170
+ var ALGO = "aes-256-gcm";
171
+ var IV_LEN = 12;
172
+ var KEY_LEN = 32;
173
+ var SALT = Buffer.from("argus.peek.v1", "utf8");
174
+ var keyCache = /* @__PURE__ */ new Map();
175
+ function deriveKey(token) {
176
+ let key = keyCache.get(token);
177
+ if (key) return key;
178
+ key = scryptSync(token, SALT, KEY_LEN);
179
+ keyCache.set(token, key);
180
+ return key;
181
+ }
182
+ __name(deriveKey, "deriveKey");
183
+ function encryptBuffer(plain, token) {
184
+ const key = deriveKey(token);
185
+ const iv = randomBytes(IV_LEN);
186
+ const cipher = createCipheriv(ALGO, key, iv);
187
+ const ct = Buffer.concat([cipher.update(plain), cipher.final()]);
188
+ const tag2 = cipher.getAuthTag();
189
+ return Buffer.concat([iv, tag2, ct]).toString("base64");
190
+ }
191
+ __name(encryptBuffer, "encryptBuffer");
192
+ var ENC_ALGO = "aes-256-gcm";
193
+
163
194
  // src/client.ts
164
195
  var HEARTBEAT_TIMEOUT_MS = 9e4;
165
196
  var ArgusClient = class {
@@ -364,18 +395,19 @@ var ArgusClient = class {
364
395
  display: target,
365
396
  format: this.config.format
366
397
  });
367
- const base64 = result.buffer.toString("base64");
398
+ const payload = encryptBuffer(result.buffer, this.config.token);
368
399
  this.send({
369
400
  type: "peek_result",
370
401
  id: frame.id,
371
- image: base64,
402
+ image: payload,
403
+ enc: ENC_ALGO,
372
404
  mime: result.mime,
373
405
  display: frame.display
374
406
  });
375
407
  const elapsed = Date.now() - start2;
376
408
  const kb = (result.buffer.length / 1024).toFixed(1);
377
409
  logger.info(
378
- `peek #${frame.id} → display ${frame.display ?? "default"} (${kb} KB ${this.config.format}, ${elapsed}ms)`
410
+ `peek #${frame.id} → display ${frame.display ?? "default"} (${kb} KB ${this.config.format} encrypted, ${elapsed}ms)`
379
411
  );
380
412
  } catch (err) {
381
413
  const message = err instanceof Error ? err.message : String(err);
package/lib/protocol.d.ts CHANGED
@@ -27,6 +27,7 @@ export interface PeekResultFrame {
27
27
  type: 'peek_result';
28
28
  id: string;
29
29
  image: string;
30
+ enc?: 'aes-256-gcm' | 'none';
30
31
  mime?: string;
31
32
  width?: number;
32
33
  height?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argus-eye",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Argus eye —— koishi-plugin-argus 的截图客户端 CLI。",
6
6
  "author": "dingyi222666 <dingyi222666@foxmail.com>",
package/readme.md CHANGED
@@ -60,6 +60,12 @@ CLI 默认开启全屏检测:当截屏时检测到当前焦点窗口铺满整
60
60
 
61
61
  环境变量:`ARGUS_SERVER` / `ARGUS_TOKEN` / `ARGUS_NAME`。
62
62
 
63
+ ## 加密
64
+
65
+ 截图 buffer 走 WebSocket 之前会用 `AES-256-GCM` 加密,key 由 `--token`
66
+ 经 scrypt 派生,IV 每帧随机。同一 token 的插件端会解出来;token 不对的
67
+ 中间人 / 抓包工具拿到的都是密文。
68
+
63
69
  ## 平台说明
64
70
 
65
71
  底层使用 [`screenshot-desktop`](https://www.npmjs.com/package/screenshot-desktop):