(msg: Api.Message, buffer: Buffer, fileName: string, targetDir: string)
| 622 | |
| 623 | // DocumentAttributeFilename 由发送者控制,必须压成单个安全路径段, |
| 624 | // 避免 `../` 或绝对路径逃逸 /root/Openlist 或改变 OpenList 目标目录。 |
| 625 | fileName = sanitizeMediaFileName(fileName); |
| 626 | |
| 627 | await msg.edit({ text: `正在下载: ${htmlEscape(fileName)}`, parseMode: "html" }); |
| 628 | |
| 629 | const client = await getGlobalClient(); |
| 630 | const buffer = await client.downloadMedia(replyToMsg.media); |
| 631 | |
| 632 | if (!buffer || !(buffer instanceof Buffer)) { |
| 633 | await msg.edit({ text: "文件下载失败或格式不支持。" }); |
| 634 | return; |
| 635 | } |
| 636 | |
| 637 | if (finalPath) { |
| 638 | await this.uploadToOpenList(msg, buffer, fileName, finalPath); |
| 639 | } else { |
| 640 | const saveDir = "/root/Openlist"; |
| 641 | await fs.mkdir(saveDir, { recursive: true }); |
| 642 | const savePath = path.join(saveDir, fileName); |
| 643 | await fs.writeFile(savePath, buffer); |
| 644 | await msg.edit({ text: `文件已保存到: ${codeTag(savePath)}`, parseMode: "html" }); |
| 645 | } |
| 646 | } catch (error: any) { |
| 647 | await msg.edit({ text: `文件保存失败: ${htmlEscape(error?.message || error)}`, parseMode: "html" }); |
| 648 | } |
| 649 | } |
| 650 | |
| 651 | private async uploadToOpenList(msg: Api.Message, buffer: Buffer, fileName: string, targetDir: string) { |
| 652 | try { |
| 653 | await msg.edit({ text: "正在登录 OpenList API..." }); |
| 654 | const credentials = await this.getOpenListCredentials(); |
| 655 | if (!credentials) { |
| 656 | throw new Error("未找到 OpenList 凭证。\n请使用以下命令手动配置:\n`op login [用户名] [密码]`"); |
| 657 | } |
| 658 | |
| 659 | const token = await this.getOpenListToken(credentials.username, credentials.password); |
| 660 | if (!token) { |
| 661 | throw new Error("登录 OpenList 失败"); |
| 662 | } |
| 663 | |
| 664 | // 处理路径,确保是 API 友好的格式 |
| 665 | let fullPath = path.join(targetDir, fileName).replace(/\\/g, "/"); |
| 666 | if (!fullPath.startsWith("/")) fullPath = "/" + fullPath; |
| 667 | // 移除多余的斜杠 |
| 668 | fullPath = fullPath.replace(/\/+/g, "/"); |
| 669 | |
| 670 | await msg.edit({ text: `正在上传到: ${codeTag(fullPath)}`, parseMode: "html" }); |
no test coverage detected