fix: normalize v1.21.0 updater signing key

This commit is contained in:
coso
2026-04-28 10:33:42 +08:00
parent af597c6fd7
commit fba6b22493
3 changed files with 39 additions and 28 deletions
+13 -27
View File
@@ -268,6 +268,7 @@ jobs:
run: |
python - <<'PY'
import base64
import binascii
import os
from pathlib import Path
@@ -286,46 +287,31 @@ jobs:
if "\\n" in raw and "\n" not in raw:
add(raw.replace("\\r\\n", "\n").replace("\\n", "\n"))
for candidate in list(candidates):
compact = candidate.strip()
if not compact:
continue
padding = (-len(compact)) % 4
compact = compact + ("=" * padding)
def as_tauri_secret_key(value: str) -> str:
compact = "".join(value.split())
try:
decoded = base64.b64decode(compact, validate=True).decode("utf-8")
except Exception:
continue
add(decoded)
if "\\n" in decoded and "\n" not in decoded:
add(decoded.replace("\\r\\n", "\n").replace("\\n", "\n"))
base64.b64decode(compact, validate=True)
except (binascii.Error, ValueError):
return ""
return compact
normalized_key = next(
(
candidate
key
for candidate in candidates
if candidate.lstrip().startswith("untrusted comment:")
and "\n" in candidate
for key in [as_tauri_secret_key(candidate)]
if key
),
"",
)
if not normalized_key:
normalized_key = next(
(
candidate
for candidate in candidates
if candidate.lstrip().startswith("untrusted comment:")
),
"",
)
if not normalized_key:
raise SystemExit(
"Unable to normalize TAURI_SIGNING_PRIVATE_KEY into minisign secret key content. "
"Expected raw multiline key, literal \\\\n escaped key, or base64 encoded key."
"Unable to normalize TAURI_SIGNING_PRIVATE_KEY into Tauri signer base64 key content. "
"Expected the private key value generated by `npx tauri signer generate --write-keys`."
)
key_path = Path(os.environ["RUNNER_TEMP"]) / "tauri-updater.key"
key_path.write_text(normalized_key.rstrip("\n") + "\n", encoding="utf-8")
key_path.write_text(normalized_key, encoding="utf-8")
key_path.chmod(0o600)
with open(os.environ["GITHUB_ENV"], "a", encoding="utf-8") as env_file:
+14
View File
@@ -40,6 +40,7 @@ describe("oemCloudStartupLogin", () => {
delete window.__LIME_BOOTSTRAP__;
delete window.__LIME_OEM_CLOUD__;
delete window.__LIME_SESSION_TOKEN__;
vi.spyOn(console, "warn").mockImplementation(() => undefined);
mockListPublicOAuthProviders.mockResolvedValue([
{
provider: "google",
@@ -120,4 +121,17 @@ describe("oemCloudStartupLogin", () => {
expect(result.status).toBe("no_google_provider");
expect(mockStartOemCloudLogin).not.toHaveBeenCalled();
});
it("读取后端登录策略失败时不应阻塞主应用启动", async () => {
configureRuntime();
mockListPublicOAuthProviders.mockRejectedValue(new Error("network down"));
const result = await startOemCloudStartupLoginIfRequired();
expect(result).toEqual({
status: "failed",
reason: "network down",
});
expect(mockStartOemCloudLogin).not.toHaveBeenCalled();
});
});
+12 -1
View File
@@ -83,7 +83,18 @@ export async function startOemCloudStartupLoginIfRequired(
return { status: "already_attempted" };
}
const providers = await listPublicOAuthProviders(runtime.tenantId);
let providers: OemCloudPublicOAuthProvider[];
try {
providers = await listPublicOAuthProviders(runtime.tenantId);
} catch (error) {
const reason =
error instanceof Error && error.message.trim()
? error.message.trim()
: "读取云端登录配置失败";
console.warn("读取启动期云端登录配置失败:", error);
return { status: "failed", reason };
}
if (!hasGoogleOAuthProvider(providers)) {
return { status: "no_google_provider" };
}