mirror of
https://github.com/cedar2025/Xboard.git
synced 2025-01-22 10:38:14 -05:00
Compare commits
10 Commits
686f8a93ca
...
2c4a3b520f
Author | SHA1 | Date | |
---|---|---|---|
|
2c4a3b520f | ||
|
94ecd10704 | ||
|
78370717df | ||
|
abe93bf5ff | ||
|
d7b88d7b5d | ||
|
bc16656371 | ||
|
e0e76a22ea | ||
|
7cf839488b | ||
|
c895de839a | ||
|
296a72331e |
@ -145,7 +145,6 @@ class XboardInstall extends Command
|
||||
}
|
||||
}
|
||||
$envConfig['APP_KEY'] = 'base64:' . base64_encode(Encrypter::generateKey('AES-256-CBC'));
|
||||
$envConfig['INSTALLED'] = true;
|
||||
$isReidsValid = false;
|
||||
while (!$isReidsValid) {
|
||||
// 判断是否为Docker环境
|
||||
@ -212,6 +211,8 @@ class XboardInstall extends Command
|
||||
|
||||
$defaultSecurePath = hash('crc32b', config('app.key'));
|
||||
$this->info("访问 http(s)://你的站点/{$defaultSecurePath} 进入管理面板,你可以在用户中心修改你的密码。");
|
||||
$envConfig['INSTALLED'] = true;
|
||||
$this->saveToEnv($envConfig);
|
||||
} catch (\Exception $e) {
|
||||
$this->error($e);
|
||||
}
|
||||
|
@ -30,8 +30,9 @@ class AppController extends Controller
|
||||
$proxies = [];
|
||||
|
||||
foreach ($servers as $item) {
|
||||
$protocol_settings = $item['protocol_settings'];
|
||||
if ($item['type'] === 'shadowsocks'
|
||||
&& in_array($item['cipher'], [
|
||||
&& in_array(data_get($protocol_settings, 'cipher'), [
|
||||
'aes-128-gcm',
|
||||
'aes-192-gcm',
|
||||
'aes-256-gcm',
|
||||
|
@ -166,7 +166,10 @@ class ClientController extends Controller
|
||||
|
||||
private function getFilterArray(?string $filter): ?array
|
||||
{
|
||||
return mb_strlen((string) $filter) > 20 ? null :
|
||||
if ($filter === null) {
|
||||
return null;
|
||||
}
|
||||
return mb_strlen($filter) > 20 ? null :
|
||||
explode('|', str_replace(['|', '|', ','], '|', $filter));
|
||||
}
|
||||
|
||||
|
@ -170,16 +170,17 @@ class Clash implements ProtocolInterface
|
||||
break;
|
||||
case 'ws':
|
||||
$array['network'] = 'ws';
|
||||
$array['ws-opts']['path'] = data_get($protocol_settings, 'network_settings.path', '/');
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) {
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$array['ws-opts']['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$array['ws-opts']['headers'] = ['Host' => $host];
|
||||
}
|
||||
break;
|
||||
case 'grpc':
|
||||
$array['network'] = 'grpc';
|
||||
$array['grpc-opts'] = [
|
||||
'grpc-service-name' => data_get($protocol_settings, 'network_settings.serviceName')
|
||||
];
|
||||
if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$array['grpc-opts']['grpc-service-name'] = $serviceName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $array;
|
||||
@ -206,16 +207,15 @@ class Clash implements ProtocolInterface
|
||||
break;
|
||||
case 'ws':
|
||||
$array['network'] = 'ws';
|
||||
$array['ws-opts']['path'] = data_get($protocol_settings, 'network_settings.path', '/');
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) {
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$array['ws-opts']['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$array['ws-opts']['headers'] = ['Host' => $host];
|
||||
}
|
||||
break;
|
||||
case 'grpc':
|
||||
$array['network'] = 'grpc';
|
||||
$array['grpc-opts'] = [
|
||||
'grpc-service-name' => data_get($protocol_settings, 'network_settings.serviceName')
|
||||
];
|
||||
if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$array['grpc-opts']['grpc-service-name'] = $serviceName;
|
||||
break;
|
||||
default:
|
||||
$array['network'] = 'tcp';
|
||||
|
@ -43,6 +43,7 @@ class ClashMeta implements ProtocolInterface
|
||||
$proxies = [];
|
||||
|
||||
foreach ($servers as $item) {
|
||||
$protocol_settings = $item['protocol_settings'];
|
||||
if ($item['type'] === 'shadowsocks') {
|
||||
array_push($proxy, self::buildShadowsocks($item['password'], $item));
|
||||
array_push($proxies, $item['name']);
|
||||
@ -55,7 +56,10 @@ class ClashMeta implements ProtocolInterface
|
||||
array_push($proxy, self::buildTrojan($user['uuid'], $item));
|
||||
array_push($proxies, $item['name']);
|
||||
}
|
||||
if ($item['type'] === 'vless') {
|
||||
if (
|
||||
$item['type'] === 'vless'
|
||||
&& in_array(data_get($protocol_settings, 'network'), ['tcp', 'ws', 'grpc', 'http', 'h2'])
|
||||
) {
|
||||
array_push($proxy, self::buildVless($user['uuid'], $item));
|
||||
array_push($proxies, $item['name']);
|
||||
}
|
||||
@ -167,16 +171,15 @@ class ClashMeta implements ProtocolInterface
|
||||
break;
|
||||
case 'ws':
|
||||
$array['network'] = 'ws';
|
||||
$array['ws-opts'] = [
|
||||
'path' => data_get($protocol_settings, 'network_settings.path'),
|
||||
'headers' => ['Host' => data_get($protocol_settings, 'network_settings.headers.Host', $server['host'])]
|
||||
];
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$array['ws-opts']['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$array['ws-opts']['headers'] = ['Host' => $host];
|
||||
break;
|
||||
case 'grpc':
|
||||
$array['network'] = 'grpc';
|
||||
$array['grpc-opts'] = [
|
||||
'grpc-service-name' => data_get($protocol_settings, 'network_settings.serviceName')
|
||||
];
|
||||
if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$array['grpc-opts']['grpc-service-name'] = $serviceName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -226,23 +229,15 @@ class ClashMeta implements ProtocolInterface
|
||||
switch (data_get($protocol_settings, 'network')) {
|
||||
case 'ws':
|
||||
$array['network'] = 'ws';
|
||||
$array['ws-opts']['path'] = data_get($protocol_settings, 'network_settings.path', '/');
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) {
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$array['ws-opts']['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$array['ws-opts']['headers'] = ['Host' => $host];
|
||||
}
|
||||
break;
|
||||
case 'grpc':
|
||||
$array['network'] = 'grpc';
|
||||
$array['grpc-opts'] = [
|
||||
'grpc-service-name' => data_get($protocol_settings, 'network_settings.serviceName')
|
||||
];
|
||||
break;
|
||||
case 'h2':
|
||||
$array['network'] = 'h2';
|
||||
$array['h2-opts'] = [
|
||||
'path' => data_get($protocol_settings, 'network_settings.path', '/'),
|
||||
'host' => data_get($protocol_settings, 'network_settings.host')
|
||||
];
|
||||
if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$array['grpc-opts']['grpc-service-name'] = $serviceName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -268,20 +263,23 @@ class ClashMeta implements ProtocolInterface
|
||||
}
|
||||
|
||||
switch (data_get($protocol_settings, 'network')) {
|
||||
case 'grpc':
|
||||
$array['network'] = 'grpc';
|
||||
$array['grpc-opts'] = [
|
||||
'grpc-service-name' => data_get($protocol_settings, 'network_settings.serviceName')
|
||||
];
|
||||
case 'tcp':
|
||||
$array['network'] = 'tcp';
|
||||
break;
|
||||
case 'ws':
|
||||
$array['network'] = 'ws';
|
||||
$array['ws-opts']['path'] = data_get($protocol_settings, 'network_settings.path', '/');
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) {
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$array['ws-opts']['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$array['ws-opts']['headers'] = ['Host' => $host];
|
||||
}
|
||||
break;
|
||||
case 'grpc':
|
||||
$array['network'] = 'grpc';
|
||||
if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$array['grpc-opts']['grpc-service-name'] = $serviceName;
|
||||
break;
|
||||
default:
|
||||
$array['network'] = 'tcp';
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -92,14 +92,15 @@ class General implements ProtocolInterface
|
||||
break;
|
||||
case 'ws':
|
||||
$config['type'] = 'ws';
|
||||
$config['path'] = data_get($protocol_settings, 'network_settings.path');
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) {
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$config['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$config['host'] = $host;
|
||||
}
|
||||
break;
|
||||
case 'grpc':
|
||||
$config['type'] = 'grpc';
|
||||
$config['path'] = data_get($protocol_settings, 'network_settings.serviceName');
|
||||
if ($path = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$config['path'] = $path;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -144,20 +145,23 @@ class General implements ProtocolInterface
|
||||
// 处理传输协议
|
||||
switch ($server['protocol_settings']['network']) {
|
||||
case 'ws':
|
||||
$config['path'] = data_get($protocol_settings, 'network_settings.path');
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host')) {
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$config['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$config['host'] = $host;
|
||||
}
|
||||
break;
|
||||
case 'grpc':
|
||||
$config['serviceName'] = data_get($protocol_settings, 'network_settings.serviceName');
|
||||
if ($path = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$config['path'] = $path;
|
||||
break;
|
||||
case 'kcp':
|
||||
$config['path'] = data_get($protocol_settings, 'network_settings.seed');
|
||||
if ($path = data_get($protocol_settings, 'network_settings.seed'))
|
||||
$config['path'] = $path;
|
||||
$config['type'] = data_get($protocol_settings, 'network_settings.header.type', 'none');
|
||||
break;
|
||||
case 'httpupgrade':
|
||||
$config['path'] = data_get($protocol_settings, 'network_settings.path');
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$config['path'] = $path;
|
||||
$config['host'] = data_get($protocol_settings, 'network_settings.host', $server['host']);
|
||||
break;
|
||||
case 'xhttp':
|
||||
@ -185,6 +189,23 @@ class General implements ProtocolInterface
|
||||
$array['peer'] = $serverName;
|
||||
$array['sni'] = $serverName;
|
||||
}
|
||||
switch ($server['protocol_settings']['network']) {
|
||||
case 'ws':
|
||||
$array['type'] = 'ws';
|
||||
if ($path = data_get($protocol_settings, 'network_settings.path'))
|
||||
$array['path'] = $path;
|
||||
if ($host = data_get($protocol_settings, 'network_settings.headers.Host'))
|
||||
$array['host'] = $host;
|
||||
break;
|
||||
case 'grpc':
|
||||
// Follow V2rayN family standards
|
||||
$array['type'] = 'grpc';
|
||||
if ($serviceName = data_get($protocol_settings, 'network_settings.serviceName'))
|
||||
$array['serviceName'] = $serviceName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$query = http_build_query($array);
|
||||
$uri = "trojan://{$password}@{$server['host']}:{$server['port']}?{$query}#{$name}";
|
||||
$uri .= "\r\n";
|
||||
|
@ -51,6 +51,7 @@ class SingBox implements ProtocolInterface
|
||||
$outbounds = $this->config['outbounds'];
|
||||
$proxies = [];
|
||||
foreach ($this->servers as $item) {
|
||||
$protocol_settings = $item['protocol_settings'];
|
||||
if ($item['type'] === 'shadowsocks') {
|
||||
$ssConfig = $this->buildShadowsocks($item['password'], $item);
|
||||
$proxies[] = $ssConfig;
|
||||
@ -63,7 +64,9 @@ class SingBox implements ProtocolInterface
|
||||
$vmessConfig = $this->buildVmess($this->user['uuid'], $item);
|
||||
$proxies[] = $vmessConfig;
|
||||
}
|
||||
if ($item['type'] === 'vless') {
|
||||
if ($item['type'] === 'vless'
|
||||
&& in_array(data_get($protocol_settings, 'network'), ['tcp', 'ws', 'grpc', 'http', 'quic', 'httpupgrade'])
|
||||
) {
|
||||
$vlessConfig = $this->buildVless($this->user['uuid'], $item);
|
||||
$proxies[] = $vlessConfig;
|
||||
}
|
||||
@ -213,13 +216,13 @@ class SingBox implements ProtocolInterface
|
||||
],
|
||||
'h2' => [
|
||||
'type' => 'http',
|
||||
'host' => data_get($protocol_settings, 'network_settings.host') ? [data_get($protocol_settings, 'network_settings.host')] : null,
|
||||
'host' => data_get($protocol_settings, 'network_settings.host'),
|
||||
'path' => data_get($protocol_settings, 'network_settings.path')
|
||||
],
|
||||
'httpupgrade' => [
|
||||
'type' => 'httpupgrade',
|
||||
'path' => data_get($protocol_settings, 'network_settings.path'),
|
||||
'host' => data_get($protocol_settings, 'network_settings.headers.Host', $server['host']),
|
||||
'host' => data_get($protocol_settings, 'network_settings.host', $server['host']),
|
||||
'headers' => data_get($protocol_settings, 'network_settings.headers')
|
||||
],
|
||||
default => null
|
||||
|
@ -59,10 +59,15 @@ class Stash implements ProtocolInterface
|
||||
array_push($proxy, self::buildVmess($user['uuid'], $item));
|
||||
array_push($proxies, $item['name']);
|
||||
}
|
||||
// if ($item['type'] === 'vless') {
|
||||
// array_push($proxy, self::buildVless($user['uuid'], $item));
|
||||
// array_push($proxies, $item['name']);
|
||||
// }
|
||||
if (
|
||||
$item['type'] === 'vless'
|
||||
&& in_array(data_get($item['protocol_settings'], 'network'), ['tcp', 'ws', 'grpc', 'http', 'h2'])
|
||||
&& in_array(data_get($item['protocol_settings'], 'tls'), [1, 0])
|
||||
&& in_array(data_get($item['protocol_settings'], 'flow'), ['xtls-rprx-origin', 'xtls-rprx-direct', 'xtls-rprx-splice'])
|
||||
) {
|
||||
array_push($proxy, self::buildVless($user['uuid'], $item));
|
||||
array_push($proxies, $item['name']);
|
||||
}
|
||||
if ($item['type'] === 'hysteria') {
|
||||
array_push($proxy, self::buildHysteria($user['uuid'], $item));
|
||||
array_push($proxies, $item['name']);
|
||||
@ -192,15 +197,6 @@ class Stash implements ProtocolInterface
|
||||
$array['servername'] = $serverName;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
$array['tls'] = true;
|
||||
$array['skip-cert-verify'] = data_get($protocol_settings, 'reality_settings.allow_insecure');
|
||||
$array['servername'] = data_get($protocol_settings, 'reality_settings.server_name');
|
||||
$array['reality-opts'] = [
|
||||
'public-key' => data_get($protocol_settings, 'reality_settings.public_key'),
|
||||
'short-id' => data_get($protocol_settings, 'reality_settings.short_id')
|
||||
];
|
||||
break;
|
||||
}
|
||||
|
||||
switch (data_get($protocol_settings, 'network')) {
|
||||
@ -219,6 +215,11 @@ class Stash implements ProtocolInterface
|
||||
$array['network'] = 'grpc';
|
||||
$array['grpc-opts']['grpc-service-name'] = data_get($protocol_settings, 'network_settings.serviceName');
|
||||
break;
|
||||
// case 'h2':
|
||||
// $array['network'] = 'h2';
|
||||
// $array['h2-opts']['host'] = data_get($protocol_settings, 'network_settings.host');
|
||||
// $array['h2-opts']['path'] = data_get($protocol_settings, 'network_settings.path');
|
||||
// break;
|
||||
}
|
||||
|
||||
return $array;
|
||||
|
@ -42,27 +42,19 @@ class Surge implements ProtocolInterface
|
||||
'chacha20-ietf-poly1305'
|
||||
])
|
||||
) {
|
||||
// [Proxy]
|
||||
$proxies .= self::buildShadowsocks($item['password'], $item);
|
||||
// [Proxy Group]
|
||||
$proxyGroup .= $item['name'] . ', ';
|
||||
}
|
||||
if ($item['type'] === 'vmess') {
|
||||
// [Proxy]
|
||||
$proxies .= self::buildVmess($user['uuid'], $item);
|
||||
// [Proxy Group]
|
||||
$proxyGroup .= $item['name'] . ', ';
|
||||
}
|
||||
if ($item['type'] === 'trojan') {
|
||||
// [Proxy]
|
||||
$proxies .= self::buildTrojan($user['uuid'], $item);
|
||||
// [Proxy Group]
|
||||
$proxyGroup .= $item['name'] . ', ';
|
||||
}
|
||||
if ($item['type'] === 'hysteria') {
|
||||
// [Proxy]
|
||||
$proxies .= self::buildHysteria($user['uuid'], $item);
|
||||
// [Proxy Group]
|
||||
$proxyGroup .= $item['name'] . ', ';
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ return new class extends Migration {
|
||||
->where('id', $plan->id)
|
||||
->update([
|
||||
'prices' => json_encode($prices),
|
||||
'sell' => $plan->show
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('v2_order', function (Blueprint $table) {
|
||||
$table->index('updated_at');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('v2_order', function (Blueprint $table) {
|
||||
$table->dropIndex(['updated_at']);
|
||||
});
|
||||
}
|
||||
};
|
8
public/assets/admin/assets/index.js
vendored
8
public/assets/admin/assets/index.js
vendored
File diff suppressed because one or more lines are too long
13
public/assets/admin/locales/en-US.js
vendored
13
public/assets/admin/locales/en-US.js
vendored
@ -780,6 +780,19 @@ window.XBOARD_TRANSLATIONS['en-US'] = {
|
||||
"success": "Copied successfully",
|
||||
"error": "Copy failed",
|
||||
"errorLog": "Error copying to clipboard"
|
||||
},
|
||||
"table": {
|
||||
"noData": "No data available",
|
||||
"pagination": {
|
||||
"selected": "{{selected}} of {{total}} items selected",
|
||||
"itemsPerPage": "Per page",
|
||||
"page": "Page",
|
||||
"pageOf": "of {{total}} pages",
|
||||
"firstPage": "Go to first page",
|
||||
"previousPage": "Previous page",
|
||||
"nextPage": "Next page",
|
||||
"lastPage": "Go to last page"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
|
15
public/assets/admin/locales/ko-KR.js
vendored
15
public/assets/admin/locales/ko-KR.js
vendored
@ -481,7 +481,7 @@ window.XBOARD_TRANSLATIONS['ko-KR'] = {
|
||||
"delete": "삭제",
|
||||
"edit": "편집",
|
||||
"view": "보기",
|
||||
"toggleNavigation": "내비게이션 전환",
|
||||
"toggleNavigation": "네비게이션 전환",
|
||||
"toggleSidebar": "사이드바 전환",
|
||||
"search": "검색...",
|
||||
"theme": {
|
||||
@ -497,6 +497,19 @@ window.XBOARD_TRANSLATIONS['ko-KR'] = {
|
||||
"success": "복사 성공",
|
||||
"error": "복사 실패",
|
||||
"errorLog": "클립보드에 복사하는 중 오류 발생"
|
||||
},
|
||||
"table": {
|
||||
"noData": "데이터가 없습니다",
|
||||
"pagination": {
|
||||
"selected": "{{selected}}개 선택됨, 총 {{total}}개",
|
||||
"itemsPerPage": "페이지당 표시",
|
||||
"page": "페이지",
|
||||
"pageOf": "/ {{total}} 페이지",
|
||||
"firstPage": "첫 페이지로 이동",
|
||||
"previousPage": "이전 페이지",
|
||||
"nextPage": "다음 페이지",
|
||||
"lastPage": "마지막 페이지로 이동"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
|
13
public/assets/admin/locales/zh-CN.js
vendored
13
public/assets/admin/locales/zh-CN.js
vendored
@ -784,6 +784,19 @@ window.XBOARD_TRANSLATIONS['zh-CN'] = {
|
||||
"success": "复制成功",
|
||||
"error": "复制失败",
|
||||
"errorLog": "复制到剪贴板时出错"
|
||||
},
|
||||
"table": {
|
||||
"noData": "暂无数据",
|
||||
"pagination": {
|
||||
"selected": "已选择 {{selected}} 项,共 {{total}} 项",
|
||||
"itemsPerPage": "每页显示",
|
||||
"page": "第",
|
||||
"pageOf": "页,共 {{total}} 页",
|
||||
"firstPage": "跳转到第一页",
|
||||
"previousPage": "上一页",
|
||||
"nextPage": "下一页",
|
||||
"lastPage": "跳转到最后一页"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dashboard": {
|
||||
|
Loading…
Reference in New Issue
Block a user