diff --git a/.gitignore b/.gitignore index 4ce37a3..a0b8260 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ secrets.txt +users.txt +auto-setup.ps1.bak-* +.tmp-authcodes.json 管理员SOP.html dist/ diff --git a/auto-setup.ps1 b/auto-setup.ps1 index b4759cf..9837de3 100644 --- a/auto-setup.ps1 +++ b/auto-setup.ps1 @@ -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"