浏览代码

refactor: remove raw sql & better ss2022 pk gen

M1Screw 2 年之前
父节点
当前提交
1e7eda716c

+ 3 - 3
app/routes.php

@@ -193,9 +193,9 @@ return static function (Slim\App $app): void {
         // 登录日志
         $group->get('/login', App\Controllers\Admin\LoginLogController::class . ':index');
         $group->post('/login/ajax', App\Controllers\Admin\LoginLogController::class . ':ajax');
-        // 在线IP
-        $group->get('/online', App\Controllers\Admin\OnlineIpController::class . ':index');
-        $group->post('/online/ajax', App\Controllers\Admin\OnlineIpController::class . ':ajax');
+        // 在线IP日志
+        $group->get('/online', App\Controllers\Admin\OnlineLogController::class . ':index');
+        $group->post('/online/ajax', App\Controllers\Admin\OnlineLogController::class . ':ajax');
         // 订阅日志
         $group->get('/subscribe', App\Controllers\Admin\SubscribeLogController::class . ':index');
         $group->post('/subscribe/ajax', App\Controllers\Admin\SubscribeLogController::class . ':ajax');

+ 25 - 26
composer.lock

@@ -123,16 +123,16 @@
         },
         {
             "name": "aws/aws-sdk-php",
-            "version": "3.281.11",
+            "version": "3.281.12",
             "source": {
                 "type": "git",
                 "url": "https://github.com/aws/aws-sdk-php.git",
-                "reference": "9d466efae67d5016ed132fd4ffa1566a7d4cab98"
+                "reference": "22a92f08758db2b152843ea0875eeee5a467d8ff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/9d466efae67d5016ed132fd4ffa1566a7d4cab98",
-                "reference": "9d466efae67d5016ed132fd4ffa1566a7d4cab98",
+                "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/22a92f08758db2b152843ea0875eeee5a467d8ff",
+                "reference": "22a92f08758db2b152843ea0875eeee5a467d8ff",
                 "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.281.11"
+                "source": "https://github.com/aws/aws-sdk-php/tree/3.281.12"
             },
-            "time": "2023-09-20T19:16:24+00:00"
+            "time": "2023-09-22T18:12:27+00:00"
         },
         {
             "name": "bacon/bacon-qr-code",
@@ -3646,16 +3646,16 @@
         },
         {
             "name": "psr/http-client",
-            "version": "1.0.2",
+            "version": "1.0.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/php-fig/http-client.git",
-                "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31"
+                "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/php-fig/http-client/zipball/0955afe48220520692d2d09f7ab7e0f93ffd6a31",
-                "reference": "0955afe48220520692d2d09f7ab7e0f93ffd6a31",
+                "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
+                "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
                 "shasum": ""
             },
             "require": {
@@ -3692,9 +3692,9 @@
                 "psr-18"
             ],
             "support": {
-                "source": "https://github.com/php-fig/http-client/tree/1.0.2"
+                "source": "https://github.com/php-fig/http-client"
             },
-            "time": "2023-04-10T20:12:12+00:00"
+            "time": "2023-09-23T14:17:50+00:00"
         },
         {
             "name": "psr/http-factory",
@@ -4898,16 +4898,16 @@
         },
         {
             "name": "stripe/stripe-php",
-            "version": "v12.3.0",
+            "version": "v12.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/stripe/stripe-php.git",
-                "reference": "260aad072f92ddb05e03d47af13b3616d99b3444"
+                "reference": "7d0a90772fc1c179e370971264318208533324b9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/260aad072f92ddb05e03d47af13b3616d99b3444",
-                "reference": "260aad072f92ddb05e03d47af13b3616d99b3444",
+                "url": "https://api.github.com/repos/stripe/stripe-php/zipball/7d0a90772fc1c179e370971264318208533324b9",
+                "reference": "7d0a90772fc1c179e370971264318208533324b9",
                 "shasum": ""
             },
             "require": {
@@ -4920,8 +4920,7 @@
                 "friendsofphp/php-cs-fixer": "3.5.0",
                 "php-coveralls/php-coveralls": "^2.5",
                 "phpstan/phpstan": "^1.2",
-                "phpunit/phpunit": "^5.7 || ^9.0",
-                "squizlabs/php_codesniffer": "^3.3"
+                "phpunit/phpunit": "^5.7 || ^9.0"
             },
             "type": "library",
             "extra": {
@@ -4953,9 +4952,9 @@
             ],
             "support": {
                 "issues": "https://github.com/stripe/stripe-php/issues",
-                "source": "https://github.com/stripe/stripe-php/tree/v12.3.0"
+                "source": "https://github.com/stripe/stripe-php/tree/v12.4.0"
             },
-            "time": "2023-09-15T00:57:14+00:00"
+            "time": "2023-09-21T22:55:47+00:00"
         },
         {
             "name": "symfony/deprecation-contracts",
@@ -7110,16 +7109,16 @@
         },
         {
             "name": "friendsofphp/php-cs-fixer",
-            "version": "v3.27.0",
+            "version": "v3.28.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
-                "reference": "e73ccaae1208f017bb7860986eebb3da48bd25d6"
+                "reference": "113e09fea3d2306319ffaa2423fe3de768b28cff"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/e73ccaae1208f017bb7860986eebb3da48bd25d6",
-                "reference": "e73ccaae1208f017bb7860986eebb3da48bd25d6",
+                "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/113e09fea3d2306319ffaa2423fe3de768b28cff",
+                "reference": "113e09fea3d2306319ffaa2423fe3de768b28cff",
                 "shasum": ""
             },
             "require": {
@@ -7193,7 +7192,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.27.0"
+                "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.28.0"
             },
             "funding": [
                 {
@@ -7201,7 +7200,7 @@
                     "type": "github"
                 }
             ],
-            "time": "2023-09-17T14:37:54+00:00"
+            "time": "2023-09-22T20:43:40+00:00"
         },
         {
             "name": "justinrainbow/json-schema",

+ 2 - 2
config/appprofile.example.php

@@ -102,11 +102,11 @@ $_ENV['SingBox_Config'] = [
     ],
     'route' => [
         'geoip' => [
-            'download_url' => 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip-lite.db',
+            'download_url' => 'https://' . $_ENV['jsdelivr_url'] . '/gh/MetaCubeX/meta-rules-dat@release/geoip-lite.db',
             'download_detour' => 'direct',
         ],
         'geosite' => [
-            'download_url' => 'https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite-lite.db',
+            'download_url' => 'https://' . $_ENV['jsdelivr_url'] . '/gh/MetaCubeX/meta-rules-dat@release/geosite-lite.db',
             'download_detour' => 'direct',
         ],
         'rules' => [

+ 0 - 24
config/clients.json

@@ -32,30 +32,6 @@
                 }
             ]
         },
-        {
-            "name": "v2rayN",
-            "tagMethod": "github_pre_release",
-            "gitRepo": "2dust/v2rayN",
-            "savePath": "public/clients/",
-            "downloads": [
-                {
-                    "sourceName": "v2rayN-With-Core.zip",
-                    "saveName": "v2rayN-Core.zip"
-                }
-            ]
-        },
-        {
-            "name": "v2rayNG",
-            "tagMethod": "github_pre_release",
-            "gitRepo": "2dust/v2rayNG",
-            "savePath": "public/clients/",
-            "downloads": [
-                {
-                    "sourceName": "v2rayNG_%tagName%.apk",
-                    "saveName": "v2rayNG.apk"
-                }
-            ]
-        },
         {
             "name": "sing-box",
             "tagMethod": "github_release",

+ 1 - 1
resources/views/tabler/admin/log/online.tpl

@@ -45,7 +45,7 @@
             ajax: {
                 url: '/admin/online/ajax',
                 type: 'POST',
-                dataSrc: 'onlines'
+                dataSrc: 'onlines.data'
             },
             "autoWidth":false,
             'iDisplayLength': 10,

+ 0 - 14
resources/views/tabler/user/index.tpl

@@ -255,20 +255,6 @@
                                                     复制传统订阅(Trojan)
                                                 </a>
                                                 {/if}
-                                                <a {if $config['enable_r2_client_download']}
-                                                        href="/user/clients/v2rayN-Core.zip"
-                                                    {else}
-                                                        href="/clients/v2rayN-Core.zip"
-                                                    {/if} class="btn btn-azure">
-                                                    下载 v2rayN(Windows)
-                                                </a>
-                                                <a {if $config['enable_r2_client_download']}
-                                                        href="/user/clients/v2rayNG.apk"
-                                                    {else}
-                                                        href="/clients/v2rayNG.apk"
-                                                    {/if} class="btn btn-azure">
-                                                    下载 v2rayNG(Android)
-                                                </a>
                                             </div>
                                         </div>
                                     </div>

+ 2 - 1
src/Command/Tool.php

@@ -247,7 +247,8 @@ EOL;
         $users = ModelsUser::all();
 
         foreach ($users as $user) {
-            $user->generateUUID();
+            $user->uuid = Uuid::uuid4();
+            $user->save();
         }
 
         echo 'generate UUID successful';

+ 0 - 106
src/Controllers/Admin/OnlineIpController.php

@@ -1,106 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace App\Controllers\Admin;
-
-use App\Controllers\BaseController;
-use App\Services\DB;
-use App\Utils\Tools;
-use Exception;
-use MaxMind\Db\Reader\InvalidDatabaseException;
-use Psr\Http\Message\ResponseInterface;
-use Slim\Http\Response;
-use Slim\Http\ServerRequest;
-use function array_map;
-use function array_slice;
-use function count;
-use function str_replace;
-
-final class OnlineIpController extends BaseController
-{
-    private static array $details =
-        [
-            'field' => [
-                'id' => '事件ID',
-                'user_id' => '用户ID',
-                'user_name' => '用户名',
-                'node_id' => '节点ID',
-                'node_name' => '节点名',
-                'ip' => 'IP',
-                'location' => 'IP归属地',
-                'first_time' => '首次连接',
-                'last_time' => '最后连接',
-            ],
-        ];
-
-    /**
-     * 后台在线 IP 页面
-     *
-     * @throws Exception
-     */
-    public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
-    {
-        return $response->write(
-            $this->view()
-                ->assign('details', self::$details)
-                ->fetch('admin/log/online.tpl')
-        );
-    }
-
-    /**
-     * 后台在线 IP 页面 AJAX
-     *
-     * @throws InvalidDatabaseException
-     */
-    public function ajax(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
-    {
-        $data = $request->getParsedBody();
-        $length = (int) ($data['length'] ?? 0);
-        $start = (int) ($data['start'] ?? 0);
-        $draw = $data['draw'] ?? null;
-
-        $logs = DB::select('
-            SELECT
-                online_log.id,
-                online_log.user_id,
-                user.user_name,
-                online_log.node_id,
-                node.name AS node_name,
-                online_log.ip,
-                online_log.first_time,
-                online_log.last_time
-            FROM
-                online_log
-                LEFT JOIN user ON user.id = online_log.user_id
-                LEFT JOIN node ON node.id = online_log.node_id
-            WHERE
-                last_time > UNIX_TIMESTAMP() - 90
-        ');
-
-        $count = count($logs);
-        $data = array_map(
-            static function ($val) {
-                return [
-                    'id' => $val->id,
-                    'user_id' => $val->user_id,
-                    'user_name' => $val->user_name,
-                    'node_id' => $val->node_id,
-                    'node_name' => $val->node_name,
-                    'ip' => str_replace('::ffff:', '', $val->ip),
-                    'location' => Tools::getIpLocation(str_replace('::ffff:', '', $val->ip)),
-                    'first_time' => Tools::toDateTime($val->first_time),
-                    'last_time' => Tools::toDateTime($val->last_time),
-                ];
-            },
-            array_slice($logs, $start, $length)
-        );
-
-        return $response->withJson([
-            'draw' => $draw,
-            'recordsTotal' => $count,
-            'recordsFiltered' => $count,
-            'onlines' => $data,
-        ]);
-    }
-}

+ 78 - 0
src/Controllers/Admin/OnlineLogController.php

@@ -0,0 +1,78 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\Controllers\Admin;
+
+use App\Controllers\BaseController;
+use App\Models\OnlineLog;
+use App\Utils\Tools;
+use Exception;
+use MaxMind\Db\Reader\InvalidDatabaseException;
+use Psr\Http\Message\ResponseInterface;
+use Slim\Http\Response;
+use Slim\Http\ServerRequest;
+use function time;
+
+final class OnlineLogController extends BaseController
+{
+    private static array $details =
+        [
+            'field' => [
+                'id' => '事件ID',
+                'user_id' => '用户ID',
+                'user_name' => '用户名',
+                'node_id' => '节点ID',
+                'node_name' => '节点名',
+                'ip' => 'IP',
+                'location' => 'IP归属地',
+                'first_time' => '首次连接',
+                'last_time' => '最后连接',
+            ],
+        ];
+
+    /**
+     * 后台在线 IP 页面
+     *
+     * @throws Exception
+     */
+    public function index(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
+    {
+        return $response->write(
+            $this->view()
+                ->assign('details', self::$details)
+                ->fetch('admin/log/online.tpl')
+        );
+    }
+
+    /**
+     * 后台在线 IP 页面 AJAX
+     *
+     * @throws InvalidDatabaseException
+     */
+    public function ajax(ServerRequest $request, Response $response, array $args): Response|ResponseInterface
+    {
+        $length = $request->getParam('length');
+        $page = $request->getParam('start') / $length + 1;
+        $draw = $request->getParam('draw');
+
+        $onlines = OnlineLog::where('last_time', '>', time() - 90)->orderByDesc('last_time')->paginate($length, '*', '', $page);
+        $total = OnlineLog::where('last_time', '>', time() - 90)->count();
+
+        foreach ($onlines as $online) {
+            $online->user_name = $online->userName();
+            $online->node_name = $online->nodeName();
+            $online->ip = $online->ip();
+            $online->location = Tools::getIpLocation($online->ip);
+            $online->first_time = Tools::toDateTime($online->first_time);
+            $online->last_time = Tools::toDateTime($online->last_time);
+        }
+
+        return $response->withJson([
+            'draw' => $draw,
+            'recordsTotal' => $total,
+            'recordsFiltered' => $total,
+            'onlines' => $onlines,
+        ]);
+    }
+}

+ 0 - 2
src/Controllers/User/ClientController.php

@@ -28,8 +28,6 @@ final class ClientController extends BaseController
             'Clash.Verge_aarch64.dmg',
             'Clash.Verge.AppImage.tar.gz',
             'Clash-Android.apk',
-            'v2rayN-Core.zip',
-            'v2rayNG.apk',
             'SFA.apk',
             'SFM.zip',
         ];

+ 1 - 1
src/Controllers/WebAPI/UserController.php

@@ -112,7 +112,7 @@ final class UserController extends BaseController
                     default => 32,
                 };
 
-                $user_raw->passwd = $user_raw->getSs2022Pk($pk_len);
+                $user_raw->passwd = Tools::genSs2022UserPk($user_raw->passwd, $pk_len);
             }
 
             $user_raw->node_connector = 0;

+ 10 - 0
src/Models/OnlineLog.php

@@ -55,4 +55,14 @@ final class OnlineLog extends Model
 
         return $ip;
     }
+
+    public function userName(): string
+    {
+        return User::where('id', $this->user_id)->value('user_name');
+    }
+
+    public function nodeName(): string
+    {
+        return Node::where('id', $this->node_id)->value('name');
+    }
 }

+ 3 - 32
src/Models/User.php

@@ -4,7 +4,6 @@ declare(strict_types=1);
 
 namespace App\Models;
 
-use App\Services\DB;
 use App\Services\IM;
 use App\Utils\Hash;
 use App\Utils\Tools;
@@ -51,15 +50,7 @@ final class User extends Model
      */
     public function getSs2022Pk($len): string
     {
-        $passwd_hash = hash('sha256', $this->passwd);
-
-        $pk = match ($len) {
-            16 => mb_strcut($passwd_hash, 0, 16),
-            32 => mb_strcut($passwd_hash, 0, 32),
-            default => $passwd_hash,
-        };
-
-        return base64_encode($pk);
+        return Tools::genSs2022UserPk($this->passwd, $len);
     }
 
     /**
@@ -67,7 +58,7 @@ final class User extends Model
      */
     public function getDiceBearAttribute(): string
     {
-        return 'https://api.dicebear.com/6.x/identicon/svg?seed=' . md5($this->email);
+        return 'https://api.dicebear.com/7.x/identicon/svg?seed=' . md5($this->email);
     }
 
     /**
@@ -131,16 +122,6 @@ final class User extends Model
         return $this->save();
     }
 
-    /**
-     * 生成新的 UUID
-     */
-    public function generateUUID(): bool
-    {
-        $this->uuid = Uuid::uuid4();
-
-        return $this->save();
-    }
-
     /**
      * 生成新的 API Token
      */
@@ -281,17 +262,7 @@ final class User extends Model
      */
     public function onlineIpCount(): int
     {
-        return DB::select(
-            '
-            SELECT
-                COUNT(*) AS count
-            FROM
-                online_log
-            WHERE
-                user_id = ?
-                AND last_time >= UNIX_TIMESTAMP() - 90',
-            [$this->attributes['id']]
-        )[0]->count;
+        return OnlineLog::where('user_id', $this->id)->where('last_time', '>', time() - 90)->count();
     }
 
     /**

+ 16 - 0
src/Utils/Tools.php

@@ -12,16 +12,19 @@ use GeoIp2\Exception\AddressNotFoundException;
 use MaxMind\Db\Reader\InvalidDatabaseException;
 use function array_diff;
 use function array_flip;
+use function base64_encode;
 use function bin2hex;
 use function closedir;
 use function date;
 use function explode;
 use function filter_var;
 use function floor;
+use function hash;
 use function in_array;
 use function is_numeric;
 use function json_decode;
 use function log;
+use function mb_strcut;
 use function opendir;
 use function openssl_random_pseudo_bytes;
 use function pow;
@@ -215,6 +218,19 @@ final class Tools
         return "couldn't alloc token";
     }
 
+    public static function genSs2022UserPk($passwd, $len): string
+    {
+        $passwd_hash = hash('sha256', $passwd);
+
+        $pk = match ($len) {
+            16 => mb_strcut($passwd_hash, 0, 16),
+            32 => mb_strcut($passwd_hash, 0, 32),
+            default => $passwd_hash,
+        };
+
+        return base64_encode($pk);
+    }
+
     public static function toDateTime(int $time): string
     {
         return date('Y-m-d H:i:s', $time);