Explorar o código

Merge pull request #2161 from sspanel-uim/dev

Dev 20230911
M1Screw %!s(int64=2) %!d(string=hai) anos
pai
achega
96e9090d9d

+ 2 - 2
composer.json

@@ -26,7 +26,7 @@
         "league/omnipay": "^3.2.1",
         "mailgun/mailgun-php": "^3",
         "nikolaposa/rate-limit": "^3.0",
-        "openai-php/client": "^0.6.1",
+        "openai-php/client": "^0.7",
         "ozdemir/datatables": "^2",
         "phpmailer/phpmailer": "^6",
         "postal/postal": "^2",
@@ -37,7 +37,7 @@
         "slim/slim": "^4.11",
         "smarty/smarty": "^4",
         "srmklive/paypal": "~3.0",
-        "stripe/stripe-php": "^10",
+        "stripe/stripe-php": "^12",
         "symfony/yaml": "^6",
         "tronovav/geoip2-update": "^2.1",
         "vectorface/googleauthenticator": "^3.0",

+ 68 - 67
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "2fcedaff11e3ab25db456faff60ebd95",
+    "content-hash": "02453d2715cf86e568a5235e9dadb9f6",
     "packages": [
         {
             "name": "anankke/omnipay-alipay",
@@ -123,16 +123,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.280.2",
+            "version": "3.281.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "d68b83b3bc39b70bf33e9b8b5166facbe3e4fe9b"
+                "reference": "a3cfb20dbfb11117b7174b2594fc597745252e0c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/d68b83b3bc39b70bf33e9b8b5166facbe3e4fe9b",
-                "reference": "d68b83b3bc39b70bf33e9b8b5166facbe3e4fe9b",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a3cfb20dbfb11117b7174b2594fc597745252e0c",
+                "reference": "a3cfb20dbfb11117b7174b2594fc597745252e0c",
                 "shasum": ""
             },
             "require": {
@@ -212,9 +212,9 @@
             "support": {
                 "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80",
                 "issues": "https://github.com/aws/aws-sdk-php/issues",
-                "source": "https://github.com/aws/aws-sdk-php/tree/3.280.2"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.281.3"
             },
-            "time": "2023-09-01T18:06:10+00:00"
+            "time": "2023-09-08T18:06:26+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -1237,7 +1237,7 @@
         },
         {
             "name": "illuminate/collections",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/collections.git",
@@ -1292,7 +1292,7 @@
         },
         {
             "name": "illuminate/conditionable",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/conditionable.git",
@@ -1338,7 +1338,7 @@
         },
         {
             "name": "illuminate/container",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/container.git",
@@ -1389,7 +1389,7 @@
         },
         {
             "name": "illuminate/contracts",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/contracts.git",
@@ -1437,7 +1437,7 @@
         },
         {
             "name": "illuminate/database",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/database.git",
@@ -1506,7 +1506,7 @@
         },
         {
             "name": "illuminate/macroable",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/macroable.git",
@@ -1552,7 +1552,7 @@
         },
         {
             "name": "illuminate/pagination",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/pagination.git",
@@ -1602,16 +1602,16 @@
         },
         {
             "name": "illuminate/support",
-            "version": "v10.21.1",
+            "version": "v10.22.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/support.git",
-                "reference": "88cf94abf6eca3d39cbaa63b588e5ba44a30f4f1"
+                "reference": "7ff0d0d70a7b8275816398a88870e062a01ebb8b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/support/zipball/88cf94abf6eca3d39cbaa63b588e5ba44a30f4f1",
-                "reference": "88cf94abf6eca3d39cbaa63b588e5ba44a30f4f1",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/7ff0d0d70a7b8275816398a88870e062a01ebb8b",
+                "reference": "7ff0d0d70a7b8275816398a88870e062a01ebb8b",
                 "shasum": ""
             },
             "require": {
@@ -1669,7 +1669,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2023-09-01T14:20:02+00:00"
+            "time": "2023-09-04T15:58:19+00:00"
         },
         {
             "name": "irazasyed/telegram-bot-sdk",
@@ -2402,16 +2402,16 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "2.69.0",
+            "version": "2.70.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c"
+                "reference": "d3298b38ea8612e5f77d38d1a99438e42f70341d"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4308217830e4ca445583a37d1bf4aff4153fa81c",
-                "reference": "4308217830e4ca445583a37d1bf4aff4153fa81c",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d3298b38ea8612e5f77d38d1a99438e42f70341d",
+                "reference": "d3298b38ea8612e5f77d38d1a99438e42f70341d",
                 "shasum": ""
             },
             "require": {
@@ -2504,7 +2504,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-08-03T09:00:52+00:00"
+            "time": "2023-09-07T16:43:50+00:00"
         },
         {
             "name": "nikic/fast-route",
@@ -2718,16 +2718,16 @@
         },
         {
             "name": "openai-php/client",
-            "version": "v0.6.4",
+            "version": "v0.7.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/openai-php/client.git",
-                "reference": "6e0738a3f052fb0d27bd57136fff47db96248f65"
+                "reference": "86ffa2abe167d6192f01d4df90f83a97c8533303"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/openai-php/client/zipball/6e0738a3f052fb0d27bd57136fff47db96248f65",
-                "reference": "6e0738a3f052fb0d27bd57136fff47db96248f65",
+                "url": "https://api.github.com/repos/openai-php/client/zipball/86ffa2abe167d6192f01d4df90f83a97c8533303",
+                "reference": "86ffa2abe167d6192f01d4df90f83a97c8533303",
                 "shasum": ""
             },
             "require": {
@@ -2744,7 +2744,7 @@
                 "guzzlehttp/psr7": "^2.5.0",
                 "laravel/pint": "^1.10.3",
                 "nunomaduro/collision": "^7.7.0",
-                "pestphp/pest": "dev-develop as 2.6.2",
+                "pestphp/pest": "^2.16.0",
                 "pestphp/pest-plugin-arch": "^2.2.1",
                 "pestphp/pest-plugin-mock": "^2.0.0",
                 "pestphp/pest-plugin-type-coverage": "^2.0.0",
@@ -2790,7 +2790,7 @@
             ],
             "support": {
                 "issues": "https://github.com/openai-php/client/issues",
-                "source": "https://github.com/openai-php/client/tree/v0.6.4"
+                "source": "https://github.com/openai-php/client/tree/v0.7.3"
             },
             "funding": [
                 {
@@ -2806,7 +2806,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-07-18T22:59:43+00:00"
+            "time": "2023-09-08T08:48:59+00:00"
         },
         {
             "name": "ozdemir/datatables",
@@ -4789,16 +4789,16 @@
         },
         {
             "name": "srmklive/paypal",
-            "version": "3.0.22",
+            "version": "3.0.24",
             "source": {
                 "type": "git",
                 "url": "https://github.com/srmklive/laravel-paypal.git",
-                "reference": "ceae395de0d6c4b7c5a415e515f1baee6359379d"
+                "reference": "f9b3e6162f4b7ded0f53737101af5cf1ea9a02a2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/srmklive/laravel-paypal/zipball/ceae395de0d6c4b7c5a415e515f1baee6359379d",
-                "reference": "ceae395de0d6c4b7c5a415e515f1baee6359379d",
+                "url": "https://api.github.com/repos/srmklive/laravel-paypal/zipball/f9b3e6162f4b7ded0f53737101af5cf1ea9a02a2",
+                "reference": "f9b3e6162f4b7ded0f53737101af5cf1ea9a02a2",
                 "shasum": ""
             },
             "require": {
@@ -4849,9 +4849,9 @@
             ],
             "support": {
                 "issues": "https://github.com/srmklive/laravel-paypal/issues",
-                "source": "https://github.com/srmklive/laravel-paypal/tree/3.0.22"
+                "source": "https://github.com/srmklive/laravel-paypal/tree/3.0.24"
             },
-            "time": "2023-08-22T20:11:26+00:00"
+            "time": "2023-09-06T22:26:06+00:00"
         },
         {
             "name": "starkbank/ecdsa",
@@ -4898,16 +4898,16 @@
         },
         {
             "name": "stripe/stripe-php",
-            "version": "v10.21.0",
+            "version": "v12.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/stripe/stripe-php.git",
-                "reference": "b4ab319731958077227fad1874a3671458c5d593"
+                "reference": "07829f2102362b0bfe0b680dab801e00cc4dce89"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/b4ab319731958077227fad1874a3671458c5d593",
-                "reference": "b4ab319731958077227fad1874a3671458c5d593",
+                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/07829f2102362b0bfe0b680dab801e00cc4dce89",
+                "reference": "07829f2102362b0bfe0b680dab801e00cc4dce89",
                 "shasum": ""
             },
             "require": {
@@ -4953,9 +4953,9 @@
             ],
             "support": {
                 "issues": "https://github.com/stripe/stripe-php/issues",
-                "source": "https://github.com/stripe/stripe-php/tree/v10.21.0"
+                "source": "https://github.com/stripe/stripe-php/tree/v12.2.0"
             },
-            "time": "2023-08-11T00:23:24+00:00"
+            "time": "2023-09-07T18:03:22+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -7119,16 +7119,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v3.25.1",
+            "version": "v3.26.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
-                "reference": "8e21d69801de6b5ecb0dbe0bcdf967b335b1260b"
+                "reference": "d023ba6684055f6ea1da1352d8a02baca0426983"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/8e21d69801de6b5ecb0dbe0bcdf967b335b1260b",
-                "reference": "8e21d69801de6b5ecb0dbe0bcdf967b335b1260b",
+                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/d023ba6684055f6ea1da1352d8a02baca0426983",
+                "reference": "d023ba6684055f6ea1da1352d8a02baca0426983",
                 "shasum": ""
             },
             "require": {
@@ -7202,7 +7202,7 @@
             ],
             "support": {
                 "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
-                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.25.1"
+                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.26.1"
             },
             "funding": [
                 {
@@ -7210,7 +7210,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-09-04T01:22:52+00:00"
+            "time": "2023-09-08T19:09:07+00:00"
         },
         {
             "name": "justinrainbow/json-schema",
@@ -7755,16 +7755,16 @@
         },
         {
             "name": "phpstan/phpdoc-parser",
-            "version": "1.23.1",
+            "version": "1.24.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpstan/phpdoc-parser.git",
-                "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26"
+                "reference": "3510b0a6274cc42f7219367cb3abfc123ffa09d6"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/846ae76eef31c6d7790fac9bc399ecee45160b26",
-                "reference": "846ae76eef31c6d7790fac9bc399ecee45160b26",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/3510b0a6274cc42f7219367cb3abfc123ffa09d6",
+                "reference": "3510b0a6274cc42f7219367cb3abfc123ffa09d6",
                 "shasum": ""
             },
             "require": {
@@ -7796,9 +7796,9 @@
             "description": "PHPDoc parser with support for nullable, intersection and generic types",
             "support": {
                 "issues": "https://github.com/phpstan/phpdoc-parser/issues",
-                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.23.1"
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.0"
             },
-            "time": "2023-08-03T16:32:59+00:00"
+            "time": "2023-09-07T20:46:32+00:00"
         },
         {
             "name": "phpunit/php-code-coverage",
@@ -8123,16 +8123,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "10.3.2",
+            "version": "10.3.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1"
+                "reference": "241ed4dd0db1c096984e62d414c4e1ac8d5dbff4"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0dafb1175c366dd274eaa9a625e914451506bcd1",
-                "reference": "0dafb1175c366dd274eaa9a625e914451506bcd1",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/241ed4dd0db1c096984e62d414c4e1ac8d5dbff4",
+                "reference": "241ed4dd0db1c096984e62d414c4e1ac8d5dbff4",
                 "shasum": ""
             },
             "require": {
@@ -8204,7 +8204,7 @@
             "support": {
                 "issues": "https://github.com/sebastianbergmann/phpunit/issues",
                 "security": "https://github.com/sebastianbergmann/phpunit/security/policy",
-                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.2"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.3.3"
             },
             "funding": [
                 {
@@ -8220,7 +8220,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2023-08-15T05:34:23+00:00"
+            "time": "2023-09-05T04:34:51+00:00"
         },
         {
             "name": "psr/cache",
@@ -8706,16 +8706,16 @@
         },
         {
             "name": "sebastian/exporter",
-            "version": "5.0.0",
+            "version": "5.0.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/exporter.git",
-                "reference": "f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0"
+                "reference": "32ff03d078fed1279c4ec9a407d08c5e9febb480"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0",
-                "reference": "f3ec4bf931c0b31e5b413f5b4fc970a7d03338c0",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/32ff03d078fed1279c4ec9a407d08c5e9febb480",
+                "reference": "32ff03d078fed1279c4ec9a407d08c5e9febb480",
                 "shasum": ""
             },
             "require": {
@@ -8771,7 +8771,8 @@
             ],
             "support": {
                 "issues": "https://github.com/sebastianbergmann/exporter/issues",
-                "source": "https://github.com/sebastianbergmann/exporter/tree/5.0.0"
+                "security": "https://github.com/sebastianbergmann/exporter/security/policy",
+                "source": "https://github.com/sebastianbergmann/exporter/tree/5.0.1"
             },
             "funding": [
                 {
@@ -8779,7 +8780,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-02-03T07:06:49+00:00"
+            "time": "2023-09-08T04:46:58+00:00"
         },
         {
             "name": "sebastian/global-state",

+ 31 - 34
config/.config.example.php

@@ -7,8 +7,13 @@ $_ENV['salt']       = '';                             //bcrypt/argon2i/argon2id
 
 $_ENV['debug']      = false;                          //debug模式开关,生产环境请保持为false
 $_ENV['appName']    = 'SSPanel-UIM';                  //站点名称
-$_ENV['baseUrl']    = 'https://example.com';          //站点地址
-$_ENV['muKey']      = 'ChangeMe';                     //WebAPI密钥,用于节点服务端与面板通信,请务必修改此key为随机字符串
+$_ENV['baseUrl']    = 'https://example.com';          //站点地址,必须以https://开头,不要以/结尾
+
+// WebAPI
+$_ENV['webAPI']      = true;               //是否开启WebAPI功能
+$_ENV['webAPIUrl']   = $_ENV['baseUrl'];   //WebAPI地址,如需和站点名称相同,请不要修改
+$_ENV['muKey']       = 'ChangeMe';         //WebAPI密钥,用于节点服务端与面板通信,请务必修改此key为随机字符串
+$_ENV['checkNodeIp'] = true;               //是否webapi验证节点ip
 
 //数据库设置-------------------------------------------------------------------------------------------
 // db_host|db_socket 二选一,若设置 db_socket 则 db_host 会被忽略,不用请留空。若数据库在本机上推荐用 db_socket。
@@ -62,11 +67,11 @@ $_ENV['notify_limit_mode']          = false;         //false为关闭,per为
 $_ENV['notify_limit_value']         = 500;           //当上一项为per时,此处填写百分比;当上一项为mb时,此处填写流量
 
 //日志设置---------------------------------------------------------------------------------------
-$_ENV['trafficLog']               = false;                          //是否记录用户每小时使用流量
-$_ENV['trafficLog_keep_days']     = 7;                             //每小时使用流量记录保留天数
+$_ENV['trafficLog']               = false;                       //是否记录用户每小时使用流量
+$_ENV['trafficLog_keep_days']     = 7;                           //每小时使用流量记录保留天数
 
-$_ENV['subscribeLog']               = false;                        //是否记录用户订阅日志
-$_ENV['subscribeLog_keep_days']     = 7;                            //订阅记录保留天数
+$_ENV['subscribeLog']             = false;                       //是否记录用户订阅日志
+$_ENV['subscribeLog_keep_days']   = 7;                           //订阅记录保留天数
 
 //订阅设置---------------------------------------------------------------------------------------
 $_ENV['Subscribe']                  = true;                         //本站是否提供订阅功能
@@ -76,8 +81,8 @@ $_ENV['sub_token_len']              = 16;                           //订阅toke
 //审计自动封禁设置--------------------------------------------------------------------------------------------
 $_ENV['auto_detect_ban_allow_admin'] = true;        // 管理员不受审计限制
 $_ENV['auto_detect_ban_allow_users'] = [];          // 审计封禁的例外用户 ID
-$_ENV['auto_detect_ban_number']      = 30;             // 每次执行封禁所需的触发次数
-$_ENV['auto_detect_ban_time']        = 60;             // 每次封禁的时长 (分钟)
+$_ENV['auto_detect_ban_number']      = 30;          // 每次执行封禁所需的触发次数
+$_ENV['auto_detect_ban_time']        = 60;          // 每次封禁的时长 (分钟)
 
 //节点检测-----------------------------------------------------------------------------------------------
 #GFW检测
@@ -85,43 +90,35 @@ $_ENV['detect_gfw_port']     = 443;
 $_ENV['detect_gfw_url']      = 'http://example.com:8080/tcping?ip={ip}&port={port}'; //检测节点是否被gfw墙了的API的URL
 
 #离线检测
-$_ENV['enable_detect_offline'] = true;
-
-// 主站是否提供 WebAPI
-$_ENV['WebAPI']     = true;
-
-$_ENV['enable_login_bind_ip']   = false;        //是否将登陆线程和IP绑定
-$_ENV['rememberMeDuration']     = 7;           //登录时记住账号时长天数
-
-$_ENV['timeZone']               = 'Asia/Taipei';         //需使用 PHP 兼容的时区格式
-$_ENV['theme']                  = 'tabler';              //默认主题
-$_ENV['jump_delay']             = 1200;                  //跳转延时,单位ms,不建议太长
-
-$_ENV['checkNodeIp']            = true;                 //是否webapi验证节点ip
-$_ENV['keep_connect']           = false;               // 流量耗尽用户限速至 1Mbps
+$_ENV['enable_detect_offline']  = true;
 
-#是否夹带统计代码,自己在 resources/views/{主题名} 下创建一个 analytics.tpl ,如果有必要就用 literal 界定符
-$_ENV['enable_analytics_code']  = false;
+$_ENV['enable_login_bind_ip']   = false;            //是否将登陆线程和IP绑定
+$_ENV['rememberMeDuration']     = 7;                //登录时记住账号时长天数
+$_ENV['timeZone']               = 'Asia/Taipei';    //需使用 PHP 兼容的时区格式
+$_ENV['theme']                  = 'tabler';         //默认主题
+$_ENV['jump_delay']             = 1200;             //跳转延时,单位ms,不建议太长
+$_ENV['keep_connect']           = false;            // 流量耗尽用户限速至 1Mbps
 
-$_ENV['jsdelivr_url'] = 'fastly.jsdelivr.net'; // cdn.jsdelivr.net / fastly.jsdelivr.net / gcore.jsdelivr.net / testingcf.jsdelivr.net
+// cdn.jsdelivr.net / fastly.jsdelivr.net / gcore.jsdelivr.net / testingcf.jsdelivr.net
+$_ENV['jsdelivr_url'] = 'fastly.jsdelivr.net';
 
 // https://sentry.io for production debugging
 $_ENV['sentry_dsn'] = '';
 
 // Maxmind GeoIP2 database
 $_ENV['maxmind_license_key'] = '';
-$_ENV['geoip_locale'] = 'en';
+$_ENV['geoip_locale']        = 'en';
 
 // Large language model powered ticket reply and more
 $_ENV['llm_backend'] = 'openai'; // openai/palm/huggingface
 // OpenAI ChatGPT
 $_ENV['openai_api_key'] = '';
-$_ENV['openai_model'] = 'gpt-3.5-turbo-16k';
+$_ENV['openai_model']   = 'gpt-3.5-turbo-16k';
 // Google PaLM API
-$_ENV['palm_api_key'] = '';
+$_ENV['palm_api_key']    = '';
 $_ENV['palm_text_model'] = 'text-bison-001';
 // Hugging Face Inference API
-$_ENV['huggingface_api_key'] = '';
+$_ENV['huggingface_api_key']      = '';
 $_ENV['huggingface_endpoint_url'] = '';
 
 // ClientDownload 命令解决 API 访问频率高而被限制使用的 Github access token
@@ -134,9 +131,9 @@ $_ENV['cloudflare_key']         = '';            //Cloudflare API Key
 $_ENV['cloudflare_name']        = '';            //域名
 
 // use Cloudflare R2 for clients download
-$_ENV['enable_r2_client_download'] = false;
-$_ENV['r2_bucket_name'] = '';
-$_ENV['r2_account_id'] = '';
-$_ENV['r2_access_key_id'] = '';
-$_ENV['r2_access_key_secret'] = '';
+$_ENV['enable_r2_client_download']  = false;
+$_ENV['r2_bucket_name']             = '';
+$_ENV['r2_account_id']              = '';
+$_ENV['r2_access_key_id']           = '';
+$_ENV['r2_access_key_secret']       = '';
 $_ENV['r2_client_download_timeout'] = 10;

+ 3 - 0
src/Controllers/Admin/DocsController.php

@@ -9,6 +9,7 @@ use App\Models\Docs;
 use App\Services\LLM;
 use App\Utils\Tools;
 use Exception;
+use GuzzleHttp\Exception\GuzzleException;
 use Psr\Http\Message\ResponseInterface;
 use Slim\Http\Response;
 use Slim\Http\ServerRequest;
@@ -88,6 +89,8 @@ final class DocsController extends BaseController
 
     /**
      * 使用LLM生成文档
+     *
+     * @throws GuzzleException
      */
     public function generate(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     {

+ 8 - 0
src/Controllers/Admin/ProductController.php

@@ -83,6 +83,14 @@ final class ProductController extends BaseController
         $content = json_decode($product->content);
         $limit = json_decode($product->limit);
 
+        $content->time = $content->time ?? 0;
+        $content->class = $content->class ?? 0;
+        $content->class_time = $content->class_time ?? 0;
+        $content->bandwidth = $content->bandwidth ?? 0;
+        $content->node_group = $content->node_group ?? 0;
+        $content->speed_limit = $content->speed_limit ?? 0;
+        $content->ip_limit = $content->ip_limit ?? 0;
+
         return $response->write(
             $this->view()
                 ->assign('product', $product)

+ 3 - 2
src/Controllers/CallbackController.php

@@ -6,6 +6,7 @@ namespace App\Controllers;
 
 use App\Models\Setting;
 use App\Services\Bot\Telegram\Process;
+use GuzzleHttp\Exception\GuzzleException;
 use MaxMind\Db\Reader\InvalidDatabaseException;
 use Psr\Http\Message\ResponseInterface;
 use Slim\Http\Response;
@@ -21,7 +22,7 @@ final class CallbackController extends BaseController
     /**
      * @throws InvalidDatabaseException
      * @throws SmartyException
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
     public function index(ServerRequest $request, Response $response, array $args): ResponseInterface
     {
@@ -33,7 +34,7 @@ final class CallbackController extends BaseController
 
     /**
      * @throws TelegramSDKException
-     * @throws InvalidDatabaseException
+     * @throws InvalidDatabaseException|GuzzleException
      */
     public function telegram(ServerRequest $request, Response $response, array $args): ResponseInterface
     {

+ 2 - 0
src/Controllers/OAuthController.php

@@ -97,6 +97,7 @@ final class OAuthController extends BaseController
         $code_response = $client->post($slack_api_url, [
             'headers' => $code_headers,
             'form_params' => $code_body,
+            'timeout' => 3,
         ]);
 
         if (! json_decode($code_response->getBody()->__toString())->ok) {
@@ -161,6 +162,7 @@ final class OAuthController extends BaseController
         $code_response = $client->post($discord_api_url, [
             'headers' => $code_headers,
             'form_params' => $code_body,
+            'timeout' => 3,
         ]);
 
         if ($code_response->getStatusCode() !== 200) {

+ 1 - 0
src/Controllers/SubController.php

@@ -54,6 +54,7 @@ final class SubController extends BaseController
 
         $user = $link->user();
         $sub_info = Subscribe::getContent($user, $subtype);
+
         $content_type = match ($subtype) {
             'clash' => 'application/yaml',
             default => 'application/json',

+ 4 - 1
src/Middleware/NodeToken.php

@@ -42,7 +42,10 @@ final class NodeToken implements MiddlewareInterface
             ]);
         }
 
-        if (! $_ENV['WebAPI'] || $key !== $_ENV['muKey']) {
+        if (! $_ENV['webAPI'] ||
+            $key !== $_ENV['muKey'] ||
+            'https://' . $request->getHeaderLine('Host') !== $_ENV['webAPIUrl']
+        ) {
             return AppFactory::determineResponseFactory()->createResponse(401)->withJson([
                 'ret' => 0,
                 'data' => 'Invalid request.',

+ 0 - 0
resources/views/tabler/analytics.tpl → src/Services/Bot/Discord/.gitkeep


+ 116 - 53
src/Services/Bot/Telegram/Callback.php

@@ -13,14 +13,21 @@ use App\Models\Setting;
 use App\Models\SubscribeLog;
 use App\Services\Config;
 use App\Utils\Tools;
+use GuzzleHttp\Exception\GuzzleException;
+use Illuminate\Support\Collection;
 use MaxMind\Db\Reader\InvalidDatabaseException;
 use Telegram\Bot\Api;
 use Telegram\Bot\Exceptions\TelegramSDKException;
-use Telegram\Bot\Objects\CallbackQuery;
+use function array_chunk;
+use function array_merge;
+use function end;
+use function explode;
+use function implode;
 use function in_array;
 use function is_null;
 use function json_encode;
 use function time;
+use const PHP_EOL;
 
 final class Callback
 {
@@ -42,7 +49,7 @@ final class Callback
     /**
      * 回调
      */
-    private CallbackQuery $callback;
+    private Collection $callback;
 
     /**
      * 回调数据内容
@@ -65,21 +72,20 @@ final class Callback
     private bool $allow_edit_message;
 
     /**
-     * @param Api $bot
-     * @param CallbackQuery $callback
-     *
      * @throws InvalidDatabaseException
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
-    public function __construct(Api $bot, CallbackQuery $callback)
+    public function __construct(Api $bot, Collection $callback)
     {
         $this->bot = $bot;
+
         $this->trigger_user = [
             'id' => $callback->getFrom()->getId(),
             'name' => $callback->getFrom()->getFirstName() . ' Callback.php' . $callback->getFrom()->getLastName(),
             'username' => $callback->getFrom()->getUsername(),
         ];
-        $this->user = Tool::getUser($this->trigger_user['id']);
+
+        $this->user = Message::getUser($this->trigger_user['id']);
         $this->chat_id = $callback->getMessage()->getChat()->getId();
         $this->callback = $callback;
         $this->message_id = $callback->getMessage()->getMessageId();
@@ -103,6 +109,7 @@ final class Callback
      * @param array $send_message
      *
      * @throws TelegramSDKException
+     * @throws GuzzleException
      */
     public function replyWithMessage(array $send_message): void
     {
@@ -115,7 +122,7 @@ final class Callback
         );
 
         if ($this->allow_edit_message) {
-            Tool::sendPost('editMessageText', $send_message);
+            Message::sendPost('editMessageText', $send_message);
         } else {
             $this->bot->sendMessage($send_message);
         }
@@ -132,6 +139,8 @@ final class Callback
      * </code>
      *
      * @param array $send_message
+     *
+     * @throws GuzzleException
      */
     public function answerCallbackQuery(array $send_message): void
     {
@@ -142,13 +151,15 @@ final class Callback
             ],
             $send_message
         );
-        Tool::sendPost('answerCallbackQuery', $send_message);
+
+        Message::sendPost('answerCallbackQuery', $send_message);
     }
 
     public static function getUserIndexKeyboard($user): array
     {
         $checkin = (! $user->isAbleToCheckin() ? '已签到' : '签到');
-        $Keyboard = [
+
+        $keyboard = [
             [
                 [
                     'text' => '用户中心',
@@ -176,13 +187,14 @@ final class Callback
                 ],
             ],
         ];
+
         $text = Message::getUserTitle($user);
         $text .= PHP_EOL . PHP_EOL;
         $text .= Message::getUserInfo($user);
 
         return [
             'text' => $text,
-            'keyboard' => $Keyboard,
+            'keyboard' => $keyboard,
         ];
     }
 
@@ -190,18 +202,16 @@ final class Callback
      * 用户相关回调数据处理
      *
      * @throws InvalidDatabaseException
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
     public function userCallback(): void
     {
-        if ($this->user === null) {
-            if ($this->chat_id < 0) {
-                // 群组内提示
-                $this->answerCallbackQuery([
-                    'text' => '你好,你尚未绑定账户,无法进行操作。',
-                    'show_alert' => true,
-                ]);
-            }
+        if ($this->user === null && $this->chat_id < 0) {
+            // 群组内提示
+            $this->answerCallbackQuery([
+                'text' => '你好,你尚未绑定账户,无法进行操作。',
+                'show_alert' => true,
+            ]);
         }
 
         $CallbackDataExplode = explode('|', $this->callback_data);
@@ -258,6 +268,7 @@ final class Callback
         $text = Message::getUserTitle($this->user);
         $text .= PHP_EOL . PHP_EOL;
         $text .= Message::getUserTrafficInfo($this->user);
+
         $keyboard = [
             [
                 [
@@ -297,7 +308,7 @@ final class Callback
      * 用户中心
      *
      * @throws TelegramSDKException
-     * @throws InvalidDatabaseException
+     * @throws InvalidDatabaseException|GuzzleException
      */
     public function userCenter(): void
     {
@@ -313,6 +324,7 @@ final class Callback
                 ],
             ],
         ];
+
         $CallbackDataExplode = explode('|', $this->callback_data);
         $Operate = explode('.', $CallbackDataExplode[0]);
         $OpEnd = end($Operate);
@@ -325,15 +337,13 @@ final class Callback
                     ->orderBy('datetime', 'desc')
                     ->take(10)
                     ->get();
-                $text = '<strong>以下是你最近 10 次的登录 IP 和地理位置:</strong>' . PHP_EOL;
-                $text .= PHP_EOL;
+                $text = '<strong>以下是你最近 10 次的登录 IP 和地理位置:</strong>' . PHP_EOL . PHP_EOL;
 
                 foreach ($total as $single) {
-                    $location = Tools::getIpLocation($single->ip);
-                    $text .= $single->ip . ' - ' . $location . PHP_EOL;
+                    $text .= $single->ip . ' - ' . Tools::getIpLocation($single->ip) . PHP_EOL;
                 }
 
-                $text .= PHP_EOL . '<strong>注意:地理位置根据 IP 数据库预估,可能与实际位置不符,仅供参考使用</strong>' . PHP_EOL;
+                $text .= PHP_EOL . '<strong>注意:地理位置根据 MaxMind GeoIP2 数据库预估,可能与实际位置不符,仅供参考</strong>' . PHP_EOL;
 
                 $sendMessage = [
                     'text' => $text,
@@ -346,21 +356,20 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             case 'usage_log':
                 // 使用记录
                 $logs = OnlineLog::where('user_id', $this->user->id)
                     ->where('last_time', '>', time() - 90)->orderByDesc('last_time')->get('ip');
-                $text = '<strong>以下是你账户在线 IP 和地理位置:</strong>' . PHP_EOL;
-                $text .= PHP_EOL;
+                $text = '<strong>以下是你账户在线 IP 和地理位置:</strong>' . PHP_EOL . PHP_EOL;
 
                 foreach ($logs as $log) {
                     $ip = $log->ip();
-                    $location = Tools::getIpLocation($ip);
-                    $text .= "{$ip} - {$location}\n";
+                    $text .= $ip . ' - ' . Tools::getIpLocation($ip) . PHP_EOL;
                 }
 
-                $text .= PHP_EOL . '<strong>注意:地理位置根据 IP 数据库预估,可能与实际位置不符,仅供参考使用</strong>' . PHP_EOL;
+                $text .= PHP_EOL . '<strong>注意:地理位置根据 MaxMind GeoIP2 数据库预估,可能与实际位置不符,仅供参考</strong>' . PHP_EOL;
 
                 $sendMessage = [
                     'text' => $text,
@@ -373,19 +382,19 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             case 'rebate_log':
                 // 返利记录
                 $paybacks = Payback::where('ref_by', $this->user->id)->orderBy('datetime', 'desc')->take(10)->get();
-                $temp = [];
+                $text = '<strong>以下是你最近 10 次返利记录:</strong>' . PHP_EOL . PHP_EOL;
+
                 foreach ($paybacks as $payback) {
-                    $temp[] = '<code>#' . $payback->id .
+                    $text .= '<code>#' . $payback->id .
                         ':' . ($payback->user() !== null ? $payback->user()->user_name : '已注销') . ':' .
-                        $payback->ref_get . ' 元</code>';
+                        $payback->ref_get . ' 元</code>' . PHP_EOL;
                 }
-                $text = '<strong>以下是你最近 10 次返利记录:</strong>';
-                $text .= PHP_EOL . PHP_EOL;
-                $text .= implode(PHP_EOL, $temp);
+
                 $sendMessage = [
                     'text' => $text,
                     'disable_web_page_preview' => false,
@@ -397,20 +406,25 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             case 'subscribe_log':
                 // 订阅记录
-                $logs = SubscribeLog::orderBy('id', 'desc')->where('user_id', $this->user->id)->take(10)->get();
-                $temp = [];
-                foreach ($logs as $log) {
-                    $location = Tools::getIpLocation($log->request_ip);
-                    $temp[] = '<code>' . Tools::toDateTime($log->request_time) .
-                        ' 在 [' . $log->request_ip . '] ' . $location .
-                        ' 访问了 ' . $log->type . ' 订阅</code>';
+                if ($_ENV['subscribeLog']) {
+                    $logs = SubscribeLog::orderBy('id', 'desc')->where('user_id', $this->user->id)->take(10)->get();
+                    $text = '<strong>以下是你最近 10 次订阅记录:</strong>' . PHP_EOL . PHP_EOL;
+
+                    foreach ($logs as $log) {
+                        $text .= '<code>' . Tools::toDateTime($log->request_time) .
+                            ' 在 [' . $log->request_ip . '] ' . Tools::getIpLocation($log->request_ip) .
+                            ' 访问了 ' . $log->type . ' 订阅</code>' . PHP_EOL;
+                    }
+
+                    $text .= PHP_EOL . '<strong>注意:地理位置根据 MaxMind GeoIP2 数据库预估,可能与实际位置不符,仅供参考</strong>' . PHP_EOL;
+                } else {
+                    $text = '站点未开启订阅记录功能';
                 }
-                $text = '<strong>以下是你最近 10 次订阅记录:</strong>';
-                $text .= PHP_EOL . PHP_EOL;
-                $text .= implode(PHP_EOL . PHP_EOL, $temp);
+
                 $sendMessage = [
                     'text' => $text,
                     'disable_web_page_preview' => false,
@@ -422,9 +436,11 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             default:
                 $temp = $this->getUserCenterKeyboard();
+
                 $sendMessage = [
                     'text' => $temp['text'],
                     'disable_web_page_preview' => false,
@@ -435,6 +451,7 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
         }
 
@@ -489,6 +506,7 @@ final class Callback
      * 用户编辑
      *
      * @throws TelegramSDKException
+     * @throws GuzzleException
      */
     public function userEdit(): void
     {
@@ -521,11 +539,14 @@ final class Callback
             case 'update_link':
                 // 重置订阅链接
                 $this->user->cleanLink();
+
                 $this->answerCallbackQuery([
                     'text' => '订阅链接重置成功,请在下方重新更新订阅。',
                     'show_alert' => true,
                 ]);
+
                 $temp = $this->getUserSubscribeKeyboard();
+
                 $sendMessage = [
                     'text' => $temp['text'],
                     'disable_web_page_preview' => false,
@@ -536,10 +557,12 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             case 'update_passwd':
                 // 重置链接密码
                 $this->user->passwd = Tools::genRandomChar();
+
                 if ($this->user->save()) {
                     $answerCallbackQuery = '连接密码更新成功,请在下方重新更新订阅。';
                     $temp = $this->getUserSubscribeKeyboard();
@@ -547,10 +570,12 @@ final class Callback
                     $answerCallbackQuery = '出现错误,连接密码更新失败,请联系管理员。';
                     $temp = $this->getUserEditKeyboard();
                 }
+
                 $this->answerCallbackQuery([
                     'text' => $answerCallbackQuery,
                     'show_alert' => true,
                 ]);
+
                 $sendMessage = [
                     'text' => $temp['text'],
                     'disable_web_page_preview' => false,
@@ -561,6 +586,7 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             case 'encrypt':
                 // 加密方式更改
@@ -578,20 +604,25 @@ final class Callback
                     }
                 } else {
                     $Encrypts = [];
+
                     foreach (Config::getSupportParam('method') as $value) {
                         $Encrypts[] = [
                             'text' => $value,
                             'callback_data' => 'user.edit.encrypt|' . $value,
                         ];
                     }
+
                     $Encrypts = array_chunk($Encrypts, 2);
                     $keyboard = [];
+
                     foreach ($Encrypts as $Encrypt) {
                         $keyboard[] = $Encrypt;
                     }
+
                     $keyboard[] = $back[0];
                     $text = '你当前的加密方式为:' . $this->user->method;
                 }
+
                 $sendMessage = [
                     'text' => $text,
                     'disable_web_page_preview' => false,
@@ -638,20 +669,23 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
             case 'unban_update':
                 // 提交群组解封
-                Tool::sendPost(
+                Message::sendPost(
                     'unbanChatMember',
                     [
                         'chat_id' => Setting::obtain('telegram_chatid'),
                         'user_id' => $this->trigger_user['id'],
                     ]
                 );
+
                 $this->answerCallbackQuery([
                     'text' => '已提交解封,如你仍无法加入群组,请联系管理员。',
                     'show_alert' => true,
                 ]);
+
                 break;
             default:
                 $temp = $this->getUserEditKeyboard();
@@ -659,6 +693,7 @@ final class Callback
                 $text .= '端口:' . $this->user->port . PHP_EOL;
                 $text .= '密码:' . $this->user->passwd . PHP_EOL;
                 $text .= '加密:' . $this->user->method;
+
                 $sendMessage = [
                     'text' => $text,
                     'disable_web_page_preview' => false,
@@ -669,6 +704,7 @@ final class Callback
                         ]
                     ),
                 ];
+
                 break;
         }
 
@@ -682,6 +718,7 @@ final class Callback
     public function getUserSubscribeKeyboard(): array
     {
         $text = '选择你想要使用的订阅链接类型:';
+
         $keyboard = [
             [
                 [
@@ -725,16 +762,34 @@ final class Callback
             ],
         ];
 
+        if (! Setting::obtain('enable_traditional_sub')) {
+            unset($keyboard[1]);
+            unset($keyboard[2]);
+        }
+
+        if (! Setting::obtain('enable_ss_sub')) {
+            unset($keyboard[0][2]);
+            unset($keyboard[1]);
+        }
+
+        if (! Setting::obtain('enable_v2_sub')) {
+            unset($keyboard[2][0]);
+        }
+
+        if (! Setting::obtain('enable_trojan_sub')) {
+            unset($keyboard[2][1]);
+        }
+
         return [
             'text' => $text,
-            'keyboard' => $keyboard,
+            'keyboard' => array_values($keyboard),
         ];
     }
 
     /**
      * 用户订阅
      *
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
     public function userSubscribe(): void
     {
@@ -760,6 +815,7 @@ final class Callback
 
             $UniversalSub_Url = SubController::getUniversalSubLink($this->user);
             $TraditionalSub_Url = SubController::getTraditionalSubLink($this->user);
+
             $text = match ($CallbackDataExplode[1]) {
                 'clash' => 'Clash 通用订阅地址:' . PHP_EOL . PHP_EOL .
                     '<code>' . $UniversalSub_Url . '/clash</code>' . PHP_EOL . PHP_EOL,
@@ -777,6 +833,7 @@ final class Callback
                     '<code>' . $TraditionalSub_Url . '?trojan=1</code>' . PHP_EOL . PHP_EOL,
                 default => '未知参数' . PHP_EOL . PHP_EOL,
             };
+
             $sendMessage = [
                 'text' => $text,
                 'disable_web_page_preview' => true,
@@ -789,6 +846,7 @@ final class Callback
             ];
         } else {
             $temp = $this->getUserSubscribeKeyboard();
+
             $sendMessage = [
                 'text' => $temp['text'],
                 'disable_web_page_preview' => false,
@@ -820,6 +878,7 @@ final class Callback
         }
 
         $invite = Setting::getClass('invite');
+
         $text = [
             '<strong>你每邀请 1 位用户注册:</strong>',
             '',
@@ -829,6 +888,7 @@ final class Callback
             '',
             '已获得返利:' . $paybacks_sum . ' 元。',
         ];
+
         $keyboard = [
             [
                 [
@@ -853,7 +913,7 @@ final class Callback
     /**
      * 分享计划
      *
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
     public function userInvite(): void
     {
@@ -881,6 +941,7 @@ final class Callback
             ];
         } else {
             $temp = $this->getUserInviteKeyboard();
+
             $sendMessage = [
                 'text' => $temp['text'],
                 'disable_web_page_preview' => false,
@@ -906,11 +967,12 @@ final class Callback
     /**
      * 每日签到
      *
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
     public function userCheckin(): void
     {
         $checkin = $this->user->checkin();
+
         $this->answerCallbackQuery([
             'text' => $checkin['msg'],
             'show_alert' => true,
@@ -922,6 +984,7 @@ final class Callback
             $temp['text'] = Message::getUserTitle($this->user);
             $temp['text'] .= PHP_EOL . PHP_EOL;
             $temp['text'] .= Message::getUserTrafficInfo($this->user);
+
             $temp['keyboard'] = [
                 [
                     [

+ 2 - 2
src/Services/Bot/Telegram/Commands/CheckinCommand.php

@@ -5,7 +5,7 @@ declare(strict_types=1);
 namespace App\Services\Bot\Telegram\Commands;
 
 use App\Models\Setting;
-use App\Services\Bot\Telegram\Tool;
+use App\Services\Bot\Telegram\Message;
 use Telegram\Bot\Actions;
 use Telegram\Bot\Commands\Command;
 
@@ -52,7 +52,7 @@ final class CheckinCommand extends Command
         $send_user = [
             'id' => $message->getFrom()->getId(),
         ];
-        $user = Tool::getUser($send_user['id']);
+        $user = Message::getUser($send_user['id']);
 
         if ($user === null) {
             // 回送信息

+ 2 - 0
src/Services/Bot/Telegram/Commands/HelpCommand.php

@@ -7,6 +7,8 @@ namespace App\Services\Bot\Telegram\Commands;
 use App\Models\Setting;
 use Telegram\Bot\Actions;
 use Telegram\Bot\Commands\Command;
+use function preg_match;
+use const PHP_EOL;
 
 /**
  * Class HelpCommand.

+ 2 - 2
src/Services/Bot/Telegram/Commands/MenuCommand.php

@@ -5,7 +5,7 @@ declare(strict_types=1);
 namespace App\Services\Bot\Telegram\Commands;
 
 use App\Services\Bot\Telegram\Callback;
-use App\Services\Bot\Telegram\Tool;
+use App\Services\Bot\Telegram\Message;
 use Telegram\Bot\Actions;
 use Telegram\Bot\Commands\Command;
 use function json_encode;
@@ -47,7 +47,7 @@ final class MenuCommand extends Command
                 'id' => $message->getFrom()->getId(),
             ];
 
-            $user = Tool::getUser($send_user['id']);
+            $user = Message::getUser($send_user['id']);
             if ($user === null) {
                 $reply = null;
             } else {

+ 1 - 0
src/Services/Bot/Telegram/Commands/MyCommand.php

@@ -10,6 +10,7 @@ use App\Services\Bot\Telegram\Message;
 use Telegram\Bot\Actions;
 use Telegram\Bot\Commands\Command;
 use function json_encode;
+use const PHP_EOL;
 
 /**
  * Class MyCommand.

+ 2 - 0
src/Services/Bot/Telegram/Commands/PingCommand.php

@@ -7,6 +7,8 @@ namespace App\Services\Bot\Telegram\Commands;
 use App\Models\Setting;
 use Telegram\Bot\Actions;
 use Telegram\Bot\Commands\Command;
+use function implode;
+use const PHP_EOL;
 
 /**
  * Class PingCommand.

+ 6 - 2
src/Services/Bot/Telegram/Commands/UnbindCommand.php

@@ -5,9 +5,13 @@ declare(strict_types=1);
 namespace App\Services\Bot\Telegram\Commands;
 
 use App\Models\Setting;
-use App\Services\Bot\Telegram\Tool;
+use App\Services\Bot\Telegram\Message;
 use Telegram\Bot\Actions;
 use Telegram\Bot\Commands\Command;
+use function array_splice;
+use function explode;
+use function trim;
+use const PHP_EOL;
 
 /**
  * Class UnbindCommand.
@@ -34,7 +38,7 @@ final class UnbindCommand extends Command
         $send_user = [
             'id' => $message->getFrom()->getId(),
         ];
-        $user = Tool::getUser($send_user['id']);
+        $user = Message::getUser($send_user['id']);
 
         if ($chat_id > 0) {
             // 发送 '输入中' 会话状态

+ 55 - 8
src/Services/Bot/Telegram/Message.php

@@ -6,11 +6,16 @@ namespace App\Services\Bot\Telegram;
 
 use App\Models\Setting;
 use App\Models\User;
+use GuzzleHttp\Client;
+use GuzzleHttp\Exception\GuzzleException;
+use Illuminate\Support\Collection;
 use Telegram\Bot\Api;
 use Telegram\Bot\Exceptions\TelegramSDKException;
-use Telegram\Bot\Objects\Message as TelegramMessage;
+use function array_merge;
+use function implode;
 use function in_array;
 use function json_decode;
+use const PHP_EOL;
 
 final class Message
 {
@@ -32,7 +37,7 @@ final class Message
     /**
      * 触发源信息
      */
-    private TelegramMessage $message;
+    private Collection $message;
 
     /**
      * 触发源信息 ID
@@ -41,17 +46,19 @@ final class Message
     private $user;
 
     /**
-     * @throws TelegramSDKException
+     * @throws TelegramSDKException|GuzzleException
      */
-    public function __construct(Api $bot, TelegramMessage $message)
+    public function __construct(Api $bot, Collection $message)
     {
         $this->bot = $bot;
+
         $this->trigger_user = [
             'id' => $message->getFrom()->getId(),
             'name' => $message->getFrom()->getFirstName() . ' Message.php' . $message->getFrom()->getLastName(),
             'username' => $message->getFrom()->getUsername(),
         ];
-        $this->user = Tool::getUser($this->trigger_user['id']);
+
+        $this->user = self::getUser($this->trigger_user['id']);
         $this->chat_id = $message->getChat()->getId();
         $this->message = $message;
         $this->message_id = $message->getMessageId();
@@ -85,6 +92,7 @@ final class Message
      * 入群检测
      *
      * @throws TelegramSDKException
+     * @throws GuzzleException
      */
     public function newChatParticipant(): void
     {
@@ -108,7 +116,7 @@ final class Message
                     ]
                 );
 
-                Tool::sendPost(
+                self::sendPost(
                     'kickChatMember',
                     [
                         'chat_id' => $this->chat_id,
@@ -124,7 +132,7 @@ final class Message
             }
         } else {
             // 新成员加入群组
-            $NewUser = Tool::getUser($Member['id']);
+            $NewUser = self::getUser($Member['id']);
 
             if (Setting::obtain('telegram_group_bound_user')
                 &&
@@ -140,7 +148,7 @@ final class Message
                     ]
                 );
 
-                Tool::sendPost(
+                self::sendPost(
                     'kickChatMember',
                     [
                         'chat_id' => $this->chat_id,
@@ -209,4 +217,43 @@ final class Message
 
         return $text;
     }
+
+    /**
+     * Sends a POST request to Telegram Bot API.
+     * 伪异步,无结果返回.
+     *
+     * @param $method
+     * @param $params
+     *
+     * @throws GuzzleException
+     */
+    public static function sendPost($method, $params): void
+    {
+        $client = new Client();
+        $telegram_api_url = 'https://api.telegram.org/bot' . Setting::obtain('telegram_token') . '/' . $method;
+
+        $headers = [
+            'Content-Type' => 'application/json; charset=utf-8',
+        ];
+
+        $client->post(
+            $telegram_api_url,
+            [
+                'headers' => $headers,
+                'json' => $params,
+                'timeout' => 1,
+            ]
+        );
+    }
+
+    /**
+     * 搜索用户
+     *
+     * @param int $value  搜索值
+     * @param string $method 查找列
+     */
+    public static function getUser(int $value, string $method = 'im_value')
+    {
+        return User::where('im_type', 4)->where($method, $value)->first();
+    }
 }

+ 3 - 0
src/Services/Bot/Telegram/Process.php

@@ -5,6 +5,7 @@ declare(strict_types=1);
 namespace App\Services\Bot\Telegram;
 
 use App\Models\Setting;
+use GuzzleHttp\Exception\GuzzleException;
 use MaxMind\Db\Reader\InvalidDatabaseException;
 use Psr\Http\Message\RequestInterface;
 use Telegram\Bot\Api;
@@ -15,6 +16,7 @@ final class Process
     /**
      * @throws InvalidDatabaseException
      * @throws TelegramSDKException
+     * @throws GuzzleException
      */
     public static function index(RequestInterface $request): void
     {
@@ -31,6 +33,7 @@ final class Process
         ]);
 
         $bot->commandsHandler(true, $request);
+        $bot->setConnectTimeOut(1);
         $update = $bot->getWebhookUpdate();
 
         if ($update->has('callback_query')) {

+ 0 - 53
src/Services/Bot/Telegram/Tool.php

@@ -1,53 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace App\Services\Bot\Telegram;
-
-use App\Models\Setting;
-use App\Models\User;
-use function curl_close;
-use function curl_exec;
-use function curl_init;
-use function curl_setopt;
-use function json_encode;
-use const CURLOPT_HTTPHEADER;
-use const CURLOPT_POST;
-use const CURLOPT_POSTFIELDS;
-use const CURLOPT_TIMEOUT;
-use const CURLOPT_URL;
-
-final class Tool
-{
-    /**
-     * 搜索用户
-     *
-     * @param int $value  搜索值
-     * @param string $method 查找列
-     */
-    public static function getUser(int $value, string $method = 'im_value')
-    {
-        return User::where('im_type', 4)->where($method, $value)->first();
-    }
-
-    /**
-     * Sends a POST request to Telegram Bot API.
-     * 伪异步,无结果返回.
-     *
-     * @param $method
-     * @param $params
-     */
-    public static function sendPost($method, $params): void
-    {
-        $URL = 'https://api.telegram.org/bot' . Setting::obtain('telegram_token') . '/' . $method;
-        $POSTData = json_encode($params);
-        $C = curl_init();
-        curl_setopt($C, CURLOPT_URL, $URL);
-        curl_setopt($C, CURLOPT_POST, 1);
-        curl_setopt($C, CURLOPT_HTTPHEADER, ['Content-Type:application/json; charset=utf-8']);
-        curl_setopt($C, CURLOPT_POSTFIELDS, $POSTData);
-        curl_setopt($C, CURLOPT_TIMEOUT, 1);
-        curl_exec($C);
-        curl_close($C);
-    }
-}

+ 0 - 1
src/Services/Config.php

@@ -18,7 +18,6 @@ final class Config
             'checkinMax' => $_ENV['checkinMax'],
 
             'jump_delay' => $_ENV['jump_delay'],
-            'enable_analytics_code' => $_ENV['enable_analytics_code'],
 
             'enable_kill' => $_ENV['enable_kill'],
             'enable_change_email' => $_ENV['enable_change_email'],

+ 2 - 0
src/Services/LLM.php

@@ -112,6 +112,7 @@ final class LLM
         $response = json_decode($client->post($api_url, [
             'headers' => $headers,
             'json' => $data,
+            'timeout' => 10,
         ])->getBody()->getContents());
 
         return $response->candidates[0]->output;
@@ -146,6 +147,7 @@ final class LLM
         $response = json_decode($client->post($_ENV['huggingface_endpoint_url'], [
             'headers' => $headers,
             'json' => $data,
+            'timeout' => 10,
         ])->getBody()->getContents());
 
         return $response->answer;

+ 0 - 3
tests/App/Services/ConfigTest.php

@@ -21,7 +21,6 @@ class ConfigTest extends TestCase
             'checkinMin' => 10,
             'checkinMax' => 20,
             'jump_delay' => 5,
-            'enable_analytics_code' => false,
             'enable_kill' => true,
             'enable_change_email' => false,
             'subscribeLog' => true,
@@ -37,7 +36,6 @@ class ConfigTest extends TestCase
             'checkinMin' => 10,
             'checkinMax' => 20,
             'jump_delay' => 5,
-            'enable_analytics_code' => false,
             'enable_kill' => true,
             'enable_change_email' => false,
             'subscribeLog' => true,
@@ -54,7 +52,6 @@ class ConfigTest extends TestCase
         $this->assertSame($mockEnv['checkinMin'], $config['checkinMin']);
         $this->assertSame($mockEnv['checkinMax'], $config['checkinMax']);
         $this->assertSame($mockEnv['jump_delay'], $config['jump_delay']);
-        $this->assertSame($mockEnv['enable_analytics_code'], $config['enable_analytics_code']);
         $this->assertSame($mockEnv['enable_kill'], $config['enable_kill']);
         $this->assertSame($mockEnv['enable_change_email'], $config['enable_change_email']);
         $this->assertSame($mockEnv['subscribeLog'], $config['subscribeLog']);