pi-courier 0.1.44 → 0.1.45
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 +17 -0
- package/README.zh-CN.md +17 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/rpc/message-router.d.ts +13 -1
- package/dist/rpc/message-router.d.ts.map +1 -1
- package/dist/rpc/message-router.js +66 -3
- package/dist/rpc/message-router.js.map +1 -1
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +15 -0
- package/dist/setup.js.map +1 -1
- package/dist/standalone.d.ts.map +1 -1
- package/dist/standalone.js +12 -0
- package/dist/standalone.js.map +1 -1
- package/dist/transports/attachments.d.ts +54 -0
- package/dist/transports/attachments.d.ts.map +1 -0
- package/dist/transports/attachments.js +143 -0
- package/dist/transports/attachments.js.map +1 -0
- package/dist/transports/matrix-utils.d.ts +55 -0
- package/dist/transports/matrix-utils.d.ts.map +1 -1
- package/dist/transports/matrix-utils.js +75 -7
- package/dist/transports/matrix-utils.js.map +1 -1
- package/dist/transports/matrix-utils.test.js +94 -3
- package/dist/transports/matrix-utils.test.js.map +1 -1
- package/dist/transports/matrix.d.ts +30 -0
- package/dist/transports/matrix.d.ts.map +1 -1
- package/dist/transports/matrix.js +127 -14
- package/dist/transports/matrix.js.map +1 -1
- package/dist/types.d.ts +39 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { EncryptedMediaFile } from "./matrix-utils.js";
|
|
2
|
+
/** Where bytes come from — the transport-specific half (Matrix client). */
|
|
3
|
+
export interface MediaSource {
|
|
4
|
+
downloadPlaintext(mxcUrl: string): Promise<Buffer>;
|
|
5
|
+
/** Present only when the deployment runs with E2EE crypto available. */
|
|
6
|
+
downloadEncrypted?(file: EncryptedMediaFile): Promise<Buffer>;
|
|
7
|
+
}
|
|
8
|
+
export interface AttachmentStoreConfig {
|
|
9
|
+
/** Root directory; one subdirectory per room. */
|
|
10
|
+
rootDir: string;
|
|
11
|
+
/** Hard cap per attachment in bytes (pre-checked against the event's
|
|
12
|
+
* declared size, re-checked against real bytes after download). */
|
|
13
|
+
maxBytes: number;
|
|
14
|
+
}
|
|
15
|
+
export interface SavedAttachment {
|
|
16
|
+
/** Absolute path of the file on disk */
|
|
17
|
+
path: string;
|
|
18
|
+
/** Sanitized filename (hash prefix + safe body) */
|
|
19
|
+
filename: string;
|
|
20
|
+
/** Real byte count as written */
|
|
21
|
+
bytes: number;
|
|
22
|
+
}
|
|
23
|
+
/** Input for one save: the classified media payload of a Matrix event. */
|
|
24
|
+
export interface IncomingMedia {
|
|
25
|
+
mxcUrl?: string;
|
|
26
|
+
encryptedFile?: EncryptedMediaFile;
|
|
27
|
+
/** Raw event body (Element sends the filename here). */
|
|
28
|
+
body: string;
|
|
29
|
+
/** Declared size from info.size — a hint, never trusted (servers lie). */
|
|
30
|
+
sizeHint?: number;
|
|
31
|
+
}
|
|
32
|
+
/** 附件超过大小上限 — 带上预检用的声明值与实际上限,文案在 message 里。 */
|
|
33
|
+
export declare class AttachmentTooLargeError extends Error {
|
|
34
|
+
constructor(declaredBytes: number, maxBytes: number);
|
|
35
|
+
}
|
|
36
|
+
/** 下载/解密 I/O 失败 — message 直接可用于房间回执。 */
|
|
37
|
+
export declare class AttachmentDownloadError extends Error {
|
|
38
|
+
constructor(detail: string);
|
|
39
|
+
}
|
|
40
|
+
/** 房间 ID → 安全子目录名("!abc:server" 含 ! 与 :,全部替换 + 哈希防碰撞)。 */
|
|
41
|
+
export declare function sanitizeRoomKey(roomId: string): string;
|
|
42
|
+
export declare function formatBytes(bytes: number): string;
|
|
43
|
+
export declare class AttachmentStore {
|
|
44
|
+
private config;
|
|
45
|
+
private source;
|
|
46
|
+
/** mxc:// → 已存绝对路径(票3):同一张图被转发/重发时不二次下载。 */
|
|
47
|
+
private dedup;
|
|
48
|
+
constructor(config: AttachmentStoreConfig, source: MediaSource);
|
|
49
|
+
/** Download (or reuse) and persist one media payload. Throws
|
|
50
|
+
* AttachmentTooLargeError / AttachmentDownloadError with user-ready
|
|
51
|
+
* messages; callers forward the message verbatim to the room receipt. */
|
|
52
|
+
save(roomId: string, media: IncomingMedia): Promise<SavedAttachment>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=attachments.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.d.ts","sourceRoot":"","sources":["../../src/transports/attachments.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAG5D,2EAA2E;AAC3E,MAAM,WAAW,WAAW;IAC1B,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,wEAAwE;IACxE,iBAAiB,CAAC,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,qBAAqB;IACpC,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB;wEACoE;IACpE,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,+CAA+C;AAC/C,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;CAIpD;AAED,wCAAwC;AACxC,qBAAa,uBAAwB,SAAQ,KAAK;gBACpC,MAAM,EAAE,MAAM;CAI3B;AAKD,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,qBAAa,eAAe;IAKxB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IALhB,4CAA4C;IAC5C,OAAO,CAAC,KAAK,CAA6B;gBAGhC,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,WAAW;IAG7B;;8EAE0E;IACpE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC;CAoD3E"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attachment storage (issue #66) — the bridge is a porter, not a translator:
|
|
3
|
+
* it downloads media bytes from the homeserver to a global on-disk directory
|
|
4
|
+
* and hands the ABSOLUTE PATH to the router, which injects it into the next
|
|
5
|
+
* prompt. The pi subprocess reads files with its own `read` tool (no sandbox,
|
|
6
|
+
* absolute paths fine) — no base64 over the RPC wire.
|
|
7
|
+
*
|
|
8
|
+
* The download seam (MediaSource) is injectable: tests use fakes, the
|
|
9
|
+
* composition root backs it with matrix-bot-sdk downloadContent /
|
|
10
|
+
* crypto.decryptMedia.
|
|
11
|
+
*/
|
|
12
|
+
import { createHash } from "node:crypto";
|
|
13
|
+
import * as fs from "node:fs";
|
|
14
|
+
import * as path from "node:path";
|
|
15
|
+
import { sanitizeMediaFilename } from "./matrix-utils.js";
|
|
16
|
+
/** 附件超过大小上限 — 带上预检用的声明值与实际上限,文案在 message 里。 */
|
|
17
|
+
export class AttachmentTooLargeError extends Error {
|
|
18
|
+
constructor(declaredBytes, maxBytes) {
|
|
19
|
+
super(`附件过大(${formatBytes(declaredBytes)} > 上限 ${formatBytes(maxBytes)}),未保存。请压缩后重发,或让管理员调大 attachments.maxMb 配置。`);
|
|
20
|
+
this.name = "AttachmentTooLargeError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** 下载/解密 I/O 失败 — message 直接可用于房间回执。 */
|
|
24
|
+
export class AttachmentDownloadError extends Error {
|
|
25
|
+
constructor(detail) {
|
|
26
|
+
super(`附件下载失败: ${detail}`);
|
|
27
|
+
this.name = "AttachmentDownloadError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** 单附件下载超时(ms):挂起的下载不能让"失败必回执"变成"永不回执"。 */
|
|
31
|
+
const DOWNLOAD_TIMEOUT_MS = 60_000;
|
|
32
|
+
/** 房间 ID → 安全子目录名("!abc:server" 含 ! 与 :,全部替换 + 哈希防碰撞)。 */
|
|
33
|
+
export function sanitizeRoomKey(roomId) {
|
|
34
|
+
const hash = createHash("sha256").update(roomId).digest("hex").slice(0, 8);
|
|
35
|
+
const safe = roomId.replace(/[^A-Za-z0-9._-]/g, "_");
|
|
36
|
+
return `${safe}-${hash}`;
|
|
37
|
+
}
|
|
38
|
+
export function formatBytes(bytes) {
|
|
39
|
+
if (bytes >= 1024 * 1024)
|
|
40
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
41
|
+
if (bytes >= 1024)
|
|
42
|
+
return `${(bytes / 1024).toFixed(0)} KB`;
|
|
43
|
+
return `${bytes} B`;
|
|
44
|
+
}
|
|
45
|
+
export class AttachmentStore {
|
|
46
|
+
config;
|
|
47
|
+
source;
|
|
48
|
+
/** mxc:// → 已存绝对路径(票3):同一张图被转发/重发时不二次下载。 */
|
|
49
|
+
dedup = new Map();
|
|
50
|
+
constructor(config, source) {
|
|
51
|
+
this.config = config;
|
|
52
|
+
this.source = source;
|
|
53
|
+
}
|
|
54
|
+
/** Download (or reuse) and persist one media payload. Throws
|
|
55
|
+
* AttachmentTooLargeError / AttachmentDownloadError with user-ready
|
|
56
|
+
* messages; callers forward the message verbatim to the room receipt. */
|
|
57
|
+
async save(roomId, media) {
|
|
58
|
+
const mxcKey = media.encryptedFile?.url ?? media.mxcUrl;
|
|
59
|
+
if (!mxcKey) {
|
|
60
|
+
throw new AttachmentDownloadError("事件中没有可下载的媒体地址");
|
|
61
|
+
}
|
|
62
|
+
// Dedup (ticket 3): a forwarded/re-sent mxc maps to the existing file.
|
|
63
|
+
// A mapped file that vanished from disk (manual cleanup) re-downloads.
|
|
64
|
+
const known = this.dedup.get(mxcKey);
|
|
65
|
+
if (known) {
|
|
66
|
+
const bytes = await statSize(known).catch(() => -1);
|
|
67
|
+
if (bytes >= 0) {
|
|
68
|
+
return { path: known, filename: path.basename(known), bytes };
|
|
69
|
+
}
|
|
70
|
+
this.dedup.delete(mxcKey);
|
|
71
|
+
}
|
|
72
|
+
// Pre-check against the DECLARED size (cheap rejection before download).
|
|
73
|
+
if (media.sizeHint !== undefined && media.sizeHint > this.config.maxBytes) {
|
|
74
|
+
throw new AttachmentTooLargeError(media.sizeHint, this.config.maxBytes);
|
|
75
|
+
}
|
|
76
|
+
let data;
|
|
77
|
+
try {
|
|
78
|
+
if (media.encryptedFile) {
|
|
79
|
+
if (!this.source.downloadEncrypted) {
|
|
80
|
+
throw new Error("加密附件需要启用 E2EE(部署未开启加密或 crypto 原生库不可用)");
|
|
81
|
+
}
|
|
82
|
+
data = await withTimeout(this.source.downloadEncrypted(media.encryptedFile));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
data = await withTimeout(this.source.downloadPlaintext(mxcKey));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
if (err instanceof AttachmentTooLargeError)
|
|
90
|
+
throw err;
|
|
91
|
+
throw new AttachmentDownloadError(err.message);
|
|
92
|
+
}
|
|
93
|
+
// Re-check against REAL bytes — info.size is a hint, servers lie.
|
|
94
|
+
if (data.length > this.config.maxBytes) {
|
|
95
|
+
throw new AttachmentTooLargeError(data.length, this.config.maxBytes);
|
|
96
|
+
}
|
|
97
|
+
const dir = path.join(this.config.rootDir, sanitizeRoomKey(roomId));
|
|
98
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
99
|
+
const filename = sanitizeMediaFilename(media.body, mxcKey);
|
|
100
|
+
const target = await uniqueTarget(dir, filename);
|
|
101
|
+
await fs.promises.writeFile(target, data, { mode: 0o600 });
|
|
102
|
+
this.dedup.set(mxcKey, target);
|
|
103
|
+
return { path: target, filename: path.basename(target), bytes: data.length };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** 同名不覆盖:哈希前缀已使碰撞近乎不可能,仍按 -1/-2 递增兜底(确定性)。 */
|
|
107
|
+
async function uniqueTarget(dir, filename) {
|
|
108
|
+
let target = path.join(dir, filename);
|
|
109
|
+
const ext = path.extname(filename);
|
|
110
|
+
const stem = filename.slice(0, filename.length - ext.length);
|
|
111
|
+
// 存在性判定用 stat 成败而非字节数 — 0 字节的同名文件同样不许被覆盖。
|
|
112
|
+
for (let i = 1; await pathExists(target); i++) {
|
|
113
|
+
target = path.join(dir, `${stem}-${i}${ext}`);
|
|
114
|
+
}
|
|
115
|
+
return target;
|
|
116
|
+
}
|
|
117
|
+
async function pathExists(p) {
|
|
118
|
+
try {
|
|
119
|
+
await fs.promises.access(p);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
async function statSize(p) {
|
|
127
|
+
const st = await fs.promises.stat(p);
|
|
128
|
+
return st.size;
|
|
129
|
+
}
|
|
130
|
+
function withTimeout(p) {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
const timer = setTimeout(() => reject(new Error(`下载超时(${DOWNLOAD_TIMEOUT_MS / 1000}s)`)), DOWNLOAD_TIMEOUT_MS);
|
|
133
|
+
timer.unref?.();
|
|
134
|
+
p.then((v) => {
|
|
135
|
+
clearTimeout(timer);
|
|
136
|
+
resolve(v);
|
|
137
|
+
}, (e) => {
|
|
138
|
+
clearTimeout(timer);
|
|
139
|
+
reject(e);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=attachments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachments.js","sourceRoot":"","sources":["../../src/transports/attachments.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,61 @@ export declare function formatForMatrix(text: string): {
|
|
|
3
3
|
body: string;
|
|
4
4
|
formattedBody?: string;
|
|
5
5
|
};
|
|
6
|
+
/** 加密附件块(EncryptedFileInfo)的最小结构视图 — 与 matrix-bot-sdk 的
|
|
7
|
+
* MessageEvent.EncryptedFile 结构兼容,避免本模块依赖 SDK。 */
|
|
8
|
+
export interface EncryptedMediaFile {
|
|
9
|
+
url: string;
|
|
10
|
+
key: {
|
|
11
|
+
k: string;
|
|
12
|
+
};
|
|
13
|
+
iv: string;
|
|
14
|
+
hashes: {
|
|
15
|
+
sha256: string;
|
|
16
|
+
};
|
|
17
|
+
v?: string;
|
|
18
|
+
}
|
|
19
|
+
/** 媒体事件内容的分类视图(纯结构,来自 event.content)。 */
|
|
20
|
+
export interface MediaEventContent {
|
|
21
|
+
/** mxc:// 明文地址(加密附件时可能缺失 — 以 file 为准) */
|
|
22
|
+
url?: string;
|
|
23
|
+
/** 加密附件块(E2EE 房间);与 url 并存时优先 */
|
|
24
|
+
file?: EncryptedMediaFile;
|
|
25
|
+
/** 原始文件名(Element 粘贴发送时通常是 image.png 之类) */
|
|
26
|
+
body?: string;
|
|
27
|
+
/** 事件声明的元信息 — size 仅作超限预检,不作为信任依据 */
|
|
28
|
+
info?: {
|
|
29
|
+
size?: number;
|
|
30
|
+
mimetype?: string;
|
|
31
|
+
w?: number;
|
|
32
|
+
h?: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/** 当前按媒体处理的类型全集(票3):m.image/m.file/m.audio/m.video 四种
|
|
36
|
+
* msgtype 内容同构;m.sticker 是事件类型(内容同构但无 msgtype 字段)。 */
|
|
37
|
+
export declare const MEDIA_MSGTYPES: Set<string>;
|
|
38
|
+
/** Classification of one room message content (issue #66 票1). */
|
|
39
|
+
export type MessageContentClassification = {
|
|
40
|
+
kind: "text";
|
|
41
|
+
} | {
|
|
42
|
+
kind: "media";
|
|
43
|
+
msgtype: string;
|
|
44
|
+
mxcUrl?: string;
|
|
45
|
+
encryptedFile?: EncryptedMediaFile;
|
|
46
|
+
filename: string;
|
|
47
|
+
sizeHint?: number;
|
|
48
|
+
} | {
|
|
49
|
+
kind: "other";
|
|
50
|
+
msgtype: string;
|
|
51
|
+
};
|
|
52
|
+
/** 判断内容是否携带媒体载荷(url 明文或 file 加密块)。 */
|
|
53
|
+
export declare function isMediaContent(content: unknown): content is MediaEventContent;
|
|
54
|
+
/** 对一条房间消息内容做分类:文本 / 媒体(带下载所需信息) / 其他。 */
|
|
55
|
+
export declare function classifyMessageContent(content: unknown): MessageContentClassification;
|
|
56
|
+
/**
|
|
57
|
+
* 文件名消毒(issue #66 票1):防路径穿越/分隔符注入,输出确定性的
|
|
58
|
+
* "<mxc mediaId 哈希前缀>-<安全化原名>"。body 为空时回退 "file"。
|
|
59
|
+
*/
|
|
60
|
+
export declare function sanitizeMediaFilename(body: string | undefined, mxcUrl: string): string;
|
|
6
61
|
/**
|
|
7
62
|
* Determine whether to skip a Matrix room event before processing.
|
|
8
63
|
* Returns a reason string if the event should be skipped, or null if it should be processed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matrix-utils.d.ts","sourceRoot":"","sources":["../../src/transports/matrix-utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"matrix-utils.d.ts","sourceRoot":"","sources":["../../src/transports/matrix-utils.ts"],"names":[],"mappings":"AAYA,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,CAEtF;AAID;mDACmD;AACnD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE;QAAE,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,CAAC,CAAC,EAAE,MAAM,CAAC;CACZ;AAED,yCAAyC;AACzC,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,IAAI,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrE;AAED;uDACuD;AACvD,eAAO,MAAM,cAAc,aAA4E,CAAC;AAExG,iEAAiE;AACjE,MAAM,MAAM,4BAA4B,GACpC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,kBAAkB,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5H;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,sCAAsC;AACtC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,IAAI,iBAAiB,CAI7E;AAED,0CAA0C;AAC1C,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,4BAA4B,CAuBrF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAUtF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,GAAG,CAAA;CAAE,EACpE,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,EACxB,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CA8Bf;AAQD,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAM/E;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAOvE;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAEnF"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Pure utility functions for Matrix transport.
|
|
3
3
|
* Extracted for testability — no SDK or network dependencies.
|
|
4
4
|
*/
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
import MarkdownIt from "markdown-it";
|
|
6
7
|
// html:false escapes raw HTML (pi output must never inject tags);
|
|
7
8
|
// breaks:true keeps chat-style single newlines as <br>;
|
|
@@ -11,6 +12,57 @@ const md = new MarkdownIt({ html: false, breaks: true, linkify: true });
|
|
|
11
12
|
export function formatForMatrix(text) {
|
|
12
13
|
return { body: text, formattedBody: md.render(text).trim() };
|
|
13
14
|
}
|
|
15
|
+
/** 当前按媒体处理的类型全集(票3):m.image/m.file/m.audio/m.video 四种
|
|
16
|
+
* msgtype 内容同构;m.sticker 是事件类型(内容同构但无 msgtype 字段)。 */
|
|
17
|
+
export const MEDIA_MSGTYPES = new Set(["m.image", "m.file", "m.audio", "m.video", "m.sticker"]);
|
|
18
|
+
/** 判断内容是否携带媒体载荷(url 明文或 file 加密块)。 */
|
|
19
|
+
export function isMediaContent(content) {
|
|
20
|
+
if (typeof content !== "object" || content === null)
|
|
21
|
+
return false;
|
|
22
|
+
const c = content;
|
|
23
|
+
return typeof c.url === "string" || typeof c.file === "object";
|
|
24
|
+
}
|
|
25
|
+
/** 对一条房间消息内容做分类:文本 / 媒体(带下载所需信息) / 其他。 */
|
|
26
|
+
export function classifyMessageContent(content) {
|
|
27
|
+
if (isMediaContent(content)) {
|
|
28
|
+
const c = content;
|
|
29
|
+
// m.sticker 事件的内容不带 msgtype(它是事件类型,非 m.room.message);
|
|
30
|
+
// 带媒体载荷却缺 msgtype 的只会是 sticker(m.room.message 必有 msgtype)。
|
|
31
|
+
const msgtype = typeof c.msgtype === "string" && c.msgtype ? c.msgtype : "m.sticker";
|
|
32
|
+
if (MEDIA_MSGTYPES.has(msgtype)) {
|
|
33
|
+
return {
|
|
34
|
+
kind: "media",
|
|
35
|
+
msgtype,
|
|
36
|
+
// 加密附件与明文 url 并存时以加密版优先(票2 裁决)
|
|
37
|
+
...(c.file ? { encryptedFile: c.file } : { mxcUrl: c.url }),
|
|
38
|
+
filename: c.body ?? "",
|
|
39
|
+
...(typeof c.info?.size === "number" ? { sizeHint: c.info.size } : {}),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return { kind: "other", msgtype };
|
|
43
|
+
}
|
|
44
|
+
// 无媒体载荷:m.text / m.emote 走文本管道,其余(如 m.location)是
|
|
45
|
+
// "other" — 由 router 回执礼貌提示(票3 消灭静默吞消息)。
|
|
46
|
+
const msgtype = content?.msgtype;
|
|
47
|
+
if (msgtype === "m.text" || msgtype === "m.emote")
|
|
48
|
+
return { kind: "text" };
|
|
49
|
+
return { kind: "other", msgtype: msgtype || "(unknown)" };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* 文件名消毒(issue #66 票1):防路径穿越/分隔符注入,输出确定性的
|
|
53
|
+
* "<mxc mediaId 哈希前缀>-<安全化原名>"。body 为空时回退 "file"。
|
|
54
|
+
*/
|
|
55
|
+
export function sanitizeMediaFilename(body, mxcUrl) {
|
|
56
|
+
const hash = createHash("sha256").update(mxcUrl).digest("hex").slice(0, 12);
|
|
57
|
+
const base = (body ?? "").split(/[/\\]/).pop() ?? "";
|
|
58
|
+
const cleaned = base
|
|
59
|
+
.replace(/[\x00-\x1f\x7f]/g, "") // 控制字符
|
|
60
|
+
.replace(/\s+/g, " ")
|
|
61
|
+
.replace(/^\.+/, "") // 防 ".."/"."
|
|
62
|
+
.trim();
|
|
63
|
+
const safe = cleaned.length > 0 ? cleaned : "file";
|
|
64
|
+
return `${hash}-${safe.slice(0, 150)}`;
|
|
65
|
+
}
|
|
14
66
|
/**
|
|
15
67
|
* Determine whether to skip a Matrix room event before processing.
|
|
16
68
|
* Returns a reason string if the event should be skipped, or null if it should be processed.
|
|
@@ -23,18 +75,34 @@ export function shouldSkipEvent(event, botUserId, connectedAt, joinedRooms, room
|
|
|
23
75
|
const eventTs = event.origin_server_ts || 0;
|
|
24
76
|
if (eventTs < connectedAt)
|
|
25
77
|
return "stale";
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
78
|
+
// m.notice stays silent in every branch (issue #66 票3: the ONE deliberate
|
|
79
|
+
// silence — other bots/services' notices must not trigger receipts or the
|
|
80
|
+
// bot loops).
|
|
81
|
+
if (event.content?.msgtype === "m.notice")
|
|
82
|
+
return "notice";
|
|
83
|
+
// Media events (issue #66) flow through the attachment path. Everything
|
|
84
|
+
// else with a body flows on too: m.text/m.emote are classified as text,
|
|
85
|
+
// exotic msgtypes (m.location…) reach the router's polite receipt — the
|
|
86
|
+
// filter itself no longer silently drops them (票3). Only body-less
|
|
87
|
+
// messages and edits stay skipped here.
|
|
88
|
+
if (!isMediaEventContent(event.content)) {
|
|
89
|
+
const content = event.content;
|
|
90
|
+
if (!content?.body)
|
|
91
|
+
return "not_text";
|
|
92
|
+
// Ignore edits (we only process original messages)
|
|
93
|
+
if (content["m.new_content"])
|
|
94
|
+
return "edit";
|
|
95
|
+
}
|
|
33
96
|
// Skip events from rooms we're not in (cached, no API call)
|
|
34
97
|
if (!joinedRooms.has(roomId))
|
|
35
98
|
return "not_joined";
|
|
36
99
|
return null;
|
|
37
100
|
}
|
|
101
|
+
/** shouldSkipEvent 用的窄判别:内容带媒体载荷即视为媒体事件(不查白名单 —
|
|
102
|
+
* 白名单归类由 classifyMessageContent 负责,m.file 等在票3 前落入 "other")。 */
|
|
103
|
+
function isMediaEventContent(content) {
|
|
104
|
+
return isMediaContent(content) && typeof content.msgtype === "string";
|
|
105
|
+
}
|
|
38
106
|
/** Extract Matrix username (localpart) from a full MXID like @user:matrix.org */
|
|
39
107
|
export function extractUsername(userId) {
|
|
40
108
|
return userId.replace(/^@/, "").replace(/:.*$/, "");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matrix-utils.js","sourceRoot":"","sources":["../../src/transports/matrix-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,UAAU,MAAM,aAAa,CAAC;AAErC,kEAAkE;AAClE,wDAAwD;AACxD,sCAAsC;AACtC,MAAM,EAAE,GAAG,IAAI,UAAU,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AAExE,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,KAAoE,EACpE,SAAiB,EACjB,WAAmB,EACnB,WAAwB,EACxB,MAAc;IAEd,sBAAsB;IACtB,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,aAAa,CAAC;IAErD,2EAA2E;IAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,gBAAgB,IAAI,CAAC,CAAC;IAC5C,IAAI,OAAO,GAAG,WAAW;QAAE,OAAO,OAAO,CAAC;IAE1C,
|
|
1
|
+
{"version":3,"file":"matrix-utils.js","sourceRoot":"","sources":["../../src/transports/matrix-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fc from "fast-check";
|
|
2
2
|
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { extractUsername, formatForMatrix, isGroupChatRoom, shouldPostJoinHint, shouldSkipEvent, stripBotMention, wasBotMentioned, } from "./matrix-utils.js";
|
|
3
|
+
import { classifyMessageContent, extractUsername, formatForMatrix, isGroupChatRoom, sanitizeMediaFilename, shouldPostJoinHint, shouldSkipEvent, stripBotMention, wasBotMentioned, } from "./matrix-utils.js";
|
|
4
4
|
// ─── formatForMatrix ──────────────────────────────────────────
|
|
5
5
|
describe("formatForMatrix", () => {
|
|
6
6
|
it("renders plain text as a paragraph, body preserved", () => {
|
|
@@ -102,9 +102,25 @@ describe("shouldSkipEvent", () => {
|
|
|
102
102
|
expect(shouldSkipEvent(makeEvent({ origin_server_ts: 999 }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org"))
|
|
103
103
|
.toBe("stale");
|
|
104
104
|
});
|
|
105
|
-
it("
|
|
105
|
+
it("lets body-carrying exotic msgtypes through (m.location → router's polite receipt, 票3)", () => {
|
|
106
|
+
expect(shouldSkipEvent(makeEvent({ content: { msgtype: "m.location", geo_uri: "geo:0,0", body: "Location" } }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org"))
|
|
107
|
+
.toBeNull();
|
|
108
|
+
});
|
|
109
|
+
it("lets media events through (m.image with url) — attachment path handles them (#67)", () => {
|
|
110
|
+
expect(shouldSkipEvent(makeEvent({ content: { msgtype: "m.image", body: "photo.png", url: "mxc://server/abc123" } }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org")).toBeNull();
|
|
111
|
+
});
|
|
112
|
+
it("lets encrypted media events through (m.image with file block)", () => {
|
|
113
|
+
expect(shouldSkipEvent(makeEvent({ content: { msgtype: "m.image", body: "photo.png", file: { url: "mxc://server/enc1", key: { k: "x" }, iv: "y", hashes: { sha256: "z" } } } }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org")).toBeNull();
|
|
114
|
+
});
|
|
115
|
+
it("skips m.notice silently (the ONE deliberate silence — bot-loop guard)", () => {
|
|
116
|
+
expect(shouldSkipEvent(makeEvent({ content: { msgtype: "m.notice", body: "* bot does things" } }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org")).toBe("notice");
|
|
117
|
+
});
|
|
118
|
+
it("lets m.emote through as text (票3:emote body 是可读文本)", () => {
|
|
119
|
+
expect(shouldSkipEvent(makeEvent({ content: { msgtype: "m.emote", body: "waves hello" } }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org")).toBeNull();
|
|
120
|
+
});
|
|
121
|
+
it("lets payload-less media msgtypes through too (→ polite receipt path, 票3)", () => {
|
|
106
122
|
expect(shouldSkipEvent(makeEvent({ content: { msgtype: "m.image", body: "photo" } }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org"))
|
|
107
|
-
.
|
|
123
|
+
.toBeNull();
|
|
108
124
|
});
|
|
109
125
|
it("skips messages with no content", () => {
|
|
110
126
|
expect(shouldSkipEvent(makeEvent({ content: undefined }), botUserId, connectedAt, joinedRooms, "!room1:matrix.org"))
|
|
@@ -244,4 +260,79 @@ describe("shouldPostJoinHint", () => {
|
|
|
244
260
|
// - sendMessage()/sendTyping() (thin SDK wrappers)
|
|
245
261
|
// - index.ts wiring (env var reading, command handler plumbing)
|
|
246
262
|
// - Widget abbreviation (mx)
|
|
263
|
+
// ─── 附件分类与文件名消毒(issue #66 票1,接缝1)──────────────────
|
|
264
|
+
describe("classifyMessageContent", () => {
|
|
265
|
+
it("classifies plain text as text", () => {
|
|
266
|
+
expect(classifyMessageContent({ msgtype: "m.text", body: "hi" })).toEqual({ kind: "text" });
|
|
267
|
+
});
|
|
268
|
+
it("classifies m.image with url as media carrying the mxc url", () => {
|
|
269
|
+
const c = classifyMessageContent({ msgtype: "m.image", body: "photo.png", url: "mxc://s/abc", info: { size: 123 } });
|
|
270
|
+
expect(c).toEqual({ kind: "media", msgtype: "m.image", mxcUrl: "mxc://s/abc", filename: "photo.png", sizeHint: 123 });
|
|
271
|
+
});
|
|
272
|
+
it("prefers the encrypted file block when url and file coexist (票2 裁决)", () => {
|
|
273
|
+
const file = { url: "mxc://s/enc", key: { k: "k" }, iv: "iv", hashes: { sha256: "h" } };
|
|
274
|
+
const c = classifyMessageContent({ msgtype: "m.image", body: "p.png", url: "mxc://s/plain", file });
|
|
275
|
+
expect(c).toMatchObject({ kind: "media", encryptedFile: file });
|
|
276
|
+
expect(c.kind !== "media" || c.mxcUrl === undefined).toBe(true);
|
|
277
|
+
});
|
|
278
|
+
it("classifies every media msgtype as media (票3:m.file/m.audio/m.video)", () => {
|
|
279
|
+
for (const msgtype of ["m.image", "m.file", "m.audio", "m.video"]) {
|
|
280
|
+
const c = classifyMessageContent({ msgtype, body: "x.bin", url: "mxc://s/m" });
|
|
281
|
+
expect(c).toMatchObject({ kind: "media", msgtype });
|
|
282
|
+
}
|
|
283
|
+
});
|
|
284
|
+
it("treats media-shaped content without msgtype as m.sticker (票3:事件类型非 msgtype)", () => {
|
|
285
|
+
const c = classifyMessageContent({ body: "sticker.png", url: "mxc://s/st" });
|
|
286
|
+
expect(c).toMatchObject({ kind: "media", msgtype: "m.sticker" });
|
|
287
|
+
});
|
|
288
|
+
it("classifies media-shaped content with unknown msgtype as other", () => {
|
|
289
|
+
expect(classifyMessageContent({ msgtype: "m.fancy", body: "x", url: "mxc://s/y" })).toEqual({ kind: "other", msgtype: "m.fancy" });
|
|
290
|
+
});
|
|
291
|
+
it("content without a media payload: m.text/m.emote → text, others → other (票3)", () => {
|
|
292
|
+
expect(classifyMessageContent({ msgtype: "m.text", body: "hi" })).toEqual({ kind: "text" });
|
|
293
|
+
expect(classifyMessageContent({ msgtype: "m.emote", body: "waves" })).toEqual({ kind: "text" });
|
|
294
|
+
expect(classifyMessageContent({ msgtype: "m.location", geo_uri: "geo:0,0", body: "Location" })).toEqual({ kind: "other", msgtype: "m.location" });
|
|
295
|
+
});
|
|
296
|
+
it("defaults filename to empty string when body is missing", () => {
|
|
297
|
+
const c = classifyMessageContent({ msgtype: "m.image", url: "mxc://s/abc" });
|
|
298
|
+
expect(c.kind === "media" && c.filename === "").toBe(true);
|
|
299
|
+
});
|
|
300
|
+
});
|
|
301
|
+
describe("sanitizeMediaFilename", () => {
|
|
302
|
+
it("prefixes a deterministic hash of the mxc url", () => {
|
|
303
|
+
expect(sanitizeMediaFilename("photo.png", "mxc://s/abc"))
|
|
304
|
+
.toBe(sanitizeMediaFilename("photo.png", "mxc://s/abc"));
|
|
305
|
+
expect(sanitizeMediaFilename("a.png", "mxc://s/1")).not.toBe(sanitizeMediaFilename("a.png", "mxc://s/2"));
|
|
306
|
+
});
|
|
307
|
+
it("strips path traversal components", () => {
|
|
308
|
+
const name = sanitizeMediaFilename("../../etc/passwd", "mxc://s/abc");
|
|
309
|
+
expect(name).not.toContain("..");
|
|
310
|
+
expect(name).not.toContain("/");
|
|
311
|
+
expect(name.endsWith("passwd")).toBe(true);
|
|
312
|
+
});
|
|
313
|
+
it("strips windows separators and control characters", () => {
|
|
314
|
+
const name = sanitizeMediaFilename("..\\..\\x\u0000y\r\n z.png", "mxc://s/abc");
|
|
315
|
+
expect(name).not.toMatch(/[\\/]/);
|
|
316
|
+
expect(name).not.toMatch(/[\x00-\x1f\x7f]/);
|
|
317
|
+
});
|
|
318
|
+
it("never starts with dots (hidden file / relative-path tricks)", () => {
|
|
319
|
+
expect(sanitizeMediaFilename("..hidden", "mxc://s/abc").endsWith("hidden")).toBe(true);
|
|
320
|
+
expect(sanitizeMediaFilename("..", "mxc://s/abc")).not.toContain("..");
|
|
321
|
+
});
|
|
322
|
+
it("falls back to 'file' when nothing safe remains", () => {
|
|
323
|
+
expect(sanitizeMediaFilename("", "mxc://s/abc")).toMatch(/^[0-9a-f]{12}-file$/);
|
|
324
|
+
expect(sanitizeMediaFilename(undefined, "mxc://s/abc")).toMatch(/^[0-9a-f]{12}-file$/);
|
|
325
|
+
});
|
|
326
|
+
it("property: output is safe for any input (no separators, no traversal, non-empty)", () => {
|
|
327
|
+
const mxc = fc.constant("mxc://server/mediaId");
|
|
328
|
+
const arbBody = fc.string({ maxLength: 300 });
|
|
329
|
+
fc.assert(fc.property(arbBody, mxc, (body, url) => {
|
|
330
|
+
const name = sanitizeMediaFilename(body, url);
|
|
331
|
+
expect(name.length).toBeGreaterThan(0);
|
|
332
|
+
expect(name).not.toMatch(/[/\\]/);
|
|
333
|
+
expect(name).not.toContain("..");
|
|
334
|
+
expect(name).toMatch(/^[0-9a-f]{12}-/);
|
|
335
|
+
}));
|
|
336
|
+
});
|
|
337
|
+
});
|
|
247
338
|
//# sourceMappingURL=matrix-utils.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matrix-utils.test.js","sourceRoot":"","sources":["../../src/transports/matrix-utils.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"matrix-utils.test.js","sourceRoot":"","sources":["../../src/transports/matrix-utils.test.ts"],"names":[],"mappings":"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"}
|