简介
为 Xiuno X 提供 LskyPro 图片存储支持,支持本地/LskyPro 模式切换、远端上传读取删除、重复上传保护、失败本地回退和后台状态监控。
功能
支持 LskyPro V1 / LskyPro V2 版本,支持本地与 LskyPro 相互切换,互不影响。
支持 更换 LskyPro 存储策略,支持远端相册。
如果 LskyPro 部署内网,支持放宽地址保护。
如果上传失败可以选择终止本次上传或保留本地(后台调整)。
上传成功后可直接清理临时图片,支持 SSL 证书校验,可选是否上传为公开图片。
文件结构
plugin/
└── suncosmos_lsky/
├── conf.json
│ # 插件名称、简介、版本、兼容 Xiuno X 版本和 Hook 注册配置
├── discover_register.php
│ # 向 Xiuno X 发现页注册 LskyPro 图片存储卡片
├── icon.png
│ # 插件图标
├── install.php
│ # 安装插件、创建数据表并写入默认配置
├── setting.php
│ # 后台设置入口,处理权限、CSRF、配置保存和连接测试
├── uninstall.php
│ # 卸载插件、切回本地存储并清理插件配置
├── upgrade.php
│ # 插件数据库结构和配置的幂等升级脚本
├── update.md
│ # 插件版本、API 适配、数据结构、安全机制和测试记录
│
├── hook/
│ ├── admin_attach_start.php
│ │ # 扩展后台附件处理流程,维护远端映射和异常状态
│ ├── admin_footer_footer_before.htm
│ │ # 在后台页脚结束前注入插件所需的收尾脚本或状态处理
│ ├── admin_footer_start.htm
│ │ # 在后台页脚开始位置加载插件前端资源和运行时数据
│ ├── admin_index_route_case_end.php
│ │ # 注册后台管理路由的 switch 分支
│ ├── admin_setting_upload_driver_register.php
│ │ # 将 suncosmos_lsky 注册为 Xiuno X 后台可选存储驱动
│ ├── attach_assoc_post_end.php
│ │ # 附件关联帖子完成后更新正文地址和远端映射状态
│ ├── attach_assoc_post_start.php
│ │ # 附件关联帖子前识别和归一化远端图片地址
│ ├── footer_main_end.htm
│ │ # 在前台主体底部注入插件需要的页面扩展内容
│ ├── footer_start.htm
│ │ # 在前台页脚开始位置准备插件资源和运行时状态
│ ├── index_route_case_end.php
│ │ # 注册前台状态和管理相关路由的 switch 分支
│ ├── lang_en_us_bbs.php
│ │ # 扩展 Xiuno X 英文前台语言数组
│ ├── lang_zh_cn_bbs.php
│ │ # 扩展 Xiuno X 简体中文前台语言数组
│ ├── lang_zh_tw_bbs.php
│ │ # 扩展 Xiuno X 繁体中文前台语言数组
│ ├── model_attach_create_end.php
│ │ # 附件主记录创建后回写附件 ID 和远端关联信息
│ ├── model_attach_delete_by_pid_start.php
│ │ # 按帖子 ID 删除附件前同步处理远端映射
│ ├── model_attach_delete_by_uid_start.php
│ │ # 按用户 ID 删除附件前同步处理远端映射
│ ├── model_attach_delete_start.php
│ │ # 删除单个附件前准备远端文件删除流程
│ ├── model_post_delete_by_tid_start.php
│ │ # 删除主题前处理主题内附件的远端映射
│ ├── model_post_delete_by_tids_batch_start.php
│ │ # 批量删除主题前处理相关远端文件
│ ├── more_discover_items_after.htm
│ │ # 在发现页其他项目后显示 LskyPro 存储卡片
│ ├── storage_delete.php
│ │ # 接入 Xiuno X 存储驱动删除生命周期,同步删除远端文件
│ ├── storage_save.php
│ │ # 接入存储驱动保存生命周期,执行本地校验和远端上传
│ └── storage_serve.php
│ # 接入存储驱动读取生命周期,处理远端跳转、下载和本地回退
│
├── lang/
│ ├── en-us/
│ │ └── bbs_admin.php
│ │ # 英文后台设置、状态和错误提示
│ ├── zh-cn/
│ │ └── bbs_admin.php
│ │ # 简体中文后台设置、状态和错误提示
│ └── zh-tw/
│ └── bbs_admin.php
│ # 繁体中文后台设置、状态和错误提示
│
├── model/
│ ├── LskyDebugSanitizerService.php
│ │ # 对 Token、Authorization、Cookie、JSON 和调试信息进行脱敏
│ └── LskyStorageService.php
│ # LskyPro 存储核心 Service,负责配置、上传、读取、下载、删除、
│ # 失败回退、重复上传保护、远端映射、错误记录和安全校验
│
├── route/
│ ├── manage.php
│ │ # 后台状态、错误记录、远端删除重试和孤儿文件管理路由
│ ├── status.php
│ │ # 输出当前存储模式、连接状态和上传准备状态
│ └── test.php
│ # 执行 LskyPro 连接测试并返回脱敏后的检测结果
│
├── static/
│ ├── css/
│ │ └── lsky.css
│ │ # 后台设置页、状态页和错误列表的插件样式
│ └── js/
│ └── lsky.js
│ # 使用原生 JavaScript 实现连接测试、清理记录、
│ # 删除重试、Nonce 更新和防重复提交
│
├── tests/
│ ├── debug_redaction_test.php
│ │ # 验证 Token、Bearer 凭证、Cookie 和调试内容不会泄露
│ ├── mock_remote_download_server.py
│ │ # 提供远程下载测试所需的模拟 HTTP 服务
│ ├── post_rewrite_regex_test.php
│ │ # 验证帖子正文中的远程图片地址重写规则
│ ├── remote_download_contract_test.sh
│ │ # 验证远程下载大小限制、重定向限制和请求头安全策略
│ └── service_contract_test.php
│ # 验证存储 Service 的配置、加密、API 响应和映射契约
│
└── view/
└── htm/
├── manage.htm
│ # 后台状态、上传统计、错误记录和删除重试页面
├── setting.htm
│ # 存储模式、LskyPro 地址、Token、策略和失败策略配置页面
└── status.htm
# 发现页或状态路由使用的存储状态展示模板配置流程
后台「插件管理」安装并启用 suncosmos_lsky
选择 LskyPro 版本,填写基础域名并填写API Token 与策略 ID,选择测试当前表单,成功后保存配置。
如有远端图片地址(存储策略的访问域名)也可以填写。
其它配置根据自己需求选择开启或关闭。
最后保存配置。
兼容版本
XiunoX v1.1
其它说明
本插件已在生产环境进行测试,但未与其它 插件 / 模板 进行测试,无法确定此插件是否与其它插件存在冲突;已确定不引起冲突插件 “ CloudFlare TurnStile 安全防护 " ;由于我没有 LskyPro V2 的授权,所以未对 V2 版本进行测试,若要使用此版本需自行测试 ;如有其它BUG,欢迎大家向我反馈问题,非常感谢!
常见问题
Q1. 为什么提示:LskyPro 存储策略 ID 不存在,请填写有效的策略 ID
首先在 LskyPro 图床中确认存储策略 ID,并检查插件中的ID 是否填错;
确认是否配置了游客角色组存储策略,并在插件中是否填写的是该存储策略。该问题为LskyPro原生问题,非游客组的存储策略是无法被/strategies获取到,使用API Token会以这个角色上传图片,但是不会以这个用户获取存储策略;
Q2 为什么全部测试成功前台还是上传失败?
全部成功后还是失败可以到后台将请求时间增大,但是建议不要超过 180 秒;
Q3 为什么前台上传提示:LskyPro 响应缺少文件标识或访问地址
提示这个是远端图片主机地址没有填写,需要将对应存储策略中的访问域名;
Q4 怎么获取API Token?
POST 域名/api/v1/tokens;
请求参数(Body)填写邮箱和密码:
{
"email" : "邮箱",
"password" : "密码"
}图片预览

插件分享
- 插件名称:
- LskyPro 图片存储
- 兼容版本:
- XIUNOX 1.1
- 插件自检报告:
-
# `suncosmos_lsky` 代码规范与安全审计报告
## 审计结论
**审计通过,未发现需要修复的高危、中危或规范性问题。**
本轮未修改插件代码。已确认此前上传失败原因属于 LskyPro 远端服务或远端配置问题,插件侧具备失败记录、本地回退和错误脱敏机制。
## 审计范围
- 插件目录:`plugin/suncosmos_lsky`
- 插件版本:`1.2.4`
- Xiuno X 核心版本:`1.1.10`
- 目标 API:LskyPro V1/V2 profile
- 审计内容:插件结构、Hook、路由、Service、后台页面、数据库脚本、前端资源及安全处理
## 规范检查
- `conf.json` 字段完整,版本格式正确。
- `bbs_version: 1.1` 与当前核心版本匹配。
- 未使用废弃的 `id`、`installed`、`enable` 字段。
- 存储驱动通过 Xiuno X 官方 Hook 扩展机制接入。
- 未覆盖核心 `model/`、`route/`、`lib/` 或后台源码。
- Hook 变量、数据库表、配置键、CSS 类和 JS 标识均使用插件前缀。
- 未发现 jQuery、Alpine.js 或旧版 htmx 事件。
- 未发现 `return;` Hook 终止问题。
- 静态 JS/CSS 中无 PHP 代码。
- 模板输出使用 `esc_html()`、`esc_attr()`。
- 后台页面使用 Bootstrap 5 和 Tabler Icons。
- 路由片段属于编译注入格式,单独 lint 报 `unexpected token case` 是预期现象;对应 Xiuno 编译文件均通过语法检查。
## 安全检查
- 后台权限限制为管理员组 `gid=1/2`。
- POST 操作均执行 CSRF 校验。
- 保存、测试、清理和重试操作使用一次性 nonce,并有前端防重复提交。
- API Token 使用 AES-GCM 加密保存。
- 页面仅显示脱敏 Token。
- 日志、错误记录、调试输出会过滤 Token、Authorization 和 Cookie。
- 远端 URL 校验 HTTPS、主机、重定向、DNS 及私网地址。
- 远端图片访问不携带 Authorization。
- 下载代理限制响应大小、禁止重定向,并使用临时文件。
- 上传失败支持本地回退或终止上传。
- 远端删除失败不会阻塞本地附件删除。
- 远端映射、重复上传、共享引用和孤儿文件均有处理。
- 卸载前会切回本地存储,并保留远端映射追踪信息。
## 测试结果
以下测试全部通过:
- `service_contract_test.php`
- `debug_redaction_test.php`
- `post_rewrite_regex_test.php`
- `remote_download_contract_test.sh`
- 插件全部 PHP 文件语法检查
- Xiuno 编译后的路由、Hook、设置页文件语法检查
- PluginScanner 扫描结果:**0 项问题**
## 前端审计
- 设置页、状态页、管理页均通过 PHP lint。
- 移动端响应式布局存在。
- 所有后台 POST 表单包含 CSRF Token。
- 请求期间按钮禁用并显示加载状态。
- 成功后轮换 nonce。
- 动态输出均经过转义。
- Discover 卡片使用安全 JSON 编码和 `textContent`。
- 未发现前端 XSS、jQuery 或 Alpine.js 使用。
限制:当前环境未安装 Node.js,因此未运行 `node --check`;现有 PHP、契约和远程下载测试已通过。
## 已知限制
- LskyPro 实例的实际 API 版本、Token 权限、存储 ID/策略 ID 和响应结构仍需以目标实例官方文档为准。
- 历史附件不会自动迁移。
- 远端服务不可用时,插件按配置回退本地或终止上传。
- 当前环境 PHP CLI 输出存在 `zip` 扩展重复加载警告,但不影响插件测试结果。 - 插件类型:
- 功能增强



