Explorar o código

Merge pull request #2410 from SSPanel-UIM/dev

Dev 20240402
M1Screw hai 1 ano
pai
achega
ed93a72293

+ 1 - 1
composer.json

@@ -36,7 +36,7 @@
         "sentry/sdk": "^4",
         "slim/http": "^1",
         "slim/slim": "^4",
-        "smarty/smarty": "^4",
+        "smarty/smarty": "^5",
         "srmklive/paypal": "^3",
         "stripe/stripe-php": "^13",
         "symfony/http-client": "^7",

+ 100 - 91
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": "610d76a6a2b0c7ce5ee421d330e55391",
+    "content-hash": "39ab430ad43a297c4e1b232afd979153",
     "packages": [
         {
             "name": "adbario/php-dot-notation",
@@ -510,12 +510,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/alipay/alipay-sdk-php-all.git",
-                "reference": "3618beb0ab933209ed15cbbb4c52106cda0c5f4b"
+                "reference": "3b86882423995c15992c277ffeb1c8e8b2a4a6c3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/alipay/alipay-sdk-php-all/zipball/3618beb0ab933209ed15cbbb4c52106cda0c5f4b",
-                "reference": "3618beb0ab933209ed15cbbb4c52106cda0c5f4b",
+                "url": "https://api.github.com/repos/alipay/alipay-sdk-php-all/zipball/3b86882423995c15992c277ffeb1c8e8b2a4a6c3",
+                "reference": "3b86882423995c15992c277ffeb1c8e8b2a4a6c3",
                 "shasum": ""
             },
             "require": {
@@ -564,7 +564,7 @@
             "support": {
                 "source": "https://github.com/alipay/alipay-sdk-php-all/tree/master"
             },
-            "time": "2024-03-13T02:49:07+00:00"
+            "time": "2024-03-27T06:32:49+00:00"
         },
         {
             "name": "aws/aws-crt-php",
@@ -622,16 +622,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.301.6",
+            "version": "3.303.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "18c0ebd71d3071304f1ea02aa9af75f95863177a"
+                "reference": "34ace61fdffcea032826b0aac61ff3135b24b727"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/18c0ebd71d3071304f1ea02aa9af75f95863177a",
-                "reference": "18c0ebd71d3071304f1ea02aa9af75f95863177a",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/34ace61fdffcea032826b0aac61ff3135b24b727",
+                "reference": "34ace61fdffcea032826b0aac61ff3135b24b727",
                 "shasum": ""
             },
             "require": {
@@ -711,9 +711,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.301.6"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.303.0"
             },
-            "time": "2024-03-22T18:05:21+00:00"
+            "time": "2024-04-01T18:48:47+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -1703,7 +1703,7 @@
         },
         {
             "name": "illuminate/collections",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/collections.git",
@@ -1758,7 +1758,7 @@
         },
         {
             "name": "illuminate/conditionable",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/conditionable.git",
@@ -1804,7 +1804,7 @@
         },
         {
             "name": "illuminate/container",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/container.git",
@@ -1855,7 +1855,7 @@
         },
         {
             "name": "illuminate/contracts",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/contracts.git",
@@ -1903,16 +1903,16 @@
         },
         {
             "name": "illuminate/database",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/database.git",
-                "reference": "b3b8cd87a2271fc9427006dc56710ea9dc55af1c"
+                "reference": "3e4e41b278146ad645ccc5901ccaf343efd850ea"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/database/zipball/b3b8cd87a2271fc9427006dc56710ea9dc55af1c",
-                "reference": "b3b8cd87a2271fc9427006dc56710ea9dc55af1c",
+                "url": "https://api.github.com/repos/illuminate/database/zipball/3e4e41b278146ad645ccc5901ccaf343efd850ea",
+                "reference": "3e4e41b278146ad645ccc5901ccaf343efd850ea",
                 "shasum": ""
             },
             "require": {
@@ -1967,11 +1967,11 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-03-19T20:07:36+00:00"
+            "time": "2024-03-28T14:12:19+00:00"
         },
         {
             "name": "illuminate/macroable",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/macroable.git",
@@ -2017,7 +2017,7 @@
         },
         {
             "name": "illuminate/pagination",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/pagination.git",
@@ -2067,16 +2067,16 @@
         },
         {
             "name": "illuminate/support",
-            "version": "v11.0.8",
+            "version": "v11.1.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/illuminate/support.git",
-                "reference": "9e4c65a95465d6c5d4282c4d2435dc04a2f9f10a"
+                "reference": "9fdd4fc622524787185264faeadfe14f2f0e356b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/illuminate/support/zipball/9e4c65a95465d6c5d4282c4d2435dc04a2f9f10a",
-                "reference": "9e4c65a95465d6c5d4282c4d2435dc04a2f9f10a",
+                "url": "https://api.github.com/repos/illuminate/support/zipball/9fdd4fc622524787185264faeadfe14f2f0e356b",
+                "reference": "9fdd4fc622524787185264faeadfe14f2f0e356b",
                 "shasum": ""
             },
             "require": {
@@ -2137,7 +2137,7 @@
                 "issues": "https://github.com/laravel/framework/issues",
                 "source": "https://github.com/laravel/framework"
             },
-            "time": "2024-03-20T20:10:03+00:00"
+            "time": "2024-03-27T16:39:25+00:00"
         },
         {
             "name": "irazasyed/telegram-bot-sdk",
@@ -2762,16 +2762,16 @@
         },
         {
             "name": "nesbot/carbon",
-            "version": "3.1.1",
+            "version": "3.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/briannesbitt/Carbon.git",
-                "reference": "34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2"
+                "reference": "4d599a6e2351d6b6bf21737accdfe1a4ce3fdbb1"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2",
-                "reference": "34ccf6f6b49c915421c7886c88c0cb77f3ebbfd2",
+                "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4d599a6e2351d6b6bf21737accdfe1a4ce3fdbb1",
+                "reference": "4d599a6e2351d6b6bf21737accdfe1a4ce3fdbb1",
                 "shasum": ""
             },
             "require": {
@@ -2789,14 +2789,14 @@
             "require-dev": {
                 "doctrine/dbal": "^3.6.3 || ^4.0",
                 "doctrine/orm": "^2.15.2 || ^3.0",
-                "friendsofphp/php-cs-fixer": "^3.18.0",
-                "kylekatarnls/multi-tester": "^2.2.0",
-                "ondrejmirtes/better-reflection": "^6.11.0.0",
-                "phpmd/phpmd": "^2.13.0",
-                "phpstan/extension-installer": "^1.3.0",
-                "phpstan/phpstan": "^1.10.20",
-                "phpunit/phpunit": "^10.2.2",
-                "squizlabs/php_codesniffer": "^3.7.2"
+                "friendsofphp/php-cs-fixer": "^3.52.1",
+                "kylekatarnls/multi-tester": "^2.5.3",
+                "ondrejmirtes/better-reflection": "^6.25.0.4",
+                "phpmd/phpmd": "^2.15.0",
+                "phpstan/extension-installer": "^1.3.1",
+                "phpstan/phpstan": "^1.10.65",
+                "phpunit/phpunit": "^10.5.15",
+                "squizlabs/php_codesniffer": "^3.9.0"
             },
             "bin": [
                 "bin/carbon"
@@ -2864,7 +2864,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-03-13T12:42:37+00:00"
+            "time": "2024-03-30T18:22:00+00:00"
         },
         {
             "name": "nikic/fast-route",
@@ -3189,16 +3189,16 @@
         },
         {
             "name": "php-http/discovery",
-            "version": "1.19.2",
+            "version": "1.19.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-http/discovery.git",
-                "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb"
+                "reference": "0700efda8d7526335132360167315fdab3aeb599"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-http/discovery/zipball/61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb",
-                "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb",
+                "url": "https://api.github.com/repos/php-http/discovery/zipball/0700efda8d7526335132360167315fdab3aeb599",
+                "reference": "0700efda8d7526335132360167315fdab3aeb599",
                 "shasum": ""
             },
             "require": {
@@ -3222,7 +3222,8 @@
                 "php-http/httplug": "^1.0 || ^2.0",
                 "php-http/message-factory": "^1.0",
                 "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3",
-                "symfony/phpunit-bridge": "^6.2"
+                "sebastian/comparator": "^3.0.5 || ^4.0.8",
+                "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1"
             },
             "type": "composer-plugin",
             "extra": {
@@ -3261,9 +3262,9 @@
             ],
             "support": {
                 "issues": "https://github.com/php-http/discovery/issues",
-                "source": "https://github.com/php-http/discovery/tree/1.19.2"
+                "source": "https://github.com/php-http/discovery/tree/1.19.4"
             },
-            "time": "2023-11-30T16:49:05+00:00"
+            "time": "2024-03-29T13:00:05+00:00"
         },
         {
             "name": "php-http/httplug",
@@ -4854,35 +4855,39 @@
         },
         {
             "name": "smarty/smarty",
-            "version": "v4.5.1",
+            "version": "v5.0.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/smarty-php/smarty.git",
-                "reference": "42b869e3a098b1c8ee07922ccded0e5a5dceadcd"
+                "reference": "bbd09c7bfaa6c2c091adc4568a944f765bb4f1d9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/smarty-php/smarty/zipball/42b869e3a098b1c8ee07922ccded0e5a5dceadcd",
-                "reference": "42b869e3a098b1c8ee07922ccded0e5a5dceadcd",
+                "url": "https://api.github.com/repos/smarty-php/smarty/zipball/bbd09c7bfaa6c2c091adc4568a944f765bb4f1d9",
+                "reference": "bbd09c7bfaa6c2c091adc4568a944f765bb4f1d9",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.1 || ^8.0"
+                "php": "^7.2 || ^8.0",
+                "symfony/polyfill-mbstring": "^1.27"
             },
             "require-dev": {
                 "phpunit/phpunit": "^8.5 || ^7.5",
-                "smarty/smarty-lexer": "^3.1"
+                "smarty/smarty-lexer": "^4.0.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.0.x-dev"
+                    "dev-master": "5.0.x-dev"
                 }
             },
             "autoload": {
-                "classmap": [
-                    "libs/"
-                ]
+                "files": [
+                    "src/functions.php"
+                ],
+                "psr-4": {
+                    "Smarty\\": "src/"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
@@ -4914,9 +4919,9 @@
             "support": {
                 "forum": "https://github.com/smarty-php/smarty/discussions",
                 "issues": "https://github.com/smarty-php/smarty/issues",
-                "source": "https://github.com/smarty-php/smarty/tree/v4.5.1"
+                "source": "https://github.com/smarty-php/smarty/tree/v5.0.2"
             },
-            "time": "2024-03-18T14:19:07+00:00"
+            "time": "2024-03-28T10:23:18+00:00"
         },
         {
             "name": "srmklive/paypal",
@@ -5029,16 +5034,16 @@
         },
         {
             "name": "stripe/stripe-php",
-            "version": "v13.15.0",
+            "version": "v13.16.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/stripe/stripe-php.git",
-                "reference": "22963c3596eb198e3dd56fbd95d7de9bc4d44f8f"
+                "reference": "b122efcf4ee02256e4a9ae60783cbf1c3f702503"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/22963c3596eb198e3dd56fbd95d7de9bc4d44f8f",
-                "reference": "22963c3596eb198e3dd56fbd95d7de9bc4d44f8f",
+                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/b122efcf4ee02256e4a9ae60783cbf1c3f702503",
+                "reference": "b122efcf4ee02256e4a9ae60783cbf1c3f702503",
                 "shasum": ""
             },
             "require": {
@@ -5082,9 +5087,9 @@
             ],
             "support": {
                 "issues": "https://github.com/stripe/stripe-php/issues",
-                "source": "https://github.com/stripe/stripe-php/tree/v13.15.0"
+                "source": "https://github.com/stripe/stripe-php/tree/v13.16.0"
             },
-            "time": "2024-03-21T21:05:10+00:00"
+            "time": "2024-03-28T19:17:08+00:00"
         },
         {
             "name": "symfony/clock",
@@ -7067,16 +7072,16 @@
         },
         {
             "name": "composer/xdebug-handler",
-            "version": "3.0.3",
+            "version": "3.0.4",
             "source": {
                 "type": "git",
                 "url": "https://github.com/composer/xdebug-handler.git",
-                "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+                "reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
-                "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
+                "reference": "4f988f8fdf580d53bdb2d1278fe93d1ed5462255",
                 "shasum": ""
             },
             "require": {
@@ -7087,7 +7092,7 @@
             "require-dev": {
                 "phpstan/phpstan": "^1.0",
                 "phpstan/phpstan-strict-rules": "^1.1",
-                "symfony/phpunit-bridge": "^6.0"
+                "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5"
             },
             "type": "library",
             "autoload": {
@@ -7111,9 +7116,9 @@
                 "performance"
             ],
             "support": {
-                "irc": "irc://irc.freenode.org/composer",
+                "irc": "ircs://irc.libera.chat:6697/composer",
                 "issues": "https://github.com/composer/xdebug-handler/issues",
-                "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+                "source": "https://github.com/composer/xdebug-handler/tree/3.0.4"
             },
             "funding": [
                 {
@@ -7129,7 +7134,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2022-02-25T21:32:43+00:00"
+            "time": "2024-03-26T18:29:49+00:00"
         },
         {
             "name": "dealerdirect/phpcodesniffer-composer-installer",
@@ -7849,16 +7854,16 @@
         },
         {
             "name": "php-parallel-lint/php-parallel-lint",
-            "version": "v1.3.2",
+            "version": "v1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-parallel-lint/PHP-Parallel-Lint.git",
-                "reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de"
+                "reference": "6db563514f27e19595a19f45a4bf757b6401194e"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6483c9832e71973ed29cf71bd6b3f4fde438a9de",
-                "reference": "6483c9832e71973ed29cf71bd6b3f4fde438a9de",
+                "url": "https://api.github.com/repos/php-parallel-lint/PHP-Parallel-Lint/zipball/6db563514f27e19595a19f45a4bf757b6401194e",
+                "reference": "6db563514f27e19595a19f45a4bf757b6401194e",
                 "shasum": ""
             },
             "require": {
@@ -7896,13 +7901,17 @@
                     "email": "[email protected]"
                 }
             ],
-            "description": "This tool check syntax of PHP files about 20x faster than serial check.",
+            "description": "This tool checks the syntax of PHP files about 20x faster than serial check.",
             "homepage": "https://github.com/php-parallel-lint/PHP-Parallel-Lint",
+            "keywords": [
+                "lint",
+                "static analysis"
+            ],
             "support": {
                 "issues": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/issues",
-                "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.3.2"
+                "source": "https://github.com/php-parallel-lint/PHP-Parallel-Lint/tree/v1.4.0"
             },
-            "time": "2022-02-21T12:50:22+00:00"
+            "time": "2024-03-27T12:14:49+00:00"
         },
         {
             "name": "phpstan/phpdoc-parser",
@@ -8274,16 +8283,16 @@
         },
         {
             "name": "phpunit/phpunit",
-            "version": "10.5.15",
+            "version": "10.5.16",
             "source": {
                 "type": "git",
                 "url": "https://github.com/sebastianbergmann/phpunit.git",
-                "reference": "86376e05e8745ed81d88232ff92fee868247b07b"
+                "reference": "18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/86376e05e8745ed81d88232ff92fee868247b07b",
-                "reference": "86376e05e8745ed81d88232ff92fee868247b07b",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd",
+                "reference": "18f8d4a5f52b61fdd9370aaae3167daa0eeb69cd",
                 "shasum": ""
             },
             "require": {
@@ -8355,7 +8364,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.5.15"
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.16"
             },
             "funding": [
                 {
@@ -8371,7 +8380,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2024-03-22T04:17:47+00:00"
+            "time": "2024-03-28T10:08:10+00:00"
         },
         {
             "name": "psr/cache",
@@ -9405,16 +9414,16 @@
         },
         {
             "name": "squizlabs/php_codesniffer",
-            "version": "3.9.0",
+            "version": "3.9.1",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
-                "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b"
+                "reference": "267a4405fff1d9c847134db3a3c92f1ab7f77909"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
-                "reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
+                "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/267a4405fff1d9c847134db3a3c92f1ab7f77909",
+                "reference": "267a4405fff1d9c847134db3a3c92f1ab7f77909",
                 "shasum": ""
             },
             "require": {
@@ -9481,7 +9490,7 @@
                     "type": "open_collective"
                 }
             ],
-            "time": "2024-02-16T15:06:51+00:00"
+            "time": "2024-03-31T21:03:09+00:00"
         },
         {
             "name": "symfony/cache",

+ 64 - 64
config/.config.example.php

@@ -1,99 +1,99 @@
 <?php
 
 //基本设置--------------------------------------------------------------------------------------------
-$_ENV['key']        = 'ChangeMe';            // Cookie加密密钥,请务必修改此key为随机字符串
-$_ENV['pwdMethod']  = 'bcrypt';              // 密码加密 可选 bcrypt, argon2i, argon2id
-$_ENV['salt']       = '';                    // bcrypt/argon2i/argon2id 会忽略此项
+$_ENV['key'] = 'ChangeMe';            // Cookie加密密钥,请务必修改此key为随机字符串
+$_ENV['pwdMethod'] = 'bcrypt';              // 密码加密 可选 bcrypt, argon2i, argon2id
+$_ENV['salt'] = '';                    // bcrypt/argon2i/argon2id 会忽略此项
 
-$_ENV['debug']      = false;                 // debug模式开关,生产环境请保持为false
-$_ENV['appName']    = 'SSPanel-UIM';         // 站点名称
-$_ENV['baseUrl']    = 'https://example.com'; // 站点地址,必须以https://开头,不要以/结尾
+$_ENV['debug'] = false;                 // debug模式开关,生产环境请保持为false
+$_ENV['appName'] = 'SSPanel-UIM';         // 站点名称
+$_ENV['baseUrl'] = 'https://example.com'; // 站点地址,必须以https://开头,不要以/结尾
 
 // WebAPI
-$_ENV['webAPI']      = true;               // 是否开启WebAPI功能
-$_ENV['webAPIUrl']   = $_ENV['baseUrl'];   // WebAPI地址,如需和站点地址相同,请不要修改
-$_ENV['muKey']       = 'ChangeMe';         // WebAPI密钥,用于节点服务端与面板通信,请务必修改此key为随机字符串
+$_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_host 例: localhost(可解析的主机名), 127.0.0.1(IP 地址)
 // db_socket 例:/var/run/mysqld/mysqld.sock(需使用绝对地址)
-$_ENV['db_host']      = '';
-$_ENV['db_socket']    = '';
-$_ENV['db_database']  = 'sspanel';           // 数据库名
-$_ENV['db_username']  = 'root';              // 数据库用户名
-$_ENV['db_password']  = 'sspanel';           // 用户密码
-$_ENV['db_port']      = '3306';              // 端口
+$_ENV['db_host'] = '';
+$_ENV['db_socket'] = '';
+$_ENV['db_database'] = 'sspanel';           // 数据库名
+$_ENV['db_username'] = 'root';              // 数据库用户名
+$_ENV['db_password'] = 'sspanel';           // 用户密码
+$_ENV['db_port'] = '3306';              // 端口
 #读写分离相关配置
 $_ENV['enable_db_rw_split'] = false;         // 是否开启读写分离
-$_ENV['read_db_hosts']      = [''];          // 从库地址,可配置多个
-$_ENV['write_db_host']      = '';            // 主库地址
+$_ENV['read_db_hosts'] = [''];          // 从库地址,可配置多个
+$_ENV['write_db_host'] = '';            // 主库地址
 #高级
-$_ENV['db_charset']   = 'utf8mb4';
+$_ENV['db_charset'] = 'utf8mb4';
 $_ENV['db_collation'] = 'utf8mb4_unicode_ci';
-$_ENV['db_prefix']    = '';
+$_ENV['db_prefix'] = '';
 
 //Redis设置-------------------------------------------------------------------------------------------
-$_ENV['redis_host']            = '127.0.0.1'; // Redis地址,使用unix domain socket时填写文件路径
-$_ENV['redis_port']            = 6379;        // Redis端口,使用unix domain socket时填写-1
+$_ENV['redis_host'] = '127.0.0.1'; // Redis地址,使用unix domain socket时填写文件路径
+$_ENV['redis_port'] = 6379;        // Redis端口,使用unix domain socket时填写-1
 $_ENV['redis_connect_timeout'] = 2.0;         // Redis连接超时时间,单位秒
-$_ENV['redis_read_timeout']    = 8.0;         // Redis读取超时时间,单位秒
-$_ENV['redis_username']        = '';          // Redis用户名,留空则不使用用户名连接
-$_ENV['redis_password']        = '';          // Redis密码,留空则无密码
-$_ENV['redis_ssl']             = false;       // 是否使用SSL连接Redis,如果使用了SSL,那么Redis端口应为Redis实例的TLS端口
-$_ENV['redis_ssl_context']     = [];          // 使用SSL时的上下文选项,参考 https://www.php.net/manual/zh/context.ssl.php
+$_ENV['redis_read_timeout'] = 8.0;         // Redis读取超时时间,单位秒
+$_ENV['redis_username'] = '';          // Redis用户名,留空则不使用用户名连接
+$_ENV['redis_password'] = '';          // Redis密码,留空则无密码
+$_ENV['redis_ssl'] = false;       // 是否使用SSL连接Redis,如果使用了SSL,那么Redis端口应为Redis实例的TLS端口
+$_ENV['redis_ssl_context'] = [];          // 使用SSL时的上下文选项,参考 https://www.php.net/manual/zh/context.ssl.php
 
 //Rate Limit设置--------------------------------------------------------------------------------------------
-$_ENV['enable_rate_limit']    = true;         // 是否开启请求限制
-$_ENV['rate_limit_ip']        = 120;          // 每分钟每个IP的全局请求限制
-$_ENV['rate_limit_sub']       = 30;           // 每分钟每个用户的订阅链接请求限制
-$_ENV['rate_limit_webapi']    = 600;          // 每分钟每个节点WebAPI密钥请求限制
-$_ENV['rate_limit_user_api']  = 60;           // 每分钟每个用户的API请求限制
+$_ENV['enable_rate_limit'] = true;         // 是否开启请求限制
+$_ENV['rate_limit_ip'] = 120;          // 每分钟每个IP的全局请求限制
+$_ENV['rate_limit_sub'] = 30;           // 每分钟每个用户的订阅链接请求限制
+$_ENV['rate_limit_webapi'] = 600;          // 每分钟每个节点WebAPI密钥请求限制
+$_ENV['rate_limit_user_api'] = 60;           // 每分钟每个用户的API请求限制
 $_ENV['rate_limit_admin_api'] = 60;           // 每分钟每个管理员的API请求限制
 
 //邮件设置--------------------------------------------------------------------------------------------
-$_ENV['mail_filter']        = 0;            // 0: 关闭; 1: 白名单模式; 2; 黑名单模式;
-$_ENV['mail_filter_list']   = [];
+$_ENV['mail_filter'] = 0;            // 0: 关闭; 1: 白名单模式; 2; 黑名单模式;
+$_ENV['mail_filter_list'] = [];
 
 //已注册用户设置---------------------------------------------------------------------------------------
 #高级
 $_ENV['class_expire_reset_traffic'] = 0;            // 等级到期时重置为的流量值,单位GB,小于0时不重置
-$_ENV['enable_kill']                = true;         // 是否允许用户注销账户
-$_ENV['enable_change_email']        = true;         // 是否允许用户更改賬戶郵箱
+$_ENV['enable_kill'] = true;         // 是否允许用户注销账户
+$_ENV['enable_change_email'] = true;         // 是否允许用户更改賬戶郵箱
 
 #用户流量余量不足邮件提醒
-$_ENV['notify_limit_mode']          = false;         // false为关闭,per为按照百分比提醒,mb为按照固定剩余流量提醒
-$_ENV['notify_limit_value']         = 500;           // 当上一项为per时,此处填写百分比;当上一项为mb时,此处填写流量
+$_ENV['notify_limit_mode'] = false;         // false为关闭,per为按照百分比提醒,mb为按照固定剩余流量提醒
+$_ENV['notify_limit_value'] = 500;           // 当上一项为per时,此处填写百分比;当上一项为mb时,此处填写流量
 
 //订阅设置---------------------------------------------------------------------------------------
-$_ENV['Subscribe']                  = true;              // 本站是否提供订阅功能
-$_ENV['subUrl']                     = $_ENV['baseUrl'];  // 订阅地址,如需和站点名称相同,请不要修改
-$_ENV['sub_token_len']              = 16;                // 订阅token长度
+$_ENV['Subscribe'] = true;              // 本站是否提供订阅功能
+$_ENV['subUrl'] = $_ENV['baseUrl'];  // 订阅地址,如需和站点名称相同,请不要修改
+$_ENV['sub_token_len'] = 16;                // 订阅token长度
 
 //审计自动封禁设置--------------------------------------------------------------------------------------------
 $_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检测
-$_ENV['detect_gfw_port']     = 443;                                                  //所有节点服务器都打开的TCP端口
-$_ENV['detect_gfw_url']      = 'http://example.com:8080/v1/tcping?ip={ip}&port={port}'; //检测节点是否被gfw墙了的API的URL
+$_ENV['detect_gfw_port'] = 443;                                                  //所有节点服务器都打开的TCP端口
+$_ENV['detect_gfw_url'] = 'http://example.com:8080/v1/tcping?ip={ip}&port={port}'; //检测节点是否被gfw墙了的API的URL
 
 #离线检测
-$_ENV['enable_detect_offline']  = true;
+$_ENV['enable_detect_offline'] = true;
 
 //高级设置-----------------------------------------------------------------------------------------------
-$_ENV['enable_login_bind_ip']     = true;             //是否将登陆线程和IP绑定
+$_ENV['enable_login_bind_ip'] = true;             //是否将登陆线程和IP绑定
 $_ENV['enable_login_bind_device'] = true;             //是否将登陆线程和设备绑定
-$_ENV['rememberMeDuration']       = 7;                //登录时记住账号时长天数
-$_ENV['timeZone']                 = 'Asia/Taipei';    //需使用 PHP 兼容的时区格式
-$_ENV['theme']                    = 'tabler';         //默认主题
-$_ENV['locale']                   = 'zh-TW';          //默认语言
-$_ENV['jump_delay']               = 1200;             //跳转延时,单位ms
-$_ENV['keep_connect']             = false;            // 流量耗尽用户限速至 1Mbps
+$_ENV['rememberMeDuration'] = 7;                //登录时记住账号时长天数
+$_ENV['timeZone'] = 'Asia/Taipei';    //需使用 PHP 兼容的时区格式
+$_ENV['theme'] = 'tabler';         //默认主题
+$_ENV['locale'] = 'zh-TW';          //默认语言
+$_ENV['jump_delay'] = 1200;             //跳转延时,单位ms
+$_ENV['keep_connect'] = false;            // 流量耗尽用户限速至 1Mbps
 
 // cdn.jsdelivr.net / fastly.jsdelivr.net / testingcf.jsdelivr.net
 $_ENV['jsdelivr_url'] = 'fastly.jsdelivr.net';
@@ -103,28 +103,28 @@ $_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/google-ai/huggingface/cf-workers-ai/anthropic
 // OpenAI ChatGPT
 $_ENV['openai_api_key'] = '';
-$_ENV['openai_model']   = 'gpt-4-turbo-preview';
+$_ENV['openai_model'] = 'gpt-4-turbo-preview';
 // Google AI API
-$_ENV['google_ai_api_key']  = '';
+$_ENV['google_ai_api_key'] = '';
 $_ENV['google_ai_model_id'] = 'gemini-1.5-pro-latest';
 // Vertex AI API
-$_ENV['vertex_ai_access_token']  = '';
+$_ENV['vertex_ai_access_token'] = '';
 $_ENV['vertex_ai_location'] = 'us-central1';
 $_ENV['vertex_ai_model_id'] = 'gemini-1.0-pro';
 $_ENV['vertex_ai_project_id'] = '';
 // Hugging Face Inference API
-$_ENV['huggingface_api_key']      = '';
+$_ENV['huggingface_api_key'] = '';
 $_ENV['huggingface_endpoint_url'] = '';
 // Cloudflare Workers AI
 $_ENV['cf_workers_ai_account_id'] = '';
-$_ENV['cf_workers_ai_api_token']  = '';
-$_ENV['cf_workers_ai_model_id']   = '@cf/meta/llama-2-7b-chat-int8';
+$_ENV['cf_workers_ai_api_token'] = '';
+$_ENV['cf_workers_ai_model_id'] = '@cf/meta/llama-2-7b-chat-int8';
 // Anthropic
 $_ENV['anthropic_api_key'] = '';
 $_ENV['anthropic_model_id'] = 'claude-3-opus-20240229';
@@ -133,9 +133,9 @@ $_ENV['anthropic_model_id'] = 'claude-3-opus-20240229';
 $_ENV['github_access_token'] = '';
 
 // 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;

+ 1 - 1
resources/views/tabler/admin/announcement/create.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.3/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/7.0.0/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 1 - 1
resources/views/tabler/admin/announcement/edit.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.3/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/7.0.0/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 1 - 1
resources/views/tabler/admin/docs/create.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.3/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/7.0.0/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 1 - 1
resources/views/tabler/admin/docs/edit.tpl

@@ -1,6 +1,6 @@
 {include file='admin/header.tpl'}
 
-<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/6.8.3/tinymce.min.js"></script>
+<script src="//cdnjs.cloudflare.com/ajax/libs/tinymce/7.0.0/tinymce.min.js"></script>
 
 <div class="page-wrapper">
     <div class="container-xl">

+ 5 - 2
src/Controllers/Admin/DocsController.php

@@ -9,7 +9,6 @@ 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;
@@ -90,7 +89,11 @@ final class DocsController extends BaseController
     /**
      * 使用LLM生成文档
      *
-     * @throws GuzzleException
+     * @param ServerRequest $request
+     * @param Response $response
+     * @param array $args
+     *
+     * @return Response|ResponseInterface
      */
     public function generate(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
     {

+ 1 - 1
src/Controllers/Admin/NodeController.php

@@ -12,7 +12,7 @@ use App\Utils\Tools;
 use Psr\Http\Message\ResponseInterface;
 use Slim\Http\Response;
 use Slim\Http\ServerRequest;
-use SmartyException;
+use Smarty\Exception as SmartyException;
 use Telegram\Bot\Exceptions\TelegramSDKException;
 use function json_decode;
 use function json_encode;

+ 9 - 7
src/Controllers/AuthController.php

@@ -11,6 +11,7 @@ use App\Models\User;
 use App\Services\Auth;
 use App\Services\Cache;
 use App\Services\Captcha;
+use App\Services\Filter;
 use App\Services\Mail;
 use App\Services\MFA;
 use App\Services\RateLimit;
@@ -150,9 +151,10 @@ final class AuthController extends BaseController
             }
 
             // check email format
-            $check_res = Tools::isEmailLegal($email);
-            if ($check_res['ret'] === 0) {
-                return $response->withJson($check_res);
+            $email_check = Filter::checkEmailFilter($email);
+
+            if (! $email_check) {
+                return ResponseHelper::error($response, '无效的邮箱');
             }
 
             if (! RateLimit::checkEmailIpLimit($request->getServerParam('REMOTE_ADDR')) ||
@@ -334,16 +336,16 @@ final class AuthController extends BaseController
         $imvalue = '';
 
         // check email format
-        $check_res = Tools::isEmailLegal($email);
+        $email_check = Filter::checkEmailFilter($email);
 
-        if ($check_res['ret'] === 0) {
-            return $response->withJson($check_res);
+        if (! $email_check) {
+            return ResponseHelper::error($response, '无效的邮箱');
         }
         // check email
         $user = (new User())->where('email', $email)->first();
 
         if ($user !== null) {
-            return ResponseHelper::error($response, '邮箱已经被注册了');
+            return ResponseHelper::error($response, '无效的邮箱');
         }
 
         if (Config::obtain('reg_email_verify')) {

+ 1 - 1
src/Controllers/BaseController.php

@@ -7,7 +7,7 @@ namespace App\Controllers;
 use App\Models\User;
 use App\Services\Auth;
 use App\Services\View;
-use Smarty;
+use Smarty\Smarty;
 use Twig\Environment;
 use voku\helper\AntiXSS;
 use function microtime;

+ 1 - 1
src/Controllers/CallbackController.php

@@ -11,7 +11,7 @@ use MaxMind\Db\Reader\InvalidDatabaseException;
 use Psr\Http\Message\ResponseInterface;
 use Slim\Http\Response;
 use Slim\Http\ServerRequest;
-use SmartyException;
+use Smarty\Exception as SmartyException;
 use Telegram\Bot\Exceptions\TelegramSDKException;
 
 final class CallbackController extends BaseController

+ 1 - 1
src/Controllers/HomeController.php

@@ -8,7 +8,7 @@ use App\Services\Auth;
 use Psr\Http\Message\ResponseInterface;
 use Slim\Http\Response;
 use Slim\Http\ServerRequest;
-use SmartyException;
+use Smarty\Exception as SmartyException;
 
 final class HomeController extends BaseController
 {

+ 1 - 1
src/Controllers/OAuthController.php

@@ -18,7 +18,7 @@ use Psr\Http\Message\ResponseInterface;
 use RedisException;
 use Slim\Http\Response;
 use Slim\Http\ServerRequest;
-use SmartyException;
+use Smarty\Exception as SmartyException;
 use function hash;
 use function hash_hmac;
 use function implode;

+ 1 - 1
src/Controllers/SubController.php

@@ -59,7 +59,7 @@ final class SubController extends BaseController
 
         $content_type = match ($subtype) {
             'clash' => 'application/yaml',
-            'json','sip008','singbox', 'v2rayjson' => 'application/json',
+            'json','sip008','singbox','v2rayjson' => 'application/json',
             default => 'text/plain',
         };
 

+ 4 - 3
src/Controllers/User/InfoController.php

@@ -9,6 +9,7 @@ use App\Models\Config;
 use App\Models\User;
 use App\Services\Auth;
 use App\Services\Cache;
+use App\Services\Filter;
 use App\Services\MFA;
 use App\Utils\Hash;
 use App\Utils\ResponseHelper;
@@ -60,10 +61,10 @@ final class InfoController extends BaseController
             return ResponseHelper::error($response, '未填写邮箱');
         }
 
-        $check_res = Tools::isEmailLegal($new_email);
+        $email_check = Filter::checkEmailFilter($email);
 
-        if ($check_res['ret'] !== 1) {
-            return $response->withJson($check_res);
+        if (! $email_check) {
+            return ResponseHelper::error($response, '无效的邮箱');
         }
 
         $exist_user = (new User())->where('email', $new_email)->first();

+ 45 - 0
src/Services/Filter.php

@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Services;
+
+use App\Utils\Tools;
+use function explode;
+use function in_array;
+
+final class Filter
+{
+    public static function checkEmailFilter(string $email): bool
+    {
+        if (! Tools::isEmail($email)) {
+            return false;
+        }
+
+        $res = false;
+        $mail_suffix = explode('@', $email)[1];
+        $mail_filter = $_ENV['mail_filter'] ?? 0;
+        $mail_filter_list = $_ENV['mail_filter_list'] ?? [];
+
+        switch ($mail_filter) {
+            case 1:
+                // Whitelist
+                if (in_array($mail_suffix, $mail_filter_list)) {
+                    $res = true;
+                }
+
+                break;
+            case 2:
+                // Blacklist
+                if (! in_array($mail_suffix, $mail_filter_list)) {
+                    $res = true;
+                }
+
+                break;
+            default:
+                $res = true;
+        }
+
+        return $res;
+    }
+}

+ 4 - 4
src/Services/Mail.php

@@ -15,7 +15,7 @@ use App\Services\Mail\Ses;
 use App\Services\Mail\Smtp;
 use Exception;
 use Psr\Http\Client\ClientExceptionInterface;
-use Smarty;
+use Smarty\Smarty;
 
 /*
  * Mail Service
@@ -42,9 +42,9 @@ final class Mail
     public static function genHtml($template, $ary): false|string
     {
         $smarty = new Smarty();
-        $smarty->settemplatedir(BASE_PATH . '/resources/email/');
-        $smarty->setcompiledir(BASE_PATH . '/storage/framework/smarty/compile/');
-        $smarty->setcachedir(BASE_PATH . '/storage/framework/smarty/cache/');
+        $smarty->setTemplateDir(BASE_PATH . '/resources/email/');
+        $smarty->setCompileDir(BASE_PATH . '/storage/framework/smarty/compile/');
+        $smarty->setCacheDir(BASE_PATH . '/storage/framework/smarty/cache/');
         $smarty->assign('config', View::getConfig());
 
         foreach ($ary as $key => $value) {

+ 2 - 2
src/Services/Subscribe.php

@@ -56,12 +56,12 @@ final class Subscribe
             ->get();
     }
 
-    public static function getContent($user, $type): string
+    public static function getContent($user, string $type): string
     {
         return self::getClient($type)->getContent($user);
     }
 
-    public static function getClient($type): Json|SS|SIP002|V2Ray|Trojan|Clash|SIP008|SingBox|V2RayJson
+    public static function getClient(string $type): Json|SS|SIP002|V2Ray|Trojan|Clash|SIP008|SingBox|V2RayJson
     {
         return match ($type) {
             'ss' => new SS(),

+ 4 - 4
src/Services/View.php

@@ -6,7 +6,7 @@ namespace App\Services;
 
 use App\Models\Config;
 use Illuminate\Database\DatabaseManager;
-use Smarty;
+use Smarty\Smarty;
 use Twig\Environment;
 use Twig\Loader\FilesystemLoader;
 use const BASE_PATH;
@@ -21,9 +21,9 @@ final class View
         $smarty = new Smarty(); //实例化smarty
         $user = Auth::getUser();
 
-        $smarty->settemplatedir(BASE_PATH . '/resources/views/' . self::getTheme($user) . '/'); //设置模板文件存放目录
-        $smarty->setcompiledir(BASE_PATH . '/storage/framework/smarty/compile/'); //设置生成文件存放目录
-        $smarty->setcachedir(BASE_PATH . '/storage/framework/smarty/cache/'); //设置缓存文件存放目录
+        $smarty->setTemplateDir(BASE_PATH . '/resources/views/' . self::getTheme($user) . '/'); //设置模板文件存放目录
+        $smarty->setCompileDir(BASE_PATH . '/storage/framework/smarty/compile/'); //设置生成文件存放目录
+        $smarty->setCacheDir(BASE_PATH . '/storage/framework/smarty/cache/'); //设置缓存文件存放目录
         // add config
         $smarty->assign('config', self::getConfig());
         $smarty->assign('public_setting', Config::getPublicConfig());

+ 1 - 53
src/Utils/Tools.php

@@ -5,7 +5,6 @@ declare(strict_types=1);
 namespace App\Utils;
 
 use App\Models\Config;
-use App\Models\Link;
 use App\Models\User;
 use App\Services\GeoIP2;
 use GeoIp2\Exception\AddressNotFoundException;
@@ -17,7 +16,6 @@ use function bin2hex;
 use function closedir;
 use function count;
 use function date;
-use function explode;
 use function filter_var;
 use function floor;
 use function hash;
@@ -170,14 +168,7 @@ final class Tools
 
     public static function genSubToken(): string
     {
-        $token = self::genRandomChar($_ENV['sub_token_len']);
-        $is_token_used = (new Link())->where('token', $token)->first();
-
-        if ($is_token_used === null) {
-            return $token;
-        }
-
-        return "couldn't alloc token";
+        return self::genRandomChar(max($_ENV['sub_token_len'], 8));
     }
 
     public static function genRandomChar(int $length = 8): string
@@ -297,49 +288,6 @@ final class Tools
         };
     }
 
-    /**
-     * @param $email
-     *
-     * @return array
-     */
-    public static function isEmailLegal($email): array
-    {
-        $res = [];
-        $res['ret'] = 0;
-
-        if (! self::isEmail($email)) {
-            $res['msg'] = '邮箱不规范';
-            return $res;
-        }
-
-        $mail_suffix = explode('@', $email)[1];
-        $mail_filter_list = $_ENV['mail_filter_list'];
-
-        switch ($_ENV['mail_filter']) {
-            case 1:
-                // 白名单
-                if (in_array($mail_suffix, $mail_filter_list)) {
-                    $res['ret'] = 1;
-                } else {
-                    $res['msg'] = '邮箱域名 ' . $mail_suffix . ' 无效,请更换邮件地址';
-                }
-
-                return $res;
-            case 2:
-                // 黑名单
-                if (! in_array($mail_suffix, $mail_filter_list)) {
-                    $res['ret'] = 1;
-                } else {
-                    $res['msg'] = '邮箱域名 ' . $mail_suffix . ' 无效,请更换邮件地址';
-                }
-
-                return $res;
-            default:
-                $res['ret'] = 1;
-                return $res;
-        }
-    }
-
     public static function isEmail($input): bool
     {
         if (! filter_var($input, FILTER_VALIDATE_EMAIL)) {

+ 32 - 0
tests/App/Services/FilterTest.php

@@ -0,0 +1,32 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Services;
+
+use PHPUnit\Framework\TestCase;
+
+final class FilterTest extends TestCase
+{
+    /**
+     * @covers App\Services\Filter::checkEmailFilter
+     */
+    public function testCheckEmailFilter(): void
+    {
+        $_ENV['mail_filter'] = 1;
+        $_ENV['mail_filter_list'] = ['example.com'];
+        $this->assertTrue(Filter::checkEmailFilter('[email protected]'));
+        $_ENV['mail_filter'] = 2;
+        $_ENV['mail_filter_list'] = ['example.com'];
+        $this->assertFalse(Filter::checkEmailFilter('[email protected]'));
+        $this->assertFalse(Filter::checkEmailFilter('invalid_email'));
+        $_ENV['mail_filter'] = 0;
+        $this->assertTrue(Filter::checkEmailFilter('[email protected]'));
+        $_ENV['mail_filter'] = 1;
+        $_ENV['mail_filter_list'] = ['example.com'];
+        $this->assertFalse(Filter::checkEmailFilter('[email protected]'));
+        $_ENV['mail_filter'] = 2;
+        $_ENV['mail_filter_list'] = ['example.com'];
+        $this->assertTrue(Filter::checkEmailFilter('[email protected]'));
+    }
+}

+ 26 - 18
tests/App/Utils/ToolsTest.php

@@ -7,6 +7,7 @@ namespace App\Utils;
 use MaxMind\Db\Reader\InvalidDatabaseException;
 use PHPUnit\Framework\TestCase;
 use function date_default_timezone_set;
+use function strlen;
 
 class ToolsTest extends TestCase
 {
@@ -102,15 +103,38 @@ class ToolsTest extends TestCase
         $this->assertEquals($traffic / $mb, $result);
     }
 
+    /**
+     * @covers App\Utils\Tools::genSubToken
+     */
+    public function testGenSubToken()
+    {
+        $_ENV['sub_token_len'] = 10;
+        $token = Tools::genSubToken();
+        $this->assertEquals(10, strlen($token));
+        $_ENV['sub_token_len'] = 0;
+        $token = Tools::genSubToken();
+        $this->assertEquals(8, strlen($token));
+        $_ENV['sub_token_len'] = -5;
+        $token = Tools::genSubToken();
+        $this->assertEquals(8, strlen($token));
+    }
+
     /**
      * @covers App\Utils\Tools::genRandomChar
      */
     public function testGenRandomChar()
     {
+        $randomString = Tools::genRandomChar();
+        $this->assertIsString($randomString);
+        $this->assertEquals(8, strlen($randomString));
         $length = 10;
         $randomString = Tools::genRandomChar($length);
         $this->assertIsString($randomString);
         $this->assertEquals($length, strlen($randomString));
+        $length = 1;
+        $randomString = Tools::genRandomChar($length);
+        $this->assertIsString($randomString);
+        $this->assertEquals(2, strlen($randomString));
     }
 
     /**
@@ -220,24 +244,6 @@ class ToolsTest extends TestCase
         $this->assertEquals($expected4, $result4);
     }
 
-    /**
-     * @covers App\Utils\Tools::isEmailLegal
-     */
-    public function testIsEmailLegal()
-    {
-        $_ENV['mail_filter'] = 1;
-        $_ENV['mail_filter_list'] = ['example.com'];
-
-        $email1 = '[email protected]';
-        $email2 = '[email protected]';
-
-        $expected1 = ['ret' => 1];
-        $expected2 = ['ret' => 0, 'msg' => '邮箱域名 example.org 无效,请更换邮件地址'];
-
-        $this->assertEquals($expected1, Tools::isEmailLegal($email1));
-        $this->assertEquals($expected2, Tools::isEmailLegal($email2));
-    }
-
     /**
      * @covers App\Utils\Tools::isEmail
      */
@@ -254,6 +260,7 @@ class ToolsTest extends TestCase
     {
         $this->assertTrue(Tools::isIPv4('192.168.0.1'));
         $this->assertFalse(Tools::isIPv4('2001:0db8:85a3:0000:0000:8a2e:0370:7334'));
+        $this->assertFalse(Tools::isIPv4('UwU'));
     }
 
     /**
@@ -263,6 +270,7 @@ class ToolsTest extends TestCase
     {
         $this->assertTrue(Tools::isIPv6('2001:0db8:85a3:0000:0000:8a2e:0370:7334'));
         $this->assertFalse(Tools::isIPv6('192.168.0.1'));
+        $this->assertFalse(Tools::isIPv6('hmm'));
     }
 
     /**