fix: 修复授权码认证的 2 个 BLOCKER + 3 个 WARNING

BLOCKER:
- Bookworm-Setup.sh: ${var,,} → tr 兼容 macOS bash 3.2
- Bookworm-Setup.sh: while 循环加 total_attempts<10 防死循环

WARNING:
- install.ps1: 重写 Decrypt-Secrets 为 while 双计数器,
  格式/过期错误不消耗有效次数,清理残留"主密码"文案
- install.ps1 + auto-setup.ps1: 格式示例去掉误导性空格
  (XXXXXXXX → XXXXXXXXXXXXXXXXXXXXXXXX)

其他:
- 新增 .gitignore,排除 secrets.txt 防止明文密钥误提交

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
bookworm 2026-04-06 22:57:47 +08:00
parent b83c508c22
commit 51525d3c1f
4 changed files with 22 additions and 27 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
secrets.txt

View File

@ -292,7 +292,7 @@ parse_authcode() {
echo "EXPIRED"
return
fi
echo "${token_upper,,}" # bash4+ 转小写
echo "$token_upper" | tr '[:upper:]' '[:lower:]' # 兼容 bash 3.2 (macOS 默认)
}
# 先尝试缓存
@ -301,17 +301,19 @@ if load_cached_secrets 2>/dev/null; then
elif [ -f "$SECRETS_ENC" ]; then
DECRYPTED=""
valid_attempts=0
while [ $valid_attempts -lt 3 ]; do
total_attempts=0
while [ $valid_attempts -lt 3 ] && [ $total_attempts -lt 10 ]; do
echo ""
read -p " 输入授权码 (BW-YYYYMMDD-XXXXXX, 第 $((valid_attempts+1))/3 次): " AUTH_CODE
total_attempts=$((total_attempts + 1))
TOKEN=$(parse_authcode "$AUTH_CODE")
AUTH_CODE=""
if [ "$TOKEN" = "EXPIRED" ]; then
warn "授权码已过期, 请联系管理员获取新授权码"
continue # 不消耗尝试次数
continue # 不消耗有效次数
elif [ -z "$TOKEN" ]; then
warn "授权码格式错误 (格式: BW-YYYYMMDD-24位字母数字)"
continue # 不消耗尝试次数
warn "授权码格式错误 (格式: BW-YYYYMMDD-XXXXXXXXXXXXXXXXXXXXXXXX)"
continue # 不消耗有效次数
fi
valid_attempts=$((valid_attempts + 1))
DECRYPTED=$(_decrypt_secrets "$TOKEN" "$SECRETS_ENC") || true

View File

@ -231,38 +231,33 @@ function Decrypt-Secrets {
}
$cryptoHelper = Join-Path $ScriptDir "crypto-helper.js"
$maxRetries = 3
for ($attempt = 1; $attempt -le $maxRetries; $attempt++) {
$label = if ($attempt -gt 1) { " 重新输入授权码 (第 $attempt/$maxRetries 次)" } else { " 输入授权码 (格式: BW-YYYYMMDD-...)" }
$validAttempts = 0
$totalAttempts = 0
while ($validAttempts -lt 3 -and $totalAttempts -lt 10) {
$totalAttempts++
$label = if ($validAttempts -gt 0) { " 重新输入授权码 (第 $($validAttempts+1)/3 次)" } else { " 输入授权码 (格式: BW-YYYYMMDD-...)" }
$authCodeRaw = Read-Host $label
$plainPwd = Parse-AuthCode $authCodeRaw
if (-not $plainPwd) {
# 格式错误或已过期: 不计入密码重试, 直接继续
$attempt--
$maxRetries-- # 最多给 3 次有效尝试
if ($maxRetries -lt 1) { break }
# 格式错误或已过期: 不计入有效重试次数
continue
}
$validAttempts++
$prevEAP = $ErrorActionPreference
$ErrorActionPreference = "Continue"
if ($useNode) {
# Node.js 解密 (跨平台一致)
$decrypted = & node $cryptoHelper decrypt $plainPwd $SecretsEnc 2>&1
$decExit = $LASTEXITCODE
} else {
# openssl 回退
$decrypted = $plainPwd | & $opensslCmd enc -aes-256-cbc -d -pbkdf2 -iter 600000 -md sha256 -in $SecretsEnc -pass stdin 2>&1
$decExit = $LASTEXITCODE
}
$ErrorActionPreference = $prevEAP
# 清除内存中的 token
$plainPwd = $null
if ($decExit -eq 0 -and $decrypted -and $decrypted -notmatch 'PASSWORD_ERROR|FORMAT_ERROR|bad decrypt') {
# 解密成功,注入环境变量
$decrypted -split "`n" | ForEach-Object {
$line = $_.Trim()
if ($line -and $line.Contains('=')) {
@ -276,18 +271,15 @@ function Decrypt-Secrets {
return
}
# 解密失败
$remaining = $maxRetries - $attempt
$remaining = 3 - $validAttempts
if ($remaining -gt 0) {
Write-Host " [!!] 密码错误,剩余重试: $remaining" -ForegroundColor Red
Write-Host " [!!] 授权码无效 (解密失败),剩余重试: $remaining" -ForegroundColor Red
}
}
# 3次全部失败
Write-Host ""
Write-Host " [ABORT] 3 次密码均错误" -ForegroundColor Red
Write-Host " 请确认主密码是否正确 (区分大小写)" -ForegroundColor Yellow
Write-Host " 如忘记密码,请联系管理员重新生成 secrets.enc" -ForegroundColor Yellow
Write-Host " [ABORT] 3 次授权码均无效,凭证未解密" -ForegroundColor Red
Write-Host " 请确认授权码是否正确,或联系管理员重新生成" -ForegroundColor Yellow
exit 1
}