laoyang
|
c19e475e85
|
修复:附件总量上限填 10240 被浏览器拦住(step 与 min 冲突) (#1)
用户反馈「全站附件总量上限填 10240 不行」。
根因:input 写成 step="16" min="10"。
HTML 的 step 是从 min 起算的 —— 合法值只有 10、26、42、58…(10 + 16n)。
10240 不在这个序列里,浏览器直接判为非法值、拒绝提交。
更糟的是这不是个例:1024(1G)、2048、4096、8192 全都不合法,
只有 10/26/42 这种怪数字能填进去。这个 bug 从该字段上线就存在。
修法:
- step="16" → step="any",允许任意数值
- 补 max="100000",与服务端 [10, 100000] 区间对齐,
避免用户填 999999 被服务端静默截断成 100000
顺带排查另外两个容量字段,确认没事:
- 图片单张上限 min=0.2 step=0.1 → 0.2 起步正好对齐,0.5/1/5/10 都合法
- 视频单个上限 min=1 step=1 → 整数都对
只有总量那一个字段踩了坑。
新增 tools 级检查脚本(_tooling 侧 fb_input_constraint_check.py):
按 HTML 规范逐条验算每个 number 输入框的 min/max/step 是否放行
「默认值」与「常见取值」,并核对前后端区间是否一致。19/19 通过。
这类错误肉眼看不出来,必须用规则算。
验证:约束一致性检查 19/19;服务端 MB↔字节往返一致(含 10240)。
|
2026-11-01 15:26:08 +08:00 |
|
laoyang
|
9b822d2d9a
|
安装向导:加管理员用户名,精简为填表即装、装完进首页 (#1 #2)
## 管理员账号(用户名 + 口令)
原先只有口令,没有用户名。现在两者都有:
- 用户名词入库 settings 的 admin.username(2~32 位,字母数字下划线点连字符)
- 口令仍是 bcrypt 哈希存 admin.password_hash,明文不落任何文件
- 登录校验 fb_admin_verify_login():用户名或口令任一不对都返回同一句
「用户名或口令不正确」,且用户名错时也照常跑一次 password_verify,避免用耗时探测账号
- 向后兼容:老部署只设了口令没用户名时,仍可只填口令登录,
并在登录页提示补一个用户名
## 安装向导精简
按用户要求「没数据就初始化,填完进主页」:
- 必填只剩 4 项:网站名称、管理员用户名、口令、确认口令
- 站点描述 / 官方邮箱 / 站点根地址改为 hidden(可留空自动探测)
- 密钥、令牌原本就自动生成
- 安装成功后展示网站名称与用户名,2 秒自动跳首页,也有按钮
- 按钮文案改为「完成安装,进入首页」
## 修掉一个真实 bug
首页把软件说明当成站点描述,导致「软件有 note 时站点描述被顶掉」。
两者是不同的东西:站点描述是全局设置必须始终显示,软件说明另起一行补充。
老基线 D6「首页描述变为新描述」就是被这个 bug 弄失败的。
## 另一个坑
admin.username 忘了加进 fb_setting_keys() 白名单,fb_set_setting() 会静默丢弃,
表现为「安装时填了用户名,装完却没有」。已补。
验证:
- 全新安装流程 32/32(真空站:无 config.php、无 data/*.db)
- 老基线 25/25、附件专项 22/22、安装向导 60/60
- PHP 8.5 全部入口 0 弃用
|
2026-11-01 12:39:20 +08:00 |
|
laoyang
|
55d2dfa46b
|
后台管理界面:软件/分类/状态可配,反馈可改挂归属 (#1)
## 新增 lib/admin_taxonomy.php
- 软件:增删改、排序、启停;新增时自动预置 Bug/功能建议/其他 三个分类
- 分类:在选定软件下增删改、排序、启停
- 状态:改名、改「给用户看的话」、排序、启停;标识不可改(历史数据靠它对应)
- 反馈改挂:th_move,可把反馈移到别的软件/分类,跨软件的非法分类会被拒
## 安全与边界
- 所有动作走 CSRF 校验(沿用现有机制)
- 不能删最后一个软件 / 没有分类的软件至少要留一个启用分类
- 有反馈挂着的软件或分类不能删,提示改为停用(停用后前台消失、数据保留)
- th_move 加入 fb_admin_is_taxonomy_act 白名单,否则会被「问题不存在」静默吞掉
## admin.php 接线
- 引入模块 + 动作分发 + tab 白名单加 taxonomy/statuses + 导航两项
- 前置检查放行不依赖 $t 的动作(否则新增软件报「问题不存在」)
- 全部问题列表:加软件筛选、分类跟着软件走;修掉三处仍在用旧
fb_statuses()/fb_categories() 的遍历(那会渲染出错)
- 详情页加「归属」表单,软件徽章可显示
## 其他文件
- api.php:状态/分类改数据库;新增 ?sw= / ?software_id= / ?cid= 过滤,
老的 ?category=<slug> 仍可用(在所属软件内解析)
- thread.php:详情页显示软件与分类徽章
- config.example.php:移除 categories / statuses,改由数据库管理
## 修掉两个真实 bug
1. 移除配置后出厂分类兜底只剩 4 个,漏了「同步问题」—— 建库后核对数量才发现
2. th_move 不在白名单,POST 后返回 200 却静默不生效
验证:后台 e2e 29/29;改挂与联动 13/13;PHP 8.5 全部入口 0 弃用;
19 个 PHP 文件语法全过。
|
2026-11-01 12:03:11 +08:00 |
|
laoyang
|
5006d54be3
|
附件读取统一走 media.php 代理,真实地址不再暴露
无论附件存在本机 uploads/ 还是 OSS 私有桶,前台给浏览器的地址现在完全一致:
media.php?k=<对象键>。界面上不再出现 uploads/ 真实路径,也不出现任何 bucket /
endpoint / 签名痕迹。
- lib/attach.php:新增 fb_attach_proxy_url(),fb_attach_url() 与
fb_attach_thumb_url() 的本机分支一并改走代理(地址不落库、渲染现算,
对历史附件立即生效,无需迁移)。
- uploads/ 整目录禁止 Web 直读:附件只能经 media.php 出,真实物理路径
即便被猜到也取不到,同时绕不开 media.php 的可见性鉴权。
- 规则版本化自动升级:.htaccess 内埋 `# fb-local-guard: vN`,
旧版规则在任意请求时由 PHP(目录属主)整份重写。之所以不能靠部署覆盖:
部署账号对 uploads/ 无写权限,只有程序自己能改。
- 随包 uploads/.htaccess 改为程序产出的逐字节副本,并加断言防漂移
(否则线上会被自动升级覆盖,随包那份形同虚设)。
- 顺带修复真实源码泄漏:config.php.bak_<时间戳> 这类「非 .php 结尾、
但含源码」的备份文件此前可被公开下载。加固根 .htaccess:
去掉正则结尾锚点、补 .php[.\-_] 兜底、点名拒绝 config.php / oss.sts.php。
- media.php / upload.php / admin.php / README.md:文档与响应头同步。
验证:php -l 19 文件 0 失败;主回归 25/25、附件专项 22/22、安装向导 60/60、
统一代理渲染 7/7、反向验证 V1-V4 全被抓住;线上冒烟 30/30、
线上统一代理真机 13/13(OSS 私有桶 + 内网 endpoint 下上传→代理读回→
Range 206→伪造键 403)。
|
2026-09-28 23:33:45 +08:00 |
|
laoyang
|
27187b38f1
|
页脚入口与安装向导;加固管理员口令存储
需求落实:
1. 页脚常驻「管理后台」链接,不用再手敲 admin.php。
2. 页脚「由 FeedLite 驱动」中的 FeedLite 改为超链接(指向开源仓库);
后台新增「页脚」设置组,可关闭整句(关闭后只留管理后台链接),也可改链接地址。
3. 管理员口令存储方式在后台如实展示:数据库 settings.admin.password_hash,
存 bcrypt 单向哈希(不可逆),明文不落盘。
4. 新增安装向导 install.php:data/ 下没有数据库时自动 302 引导;
体检环境 -> 填站点信息与口令 -> 生成 config.php -> 建库建表 -> 完成。
顺带修掉一个真实安全隐患:
config.php 里的出厂占位口令 CHANGE_ME_admin 原先可被当作有效口令登录后台
(等于公开仓库里就写着线上后门口令)。现改为占位/空值一律拒绝,
未设口令时后台明确提示去安装向导,不再含糊报「口令不正确」。
实现要点:
- 新增 fb_cfg_file():只读配置文件、不叠加 settings 表、绝不触达数据库。
「是否已安装」以数据库文件是否存在为判据,而 fb_cfg() 读 settings 会触发
fb_db() 就地建库 —— 那会把安装态自己造出来,所以判定必须走不碰库的通道。
- bootstrap 只在已安装时建库;未安装则 302 到 install.php(CLI 下报错退出)。
- fb_settings_flat() 在未安装时直接返回空,杜绝任何隐式建库。
- install.php 用文本级替换生成 config.php,保留全部注释与 OSS/SMTP 段落;
生成的 PHP 用 token_get_all(TOKEN_PARSE) 校验后才落盘。
- 页脚链接只放行 http/https,后台保存时校验(防 javascript: 伪协议)。
- style.css 页脚行改 flex,版本号 v6 -> v7。
验证:
- php -l 全量通过;现有回归 25/25、附件专项 13/13 保持通过。
- 安装向导专项 60/60(含「明文口令未写入任何文件」「数据库字节里搜不到明文」)。
- 反向验证:撤销三处修复后对应断言确实失败(断言非装饰)。
- 几何检查:本机 15/15 + 页脚专项全过;线上真实 URL 15/15 + 页脚专项全过。
- 线上真机冒烟 22/22。
|
2026-09-28 22:53:55 +08:00 |
|
laoyang
|
1401ad899b
|
OSS 附件改为私有桶+内网Endpoint+服务器代理架构
背景:桶为私有、且只用内网 Endpoint(外网不可达),浏览器既无法直传、
也无法直连。原「浏览器直传 + 签名URL直连」两条路都失效,改为全站代理。
lib/oss.php:
- endpoint 自动转内网(*-internal),use_internal_endpoint 开关控制,内网走 http
- 移除浏览器直传凭证(PostObject),改为服务器端 PUT(流式 fb_oss_put_file)
- 新增 fb_oss_stream_get 流式读取(回调式,支持 Range,不整文件进内存)
- 签名支持 x-oss-process 子资源 + Authorization 头签名(Content-Type 入签)
- 新增 fb_oss_probe 连通性自检、fb_oss_error_text 错误归因(含跨地域提示)
media.php(新增): 附件代理输出,鉴权边界=对象键须在本站附件表(或本人待入库
登记)且帖子对访客可见,防止本站沦为能读整个共用桶的开放代理;透传 Range。
upload.php: local/oss 统一走两步(领键→action=put),OSS 模式由服务器代理 PUT。
lib/db.php: 新增 pending_attachments 表 + idx_att_key 索引(迁移幂等自动建)。
lib/attach.php: 待入库登记(mark/clear/mine/gc),解决上传后入库前的预览鉴权。
cron.php: 清理过期待入库登记 + 桶连通性自检输出。
admin.php: 设置页加「使用内网 Endpoint」开关、存储体检显示实际连接地址与探测按钮。
README/config: 全面更新为代理架构(无需CORS、无需自定义域名、同地域要求)。
验证:本地 e2e 25/25 + 附件专项 13/13(含防开放代理/Range/内网改写);
线上真机上传→内网PUT→media.php代理读回→Range 全通过。
|
2026-09-28 22:12:28 +08:00 |
|
laoyang
|
cede838b5e
|
FeedLite 初始提交:通用轻量级反馈系统(PHP + SQLite,零依赖)
- 前台:问题列表 / 详情 / 发布与回复(趣味问答验证码、蜜罐、IP 限流)
- 后台:先审后显、站点设置(站点标题/描述、附件存储、OSS 参数)、操作日志
- 附件:关闭 / 本机硬盘 / 阿里云 OSS 浏览器直传(ECS 实例 RAM 角色)三种模式
- 品牌资源:全套图标(favicon.ico / SVG / PNG 各尺寸 / manifest)
- 安全:CSRF、session 加固、.htaccess 屏蔽敏感文件、口令仅存哈希
- 配置:config.example.php 为模板,config.php 不入库
|
2026-09-28 20:34:37 +08:00 |
|