chore: prepare production release package

This commit is contained in:
wushumin
2026-06-05 16:12:56 +08:00
parent ed87ea1541
commit 995eae3969
15 changed files with 740 additions and 37 deletions

View File

@@ -593,39 +593,92 @@ class SystemConfigsController
throw new \RuntimeException('收钱吧订单有效分钟数需填写 1-43200 之间的整数');
}
if (!$this->isPemContentOrReadablePath((string)$configValueMap['payment.merchant_private_key'])) {
throw new \RuntimeException('商户 RSA 私钥需填写 PEM 内容,或填写服务器可读取的 PEM 文件路径');
if (!$this->isPrivateKeyContentOrReadablePath((string)$configValueMap['payment.merchant_private_key'])) {
throw new \RuntimeException('商户 RSA 私钥需填写可被 OpenSSL 解析的 PEM 内容,或填写服务器可读取的 PEM 文件路径');
}
if (!$this->isPublicKeyContentOrReadablePath((string)$configValueMap['payment.shouqianba_public_key'])) {
throw new \RuntimeException('收钱吧 RSA 公钥需填写 PEM 内容、纯公钥文本,或填写服务器可读取的 PEM 文件路径');
throw new \RuntimeException('收钱吧 RSA 公钥需填写可被 OpenSSL 解析的 PEM 内容、纯公钥文本,或填写服务器可读取的 PEM 文件路径');
}
}
private function isPrivateKeyContentOrReadablePath(string $value): bool
{
$content = $this->pemContentOrReadablePath($value);
if ($content === '') {
return false;
}
$key = openssl_pkey_get_private($content);
$ok = $key !== false;
$this->clearOpenSslErrors();
return $ok;
}
private function isPublicKeyContentOrReadablePath(string $value): bool
{
$value = trim($value);
if ($this->isPemContentOrReadablePath($value)) {
$content = $this->pemContentOrReadablePath($value);
if ($content !== '' && $this->canOpenPublicKey($content)) {
return true;
}
return $this->looksLikeBase64KeyBody($value);
if (!$this->looksLikeBase64KeyBody($value)) {
return false;
}
return $this->canOpenPublicKey($this->wrapPemKey($value, 'PUBLIC KEY'));
}
private function isPemContentOrReadablePath(string $value): bool
private function pemContentOrReadablePath(string $value): string
{
$value = trim($value);
if ($value === '') {
return false;
return '';
}
if (str_contains($value, '-----BEGIN')) {
return true;
return $this->normalizePemNewlines($value);
}
if (!is_file($value) || !is_readable($value)) {
return false;
return '';
}
$content = file_get_contents($value);
return is_string($content) && str_contains($content, '-----BEGIN');
if (!is_string($content) || !str_contains($content, '-----BEGIN')) {
return '';
}
return $this->normalizePemNewlines($content);
}
private function canOpenPublicKey(string $content): bool
{
$key = openssl_pkey_get_public($content);
$ok = $key !== false;
$this->clearOpenSslErrors();
return $ok;
}
private function wrapPemKey(string $value, string $pemLabel): string
{
$body = preg_replace('/\s+/', '', trim($value)) ?: '';
return sprintf(
"-----BEGIN %s-----\n%s\n-----END %s-----",
$pemLabel,
rtrim(chunk_split($body, 64, "\n")),
$pemLabel
);
}
private function normalizePemNewlines(string $value): string
{
return str_replace(["\\r\\n", "\\n", "\\r"], ["\n", "\n", "\r"], $value);
}
private function clearOpenSslErrors(): void
{
while (openssl_error_string() !== false) {
}
}
private function looksLikeBase64KeyBody(string $value): bool