Browse Source

支持生成自签SSL证书

tags/2.7
flucout 1 month ago
parent
commit
5e1f19de53
  1. 70
      app/common.php
  2. 33
      app/controller/Admin.php
  3. 27
      app/controller/Api.php
  4. 2
      app/middleware/LoadConfig.php
  5. 31
      app/script/cacert.sh
  6. 2
      app/view/admin/deplist.html
  7. 17
      app/view/admin/layout.html
  8. 6
      app/view/admin/list.html
  9. 6
      app/view/admin/log.html
  10. 12
      app/view/admin/login.html
  11. 6
      app/view/admin/plugins.html
  12. 6
      app/view/admin/pluginswin.html
  13. 6
      app/view/admin/record.html
  14. 2
      app/view/admin/set.html
  15. 86
      app/view/admin/ssl.html
  16. 6
      app/view/index/download.html
  17. 2
      app/view/install/index.html
  18. 12
      install.sql
  19. 3
      route/app.php

70
app/common.php

@ -180,6 +180,11 @@ function checkIfActive($string) {
return null; return null;
} }
function checkDomain($domain){
if(empty($domain) || !preg_match('/^[-$a-z0-9_*.]{2,512}$/i', $domain) || (stripos($domain, '.') === false) || substr($domain, -1) == '.' || substr($domain, 0 ,1) == '.' || substr($domain, 0 ,1) == '*' && substr($domain, 1 ,1) != '.' || substr_count($domain, '*')>1 || strpos($domain, '*')>0 || strlen($domain)<4) return false;
return true;
}
function errorlog($msg){ function errorlog($msg){
$handle = fopen(app()->getRootPath()."record.txt", 'a'); $handle = fopen(app()->getRootPath()."record.txt", 'a');
fwrite($handle, date('Y-m-d H:i:s')."\t".$msg."\r\n"); fwrite($handle, date('Y-m-d H:i:s')."\t".$msg."\r\n");
@ -225,3 +230,68 @@ function pemToBase64($pem){
} }
return $encoded; return $encoded;
} }
function makeSelfSignSSL(string $commonName, array $domainList, $validity = 3650){
// 加载 CA 证书和私钥
$dir = app()->getBasePath().'script/';
$caCert = file_get_contents($dir.'ca.crt');
$caPrivateKey = file_get_contents($dir.'ca.key');
$opensslConfigFile = sys_get_temp_dir().'/openssl'.time().mt_rand(1000, 9999).'.cnf';
$opensslConfigContent = <<<EOF
[req]
req_extensions = extension_section
x509_extensions = extension_section
distinguished_name = dn
[dn]
[extension_section]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
EOF;
$ip_index = 1;
$dns_index = 1;
foreach ($domainList as $value) {
if(empty($value)) continue;
if(filter_var($value, FILTER_VALIDATE_IP)){
$opensslConfigContent .= sprintf("\nIP.%d = %s", $ip_index, $value);
$ip_index++;
}else{
$opensslConfigContent .= sprintf("\nDNS.%d = %s", $dns_index, $value);
$dns_index++;
}
}
if(!file_put_contents($opensslConfigFile, $opensslConfigContent)) return false;
// 生成域名证书的私钥和 CSR
$domainPrivateKey = openssl_pkey_new([
'private_key_bits' => 2048,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);
if(!$domainPrivateKey) return false;
$csrConfig = ['digest_alg' => 'sha256', 'config' => $opensslConfigFile];
$domainCsr = openssl_csr_new([
'commonName' => $commonName
], $domainPrivateKey, $csrConfig);
if(!$domainCsr) return false;
// 生成域名证书
$domainCertificate = openssl_csr_sign($domainCsr, $caCert, $caPrivateKey, $validity, $csrConfig);
if(!$domainCertificate) return false;
// 导出域名证书
openssl_x509_export($domainCertificate, $certificate);
openssl_pkey_export($domainPrivateKey, $privateKey);
$certificate .= $caCert;
unlink($opensslConfigFile);
return ['cert' => $certificate, 'key' => $privateKey];
}

33
app/controller/Admin.php

@ -400,4 +400,37 @@ class Admin extends BaseController
Cache::clear(); Cache::clear();
return json(['code'=>0,'msg'=>'succ']); return json(['code'=>0,'msg'=>'succ']);
} }
public function ssl(){
if(request()->isAjax()){
$domain_list = input('post.domain_list', null, 'trim');
$common_name = input('post.common_name', null, 'trim');
$validity = input('post.validity/d');
if(empty($domain_list) || empty($validity)){
return json(['code'=>-1, 'msg'=>'参数不能为空']);
}
$array = explode("\n", $domain_list);
$domain_list = [];
foreach($array as $domain){
$domain = trim($domain);
if(empty($domain)) continue;
if(!checkDomain($domain)) return json(['code'=>-1, 'msg'=>'域名或IP格式不正确:'.$domain]);
$domain_list[] = $domain;
}
if(empty($domain_list)) return json(['code'=>-1, 'msg'=>'域名列表不能为空']);
if(empty($common_name)) $common_name = $domain_list[0];
$result = makeSelfSignSSL($common_name, $domain_list, $validity);
if(!$result){
return json(['code'=>-1, 'msg'=>'生成证书失败']);
}
return json(['code'=>0, 'msg'=>'生成证书成功', 'cert'=>$result['cert'], 'key'=>$result['key']]);
}
$dir = app()->getBasePath().'script/';
$ssl_path = app()->getRootPath().'public/ssl/baota_root.pfx';
$ssl_path_mac = app()->getRootPath().'public/ssl/baota_root.crt';
$isca = file_exists($dir.'ca.crt') && file_exists($dir.'ca.key') && file_exists($ssl_path) && file_exists($ssl_path_mac);
View::assign('isca', $isca);
return view();
}
} }

27
app/controller/Api.php

@ -464,4 +464,31 @@ class Api extends BaseController
fclose($handle); fclose($handle);
return json(['status'=>false, 'msg'=>'不支持当前操作']); return json(['status'=>false, 'msg'=>'不支持当前操作']);
} }
//生成自签名SSL证书
public function bt_cert(){
$data = input('post.data');
$param = json_decode($data, true);
if(!$param || !isset($param['domain'])) return json(['status'=>false, 'msg'=>'参数错误']);
$dir = app()->getBasePath().'script/';
$ssl_path = app()->getRootPath().'public/ssl/baota_root.pfx';
$isca = file_exists($dir.'ca.crt') && file_exists($dir.'ca.key') && file_exists($ssl_path);
if(!$isca) return json(['status'=>false, 'msg'=>'CA证书不存在']);
$domain = $param['domain'];
if(empty($domain)) return json(['status'=>false, 'msg'=>'域名不能为空']);
$domain_list = explode(',', $domain);
foreach($domain_list as $d){
if(!checkDomain($d)) return json(['status'=>false, 'msg'=>'域名或IP格式不正确:'.$d]);
}
$common_name = $domain_list[0];
$validity = 3650;
$result = makeSelfSignSSL($common_name, $domain_list, $validity);
if(!$result){
return json(['status'=>false, 'msg'=>'生成证书失败']);
}
$ca_pfx = base64_encode(file_get_contents($ssl_path));
return json(['status'=>true, 'msg'=>'生成证书成功', 'cert'=>$result['cert'], 'key'=>$result['key'], 'pfx'=>$ca_pfx, 'password'=>'']);
}
} }

2
app/middleware/LoadConfig.php

@ -5,6 +5,7 @@ namespace app\middleware;
use think\facade\Db; use think\facade\Db;
use think\facade\Config; use think\facade\Config;
use think\facade\View;
class LoadConfig class LoadConfig
{ {
@ -31,6 +32,7 @@ class LoadConfig
$res = Db::name('config')->cache('configs',0)->column('value','key'); $res = Db::name('config')->cache('configs',0)->column('value','key');
Config::set($res, 'sys'); Config::set($res, 'sys');
View::assign('cdnpublic', '//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/');
return $next($request)->header([ return $next($request)->header([
'Cache-Control' => 'no-store, no-cache, must-revalidate', 'Cache-Control' => 'no-store, no-cache, must-revalidate',
'Pragma' => 'no-cache', 'Pragma' => 'no-cache',

31
app/script/cacert.sh

@ -0,0 +1,31 @@
#!/bin/bash
OPENSSL_CHECK=$(which openssl)
if [ "$?" != "0" ]; then
echo "未安装OpenSSL"
exit 1
fi
if [ ! -f ca.key ] && [ ! -f ca.crt ]; then
openssl genrsa -out ca.key 2048
openssl req -new -x509 -utf8 -days 3650 -extensions v3_ca -subj "/C=CN/O=宝塔面板/CN=宝塔面板" -key ca.key -out ca.crt
fi
openssl genrsa -out server.key 2048
openssl req -new -nodes -key server.key -subj "/C=CN/O=BTPanel/CN=BTPanel" -out server.csr
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -extensions req_ext
cat ca.crt >> server.crt
openssl pkcs12 -export -out baota_root.pfx -inkey server.key -in server.crt -password pass:
if [ "$?" != "0" ]; then
echo "生成CA根证书失败"
exit 1
fi
mkdir -p ../../public/ssl
\cp baota_root.pfx ../../public/ssl/baota_root.pfx
\cp ca.crt ../../public/ssl/baota_root.crt
rm -f server.crt server.key server.csr
echo "生成CA根证书成功"

2
app/view/admin/deplist.html

@ -16,7 +16,7 @@
</div> </div>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script> <script>
function refresh_deplist(os){ function refresh_deplist(os){
var confirm = layer.confirm('是否确定从宝塔官方获取最新一键部署列表?', { var confirm = layer.confirm('是否确定从宝塔官方获取最新一键部署列表?', {

17
app/view/admin/layout.html

@ -5,15 +5,15 @@
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>{block name="title"}标题{/block}</title> <title>{block name="title"}标题{/block}</title>
<link href="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="{$cdnpublic}twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="{$cdnpublic}font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="/static/css/bootstrap-table.css" rel="stylesheet" /> <link href="/static/css/bootstrap-table.css" rel="stylesheet" />
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/modernizr/2.8.3/modernizr.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.4/jquery.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="{$cdnpublic}modernizr/2.8.3/modernizr.min.js"></script>
<script src="{$cdnpublic}jquery/2.1.4/jquery.min.js"></script>
<script src="{$cdnpublic}twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
<script src="{$cdnpublic}html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="{$cdnpublic}respond.js/1.4.2/respond.min.js"></script>
<![endif]--> <![endif]-->
</head> </head>
<body> <body>
@ -51,6 +51,9 @@
<li class="{:checkIfActive('log')}"> <li class="{:checkIfActive('log')}">
<a href="/admin/log"><i class="fa fa-calendar"></i> 操作日志</a> <a href="/admin/log"><i class="fa fa-calendar"></i> 操作日志</a>
</li> </li>
<li class="{:checkIfActive('ssl')}">
<a href="/admin/ssl"><i class="fa fa-expeditedssl"></i> 自签SSL</a>
</li>
<li class="{:checkIfActive('set')}"> <li class="{:checkIfActive('set')}">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-cog"></i> 系统设置<b <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="fa fa-cog"></i> 系统设置<b
class="caret"></b></a> class="caret"></b></a>

6
app/view/admin/list.html

@ -42,9 +42,9 @@
</table> </table>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="/static/js/custom.js"></script> <script src="/static/js/custom.js"></script>
<script> <script>
function setEnable(id,enable) { function setEnable(id,enable) {

6
app/view/admin/log.html

@ -23,9 +23,9 @@
</table> </table>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="/static/js/custom.js"></script> <script src="/static/js/custom.js"></script>
<script> <script>

12
app/view/admin/login.html

@ -5,12 +5,12 @@
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1"/> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>管理员登录</title> <title>管理员登录</title>
<link href="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/modernizr/2.8.3/modernizr.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.4/jquery.min.js"></script>
<link href="{$cdnpublic}twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="{$cdnpublic}modernizr/2.8.3/modernizr.min.js"></script>
<script src="{$cdnpublic}jquery/2.1.4/jquery.min.js"></script>
<!--[if lt IE 9]> <!--[if lt IE 9]>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/respond.js/1.4.2/respond.min.js"></script>
<script src="{$cdnpublic}html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="{$cdnpublic}respond.js/1.4.2/respond.min.js"></script>
<![endif]--> <![endif]-->
</head> </head>
<body> <body>
@ -63,7 +63,7 @@
</div> </div>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script> <script>
function submitlogin(){ function submitlogin(){
var user = $("input[name='user']").val(); var user = $("input[name='user']").val();

6
app/view/admin/plugins.html

@ -69,9 +69,9 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:340px;
</table> </table>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="/static/js/custom.js"></script> <script src="/static/js/custom.js"></script>
<script> <script>

6
app/view/admin/pluginswin.html

@ -69,9 +69,9 @@ td{overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:340px;
</table> </table>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="/static/js/custom.js"></script> <script src="/static/js/custom.js"></script>
<script> <script>

6
app/view/admin/record.html

@ -23,9 +23,9 @@
</table> </table>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/bootstrap-table.min.js"></script>
<script src="{$cdnpublic}bootstrap-table/1.19.1/extensions/page-jump-to/bootstrap-table-page-jump-to.min.js"></script>
<script src="/static/js/custom.js"></script> <script src="/static/js/custom.js"></script>
<script> <script>

2
app/view/admin/set.html

@ -279,7 +279,7 @@ $("select[name='wbt_type']").change(function(){
</div> </div>
</div> </div>
{/if} {/if}
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script> <script>
$(document).ready(function(){ $(document).ready(function(){
var items = $("select[default]"); var items = $("select[default]");

86
app/view/admin/ssl.html

@ -0,0 +1,86 @@
{extend name="admin/layout" /}
{block name="title"}自签名SSL证书生成{/block}
{block name="main"}
<style>
.control-label[is-required]:before {
content: "*";
color: #f56c6c;
margin-right: 4px;
}
</style>
<div class="container" style="padding-top:70px;">
<div class="col-sm-12 col-md-10 col-lg-8 center-block" style="float: none;">
<div class="panel panel-primary">
<div class="panel-heading"><h3 class="panel-title">自签名SSL证书生成</h3></div>
<div class="panel-body">
{if $isca}
<div class="alert alert-warning" style="word-break:break-all;">下载CA证书并导入,可解决浏览器不安全提醒。<br/>Windows:<a href="/ssl/baota_root.pfx">baota_root.pfx</a>(密码为空),Mac/Linux:<a href="/ssl/baota_root.crt">baota_root.crt</a></div>
<form onsubmit="return makeSSL(this)" method="post" class="form" role="form">
<div class="form-group">
<label is-required="true" class="control-label">域名列表:</label>
<textarea class="form-control" name="domain_list" rows="6" placeholder="每行一个域名/IP,支持通配符" required></textarea>
</div>
<div class="form-group">
<label class="control-label">通用名称:</label>
<input type="text" name="common_name" value="" placeholder="留空则为域名列表第一个域名" class="form-control"/>
</div>
<div class="form-group">
<label is-required="true" class="control-label">有效天数:</label>
<input type="number" name="validity" value="3650" class="form-control" required/>
</div>
<div class="form-group text-center">
<input type="submit" name="submit" value="生成自签名证书" class="btn btn-success btn-block"/>
</div>
<div class="form-group row" id="result" style="display:none;">
<div class="col-md-6">
<label class="control-label">SSL证书:</label>
<textarea class="form-control" name="ssl_cert" rows="5" onclick="copy(this)" title="点击复制"></textarea>
</div>
<div class="col-md-6">
<label class="control-label">SSL证书私钥:</label>
<textarea class="form-control" name="ssl_key" rows="5" onclick="copy(this)" title="点击复制"></textarea>
</div>
</div>
</form>
{else}
<div class="alert alert-danger" role="alert">你还没有生成CA证书,无法生成SSL证书!</div>
<div class="alert alert-info" style="word-break:break-all;">执行以下命令,生成自签名CA证书。然后,可通过接口或当前页面生成SSL证书,用于面板访问。</div>
<div class="list-group-item" style="word-break:break-all;">cd {:app()->getRootPath()}app/script && chmod +x cacert.sh && ./cacert.sh</div><br/>
{/if}
</div>
</div>
<script src="{$cdnpublic}layer/3.5.1/layer.js"></script>
<script>
function makeSSL(obj){
var ii = layer.load(2, {shade:[0.1,'#fff']});
$.ajax({
type : 'POST',
url : '/admin/ssl',
data : $(obj).serialize(),
dataType : 'json',
success : function(data) {
layer.close(ii);
if(data.code == 0){
$("textarea[name='ssl_cert']").val(data.cert);
$("textarea[name='ssl_key']").val(data.key);
$("#result").show();
layer.msg('SSL证书生成成功', {icon:1, time:800});
}else{
layer.alert(data.msg, {icon: 2})
}
},
error:function(data){
layer.close(ii);
layer.msg('服务器错误');
}
});
return false;
}
function copy(obj){
if($(obj).val() == '') return;
$(obj).select();
document.execCommand("Copy");
layer.msg('复制成功', {icon:1, time:500});
}
</script>
{/block}

6
app/view/index/download.html

@ -193,10 +193,10 @@
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/3.6.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/layer/3.5.1/layer.js" type="text/javascript" charset="utf-8"></script>
<script src="{$cdnpublic}jquery/3.6.0/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<script src="{$cdnpublic}layer/3.5.1/layer.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/clipboard.js/1.7.1/clipboard.min.js"></script>
<script type="text/javascript" src="{$cdnpublic}clipboard.js/1.7.1/clipboard.min.js"></script>
<script type="text/javascript" src="/static/js/dx.js"></script> <script type="text/javascript" src="/static/js/dx.js"></script>
<script> <script>
$(function () { $(function () {

2
app/view/install/index.html

@ -217,7 +217,7 @@
</form> </form>
</div> </div>
</div> </div>
<script src="//lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.1.4/jquery.min.js"></script>
<script src="{$cdnpublic}jquery/2.1.4/jquery.min.js"></script>
<script> <script>
$(function () { $(function () {
$('form').on('submit', function (e) { $('form').on('submit', function (e) {

12
install.sql

@ -12,15 +12,15 @@ INSERT INTO `cloud_config` (`key`, `value`) VALUES
('bt_key', ''), ('bt_key', ''),
('whitelist', '0'), ('whitelist', '0'),
('download_page', '1'), ('download_page', '1'),
('new_version', '8.0.5'),
('new_version', '9.1.0'),
('update_msg', '暂无更新日志'), ('update_msg', '暂无更新日志'),
('update_date', '2024-01-12'),
('new_version_win', '7.9.0'),
('update_date', '2024-07-15'),
('new_version_win', '8.1.0'),
('update_msg_win', '暂无更新日志'), ('update_msg_win', '暂无更新日志'),
('update_date_win', '2023-07-20'),
('new_version_btm', '2.2.9'),
('update_date_win', '2024-07-17'),
('new_version_btm', '2.3.0'),
('update_msg_btm', '暂无更新日志'), ('update_msg_btm', '暂无更新日志'),
('update_date_btm', '2023-08-11'),
('update_date_btm', '2024-04-24'),
('updateall_type', '0'), ('updateall_type', '0'),
('syskey', 'UqP94LtI8eWAIgCP'); ('syskey', 'UqP94LtI8eWAIgCP');

3
route/app.php

@ -12,7 +12,7 @@ Route::post('/down/download_plugin', 'api/download_plugin');
Route::post('/down/download_plugin_main', 'api/download_plugin_main'); Route::post('/down/download_plugin_main', 'api/download_plugin_main');
Route::post('/panel/get_soft_list_status', 'api/return_success'); Route::post('/panel/get_soft_list_status', 'api/return_success');
Route::post('/panel/get_unbinding', 'api/return_success'); Route::post('/panel/get_unbinding', 'api/return_success');
Route::post('/bt_cert', 'api/return_error');
Route::post('/bt_cert', 'api/bt_cert');
Route::post('/Auth/GetAuthToken', 'api/get_auth_token'); Route::post('/Auth/GetAuthToken', 'api/get_auth_token');
Route::post('/Auth/GetBindCode', 'api/return_error'); Route::post('/Auth/GetBindCode', 'api/return_error');
Route::any('/bt_monitor/update_history', 'api/btm_update_history'); Route::any('/bt_monitor/update_history', 'api/btm_update_history');
@ -146,6 +146,7 @@ Route::group('admin', function () {
Route::get('/deplist', 'admin/deplist'); Route::get('/deplist', 'admin/deplist');
Route::get('/refresh_deplist', 'admin/refresh_deplist'); Route::get('/refresh_deplist', 'admin/refresh_deplist');
Route::get('/cleancache', 'admin/cleancache'); Route::get('/cleancache', 'admin/cleancache');
Route::any('/ssl', 'admin/ssl');
})->middleware(\app\middleware\CheckAdmin::class); })->middleware(\app\middleware\CheckAdmin::class);

Loading…
Cancel
Save