fix(installer): 修复 EXE 安装器关键缺陷 + 多用户加密文件首发
根因 (auto-setup.ps1): 1. $BootUrl 定义但未使用 — bookworm-boot 仓库从未被克隆 2. $ScriptDir 在 PS2EXE 打包后回退到 $PWD (Downloads 目录) 3. Phase 4 在 EXE 同目录找 crypto-helper.js / secrets-*.enc → 必然失败 4. Phase 6 桌面快捷方式同样指向 $ScriptDir → 路径错误 修复: - $ScriptDir 改用 Process.MainModule + PSScriptRoot 三级回退 (PS2EXE 兼容) - 新增 $BootDir = $ScriptDir/bookworm-boot - Phase 3 增加克隆/更新 bookworm-boot 仓库逻辑 (失败 fail-fast) - Phase 4 crypto-helper.js / secrets-*.enc 路径统一指向 $BootDir - Phase 6 快捷方式 .bat 路径同样改用 $BootDir 附加: - 新增多用户加密文件 secrets-dfff6f13.enc (用户: 茶师兄, 30 天有效期) - .gitignore 新增 users.txt / .tmp-authcodes.json / auto-setup.ps1.bak-* 防泄露 - 删除旧版 secrets.enc (单用户共享模式废弃) 测试: - gen-authcode.js → encrypt → crypto-helper.js decrypt 闭环验证通过 - PS2EXE build artifact (215 KB) 经字符串扫描确认 5 处补丁已编译 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a2a7ff1edb
commit
3cb6f1dac1
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
secrets.txt
|
||||
users.txt
|
||||
auto-setup.ps1.bak-*
|
||||
.tmp-authcodes.json
|
||||
管理员SOP.html
|
||||
dist/
|
||||
|
||||
@ -16,12 +16,22 @@ param(
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# ─── 路径定义 ────────────────────────────────────────
|
||||
$ScriptDir = if ($MyInvocation.MyCommand.Path) { Split-Path -Parent $MyInvocation.MyCommand.Path } else { $PWD.Path }
|
||||
# PS2EXE 兼容: $MyInvocation.MyCommand.Path 在 EXE 启动时为空,需用 Process MainModule
|
||||
$ScriptDir = if ($PSScriptRoot) {
|
||||
$PSScriptRoot
|
||||
} elseif ([System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName -match '\.exe$') {
|
||||
Split-Path -Parent ([System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName)
|
||||
} elseif ($MyInvocation.MyCommand.Path) {
|
||||
Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
} else {
|
||||
$PWD.Path
|
||||
}
|
||||
$ClaudeDir = Join-Path $env:USERPROFILE ".claude"
|
||||
$BackupDir = Join-Path $env:USERPROFILE ".claude.bw-backup"
|
||||
$GitUrl = "https://code.letcareme.com/bookworm/bookworm-config.git"
|
||||
$BootUrl = "https://code.letcareme.com/bookworm/bookworm-boot.git"
|
||||
$SecretsEnc = Join-Path $ScriptDir "secrets.enc"
|
||||
$BootDir = Join-Path $ScriptDir "bookworm-boot"
|
||||
$SecretsEnc = Join-Path $BootDir "secrets.enc"
|
||||
$TOTAL_PHASES = 7
|
||||
|
||||
# ─── GUI 初始化 ─────────────────────────────────────
|
||||
@ -238,21 +248,21 @@ function New-DesktopShortcuts {
|
||||
$shell = New-Object -ComObject WScript.Shell
|
||||
$desktop = $shell.SpecialFolders("Desktop")
|
||||
|
||||
# 快速启动
|
||||
# 快速启动 (bat 文件位于 bookworm-boot 仓库内)
|
||||
$shortcut = $shell.CreateShortcut("$desktop\Bookworm.lnk")
|
||||
$batPath = Join-Path $ScriptDir "启动Bookworm.bat"
|
||||
if (-not (Test-Path $batPath)) { $batPath = Join-Path $ScriptDir "Bookworm-OneClick.bat" }
|
||||
$batPath = Join-Path $BootDir "启动Bookworm.bat"
|
||||
if (-not (Test-Path $batPath)) { $batPath = Join-Path $BootDir "Bookworm-OneClick.bat" }
|
||||
$shortcut.TargetPath = $batPath
|
||||
$shortcut.WorkingDirectory = $ScriptDir
|
||||
$shortcut.WorkingDirectory = $BootDir
|
||||
$shortcut.Description = "Bookworm Smart Assistant"
|
||||
$shortcut.Save()
|
||||
|
||||
# 更新启动
|
||||
$shortcut2 = $shell.CreateShortcut("$desktop\更新Bookworm.lnk")
|
||||
$updateBat = Join-Path $ScriptDir "更新并启动Bookworm.bat"
|
||||
$updateBat = Join-Path $BootDir "更新并启动Bookworm.bat"
|
||||
if (Test-Path $updateBat) {
|
||||
$shortcut2.TargetPath = $updateBat
|
||||
$shortcut2.WorkingDirectory = $ScriptDir
|
||||
$shortcut2.WorkingDirectory = $BootDir
|
||||
$shortcut2.Description = "更新并启动 Bookworm"
|
||||
$shortcut2.Save()
|
||||
}
|
||||
@ -592,6 +602,32 @@ foreach ($d in $dirs) {
|
||||
if (-not (Test-Path $p)) { New-Item -ItemType Directory -Path $p -Force | Out-Null }
|
||||
}
|
||||
|
||||
# ─── 克隆/更新 bookworm-boot (含 crypto-helper.js + secrets-*.enc + install.ps1) ───
|
||||
if (Test-Path (Join-Path $BootDir ".git")) {
|
||||
Log-Info "boot 仓库已存在, 更新中..."
|
||||
Push-Location $BootDir
|
||||
try {
|
||||
git pull --rebase 2>&1 | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
Log-OK "boot 仓库已更新"
|
||||
} catch { Log-Warn "boot 仓库更新失败, 使用本地版本" }
|
||||
finally { Pop-Location }
|
||||
} else {
|
||||
Log-Info "克隆 boot 仓库 (含解密工具与凭证)..."
|
||||
if (-not $cred) { $cred = Show-GiteaCredentialDialog }
|
||||
if ($cred) {
|
||||
$bootCredUrl = $BootUrl -replace '://', "://$($cred.User):$($cred.Pass)@"
|
||||
git clone --depth 1 $bootCredUrl $BootDir 2>&1 | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
} else {
|
||||
git clone --depth 1 $BootUrl $BootDir 2>&1 | ForEach-Object { Write-Host " $_" -ForegroundColor Gray }
|
||||
}
|
||||
if (-not (Test-Path (Join-Path $BootDir "crypto-helper.js"))) {
|
||||
Log-Fail "boot 仓库克隆失败 (crypto-helper.js 缺失)"
|
||||
Show-MsgBox "boot 仓库克隆失败。`n请检查网络和 Gitea 凭证。" "克隆失败" "OK" "Error"
|
||||
exit 1
|
||||
}
|
||||
Log-OK "boot 仓库克隆成功 → $BootDir"
|
||||
}
|
||||
|
||||
# ========================================================================
|
||||
# Phase 4: 凭证解密 (GUI 弹窗)
|
||||
# ========================================================================
|
||||
@ -606,12 +642,12 @@ if (Get-CachedSecrets) {
|
||||
}
|
||||
# 再解密 (缓存命中则跳过)
|
||||
if (-not $secretsDecrypted) {
|
||||
$cryptoHelper = Join-Path $ScriptDir "crypto-helper.js"
|
||||
$cryptoHelper = Join-Path $BootDir "crypto-helper.js"
|
||||
$useNode = (Test-Cmd "node") -and (Test-Path $cryptoHelper)
|
||||
if (-not $useNode -and -not $opensslCmd) {
|
||||
Log-Fail "无解密工具 (需要 Node.js 或 OpenSSL)"
|
||||
}
|
||||
elseif ((Test-Path $SecretsEnc) -or (Get-ChildItem $ScriptDir -Filter "secrets-*.enc" -ErrorAction SilentlyContinue)) {
|
||||
elseif ((Test-Path $SecretsEnc) -or (Get-ChildItem $BootDir -Filter "secrets-*.enc" -ErrorAction SilentlyContinue)) {
|
||||
$validAttempts = 0
|
||||
while ($validAttempts -lt 3) {
|
||||
$rawCode = Show-AuthCodeDialog ($validAttempts + 1) 3
|
||||
@ -633,7 +669,7 @@ elseif ((Test-Path $SecretsEnc) -or (Get-ChildItem $ScriptDir -Filter "secrets-*
|
||||
|
||||
# 按 token 前8位定位 .enc 文件 (多用户独立 Key),回退 secrets.enc
|
||||
$fileId = $token.Substring(0, 8)
|
||||
$encFile = Join-Path $ScriptDir "secrets-$fileId.enc"
|
||||
$encFile = Join-Path $BootDir "secrets-$fileId.enc"
|
||||
if (-not (Test-Path $encFile)) { $encFile = $SecretsEnc }
|
||||
if (-not (Test-Path $encFile)) {
|
||||
Show-MsgBox "未找到对应凭证文件。`n请确认管理员已推送 secrets-$fileId.enc 到 Gitea`n并重新运行安装器(会自动拉取)。" "文件未找到" "OK" "Warning"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user