两件事:
1) 安装向导(src/resources/views/install.blade.php)
· 数据库类型的选项顺序:SQLite 提到第一个(= 浏览器默认选中),MySQL/PostgreSQL/SQL Server 保持原序。
镜像自带 pdo_sqlite,开箱即用;README 第 55 行本来就写着「默认 SQLite」,这次把代码对齐文档。
· 页面加载时主动触发一次 change:那个 change 处理器同时负责「按类型显示/隐藏连接字段」,
不触发的话默认选中的 SQLite 旁边还挂着 MySQL 那套字段(127.0.0.1 / 3306 / root)与端口,
看着像选错了,SQLite 的说明文字也不会出现。
· tools/diff-vs-upstream.sh 的 KNOWN_DEVIATIONS 里该文件的理由补上这一条(文件本来就在清单里)。
2) README(只改文档,不动任何 compose 文件)
· 挂载卷路径 /root/lsky-pro/data → $PWD/data(compose 片段)与 "$PWD/data:/var/www/html"(docker run 片段);
仓库自带的 docker-compose.yaml 本来就用 $PWD/web 这套写法,风格统一。
· 补一句提醒:compose 文件里别写 ~(不经过 shell 不会展开)。
348 lines
18 KiB
Bash
Executable File
348 lines
18 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ---------------------------------------------------------------------------
|
||
# 用途:把本仓库 src/ 与上游官方快照做**全树对比**,回答两个问题:
|
||
# 1) 我们相对上游到底改了哪几个文件、改了什么(默认就打印这个)
|
||
# 2) src/ 里有没有「手滑改动」—— 只要出现**已知偏离清单**之外的文件与上游不同就报警
|
||
#
|
||
# 依赖:git(需要能访问 github.com;上游已停更,平时不需要跑这个脚本)
|
||
# 用法:bash tools/diff-vs-upstream.sh [commit] # 默认用 Dockerfile 里的 LSKY_COMMIT
|
||
#
|
||
# 维护:有意改了 src/ 里的上游文件后,把该文件登记进下面的 KNOWN_DEVIATIONS(附一句理由),
|
||
# 否则脚本会把它当成「手滑改动」而 exit 1。反过来说:只要它不报错,src/ 相对上游
|
||
# 的改动就**恰好**是清单里这些 —— 这也正是 CI / 人工复核想看到的不变量。
|
||
# ---------------------------------------------------------------------------
|
||
set -euo pipefail
|
||
cd "$(dirname "$0")/.."
|
||
|
||
COMMIT="${1:-$(grep -oE '^ARG LSKY_COMMIT=[0-9a-f]+' Dockerfile | cut -d= -f2)}"
|
||
if [ -z "$COMMIT" ]; then
|
||
echo "用法:bash tools/diff-vs-upstream.sh <上游 commit>" >&2
|
||
exit 2
|
||
fi
|
||
|
||
# ===========================================================================
|
||
# 已知偏离清单(KNOWN DEVIATIONS)—— 本 fork **有意**相对上游修改的上游文件。
|
||
# 判据:diff 出来的「内容不同」清单必须**恰好**落在下面这些行内(顺序无关)。
|
||
# 不在清单里的文件一旦与上游不同 = 手滑改动 / 未登记的改动 → 报警 + exit 1。
|
||
#
|
||
# 每行是 `src/<路径>`;它上方最近的 `# [n ...]` 注释就是「这个文件为什么偏离上游」的理由。
|
||
# 新增/删除条目时「理由」必须跟着改 —— 这份清单本身就是「我们和上游差在哪」的权威记录。
|
||
#
|
||
# 注意:这里只登记「内容不同」(两边都存在、内容不一样)的文件。
|
||
# “只在一边存在”(我们新增的 theme.js / public/static 等、上游有而我们删掉的
|
||
# Gallery/Upgrade 文件)只做信息展示,不参与报警 —— src/ 里还混着 node_modules /
|
||
# vendor / storage 这类构建或运行期产物,用「新增文件」报警会全是噪音。
|
||
# ===========================================================================
|
||
KNOWN_RAW=$(cat <<'EOF'
|
||
# [1 补丁产物:iOS Safari 长按弹菜单 + 菜单交互修复]
|
||
# src/resources/js/context-js.js
|
||
src/resources/js/context-js.js
|
||
# src/public/js/context-js/context-js.js
|
||
src/public/js/context-js/context-js.js
|
||
# src/resources/views/user/images.blade.php
|
||
src/resources/views/user/images.blade.php
|
||
# # (两份 JS 内容必须逐字节一致;blade 只改了引入脚本那一行的资源版本串。完整 diff:patches/ios-longpress.patch)
|
||
# (两份 JS 内容必须逐字节一致;blade 只改了引入脚本那一行的资源版本串。完整 diff:patches/ios-longpress.patch)
|
||
|
||
# [2 功能移除:画廊(Gallery)与系统升级;登录态访问首页改跳「我的图片」]
|
||
# src/app/Enums/ConfigKey.php
|
||
src/app/Enums/ConfigKey.php
|
||
# src/app/Http/Controllers/Admin/SettingController.php
|
||
src/app/Http/Controllers/Admin/SettingController.php
|
||
# src/config/app.php
|
||
src/config/app.php
|
||
# src/config/convention.php
|
||
src/config/convention.php
|
||
# src/routes/web.php
|
||
src/routes/web.php
|
||
# src/resources/views/admin/setting/index.blade.php
|
||
src/resources/views/admin/setting/index.blade.php
|
||
|
||
# [3 安全:彻底移除 SVG 上传(读取侧硬过滤 + 只可能因 svg 命中的死代码清理)]
|
||
# src/app/Http/Controllers/Controller.php
|
||
src/app/Http/Controllers/Controller.php
|
||
# src/app/Http/Requests/Admin/GroupRequest.php
|
||
src/app/Http/Requests/Admin/GroupRequest.php
|
||
# src/app/Models/Group.php
|
||
src/app/Models/Group.php
|
||
# src/app/Models/Image.php
|
||
src/app/Models/Image.php
|
||
# src/app/Services/ImageService.php
|
||
src/app/Services/ImageService.php
|
||
|
||
# [4 依赖安全升级:composer.lock 升到同大版本线内的安全版本
|
||
# (laravel/framework 9.52.22、symfony/* 6.4 LTS、guzzle、phpseclib、commonmark 等一批 CVE 修复)]
|
||
# src/composer.lock
|
||
src/composer.lock
|
||
|
||
# [5 前端源码:全站前端换新(清爽极简 + 亮/暗/跟随系统)及后续 UI/交互迭代
|
||
# (菜单/弹窗/侧栏/图片页…;app/Utils.php 是配套加的「资源版本串 / 本地默认头像」助手方法)]
|
||
# src/app/Utils.php
|
||
src/app/Utils.php
|
||
# src/package.json
|
||
src/package.json
|
||
# src/package-lock.json(前端依赖升级:sweetalert2 11.4.6 → 11.22.4,修掉它的 3 条 npm 公告
|
||
# —— 见 osv-scanner.toml「test/package-lock.json 侧」;锁里只有 sweetalert2 一处
|
||
# version/resolved/integrity/赞助链接变化,其余与上游锁逐字节一致)
|
||
src/package-lock.json
|
||
# src/resources/css/app.css
|
||
src/resources/css/app.css
|
||
# src/resources/css/common.less
|
||
src/resources/css/common.less
|
||
# src/resources/css/context-js.less
|
||
src/resources/css/context-js.less
|
||
# src/resources/css/gallery.less
|
||
src/resources/css/gallery.less
|
||
# src/resources/js/app.js
|
||
src/resources/js/app.js
|
||
# src/resources/js/stores/sidebar.js
|
||
src/resources/js/stores/sidebar.js
|
||
# src/resources/views/admin/console/index.blade.php
|
||
src/resources/views/admin/console/index.blade.php
|
||
# src/resources/views/admin/group/add.blade.php
|
||
src/resources/views/admin/group/add.blade.php
|
||
# src/resources/views/admin/group/edit.blade.php
|
||
src/resources/views/admin/group/edit.blade.php
|
||
# src/resources/views/admin/group/index.blade.php
|
||
src/resources/views/admin/group/index.blade.php
|
||
# src/resources/views/admin/group/rules.blade.php
|
||
src/resources/views/admin/group/rules.blade.php
|
||
# src/resources/views/admin/image/index.blade.php
|
||
src/resources/views/admin/image/index.blade.php
|
||
# src/resources/views/admin/strategy/add.blade.php
|
||
src/resources/views/admin/strategy/add.blade.php
|
||
# src/resources/views/admin/strategy/edit.blade.php
|
||
src/resources/views/admin/strategy/edit.blade.php
|
||
# src/resources/views/admin/strategy/index.blade.php
|
||
src/resources/views/admin/strategy/index.blade.php
|
||
# src/resources/views/admin/strategy/tips.blade.php
|
||
src/resources/views/admin/strategy/tips.blade.php
|
||
# src/resources/views/admin/user/edit.blade.php
|
||
src/resources/views/admin/user/edit.blade.php
|
||
# src/resources/views/admin/user/index.blade.php
|
||
src/resources/views/admin/user/index.blade.php
|
||
# src/resources/views/auth/confirm-password.blade.php
|
||
src/resources/views/auth/confirm-password.blade.php
|
||
# src/resources/views/auth/forgot-password.blade.php
|
||
src/resources/views/auth/forgot-password.blade.php
|
||
# src/resources/views/auth/login.blade.php
|
||
src/resources/views/auth/login.blade.php
|
||
# src/resources/views/auth/register.blade.php
|
||
src/resources/views/auth/register.blade.php
|
||
# src/resources/views/auth/reset-password.blade.php
|
||
src/resources/views/auth/reset-password.blade.php
|
||
# src/resources/views/auth/verify-email.blade.php
|
||
src/resources/views/auth/verify-email.blade.php
|
||
# src/resources/views/common/api.blade.php
|
||
src/resources/views/common/api.blade.php
|
||
# src/resources/views/components/auth-card.blade.php
|
||
src/resources/views/components/auth-card.blade.php
|
||
# src/resources/views/components/auth-validation-errors.blade.php
|
||
src/resources/views/components/auth-validation-errors.blade.php
|
||
# src/resources/views/components/box.blade.php
|
||
src/resources/views/components/box.blade.php
|
||
# src/resources/views/components/button.blade.php
|
||
src/resources/views/components/button.blade.php
|
||
# src/resources/views/components/code.blade.php
|
||
src/resources/views/components/code.blade.php
|
||
# src/resources/views/components/container.blade.php
|
||
src/resources/views/components/container.blade.php
|
||
# src/resources/views/components/default-avatar.blade.php
|
||
src/resources/views/components/default-avatar.blade.php
|
||
# src/resources/views/components/dropdown-link.blade.php
|
||
src/resources/views/components/dropdown-link.blade.php
|
||
# src/resources/views/components/dropdown.blade.php
|
||
src/resources/views/components/dropdown.blade.php
|
||
# src/resources/views/components/fieldset-checkbox.blade.php
|
||
src/resources/views/components/fieldset-checkbox.blade.php
|
||
# src/resources/views/components/fieldset-radio.blade.php
|
||
src/resources/views/components/fieldset-radio.blade.php
|
||
# src/resources/views/components/fieldset.blade.php
|
||
src/resources/views/components/fieldset.blade.php
|
||
# src/resources/views/components/input.blade.php
|
||
src/resources/views/components/input.blade.php
|
||
# src/resources/views/components/label.blade.php
|
||
src/resources/views/components/label.blade.php
|
||
# src/resources/views/components/loading-spin.blade.php
|
||
src/resources/views/components/loading-spin.blade.php
|
||
# src/resources/views/components/modal.blade.php
|
||
src/resources/views/components/modal.blade.php
|
||
# src/resources/views/components/nav-link.blade.php
|
||
src/resources/views/components/nav-link.blade.php
|
||
# src/resources/views/components/no-data.blade.php
|
||
src/resources/views/components/no-data.blade.php
|
||
# src/resources/views/components/select.blade.php
|
||
src/resources/views/components/select.blade.php
|
||
# src/resources/views/components/table.blade.php
|
||
src/resources/views/components/table.blade.php
|
||
# src/resources/views/components/textarea.blade.php
|
||
src/resources/views/components/textarea.blade.php
|
||
# src/resources/views/components/upload.blade.php
|
||
src/resources/views/components/upload.blade.php
|
||
# src/resources/views/install.blade.php(安装向导:默认数据库类型改成 SQLite + 加载时联动一次;成功页加本 fork 仓库链接)
|
||
src/resources/views/install.blade.php
|
||
# src/resources/views/layouts/app.blade.php
|
||
src/resources/views/layouts/app.blade.php
|
||
# src/resources/views/layouts/guest.blade.php
|
||
src/resources/views/layouts/guest.blade.php
|
||
# src/resources/views/layouts/header.blade.php
|
||
src/resources/views/layouts/header.blade.php
|
||
# src/resources/views/layouts/notice.blade.php
|
||
src/resources/views/layouts/notice.blade.php
|
||
# src/resources/views/layouts/sidebar.blade.php
|
||
src/resources/views/layouts/sidebar.blade.php
|
||
# src/resources/views/layouts/strategies.blade.php
|
||
src/resources/views/layouts/strategies.blade.php
|
||
# src/resources/views/layouts/user-nav.blade.php
|
||
src/resources/views/layouts/user-nav.blade.php
|
||
# src/resources/views/user/dashboard.blade.php
|
||
src/resources/views/user/dashboard.blade.php
|
||
# src/resources/views/user/settings.blade.php
|
||
src/resources/views/user/settings.blade.php
|
||
# src/resources/views/welcome.blade.php
|
||
src/resources/views/welcome.blade.php
|
||
# src/tailwind.config.js
|
||
src/tailwind.config.js
|
||
# src/webpack.mix.js
|
||
src/webpack.mix.js
|
||
|
||
# [6 前端构建产物:由 [5] 的源码经 webpack(npm run prod)重建得到,与上游那份旧产物逐字节不同]
|
||
# src/public/css/app.css
|
||
src/public/css/app.css
|
||
# src/public/css/common.css
|
||
src/public/css/common.css
|
||
# src/public/css/context-js/context-js.css
|
||
src/public/css/context-js/context-js.css
|
||
# src/public/css/gallery.css
|
||
src/public/css/gallery.css
|
||
# src/public/css/fontawesome.css
|
||
src/public/css/fontawesome.css
|
||
# src/public/js/app.js
|
||
src/public/js/app.js
|
||
# src/public/js/app.js.LICENSE.txt
|
||
src/public/js/app.js.LICENSE.txt
|
||
# src/public/js/blueimp-file-upload/jquery.fileupload.js
|
||
src/public/js/blueimp-file-upload/jquery.fileupload.js
|
||
# src/public/js/blueimp-load-image/load-image.all.min.js
|
||
src/public/js/blueimp-load-image/load-image.all.min.js
|
||
# src/public/js/clipboard/clipboard.min.js
|
||
src/public/js/clipboard/clipboard.min.js
|
||
# src/public/js/dragselect/ds.min.js
|
||
src/public/js/dragselect/ds.min.js
|
||
# src/public/js/echarts/echarts.min.js
|
||
src/public/js/echarts/echarts.min.js
|
||
# src/public/js/masonry/masonry.pkgd.min.js
|
||
src/public/js/masonry/masonry.pkgd.min.js
|
||
# src/public/js/viewer-js/viewer.min.js
|
||
src/public/js/viewer-js/viewer.min.js
|
||
# src/public/mix-manifest.json
|
||
src/public/mix-manifest.json
|
||
#
|
||
# [7 SQLite 并发参数(B9):连接建立时把 journal_mode 设成 WAL + 用 PDO::ATTR_TIMEOUT 设 busy_timeout,
|
||
# 避免并发读写偶发 'database is locked'。Laravel 9.52 的 sqlite 驱动不认 journal_mode/busy_timeout
|
||
# 这两个 config 键,所以 journal_mode 只能 PRAGMA(放在 AppServiceProvider)]
|
||
# src/app/Providers/AppServiceProvider.php
|
||
src/app/Providers/AppServiceProvider.php
|
||
# src/config/database.php
|
||
src/config/database.php
|
||
|
||
# [8 安全加固(F23):认证类 POST 端点加路由级节流 —— login / register / forgot-password /
|
||
# confirm-password 各加 throttle(防爆破、防同 IP 批量撒网/邮箱枚举、防邮件轰炸)。
|
||
# 应用里 Breeze 自带的 RateLimiter 只按 (邮箱|IP) 计数,挡不住换邮箱或换 IP 的批量请求]
|
||
# src/routes/auth.php
|
||
src/routes/auth.php
|
||
# [9 安全:收窄信任代理 —— TrustProxies 的 $proxies 从 '*' 改成只信任私有网段。
|
||
# 上游默认 '*' 等于信任所有转发头,而外层 nginx 用的是 $proxy_add_x_forwarded_for
|
||
# (追加而不是覆盖),客户端自己带的 X-Forwarded-For 会排在列表最前面被采信 ——
|
||
# 于是所有按 IP 限流的地方(登录失败计数、throttle 中间件)都能靠伪造一个头无限重置。
|
||
# 实测:写 '*' 时应用解析出的客户端 IP 就是伪造值;改成私有网段后解析出真实客户端,
|
||
# 且 HTTPS 判定不受影响(正常用户解析结果与改动前完全一致)。]
|
||
# src/app/Http/Middleware/TrustProxies.php
|
||
src/app/Http/Middleware/TrustProxies.php
|
||
|
||
# [10 fork 标签功能(按用户隔离的图片标签)+ 原「图片权限」界面临口下线]
|
||
# 标签:新增 tags / image_tag 两张表与 Tag 模型、Image/User 的关联、GET|POST|PUT|DELETE
|
||
# user/tags 与 PUT user/images/tags 五个端点,图片列表新增 tags[] 多值 AND 筛选;
|
||
# 界面侧原「图片权限」口径整体下线(图库页的权限按钮/筛选/详情行换成标签、
|
||
# 用户设置页不再有「图片默认权限」这一项、后台图片页与接口文档的相关行删除),
|
||
# 连带把 UserSettingRequest 里 configs.default_permission 从 required 放宽成 nullable
|
||
# (表单不再提交这一项,不放宽则「保存设置」直接 422)。permission 列与后端接口按产品决策保留。
|
||
# src/app/Http/Controllers/User/ImageController.php
|
||
src/app/Http/Controllers/User/ImageController.php
|
||
# src/app/Models/User.php
|
||
src/app/Models/User.php
|
||
# src/app/Http/Requests/UserSettingRequest.php
|
||
src/app/Http/Requests/UserSettingRequest.php
|
||
# src/app/Http/Controllers/Admin/ImageController.php
|
||
# (后台搜索的 'is:public' / 'is:private' 两条语法随「图片权限」口径下线一起删除;
|
||
# ImagePermission 的引用同时摘掉,其余搜索语法原样保留)
|
||
src/app/Http/Controllers/Admin/ImageController.php
|
||
# src/app/Services/UserService.php
|
||
# src/app/Http/Controllers/Admin/UserController.php
|
||
# (删图片 / 删用户时显式清理 image_tag 与 tags —— 本仓 SQLite 未启用 PRAGMA foreign_keys,
|
||
# 迁移注释声明的「关联行由应用代码显式删除」必须在应用层落实,否则残留行无声累积。
|
||
# 自检脚本:tools/check-tag-integrity.php)
|
||
src/app/Services/UserService.php
|
||
src/app/Http/Controllers/Admin/UserController.php
|
||
EOF
|
||
)
|
||
# 去掉注释/空行/行尾空白,得到排序后的文件清单
|
||
KNOWN="$(printf '%s\n' "$KNOWN_RAW" | sed -e 's/#.*//' -e 's/[[:space:]]*$//' -e '/^[[:space:]]*$/d' | sort)"
|
||
|
||
TMP="$(mktemp -d)"
|
||
trap 'rm -rf "$TMP"' EXIT
|
||
|
||
echo "[1/3] 拉取上游快照 ${COMMIT:0:9} …"
|
||
git init -q "$TMP/up"
|
||
git -C "$TMP/up" remote add origin https://github.com/lsky-org/lsky-pro.git
|
||
git -C "$TMP/up" fetch -q --depth 1 origin "$COMMIT"
|
||
git -C "$TMP/up" checkout -q FETCH_HEAD
|
||
|
||
echo "[2/3] 全树对比(只列有差异的文件)…"
|
||
# 排除构建/运行期产物:它们不在上游仓库里,也不属于「源码有没有被改」的判据
|
||
diff -rq --exclude=.git --exclude=node_modules --exclude=vendor --exclude=storage \
|
||
--exclude=cache --exclude=.env "$TMP/up" src > "$TMP/raw.txt" 2>&1 || true
|
||
|
||
# 分类:内容不同 / 只在 src(我们新增)/ 只在上游(我们删了)
|
||
DIFFERS=$(grep -oE '^Files .* and src/.* differ$' "$TMP/raw.txt" | sed -E 's#^Files .* and (src/.*) differ$#\1#' | sort || true)
|
||
ONLY_SRC=$(grep -oE "^Only in src.*: .*$" "$TMP/raw.txt" | sed -E 's#^Only in (src[^:]*): (.*)$#\1/\2#' | sed 's#^\./##' | sort || true)
|
||
ONLY_UP=$(grep -oE "^Only in .*lsky-pro.*: .*$" "$TMP/raw.txt" | grep -v 'Only in src' | sed -E 's#^Only in [^:]*: (.*)$#\1#' | sort || true)
|
||
|
||
# 空字符串要变成「零行」(不能变成一行空行,否则 comm 会误判)
|
||
lines() { [ -n "${1:-}" ] && printf '%s\n' "$1" || true; }
|
||
|
||
echo
|
||
echo "=== 内容不同的文件(应恰好落在「已知偏离清单」内)==="
|
||
if [ -n "$DIFFERS" ]; then echo "$DIFFERS"; else echo "(无)"; fi
|
||
|
||
if [ -n "$ONLY_SRC" ] || [ -n "$ONLY_UP" ]; then
|
||
echo
|
||
echo "=== 只在一边存在的文件(信息展示,不参与报警)==="
|
||
[ -n "$ONLY_SRC" ] && echo "$ONLY_SRC" | sed 's/^/ 只在 src\/:/'
|
||
[ -n "$ONLY_UP" ] && echo "$ONLY_UP" | sed 's/^/ 只在上游:/'
|
||
fi
|
||
|
||
echo
|
||
echo "=== 每个文件的详细 diff ==="
|
||
for f in $DIFFERS; do
|
||
echo "---- $f"
|
||
diff -u "$TMP/up/${f#src/}" "$f" || true
|
||
done
|
||
|
||
echo
|
||
echo "[3/3] 已知偏离清单校验:"
|
||
UNEXPECTED="$(comm -23 <(lines "$DIFFERS") <(lines "$KNOWN") || true)"
|
||
STALE="$(comm -13 <(lines "$DIFFERS") <(lines "$KNOWN") || true)"
|
||
if [ -n "$UNEXPECTED" ]; then
|
||
echo " ❌ 有清单之外的改动(要么是有意的、请登记进 KNOWN_DEVIATIONS 并写一句理由,要么是手滑):"
|
||
printf '%s\n' "$UNEXPECTED" | sed 's/^/ /'
|
||
exit 1
|
||
fi
|
||
echo " ✅ src/ 相对上游的改动全部落在已知偏离清单内(清单 $(printf '%s\n' "$KNOWN" | wc -l | tr -d ' ') 项,实际不同 $(printf '%s\n' "$(lines "$DIFFERS")" | grep -c . || true) 项)"
|
||
if [ -n "$STALE" ]; then
|
||
echo " ⚠️ 清单里登记了、但实际已与上游一致(条目可清理):"
|
||
printf '%s\n' "$STALE" | sed 's/^/ /'
|
||
fi
|
||
echo
|
||
echo "提示:把上面的 diff 存进 patches/ios-longpress.patch 即可(patch 文件只是「给上下级看」的存档,不参与构建)。"
|