NavGCN 插件市场
纯后台插件:远程插件市场客户端,数据源在代码内硬编码(Gitee 仓库 + 自建仓库 repo-server),后台一键浏览清单、安装/升级免费插件,无任何后台设置项。
类型:后台插件(plugin)
版本:1.0.0
兼容:Xiuno BBS 1.1(bbs_version 1.1)
依赖:PHP 7.4+(推荐 8.x)、
ZipArchive扩展、curl或allow_url_fopen
功能
拉取
manifest.json插件清单(Gitee raw / 自建仓库 api),带文件缓存(6 小时)与源标记。双源故障转移:主源(Gitee)拉取失败自动切换自建仓库备用源;降级期间页面直接用缓存秒开,降级超过 15 分钟自动重新探测主源,主源恢复即自动切回;也可点「刷新」立即强制探测。双源均失败时回退过期缓存并显示错误原因。
与本地插件比对状态:
not_installed/paid/latest/need_upgrade,支持免费/付费筛选、分类筛选与关键词搜索。免费插件一键安装 / 升级:下载 zip → 魔数与结构校验 → 解压 → 移动 →
plugin_install/upgrade.php→ 冲突插件自动禁用。升级全程备份回滚:失败自动恢复旧目录并用
plugin_install重同步数据库(绝不plugin_unstall)。本地已有插件文件但未安装时,支持直接本地安装(无需重新下载 zip)。
已安装插件就地启用/禁用/卸载,支持依赖检查与同类插件互斥自动禁用。
安全:
所有下载请求(与数据源无关)统一执行 URL 安全校验:协议白名单(仅 http/https)、禁止账号密码、主机名校验;私网/回环放行策略便于内网自建仓库部署。
zip 校验含魔数、条目数上限、单文件/总大小限流、绝对路径与
..穿越拒绝、符号链接条目拒绝,并在解压后全目录递归复查符号链接。下载限流(50MB),cURL 超时与连接超时双重控制,Gitee raw 302 CDN 跳转采用有界跟随(MAXREDIRS=3)。
来源映射:已安装插件记录其来源仓库(
installed_source),便于审计。
数据源(硬编码,修改见 model/NavgcnMarketService.php 顶部常量)
常量 | 值 | 说明 |
|---|---|---|
|
| 主数据源: |
|
| Gitee 仓库完整链接(分支默认 |
|
| 自建仓库根地址(repo-server) |
|
| 清单缓存有效期(秒) |
|
| 插件包下载超时(秒) |
|
| SSRF 私网/回环放行(1=放行,便于内网部署) |
installed_source(来源映射)为运行时数据,持久化于setting_get('navgcn_market'),不在后台修改。
与 repo-server 的对接协议
自建源地址为 self_base_url/api/index.php,返回 JSON:
{
"plugins": [
{
"dir": "navgcn_demo",
"name": "演示插件",
"version": "1.0.0",
"type": "plugin",
"free": 1,
"brief": "简介",
"author": "navg.cn",
"author_homepage": "https://navg.cn",
"icon_url": "https://.../icon.png",
"zip_url": "https://.../navgcn_demo_1.0.0.zip",
"detail_url": "https://.../detail",
"homepage": "https://..."
}
]
}Gitee 源清单为仓库根目录 manifest.json(同一格式),raw 地址: https://gitee.com/{owner}/{repo}/raw/{branch}/manifest.json。
安装包 zip 需满足:conf.json 位于根目录或唯一子目录;无路径穿越与符号链接条目。
文件结构
plugin/navgcn_market/
├── conf.json # 插件配置(hooks_rank)
├── install.php # 安装:初始化运行时数据(来源映射)
├── uninstall.php # 卸载:清除数据与缓存
├── hook/
│ ├── admin_index_route_case_end.php # 内联编译:路由 case
│ ├── admin_sidebar_end.htm # 后台侧边栏菜单
│ └── model_inc_file.php # 内联编译:Service 类注册
├── lang/{zh-cn,zh-tw,en-us}/bbs_admin.php # 后台语言包
├── model/NavgcnMarketService.php # 核心服务(静态方法,源配置常量在顶部)
├── route/navgcn_market.php # 后台路由分发(无设置页)
└── view/htm/market.htm # 市场页自检报告
以下自检基于
xiunox-plugin-devSkill 硬规则与交付检查表,逐项验证通过。
一、conf.json 配置
检查项 | 结果 |
|---|---|
必填字段完整( | 通过 |
| 通过 |
不含 | 通过 |
| 通过 |
插件目录名 | 通过 |
二、安装/卸载脚本
检查项 | 结果 |
|---|---|
| 通过 |
| 通过 |
| 通过 |
| 通过 |
| 通过 |
| 通过 |
三、Hook 规范
检查项 | 结果 |
|---|---|
所有 PHP hook 以 | 通过 |
所有 | 通过 |
hook 目录下无 | 通过 |
hook 文件名与源码标记完全匹配 | 通过 |
hook 内局部变量带插件前缀,无通用名污染宿主作用域 | 通过 |
四、安全规范
检查项 | 结果 |
|---|---|
所有 POST 表单包含 | 通过 |
所有 POST 处理以 | 通过 |
路由文件开头有 | 通过 |
所有下载请求(与数据源无关)统一执行 URL 安全校验(协议白名单/禁账号密码/主机名校验) | 通过 |
安装/升级前做 zip 校验(魔数、条目数、单文件/总大小、路径穿越、符号链接) | 通过 |
解压后全目录递归复查符号链接(纵深防御) | 通过 |
下载限流( | 通过 |
升级流程含备份回滚(失败自动恢复旧目录 + 重同步 DB,绝不 | 通过 |
五、输出转义
检查项 | 结果 |
|---|---|
无 | 通过 |
无裸 | 通过 |
远端 manifest 数据注入 URL 属性时使用 | 通过 |
JS 内嵌语言串使用 | 通过 |
确认弹窗中远端数据先经 | 通过 |
无 | 通过 |
六、前端框架
检查项 | 结果 |
|---|---|
无 jQuery( | 通过 |
无 Alpine.js( | 通过 |
无 htmx 2.x 旧事件名 | 通过 |
无独立 | 通过 |
七、命名规范
检查项 | 结果 |
|---|---|
语言键带前缀 | 通过 |
setting 键为 | 通过 |
模板/hook 内局部变量带前缀( | 通过 |
无 | 通过 |
八、URL 与路由
检查项 | 结果 |
|---|---|
后台 URL 使用 | 通过 |
无硬编码 | 通过 |
路由 case 值不含 | 通过 |
后台 URL 保持 | 通过 |
分页/筛选 URL 首个分隔符动态适配 | 通过 |
九、Service 与核心类
检查项 | 结果 |
|---|---|
Service 通过 | 通过 |
路由层含 | 通过 |
调用核心插件函数( | 通过 |
安装/升级/本地安装/切换/卸载操作使用并发锁(生命周期对齐操作时长) | 通过 |
锁内操作使用 | 通过 |
依赖检查为只读操作,在锁外执行 | 通过 |
| 通过 |
十、模板规范
检查项 | 结果 |
|---|---|
后台模板 include | 通过 |
Card 组件使用 | 通过 |
使用 Tabler Icons( | 通过 |
十一、其他规则
检查项 | 结果 |
|---|---|
单行注释无 | 通过 |
无覆盖核心路径 | 通过 |
无调试代码( | 通过 |
无数据表依赖(纯配置型插件,无 DB 表) | 通过 |
PHP 语法检查通过( | 通过 |
十二、多语言
检查项 | 结果 |
|---|---|
简体中文 | 通过 |
繁体中文 | 通过 |
英文 | 通过 |
语言包使用 | 通过 |
自检结论:全部检查项通过。