From 6ac69b93ac123471fcaec05025331e0686323d3b Mon Sep 17 00:00:00 2001 From: bookworm Date: Tue, 28 Apr 2026 00:37:35 +0800 Subject: [PATCH] =?UTF-8?q?security(v3.2.0):=20W4=20=E5=87=AD=E8=AF=81?= =?UTF-8?q?=E4=B8=8D=E5=B5=8C=20URL=20+=20W5=20OTA=20Copy=20=E6=9B=BF?= =?UTF-8?q?=E4=BB=A3=20Move?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit W4: clone URL 不再含明文凭证, 改为先 Cache-GitCredentials (credential manager) 再用原始 URL clone, git 自动取凭证 W5: OTA 原子替换 Move-Item → Copy-Item + Remove (04-27 Move 数据丢失教训, Copy 中途失败可完整回滚) Co-Authored-By: Claude Opus 4.6 (1M context) --- Bookworm-Setup.exe | Bin 238592 -> 238080 bytes auto-setup.ps1 | 16 ++++++---------- bw-ota.ps1 | 14 ++++++++------ 3 files changed, 14 insertions(+), 16 deletions(-) diff --git a/Bookworm-Setup.exe b/Bookworm-Setup.exe index c8dac6d6ac17b4d242e5d064ba79e48cb60dccda..71f175762cf33bc6d337c2f28bd5ac7cb7b289a7 100644 GIT binary patch delta 360 zcmZoT!PjtvZ$gJs-Guj<3{dcZfr*iuk(+^G4HE;y7l@$Usfnw?_+Ff3Vh9EaJYZt@ z@o}P}@MJ~CcrKS!Ky?a0(KVC17_}MKP2R?+&bVOmJw_#Ug;PK&An*WUCI(i9ggPdM z4sQkqMj*e4fr0IU7Xw4DG1K&o>zFh*2QW2gF?AX@U((rrNr$oCeY$P|qsH|721e8A z@x_dq(_Km#C8zIR#mKdNbt&Tl#_i?hKznd1nhsRtzTLixaRw`rn&WjqBjE;3?uzG~ zexRC>dwYH(W9UOhhV6%wnBF=GSkITd<7>v`H2Jb6+x(7wx!VscW$NJ&5`g*!#G!cD@ZvzdkZKSZxqO_?Z7z6f4Ds%f$5EtK+m+#)vuQ<^I3Oo-S?RZZc*D~7Bls52$evSCn$;bf!GQY j6~&l=iFUjA8m8%t+xgZp{rbqXz-GJP0_OLO6Ajn_Q{)KQ diff --git a/auto-setup.ps1 b/auto-setup.ps1 index 5d977a8..375cc22 100644 --- a/auto-setup.ps1 +++ b/auto-setup.ps1 @@ -1660,9 +1660,8 @@ elseif (Test-Path $ClaudeDir) { Log-Warn "匿名克隆失败, 弹凭证对话框重试..." $cred = Show-GiteaCredentialDialog if ($cred) { - $cloneUrl = $GitUrl -replace '://', "://$([System.Uri]::EscapeDataString($cred.User)):$([System.Uri]::EscapeDataString($cred.Pass))@" - $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $cloneUrl, $ClaudeDir) "克隆配置仓库 (认证)" 180000 - if (Test-CloneComplete) { Cache-GitCredentials $cred } + Cache-GitCredentials $cred + $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $GitUrl, $ClaudeDir) "克隆配置仓库 (认证)" 180000 } } if (Test-CloneComplete) { @@ -1676,15 +1675,13 @@ elseif (Test-Path $ClaudeDir) { } else { Log-Info "首次安装, 匿名克隆配置仓库..." - # v3.0.1 先匿名, 失败才弹凭证 $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $GitUrl, $ClaudeDir) "克隆配置仓库 (匿名)" 180000 if (-not (Test-CloneComplete)) { Log-Warn "匿名克隆失败, 弹凭证对话框重试..." $cred = Show-GiteaCredentialDialog if ($cred) { - $cloneUrl = $GitUrl -replace '://', "://$([System.Uri]::EscapeDataString($cred.User)):$([System.Uri]::EscapeDataString($cred.Pass))@" - $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $cloneUrl, $ClaudeDir) "克隆配置仓库 (认证)" 180000 - if (Test-CloneComplete) { Cache-GitCredentials $cred } + Cache-GitCredentials $cred + $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $GitUrl, $ClaudeDir) "克隆配置仓库 (认证)" 180000 } } if (Test-CloneComplete) { @@ -1718,9 +1715,8 @@ if (Test-Path (Join-Path $BootDir ".git")) { Log-Warn "匿名克隆失败, 弹凭证对话框重试..." $cred = Show-GiteaCredentialDialog if ($cred) { - $bootCloneUrl = $BootUrl -replace '://', "://$([System.Uri]::EscapeDataString($cred.User)):$([System.Uri]::EscapeDataString($cred.Pass))@" - $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $bootCloneUrl, $BootDir) "克隆 boot 仓库 (认证)" 180000 - if (Test-Path (Join-Path $BootDir "crypto-helper.js")) { Cache-GitCredentials $cred } + Cache-GitCredentials $cred + $r = Run-CmdWithUI "git" @("clone", "--depth", "1", $BootUrl, $BootDir) "克隆 boot 仓库 (认证)" 180000 } } if (-not (Test-Path (Join-Path $BootDir "crypto-helper.js"))) { diff --git a/bw-ota.ps1 b/bw-ota.ps1 index 5e508bc..2ff09dc 100644 --- a/bw-ota.ps1 +++ b/bw-ota.ps1 @@ -167,12 +167,12 @@ function Invoke-OtaSync ($cred, $cfg, $remoteVersion) { $stageDir = Join-Path $env:TEMP "bw-ota-$([Guid]::NewGuid().ToString().Substring(0,8))" - # 1. Clone (basic auth user:pass) + # 1. Clone (凭证通过 credential manager 传递, 不嵌入 URL) Write-Ota "下载 $ref ..." - $escapedUser = [Uri]::EscapeDataString($cred.user) - $escapedPass = [Uri]::EscapeDataString($cred.pass) - $cloneUrl = "https://${escapedUser}:${escapedPass}@${host_}/${repoPath}.git" - $cloneArgs = @('-c', 'core.longpaths=true', 'clone', '--depth', '1', '--branch', $ref, '--single-branch', $cloneUrl, $stageDir) + $plainUrl = "https://${host_}/${repoPath}.git" + $credInput = "protocol=https`nhost=${host_}`nusername=$($cred.user)`npassword=$($cred.pass)`n`n" + $credInput | & git credential approve 2>$null + $cloneArgs = @('-c', 'core.longpaths=true', 'clone', '--depth', '1', '--branch', $ref, '--single-branch', $plainUrl, $stageDir) & git @cloneArgs 2>&1 | Out-Null if ($LASTEXITCODE -ne 0) { throw "clone 失败 (exit $LASTEXITCODE)" } $gitDir = Join-Path $stageDir '.git' @@ -276,9 +276,11 @@ process.exit(crypto.verify(null,d,k,s)?0:1); } } try { - Move-Item -Path $stageDir -Destination $ClaudeRoot -ErrorAction Stop + Copy-Item -Path $stageDir -Destination $ClaudeRoot -Recurse -Force -ErrorAction Stop + Remove-Item -Path $stageDir -Recurse -Force -ErrorAction SilentlyContinue } catch { if ($bakFull -and (Test-Path $bakFull)) { + Remove-Item -Path $ClaudeRoot -Recurse -Force -ErrorAction SilentlyContinue Rename-Item -Path $bakFull -NewName (Split-Path -Leaf $ClaudeRoot) Write-OtaWarn "替换失败, 已回滚到原版本" }